[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