From 428ada3c8a12dbeaba42d13f445e67e488fea94a Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Thu, 21 Feb 2008 16:44:59 +0000 Subject: [PATCH] winex11.drv: Optimise getting the bits of a DIB after calling SetDIBits. Sync the application's bits in SetDIBits if the input bits are in exactly the same format and the size of the image is small enough not to cause a performance hit (in case the application doesn't get ever access the bits directly). --- dlls/winex11.drv/dib.c | 50 ++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/dlls/winex11.drv/dib.c b/dlls/winex11.drv/dib.c index b05d90408e3..91aab9976d2 100644 --- a/dlls/winex11.drv/dib.c +++ b/dlls/winex11.drv/dib.c @@ -107,6 +107,17 @@ static void X11DRV_DIB_Unlock(X_PHYSBITMAP *,BOOL); dlls/gdi/dib.c */ +/*********************************************************************** + * DIB_DoProtectDIBSection + */ +static void X11DRV_DIB_DoProtectDIBSection( X_PHYSBITMAP *physBitmap, DWORD new_prot ) +{ + DWORD old_prot; + + VirtualProtect(physBitmap->base, physBitmap->size, new_prot, &old_prot); + TRACE("Changed protection from %d to %d\n", old_prot, new_prot); +} + /*********************************************************************** * X11DRV_DIB_GetXImageWidthBytes * @@ -3960,6 +3971,34 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8; X11DRV_DIB_Lock( physBitmap, DIB_Status_GdiMod ); result = X11DRV_DIB_SetImageBits( &descr ); + + /* optimisation for the case where the input bits are in exactly the same + * format as the internal representation and copying to the app bits is + * cheap - saves a round trip to the X server */ + if (descr.compression == BI_RGB && + coloruse == DIB_RGB_COLORS && + descr.infoBpp == bitmap.bmBitsPixel && + physBitmap->base && physBitmap->size < 65536) + { + unsigned int srcwidthb = bitmap.bmWidthBytes; + int dstwidthb = X11DRV_DIB_GetDIBWidthBytes( width, descr.infoBpp ); + LPBYTE dbits = physBitmap->base, sbits = (LPBYTE)bits + (startscan * srcwidthb); + int widthb; + UINT y; + + TRACE("syncing compatible set bits to app bits\n"); + if ((tmpheight < 0) ^ (bitmap.bmHeight < 0)) + { + dbits = (LPBYTE)bits + (dstwidthb * (lines-1)); + dstwidthb = -dstwidthb; + } + X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE ); + widthb = min(srcwidthb, abs(dstwidthb)); + for (y = 0; y < lines; y++, dbits += dstwidthb, sbits += srcwidthb) + memcpy(dbits, sbits, widthb); + X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READONLY ); + physBitmap->status = DIB_Status_InSync; + } X11DRV_DIB_Unlock( physBitmap, TRUE ); HeapFree(GetProcessHeap(), 0, descr.colorMap); @@ -4115,17 +4154,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, return lines; } -/*********************************************************************** - * DIB_DoProtectDIBSection - */ -static void X11DRV_DIB_DoProtectDIBSection( X_PHYSBITMAP *physBitmap, DWORD new_prot ) -{ - DWORD old_prot; - - VirtualProtect(physBitmap->base, physBitmap->size, new_prot, &old_prot); - TRACE("Changed protection from %d to %d\n", old_prot, new_prot); -} - /*********************************************************************** * X11DRV_DIB_DoCopyDIBSection */