[winex11.drv] client-side DIB copy

Damjan Jovanovic damjan.jov at gmail.com
Sat Oct 14 03:09:53 CDT 2006


Changelog:
* implemented the client-side DIB copy optimization

Damjan Jovanovic
-------------- next part --------------
--- a/dlls/winex11.drv/bitblt.c	2006-10-13 19:13:40.000000000 +0200
+++ b/dlls/winex11.drv/bitblt.c	2006-10-14 10:06:03.000000000 +0200
@@ -2,6 +2,7 @@
  * GDI bit-blit operations
  *
  * Copyright 1993, 1994  Alexandre Julliard
+ * Copyright 2006 Damjan Jovanovic
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1526,6 +1527,75 @@
 
 
 /***********************************************************************
+ *           X11DRV_ClientSideDIBCopy
+ */
+static BOOL X11DRV_ClientSideDIBCopy( X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
+                                      X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
+                                      INT width, INT height )
+{
+    DIBSECTION srcDib, dstDib;
+    BYTE *srcPtr, *dstPtr;
+    INT widthBytes, srcOffsetBytes, dstOffsetBytes;
+    INT i;
+
+    if (GetObjectW(physDevSrc->bitmap->hbitmap, sizeof(srcDib), &srcDib) != sizeof(srcDib))
+      return FALSE;
+    if (GetObjectW(physDevDst->bitmap->hbitmap, sizeof(dstDib), &dstDib) != sizeof(dstDib))
+      return FALSE;
+
+    switch (dstDib.dsBm.bmBitsPixel)
+    {
+      case 1:
+        widthBytes = (width + 7) / 8;
+        srcOffsetBytes = (xSrc + 7) / 8;
+        dstOffsetBytes = (xDst + 7) / 8;
+        break;
+      case 4:
+        widthBytes = (width + 1) / 2;
+        srcOffsetBytes = (xSrc + 1) / 2;
+        dstOffsetBytes = (xDst + 1) / 2;
+        break;
+      case 8:
+        widthBytes = width;
+        srcOffsetBytes = xSrc;
+        dstOffsetBytes = xDst;
+        break;
+      case 15:
+      case 16:
+        widthBytes = width * 2;
+        srcOffsetBytes = xSrc * 2;
+        dstOffsetBytes = xDst * 2;
+        break;
+      case 24:
+        widthBytes = width * 2;
+        srcOffsetBytes = xSrc * 2;
+        dstOffsetBytes = xDst * 2;
+        break;
+      case 32:
+        widthBytes = width * 4;
+        srcOffsetBytes = xSrc * 4;
+        dstOffsetBytes = xDst * 4;
+        break;
+      default:
+        FIXME("don't know how to work with a depth of %d\n", physDevSrc->depth);
+        return FALSE;
+    }
+
+    srcPtr = &physDevSrc->bitmap->base[ySrc*srcDib.dsBm.bmWidthBytes + srcOffsetBytes];
+    dstPtr = &physDevDst->bitmap->base[yDst*dstDib.dsBm.bmWidthBytes + dstOffsetBytes];
+
+    for (i = 0; i < height; ++i)
+    {
+      memcpy(dstPtr, srcPtr, widthBytes);
+      srcPtr += srcDib.dsBm.bmWidthBytes;
+      dstPtr += dstDib.dsBm.bmWidthBytes;
+    }
+
+    return TRUE;
+}
+
+
+/***********************************************************************
  *           X11DRV_BitBlt
  */
 BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
@@ -1587,6 +1657,12 @@
       height = visRectDst.bottom - visRectDst.top;
 
       if (sDst == DIB_Status_AppMod) {
+        result = X11DRV_ClientSideDIBCopy( physDevSrc, xSrc, ySrc,
+                                           physDevDst, xDst, yDst,
+                                           width, height );
+        if (result)
+          goto END;
+        /* fall-back */
         FIXME("potential optimization - client-side DIB copy\n");
       }
       X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod, FALSE );


More information about the wine-patches mailing list