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