PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Dependencies/Media SDK 2012/samples/sample_dshow_plugins/custom_evr_presenter/presentengine.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 829 lines | 459 code | 175 blank | 195 comment | 74 complexity | 06ce6294f18aed71fe49cf896eed4547 MD5 | raw file
  1. /*//////////////////////////////////////////////////////////////////////////////
  2. //
  3. // INTEL CORPORATION PROPRIETARY INFORMATION
  4. // This software is supplied under the terms of a license agreement or
  5. // nondisclosure agreement with Intel Corporation and may not be copied
  6. // or disclosed except mtIn accordance with the terms of that agreement.
  7. // Copyright(c) 2003-2011 Intel Corporation. All Rights Reserved.
  8. //
  9. */
  10. //////////////////////////////////////////////////////////////////////////
  11. //
  12. // PresentEngine.cpp: Defines the D3DPresentEngine object.
  13. //
  14. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  15. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  16. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  17. // PARTICULAR PURPOSE.
  18. //
  19. // Copyright (c) Microsoft Corporation. All rights reserved.
  20. //
  21. //
  22. //////////////////////////////////////////////////////////////////////////
  23. #include "EVRPresenter.h"
  24. HRESULT FindAdapter(IDirect3D9 *pD3D9, HMONITOR hMonitor, UINT *puAdapterID);
  25. //-----------------------------------------------------------------------------
  26. // Constructor
  27. //-----------------------------------------------------------------------------
  28. D3DPresentEngine::D3DPresentEngine(HRESULT& hr) :
  29. m_hwnd(NULL),
  30. m_DeviceResetToken(0),
  31. m_pD3D9(NULL),
  32. m_pDevice(NULL),
  33. m_pDeviceManager(NULL),
  34. m_pSurfaceRepaint(NULL),
  35. m_pRenderSurface(NULL),
  36. m_pDXVAVPS(NULL),
  37. m_pDXVAVP_Left(NULL),
  38. m_pDXVAVP_Right(NULL),
  39. m_pS3DControl(NULL)
  40. {
  41. SetRectEmpty(&m_rcDestRect);
  42. ZeroMemory(&m_VideoDesc, sizeof(m_VideoDesc));
  43. ZeroMemory(&m_BltParams, sizeof(m_BltParams));
  44. ZeroMemory(&m_Sample, sizeof(m_Sample));
  45. ZeroMemory(&m_Caps, sizeof(m_Caps));
  46. for (UINT i = 0; i < PRESENTER_BUFFER_COUNT; i++)
  47. {
  48. m_pMixerSurfaces[i] = NULL;
  49. }
  50. // Initialize DXVA structures
  51. DXVA2_AYUVSample16 color = {0x8000, 0x8000, 0x1000, 0xffff};
  52. DXVA2_ExtendedFormat format = { DXVA2_SampleProgressiveFrame, // SampleFormat
  53. DXVA2_VideoChromaSubsampling_MPEG2, // VideoChromaSubsampling
  54. DXVA2_NominalRange_Normal, // NominalRange
  55. DXVA2_VideoTransferMatrix_BT709, // VideoTransferMatrix
  56. DXVA2_VideoLighting_dim, // VideoLighting
  57. DXVA2_VideoPrimaries_BT709, // VideoPrimaries
  58. DXVA2_VideoTransFunc_709 // VideoTransferFunction
  59. };
  60. // init m_VideoDesc structure
  61. memcpy(&m_VideoDesc.SampleFormat, &format, sizeof(DXVA2_ExtendedFormat));
  62. m_VideoDesc.SampleWidth = 256;
  63. m_VideoDesc.SampleHeight = 256;
  64. m_VideoDesc.InputSampleFreq.Numerator = 60;
  65. m_VideoDesc.InputSampleFreq.Denominator = 1;
  66. m_VideoDesc.OutputFrameFreq.Numerator = 60;
  67. m_VideoDesc.OutputFrameFreq.Denominator = 1;
  68. // init m_BltParams structure
  69. memcpy(&m_BltParams.DestFormat, &format, sizeof(DXVA2_ExtendedFormat));
  70. memcpy(&m_BltParams.BackgroundColor, &color, sizeof(DXVA2_AYUVSample16));
  71. m_BltParams.BackgroundColor = color;
  72. m_BltParams.DestFormat = format;
  73. // init m_Sample structure
  74. m_Sample.Start = 0;
  75. m_Sample.End = 1;
  76. m_Sample.SampleFormat = format;
  77. m_Sample.PlanarAlpha.Fraction = 0;
  78. m_Sample.PlanarAlpha.Value = 1;
  79. ZeroMemory(&m_DisplayMode, sizeof(m_DisplayMode));
  80. hr = InitializeD3D();
  81. if (SUCCEEDED(hr))
  82. {
  83. hr = CreateD3DDevice();
  84. }
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Destructor
  88. //-----------------------------------------------------------------------------
  89. D3DPresentEngine::~D3DPresentEngine()
  90. {
  91. // switch back to 2D otherwise next switch to 3D fails,
  92. // use current display mode
  93. m_pS3DControl->SwitchTo2D(NULL);
  94. SAFE_RELEASE(m_pDevice);
  95. SAFE_RELEASE(m_pSurfaceRepaint);
  96. SAFE_RELEASE(m_pDeviceManager);
  97. SAFE_RELEASE(m_pD3D9);
  98. for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++)
  99. {
  100. SAFE_RELEASE(m_pMixerSurfaces[i]);
  101. }
  102. SAFE_RELEASE(m_pDXVAVPS);
  103. SAFE_RELEASE(m_pDXVAVP_Left);
  104. SAFE_RELEASE(m_pDXVAVP_Right);
  105. SAFE_DELETE(m_pS3DControl);
  106. //sleep 4 sec to wait until monitor switches
  107. Sleep(4*1000);
  108. }
  109. //-----------------------------------------------------------------------------
  110. // GetService
  111. //
  112. // Returns a service interface from the presenter engine.
  113. // The presenter calls this method from inside it's implementation of
  114. // IMFGetService::GetService.
  115. //
  116. // Classes that derive from D3DPresentEngine can override this method to return
  117. // other interfaces. If you override this method, call the base method from the
  118. // derived class.
  119. //-----------------------------------------------------------------------------
  120. HRESULT D3DPresentEngine::GetService(REFGUID guidService, REFIID riid, void** ppv)
  121. {
  122. assert(ppv != NULL);
  123. HRESULT hr = S_OK;
  124. if (riid == __uuidof(IDirect3DDeviceManager9))
  125. {
  126. if (m_pDeviceManager == NULL)
  127. {
  128. hr = MF_E_UNSUPPORTED_SERVICE;
  129. }
  130. else
  131. {
  132. *ppv = m_pDeviceManager;
  133. m_pDeviceManager->AddRef();
  134. }
  135. }
  136. else
  137. {
  138. hr = MF_E_UNSUPPORTED_SERVICE;
  139. }
  140. return hr;
  141. }
  142. //-----------------------------------------------------------------------------
  143. // CheckFormat
  144. //
  145. // Queries whether the D3DPresentEngine can use a specified Direct3D format.
  146. //-----------------------------------------------------------------------------
  147. HRESULT D3DPresentEngine::CheckFormat(D3DFORMAT format)
  148. {
  149. HRESULT hr = S_OK;
  150. UINT uAdapter = D3DADAPTER_DEFAULT;
  151. D3DDEVTYPE type = D3DDEVTYPE_HAL;
  152. D3DDISPLAYMODE mode;
  153. D3DDEVICE_CREATION_PARAMETERS params;
  154. if (m_pDevice)
  155. {
  156. CHECK_HR(hr = m_pDevice->GetCreationParameters(&params));
  157. uAdapter = params.AdapterOrdinal;
  158. type = params.DeviceType;
  159. }
  160. CHECK_HR(hr = m_pD3D9->GetAdapterDisplayMode(uAdapter, &mode));
  161. CHECK_HR(hr = m_pD3D9->CheckDeviceType(uAdapter, type, mode.Format, format, TRUE));
  162. done:
  163. return hr;
  164. }
  165. //-----------------------------------------------------------------------------
  166. // SetVideoWindow
  167. //
  168. // Sets the window where the video is drawn.
  169. //-----------------------------------------------------------------------------
  170. HRESULT D3DPresentEngine::SetVideoWindow(HWND hwnd)
  171. {
  172. // Assertions: EVRCustomPresenter checks these cases.
  173. assert(IsWindow(hwnd));
  174. assert(hwnd != m_hwnd);
  175. HRESULT hr = S_OK;
  176. AutoLock lock(m_ObjectLock);
  177. m_hwnd = hwnd;
  178. UpdateDestRect();
  179. // Recreate the device.
  180. hr = CreateD3DDevice();
  181. return hr;
  182. }
  183. //-----------------------------------------------------------------------------
  184. // SetDestinationRect
  185. //
  186. // Sets the region within the video window where the video is drawn.
  187. //-----------------------------------------------------------------------------
  188. HRESULT D3DPresentEngine::SetDestinationRect(const RECT& rcDest)
  189. {
  190. if (EqualRect(&rcDest, &m_rcDestRect))
  191. {
  192. return S_OK; // No change.
  193. }
  194. HRESULT hr = S_OK;
  195. AutoLock lock(m_ObjectLock);
  196. m_rcDestRect = rcDest;
  197. UpdateDestRect();
  198. return hr;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // CreateVideoSamples
  202. //-----------------------------------------------------------------------------
  203. HRESULT D3DPresentEngine::CreateVideoSamples(IMFMediaType *pFormat, VideoSampleList& videoSampleQueue)
  204. {
  205. if (m_hwnd == NULL)
  206. {
  207. return MF_E_INVALIDREQUEST;
  208. }
  209. if (pFormat == NULL)
  210. {
  211. return MF_E_UNEXPECTED;
  212. }
  213. HRESULT hr = S_OK;
  214. D3DCOLOR clrBlack = D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0x00);
  215. IMFSample* pVideoSample = NULL;
  216. HANDLE hDevice = 0;
  217. UINT nWidth(0), nHeight(0);
  218. IDirectXVideoProcessorService* pVideoProcessorService = NULL;
  219. AutoLock lock(m_ObjectLock);
  220. ReleaseResources();
  221. UpdateDestRect();
  222. // Get sizes for allocated surfaces
  223. CHECK_HR(hr = MFGetAttributeSize(pFormat, MF_MT_FRAME_SIZE, &nWidth, &nHeight));
  224. // Get device handle
  225. CHECK_HR(hr = m_pDeviceManager->OpenDeviceHandle(&hDevice));
  226. // Get IDirectXVideoProcessorService
  227. CHECK_HR(hr = m_pDeviceManager->GetVideoService(hDevice, IID_IDirectXVideoProcessorService, (void**)&pVideoProcessorService));
  228. // Create IDirect3DSurface9 surface
  229. CHECK_HR(hr = pVideoProcessorService->CreateSurface(nWidth, nHeight, PRESENTER_BUFFER_COUNT - 1, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, (IDirect3DSurface9 **)&m_pMixerSurfaces, NULL));
  230. // Create the video samples.
  231. for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++)
  232. {
  233. // Fill it with black.
  234. CHECK_HR(hr = m_pDevice->ColorFill(m_pMixerSurfaces[i], NULL, clrBlack));
  235. // Create the sample.
  236. CHECK_HR(hr = MFCreateVideoSampleFromSurface(m_pMixerSurfaces[i], &pVideoSample));
  237. pVideoSample->SetUINT32(MFSampleExtension_CleanPoint, 0);
  238. // Add it to the list.
  239. hr = videoSampleQueue.InsertBack(pVideoSample);
  240. SAFE_RELEASE(pVideoSample);
  241. CHECK_HR(hr);
  242. }
  243. done:
  244. SAFE_RELEASE(pVideoProcessorService);
  245. m_pDeviceManager->CloseDeviceHandle(hDevice);
  246. if (FAILED(hr))
  247. {
  248. ReleaseResources();
  249. }
  250. return hr;
  251. }
  252. //-----------------------------------------------------------------------------
  253. // ReleaseResources
  254. //
  255. // Released Direct3D resources used by this object.
  256. //-----------------------------------------------------------------------------
  257. void D3DPresentEngine::ReleaseResources()
  258. {
  259. // Let the derived class release any resources it created.
  260. OnReleaseResources();
  261. SAFE_RELEASE(m_pSurfaceRepaint);
  262. for (int i = 0; i < PRESENTER_BUFFER_COUNT; i++)
  263. {
  264. SAFE_RELEASE(m_pMixerSurfaces[i]);
  265. }
  266. }
  267. //-----------------------------------------------------------------------------
  268. // CheckDeviceState
  269. //
  270. // Tests the Direct3D device state.
  271. //
  272. // pState: Receives the state of the device (OK, reset, removed)
  273. //-----------------------------------------------------------------------------
  274. HRESULT D3DPresentEngine::CheckDeviceState(DeviceState *pState)
  275. {
  276. HRESULT hr = S_OK;
  277. AutoLock lock(m_ObjectLock);
  278. // Check the device state. Not every failure code is a critical failure.
  279. hr = m_pDevice->CheckDeviceState(m_hwnd);
  280. *pState = DeviceOK;
  281. switch (hr)
  282. {
  283. case S_OK:
  284. case S_PRESENT_OCCLUDED:
  285. case S_PRESENT_MODE_CHANGED:
  286. // state is DeviceOK
  287. hr = S_OK;
  288. break;
  289. case D3DERR_DEVICELOST:
  290. case D3DERR_DEVICEHUNG:
  291. // Lost/hung device. Destroy the device and create a new one.
  292. CHECK_HR(hr = CreateD3DDevice());
  293. *pState = DeviceReset;
  294. hr = S_OK;
  295. break;
  296. case D3DERR_DEVICEREMOVED:
  297. // This is a fatal error.
  298. *pState = DeviceRemoved;
  299. break;
  300. case E_INVALIDARG:
  301. // CheckDeviceState can return E_INVALIDARG if the window is not valid
  302. // We'll assume that the window was destroyed; we'll recreate the device
  303. // if the application sets a new window.
  304. hr = S_OK;
  305. }
  306. done:
  307. return hr;
  308. }
  309. //-----------------------------------------------------------------------------
  310. // PresentSample
  311. //
  312. // Presents a video frame.
  313. //
  314. // pSample: Pointer to the sample that contains the surface to present. If
  315. // this parameter is NULL, the method paints a black rectangle.
  316. // llTarget: Target presentation time.
  317. //
  318. // This method is called by the scheduler and/or the presenter.
  319. //-----------------------------------------------------------------------------
  320. HRESULT D3DPresentEngine::PresentSample(IMFSample* pSample, LONGLONG llTarget)
  321. {
  322. HRESULT hr = S_OK;
  323. IMFMediaBuffer* pBuffer = NULL;
  324. IDirect3DSurface9* pSurface = NULL;
  325. LONGLONG sampleDuration=0;
  326. if (pSample)
  327. {
  328. // Get the buffer from the sample.
  329. CHECK_HR(hr = pSample->GetBufferByIndex(0, &pBuffer));
  330. // Get the surface from the buffer.
  331. CHECK_HR(hr = MFGetService(pBuffer, MR_BUFFER_SERVICE, __uuidof(IDirect3DSurface9), (void**)&pSurface));
  332. CHECK_HR(hr = pSample->GetSampleDuration(&sampleDuration));
  333. }
  334. else if (m_pSurfaceRepaint)
  335. {
  336. // Redraw from the last surface.
  337. pSurface = m_pSurfaceRepaint;
  338. pSurface->AddRef();
  339. }
  340. if (pSurface)
  341. {
  342. // Present the surface
  343. CHECK_HR(hr = PresentSurface(pSurface, (0 == sampleDuration)));
  344. // Store this pointer in case we need to repaint the surface
  345. CopyComPointer(m_pSurfaceRepaint, pSurface);
  346. }
  347. else
  348. {
  349. // No surface. All we can do is paint a black rectangle
  350. PaintFrameWithGDI();
  351. }
  352. done:
  353. SAFE_RELEASE(pSurface);
  354. SAFE_RELEASE(pBuffer);
  355. if (FAILED(hr))
  356. {
  357. if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET || hr == D3DERR_DEVICEHUNG)
  358. {
  359. // We failed because the device was lost. Fill the destination rectangle.
  360. PaintFrameWithGDI();
  361. // Ignore. We need to reset or re-create the device, but this method
  362. // is probably being called from the scheduler thread, which is not the
  363. // same thread that created the device. The Reset(Ex) method must be
  364. // called from the thread that created the device.
  365. // The presenter will detect the state when it calls CheckDeviceState()
  366. // on the next sample.
  367. hr = S_OK;
  368. }
  369. }
  370. return hr;
  371. }
  372. //-----------------------------------------------------------------------------
  373. // private/protected methods
  374. //-----------------------------------------------------------------------------
  375. //-----------------------------------------------------------------------------
  376. // InitializeD3D
  377. //
  378. // Initializes Direct3D and the Direct3D device manager.
  379. //-----------------------------------------------------------------------------
  380. HRESULT D3DPresentEngine::InitializeD3D()
  381. {
  382. HRESULT hr = S_OK;
  383. IGFX_DISPLAY_MODE mode = {0};
  384. assert(m_pD3D9 == NULL);
  385. assert(m_pDeviceManager == NULL);
  386. //// S3D part
  387. m_pS3DControl = CreateIGFXS3DControl();
  388. CHECK_HR(hr = (NULL != m_pS3DControl))
  389. // check if s3d supported and get a list of supported display modes
  390. CHECK_HR(hr = m_pS3DControl->GetS3DCaps(&m_Caps));
  391. // choose preferable mode
  392. CHECK_HR(hr = GetPreferableS3DMode(&mode));
  393. // switch to 3D mode
  394. CHECK_HR(hr = m_pS3DControl->SwitchTo3D(&mode));
  395. // Create Direct3D
  396. CHECK_HR(hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_pD3D9));
  397. // Create the device manager
  398. CHECK_HR(hr = DXVA2CreateDirect3DDeviceManager9(&m_DeviceResetToken, &m_pDeviceManager));
  399. done:
  400. return hr;
  401. }
  402. //-----------------------------------------------------------------------------
  403. // CreateD3DDevice
  404. //
  405. // Creates the Direct3D device.
  406. //-----------------------------------------------------------------------------
  407. HRESULT D3DPresentEngine::CreateD3DDevice()
  408. {
  409. HRESULT hr = S_OK;
  410. HWND hwnd = NULL;
  411. HMONITOR hMonitor = NULL;
  412. UINT uAdapterID = D3DADAPTER_DEFAULT;
  413. DWORD vp = 0;
  414. D3DCAPS9 ddCaps;
  415. ZeroMemory(&ddCaps, sizeof(ddCaps));
  416. IDirect3DDevice9Ex* pDevice = NULL;
  417. // Hold the lock because we might be discarding an existing device.
  418. AutoLock lock(m_ObjectLock);
  419. if (!m_pD3D9 || !m_pDeviceManager)
  420. {
  421. return MF_E_NOT_INITIALIZED;
  422. }
  423. if (m_hwnd)
  424. {
  425. hwnd = m_hwnd;
  426. }
  427. else
  428. {
  429. hwnd = GetDesktopWindow();
  430. }
  431. IGFX_DISPLAY_MODE mode = {0};
  432. CHECK_HR(hr = GetPreferableS3DMode(&mode));
  433. // Note: The presenter creates additional swap chains to present the video frames
  434. D3DPRESENT_PARAMETERS pp;
  435. ZeroMemory(&pp, sizeof(pp));
  436. pp.BackBufferWidth = mode.ulResWidth;
  437. pp.BackBufferHeight = mode.ulResHeight;
  438. pp.Windowed = TRUE;
  439. pp.SwapEffect = D3DSWAPEFFECT_OVERLAY;
  440. pp.BackBufferFormat = D3DFMT_X8R8G8B8;
  441. pp.BackBufferCount = 1;
  442. pp.hDeviceWindow = hwnd;
  443. pp.Flags = D3DPRESENTFLAG_VIDEO | D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
  444. pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
  445. // Find the monitor for this window.
  446. if (m_hwnd)
  447. {
  448. hMonitor = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);
  449. // Find the corresponding adapter.
  450. CHECK_HR(hr = FindAdapter(m_pD3D9, hMonitor, &uAdapterID));
  451. }
  452. // Get the device caps for this adapter.
  453. CHECK_HR(hr = m_pD3D9->GetDeviceCaps(uAdapterID, D3DDEVTYPE_HAL, &ddCaps));
  454. if(ddCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
  455. {
  456. vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  457. }
  458. else
  459. {
  460. vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  461. }
  462. // Create the device.
  463. CHECK_HR(hr = m_pD3D9->CreateDeviceEx(uAdapterID,
  464. D3DDEVTYPE_HAL,
  465. pp.hDeviceWindow,
  466. vp | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
  467. &pp,
  468. NULL,
  469. &pDevice));
  470. // Get the adapter display mode.
  471. CHECK_HR(hr = m_pD3D9->GetAdapterDisplayMode(uAdapterID, &m_DisplayMode));
  472. CHECK_HR(hr = pDevice->ResetEx(&pp, NULL));
  473. CHECK_HR(hr = pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0));
  474. // Reset the D3DDeviceManager with the new device
  475. CHECK_HR(hr = m_pDeviceManager->ResetDevice(pDevice, m_DeviceResetToken));
  476. CHECK_HR(hr = m_pS3DControl->SetDevice(m_pDeviceManager));
  477. // Create DXVA2 Video Processor Service.
  478. CHECK_HR(hr = DXVA2CreateVideoService(pDevice, IID_IDirectXVideoProcessorService, (void**)&m_pDXVAVPS));
  479. // Activate L channel
  480. CHECK_HR(hr = m_pS3DControl->SelectLeftView());
  481. // Create VPP device for the L channel
  482. CHECK_HR(hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice, &m_VideoDesc, D3DFMT_X8R8G8B8, 1, &m_pDXVAVP_Left));
  483. // Activate R channel
  484. CHECK_HR(hr = m_pS3DControl->SelectRightView());
  485. // Create VPP device for the R channel
  486. CHECK_HR(hr = m_pDXVAVPS->CreateVideoProcessor(DXVA2_VideoProcProgressiveDevice, &m_VideoDesc, D3DFMT_X8R8G8B8, 1, &m_pDXVAVP_Right));
  487. SAFE_RELEASE(m_pDevice);
  488. m_pDevice = pDevice;
  489. m_pDevice->AddRef();
  490. done:
  491. SAFE_RELEASE(pDevice);
  492. return hr;
  493. }
  494. //-----------------------------------------------------------------------------
  495. // PresentSurface
  496. //
  497. // Presents a surface that contains a video frame.
  498. //
  499. // pSurface: Pointer to the surface.
  500. HRESULT D3DPresentEngine::PresentSurface( IDirect3DSurface9* pSurface, LONG nView /*= 0*/ )
  501. {
  502. HRESULT hr = S_OK;
  503. RECT target;
  504. if (m_hwnd == NULL)
  505. {
  506. return MF_E_INVALIDREQUEST;
  507. }
  508. if (NULL == m_pDXVAVP_Left || NULL == m_pDXVAVP_Right)
  509. {
  510. return E_FAIL;
  511. }
  512. GetClientRect(m_hwnd, &target);
  513. m_BltParams.TargetRect =
  514. m_Sample.SrcRect =
  515. m_Sample.DstRect = target;
  516. m_Sample.SrcSurface = pSurface;
  517. // select processor based on the view id
  518. IDirectXVideoProcessor* pVideoProcessor = m_pDXVAVP_Left;
  519. if (nView)
  520. {
  521. pVideoProcessor = m_pDXVAVP_Right;
  522. }
  523. // a new rendering surface must be retrieved not for every frame,
  524. // rendering frame is one for both views(L+R)
  525. if (0 == nView)
  526. {
  527. hr = m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pRenderSurface);
  528. }
  529. // process the surface
  530. hr = pVideoProcessor->VideoProcessBlt(m_pRenderSurface, &m_BltParams, &m_Sample, 1, NULL);
  531. // release after both views are in it
  532. if (nView)
  533. {
  534. m_pRenderSurface->Release();
  535. }
  536. if (SUCCEEDED(hr) && nView)
  537. {
  538. hr = m_pDevice->PresentEx(&m_rcDestRect, &m_rcDestRect, m_hwnd, NULL, 0);
  539. }
  540. LOG_MSG_IF_FAILED(L"D3DPresentEngine::PresentSurface failed.", hr);
  541. return hr;
  542. }
  543. //-----------------------------------------------------------------------------
  544. // PaintFrameWithGDI
  545. //
  546. // Fills the destination rectangle with black.
  547. //-----------------------------------------------------------------------------
  548. void D3DPresentEngine::PaintFrameWithGDI()
  549. {
  550. HDC hdc = GetDC(m_hwnd);
  551. if (hdc)
  552. {
  553. HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
  554. if (hBrush)
  555. {
  556. FillRect(hdc, &m_rcDestRect, hBrush);
  557. DeleteObject(hBrush);
  558. }
  559. ReleaseDC(m_hwnd, hdc);
  560. }
  561. }
  562. //-----------------------------------------------------------------------------
  563. // UpdateDestRect
  564. //
  565. // Updates the target rectangle by clipping it to the video window's client
  566. // area.
  567. //
  568. // Called whenever the application sets the video window or the destination
  569. // rectangle.
  570. //-----------------------------------------------------------------------------
  571. HRESULT D3DPresentEngine::UpdateDestRect()
  572. {
  573. if (m_hwnd == NULL)
  574. {
  575. return S_FALSE;
  576. }
  577. RECT rcView;
  578. GetClientRect(m_hwnd, &rcView);
  579. // Clip the destination rectangle to the window's client area.
  580. if (m_rcDestRect.right > rcView.right)
  581. {
  582. m_rcDestRect.right = rcView.right;
  583. }
  584. if (m_rcDestRect.bottom > rcView.bottom)
  585. {
  586. m_rcDestRect.bottom = rcView.bottom;
  587. }
  588. return S_OK;
  589. }
  590. //-----------------------------------------------------------------------------
  591. // GetPreferableS3DMode
  592. //
  593. // Returns index of preferable s3d mode
  594. //-----------------------------------------------------------------------------
  595. HRESULT D3DPresentEngine::GetPreferableS3DMode(IGFX_DISPLAY_MODE *mode)
  596. {
  597. ULONG pref_idx = 0;
  598. CheckPointer(m_Caps.S3DSupportedModes, E_POINTER);
  599. for (ULONG i = 0; i<m_Caps.ulNumEntries; i++)
  600. {
  601. if (Less(m_Caps.S3DSupportedModes[pref_idx], m_Caps.S3DSupportedModes[i])) pref_idx = i;
  602. }
  603. *mode = m_Caps.S3DSupportedModes[pref_idx];
  604. return S_OK;
  605. }
  606. //-----------------------------------------------------------------------------
  607. // Static functions
  608. //-----------------------------------------------------------------------------
  609. //-----------------------------------------------------------------------------
  610. // FindAdapter
  611. //
  612. // Given a handle to a monitor, returns the ordinal number that D3D uses to
  613. // identify the adapter.
  614. //-----------------------------------------------------------------------------
  615. HRESULT FindAdapter(IDirect3D9 *pD3D9, HMONITOR hMonitor, UINT *puAdapterID)
  616. {
  617. HRESULT hr = E_FAIL;
  618. UINT cAdapters = 0;
  619. UINT uAdapterID = (UINT)-1;
  620. cAdapters = pD3D9->GetAdapterCount();
  621. for (UINT i = 0; i < cAdapters; i++)
  622. {
  623. HMONITOR hMonitorTmp = pD3D9->GetAdapterMonitor(i);
  624. if (hMonitorTmp == NULL)
  625. {
  626. break;
  627. }
  628. if (hMonitorTmp == hMonitor)
  629. {
  630. uAdapterID = i;
  631. break;
  632. }
  633. }
  634. if (uAdapterID != (UINT)-1)
  635. {
  636. *puAdapterID = uAdapterID;
  637. hr = S_OK;
  638. }
  639. return hr;
  640. }
  641. //-----------------------------------------------------------------------------
  642. // Less
  643. //
  644. // Compares display modes to choose preferable s3d mode
  645. //-----------------------------------------------------------------------------
  646. bool D3DPresentEngine::Less(const IGFX_DISPLAY_MODE &l, const IGFX_DISPLAY_MODE& r)
  647. {
  648. if (r.ulResWidth >= 0xFFFF || r.ulResHeight >= 0xFFFF || r.ulRefreshRate >= 0xFFFF)
  649. return false;
  650. if (l.ulResWidth < r.ulResWidth) return true;
  651. else if (l.ulResHeight < r.ulResHeight) return true;
  652. else if (l.ulRefreshRate < r.ulRefreshRate) return true;
  653. return false;
  654. }