📄 winsurf2.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#include <math.h>
#include "ddraw.h"
#include "hxcom.h"
#include "hxmtypes.h"
#include "hxwintyp.h"
#include "hxvsurf.h"
#include "hxslist.h"
#include "ddhlpr.h"
#include "winsurf.h"
#include "vidsurf2.h"
#include "winsurf2.h"
#include "winsite.h"
#include "colormap.h"
#include "windraw2.h"
#include "hxprefs.h"
#include "hxtick.h"
#include "hxheap.h"
#include "hxevent.h"
#include "hwmemobj.h"
// these are defined in basesurf.cpp and should probably be moved to a .h file
#define HX_OVER_KEYDEST 1
#define HX_OVER_HIDE 2
#define HX_OVER_SHOW 4
#define OVERLAY_NOT_VISIBLE 0
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#include "winthrd.h"
#endif
#define OS_THREAD_QUANTUM 10
#define MAX_PREEMPTION_CHECK_ATTEMPTS 3
#define TIME_JITTER_FILTER_THRESHOLD 0.45
#define MIN_ALLOWED_REGRESSION 0.95
//#define HARDCODE_GRANULE
#define SCHEDULE_GRANULE 5
//#define LOG_JITTER_DATA
#define JITTER_LOG_FILE "c:\\temp\\ts.txt"
/****************************************************************************
* Debug
*/
//#define ENABLE_SYNC_TRACE
#ifdef ENABLE_SYNC_TRACE
#define MAX_SYNC_TRACE_ENTRIES 10000
ULONG32 ulSyncTraceIdx = 0;
double syncTraceArray[MAX_SYNC_TRACE_ENTRIES][3];
void DumpSyncEntries(void)
{
FILE* pFile = NULL;
ULONG32 ulIdx;
if (ulSyncTraceIdx > 0)
{
pFile = fopen("/tmp/getscanline.txt", "wb"); /* Flawfinder: ignore */
}
if (pFile)
{
for (ulIdx = 0; ulIdx < (ulSyncTraceIdx < MAX_SYNC_TRACE_ENTRIES ?
ulSyncTraceIdx : MAX_SYNC_TRACE_ENTRIES); ulIdx++)
{
fprintf(pFile, "%lf\t%lf\t%lf\n", syncTraceArray[ulIdx][0],
syncTraceArray[ulIdx][1],
syncTraceArray[ulIdx][2]
);
}
fclose(pFile);
}
ulSyncTraceIdx = 0;
}
#endif // ENABLE_SYNC_TRACE
//#define ENABLE_ERROR_TRACE
#ifdef ENABLE_ERROR_TRACE
#define MAX_ERROR_TRACE_ENTRIES 10000
double g_error[MAX_ERROR_TRACE_ENTRIES][3];
double g_alternateError[MAX_ERROR_TRACE_ENTRIES];
ULONG32 g_ulFrameCount;
UINT32 g_sleepError[MAX_ERROR_TRACE_ENTRIES];
ULONG32 g_ulSleepCount;
void DumpErrorEntries(void)
{
FILE* pFile = NULL;
ULONG32 ulIdx;
if (g_ulFrameCount > 0)
{
pFile = fopen("/tmp/vblankerror.txt", "wb"); /* Flawfinder: ignore */
}
if (pFile)
{
for (ulIdx = 0; ulIdx < (g_ulFrameCount < MAX_SYNC_TRACE_ENTRIES ?
g_ulFrameCount : MAX_SYNC_TRACE_ENTRIES); ulIdx++)
{
fprintf(pFile, "%lf\t%lf\t%lf\n", g_error[ulIdx][0],
g_error[ulIdx][1],
g_error[ulIdx][2]);
}
fclose(pFile);
}
g_ulFrameCount = 0;
}
#endif // ENABLE_ERROR_TRACE
// Using "this" in constructor initialzer
#pragma warning(disable:4355)
CWinSurface2::CWinSurface2(IUnknown* pContext, CHXBaseSite* pSite)
: CWinSurface(pContext,pSite)
, CVideoSurface2((IUnknown*)(IHXVideoSurface*)this)
, m_hRenThread(0)
, m_hFrameSem(0)
, m_hReinit(0)
, m_hAbort(0)
, m_hForceRender(0)
, m_hSurfaceMutex(0)
, m_bCont(FALSE)
, m_bBoostRenderThread(TRUE)
, m_bDoAlphaCheck(TRUE)
, m_bQueryMonitorFreq(FALSE)
, m_bUseVBlankFlip(TRUE)
, m_bIngnorePresentIfReady(FALSE)
, m_bScratchSurface(FALSE)
, m_bGDISurface(FALSE)
, m_nScratchIndex(0)
, m_nLastDisplayTime(0)
, m_pListOfFrames(NULL)
, m_pTimeLine(NULL)
, m_hFallbackEmpty(0)
, m_nFallbackSurfaceCID(0)
, m_bFallbackSurfaceCreated(FALSE)
, m_pSysMemSurf(NULL)
, m_nSysMemSurfSize(0)
, m_nSysMemSurfCount(0)
, m_nSysMemSurfPitch(0)
, m_nSysMemSurfID(0)
, m_nNextSysMemBuffer(0)
, m_bUseSysMemSurface(FALSE)
, m_nGdiSurfaceCount(0)
, m_nLastGdiSurface(-1)
, m_nNextGdiSurface(0)
, m_nGdiSurfaceCID(0)
, m_bGdiSurfaceCreated(FALSE)
, m_ulFillColoryKeyCount(0)
, m_bFlushing(FALSE)
, m_bFrameHasHWAlphaBlend(FALSE)
, m_bSurfaceRequiresOverlay(FALSE)
, m_bSwitchingingOverlay(FALSE)
, m_bUseDDColorControls(FALSE)
, m_bWaitingForFlush(FALSE)
, m_bWasInVidSurf2(FALSE)
, m_dLastXScale(0.0)
, m_dLastYScale(0.0)
, m_nOverlayBackBuffersCreated(0)
, m_dLastBlitError(0)
{
// initialize data so we don't have invalid ptrs floating around.
memset(&m_surface,0,sizeof(m_surface));
memset(&m_GDIsurface,0,sizeof(m_GDIsurface));
memset(&m_fallbackSurface,0,sizeof(m_fallbackSurface));
memset(&m_allocatedFallbackSize, 0, sizeof(m_allocatedFallbackSize));
memset(&m_allocatedSysMemSurfSize, 0, sizeof(m_allocatedSysMemSurfSize));
memset(&m_allocatedFallbackSize, 0, sizeof(m_allocatedFallbackSize));
memset(&m_rcLast, 0, sizeof(m_rcLast));
InitializeCriticalSection(&m_csDisplay);
InitializeCriticalSection(&m_csFallback);
InitializeCriticalSection(&m_csList);
InitializeCriticalSection(&m_csScale);
m_hAbort = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hForceRender = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hReinit = CreateEvent(NULL, TRUE, TRUE, NULL);
m_hFallbackEmpty = CreateEvent(NULL, TRUE, TRUE, NULL);
m_hSurfaceMutex = CreateMutex(NULL, FALSE, NULL);
m_pListOfFrames = new CHXSimpleList;
// Read some preferences
IHXPreferences* pPreferences = NULL;
IHXBuffer* pBuffer = NULL;
if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,(void**)&pPreferences))
{
// Use vblank flags for flipping
if (pPreferences->ReadPref("VideoBoost\\DisableVBlankFlip", pBuffer) == HXR_OK)
{
m_bUseVBlankFlip = !(::atoi((char*) pBuffer->GetBuffer()) == 1);
}
HX_RELEASE(pBuffer);
// Turn-off render thread priority boosting
if (pPreferences->ReadPref("VideoBoost\\DisablePriorityBoost", pBuffer) == HXR_OK)
{
m_bBoostRenderThread = !(::atoi((char*) pBuffer->GetBuffer()) == 1);
}
HX_RELEASE(pBuffer);
// Limit number of hw buffers
if (pPreferences->ReadPref("VideoBoost\\MaxBuffers", pBuffer) == HXR_OK)
{
m_nMaxBackBuffers = ::atoi((char*) pBuffer->GetBuffer()) - 1;
m_nMaxBackBuffers = max(1, m_nMaxBackBuffers);
}
HX_RELEASE(pBuffer);
}
HX_RELEASE(pPreferences);
}
CWinSurface2::~CWinSurface2()
{
if (m_hRenThread)
{
m_bCont = FALSE;
SetEvent(m_hAbort);
WaitForSingleObject(m_hRenThread, INFINITE);
CloseHandle(m_hFrameSem);
m_hFrameSem = 0;
CloseHandle(m_hRenThread);
m_hRenThread = 0;
DestroyFallbackSurface();
DestroySysMemSurface();
DestroyGdiSurface();
}
if (m_hAbort)
{
CloseHandle(m_hAbort);
m_hAbort = 0;
}
if (m_hForceRender)
{
CloseHandle(m_hForceRender);
m_hForceRender = 0;
}
if (m_hReinit)
{
CloseHandle(m_hReinit);
m_hReinit = 0;
}
if (m_hFallbackEmpty)
{
CloseHandle(m_hFallbackEmpty);
m_hFallbackEmpty = NULL;
}
if (m_hSurfaceMutex)
{
CloseHandle(m_hSurfaceMutex);
m_hSurfaceMutex = 0;
}
HX_DELETE(m_pListOfFrames);
DeleteCriticalSection(&m_csDisplay);
DeleteCriticalSection(&m_csFallback);
DeleteCriticalSection(&m_csList);
DeleteCriticalSection(&m_csScale);
HX_RELEASE(m_pTimeLine);
}
STDMETHODIMP CWinSurface2::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IHXVideoSurface2))
{
return CVideoSurface2::QueryInterface(riid, ppvObj);
}
return CWinSurface::QueryInterface(riid, ppvObj);
}
STDMETHODIMP_(ULONG32) CWinSurface2::AddRef()
{
return CWinSurface::AddRef();
}
STDMETHODIMP_(ULONG32) CWinSurface2::Release()
{
return CWinSurface::Release();
}
STDMETHODIMP CWinSurface2::BeginOptimizedBlt(HXBitmapInfoHeader* pBitmapInfo)
{
if (m_bWasInVidSurf2 &&
pBitmapInfo &&
m_pOptimizedFormat)
{
// Are the new parameters the same as the old paramaters? If not
// then delete the old surfaces.
if (pBitmapInfo->biWidth != m_pOptimizedFormat->biWidth ||
pBitmapInfo->biHeight != m_pOptimizedFormat->biHeight ||
pBitmapInfo->biPlanes != m_pOptimizedFormat->biPlanes ||
pBitmapInfo->biBitCount != m_pOptimizedFormat->biBitCount ||
pBitmapInfo->biCompression != m_pOptimizedFormat->biCompression ||
m_bWasInVidSurf2)
{
if (m_bWasInVidSurf2)
_WaitForFlush();
DestroySurfaces();
if (m_bWasInVidSurf2)
{
m_bVideoSurface2 = FALSE;
m_bFlipOverlay = FALSE;
m_nBackBufferCount = 0;
}
}
}
return CWinSurface::BeginOptimizedBlt(pBitmapInfo);
}
STDMETHODIMP CWinSurface2::Blt( UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) rDestRect,
REF(HXxRect) rSrcRect)
{
m_pSite->_TLSLock();
// Handle VS2->VS1 transions
if (m_bWasInVidSurf2)
{
if (!m_pSite->_BordersActive() &&
!m_pSite->_FadeTransitionActive() &&
(!m_pSite->AreVideoControlsActive() || m_bUseDDColorControls) &&
!m_pSite->IsHigherZOrderTranstitionActive() &&
m_pSite->m_pUser && !m_LinkedSites.GetCount() &&
!m_pLinkedOverlay)
{
HXxEvent event = {HX_SURFACE_MODE_CHANGE, NULL, NULL,
(void*)HX_VIDEOSURFACE1_NOT_RECOMMENDED, 0, 0};
m_bWasInVidSurf2 = FALSE;
// If we just turned off color controls inform the color converter
m_pSite->CheckColorSettings();
m_pSite->m_pUser->HandleEvent(&event);
// The renderer switched to VideoSurface1 so don't give them a buffer
if (event.handled)
{
m_pSite->_TLSUnlock();
return HXR_FAIL;
}
else
m_bWasInVidSurf2 = TRUE;
}
else if (m_bVideoSurface2)
{
m_pSite->_TLSUnlock();
_WaitForFlush();
m_bVideoSurface2 = FALSE;
m_pSite->_TLSLock();
}
}
HX_RESULT hr = CWinSurface::Blt(pImageData, pBitmapInfo, rDestRect, rSrcRect);
m_pSite->_TLSUnlock();
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -