Direct3D: effizient Systemspeicher Bitmap aus IDirect3DSurface9 (Standard-Pool) zu bekommen?
-
09-10-2019 - |
Frage
Ich habe IDirect3DSurface9, Standard-Pool, YUV-Format. Wie kann ich effizient Bits davon Bitmap? Im Moment habe ich:
- erstellen Ziel machen:
device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
- convert YUV zu RGB32:
device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
(Vollständiges Rechteck, kein Strecken)
- Ebene offscreen Oberfläche im Systemspeicher
erstellen
device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
- Kopieren von Daten von Video mem zu sysmem:
device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
- GetDC von Off-Screen-Oberfläche, schaffen kompatibel DC und kompatible Bitmap BitBlt von Offscreen sufrace DC an kompatible DC und kopieren Bitmap-Bits zu meinem Puffer durch GetDIBits ()
sieht das ein wenig Overhead, weil so viele Kopieren: von den ursprünglichen Oberfläche Ziel zu machen, dann zu offscreen Oberfläche, dann an kompatible Bitmap, und dann schließlich zu meinem Puffer. Wie kann diese verbessert werden?
Dank
Lösung
Da Sie Sie Ziel in abschließbaren Modus (6. Parameter CreateRenderTarget
) machen zu erstellen, können Sie die Renderziel mit LockRect
sperren und kopieren Sie die Daten direkt von dort aus.
Andere Tipps
Nun, wie interjay Punkte aus ... Sie sind fast Dinge zu tun, die „richtige“ Art und Weise.
Die offensichtlichen Verbesserungen sind CreateRenderTarget und CreateOffscreenPlainSurface nennen einmal und dann mehrmals wiederverwenden. Der schnellste Weg, um die Bits immer wieder aus, um direkt LockRect der Oberfläche sein würde.
Darüber hinaus, wenn Sie diese benötigen, sind in wie Video auf etwas in Echtzeit zu tun, wäre es wahrscheinlich besser, eine Reihe von Oberflächen einzurichten (beide Typen). Sie können dann mehr YUV-Frames auf die CreateRenderTarget'd Oberfläche laden und dann, wenn Sie das Array gefüllt haben kopieren Sie dann die ersten die OffscreenPlainSurface und es sperren.
Auf diese Weise können mehrere der Befehle erlauben Pipeline- sein und stoppen Sie Sperre aufrufen und Erzwingen einer Synchronisierung der Pipeline (dh die Oberfläche HAS Sie Sperren, bevor Sie fortfahren, bereit sein, die eine Pipeline-Sync verursacht).