winex11: Move the DIB locking and the client-side optimizations into BITBLT_InternalStretchBlt.
This way they also apply to the non-stretching StretchBlt case.
This commit is contained in:
parent
7bc4b074fc
commit
77b9b8a307
|
@ -1365,6 +1365,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
BOOL usePat, useSrc, useDst, destUsed, fStretch, fNullBrush;
|
BOOL usePat, useSrc, useDst, destUsed, fStretch, fNullBrush;
|
||||||
RECT visRectDst, visRectSrc;
|
RECT visRectDst, visRectSrc;
|
||||||
INT width, height;
|
INT width, height;
|
||||||
|
INT sDst, sSrc = DIB_Status_None;
|
||||||
const BYTE *opcode;
|
const BYTE *opcode;
|
||||||
Pixmap pixmaps[3] = { 0, 0, 0 }; /* pixmaps for DST, SRC, TMP */
|
Pixmap pixmaps[3] = { 0, 0, 0 }; /* pixmaps for DST, SRC, TMP */
|
||||||
GC tmpGC = 0;
|
GC tmpGC = 0;
|
||||||
|
@ -1426,6 +1427,8 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
visRectSrc.right, visRectSrc.bottom,
|
visRectSrc.right, visRectSrc.bottom,
|
||||||
visRectDst.left, visRectDst.top,
|
visRectDst.left, visRectDst.top,
|
||||||
visRectDst.right, visRectDst.bottom );
|
visRectDst.right, visRectDst.bottom );
|
||||||
|
if (physDevDst != physDevSrc)
|
||||||
|
sSrc = X11DRV_LockDIBSection( physDevSrc, DIB_Status_None );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1441,6 +1444,21 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
width = visRectDst.right - visRectDst.left;
|
width = visRectDst.right - visRectDst.left;
|
||||||
height = visRectDst.bottom - visRectDst.top;
|
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];
|
opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
|
||||||
|
|
||||||
/* a few optimizations for single-op ROPs */
|
/* 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,
|
physDevDst->dc_rect.top + visRectDst.top,
|
||||||
width, height );
|
width, height );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
return TRUE;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DSTINVERT: /* 0x55 */
|
case DSTINVERT: /* 0x55 */
|
||||||
|
@ -1487,7 +1505,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
physDevDst->dc_rect.top + visRectDst.top,
|
physDevDst->dc_rect.top + visRectDst.top,
|
||||||
width, height );
|
width, height );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
return TRUE;
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1501,7 +1519,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
width, height );
|
width, height );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
}
|
}
|
||||||
return TRUE;
|
goto done;
|
||||||
}
|
}
|
||||||
else if (OP_SRCDST(*opcode) == OP_ARGS(SRC,DST))
|
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();
|
wine_tsx11_lock();
|
||||||
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
|
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,
|
XCopyArea( gdi_display, physDevSrc->drawable,
|
||||||
physDevDst->drawable, physDevDst->gc,
|
physDevDst->drawable, physDevDst->gc,
|
||||||
physDevSrc->dc_rect.left + visRectSrc.left,
|
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->dc_rect.top + visRectDst.top );
|
||||||
physDevDst->exposures++;
|
physDevDst->exposures++;
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
return TRUE;
|
goto done;
|
||||||
}
|
}
|
||||||
if (physDevSrc->depth == 1)
|
if (physDevSrc->depth == 1)
|
||||||
{
|
{
|
||||||
int fg, bg;
|
int fg, bg;
|
||||||
|
|
||||||
|
X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
|
||||||
get_colors(physDevDst, physDevSrc, &fg, &bg);
|
get_colors(physDevDst, physDevSrc, &fg, &bg);
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
|
|
||||||
XSetBackground( gdi_display, physDevDst->gc, fg );
|
XSetBackground( gdi_display, physDevDst->gc, fg );
|
||||||
XSetForeground( gdi_display, physDevDst->gc, bg );
|
XSetForeground( gdi_display, physDevDst->gc, bg );
|
||||||
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
|
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->dc_rect.top + visRectDst.top, 1 );
|
||||||
physDevDst->exposures++;
|
physDevDst->exposures++;
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
return TRUE;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1558,6 +1590,8 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
physDevDst->depth );
|
physDevDst->depth );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
|
if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
|
||||||
|
|
||||||
if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC,
|
if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC,
|
||||||
widthSrc, heightSrc, widthDst, heightDst,
|
widthSrc, heightSrc, widthDst, heightDst,
|
||||||
&visRectSrc, &visRectDst))
|
&visRectSrc, &visRectDst))
|
||||||
|
@ -1622,6 +1656,10 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
|
||||||
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );
|
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );
|
||||||
XFreeGC( gdi_display, tmpGC );
|
XFreeGC( gdi_display, tmpGC );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (useSrc && physDevDst != physDevSrc) X11DRV_UnlockDIBSection( physDevSrc, FALSE );
|
||||||
|
X11DRV_UnlockDIBSection( physDevDst, TRUE );
|
||||||
return 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 CDECL X11DRV_PatBlt( X11DRV_PDEVICE *physDev, INT left, INT top, INT width, INT height, DWORD rop )
|
||||||
{
|
{
|
||||||
BOOL result;
|
return BITBLT_InternalStretchBlt( physDev, left, top, width, height, NULL, 0, 0, 0, 0, rop );
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1647,93 +1680,8 @@ BOOL CDECL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
|
||||||
INT width, INT height, X11DRV_PDEVICE *physDevSrc,
|
INT width, INT height, X11DRV_PDEVICE *physDevSrc,
|
||||||
INT xSrc, INT ySrc, DWORD rop )
|
INT xSrc, INT ySrc, DWORD rop )
|
||||||
{
|
{
|
||||||
BOOL result = FALSE;
|
return BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, width, height,
|
||||||
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 );
|
physDevSrc, xSrc, ySrc, width, height, rop );
|
||||||
|
|
||||||
END:
|
|
||||||
if (physDevDst != physDevSrc)
|
|
||||||
X11DRV_UnlockDIBSection( physDevSrc, FALSE );
|
|
||||||
X11DRV_UnlockDIBSection( physDevDst, TRUE );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1745,17 +1693,6 @@ BOOL CDECL X11DRV_StretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
|
||||||
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
|
X11DRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc,
|
||||||
INT widthSrc, INT heightSrc, DWORD rop )
|
INT widthSrc, INT heightSrc, DWORD rop )
|
||||||
{
|
{
|
||||||
BOOL result;
|
return BITBLT_InternalStretchBlt( physDevDst, xDst, yDst, widthDst, heightDst,
|
||||||
|
|
||||||
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 );
|
physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop );
|
||||||
|
|
||||||
if (physDevDst != physDevSrc)
|
|
||||||
X11DRV_UnlockDIBSection( physDevSrc, FALSE );
|
|
||||||
X11DRV_UnlockDIBSection( physDevDst, TRUE );
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue