📄 winsurf2.cpp
字号:
{
nPitch = m_surface.dd.lPitch;
MakeBitmap((LPBITMAPINFO)&m_bmi, sizeof(BMI), m_nSurfaceCID,
m_surfaceSize.cx, m_surfaceSize.cy, NULL, NULL);
*bmi = m_bmi;
m_bmiLastBlt = m_bmi;
if (m_pHwMemObj)
{
pVidMem = (UCHAR*)m_pHwMemObj->DeviceToRenderer(pVidMem, nPitch);
}
// Restore thread priority
if (m_nLastBltMode == HX_BASIC_BLT && m_bBoostRenderThread)
SetThreadPriority(m_hRenThread, THREAD_PRIORITY_TIME_CRITICAL);
}
// If the display mode was changed on us, destory and recreate the surfaces
else if (DDERR_WRONGMODE == hr)
{
HandleDisplayModeChange();
}
// Could not lock a surface
else if (DDERR_WASSTILLDRAWING == hr)
{
hr = HXR_BUFFER_NOT_AVAILABLE;
}
// Check if we lost DirectDraw
else
{
if (HandleDirectDrawLoss(bLockTLSMutex))
{
if (bLockTLSMutex)
bLockTLSMutex = FALSE;
goto LOCK_VIDEO_BUFFER;
}
else
{
// Turn off overlay
m_bMultipleOverlay = TRUE;
if (bLockTLSMutex)
m_pSite->_TLSUnlock();
goto LOCK_VIDEO_BUFFER;
}
}
}
if (HXR_OK == hr)
{
// TLS mutex should be locked here...
HX_ASSERT(bLockTLSMutex);
// Since RGB formats are not supported in MapFourCCtoCID,
// store the CID in biCompression.
if (!IsYUV(MapFourCCtoCID(m_bmi.biCompression)))
{
bmi->biCompression = GetBitmapColor((LPBITMAPINFO)&m_bmi);
}
// Do we need an alpha blending region
if (m_bDoAlphaCheck && !m_pHwMemObj)
{
CreateAlphaList(pVidStruct);
}
pVidStruct->pVidMem = pVidMem;
pVidStruct->lPitch = nPitch;
}
else
{
// Did not lock a surface
ReleaseMutex(m_hSurfaceMutex);
hr = HXR_FAIL;
if (bLockTLSMutex)
{
m_pSite->_TLSUnlock();
}
}
return hr;
}
STDMETHODIMP CWinSurface2::ColorConvert(INT32 fourCCIn,
HXxSize *pSrcSize,
HXxRect *prSrcRect,
SourceInputStruct *pInput,
INT32 fourCCOut,
UCHAR *pDestBuffer,
HXxSize *pDestSize,
HXxRect *prDestRect,
int nDestPitch)
{
// If the dest surface is a normal buffer, perform the transfer
if (!IsStructured(MapFourCCtoCID(fourCCOut)))
return CVideoSurface2::ColorConvert(fourCCIn, pSrcSize, prSrcRect,
pInput, fourCCOut, pDestBuffer,
pDestSize, prDestRect, nDestPitch);
// Handle this proprietary surface write
HX_ASSERT(m_pHwMemObj);
m_pHwMemObj->ProcessCommand((UCHAR*)pInput,
fourCCIn,
pSrcSize,
prSrcRect,
pDestBuffer,
fourCCOut,
pDestSize,
prDestRect);
// Need to set pItem->bAlpha if we blended the frame!!!
if (m_pHwMemObj->QueryOperation() & PERFORMED_HW_ALPHA_BLEND)
{
m_bFrameHasHWAlphaBlend = TRUE;
}
if (m_bUseDDColorControls)
{
m_pSite->CheckColorSettings();
// Did color controls change
float fBright = m_pSite->GetBrightness();
float fContrast = m_pSite->GetContrast();
float fSaturation = m_pSite->GetSaturation();
float fHue = m_pSite->GetHue();
float fSharpness = m_pSite->GetSharpness();
if (m_Brightness != fBright ||
m_Contrast != fContrast ||
m_Saturation != fSaturation ||
m_Hue != fHue ||
m_Sharpness != fSharpness)
{
CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
WINDRAW* pWindraw = pSurface->GetWinDraw();
// Change DD color controls
WinDrawSurface_SetColorControls(pWindraw,
&m_surface,
fBright,
fContrast,
fSaturation,
fHue,
fSharpness);
m_Brightness = fBright;
m_Contrast = fContrast;
m_Saturation = fSaturation;
m_Hue = fHue;
m_Sharpness = fSharpness;
}
}
return HXR_OK;
}
BOOL CWinSurface2::CanLockSurface(INT32 nIndex, int nBltMode, BOOL bBlock)
{
UCHAR* pVidMem;
HRESULT hr = HXR_FAIL;
if (m_bUseSysMemSurface)
{
if (m_pSysMemSurf)
{
if (bBlock)
{
HANDLE aWait[2] = {m_pSysMemSurf[m_nNextSysMemBuffer].hEmpty, m_hAbort};
hr = WaitForMultipleObjects(2, aWait, FALSE, INFINITE);
}
else
hr = WaitForSingleObject(m_pSysMemSurf[m_nNextSysMemBuffer].hEmpty, 0);
if (WAIT_OBJECT_0 == hr)
hr = HXR_OK;
}
else
hr = HXR_OK;
}
// If DD is not avail, use rgb blts
else if (HX_BASIC_BLT == nBltMode)
{
if (m_bGdiSurfaceCreated)
{
if (bBlock)
{
HANDLE aWait[2] = {m_GDIsurface.gdi.lpGDIBackBuffer[m_nNextGdiSurface]->hEmpty, m_hAbort};
hr = WaitForMultipleObjects(2, aWait, FALSE, INFINITE);
}
else
hr = WaitForSingleObject(m_GDIsurface.gdi.lpGDIBackBuffer[m_nNextGdiSurface]->hEmpty, 0);
if (WAIT_OBJECT_0 == hr)
hr = HXR_OK;
}
else
hr = HXR_OK;
}
else if (HX_BLT_YUV_STRETCH == nBltMode)
{
if (bBlock)
{
HANDLE aObjects[2] = {m_hFallbackEmpty, m_hAbort};
hr = WaitForMultipleObjects(2, aObjects, FALSE, INFINITE);
}
else
hr = WaitForSingleObject(m_hFallbackEmpty, 0);
if (WAIT_OBJECT_0 == hr)
hr = HXR_OK;
}
else
{
CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
WINDRAW* pWindraw = pSurface->GetWinDraw();
int nNextIndex = nIndex;
hr = WinDraw_CanLockSurface(pWindraw, &m_surface, pVidMem, nNextIndex, bBlock);
}
if (hr == HXR_OK)
return TRUE;
else
return FALSE;
}
STDMETHODIMP CWinSurface2::ReleaseVideoMem(VideoMemStruct* pVidStruct)
{
return ReleaseSurface(pVidStruct, TRUE);
}
STDMETHODIMP CWinSurface2::Present(VideoMemStruct *pVidStruct,
INT32 lTime,
UINT32 ulFlags,
HXxRect *prDestRect,
HXxRect *prSrcRect)
{
//#define _DEBUG_TIMEAHEAD
#ifdef _DEBUG_TIMEAHEAD
UINT32 ulCurrentTime;
HRESULT timelineResult = m_pTimeLine->GetTimeLineValue(ulCurrentTime);
static INT32 lMaxQueueAhead = 0;
if ((timelineResult != HXR_TIMELINE_SUSPENDED)
&& (lTime - (INT32) ulCurrentTime) > lMaxQueueAhead)
{
lMaxQueueAhead = lTime - (INT32) ulCurrentTime;
HX_TRACE("New max queue ahead: %d", lMaxQueueAhead);
}
#endif // _DEBUG_TIMEAHEAD
if (m_bWasInVidSurf2)
return HXR_FAIL;
m_pSite->m_bBltHasBeenCalled = TRUE;
if (ulFlags & HX_MODE_IMMEDIATE)
{
if (m_pListOfFrames->GetCount())
return HXR_FAIL;
else if( (HXEmptyRegion(m_pSite->m_Region) && !pVidStruct->ulCount && !m_bFrameHasHWAlphaBlend)
|| !m_pSite->IsSiteVisible())
return HXR_COULD_NOT_DISPLAY;
else
{
lTime = 0;
}
}
else if (ulFlags & HX_MODE_REFRESH)
{
HRESULT hr = HXR_FAIL;
// We do not have a visible region so we can not refresh
if( (HXEmptyRegion(m_pSite->m_Region) ) || !m_pSite->IsSiteVisible())
return HXR_COULD_NOT_DISPLAY;
// We have not displayed a frame yet so we can not refresh
else if (HX_NO_BLT == m_nLastBltMode)
return HXR_COULD_NOT_DISPLAY;
// If we are waiting on a surface re-init, fail
else if (WAIT_OBJECT_0 != WaitForSingleObject(m_hReinit, 0))
return HXR_BUFFER_NOT_AVAILABLE;
else if (HX_OVERLAY_BLT == m_nLastBltMode)
{
// Need to lose overlay...so fail the refresh
if ((IsShrinking() && !_AllowsOverlayShrinking()) ||
m_bMultipleOverlay)
return HXR_FAIL;
}
else if (HX_BLT_YUV_STRETCH == m_nLastBltMode)
{
// Need to restore overlay...so fail the refresh
if ((!IsShrinking() || _AllowsOverlayShrinking()) &&
!m_bMultipleOverlay)
return HXR_FAIL;
}
int nNumRects = 0;
HXxRect* paSrcRects = NULL;
HXxRect* paDestRects = NULL;
// Try to display a queued frame
if (m_pListOfFrames->GetCount())
{
hr = PresentIfReady();
}
if (hr != HXR_OK)
{
CWinBaseRootSurface *pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
if (!pSurface)
return HXR_FAIL;
WINDRAW *pWindraw = pSurface->GetWinDraw();
// If no dest rect is specified, use surface
if (!prDestRect->right && !prDestRect->bottom)
{
HXxSize rcSize = {0,0};
m_pSite->GetSize(rcSize);
prDestRect->right = rcSize.cx;
prDestRect->bottom = rcSize.cy;
}
// Refresh the last rgb image
//if (m_bLostHWAcceleration)
if (HX_BASIC_BLT == m_nLastBltMode)
{
// Do we have a gdi surface to refresh
if (m_nLastGdiSurface >= 0)
{
// If no src rect is specified, use surface
if (!prSrcRect->right && !prSrcRect->bottom)
{
prSrcRect->right = m_allocatedGdiSize.cx;
prSrcRect->bottom = m_allocatedGdiSize.cy;
}
SetLastScale(prSrcRect, prDestRect);
_ConstructRects( *prSrcRect,
*prDestRect,
FALSE,
nNumRects,
&paSrcRects,
&paDestRects);
memcpy(&m_lastSrcRect, paSrcRects, sizeof(*paSrcRects)); /* Flawfinder: ignore */
// Do an rgb blt for each display rect
for( int j=0 ; j<nNumRects ; j++ )
{
hr = WinDrawSurface_Blt(pWindraw, &m_GDIsurface, (RECT*)&paDestRects[j], (RECT*)&paSrcRects[j], m_nLastGdiSurface);
}
HX_VECTOR_DELETE(paSrcRects);
HX_VECTOR_DELETE(paDestRects);
}
}
// If we have a visible overlay, update it
else if (WinDraw2_IsSurfaceVisible(pWindraw, &m_surface) && !m_bYUVBlending)
{
// If no src rect is specified, use surface
if (!prSrcRect->right && !prSrcRect->bottom)
{
prSrcRect->right = m_surfaceSize.cx;
prSrcRect->bottom = m_surfaceSize.cy;
}
SetLastScale(prSrcRect, prDestRect);
_ConstructRects( *prSrcRect,
*prDestRect,
FALSE,
nNumRects,
&paSrcRects,
&paDestRects);
if (nNumRects != 1)
{
HXxPoint screenOffset = m_pSite->GetScreenOffset();
paSrcRects[0] = *prSrcRect;
paDestRects[0] = *prDestRect;
paSrcRects[0].left += screenOffset.x;
paSrcRects[0].top += screenOffset.y;
paSrcRects[0].right += screenOffset.x;
paSrcRects[0].bottom += screenOffset.y;
}
hr = ForceUpdateOverlay( &paDestRects[0],
&paSrcRects[0], HX_OVER_SHOW|HX_OVER_KEYDEST);
if (HX_NO_BLT == m_nLastBltMode)
hr = HXR_FAIL;
else
{
memcpy(&m_lastSrcRect, paSrcRects, sizeof(*paSrcRects)); /* Flawfinder: ignore */
if (hr == HXR_OK)
{
if (m_bNeedColorKeyFilled && m_pSite->IsSiteVisible())
{
_FillColorKey();
}
}
}
HX_VECTOR_DELETE(paSrcRects);
HX_VECTOR_DELETE(paDestRects);
#if !defined(_GOLD) && 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -