Direct3D: forma eficaz de obtener mapa de bits de memoria del sistema de IDirect3DSurface9 (agrupación por omisión)?

StackOverflow https://stackoverflow.com/questions/4430204

Pregunta

Tengo IDirect3DSurface9, piscina defecto, formato YUV. ¿Cómo puedo conseguir de manera eficiente mapa de bits bits de ella? En el momento en que:

    crear destino de representación:
    device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
    convertir de YUV a RGB32:
    device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
    (Rectángulo completa, sin estiramiento)
    crear una superficie llana fuera de la pantalla en la memoria del sistema
    device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
    Copiar datos de vídeo a mem sysmem:
    device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
    GetDC desde fuera de la pantalla superficie, DC crear mapa de bits compatibles y compatibles, BitBlt desde fuera de la pantalla sufrace DC a DC compatible y copiar los bits de mapa de bits a mi memoria intermedia por GetDIBits ()

Esto se ve un poco de cabeza, debido a que muchos de copia: de superficie original de destino de representación, a continuación, a fuera de la pantalla superficie, entonces al mapa de bits compatibles, y, finalmente, a mi memoria intermedia. ¿Cómo se puede mejorar?

gracias

¿Fue útil?

Solución

Desde que se crea destino de representación en el modo bloqueable (sexto parámetro para CreateRenderTarget), puede bloquear el objetivo procesamiento con LockRect y copiar los datos directamente desde allí.

MSDN no recomienda el uso de cerradura rendir objetivos, y dice:

Si necesita acceso de lectura para rendir objetivos, utilice GetRenderTargetData en lugar de llave render objetivos.

Así que una alternativa es llamar GetRenderTargetData en la superficie fuera de la pantalla, y luego bloquear la superficie fuera de la pantalla (en lugar de utilizar las DC y mapas de bits).

Otros consejos

Bien como puntos interjay fuera ... que está casi haciendo las cosas de la manera "correcta".

Las mejoras son evidentes para llamar CreateRenderTarget y CreateOffscreenPlainSurface una vez y luego las vuelve a utilizar varias veces. La forma más rápida de conseguir los bits hacia afuera sería directamente LockRect la superficie.

Por otra parte, si usted está necesitando hacer esto en tiempo real en algo como el vídeo, probablemente sería mejor establecer una serie de superficies (ambos tipos). A continuación, puede cargar múltiples marcos YUV sobre la superficie CreateRenderTarget'd y luego una vez que haya llenado la matriz a continuación, copie el primero en el OffscreenPlainSurface y bloquearlo.

De esta manera se permitirá más de los comandos para ser canalizado y dejar que llamar bloqueo y forzar una sincronización de la tubería (es decir, la superficie que está de bloqueo tiene que estar listo antes de continuar lo que provoca una sincronización tubería).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top