winex11: Make the BitBlt short-cuts more generic to apply to all possible ROPs.
This commit is contained in:
parent
997e5f1230
commit
23afe2e94c
|
@ -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,143 +1320,106 @@ 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])
|
||||||
{
|
{
|
||||||
case BLACKNESS: /* 0x00 */
|
if (OP_SRCDST(*opcode) == OP_ARGS(PAT,DST))
|
||||||
wine_tsx11_lock();
|
|
||||||
if ((physDevDst->depth == 1) || !X11DRV_PALETTE_PaletteToXPixel)
|
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXclear );
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
|
switch(rop) /* a few special cases */
|
||||||
XSetForeground( gdi_display, physDevDst->gc, X11DRV_PALETTE_PaletteToXPixel[0] );
|
{
|
||||||
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
|
case BLACKNESS: /* 0x00 */
|
||||||
}
|
case WHITENESS: /* 0xff */
|
||||||
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
if ((physDevDst->depth != 1) && X11DRV_PALETTE_PaletteToXPixel)
|
||||||
physDevDst->dc_rect.left + visRectDst.left,
|
{
|
||||||
physDevDst->dc_rect.top + visRectDst.top,
|
wine_tsx11_lock();
|
||||||
width, height );
|
XSetFunction( gdi_display, physDevDst->gc, GXcopy );
|
||||||
wine_tsx11_unlock();
|
if (rop == BLACKNESS)
|
||||||
return TRUE;
|
XSetForeground( gdi_display, physDevDst->gc, X11DRV_PALETTE_PaletteToXPixel[0] );
|
||||||
|
else
|
||||||
case DSTINVERT: /* 0x55 */
|
XSetForeground( gdi_display, physDevDst->gc,
|
||||||
wine_tsx11_lock();
|
WhitePixel( gdi_display, DefaultScreen(gdi_display) ));
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXinvert );
|
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
|
||||||
|
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
||||||
if( X11DRV_PALETTE_PaletteFlags & (X11DRV_PALETTE_PRIVATE | X11DRV_PALETTE_VIRTUAL) )
|
physDevDst->dc_rect.left + visRectDst.left,
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXinvert);
|
physDevDst->dc_rect.top + visRectDst.top,
|
||||||
else
|
width, height );
|
||||||
{
|
wine_tsx11_unlock();
|
||||||
/* Xor is much better when we do not have full colormap. */
|
return TRUE;
|
||||||
/* Using white^black ensures that we invert at least black */
|
}
|
||||||
/* and white. */
|
break;
|
||||||
unsigned long xor_pix = (WhitePixel( gdi_display, DefaultScreen(gdi_display) ) ^
|
case DSTINVERT: /* 0x55 */
|
||||||
BlackPixel( gdi_display, DefaultScreen(gdi_display) ));
|
if (!(X11DRV_PALETTE_PaletteFlags & (X11DRV_PALETTE_PRIVATE | X11DRV_PALETTE_VIRTUAL)))
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXxor );
|
{
|
||||||
XSetForeground( gdi_display, physDevDst->gc, xor_pix);
|
/* Xor is much better when we do not have full colormap. */
|
||||||
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
|
/* Using white^black ensures that we invert at least black */
|
||||||
}
|
/* and white. */
|
||||||
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
unsigned long xor_pix = (WhitePixel( gdi_display, DefaultScreen(gdi_display) ) ^
|
||||||
physDevDst->dc_rect.left + visRectDst.left,
|
BlackPixel( gdi_display, DefaultScreen(gdi_display) ));
|
||||||
physDevDst->dc_rect.top + visRectDst.top,
|
wine_tsx11_lock();
|
||||||
width, height );
|
XSetFunction( gdi_display, physDevDst->gc, GXxor );
|
||||||
wine_tsx11_unlock();
|
XSetForeground( gdi_display, physDevDst->gc, xor_pix);
|
||||||
return TRUE;
|
XSetFillStyle( gdi_display, physDevDst->gc, FillSolid );
|
||||||
|
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
||||||
case PATINVERT: /* 0x5a */
|
physDevDst->dc_rect.left + visRectDst.left,
|
||||||
if (X11DRV_SetupGCForBrush( physDevDst ))
|
physDevDst->dc_rect.top + visRectDst.top,
|
||||||
{
|
width, height );
|
||||||
wine_tsx11_lock();
|
wine_tsx11_unlock();
|
||||||
XSetFunction( gdi_display, physDevDst->gc, GXxor );
|
return TRUE;
|
||||||
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
}
|
||||||
physDevDst->dc_rect.left + visRectDst.left,
|
break;
|
||||||
physDevDst->dc_rect.top + visRectDst.top,
|
}
|
||||||
width, height );
|
if (!usePat || X11DRV_SetupGCForBrush( physDevDst ))
|
||||||
wine_tsx11_unlock();
|
{
|
||||||
}
|
wine_tsx11_lock();
|
||||||
return TRUE;
|
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
|
||||||
|
XFillRectangle( gdi_display, physDevDst->drawable, physDevDst->gc,
|
||||||
case 0xa50065:
|
physDevDst->dc_rect.left + visRectDst.left,
|
||||||
if (X11DRV_SetupGCForBrush( physDevDst ))
|
physDevDst->dc_rect.top + visRectDst.top,
|
||||||
{
|
width, height );
|
||||||
wine_tsx11_lock();
|
wine_tsx11_unlock();
|
||||||
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)
|
|
||||||
{
|
|
||||||
wine_tsx11_lock();
|
|
||||||
XSetFunction( gdi_display, physDevDst->gc, rop == SRCCOPY ? GXcopy : GXxor );
|
|
||||||
XCopyArea( gdi_display, physDevSrc->drawable,
|
|
||||||
physDevDst->drawable, physDevDst->gc,
|
|
||||||
physDevSrc->dc_rect.left + visRectSrc.left,
|
|
||||||
physDevSrc->dc_rect.top + visRectSrc.top,
|
|
||||||
width, height,
|
|
||||||
physDevDst->dc_rect.left + visRectDst.left,
|
|
||||||
physDevDst->dc_rect.top + visRectDst.top );
|
|
||||||
physDevDst->exposures++;
|
|
||||||
wine_tsx11_unlock();
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else if (OP_SRCDST(*opcode) == OP_ARGS(SRC,DST))
|
||||||
if (physDevSrc->depth == 1)
|
|
||||||
{
|
{
|
||||||
int fg, bg;
|
if (physDevSrc->depth == physDevDst->depth)
|
||||||
get_colors(physDevDst, physDevSrc, &fg, &bg);
|
{
|
||||||
wine_tsx11_lock();
|
wine_tsx11_lock();
|
||||||
|
XSetFunction( gdi_display, physDevDst->gc, OP_ROP(*opcode) );
|
||||||
|
XCopyArea( gdi_display, physDevSrc->drawable,
|
||||||
|
physDevDst->drawable, physDevDst->gc,
|
||||||
|
physDevSrc->dc_rect.left + visRectSrc.left,
|
||||||
|
physDevSrc->dc_rect.top + visRectSrc.top,
|
||||||
|
width, height,
|
||||||
|
physDevDst->dc_rect.left + visRectDst.left,
|
||||||
|
physDevDst->dc_rect.top + visRectDst.top );
|
||||||
|
physDevDst->exposures++;
|
||||||
|
wine_tsx11_unlock();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (physDevSrc->depth == 1)
|
||||||
|
{
|
||||||
|
int fg, bg;
|
||||||
|
get_colors(physDevDst, physDevSrc, &fg, &bg);
|
||||||
|
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, 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,
|
||||||
physDevSrc->dc_rect.top + visRectSrc.top,
|
physDevSrc->dc_rect.top + visRectSrc.top,
|
||||||
width, height,
|
width, height,
|
||||||
physDevDst->dc_rect.left + visRectDst.left,
|
physDevDst->dc_rect.left + visRectDst.left,
|
||||||
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;
|
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) );
|
||||||
|
|
Loading…
Reference in New Issue