From 77b9b8a307711bd1f6da30f7d2d5e04faa3f5092 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 30 Sep 2009 20:39:51 +0200 Subject: [PATCH] winex11: Move the DIB locking and the client-side optimizations into BITBLT_InternalStretchBlt. This way they also apply to the non-stretching StretchBlt case. --- dlls/winex11.drv/bitblt.c | 161 ++++++++++++-------------------------- 1 file changed, 49 insertions(+), 112 deletions(-) diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 250bf98ee0a..bfbcaafe1b8 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1365,6 +1365,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT BOOL usePat, useSrc, useDst, destUsed, fStretch, fNullBrush; RECT visRectDst, visRectSrc; INT width, height; + INT sDst, sSrc = DIB_Status_None; const BYTE *opcode; Pixmap pixmaps[3] = { 0, 0, 0 }; /* pixmaps for DST, SRC, TMP */ GC tmpGC = 0; @@ -1426,6 +1427,8 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT visRectSrc.right, visRectSrc.bottom, visRectDst.left, visRectDst.top, visRectDst.right, visRectDst.bottom ); + if (physDevDst != physDevSrc) + sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None ); } else { @@ -1441,6 +1444,21 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT width = visRectDst.right - visRectDst.left; height = visRectDst.bottom - visRectDst.top; + sDst = X11DRV_LockDIBSection( physDevDst, DIB_Status_None ); + if (physDevDst == physDevSrc) sSrc = sDst; + + /* try client-side DIB copy */ + if (!fStretch && rop == SRCCOPY && + sSrc == DIB_Status_AppMod && sDst == DIB_Status_AppMod && + physDevSrc->depth == physDevDst->depth) + { + if (client_side_dib_copy( physDevSrc, visRectSrc.left, visRectSrc.top, + physDevDst, visRectDst.left, visRectDst.top, width, height )) + goto done; + } + + X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod ); + opcode = BITBLT_Opcodes[(rop >> 16) & 0xff]; /* a few optimizations for single-op ROPs */ @@ -1467,7 +1485,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT physDevDst->dc_rect.top + visRectDst.top, width, height ); wine_tsx11_unlock(); - return TRUE; + goto done; } break; case DSTINVERT: /* 0x55 */ @@ -1487,7 +1505,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT physDevDst->dc_rect.top + visRectDst.top, width, height ); wine_tsx11_unlock(); - return TRUE; + goto done; } break; } @@ -1501,7 +1519,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT width, height ); wine_tsx11_unlock(); } - return TRUE; + goto done; } else if (OP_SRCDST(*opcode) == OP_ARGS(SRC,DST)) { @@ -1509,6 +1527,19 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT { wine_tsx11_lock(); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) ); + wine_tsx11_unlock(); + + if (physDevSrc != physDevDst) + { + if (sSrc == DIB_Status_AppMod) + { + X11DRV_DIB_CopyDIBSection( physDevSrc, physDevDst, visRectSrc.left, visRectSrc.top, + visRectDst.left, visRectDst.top, width, height ); + goto done; + } + X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); + } + wine_tsx11_lock(); XCopyArea( gdi_display, physDevSrc->drawable, physDevDst->drawable, physDevDst->gc, physDevSrc->dc_rect.left + visRectSrc.left, @@ -1518,14 +1549,15 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT physDevDst->dc_rect.top + visRectDst.top ); physDevDst->exposures++; wine_tsx11_unlock(); - return TRUE; + goto done; } if (physDevSrc->depth == 1) { int fg, bg; + + X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); get_colors(physDevDst, physDevSrc, &fg, &bg); wine_tsx11_lock(); - XSetBackground( gdi_display, physDevDst->gc, fg ); XSetForeground( gdi_display, physDevDst->gc, bg ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) ); @@ -1538,7 +1570,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT physDevDst->dc_rect.top + visRectDst.top, 1 ); physDevDst->exposures++; wine_tsx11_unlock(); - return TRUE; + goto done; } } } @@ -1558,6 +1590,8 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT physDevDst->depth ); wine_tsx11_unlock(); + if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); + if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, widthSrc, heightSrc, widthDst, heightDst, &visRectSrc, &visRectDst)) @@ -1622,6 +1656,10 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] ); XFreeGC( gdi_display, tmpGC ); wine_tsx11_unlock(); + +done: + if (useSrc && physDevDst != physDevSrc) X11DRV_UnlockDIBSection( physDevSrc, FALSE ); + X11DRV_UnlockDIBSection( physDevDst, TRUE ); return TRUE; } @@ -1631,12 +1669,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT */ BOOL CDECL X11DRV_PatBlt( X11DRV_PDEVICE *physDev, INT left, INT top, INT width, INT height, DWORD rop ) { - BOOL result; - - X11DRV_LockDIBSection( physDev, DIB_Status_GdiMod ); - result = BITBLT_InternalStretchBlt( physDev, left, top, width, height, NULL, 0, 0, 0, 0, rop ); - X11DRV_UnlockDIBSection( physDev, TRUE ); - return result; + return BITBLT_InternalStretchBlt( physDev, left, top, width, height, NULL, 0, 0, 0, 0, rop ); } @@ -1647,93 +1680,8 @@ BOOL CDECL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT width, INT height, X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, DWORD rop ) { - BOOL result = FALSE; - INT sSrc, sDst; - RECT visRectDst, visRectSrc; - - if (((rop >> 16) & 0x55) == ((rop >> 17) & 0x55)) { - /* FIXME: seems the ROP doesn't include destination; - * now if the destination area include the entire dcDst, - * we can pass TRUE instead of FALSE to CoerceDIBSection(dcDst...), - * which may avoid a copy in some situations */ - } - - sDst = X11DRV_LockDIBSection( physDevDst, DIB_Status_None ); - if (physDevDst != physDevSrc) - sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None ); - else - sSrc = sDst; - - if ((sSrc == DIB_Status_AppMod) && (rop == SRCCOPY) && - (physDevSrc->depth == physDevDst->depth)) - { - POINT pts[2]; - /* do everything ourselves; map coordinates */ - - pts[0].x = xSrc; - pts[0].y = ySrc; - pts[1].x = xSrc + width; - pts[1].y = ySrc + height; - - LPtoDP(physDevSrc->hdc, pts, 2); - width = pts[1].x - pts[0].x; - height = pts[1].y - pts[0].y; - xSrc = pts[0].x; - ySrc = pts[0].y; - - pts[0].x = xDst; - pts[0].y = yDst; - LPtoDP(physDevDst->hdc, pts, 1); - - xDst = pts[0].x; - yDst = pts[0].y; - - /* Perform basic clipping */ - if (!BITBLT_GetVisRectangles( physDevDst, xDst, yDst, width, height, - physDevSrc, xSrc, ySrc, width, height, - &visRectSrc, &visRectDst )) - { - result = TRUE; - goto END; - } - - xSrc = visRectSrc.left; - ySrc = visRectSrc.top; - xDst = visRectDst.left; - yDst = visRectDst.top; - width = visRectDst.right - visRectDst.left; - height = visRectDst.bottom - visRectDst.top; - - if (sDst == DIB_Status_AppMod) { - result = client_side_dib_copy( physDevSrc, xSrc, ySrc, physDevDst, xDst, yDst, width, height ); - if (result) - goto END; - /* fall back to X server copying */ - } - X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod ); - - wine_tsx11_lock(); - XSetFunction( gdi_display, physDevDst->gc, GXcopy ); - wine_tsx11_unlock(); - - X11DRV_DIB_CopyDIBSection( physDevSrc, physDevDst, xSrc, ySrc, xDst, yDst, width, height ); - result = TRUE; - goto END; - } - - X11DRV_CoerceDIBSection( physDevDst, DIB_Status_GdiMod ); - if (physDevDst != physDevSrc) - X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod ); - - result = BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, width, height, - physDevSrc, xSrc, ySrc, width, height, rop ); - -END: - if (physDevDst != physDevSrc) - X11DRV_UnlockDIBSection( physDevSrc, FALSE ); - X11DRV_UnlockDIBSection( physDevDst, TRUE ); - - return result; + return BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, width, height, + physDevSrc, xSrc, ySrc, width, height, rop ); } @@ -1745,17 +1693,6 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst, X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) { - BOOL result; - - X11DRV_LockDIBSection( physDevDst, DIB_Status_GdiMod ); - if (physDevDst != physDevSrc) - X11DRV_LockDIBSection( physDevSrc, DIB_Status_GdiMod ); - - result = BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, widthDst, heightDst, - physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop ); - - if (physDevDst != physDevSrc) - X11DRV_UnlockDIBSection( physDevSrc, FALSE ); - X11DRV_UnlockDIBSection( physDevDst, TRUE ); - return result; + return BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, widthDst, heightDst, + physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop ); }