MythTV  master
mythrender_d3d9.cpp
Go to the documentation of this file.
1 #define _WIN32_WINNT 0x500
2 
3 #include <algorithm>
4 
5 #include <QLibrary>
6 #include <QRect>
7 #include <QMap>
8 #include <QMutex>
9 
11 #include "mythrender_d3d9.h"
12 
13 #ifndef DXVA2_E_NEW_VIDEO_DEVICE
14 #define DXVA2_E_NEW_VIDEO_DEVICE MAKE_HRESULT(1, 4, 4097)
15 #endif
16 
18 {
19  FLOAT x;
20  FLOAT y;
21  FLOAT z;
22  FLOAT rhw;
23  D3DCOLOR diffuse;
24  FLOAT t1u;
25  FLOAT t1v;
26  FLOAT t2u;
27  FLOAT t2v;
28 };
29 
30 struct VERTEX
31 {
32  FLOAT x;
33  FLOAT y;
34  FLOAT z;
35  FLOAT rhw;
36  D3DCOLOR diffuse;
37 };
38 
39 D3D9Image::D3D9Image(MythRenderD3D9 *render, QSize size, bool video)
40  : m_size(size), m_render(render)
41 {
42  if (m_render)
43  {
47  }
49 }
50 
52 {
53  if (!m_render)
54  return;
55 
56  if (m_texture)
58  if (m_vertexbuffer)
60  if (m_surface)
62 }
63 
65 {
66  if (m_valid)
68  return false;
69 }
70 
71 bool D3D9Image::UpdateImage(IDirect3DSurface9 *surface)
72 {
73  if (m_valid)
74  return m_render->StretchRect(m_texture, surface, false);
75  return false;
76 }
77 
79 {
80  bool result = true;
81  if (m_valid)
82  {
83  result &= m_render->UpdateSurface(m_surface, img);
85  }
86  return m_valid && result;
87 }
88 
89 bool D3D9Image::UpdateVertices(const QRect &dvr, const QRect &vr, int alpha,
90  bool video)
91 {
92  if (m_valid)
93  return m_render->UpdateVertexBuffer(m_vertexbuffer, dvr, vr, alpha, video);
94  return false;
95 }
96 
97 bool D3D9Image::Draw(void)
98 {
99  if (m_valid)
101  return false;
102 }
103 
104 uint8_t* D3D9Image::GetBuffer(bool &hardware_conv, uint &pitch)
105 {
106  if (!m_valid)
107  return nullptr;
108 
109  hardware_conv = m_render->HardwareYUVConversion();
110  return m_render->GetBuffer(m_surface, pitch);
111 }
112 
114 {
115  if (!m_valid)
116  return;
119 }
120 
122 {
123  if (!m_valid)
124  return QRect();
126 }
127 
128 #define mD3DFMT_YV12 (D3DFORMAT)MAKEFOURCC('Y','V','1','2')
129 #define mD3DFMT_IYUV (D3DFORMAT)MAKEFOURCC('I','Y','U','V')
130 #define mD3DFMT_I420 (D3DFORMAT)MAKEFOURCC('I','4','2','0')
131 #define mD3DFMT_YV16 (D3DFORMAT)MAKEFOURCC('Y','V','1','6')
132 #define D3DFVF_TEXTUREVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEX2)
133 #define D3DFVF_VERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
134 #define D3DLOC QString("MythRenderD3D9: ")
135 
137 {
138  if (m_render)
140 }
141 
142 IDirect3DDevice9* D3D9Locker::Acquire(void)
143 {
144  IDirect3DDevice9* result = nullptr;
145  if (m_render)
146  result = m_render->AcquireDevice();
147  if (!result)
148  LOG(VB_GENERAL, LOG_ERR, "D3D9Locker: Failed to acquire device.");
149  return result;
150 }
151 
152 void* MythRenderD3D9::ResolveAddress(const char* lib, const char* proc)
153 {
154  return (void *)QLibrary::resolve(lib, proc);
155 }
156 
158 {
159  QMutexLocker locker(&m_lock);
160 
161  LOG(VB_GENERAL, LOG_INFO, D3DLOC + "Deleting D3D9 resources.");
162 
164  m_rect_vertexbuffer->Release();
165  if (m_current_surface)
166  m_current_surface->Release();
167  if (m_default_surface)
168  m_default_surface->Release();
169 
170  DeleteTextures();
172  DeleteSurfaces();
173 
175 
176  if (m_rootD3DDevice)
177  {
178  LOG(VB_GENERAL, LOG_INFO, D3DLOC + "Deleting D3D9 device.");
179  m_rootD3DDevice->Release();
180  }
181 
182  if (m_d3d)
183  {
184  LOG(VB_GENERAL, LOG_INFO, D3DLOC + "Deleting D3D9.");
185  m_d3d->Release();
186  }
187 }
188 
189 static const QString toString(D3DFORMAT fmt)
190 {
191  switch (fmt)
192  {
193  case D3DFMT_A8:
194  return "A8";
195  case D3DFMT_A8R8G8B8:
196  return "A8R8G8B8";
197  case D3DFMT_X8R8G8B8:
198  return "X8R8G8B8";
199  case D3DFMT_A8B8G8R8:
200  return "A8B8G8R8";
201  case D3DFMT_X8B8G8R8:
202  return "X8B8G8R8";
203  case mD3DFMT_YV12:
204  return "YV12";
205  case D3DFMT_UYVY:
206  return "UYVY";
207  case D3DFMT_YUY2:
208  return "YUY2";
209  case mD3DFMT_IYUV:
210  return "IYUV";
211  case mD3DFMT_I420:
212  return "I420";
213  case mD3DFMT_YV16:
214  return "YV16";
215  default:
216  break;
217  }
218  return QString().setNum((ulong)fmt,16);
219 }
220 
221 bool MythRenderD3D9::Create(QSize size, HWND window)
222 {
223  QMutexLocker locker(&m_lock);
224 
225  using LPFND3DC = LPDIRECT3D9 (WINAPI *)(UINT SDKVersion);
226  static LPFND3DC OurDirect3DCreate9 = nullptr;
227 
228  OurDirect3DCreate9 = (LPFND3DC)ResolveAddress("D3D9","Direct3DCreate9");
229  if (!OurDirect3DCreate9)
230  {
231  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
232  "FATAL: Failed to find Direct3DCreate9.");
233  return false;
234  }
235 
236  m_d3d = OurDirect3DCreate9(D3D_SDK_VERSION);
237  if (!m_d3d)
238  {
239  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
240  "Could not create Direct3D9 instance.");
241  return false;
242  }
243 
244  D3DCAPS9 d3dCaps;
245  ZeroMemory(&d3dCaps, sizeof(d3dCaps));
246  if (D3D_OK != m_d3d->GetDeviceCaps(
247  D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps))
248  {
249  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
250  "Could not read adapter capabilities.");
251  }
252 
253  D3DDISPLAYMODE d3ddm;
254  if (D3D_OK != m_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))
255  {
256  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
257  "Could not read adapter display mode.");
258  return false;
259  }
260 
261  // Check the adaptor format is reasonable
262  static const D3DFORMAT bfmt[] =
263  {
264  D3DFMT_A8R8G8B8,
265  D3DFMT_A8B8G8R8,
266  D3DFMT_X8R8G8B8,
267  D3DFMT_X8B8G8R8,
268  D3DFMT_R8G8B8
269  };
270 
271  m_adaptor_fmt = d3ddm.Format;
272  bool is_reasonable = false;
273  for (uint i = 0; i < sizeof(bfmt) / sizeof(bfmt[0]); i++)
274  if (bfmt[i] == m_adaptor_fmt)
275  is_reasonable = true;
276  LOG(VB_GENERAL, LOG_INFO, D3DLOC + QString("Default adaptor format %1.")
277  .arg(toString(m_adaptor_fmt)));
278  if (!is_reasonable)
279  {
280  LOG(VB_GENERAL, LOG_WARNING, D3DLOC +
281  "Warning: Default adaptor format may not work.");
282  }
283 
284  // Choose a surface format
285  for (unsigned i = 0; i < sizeof bfmt / sizeof bfmt[0]; ++i)
286  {
287  if (SUCCEEDED(m_d3d->CheckDeviceType(D3DADAPTER_DEFAULT,
288  D3DDEVTYPE_HAL, m_adaptor_fmt, bfmt[i], TRUE)))
289  {
290  m_surface_fmt = bfmt[i];
291  break;
292  }
293  }
294 
295  if (D3DFMT_UNKNOWN == m_surface_fmt)
296  {
297  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to choose surface format - "
298  "using default back buffer format.");
300  }
301 
303  LOG(VB_GENERAL, LOG_INFO, D3DLOC +
304  QString("Chosen surface and texture format: %1")
305  .arg(toString(m_surface_fmt)));
306 
307 
308  // Test whether a YV12 video surface is available
309  if (FAILED(m_d3d->CheckDeviceFormatConversion(D3DADAPTER_DEFAULT,
310  D3DDEVTYPE_HAL, D3DFMT_UNKNOWN, m_adaptor_fmt)) &&
311  SUCCEEDED(m_d3d->CheckDeviceFormatConversion(D3DADAPTER_DEFAULT,
312  D3DDEVTYPE_HAL, mD3DFMT_YV12, m_surface_fmt)))
313  {
315  }
316  else
317  {
319  }
320 
321  LOG(VB_GENERAL, LOG_INFO, D3DLOC +
322  QString("Chosen video surface format %1.")
324  LOG(VB_GENERAL, LOG_INFO, D3DLOC +
325  QString("Hardware YV12 to RGB conversion %1.")
327  "unavailable" : "available"));
328 
329  D3DPRESENT_PARAMETERS d3dpp;
330  ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
331  d3dpp.BackBufferFormat = m_adaptor_fmt;
332  d3dpp.hDeviceWindow = window;
333  d3dpp.Windowed = true;
334  d3dpp.BackBufferWidth = size.width();
335  d3dpp.BackBufferHeight = size.height();
336  d3dpp.BackBufferCount = 1;
337  d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
338  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
339  d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
340  d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
341 
342  if (D3D_OK != m_d3d->CreateDevice(D3DADAPTER_DEFAULT,
343  D3DDEVTYPE_HAL, d3dpp.hDeviceWindow,
344  D3DCREATE_SOFTWARE_VERTEXPROCESSING |
345  D3DCREATE_MULTITHREADED,
346  &d3dpp, &m_rootD3DDevice))
347  {
348  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Could not create the D3D device.");
349  return false;
350  }
351 
352  static bool debugged = false;
353  if (!debugged)
354  {
355  debugged = true;
356  D3DADAPTER_IDENTIFIER9 ident;
357  if (D3D_OK == m_d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &ident))
358  {
359  LOG(VB_GENERAL, LOG_INFO, D3DLOC + QString("Device: %1")
360  .arg(ident.Description));
361  LOG(VB_GENERAL, LOG_INFO, D3DLOC +QString("Driver: %1.%2.%3.%4")
362  .arg(HIWORD(ident.DriverVersion.HighPart))
363  .arg(LOWORD(ident.DriverVersion.HighPart))
364  .arg(HIWORD(ident.DriverVersion.LowPart))
365  .arg(LOWORD(ident.DriverVersion.LowPart)));
366  }
367  }
368 
370  Init2DState();
371  return true;
372 }
373 
375 {
377 }
378 
379 bool MythRenderD3D9::Test(bool &reset)
380 {
381  D3D9Locker locker(this);
382  IDirect3DDevice9* dev = locker.Acquire();
383  if (!dev)
384  return false;
385 
386  bool result = true;
387  HRESULT hr = dev->TestCooperativeLevel();
388  if (FAILED(hr))
389  {
390  switch (hr)
391  {
392  case D3DERR_DEVICENOTRESET:
393  LOG(VB_GENERAL, LOG_NOTICE, D3DLOC +
394  "The device was lost and needs to be reset.");
395  result = false;
396  reset = true;
397  break;
398 
399  case D3DERR_DEVICELOST:
400  LOG(VB_GENERAL, LOG_NOTICE, D3DLOC +
401  "The device has been lost and cannot be reset "
402  "at this time.");
403  result = false;
404  break;
405 
406  case D3DERR_DRIVERINTERNALERROR:
407  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
408  "Internal driver error. "
409  "Please shut down the application.");
410  result = false;
411  break;
412 
413  default:
414  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
415  "TestCooperativeLevel() failed.");
416  result = false;
417  }
418  }
419  return result;
420 }
421 
423 {
424  D3D9Locker locker(this);
425  IDirect3DDevice9* dev = locker.Acquire();
426  if (!dev)
427  return false;
428 
429  HRESULT hr = dev->Clear(0, nullptr, D3DCLEAR_TARGET,
430  D3DCOLOR_ARGB(0, 0, 0, 0), 1.0F, 0);
431  if (FAILED(hr))
432  {
433  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Clear() failed.");
434  return false;
435  }
436  return true;
437 }
438 
440 {
441  D3D9Locker locker(this);
442  IDirect3DDevice9* dev = locker.Acquire();
443  if (!dev)
444  return false;
445 
446  HRESULT hr = dev->BeginScene();
447  if (FAILED(hr))
448  {
449  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "BeginScene() failed.");
450  return false;
451  }
452  return true;
453 }
454 
456 {
457  D3D9Locker locker(this);
458  IDirect3DDevice9* dev = locker.Acquire();
459  if (!dev)
460  return false;
461 
462  HRESULT hr = dev->EndScene();
463  if (FAILED(hr))
464  {
465  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "EndScene() failed.");
466  return false;
467  }
468  return true;
469 }
470 
471 void MythRenderD3D9::CopyFrame(void* surface, D3D9Image *img)
472 {
473  if (surface && img)
474  img->UpdateImage((IDirect3DSurface9*)surface);
475 }
476 
477 bool MythRenderD3D9::StretchRect(IDirect3DTexture9 *texture,
478  IDirect3DSurface9 *surface,
479  bool known_surface)
480 {
481  if (!m_textures.contains(texture) ||
482  (known_surface && !m_surfaces.contains(surface)))
483  return false;
484 
485  D3D9Locker locker(this);
486  IDirect3DDevice9* dev = locker.Acquire();
487  if (!dev)
488  return false;
489 
490  LPDIRECT3DSURFACE9 d3ddest;
491  HRESULT hr = texture->GetSurfaceLevel(0, &d3ddest);
492  if (FAILED(hr))
493  {
494  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "GetSurfaceLevel() failed");
495  return false;
496  }
497 
498  hr = dev->StretchRect(surface, nullptr, d3ddest,
499  nullptr, D3DTEXF_POINT);
500  d3ddest->Release();
501  if (FAILED(hr))
502  {
503  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "StretchRect() failed");
504  return false;
505  }
506  return true;
507 }
508 
509 bool MythRenderD3D9::DrawTexturedQuad(IDirect3DVertexBuffer9 *vertexbuffer)
510 {
511  if (!m_vertexbuffers.contains(vertexbuffer))
512  return false;
513 
514  D3D9Locker locker(this);
515  IDirect3DDevice9* dev = locker.Acquire();
516  if (!dev)
517  return false;
518 
519  IDirect3DTexture9 *texture = m_vertexbuffers[vertexbuffer].m_texture;
520 
521  if (texture && !SetTexture(dev, texture))
522  return false;
523 
524  EnableBlending(dev, true);
525  SetTextureVertices(dev, true);
526  MultiTexturing(dev, false);
527 
528  HRESULT hr = dev->SetStreamSource(0, vertexbuffer,
529  0, sizeof(TEXTUREVERTEX));
530  if (FAILED(hr))
531  {
532  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "SetStreamSource() failed");
533  return false;
534  }
535 
536  hr = dev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
537  if (FAILED(hr))
538  {
539  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "DrawPrimitive() failed");
540  return false;
541  }
542 
543  return true;
544 }
545 
546 void MythRenderD3D9::DrawRect(const QRect &rect, const QColor &color, int alpha)
547 {
548  D3D9Locker locker(this);
549  IDirect3DDevice9* dev = locker.Acquire();
550  if (!dev)
551  return;
552 
553  if (!m_rect_vertexbuffer)
554  {
555  HRESULT hr = dev->CreateVertexBuffer(
556  sizeof(VERTEX)*4, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
557  D3DFVF_VERTEX, D3DPOOL_DEFAULT,
558  &m_rect_vertexbuffer, nullptr);
559 
560  if (FAILED(hr))
561  {
562  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to create vertex buffer");
563  return;
564  }
565  }
566 
567  EnableBlending(dev, true);
568  SetTextureVertices(dev, false);
569  MultiTexturing(dev, false);
570  SetTexture(dev, nullptr, 0);
571 
572  int alphamod = (int)(color.alpha() * (alpha / 255.0));
573  D3DCOLOR clr = D3DCOLOR_ARGB(alphamod, color.red(),
574  color.green(), color.blue());
575  VERTEX *p_vertices;
576  HRESULT hr = m_rect_vertexbuffer->Lock(0, 0, (VOID **)(&p_vertices),
577  D3DLOCK_DISCARD);
578  if (FAILED(hr))
579  {
580  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to lock vertex buffer.");
581  return;
582  }
583 
584  p_vertices[0].x = (float)rect.left();
585  p_vertices[0].y = (float)rect.top();
586  p_vertices[0].z = 0.0F;
587  p_vertices[0].diffuse = clr;
588  p_vertices[0].rhw = 1.0F;
589  p_vertices[1].x = (float)(rect.left() + rect.width());
590  p_vertices[1].y = (float)rect.top();
591  p_vertices[1].z = 0.0F;
592  p_vertices[1].diffuse = clr;
593  p_vertices[1].rhw = 1.0F;
594  p_vertices[2].x = (float)(rect.left() + rect.width());
595  p_vertices[2].y = (float)(rect.top() + rect.height());
596  p_vertices[2].z = 0.0F;
597  p_vertices[2].diffuse = clr;
598  p_vertices[2].rhw = 1.0F;
599  p_vertices[3].x = (float)rect.left();
600  p_vertices[3].y = (float)(rect.top() + rect.height());
601  p_vertices[3].z = 0.0F;
602  p_vertices[3].diffuse = clr;
603  p_vertices[3].rhw = 1.0F;
604 
605  hr = m_rect_vertexbuffer->Unlock();
606  if (FAILED(hr))
607  {
608  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to unlock vertex buffer");
609  return;
610  }
611 
612  hr = dev->SetStreamSource(0, m_rect_vertexbuffer,
613  0, sizeof(VERTEX));
614  if (FAILED(hr))
615  {
616  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "SetStreamSource() failed");
617  return;
618  }
619 
620  hr = dev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
621  if (FAILED(hr))
622  {
623  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "DrawPrimitive() failed");
624  return;
625  }
626 }
627 
628 void MythRenderD3D9::MultiTexturing(IDirect3DDevice9* dev, bool enable,
629  IDirect3DTexture9 *texture)
630 {
631  if (m_multi_texturing == enable)
632  return;
633 
634  if (!dev)
635  return;
636 
637  if (enable)
638  {
639  SetTexture(dev, texture, 1);
640  dev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
641  dev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
642  dev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
643  dev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
644  dev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
645  dev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
646  dev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
647  dev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
648  }
649  else
650  {
651  dev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
652  dev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
653  dev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
654  dev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
655  dev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
656  dev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
657  dev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
658  dev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
659  SetTexture(dev, nullptr, 1);
660  }
661  m_multi_texturing = enable;
662 }
663 
665 {
666  D3D9Locker locker(this);
667  IDirect3DDevice9* dev = locker.Acquire();
668  if (!dev)
669  return false;
670 
671  HRESULT hr = dev->Present(nullptr, nullptr, win, nullptr);
672  if (FAILED(hr))
673  {
674  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Present() failed)");
675  return false;
676  }
677  SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
678  return true;
679 }
680 
681 QRect MythRenderD3D9::GetRect(IDirect3DVertexBuffer9 *vertexbuffer)
682 {
683  if (!m_vertexbuffers.contains(vertexbuffer))
684  return QRect();
685  return m_vertexbuffers[vertexbuffer].m_dest;
686 }
687 
688 bool MythRenderD3D9::SetRenderTarget(IDirect3DTexture9 *texture)
689 {
690  D3D9Locker locker(this);
691  IDirect3DDevice9* dev = locker.Acquire();
692  if (!dev)
693  return false;
694 
695  bool ret = true;
696  HRESULT hr;
697  if (texture && m_textures.contains(texture))
698  {
699  if (!m_default_surface)
700  {
701  hr = dev->GetRenderTarget(0, &m_default_surface);
702  if (FAILED(hr))
703  {
704  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
705  "Failed to get default surface.");
706  return false;
707  }
708  }
709 
710  IDirect3DSurface9 *new_surface = nullptr;
711  hr = texture->GetSurfaceLevel(0, &new_surface);
712  if (FAILED(hr))
713  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to get surface level.");
714  else
715  {
716  if (m_current_surface && m_current_surface != new_surface)
717  m_current_surface->Release();
718  m_current_surface = new_surface;
719  hr = dev->SetRenderTarget(0, m_current_surface);
720  if (FAILED(hr))
721  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
722  "Failed to set render target.");
723  }
724  }
725  else if (!texture)
726  {
727  if (m_default_surface)
728  {
729  hr = dev->SetRenderTarget(0, m_default_surface);
730  if (FAILED(hr))
731  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
732  "Failed to set render target.");
733  }
734  else
735  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
736  "No default surface for render target.");
737  }
738  else
739  ret = false;
740  return ret;
741 }
742 
743 bool MythRenderD3D9::SetTexture(IDirect3DDevice9* dev,
744  IDirect3DTexture9 *texture, int num)
745 {
746  if (!dev)
747  return false;
748 
749  HRESULT hr = dev->SetTexture(num, (LPDIRECT3DBASETEXTURE9)texture);
750  if (FAILED(hr))
751  {
752  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "SetTexture() failed");
753  return false;
754  }
755  return true;
756 }
757 
758 IDirect3DTexture9* MythRenderD3D9::CreateTexture(const QSize &size)
759 {
760  D3D9Locker locker(this);
761  IDirect3DDevice9* dev = locker.Acquire();
762  if (!dev)
763  return nullptr;
764 
765  IDirect3DTexture9* temp_texture = nullptr;
766 
767  HRESULT hr = dev->CreateTexture(
768  size.width(), size.height(), 1, D3DUSAGE_RENDERTARGET,
769  m_texture_fmt, D3DPOOL_DEFAULT, &temp_texture, nullptr);
770 
771  if (FAILED(hr) || !temp_texture)
772  {
773  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to create texture.");
774  return nullptr;
775  }
776 
777  m_textures[temp_texture] = size;;
778  return temp_texture;
779 }
780 
782 {
783  QMap<IDirect3DTexture9*,QSize>::iterator it;
784  for (it = m_textures.begin(); it != m_textures.end(); ++it)
785  it.key()->Release();
786  m_textures.clear();
787 }
788 
789 void MythRenderD3D9::DeleteTexture(IDirect3DTexture9* texture)
790 {
791  QMutexLocker locker(&m_lock);
792  if (m_textures.contains(texture))
793  {
794  texture->Release();
795  m_textures.remove(texture);
796  }
797 }
798 
799 IDirect3DSurface9* MythRenderD3D9::CreateSurface(const QSize &size, bool video)
800 {
801  D3D9Locker locker(this);
802  IDirect3DDevice9* dev = locker.Acquire();
803  if (!dev)
804  return nullptr;
805 
806  IDirect3DSurface9* temp_surface = nullptr;
807 
808  D3DFORMAT format = video ? m_videosurface_fmt : m_surface_fmt;
809 
810  HRESULT hr = dev->CreateOffscreenPlainSurface(
811  size.width(), size.height(), format,
812  D3DPOOL_DEFAULT, &temp_surface, nullptr);
813 
814  if (FAILED(hr)|| !temp_surface)
815  {
816  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to create surface.");
817  return nullptr;
818  }
819 
820  m_surfaces[temp_surface] = MythD3DSurface(size, format);
821  dev->ColorFill(temp_surface, nullptr, D3DCOLOR_ARGB(0xFF, 0, 0, 0) );
822 
823  return temp_surface;
824 }
825 
826 bool MythRenderD3D9::UpdateSurface(IDirect3DSurface9 *surface,
827  const MythImage *image)
828 {
829  if (!surface || !image || !m_surfaces.contains(surface))
830  return false;
831 
832  if (m_surfaces[surface].m_size.width() != image->width() ||
833  m_surfaces[surface].m_size.height() != image->height())
834  {
835  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
836  "Frame size does not equal surface size.");
837  return false;
838  }
839 
840  uint d3dpitch = 0;
841  uint8_t *buf = GetBuffer(surface, d3dpitch);
842 
843  if (!(buf && d3dpitch))
844  return false;
845 
846  D3DFORMAT format = m_surfaces[surface].m_fmt;
847  switch (format)
848  {
849  case D3DFMT_A8R8G8B8:
850  case D3DFMT_X8R8G8B8:
851  {
852  uint pitch = image->width() << 2;
853  uint8_t *dst = buf;
854  uint8_t *src = (uint8_t*)image->bits();
855  for (int i = 0; i < image->height(); i++)
856  {
857  memcpy(dst, src, pitch);
858  dst += d3dpitch;
859  src += pitch;
860  }
861  }
862  break;
863  default:
864  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Surface format not supported.");
865  break;
866  }
867 
868  ReleaseBuffer(surface);
869  return true;
870 }
871 
873 {
874  QMap<IDirect3DSurface9*, MythD3DSurface>::iterator it;
875  for (it = m_surfaces.begin(); it != m_surfaces.end(); ++it)
876  it.key()->Release();
877  m_surfaces.clear();
878 }
879 
880 void MythRenderD3D9::DeleteSurface(IDirect3DSurface9 *surface)
881 {
882  QMutexLocker locker(&m_lock);
883  if (m_surfaces.contains(surface))
884  {
885  surface->Release();
886  m_surfaces.remove(surface);
887  }
888 }
889 
890 uint8_t* MythRenderD3D9::GetBuffer(IDirect3DSurface9* surface, uint &pitch)
891 {
892  if (!m_surfaces.contains(surface))
893  return nullptr;
894 
895  m_lock.lock(); // unlocked in release buffer
896  D3DLOCKED_RECT d3drect;
897  HRESULT hr = surface->LockRect(&d3drect, nullptr, 0);
898 
899  if (FAILED(hr))
900  {
901  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to lock picture surface.");
902  m_lock.unlock();
903  return nullptr;
904  }
905 
906  pitch = d3drect.Pitch;
907  return (uint8_t*)d3drect.pBits;
908 }
909 
910 void MythRenderD3D9::ReleaseBuffer(IDirect3DSurface9* surface)
911 {
912  if (!m_surfaces.contains(surface))
913  return;
914 
915  HRESULT hr = surface->UnlockRect();
916  if (FAILED(hr))
917  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to unlock picture surface.");
918  m_lock.unlock();
919 }
920 
921 IDirect3DVertexBuffer9* MythRenderD3D9::CreateVertexBuffer(IDirect3DTexture9* texture)
922 {
923  D3D9Locker locker(this);
924  IDirect3DDevice9* dev = locker.Acquire();
925  if (!dev)
926  return nullptr;
927 
928  if (texture && !m_textures.contains(texture))
929  return nullptr;
930 
931  IDirect3DVertexBuffer9* temp_vbuf = nullptr;
932  HRESULT hr = dev->CreateVertexBuffer(
933  sizeof(TEXTUREVERTEX)*4, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
934  D3DFVF_TEXTUREVERTEX, D3DPOOL_DEFAULT,
935  &temp_vbuf, nullptr);
936 
937  if (FAILED(hr))
938  {
939  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to create vertex buffer");
940  return nullptr;
941  }
942 
943  m_vertexbuffers[temp_vbuf] = MythD3DVertexBuffer(texture);
944  return temp_vbuf;
945 }
946 
948 {
949  QMap<IDirect3DVertexBuffer9*,MythD3DVertexBuffer>::iterator it;
950  for (it = m_vertexbuffers.begin();
951  it != m_vertexbuffers.end(); ++it)
952  {
953  it.key()->Release();
954  }
955  m_vertexbuffers.clear();
956 }
957 
958 void MythRenderD3D9::DeleteVertexBuffer(IDirect3DVertexBuffer9 *vertexbuffer)
959 {
960  QMutexLocker locker(&m_lock);
961  if (m_vertexbuffers.contains(vertexbuffer))
962  {
963  vertexbuffer->Release();
964  m_vertexbuffers.remove(vertexbuffer);
965  }
966 }
967 
968 bool MythRenderD3D9::UpdateVertexBuffer(IDirect3DVertexBuffer9* vertexbuffer,
969  const QRect &dst, const QRect &src,
970  int alpha, bool video)
971 {
972  if (!m_vertexbuffers.contains(vertexbuffer))
973  return false;
974 
975  MythD3DVertexBuffer mythvb = m_vertexbuffers[vertexbuffer];
976  uint32_t clr = (alpha << 24) + (255 << 16) + (255 << 8) + 255;
977 
978  int width = dst.width();
979  int height = dst.height();
980  if (!video)
981  {
982  width = std::min(src.width(), width);
983  height = std::min(src.height(), height);
984  }
985  QRect dest(dst.left(), dst.top(), width, height);
986 
987  // FIXME - with alpha pulse, this updates far more textures than necessary
988  if (dest == mythvb.m_dest &&
989  src == mythvb.m_src &&
990  clr == mythvb.m_color)
991  return true;
992 
993  QSize norm = src.size();
994  if (video && mythvb.m_texture)
995  norm = m_textures[mythvb.m_texture];
996 
997  QMutexLocker locker(&m_lock);
998  TEXTUREVERTEX *p_vertices;
999  HRESULT hr = vertexbuffer->Lock(0, 0, (VOID **)(&p_vertices),
1000  D3DLOCK_DISCARD);
1001  D3DCOLOR color = D3DCOLOR_ARGB(alpha, 255, 255, 255);
1002  if (FAILED(hr))
1003  {
1004  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to lock vertex buffer.");
1005  return false;
1006  }
1007 
1008  p_vertices[0].x = (float)dest.left();
1009  p_vertices[0].y = (float)dest.top();
1010  p_vertices[0].z = 0.0F;
1011  p_vertices[0].diffuse = color;
1012  p_vertices[0].rhw = 1.0F;
1013  p_vertices[0].t1u = ((float)src.left() - 0.5F) / (float)norm.width();
1014  p_vertices[0].t1v = ((float)src.top() - 0.5F) / (float)norm.height();
1015 
1016  p_vertices[1].x = (float)(dest.left() + dest.width());
1017  p_vertices[1].y = (float)dest.top();
1018  p_vertices[1].z = 0.0F;
1019  p_vertices[1].diffuse = color;
1020  p_vertices[1].rhw = 1.0F;
1021  p_vertices[1].t1u = ((float)(src.left() + src.width()) - 0.5F) /
1022  (float)norm.width();
1023  p_vertices[1].t1v = ((float)src.top() - 0.5F) / (float)norm.height();
1024 
1025  p_vertices[2].x = (float)(dest.left() + dest.width());
1026  p_vertices[2].y = (float)(dest.top() + dest.height());
1027  p_vertices[2].z = 0.0F;
1028  p_vertices[2].diffuse = color;
1029  p_vertices[2].rhw = 1.0F;
1030  p_vertices[2].t1u = ((float)(src.left() + src.width()) - 0.5F) /
1031  (float)norm.width();
1032  p_vertices[2].t1v = ((float)(src.top() + src.height()) - 0.5F) /
1033  (float)norm.height();
1034 
1035  p_vertices[3].x = (float)dest.left();
1036  p_vertices[3].y = (float)(dest.top() + dest.height());
1037  p_vertices[3].z = 0.0F;
1038  p_vertices[3].diffuse = color;
1039  p_vertices[3].rhw = 1.0F;
1040  p_vertices[3].t1u = ((float)src.left() - 0.5F) / (float)norm.width();
1041  p_vertices[3].t1v = ((float)(src.top() + src.height()) - 0.5F) /
1042  (float)norm.height();
1043 
1044  p_vertices[0].t2u = p_vertices[0].t1u;
1045  p_vertices[0].t2v = p_vertices[0].t1v;
1046  p_vertices[1].t2u = p_vertices[1].t1u;
1047  p_vertices[1].t2v = p_vertices[1].t1v;
1048  p_vertices[2].t2u = p_vertices[2].t1u;
1049  p_vertices[2].t2v = p_vertices[2].t1v;
1050  p_vertices[3].t2u = p_vertices[3].t1u;
1051  p_vertices[3].t2v = p_vertices[3].t1v;
1052 
1053  hr = vertexbuffer->Unlock();
1054  if (FAILED(hr))
1055  {
1056  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to unlock vertex buffer");
1057  return false;
1058  }
1059 
1060  m_vertexbuffers[vertexbuffer].m_dest = dest;
1061  m_vertexbuffers[vertexbuffer].m_src = src;
1062  m_vertexbuffers[vertexbuffer].m_color = clr;
1063  return true;
1064 }
1065 
1067 {
1068  IDirect3DDevice9* dev = AcquireDevice();
1069  if (!dev)
1070  return;
1071 
1072  dev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1073  dev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1074  dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1075  dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1076  dev->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1077  dev->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1078  dev->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1079  dev->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1080  dev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255,255,255));
1081  dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
1082  dev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
1083  dev->SetRenderState(D3DRS_LIGHTING, FALSE);
1084  dev->SetRenderState(D3DRS_DITHERENABLE, TRUE);
1085  dev->SetRenderState(D3DRS_STENCILENABLE, FALSE);
1086  dev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1087  dev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1088  dev->SetVertexShader(nullptr);
1089  SetTextureVertices(dev, false);
1090  MultiTexturing(dev, false);
1091  EnableBlending(dev, false);
1092 
1093  ReleaseDevice();
1094 }
1095 
1096 void MythRenderD3D9::EnableBlending(IDirect3DDevice9* dev, bool enable)
1097 {
1098  if (m_blend == enable)
1099  return;
1100  m_blend = enable;
1101 
1102  if (dev)
1103  dev->SetRenderState(D3DRS_ALPHABLENDENABLE, enable);
1104 }
1105 
1106 void MythRenderD3D9::SetTextureVertices(IDirect3DDevice9* dev, bool enable)
1107 {
1108  if (m_texture_vertices == enable)
1109  return;
1110  m_texture_vertices = enable;
1111 
1112  if (dev)
1113  dev->SetFVF(enable ? D3DFVF_TEXTUREVERTEX : D3DFVF_VERTEX);
1114 }
1115 
1116 IDirect3DDevice9* MythRenderD3D9::AcquireDevice(void)
1117 {
1118  m_lock.lock();
1119 #ifdef USING_DXVA2
1120  if (m_deviceManager)
1121  {
1122  IDirect3DDevice9* result = nullptr;
1123 
1124  HRESULT hr = IDirect3DDeviceManager9_LockDevice(m_deviceManager, m_deviceHandle, &result, true);
1125 
1126  if (hr == DXVA2_E_NEW_VIDEO_DEVICE)
1127  {
1128  hr = IDirect3DDeviceManager9_CloseDeviceHandle(m_deviceManager, m_deviceHandle);
1129 
1130  if (SUCCEEDED(hr))
1131  hr = IDirect3DDeviceManager9_OpenDeviceHandle(m_deviceManager, &m_deviceHandle);
1132 
1133  if (SUCCEEDED(hr))
1134  hr = IDirect3DDeviceManager9_LockDevice(m_deviceManager, m_deviceHandle, &result, true);
1135  }
1136 
1137  if (SUCCEEDED(hr))
1138  return result;
1139 
1140  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to acquire D3D9 device.");
1141  m_lock.unlock();
1142  return nullptr;
1143  }
1144 #endif
1145  return m_rootD3DDevice;
1146 }
1147 
1149 {
1150 #ifdef USING_DXVA2
1151  if (m_deviceManager)
1152  {
1153  HRESULT hr = IDirect3DDeviceManager9_UnlockDevice(m_deviceManager, m_deviceHandle, false);
1154  if (!SUCCEEDED(hr))
1155  LOG(VB_GENERAL, LOG_ERR, D3DLOC + "Failed to release D3D9 device.");
1156  }
1157 #endif
1158  m_lock.unlock();
1159 }
1160 
1161 #ifdef USING_DXVA2
1162 using CreateDeviceManager9Ptr = HRESULT (WINAPI *)(UINT *pResetToken,
1163  IDirect3DDeviceManager9 **);
1164 #endif
1165 
1167 {
1168 #ifdef USING_DXVA2
1169  CreateDeviceManager9Ptr CreateDeviceManager9 =
1171  "DXVA2CreateDirect3DDeviceManager9");
1172  if (CreateDeviceManager9)
1173  {
1174  UINT resetToken = 0;
1175  HRESULT hr = CreateDeviceManager9(&resetToken, &m_deviceManager);
1176  if (SUCCEEDED(hr))
1177  {
1178  IDirect3DDeviceManager9_ResetDevice(m_deviceManager, m_rootD3DDevice, resetToken);
1179  IDirect3DDeviceManager9_AddRef(m_deviceManager);
1180  m_deviceManagerToken = resetToken;
1181  LOG(VB_GENERAL, LOG_INFO, D3DLOC + "Created DXVA2 device manager.");
1182  hr = IDirect3DDeviceManager9_OpenDeviceHandle(m_deviceManager, &m_deviceHandle);
1183  if (SUCCEEDED(hr))
1184  {
1185  LOG(VB_GENERAL, LOG_INFO, D3DLOC + "Retrieved device handle.");
1186  return;
1187  }
1188  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
1189  "Failed to retrieve device handle.");
1190  }
1191  else
1192  {
1193  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
1194  "Failed to create DXVA2 device manager.");
1195  }
1196  }
1197  else
1198  {
1199  LOG(VB_GENERAL, LOG_ERR, D3DLOC +
1200  "Failed to get DXVA2CreateDirect3DDeviceManager9 proc address.");
1201  }
1202 #endif
1203  m_deviceManager = nullptr;
1205  LOG(VB_GENERAL, LOG_NOTICE, D3DLOC +
1206  "DXVA2 support not available - not using device manager");
1207 }
1208 
1210 {
1211 #ifdef USING_DXVA2
1213  IDirect3DDeviceManager9_CloseDeviceHandle(m_deviceManager, m_deviceHandle);
1214  if (m_deviceManager)
1215  IDirect3DDeviceManager9_Release(m_deviceManager);
1216 #endif
1217  m_deviceHandle = nullptr;
1218  m_deviceManager = nullptr;
1219 }
MythRenderD3D9::m_videosurface_fmt
D3DFORMAT m_videosurface_fmt
Definition: mythrender_d3d9.h:152
build_compdb.dest
dest
Definition: build_compdb.py:9
MythRenderD3D9::DeleteVertexBuffers
void DeleteVertexBuffers(void)
Definition: mythrender_d3d9.cpp:947
MythD3DVertexBuffer
Definition: mythrender_d3d9.h:64
MythRenderD3D9::m_surface_fmt
D3DFORMAT m_surface_fmt
Definition: mythrender_d3d9.h:153
MythD3DVertexBuffer::m_color
uint32_t m_color
Definition: mythrender_d3d9.h:73
MythRenderD3D9::m_rect_vertexbuffer
IDirect3DVertexBuffer9 * m_rect_vertexbuffer
Definition: mythrender_d3d9.h:155
D3D9Image::UpdateVertices
bool UpdateVertices(const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
Definition: mythrender_d3d9.cpp:89
D3DFVF_VERTEX
#define D3DFVF_VERTEX
Definition: mythrender_d3d9.cpp:133
D3D9Image::m_vertexbuffer
IDirect3DVertexBuffer9 * m_vertexbuffer
Definition: mythrender_d3d9.h:48
D3D9Image::SetAsRenderTarget
bool SetAsRenderTarget(void)
Definition: mythrender_d3d9.cpp:64
VERTEX
Definition: mythrender_d3d9.cpp:30
MythRenderD3D9::m_textures
QMap< IDirect3DTexture9 *, QSize > m_textures
Definition: mythrender_d3d9.h:145
MythRenderD3D9::DrawTexturedQuad
bool DrawTexturedQuad(IDirect3DVertexBuffer9 *vertexbuffer)
Definition: mythrender_d3d9.cpp:509
TEXTUREVERTEX::diffuse
D3DCOLOR diffuse
Definition: mythrender_d3d9.cpp:23
TEXTUREVERTEX::t2v
FLOAT t2v
Definition: mythrender_d3d9.cpp:27
MythRenderD3D9::DeleteVertexBuffer
void DeleteVertexBuffer(IDirect3DVertexBuffer9 *vertexbuffer)
Definition: mythrender_d3d9.cpp:958
MythRenderD3D9::StretchRect
bool StretchRect(IDirect3DTexture9 *texture, IDirect3DSurface9 *surface, bool known_surface=true)
Definition: mythrender_d3d9.cpp:477
MythRenderD3D9::m_deviceManagerToken
uint m_deviceManagerToken
Definition: mythrender_d3d9.h:176
VERTEX::rhw
FLOAT rhw
Definition: mythrender_d3d9.cpp:35
toString
static const QString toString(D3DFORMAT fmt)
Definition: mythrender_d3d9.cpp:189
MythRenderD3D9::DeleteTexture
void DeleteTexture(IDirect3DTexture9 *texture)
Definition: mythrender_d3d9.cpp:789
MythRenderD3D9::m_multi_texturing
bool m_multi_texturing
Definition: mythrender_d3d9.h:161
TEXTUREVERTEX::rhw
FLOAT rhw
Definition: mythrender_d3d9.cpp:22
MythD3DVertexBuffer::m_src
QRect m_src
Definition: mythrender_d3d9.h:75
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
D3D9Image::~D3D9Image
~D3D9Image()
Definition: mythrender_d3d9.cpp:51
MythRenderD3D9::m_blend
bool m_blend
Definition: mythrender_d3d9.h:160
MythRenderD3D9::CreateVertexBuffer
IDirect3DVertexBuffer9 * CreateVertexBuffer(IDirect3DTexture9 *texture=nullptr)
Definition: mythrender_d3d9.cpp:921
MythRenderD3D9::Create
bool Create(QSize size, HWND window)
Definition: mythrender_d3d9.cpp:221
MythD3DVertexBuffer::m_texture
IDirect3DTexture9 * m_texture
Definition: mythrender_d3d9.h:76
MythRenderD3D9::m_current_surface
IDirect3DSurface9 * m_current_surface
Definition: mythrender_d3d9.h:157
CreateDeviceManager9Ptr
HRESULT(WINAPI *)(UINT *pResetToken, IDirect3DDeviceManager9 **) CreateDeviceManager9Ptr
Definition: mythrender_d3d9.cpp:1163
MythD3DVertexBuffer::m_dest
QRect m_dest
Definition: mythrender_d3d9.h:74
MythRenderD3D9::SetTexture
bool SetTexture(IDirect3DDevice9 *dev, IDirect3DTexture9 *texture, int num=0)
Definition: mythrender_d3d9.cpp:743
D3D9Locker::Acquire
IDirect3DDevice9 * Acquire(void)
Definition: mythrender_d3d9.cpp:142
MythRenderD3D9::End
bool End(void)
Definition: mythrender_d3d9.cpp:455
D3D9Image::m_valid
bool m_valid
Definition: mythrender_d3d9.h:46
mD3DFMT_YV12
#define mD3DFMT_YV12
Definition: mythrender_d3d9.cpp:128
MythRenderD3D9::UpdateVertexBuffer
bool UpdateVertexBuffer(IDirect3DVertexBuffer9 *vertexbuffer, const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
Definition: mythrender_d3d9.cpp:968
TEXTUREVERTEX
Definition: mythrender_d3d9.cpp:17
MythRenderD3D9::m_texture_fmt
D3DFORMAT m_texture_fmt
Definition: mythrender_d3d9.h:154
MythRenderD3D9::ClearBuffer
bool ClearBuffer(void)
Definition: mythrender_d3d9.cpp:422
VERTEX::z
FLOAT z
Definition: mythrender_d3d9.cpp:34
mythlogging.h
MythRenderD3D9::CreateTexture
IDirect3DTexture9 * CreateTexture(const QSize &size)
Definition: mythrender_d3d9.cpp:758
MythRenderD3D9::GetBuffer
uint8_t * GetBuffer(IDirect3DSurface9 *surface, uint &pitch)
Definition: mythrender_d3d9.cpp:890
MythRenderD3D9::m_vertexbuffers
QMap< IDirect3DVertexBuffer9 *, MythD3DVertexBuffer > m_vertexbuffers
Definition: mythrender_d3d9.h:146
MythRenderD3D9::GetRect
QRect GetRect(IDirect3DVertexBuffer9 *vertexbuffer)
Definition: mythrender_d3d9.cpp:681
D3D9Image::GetBuffer
uint8_t * GetBuffer(bool &hardware_conv, uint &pitch)
Definition: mythrender_d3d9.cpp:104
MythRenderD3D9::ReleaseDevice
void ReleaseDevice(void)
Definition: mythrender_d3d9.cpp:1148
D3D9Image
Definition: mythrender_d3d9.h:25
MythRenderD3D9::EnableBlending
void EnableBlending(IDirect3DDevice9 *dev, bool enable)
Definition: mythrender_d3d9.cpp:1096
MythRenderD3D9::CreateDeviceManager
void CreateDeviceManager(void)
Definition: mythrender_d3d9.cpp:1166
MythRenderD3D9::m_adaptor_fmt
D3DFORMAT m_adaptor_fmt
Definition: mythrender_d3d9.h:151
MythRenderD3D9::DrawRect
void DrawRect(const QRect &rect, const QColor &color, int alpha)
Definition: mythrender_d3d9.cpp:546
MythRenderD3D9
Definition: mythrender_d3d9.h:91
MythRenderD3D9::MultiTexturing
void MultiTexturing(IDirect3DDevice9 *dev, bool enable, IDirect3DTexture9 *texture=nullptr)
Definition: mythrender_d3d9.cpp:628
MythRenderD3D9::Present
bool Present(HWND win)
Definition: mythrender_d3d9.cpp:664
MythRenderD3D9::m_lock
QRecursiveMutex m_lock
Definition: mythrender_d3d9.h:159
MythRenderD3D9::~MythRenderD3D9
virtual ~MythRenderD3D9()
Definition: mythrender_d3d9.cpp:157
MythRenderD3D9::DeleteSurfaces
void DeleteSurfaces(void)
Definition: mythrender_d3d9.cpp:872
D3D9Image::m_texture
IDirect3DTexture9 * m_texture
Definition: mythrender_d3d9.h:49
MythRenderD3D9::m_default_surface
IDirect3DSurface9 * m_default_surface
Definition: mythrender_d3d9.h:156
MythRenderD3D9::ReleaseBuffer
void ReleaseBuffer(IDirect3DSurface9 *surface)
Definition: mythrender_d3d9.cpp:910
mD3DFMT_I420
#define mD3DFMT_I420
Definition: mythrender_d3d9.cpp:130
uint
unsigned int uint
Definition: compat.h:81
MythRenderD3D9::UpdateSurface
bool UpdateSurface(IDirect3DSurface9 *surface, const MythImage *image)
Definition: mythrender_d3d9.cpp:826
MythRenderD3D9::ResolveAddress
static void * ResolveAddress(const char *lib, const char *proc)
Definition: mythrender_d3d9.cpp:152
D3D9Image::GetRect
QRect GetRect(void)
Definition: mythrender_d3d9.cpp:121
MythRenderD3D9::m_surfaces
QMap< IDirect3DSurface9 *, MythD3DSurface > m_surfaces
Definition: mythrender_d3d9.h:147
VERTEX::diffuse
D3DCOLOR diffuse
Definition: mythrender_d3d9.cpp:36
TEXTUREVERTEX::t2u
FLOAT t2u
Definition: mythrender_d3d9.cpp:26
MythRenderD3D9::HardwareYUVConversion
bool HardwareYUVConversion(void)
Definition: mythrender_d3d9.cpp:374
MythRenderD3D9::SetRenderTarget
bool SetRenderTarget(IDirect3DTexture9 *texture)
Definition: mythrender_d3d9.cpp:688
MythRenderD3D9::DeleteTextures
void DeleteTextures(void)
Definition: mythrender_d3d9.cpp:781
MythRenderD3D9::CopyFrame
void CopyFrame(void *surface, D3D9Image *img)
Definition: mythrender_d3d9.cpp:471
MythRenderD3D9::AcquireDevice
IDirect3DDevice9 * AcquireDevice(void)
Definition: mythrender_d3d9.cpp:1116
D3D9Locker
Definition: mythrender_d3d9.h:53
MythRenderD3D9::Init2DState
void Init2DState(void)
Definition: mythrender_d3d9.cpp:1066
D3D9Image::D3D9Image
D3D9Image(MythRenderD3D9 *render, QSize size, bool video=false)
Definition: mythrender_d3d9.cpp:39
D3DLOC
#define D3DLOC
Definition: mythrender_d3d9.cpp:134
MythRenderD3D9::CreateSurface
IDirect3DSurface9 * CreateSurface(const QSize &size, bool video=false)
Definition: mythrender_d3d9.cpp:799
TEXTUREVERTEX::x
FLOAT x
Definition: mythrender_d3d9.cpp:19
MythRenderD3D9::Begin
bool Begin(void)
Definition: mythrender_d3d9.cpp:439
DXVA2_E_NEW_VIDEO_DEVICE
#define DXVA2_E_NEW_VIDEO_DEVICE
Definition: mythrender_d3d9.cpp:14
D3D9Image::UpdateImage
bool UpdateImage(IDirect3DSurface9 *surface)
Definition: mythrender_d3d9.cpp:71
mD3DFMT_YV16
#define mD3DFMT_YV16
Definition: mythrender_d3d9.cpp:131
MythRenderD3D9::m_deviceManager
IDirect3DDeviceManager9 * m_deviceManager
Definition: mythrender_d3d9.h:174
D3D9Image::Draw
bool Draw(void)
Definition: mythrender_d3d9.cpp:97
D3DFVF_TEXTUREVERTEX
#define D3DFVF_TEXTUREVERTEX
Definition: mythrender_d3d9.cpp:132
MythImage
Definition: mythimage.h:36
MythRenderD3D9::Test
bool Test(bool &reset)
Definition: mythrender_d3d9.cpp:379
TEXTUREVERTEX::z
FLOAT z
Definition: mythrender_d3d9.cpp:21
D3D9Image::m_size
QSize m_size
Definition: mythrender_d3d9.h:45
mythrender_d3d9.h
MythRenderD3D9::SetTextureVertices
void SetTextureVertices(IDirect3DDevice9 *dev, bool enable)
Definition: mythrender_d3d9.cpp:1106
VERTEX::x
FLOAT x
Definition: mythrender_d3d9.cpp:32
VERTEX::y
FLOAT y
Definition: mythrender_d3d9.cpp:33
MythRenderD3D9::m_texture_vertices
bool m_texture_vertices
Definition: mythrender_d3d9.h:162
mD3DFMT_IYUV
#define mD3DFMT_IYUV
Definition: mythrender_d3d9.cpp:129
MythRender::m_size
QSize m_size
Definition: mythrender_base.h:43
D3D9Locker::~D3D9Locker
~D3D9Locker()
Definition: mythrender_d3d9.cpp:136
D3D9Locker::m_render
MythRenderD3D9 * m_render
Definition: mythrender_d3d9.h:61
TEXTUREVERTEX::y
FLOAT y
Definition: mythrender_d3d9.cpp:20
MythRenderD3D9::m_rootD3DDevice
IDirect3DDevice9 * m_rootD3DDevice
Definition: mythrender_d3d9.h:150
TEXTUREVERTEX::t1u
FLOAT t1u
Definition: mythrender_d3d9.cpp:24
TEXTUREVERTEX::t1v
FLOAT t1v
Definition: mythrender_d3d9.cpp:25
MythRenderD3D9::m_d3d
IDirect3D9 * m_d3d
Definition: mythrender_d3d9.h:149
MythRenderD3D9::m_deviceHandle
HANDLE m_deviceHandle
Definition: mythrender_d3d9.h:175
MythD3DSurface
Definition: mythrender_d3d9.h:79
D3D9Image::m_surface
IDirect3DSurface9 * m_surface
Definition: mythrender_d3d9.h:50
D3D9Image::ReleaseBuffer
void ReleaseBuffer(void)
Definition: mythrender_d3d9.cpp:113
MythRenderD3D9::DestroyDeviceManager
void DestroyDeviceManager(void)
Definition: mythrender_d3d9.cpp:1209
D3D9Image::m_render
MythRenderD3D9 * m_render
Definition: mythrender_d3d9.h:47
MythRenderD3D9::DeleteSurface
void DeleteSurface(IDirect3DSurface9 *surface)
Definition: mythrender_d3d9.cpp:880