📄 winsurf2.cpp
字号:
#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;
m_Saturation = DEF_SATURATION;
m_Hue = DEF_HUE;
m_Sharpness = DEF_SHARPNESS;
}
else
{
m_bUseDDColorControls = FALSE;
m_bSurfaceRequiresOverlay = FALSE;
}
memset(&m_rcLast, 0, sizeof(m_rcLast));
// Store actual settings
m_bmi = *bmi;
// for _ConstructRects
m_bmiLastBlt = m_bmi;
m_bVideoSurface2 = TRUE;
// Schedule a recompute clip after I set m_bmiLastBlt to remove
// deafault alpha site. This prevents us from playing in alpha
// blending mode for local clips.
if(m_pSite->m_pTopLevelSite)
m_pSite->m_pTopLevelSite->ScheduleCallback(CLIP, 0);
m_bmi.biSizeImage = m_nDDSurfaceSize;
m_bmi.biWidth = m_surfaceSize.cx;
m_bmi.biHeight = m_surfaceSize.cy;
m_bmi.biCompression = m_nSurfaceCID;
ulNumBuffers = m_nBackBufferCount+1;
#ifdef _DEBUG
char szTmp[128]; /* Flawfinder: ignore */
char acid[5][5] = {{"I420"}, {"YV12"}, {"YVU9"}, {"YUY2"}, {"UYVY"}}; /* Flawfinder: ignore */
char dvpf[5] = "DVPF"; /* Flawfinder: ignore */
char *pCurrent = dvpf;
if (m_nSurfaceCID < 5)
pCurrent = acid[m_nSurfaceCID];
wsprintf(szTmp, "SetProperties Create %ld %s buffers\n", ulNumBuffers, pCurrent);
OutputDebugString(szTmp);
#endif
HXxSize rcSize = {m_bmi.biWidth, m_bmi.biHeight};
CreateFallbackSurface(m_nSurfaceCID, &rcSize);
// Kill render thread if running
if (m_hRenThread)
{
m_bCont = FALSE;
SetEvent(m_hAbort);
WaitForSingleObject(m_hRenThread, INFINITE);
CloseHandle(m_hRenThread);
m_hRenThread = 0;
CloseHandle(m_hFrameSem);
m_hFrameSem = 0;
}
HX_RELEASE(m_pTimeLine);
m_pTimeLine = pTimeLine;
if (m_pTimeLine)
m_pTimeLine->AddRef();
// Create the render thread
DWORD dwId;
m_bCont = TRUE;
ResetEvent(m_hAbort);
m_hFrameSem = CreateSemaphore(NULL, 0, ulNumBuffers+1, NULL);
m_hRenThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE )ThreadProc,
this, 0, &dwId);
if (m_bBoostRenderThread)
SetThreadPriority(m_hRenThread, THREAD_PRIORITY_TIME_CRITICAL);
ReleaseMutex(m_hSurfaceMutex);
return HXR_OK;
}
BOOL CWinSurface2::SetYUVPriorityList(int cidIn)
{
IHXPreferences* pPreferences = NULL;
IHXBuffer* pBuffer = NULL;
BOOL bUsePriorityScheme = TRUE;
BOOL bRestore = FALSE;
BOOL bUseHWPF = FALSE;
if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,(void**)&pPreferences))
{
// Disalbe our surface priority scheme?
if (pPreferences->ReadPref("VideoBoost\\DisableSurfacePriority", pBuffer) == HXR_OK)
{
bUsePriorityScheme = !(::atoi((char*) pBuffer->GetBuffer()) == 1);
}
HX_RELEASE(pBuffer);
HX_RELEASE(pPreferences);
}
// Set the priority for the yuv format we use
if (bUsePriorityScheme)
{
int aList[5] = {0,0,0,0,0};
int *pList = aList;
int nListSize = 5;
bRestore = FALSE;
if (NOERROR == WinDraw2_GetColorspacePriorities(cidIn, pList, nListSize) && nListSize)
{
SetColorspacePriorities(aList, nListSize, cidIn);
bRestore = TRUE;
}
}
return bRestore;
}
STDMETHODIMP CWinSurface2::GetVideoMem(VideoMemStruct* pVidStruct,
UINT32 ulFlags)
{
memset(pVidStruct, 0, sizeof(*pVidStruct));
HXBitmapInfoHeader* bmi = &pVidStruct->bmi;
UCHAR* pVidMem;
INT32 nPitch = 0;
// If we lost our surface, re-create them (if we are not
// in the process of switching overlay via the OverlayManager or
// in gdi because we lost DirectDraw).
if (!m_surface.dd.lpDDSurface &&
!m_bFallbackSurfaceCreated &&
!m_bSwitchingingOverlay &&
!m_bLostHWAcceleration)
{
// Make sure we have no locked surfaces
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hSurfaceMutex, 0))
{
if (ulFlags & HX_WAIT_NEVER)
return HXR_BUFFER_NOT_AVAILABLE;
WaitForSingleObject(m_hSurfaceMutex, INFINITE);
}
ReInitSurfaces();
// Did not work...return an error
if (!m_surface.dd.lpDDSurface &&
!m_bFallbackSurfaceCreated &&
!m_bGdiSurfaceCreated)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
ReleaseMutex(m_hSurfaceMutex);
}
// Return an error if there are not buffers available
if (ulFlags & HX_WAIT_NEVER)
{
// Check m_hReinit is signaled. If not, return an error
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hReinit, 0))
return HXR_BUFFER_NOT_AVAILABLE;
// Make sure we have no locked surfaces
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hSurfaceMutex, 0))
return HXR_BUFFER_NOT_AVAILABLE;
// If we lost our surface, return an error
if (!m_surface.dd.lpDDSurface &&
!m_bFallbackSurfaceCreated &&
!m_bGdiSurfaceCreated)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
}
// Wait until a buffer is available
else
{
// Wait until our surfaces are created
WaitForSingleObject(m_hReinit, INFINITE);
// Wait for last lock
WaitForSingleObject(m_hSurfaceMutex, INFINITE);
// If we lost our surface, return an error
if (!m_surface.dd.lpDDSurface &&
!m_bFallbackSurfaceCreated &&
!m_bGdiSurfaceCreated)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
}
if (m_bFlushing || m_bWasInVidSurf2)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
INT32 nIndex = -1;
HX_RESULT hr = HXR_OK;
pVidMem = NULL;
nPitch = 0;
if (m_pSite->_BordersActive() |
m_pSite->_FadeTransitionActive() |
(m_pSite->AreVideoControlsActive() && !m_bUseDDColorControls) |
m_pSite->IsHigherZOrderTranstitionActive() |
(m_LinkedSites.GetCount() > 0) |
(m_pLinkedOverlay != NULL))
{
// Drop to VideoSurface1 for transitions
if (m_pSite->m_pUser)
{
//Can't satisfy a HX_WAIT_NEVER and block without a
//response object. :-)
if( ulFlags & HX_WAIT_NEVER )
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
HXxEvent event = {HX_SURFACE_MODE_CHANGE, NULL, NULL,
(void*)HX_VIDEOSURFACE1_RECOMMENDED, 0, 0};
m_bWasInVidSurf2 = TRUE;
_WaitForFlush();
// Unlock the surface mutex so we can be torn down
ReleaseMutex(m_hSurfaceMutex);
m_pSite->m_pUser->HandleEvent(&event);
// The renderer switched to VideoSurface1 so don't give them a buffer
if (event.handled)
{
// Reset or last scale since we are not bltting for a time
m_dLastXScale = 0.0;
m_dLastYScale = 0.0;
return HXR_BUFFER_NOT_AVAILABLE;
}
else
{
m_bWasInVidSurf2 = FALSE;
// Need to lock the mutex since the switch failed
WaitForSingleObject(m_hSurfaceMutex, INFINITE);
CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
WINDRAW* pWindraw = pSurface->GetWinDraw();
WinDraw_ResetSurfaceIndexes(pWindraw, &m_surface);
}
}
}
// Can we restore DirectDraw
if (m_bLostHWAcceleration)
{
CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
m_bLostHWAcceleration = !pSurface->_IsHardwareAccelerationAvail();
if (!m_bLostHWAcceleration)
{
if (HXR_OK != WaitForQueuedFrames())
Flush();
DestroyGdiSurface();
pSurface->_AcquireHardwareAcceleration();
ReInitSurfaces();
}
}
LOCK_VIDEO_BUFFER:
int nBltMode = GetBestBltMode();
BOOL bLockTLSMutex = FALSE;
bLockTLSMutex = CanLockSurface(nIndex, nBltMode, (ulFlags & HX_WAIT_NEVER) != HX_WAIT_NEVER);
if (m_bFlushing)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
if (bLockTLSMutex)
{
BOOL bRet = m_pSite->_TLSIsLocked();
if( bRet && (ulFlags&HX_WAIT_NEVER) )
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
m_pSite->_TLSLock();
}
else if (ulFlags & HX_WAIT_NEVER)
{
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
else
{
//XXXgfw Removing a noisy assert for now. It appears that
//NVidea GForce 2 MX 100/200 cards will fail to lock a surface
//while resizing a video. This failure does not lead to video
//artifacts or any other visible problems. However, with the
//assert it makes it nearly impossible to debug.
//HX_ASSERT(!bLockTLSMutex && (ulFlags & HX_WAIT_FOREVER));
// Some "error" is preventing us from locking the surface
ReleaseMutex(m_hSurfaceMutex);
return HXR_BUFFER_NOT_AVAILABLE;
}
// Use system mem if selected
if (m_bUseSysMemSurface)
{
hr = LockSysMemSurface(pVidMem, nPitch, (ulFlags & HX_WAIT_NEVER) != HX_WAIT_NEVER);
if (HXR_OK == hr)
{
//m_bmi.biCompression = m_nSysMemSurfID;
m_bmi.biWidth = m_allocatedSysMemSurfSize.cx;
m_bmi.biHeight = m_allocatedSysMemSurfSize.cy;
*bmi = m_bmi;
bmi->biCompression = m_nSysMemSurfID;
}
}
// If DD is not avail, use rgb blts
else if (nBltMode == HX_BASIC_BLT)
{
hr = LockGdiSurface(pVidMem, nPitch, (ulFlags & HX_WAIT_NEVER) != HX_WAIT_NEVER);
if (HXR_OK == hr)
{
MakeBitmap((LPBITMAPINFO)&m_bmi, sizeof(BMI), m_nGdiSurfaceCID,
m_allocatedGdiSize.cx, m_allocatedGdiSize.cy, NULL, NULL);
*bmi = m_bmi;
m_bmiLastBlt = m_bmi;
}
else if (DDERR_WRONGMODE == hr)
{
HandleDisplayModeChange();
}
}
// If overlay is not enabled, use offscreen memory
else if (nBltMode == HX_BLT_YUV_STRETCH)
{
hr = LockFallbackSurface(pVidMem, nPitch, (ulFlags & HX_WAIT_NEVER) != HX_WAIT_NEVER);
if (HXR_OK == hr)
{
m_nScratchIndex = nIndex;
MakeBitmap((LPBITMAPINFO)&m_bmi, sizeof(BMI), m_nFallbackSurfaceCID,
m_allocatedFallbackSize.cx, m_allocatedFallbackSize.cy, NULL, NULL);
*bmi = m_bmi;
m_bmiLastBlt = m_bmi;
// Restore thread priority
if (m_nLastBltMode == HX_BASIC_BLT && m_bBoostRenderThread)
SetThreadPriority(m_hRenThread, THREAD_PRIORITY_TIME_CRITICAL);
}
else if (DDERR_WRONGMODE == hr)
{
HandleDisplayModeChange();
}
// Check if we lost DirectDraw
else
{
if (HandleDirectDrawLoss(bLockTLSMutex))
{
if (bLockTLSMutex)
bLockTLSMutex = FALSE;
goto LOCK_VIDEO_BUFFER;
}
}
}
else
{
CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
WINDRAW* pWindraw = pSurface->GetWinDraw();
hr = WinDraw_GetLockedSurface(pWindraw, &m_surface, pVidMem, nIndex,
(ulFlags & HX_WAIT_NEVER) != HX_WAIT_NEVER);
if (pVidMem)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -