Welcome to mirror list, hosted at ThFree Co, Russian Federation.

DX9AllocatorPresenter.h « VideoRenderers « renderer « filters « src - github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ab98e85d403b1fe26e7dbcfe14232a3e6623be25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*
 * $Id$
 *
 * (C) 2003-2006 Gabest
 * (C) 2006-2010 see AUTHORS
 *
 * This file is part of mplayerc.
 *
 * Mplayerc is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Mplayerc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include "DX9RenderingEngine.h"

#define VMRBITMAP_UPDATE			0x80000000

#define NB_JITTER					126

extern bool g_bNoDuration;
extern bool g_bExternalSubtitleTime;

namespace DSObjects
{

class CDX9AllocatorPresenter
	: public CDX9RenderingEngine
{
public:
	CCritSec				m_VMR9AlphaBitmapLock;
	void					UpdateAlphaBitmap();
protected:
	UINT	m_RefreshRate;

//		bool	m_fVMRSyncFix;
	bool	m_bAlternativeVSync;
	bool	m_bCompositionEnabled;
	bool	m_bIsEVR;
	int		m_OrderedPaint;
	int		m_VSyncMode;
	bool	m_bDesktopCompositionDisabled;
	bool	m_bIsFullscreen;
	bool	m_bNeedCheckSample;
	DWORD	m_MainThreadId;

	CRenderersSettings::CRendererSettingsEVR m_LastRendererSettings;

	HRESULT (__stdcall * m_pDwmIsCompositionEnabled)(__out BOOL* pfEnabled);
	HRESULT (__stdcall * m_pDwmEnableComposition)(UINT uCompositionAction);

	HMODULE m_hDWMAPI;

	HRESULT (__stdcall * m_pDirect3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex**);
	HMODULE m_hD3D9;

	CCritSec					m_RenderLock;
	CComPtr<IDirectDraw>		m_pDirectDraw;

	CComPtr<IDirect3D9Ex>		m_pD3DEx;
	CComPtr<IDirect3D9>			m_pD3D;
	CComPtr<IDirect3DDevice9Ex>	m_pD3DDevEx;

	void LockD3DDevice()
	{
		if (m_pD3DDev)
		{
			_RTL_CRITICAL_SECTION *pCritSec = (_RTL_CRITICAL_SECTION *)((size_t)m_pD3DDev.p + sizeof(size_t));

			if (!IsBadReadPtr(pCritSec, sizeof(*pCritSec)) && !IsBadWritePtr(pCritSec, sizeof(*pCritSec))
					&& !IsBadReadPtr(pCritSec->DebugInfo, sizeof(*(pCritSec->DebugInfo))) && !IsBadWritePtr(pCritSec->DebugInfo, sizeof(*(pCritSec->DebugInfo))))
			{
				if (pCritSec->DebugInfo->CriticalSection == pCritSec)
					EnterCriticalSection(pCritSec);
			}
		}
	}

	void UnlockD3DDevice()
	{
		if (m_pD3DDev)
		{
			_RTL_CRITICAL_SECTION *pCritSec = (_RTL_CRITICAL_SECTION *)((size_t)m_pD3DDev.p + sizeof(size_t));

			if (!IsBadReadPtr(pCritSec, sizeof(*pCritSec)) && !IsBadWritePtr(pCritSec, sizeof(*pCritSec))
					&& !IsBadReadPtr(pCritSec->DebugInfo, sizeof(*(pCritSec->DebugInfo))) && !IsBadWritePtr(pCritSec->DebugInfo, sizeof(*(pCritSec->DebugInfo))))
			{
				if (pCritSec->DebugInfo->CriticalSection == pCritSec)
					LeaveCriticalSection(pCritSec);
			}
		}
	}

	CString m_D3DDevExError;
	CComPtr<IDirect3DTexture9>		m_pOSDTexture;
	CComPtr<IDirect3DSurface9>		m_pOSDSurface;
	CComPtr<ID3DXLine>				m_pLine;
	CComPtr<ID3DXFont>				m_pFont;
	CComPtr<ID3DXSprite>			m_pSprite;

	bool SettingsNeedResetDevice();

	virtual HRESULT CreateDevice(CString &_Error);
	virtual HRESULT AllocSurfaces(D3DFORMAT Format = D3DFMT_A8R8G8B8);
	virtual void DeleteSurfaces();

	// Thread stuff
	HANDLE			m_hEvtQuit;			// Stop rendering thread event
	HANDLE			m_hVSyncThread;
	static DWORD WINAPI VSyncThreadStatic(LPVOID lpParam);
	void VSyncThread();
	void StartWorkerThreads();
	void StopWorkerThreads();

	LONGLONG		m_LastAdapterCheck;
	UINT			m_CurrentAdapter;
	UINT GetAdapter(IDirect3D9 *pD3D, bool GetAdapter = false);
	DWORD GetVertexProcessing();

	bool GetVBlank(int &_ScanLine, int &_bInVBlank, bool _bMeasureTime);
	bool WaitForVBlankRange(int &_RasterStart, int _RasterEnd, bool _bWaitIfInside, bool _bNeedAccurate, bool _bMeasure, bool &_bTakenLock);
	bool WaitForVBlank(bool &_Waited, bool &_bTakenLock);
	int GetVBlackPos();
	void CalculateJitter(LONGLONG PerformanceCounter);
	virtual void OnVBlankFinished(bool fAll, LONGLONG PerformanceCounter) {}

	// Casimir666
	typedef HRESULT (WINAPI * D3DXLoadSurfaceFromMemoryPtr)(
		LPDIRECT3DSURFACE9	pDestSurface,
		CONST PALETTEENTRY*	pDestPalette,
		CONST RECT*		pDestRect,
		LPCVOID			pSrcMemory,
		D3DFORMAT		SrcFormat,
		UINT			SrcPitch,
		CONST PALETTEENTRY*	pSrcPalette,
		CONST RECT*		pSrcRect,
		DWORD			Filter,
		D3DCOLOR		ColorKey);

	typedef HRESULT (WINAPI* D3DXCreateLinePtr) (LPDIRECT3DDEVICE9   pDevice, LPD3DXLINE* ppLine);

	typedef HRESULT (WINAPI* D3DXCreateFontPtr)(
		LPDIRECT3DDEVICE9	pDevice,
		int				Height,
		UINT			Width,
		UINT			Weight,
		UINT			MipLevels,
		bool			Italic,
		DWORD			CharSet,
		DWORD			OutputPrecision,
		DWORD			Quality,
		DWORD			PitchAndFamily,
		LPCWSTR			pFaceName,
		LPD3DXFONT*		ppFont);


	void				DrawText(const RECT &rc, const CString &strText, int _Priority);
	void				DrawStats();
	virtual void		OnResetDevice() {};
	void				SendResetRequest();

	double GetFrameTime();
	double GetFrameRate();


	int						m_nTearingPos;
	VMR9AlphaBitmap			m_VMR9AlphaBitmap;
	CAutoVectorPtr<BYTE>	m_VMR9AlphaBitmapData;
	CRect					m_VMR9AlphaBitmapRect;
	int						m_VMR9AlphaBitmapWidthBytes;

	D3DXLoadSurfaceFromMemoryPtr	m_pD3DXLoadSurfaceFromMemory;
	D3DXCreateLinePtr		m_pD3DXCreateLine;
	D3DXCreateFontPtr		m_pD3DXCreateFont;
	HRESULT (__stdcall *m_pD3DXCreateSprite)(LPDIRECT3DDEVICE9 pDevice, LPD3DXSPRITE * ppSprite);



	int						m_nVMR9Surfaces;				// Total number of DX Surfaces
	int						m_iVMR9Surface;
	long					m_nUsedBuffer;

	double					m_fAvrFps;						// Estimate the real FPS
	double					m_fJitterStdDev;				// Estimate the Jitter std dev
	double					m_fJitterMean;
	double					m_fSyncOffsetStdDev;
	double					m_fSyncOffsetAvr;
	double					m_DetectedRefreshRate;

	CCritSec				m_RefreshRateLock;
	double					m_DetectedRefreshTime;
	double					m_DetectedRefreshTimePrim;
	double					m_DetectedScanlineTime;
	double					m_DetectedScanlineTimePrim;
	double					m_DetectedScanlinesPerFrame;

	bool SetCurrentDisplayMode();

	double GetRefreshRate()
	{
		if (m_DetectedRefreshRate)
			return m_DetectedRefreshRate;
		return m_RefreshRate;
	}

	LONG GetScanLines()
	{
		if (m_DetectedRefreshRate)
			return m_DetectedScanlinesPerFrame;
		return m_ScreenSize.cy;
	}

	double					m_ldDetectedRefreshRateList[100];
	double					m_ldDetectedScanlineRateList[100];
	int						m_DetectedRefreshRatePos;
	bool					m_bSyncStatsAvailable;
	LONGLONG				m_pllJitter [NB_JITTER];			// Jitter buffer for stats
	LONGLONG				m_pllSyncOffset [NB_JITTER];		// Jitter buffer for stats
	LONGLONG				m_llLastPerf;
	LONGLONG				m_JitterStdDev;
	LONGLONG				m_MaxJitter;
	LONGLONG				m_MinJitter;
	LONGLONG				m_MaxSyncOffset;
	LONGLONG				m_MinSyncOffset;
	int						m_nNextJitter;
	int						m_nNextSyncOffset;
	REFERENCE_TIME			m_rtTimePerFrame;
	double					m_DetectedFrameRate;
	double					m_DetectedFrameTime;
	double					m_DetectedFrameTimeStdDev;
	bool					m_DetectedLock;
	LONGLONG				m_DetectedFrameTimeHistory[60];
	double					m_DetectedFrameTimeHistoryHistory[500];
	int						m_DetectedFrameTimePos;
	int						m_bInterlaced;

	double					m_TextScale;

	int						m_VBlankEndWait;
	int						m_VBlankStartWait;
	LONGLONG				m_VBlankWaitTime;
	LONGLONG				m_VBlankLockTime;
	int						m_VBlankMin;
	int						m_VBlankMinCalc;
	int						m_VBlankMax;
	int						m_VBlankEndPresent;
	LONGLONG				m_VBlankStartMeasureTime;
	int						m_VBlankStartMeasure;

	LONGLONG				m_PresentWaitTime;
	LONGLONG				m_PresentWaitTimeMin;
	LONGLONG				m_PresentWaitTimeMax;

	LONGLONG				m_PaintTime;
	LONGLONG				m_PaintTimeMin;
	LONGLONG				m_PaintTimeMax;

	LONGLONG				m_WaitForGPUTime;

	LONGLONG				m_RasterStatusWaitTime;
	LONGLONG				m_RasterStatusWaitTimeMin;
	LONGLONG				m_RasterStatusWaitTimeMax;
	LONGLONG				m_RasterStatusWaitTimeMaxCalc;

	double					m_ClockDiffCalc;
	double					m_ClockDiffPrim;
	double					m_ClockDiff;

	double					m_TimeChangeHistory[100];
	double					m_ClockChangeHistory[100];
	int						m_ClockTimeChangeHistoryPos;
	double					m_ModeratedTimeSpeed;
	double					m_ModeratedTimeSpeedPrim;
	double					m_ModeratedTimeSpeedDiff;

	bool					m_bCorrectedFrameTime;
	int						m_FrameTimeCorrection;
	LONGLONG				m_LastFrameDuration;
	LONGLONG				m_LastSampleTime;

	CString					m_strStatsMsg[10];

	CString					m_D3D9Device;

public:
	CDX9AllocatorPresenter(HWND hWnd, bool bFullscreen, HRESULT& hr, bool bIsEVR, CString &_Error);
	~CDX9AllocatorPresenter();

	// ISubPicAllocatorPresenter
	STDMETHODIMP CreateRenderer(IUnknown** ppRenderer);
	STDMETHODIMP_(bool) Paint(bool fAll);
	STDMETHODIMP GetDIB(BYTE* lpDib, DWORD* size);
	STDMETHODIMP SetPixelShader(LPCSTR pSrcData, LPCSTR pTarget);
	STDMETHODIMP SetPixelShader2(LPCSTR pSrcData, LPCSTR pTarget, bool bScreenSpace);
	STDMETHODIMP_(bool) ResetDevice();
};
}