winex11: Make the BitBlt short-cuts more generic to apply to all possible ROPs.

This commit is contained in:
Alexandre Julliard 2008-02-21 20:15:41 +01:00
parent 997e5f1230
commit 23afe2e94c
1 changed files with 95 additions and 132 deletions

View File

@ -317,7 +317,7 @@ static const unsigned char BITBLT_Opcodes[256][MAX_OP_LEN] =
OP(PAT,DST,GXequiv) }, /* 0xa7 ~P^(D&(S|P)) */ OP(PAT,DST,GXequiv) }, /* 0xa7 ~P^(D&(S|P)) */
{ OP(PAT,SRC,GXor), OP(SRC,DST,GXand) }, /* 0xa8 D&(P|S) */ { OP(PAT,SRC,GXor), OP(SRC,DST,GXand) }, /* 0xa8 D&(P|S) */
{ OP(PAT,SRC,GXor), OP(SRC,DST,GXequiv) }, /* 0xa9 ~D^(P|S) */ { OP(PAT,SRC,GXor), OP(SRC,DST,GXequiv) }, /* 0xa9 ~D^(P|S) */
{ OP(SRC,DST,GXnoop) }, /* 0xaa D */ { OP(PAT,DST,GXnoop) }, /* 0xaa D */
{ OP(PAT,SRC,GXnor), OP(SRC,DST,GXor) }, /* 0xab D|~(P|S) */ { OP(PAT,SRC,GXnor), OP(SRC,DST,GXor) }, /* 0xab D|~(P|S) */
{ OP(SRC,DST,GXxor), OP(PAT,DST,GXand), { OP(SRC,DST,GXxor), OP(PAT,DST,GXand),
OP(SRC,DST,GXxor) }, /* 0xac S^(P&(D^S)) */ OP(SRC,DST,GXxor) }, /* 0xac S^(P&(D^S)) */
@ -1320,54 +1320,60 @@ 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;
if (!fStretch) switch(rop) /* A few optimisations */ opcode = BITBLT_Opcodes[(rop >> 16) & 0xff];
/* a few optimisations for single-op rops */
if (!fStretch && !opcode[1])
{
if (OP_SRCDST(*opcode) == OP_ARGS(PAT,DST))
{
switch(rop) /* a few special cases */
{ {
case BLACKNESS: /* 0x00 */ case BLACKNESS: /* 0x00 */
wine_tsx11_lock(); case WHITENESS: /* 0xff */
if ((physDevDst->depth == 1) || !X11DRV_PALETTE_PaletteToXPixel) if ((physDevDst->depth != 1) && X11DRV_PALETTE_PaletteToXPixel)
XSetFunction( gdi_display, physDevDst->gc, GXclear );
else
{ {
wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, GXcopy ); XSetFunction( gdi_display, physDevDst->gc, GXcopy );
if (rop == BLACKNESS)
XSetForeground( gdi_display, physDevDst->gc, X11DRV_PALETTE_PaletteToXPixel[0] ); XSetForeground( gdi_display, physDevDst->gc, X11DRV_PALETTE_PaletteToXPixel[0] );
else
XSetForeground( gdi_display, physDevDst->gc,
WhitePixel( gdi_display, DefaultScreen(gdi_display) ));
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid ); XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
}
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + visRectDst.top,
width, height ); width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE; return TRUE;
}
break;
case DSTINVERT: /* 0x55 */ case DSTINVERT: /* 0x55 */
wine_tsx11_lock(); if (!(X11DRV_PALETTE_PaletteFlags & (X11DRV_PALETTE_PRIVATE | X11DRV_PALETTE_VIRTUAL)))
XSetFunction( gdi_display, physDevDst->gc, GXinvert );
if( X11DRV_PALETTE_PaletteFlags & (X11DRV_PALETTE_PRIVATE | X11DRV_PALETTE_VIRTUAL) )
XSetFunction( gdi_display, physDevDst->gc, GXinvert);
else
{ {
/* Xor is much better when we do not have full colormap. */ /* Xor is much better when we do not have full colormap. */
/* Using white^black ensures that we invert at least black */ /* Using white^black ensures that we invert at least black */
/* and white. */ /* and white. */
unsigned long xor_pix = (WhitePixel( gdi_display, DefaultScreen(gdi_display) ) ^ unsigned long xor_pix = (WhitePixel( gdi_display, DefaultScreen(gdi_display) ) ^
BlackPixel( gdi_display, DefaultScreen(gdi_display) )); BlackPixel( gdi_display, DefaultScreen(gdi_display) ));
wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, GXxor ); XSetFunction( gdi_display, physDevDst->gc, GXxor );
XSetForeground( gdi_display, physDevDst->gc, xor_pix); XSetForeground( gdi_display, physDevDst->gc, xor_pix);
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid ); XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
}
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + visRectDst.top,
width, height ); width, height );
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE; return TRUE;
}
case PATINVERT: /* 0x5a */ break;
if (X11DRV_SetupGCForBrush( physDevDst )) }
if (!usePat || X11DRV_SetupGCForBrush( physDevDst ))
{ {
wine_tsx11_lock(); wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, GXxor ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc, XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left, physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top, physDevDst->dc_rect.top + visRectDst.top,
@ -1375,26 +1381,13 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
wine_tsx11_unlock(); wine_tsx11_unlock();
} }
return TRUE; return TRUE;
}
case 0xa50065: else if (OP_SRCDST(*opcode) == OP_ARGS(SRC,DST))
if (X11DRV_SetupGCForBrush( physDevDst ))
{ {
wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, GXequiv );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top,
width, height );
wine_tsx11_unlock();
}
return TRUE;
case SRCCOPY: /* 0xcc */
case SRCINVERT:
if (physDevSrc->depth == physDevDst->depth) if (physDevSrc->depth == physDevDst->depth)
{ {
wine_tsx11_lock(); wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, rop == SRCCOPY ? GXcopy : GXxor ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
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,
@ -1406,7 +1399,6 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE; return TRUE;
} }
if (physDevSrc->depth == 1) if (physDevSrc->depth == 1)
{ {
int fg, bg; int fg, bg;
@ -1415,7 +1407,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
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, rop == SRCCOPY ? GXcopy : GXxor ); XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
XCopyPlane( gdi_display, physDevSrc->drawable, XCopyPlane( gdi_display, physDevSrc->drawable,
physDevDst->drawable, physDevDst->gc, physDevDst->drawable, physDevDst->gc,
physDevSrc->dc_rect.left + visRectSrc.left, physDevSrc->dc_rect.left + visRectSrc.left,
@ -1427,36 +1419,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE; return TRUE;
} }
break;
case PATCOPY: /* 0xf0 */
if (!X11DRV_SetupGCForBrush( physDevDst )) return TRUE;
wine_tsx11_lock();
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top,
width, height );
wine_tsx11_unlock();
return TRUE;
case WHITENESS: /* 0xff */
wine_tsx11_lock();
if ((physDevDst->depth == 1) || !X11DRV_PALETTE_PaletteToXPixel)
XSetFunction( gdi_display, physDevDst->gc, GXset );
else
{
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
XSetForeground( gdi_display, physDevDst->gc,
WhitePixel( gdi_display, DefaultScreen(gdi_display) ));
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
} }
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
physDevDst->dc_rect.left + visRectDst.left,
physDevDst->dc_rect.top + visRectDst.top,
width, height );
wine_tsx11_unlock();
return TRUE;
} }
wine_tsx11_lock(); wine_tsx11_lock();
@ -1489,7 +1452,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
destUsed = FALSE; destUsed = FALSE;
wine_tsx11_lock(); wine_tsx11_lock();
for (opcode = BITBLT_Opcodes[(rop >> 16) & 0xff]; *opcode; opcode++) for ( ; *opcode; opcode++)
{ {
if (OP_DST(*opcode) == DST) destUsed = TRUE; if (OP_DST(*opcode) == DST) destUsed = TRUE;
XSetFunction( gdi_display, tmpGC, OP_ROP(*opcode) ); XSetFunction( gdi_display, tmpGC, OP_ROP(*opcode) );