winex11: Move the execution of rop operations from X11DRV_StretchBlt to a separate function.
This commit is contained in:
parent
ce9a5c6659
commit
c02bbb78b8
|
@ -1105,7 +1105,7 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
|
||||||
* Retrieve an area from the destination DC, mapping all the
|
* Retrieve an area from the destination DC, mapping all the
|
||||||
* pixels to Windows colors.
|
* pixels to Windows colors.
|
||||||
*/
|
*/
|
||||||
static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, RECT *visRectDst)
|
static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, const RECT *visRectDst)
|
||||||
{
|
{
|
||||||
int exposures = 0;
|
int exposures = 0;
|
||||||
INT width = visRectDst->right - visRectDst->left;
|
INT width = visRectDst->right - visRectDst->left;
|
||||||
|
@ -1165,7 +1165,7 @@ static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, RECT
|
||||||
* Put an area back into the destination DC, mapping the pixel
|
* Put an area back into the destination DC, mapping the pixel
|
||||||
* colors to X pixels.
|
* colors to X pixels.
|
||||||
*/
|
*/
|
||||||
static int BITBLT_PutDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, RECT *visRectDst)
|
static int BITBLT_PutDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, const RECT *visRectDst)
|
||||||
{
|
{
|
||||||
int exposures = 0;
|
int exposures = 0;
|
||||||
INT width = visRectDst->right - visRectDst->left;
|
INT width = visRectDst->right - visRectDst->left;
|
||||||
|
@ -1331,6 +1331,65 @@ static BOOL same_format(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void execute_rop( X11DRV_PDEVICE *physdev, Pixmap src_pixmap, GC gc,
|
||||||
|
const RECT *visrect, DWORD rop )
|
||||||
|
{
|
||||||
|
Pixmap pixmaps[3];
|
||||||
|
Pixmap result = src_pixmap;
|
||||||
|
BOOL null_brush;
|
||||||
|
const BYTE *opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
|
||||||
|
BOOL use_pat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
|
||||||
|
BOOL use_dst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
|
||||||
|
int width = visrect->right - visrect->left;
|
||||||
|
int height = visrect->bottom - visrect->top;
|
||||||
|
|
||||||
|
pixmaps[SRC] = src_pixmap;
|
||||||
|
pixmaps[TMP] = 0;
|
||||||
|
wine_tsx11_lock();
|
||||||
|
pixmaps[DST] = XCreatePixmap( gdi_display, root_window, width, height, physdev->depth );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
|
if (use_dst) BITBLT_GetDstArea( physdev, pixmaps[DST], gc, visrect );
|
||||||
|
null_brush = use_pat && !X11DRV_SetupGCForPatBlt( physdev, gc, TRUE );
|
||||||
|
|
||||||
|
wine_tsx11_lock();
|
||||||
|
for ( ; *opcode; opcode++)
|
||||||
|
{
|
||||||
|
if (OP_DST(*opcode) == DST) result = pixmaps[DST];
|
||||||
|
XSetFunction( gdi_display, gc, OP_ROP(*opcode) );
|
||||||
|
switch(OP_SRCDST(*opcode))
|
||||||
|
{
|
||||||
|
case OP_ARGS(DST,TMP):
|
||||||
|
case OP_ARGS(SRC,TMP):
|
||||||
|
if (!pixmaps[TMP])
|
||||||
|
pixmaps[TMP] = XCreatePixmap( gdi_display, root_window, width, height, physdev->depth );
|
||||||
|
/* fall through */
|
||||||
|
case OP_ARGS(DST,SRC):
|
||||||
|
case OP_ARGS(SRC,DST):
|
||||||
|
case OP_ARGS(TMP,SRC):
|
||||||
|
case OP_ARGS(TMP,DST):
|
||||||
|
XCopyArea( gdi_display, pixmaps[OP_SRC(*opcode)], pixmaps[OP_DST(*opcode)], gc,
|
||||||
|
0, 0, width, height, 0, 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_ARGS(PAT,TMP):
|
||||||
|
if (!pixmaps[TMP] && !null_brush)
|
||||||
|
pixmaps[TMP] = XCreatePixmap( gdi_display, root_window, width, height, physdev->depth );
|
||||||
|
/* fall through */
|
||||||
|
case OP_ARGS(PAT,DST):
|
||||||
|
case OP_ARGS(PAT,SRC):
|
||||||
|
if (!null_brush)
|
||||||
|
XFillRectangle( gdi_display, pixmaps[OP_DST(*opcode)], gc, 0, 0, width, height );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XSetFunction( gdi_display, physdev->gc, GXcopy );
|
||||||
|
physdev->exposures += BITBLT_PutDstArea( physdev, result, visrect );
|
||||||
|
XFreePixmap( gdi_display, pixmaps[DST] );
|
||||||
|
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* X11DRV_PatBlt
|
* X11DRV_PatBlt
|
||||||
*/
|
*/
|
||||||
|
@ -1397,17 +1456,15 @@ BOOL X11DRV_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
||||||
{
|
{
|
||||||
X11DRV_PDEVICE *physDevDst = get_x11drv_dev( dst_dev );
|
X11DRV_PDEVICE *physDevDst = get_x11drv_dev( dst_dev );
|
||||||
X11DRV_PDEVICE *physDevSrc = get_x11drv_dev( src_dev ); /* FIXME: check that it's really an x11 dev */
|
X11DRV_PDEVICE *physDevSrc = get_x11drv_dev( src_dev ); /* FIXME: check that it's really an x11 dev */
|
||||||
BOOL usePat, useDst, destUsed, fStretch, fNullBrush;
|
BOOL fStretch;
|
||||||
INT width, height;
|
INT width, height;
|
||||||
INT sDst, sSrc = DIB_Status_None;
|
INT sDst, sSrc = DIB_Status_None;
|
||||||
const BYTE *opcode;
|
const BYTE *opcode;
|
||||||
Pixmap pixmaps[3] = { 0, 0, 0 }; /* pixmaps for DST, SRC, TMP */
|
Pixmap src_pixmap;
|
||||||
GC tmpGC = 0;
|
GC tmpGC;
|
||||||
|
|
||||||
if (IsRectEmpty( &dst->visrect )) return TRUE;
|
if (IsRectEmpty( &dst->visrect )) return TRUE;
|
||||||
|
|
||||||
usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
|
|
||||||
useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
|
|
||||||
fStretch = (src->width != dst->width) || (src->height != dst->height);
|
fStretch = (src->width != dst->width) || (src->height != dst->height);
|
||||||
|
|
||||||
if (physDevDst != physDevSrc)
|
if (physDevDst != physDevSrc)
|
||||||
|
@ -1491,67 +1548,23 @@ BOOL X11DRV_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
||||||
tmpGC = XCreateGC( gdi_display, physDevDst->drawable, 0, NULL );
|
tmpGC = XCreateGC( gdi_display, physDevDst->drawable, 0, NULL );
|
||||||
XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
|
XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
|
||||||
XSetGraphicsExposures( gdi_display, tmpGC, False );
|
XSetGraphicsExposures( gdi_display, tmpGC, False );
|
||||||
pixmaps[DST] = XCreatePixmap( gdi_display, root_window, width, height,
|
src_pixmap = XCreatePixmap( gdi_display, root_window, width, height, physDevDst->depth );
|
||||||
physDevDst->depth );
|
|
||||||
pixmaps[SRC] = XCreatePixmap( gdi_display, root_window, width, height,
|
|
||||||
physDevDst->depth );
|
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
|
if (physDevDst != physDevSrc) X11DRV_CoerceDIBSection( physDevSrc, DIB_Status_GdiMod );
|
||||||
|
|
||||||
if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, src, dst ))
|
if(!X11DRV_XRender_GetSrcAreaStretch( physDevSrc, physDevDst, src_pixmap, tmpGC, src, dst ))
|
||||||
{
|
{
|
||||||
if (fStretch)
|
if (fStretch)
|
||||||
BITBLT_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, src, dst );
|
BITBLT_GetSrcAreaStretch( physDevSrc, physDevDst, src_pixmap, tmpGC, src, dst );
|
||||||
else
|
else
|
||||||
BITBLT_GetSrcArea( physDevSrc, physDevDst, pixmaps[SRC], tmpGC, &src->visrect );
|
BITBLT_GetSrcArea( physDevSrc, physDevDst, src_pixmap, tmpGC, &src->visrect );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useDst) BITBLT_GetDstArea( physDevDst, pixmaps[DST], tmpGC, &dst->visrect );
|
execute_rop( physDevDst, src_pixmap, tmpGC, &dst->visrect, rop );
|
||||||
if (usePat) fNullBrush = !X11DRV_SetupGCForPatBlt( physDevDst, tmpGC, TRUE );
|
|
||||||
else fNullBrush = FALSE;
|
|
||||||
destUsed = FALSE;
|
|
||||||
|
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
for ( ; *opcode; opcode++)
|
XFreePixmap( gdi_display, src_pixmap );
|
||||||
{
|
|
||||||
if (OP_DST(*opcode) == DST) destUsed = TRUE;
|
|
||||||
XSetFunction( gdi_display, tmpGC, OP_ROP(*opcode) );
|
|
||||||
switch(OP_SRCDST(*opcode))
|
|
||||||
{
|
|
||||||
case OP_ARGS(DST,TMP):
|
|
||||||
case OP_ARGS(SRC,TMP):
|
|
||||||
if (!pixmaps[TMP])
|
|
||||||
pixmaps[TMP] = XCreatePixmap( gdi_display, root_window,
|
|
||||||
width, height, physDevDst->depth );
|
|
||||||
/* fall through */
|
|
||||||
case OP_ARGS(DST,SRC):
|
|
||||||
case OP_ARGS(SRC,DST):
|
|
||||||
case OP_ARGS(TMP,SRC):
|
|
||||||
case OP_ARGS(TMP,DST):
|
|
||||||
XCopyArea( gdi_display, pixmaps[OP_SRC(*opcode)],
|
|
||||||
pixmaps[OP_DST(*opcode)], tmpGC,
|
|
||||||
0, 0, width, height, 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_ARGS(PAT,TMP):
|
|
||||||
if (!pixmaps[TMP] && !fNullBrush)
|
|
||||||
pixmaps[TMP] = XCreatePixmap( gdi_display, root_window,
|
|
||||||
width, height, physDevDst->depth );
|
|
||||||
/* fall through */
|
|
||||||
case OP_ARGS(PAT,DST):
|
|
||||||
case OP_ARGS(PAT,SRC):
|
|
||||||
if (!fNullBrush)
|
|
||||||
XFillRectangle( gdi_display, pixmaps[OP_DST(*opcode)],
|
|
||||||
tmpGC, 0, 0, width, height );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
|
|
||||||
physDevDst->exposures += BITBLT_PutDstArea( physDevDst, pixmaps[destUsed ? DST : SRC], &dst->visrect );
|
|
||||||
XFreePixmap( gdi_display, pixmaps[DST] );
|
|
||||||
if (pixmaps[SRC]) XFreePixmap( gdi_display, pixmaps[SRC] );
|
|
||||||
if (pixmaps[TMP]) XFreePixmap( gdi_display, pixmaps[TMP] );
|
|
||||||
XFreeGC( gdi_display, tmpGC );
|
XFreeGC( gdi_display, tmpGC );
|
||||||
wine_tsx11_unlock();
|
wine_tsx11_unlock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue