我有IDirect3DSurface9,默认池,YUV格式。我怎样才能有效地从中获取位图位?目前我:
device->CreateRenderTarget(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &render_target, NULL)
device->StretchRect(videomem_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
这看起来有点开销,因为有很多复制:从原始表面到渲染目标,然后到屏幕外表面,再到兼容位图,最后到我的缓冲区。如何改进?
感谢
答案 0 :(得分:4)
当interjay指出......你几乎是以“正确”的方式做事。
显而易见的改进是调用CreateRenderTarget和CreateOffscreenPlainSurface一次,然后多次重复使用它们。将比特退出的最快方法是直接锁定表面。
此外,如果您需要在像视频这样的东西上实时执行此操作,那么设置一个曲面阵列(两种类型)可能会更好。然后,您可以将多个YUV帧加载到CreateRenderTarget'd表面,然后填充数组后,将第一个复制到OffscreenPlainSurface并锁定它。
通过这种方式,您将允许更多的命令被流水线操作,并停止调用锁定和强制管道的同步(即,在继续之前锁定HAS以准备就绪,这会导致管道同步)。
答案 1 :(得分:3)
由于您以可锁定模式创建渲染目标(第6个参数为CreateRenderTarget
),您可以使用LockRect
锁定渲染目标并直接从那里复制数据。
MSDN建议不要使用可锁定的渲染目标,says:
如果您需要对渲染目标的读访问权限,请使用GetRenderTargetData而不是可锁定 渲染目标。
另一种方法是将GetRenderTargetData
调用到屏幕外表面,然后锁定屏幕外表面(而不是使用DC和位图)。