📄 winsurf2.cpp
字号:
if (m_hRenThread) { WaitForSingleObject(m_hSurfaceMutex, INFINITE); EnterCriticalSection(&m_csDisplay); } CWinSurface::_CreateBuffer(); BOOL bCreated = FALSE; if (m_surface.fMode & WINDRAW_DIRECTDRAW) { bCreated = (m_surface.dd.lpDDSurface != NULL); } else { bCreated = (m_surface.gdi.lpGDIBackBuffer[0] != NULL); } if (bCreated) { if (m_hRenThread) { // We create our surface, start servicing GetVidMem calls SetEvent(m_hReinit); } } if (m_hRenThread) { ReleaseMutex(m_hSurfaceMutex); LeaveCriticalSection(&m_csDisplay); }}HX_RESULT CWinSurface2::_CreateOverlay(BOOL bOverlay, int cid, int x, int y){ if (m_hRenThread) { WaitForSingleObject(m_hSurfaceMutex, INFINITE); EnterCriticalSection(&m_csDisplay); } HX_RESULT hr = CWinSurface::_CreateOverlay(bOverlay, cid, x, y); if (HXR_OK == hr && m_hRenThread) { // We created our surface, start servicing GetVidMem calls SetEvent(m_hReinit); } if (m_hRenThread) { LeaveCriticalSection(&m_csDisplay); ReleaseMutex(m_hSurfaceMutex); } return hr;}HX_RESULTCWinSurface2::ByPassCompositionSurface(UCHAR* pImageData, HXBitmapInfoHeader* pBitmapInfo, REF(HXxRect) rDestRect, REF(HXxRect) rSrcRect, UCHAR* pSurface, INT32 nSurfPitch){ // Check for vidsurf2-only dest surfaces if (CID_I420 == GETBITMAPCOLOR( pBitmapInfo) && m_pHwMemObj) { HXxSize srcSize = {pBitmapInfo->biWidth, pBitmapInfo->biHeight}; UCHAR* pYUV[3] = {pImageData, pYUV[0] + pBitmapInfo->biHeight*nSurfPitch, pYUV[1] + pBitmapInfo->biHeight*nSurfPitch/4}; INT32 nYUVPitch[3] = {nSurfPitch, nSurfPitch/2, nSurfPitch/2}; SourceInputStruct input = {pYUV, nYUVPitch, 3}; INT32 nPitch; UCHAR* pVidMem = (UCHAR*)m_pHwMemObj->DeviceToRenderer(pImageData, nPitch, WRITE_VIDEO_TO_STRUCT); AlignRect(&rSrcRect, pBitmapInfo->biWidth, pBitmapInfo->biHeight); AlignRect(&rDestRect, m_surfaceSize.cx, m_surfaceSize.cy); HX_RESULT hr = ColorConvert(MapCIDtoFourCC(GETBITMAPCOLOR(pBitmapInfo)), &srcSize, &rSrcRect, &input, MapCIDtoFourCC(m_nSurfaceCID), pVidMem, &m_surfaceSize, &rDestRect, nSurfPitch); m_pHwMemObj->RendererToDevice(pVidMem); return hr; } return CWinSurface::ByPassCompositionSurface(pImageData, pBitmapInfo, rDestRect, rSrcRect, pSurface, nSurfPitch);}void CWinSurface2::_ReleaseSurface(CBaseRootSurface* pSurface){ if (m_hRenThread) { Flush(); // Make the next GetVidMem wait on new surface creation WaitForSingleObject(m_hSurfaceMutex, INFINITE); ResetEvent(m_hReinit); Flush(); EnterCriticalSection(&m_csDisplay); } WINDRAW* pWindraw = ((CWinBaseRootSurface*)pSurface)->GetWinDraw(); DestroyFallbackSurface(); DestroyGdiSurface(); CWinSurface::_ReleaseSurface(pSurface); memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect)); if (m_hRenThread) { LeaveCriticalSection(&m_csDisplay); ReleaseMutex(m_hSurfaceMutex); } m_dLastXScale = 0.0; m_dLastYScale = 0.0;}void CWinSurface2::_ReleaseSurface(CWinBaseRootSurface* pSurface){ if (m_hRenThread) { Flush(); // Make the next GetVidMem wait on new surface creation WaitForSingleObject(m_hSurfaceMutex, INFINITE); ResetEvent(m_hReinit); Flush(); EnterCriticalSection(&m_csDisplay); } WINDRAW* pWindraw = pSurface->GetWinDraw(); DestroyFallbackSurface(); DestroyGdiSurface(); CWinSurface::_ReleaseSurface(pSurface); memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect)); if (m_hRenThread) { LeaveCriticalSection(&m_csDisplay); ReleaseMutex(m_hSurfaceMutex); } m_dLastXScale = 0.0; m_dLastYScale = 0.0;}void CWinSurface2::_ReleaseSurface(){ if (m_hRenThread) { Flush(); // Make the next GetVidMem wait on new surface creation WaitForSingleObject(m_hSurfaceMutex, INFINITE); ResetEvent(m_hReinit); Flush(); EnterCriticalSection(&m_csDisplay); } CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface(); if (pSurface) { WINDRAW* pWindraw = pSurface->GetWinDraw(); if (pWindraw) { DestroyFallbackSurface(); DestroyGdiSurface(); memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect)); CWinSurface::_ReleaseSurface(); } } if (m_hRenThread) { LeaveCriticalSection(&m_csDisplay); ReleaseMutex(m_hSurfaceMutex); } m_dLastXScale = 0.0; m_dLastYScale = 0.0;}void CWinSurface2::ReInitSurfaces(){ if ( (m_surface.fMode & WINDRAW_DIRECTDRAW) && m_surface.dd.lpDDSurface && m_bVideoSurface2) { return; } // Set yuv priority for vidsurf2 mode if (m_hRenThread) { // Lock the surface mutex WaitForSingleObject(m_hSurfaceMutex, INFINITE); m_pSite->_TLSLock(); int cid = GetBitmapColor((LPBITMAPINFO)m_pOptimizedFormat); BOOL bRestore = SetYUVPriorityList(cid); m_nBackBufferCount = m_nOverlayBackBuffersCreated; CWinSurface::ReInitSurfaces(); if (bRestore) RestoreColorspacePriorities(cid); // We switched to a mode that does not support overlay...yikes! if (m_bVideoSurface2 && (m_nBltMode != HX_OVERLAY_BLT || !m_nBackBufferCount)) { m_bMultipleOverlay = TRUE; ForceGDIMode(TRUE); } else { m_bMultipleOverlay = FALSE; } HXxSize rcSize = m_surfaceSize; CreateFallbackSurface(m_nSurfaceCID, &rcSize); m_pSite->_TLSUnlock(); ResetBufferTimes(0); ReleaseMutex(m_hSurfaceMutex); } else CWinSurface::ReInitSurfaces();}BOOL CWinSurface2::_IsDisplaySurfaceYuv(){ if (!m_bVideoSurface2) return CWinSurface::_IsDisplaySurfaceYuv(); return IsYUV(MapFourCCtoCID(m_bmi.biCompression));}BOOL CWinSurface2::_AllowsOverlayShrinking(){ if (m_bSurfaceRequiresOverlay) return TRUE; else return CWinSurface::_AllowsOverlayShrinking();}void CWinSurface2::_WaitForQueuedFrames(){ WaitForQueuedFrames();}void CWinSurface2::_LockBlitter(){ if (m_hSurfaceMutex) { // In the unlikely event that all of our hw buffers are // full AND GetVideoMem is blocking with m_hSurfaceMutex // while waiting for the time line to start, break // out of the time line wait loop. BOOL bOldValue = m_bWaitingForFlush; m_bWaitingForFlush = TRUE; WaitForSingleObject(m_hSurfaceMutex, INFINITE); m_bWaitingForFlush = bOldValue; }}void CWinSurface2::_UnlockBlitter(){ if (m_hSurfaceMutex) ReleaseMutex(m_hSurfaceMutex);}void CWinSurface2::_FlushSurfaces(){ Flush();}STDMETHODIMP CWinSurface2::SetProperties(HXBitmapInfoHeader* bmi, REF(UINT32) ulNumBuffers, IHXRenderTimeLine* pTimeLine){ // Block GetVideoMem calls WaitForSingleObject(m_hSurfaceMutex, INFINITE); ulNumBuffers = min(m_nMaxBackBuffers+1, (INT32)ulNumBuffers); CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface(); if (!pSurface) { ReleaseMutex(m_hSurfaceMutex); return HXR_FAIL; } WINDRAW* pWindraw = pSurface->GetWinDraw(); // If we already have surfaces, destroy and recreate if necessary if (m_hRenThread) { if (bmi->biWidth != m_bmi.biWidth || bmi->biHeight != m_bmi.biHeight || m_surface.dwBackBufferCount == 0 || ulNumBuffers != (UINT32)m_nBackBufferCount+1 || WAIT_OBJECT_0 != WaitForSingleObject(m_hReinit, 0)) { // Wait for display buffers to render if (HXR_OK != WaitForQueuedFrames()) Flush(); DestroySurfaces(); m_nBackBufferCount = 0; memset(&m_bmi, 0, sizeof(m_bmi)); memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect)); } else { HX_RELEASE(m_pTimeLine); m_pTimeLine = pTimeLine; if (m_pTimeLine) m_pTimeLine->AddRef(); m_bVideoSurface2 = TRUE; // If we are keeping our existing video buffers, reset // the flipping chain indexes if we have DirectDraw. if (!m_bLostHWAcceleration) WinDraw_ResetSurfaceIndexes(pWindraw, &m_surface); ReleaseMutex(m_hSurfaceMutex); return HXR_OK; } } // If we do not have a render thread and we have an optimized // format, we are in VS1 mode so fail the VS2 init. else if (m_pOptimizedFormat) { ReleaseMutex(m_hSurfaceMutex); return HXR_FAIL; } // Try and create an overlay flpping chain of pRequest->nNumBuffers buffers m_nBackBufferCount = ulNumBuffers - 1; if (m_nBackBufferCount) m_bFlipOverlay = TRUE; m_bSpamUpdateOverlay = FALSE; int cid = GetBitmapColor((LPBITMAPINFO)bmi); BOOL bRestore = SetYUVPriorityList(cid); BeginOptimizedBlt(bmi); int nBltMode = m_nBltMode; if (bRestore) RestoreColorspacePriorities(cid); if (nBltMode != HX_OVERLAY_BLT || !m_nBackBufferCount) { DestroySurfaces(); ulNumBuffers = 0; m_bVideoSurface2 = FALSE; ReleaseMutex(m_hSurfaceMutex); return HXR_FAIL; } m_nOverlayBackBuffersCreated = m_nBackBufferCount; bmi->biCompression = MapCIDtoFourCC(m_nSurfaceCID); // How odd, a dd driver that returns the wrong caps. // I have not seen anything like since the last time I tried // to use the caps. // // We will always try interval flips and swith to flip // waits if flip returns an error.#if DIRECTDRAW_VERSION > 0x0500 // Can we use the flip interval flag if ((pWindraw->dd.m_caps.dwCaps2 & DDCAPS2_FLIPINTERVAL) != DDCAPS2_FLIPINTERVAL) { m_bUseVBlankFlip = FALSE; }#else m_bUseVBlankFlip = FALSE;#endif if (pWindraw->dwMaxScanLine && pWindraw->dMsPerVBlank > 0.0) m_bOptimalVideoScheduler = TRUE; // If we are using a DirectDraw surface represented by a structure, // several of our post-processing functions will not work. Set the // various modes here. While we are generalizing here, most of // these surface types are proprietary so disable anything suspicious. if (IsStructured(m_nSurfaceCID)) { m_bUseDDColorControls = TRUE; m_bSurfaceRequiresOverlay = TRUE; // Set default DD color controls m_Brightness = DEF_BRIGHTNESS; m_Contrast = DEF_CONTRAST;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -