[PATCH] mfplat/buffer: Avoid two copies when locking a D3D9 buffer if possible.
Giovanni Mascellani
gmascellani at codeweavers.com
Fri Feb 11 01:54:17 CST 2022
Running CHRONO TRIGGER with this commit saves at least 3 ms per frame
in the sample copier on my computer.
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
dlls/mfplat/buffer.c | 42 +++++++++++++++++++++++++++++++-----------
1 file changed, 31 insertions(+), 11 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
index f161bb29d80..e20961169f8 100644
--- a/dlls/mfplat/buffer.c
+++ b/dlls/mfplat/buffer.c
@@ -57,6 +57,7 @@ struct buffer
int pitch;
unsigned int locks;
p_copy_image_func copy_image;
+ BOOL copy;
} _2d;
struct
{
@@ -380,17 +381,28 @@ static HRESULT WINAPI d3d9_surface_buffer_Lock(IMFMediaBuffer *iface, BYTE **dat
{
D3DLOCKED_RECT rect;
- if (!(buffer->_2d.linear_buffer = malloc(ALIGN_SIZE(buffer->_2d.plane_size, MF_64_BYTE_ALIGNMENT))))
- hr = E_OUTOFMEMORY;
+ hr = IDirect3DSurface9_LockRect(buffer->d3d9_surface.surface, &rect, NULL, 0);
if (SUCCEEDED(hr))
{
- hr = IDirect3DSurface9_LockRect(buffer->d3d9_surface.surface, &rect, NULL, 0);
- if (SUCCEEDED(hr))
+ if (rect.Pitch == buffer->_2d.width)
{
- copy_image(buffer, buffer->_2d.linear_buffer, buffer->_2d.width, rect.pBits, rect.Pitch,
- buffer->_2d.width, buffer->_2d.height);
- IDirect3DSurface9_UnlockRect(buffer->d3d9_surface.surface);
+ buffer->_2d.linear_buffer = rect.pBits;
+ buffer->_2d.copy = FALSE;
+ }
+ else
+ {
+ if ((buffer->_2d.linear_buffer = malloc(ALIGN_SIZE(buffer->_2d.plane_size, MF_64_BYTE_ALIGNMENT))))
+ {
+ copy_image(buffer, buffer->_2d.linear_buffer, buffer->_2d.width, rect.pBits, rect.Pitch,
+ buffer->_2d.width, buffer->_2d.height);
+ IDirect3DSurface9_UnlockRect(buffer->d3d9_surface.surface);
+ buffer->_2d.copy = TRUE;
+ }
+ else
+ {
+ hr = E_OUTOFMEMORY;
+ }
}
}
}
@@ -425,14 +437,22 @@ static HRESULT WINAPI d3d9_surface_buffer_Unlock(IMFMediaBuffer *iface)
{
D3DLOCKED_RECT rect;
- if (SUCCEEDED(hr = IDirect3DSurface9_LockRect(buffer->d3d9_surface.surface, &rect, NULL, 0)))
+ if (buffer->_2d.copy)
+ {
+ if (SUCCEEDED(hr = IDirect3DSurface9_LockRect(buffer->d3d9_surface.surface, &rect, NULL, 0)))
+ {
+ copy_image(buffer, rect.pBits, rect.Pitch, buffer->_2d.linear_buffer, buffer->_2d.width,
+ buffer->_2d.width, buffer->_2d.height);
+ IDirect3DSurface9_UnlockRect(buffer->d3d9_surface.surface);
+ }
+
+ free(buffer->_2d.linear_buffer);
+ }
+ else
{
- copy_image(buffer, rect.pBits, rect.Pitch, buffer->_2d.linear_buffer, buffer->_2d.width,
- buffer->_2d.width, buffer->_2d.height);
IDirect3DSurface9_UnlockRect(buffer->d3d9_surface.surface);
}
- free(buffer->_2d.linear_buffer);
buffer->_2d.linear_buffer = NULL;
}
--
2.34.1
More information about the wine-devel
mailing list