[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