📄 winsurf2.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: winsurf2.cpp,v 1.23.2.2 2004/07/26 10:28:48 pankajgupta Exp $ * * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (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. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * 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 "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_FILEstatic 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 10000ULONG32 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 10000double 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;}void CWinSurface2::_CreateBuffer(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -