Henri Verbeet : d3dx9: Introduce a special case for simple loads in D3DXLoadSurfaceFromMemory().

Alexandre Julliard julliard at winehq.org
Fri Apr 27 10:55:45 CDT 2012


Module: wine
Branch: master
Commit: e925553072ddbdeacc1705e8aed25be1421c0cd3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e925553072ddbdeacc1705e8aed25be1421c0cd3

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Apr 26 21:11:54 2012 +0200

d3dx9: Introduce a special case for simple loads in D3DXLoadSurfaceFromMemory().

---

 dlls/d3dx9_36/surface.c |   75 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index f436c53..49d4c1e 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -957,11 +957,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
 
     IDirect3DSurface9_GetDesc(pDestSurface, &surfdesc);
 
-    srcformatdesc = get_format_info(SrcFormat);
-    destformatdesc = get_format_info(surfdesc.Format);
-    if( srcformatdesc->type == FORMAT_UNKNOWN ||  srcformatdesc->bytes_per_pixel > 4) return E_NOTIMPL;
-    if(destformatdesc->type == FORMAT_UNKNOWN || destformatdesc->bytes_per_pixel > 4) return E_NOTIMPL;
-
     srcsize.x = pSrcRect->right - pSrcRect->left;
     srcsize.y = pSrcRect->bottom - pSrcRect->top;
     if( !pDestRect ) {
@@ -976,21 +971,67 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
         if(destsize.x == 0 || destsize.y == 0) return D3D_OK;
     }
 
-    hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0);
-    if(FAILED(hr)) return D3DXERR_INVALIDDATA;
+    srcformatdesc = get_format_info(SrcFormat);
+    if (srcformatdesc->type == FORMAT_UNKNOWN)
+        return E_NOTIMPL;
+
+    destformatdesc = get_format_info(surfdesc.Format);
+    if (destformatdesc->type == FORMAT_UNKNOWN)
+        return E_NOTIMPL;
+
+    if (SrcFormat == surfdesc.Format
+            && destsize.x == srcsize.x
+            && destsize.y == srcsize.y) /* Simple copy. */
+    {
+        const BYTE *src_addr;
+        BYTE *dst_addr;
+        UINT y;
+
+        if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
+            return D3DXERR_INVALIDDATA;
+
+        src_addr = pSrcMemory;
+        src_addr += pSrcRect->top * SrcPitch;
+        src_addr += pSrcRect->left * srcformatdesc->bytes_per_pixel;
+        dst_addr = lockrect.pBits;
+
+        for (y = 0; y < srcsize.y; ++y)
+        {
+            memcpy(dst_addr, src_addr, srcsize.x * srcformatdesc->bytes_per_pixel);
+            src_addr += SrcPitch;
+            dst_addr += lockrect.Pitch;
+        }
+
+        IDirect3DSurface9_UnlockRect(pDestSurface);
+    }
+    else /* Stretching or format conversion. */
+    {
+        if (srcformatdesc->bytes_per_pixel > 4)
+            return E_NOTIMPL;
+        if (destformatdesc->bytes_per_pixel > 4)
+            return E_NOTIMPL;
+
+        if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
+            return D3DXERR_INVALIDDATA;
+
+        if ((dwFilter & 0xf) == D3DX_FILTER_NONE)
+        {
+            copy_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
+                    lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
+                    Colorkey);
+        }
+        else /* if ((dwFilter & 0xf) == D3DX_FILTER_POINT) */
+        {
+            /* Always apply a point filter until D3DX_FILTER_LINEAR,
+             * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */
+            point_filter_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
+                    lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
+                    Colorkey);
+        }
 
-    if((dwFilter & 0xF) == D3DX_FILTER_NONE) {
-        copy_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
-                         lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
-                         Colorkey);
-    } else /*if((dwFilter & 0xF) == D3DX_FILTER_POINT) */ {
-        /* always apply a point filter until D3DX_FILTER_LINEAR, D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented */
-        point_filter_simple_data(pSrcMemory, SrcPitch, srcsize, srcformatdesc,
-                                 lockrect.pBits, lockrect.Pitch, destsize, destformatdesc,
-                                 Colorkey);
+        IDirect3DSurface9_UnlockRect(pDestSurface);
     }
 
-    IDirect3DSurface9_UnlockRect(pDestSurface);
     return D3D_OK;
 }
 




More information about the wine-cvs mailing list