Commit a80eafe8 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Re-create the brush bits only when the ROP has really changed.

parent 8b3271c3
...@@ -761,14 +761,11 @@ static DWORD execute_rop( dibdrv_physdev *pdev, const RECT *dst_rect, dib_info * ...@@ -761,14 +761,11 @@ static DWORD execute_rop( dibdrv_physdev *pdev, const RECT *dst_rect, dib_info *
OP_DST(*opcode) == DST ? clipped_rects : NULL, OP_ROP(*opcode) ); OP_DST(*opcode) == DST ? clipped_rects : NULL, OP_ROP(*opcode) );
break; break;
case OP_ARGS(PAT,DST): case OP_ARGS(PAT,DST):
update_brush_rop( pdev, OP_ROP(*opcode) ); pdev->brush_rects( pdev, dibs[DST], clipped_rects->count, clipped_rects->rects,
pdev->brush_rects( pdev, dibs[DST], clipped_rects->count, clipped_rects->rects ); OP_ROP(*opcode) );
update_brush_rop( pdev, GetROP2(pdev->dev.hdc) );
break; break;
case OP_ARGS(PAT,SRC): case OP_ARGS(PAT,SRC):
update_brush_rop( pdev, OP_ROP(*opcode) ); pdev->brush_rects( pdev, dibs[SRC], 1, &rects[SRC], OP_ROP(*opcode) );
pdev->brush_rects( pdev, dibs[SRC], 1, &rects[SRC] );
update_brush_rop( pdev, GetROP2(pdev->dev.hdc) );
break; break;
} }
} }
......
...@@ -389,24 +389,11 @@ static UINT dibdrv_SetDIBColorTable( PHYSDEV dev, UINT pos, UINT count, const RG ...@@ -389,24 +389,11 @@ static UINT dibdrv_SetDIBColorTable( PHYSDEV dev, UINT pos, UINT count, const RG
dibdrv_physdev *pdev = get_dibdrv_pdev(dev); dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
TRACE("(%p, %d, %d, %p)\n", dev, pos, count, colors); TRACE("(%p, %d, %d, %p)\n", dev, pos, count, colors);
if (pdev->dib.color_table) update_brush_rop( pdev, GetROP2( dev->hdc ) ); if (pdev->dib.color_table) pdev->brush_rop = -1; /* force re-creating the brush bits */
return next->funcs->pSetDIBColorTable( next, pos, count, colors ); return next->funcs->pSetDIBColorTable( next, pos, count, colors );
} }
/***********************************************************************
* dibdrv_SetROP2
*/
static INT dibdrv_SetROP2( PHYSDEV dev, INT rop )
{
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetROP2 );
dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
update_brush_rop( pdev, rop );
return next->funcs->pSetROP2( next, rop );
}
const struct gdi_dc_funcs dib_driver = const struct gdi_dc_funcs dib_driver =
{ {
...@@ -523,7 +510,7 @@ const struct gdi_dc_funcs dib_driver = ...@@ -523,7 +510,7 @@ const struct gdi_dc_funcs dib_driver =
dibdrv_SetPixel, /* pSetPixel */ dibdrv_SetPixel, /* pSetPixel */
NULL, /* pSetPixelFormat */ NULL, /* pSetPixelFormat */
NULL, /* pSetPolyFillMode */ NULL, /* pSetPolyFillMode */
dibdrv_SetROP2, /* pSetROP2 */ NULL, /* pSetROP2 */
NULL, /* pSetRelAbs */ NULL, /* pSetRelAbs */
NULL, /* pSetStretchBltMode */ NULL, /* pSetStretchBltMode */
NULL, /* pSetTextAlign */ NULL, /* pSetTextAlign */
......
...@@ -93,7 +93,7 @@ typedef struct dibdrv_physdev ...@@ -93,7 +93,7 @@ typedef struct dibdrv_physdev
/* brush */ /* brush */
UINT brush_style; UINT brush_style;
UINT brush_hatch; UINT brush_hatch;
INT brush_rop; /* PatBlt, for example, can override the DC's rop2 */ INT brush_rop; /* rop2 last used to create the brush bits */
COLORREF brush_colorref; COLORREF brush_colorref;
dib_info brush_dib; dib_info brush_dib;
void *brush_and_bits, *brush_xor_bits; void *brush_and_bits, *brush_xor_bits;
...@@ -101,7 +101,7 @@ typedef struct dibdrv_physdev ...@@ -101,7 +101,7 @@ typedef struct dibdrv_physdev
void *brush_pattern_bits; void *brush_pattern_bits;
UINT brush_pattern_usage; UINT brush_pattern_usage;
HBITMAP brush_pattern_bitmap; HBITMAP brush_pattern_bitmap;
BOOL (* brush_rects)(struct dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects); BOOL (* brush_rects)(struct dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, INT rop);
} dibdrv_physdev; } dibdrv_physdev;
#define DEFER_PEN 2 #define DEFER_PEN 2
...@@ -220,7 +220,6 @@ struct clipped_rects ...@@ -220,7 +220,6 @@ struct clipped_rects
}; };
extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN; extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN;
extern void update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN; extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
extern void init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags) DECLSPEC_HIDDEN; extern void init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags) DECLSPEC_HIDDEN;
extern BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) DECLSPEC_HIDDEN; extern BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) DECLSPEC_HIDDEN;
...@@ -230,7 +229,7 @@ extern void copy_dib_color_info(dib_info *dst, const dib_info *src) DECLSPEC_HID ...@@ -230,7 +229,7 @@ extern void copy_dib_color_info(dib_info *dst, const dib_info *src) DECLSPEC_HID
extern BOOL convert_dib(dib_info *dst, const dib_info *src) DECLSPEC_HIDDEN; extern BOOL convert_dib(dib_info *dst, const dib_info *src) DECLSPEC_HIDDEN;
extern COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel ) DECLSPEC_HIDDEN; extern COLORREF make_rgb_colorref( HDC hdc, dib_info *dib, COLORREF color, BOOL *got_pixel, DWORD *pixel ) DECLSPEC_HIDDEN;
extern DWORD get_pixel_color(dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup) DECLSPEC_HIDDEN; extern DWORD get_pixel_color(dibdrv_physdev *pdev, COLORREF color, BOOL mono_fixup) DECLSPEC_HIDDEN;
extern BOOL brush_rect( dibdrv_physdev *pdev, const RECT *rect ) DECLSPEC_HIDDEN; extern BOOL brush_rect( dibdrv_physdev *pdev, const RECT *rect, INT rop ) DECLSPEC_HIDDEN;
extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN; extern int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects ) DECLSPEC_HIDDEN;
extern int clip_line(const POINT *start, const POINT *end, const RECT *clip, extern int clip_line(const POINT *start, const POINT *end, const RECT *clip,
const bres_params *params, POINT *pt1, POINT *pt2) DECLSPEC_HIDDEN; const bres_params *params, POINT *pt1, POINT *pt2) DECLSPEC_HIDDEN;
......
...@@ -476,15 +476,10 @@ static inline INT get_rop2_from_rop(INT rop) ...@@ -476,15 +476,10 @@ static inline INT get_rop2_from_rop(INT rop)
BOOL dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) BOOL dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop )
{ {
dibdrv_physdev *pdev = get_dibdrv_pdev(dev); dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
INT rop2 = get_rop2_from_rop(rop);
BOOL ret;
TRACE("(%p, %d, %d, %d, %d, %06x)\n", dev, dst->x, dst->y, dst->width, dst->height, rop); TRACE("(%p, %d, %d, %d, %d, %06x)\n", dev, dst->x, dst->y, dst->width, dst->height, rop);
update_brush_rop( pdev, rop2 ); return brush_rect( pdev, &dst->visrect, get_rop2_from_rop(rop) );
ret = brush_rect( pdev, &dst->visrect );
update_brush_rop( pdev, GetROP2(dev->hdc) );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -506,7 +501,7 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn ) ...@@ -506,7 +501,7 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn )
{ {
rect = get_device_rect( dev->hdc, region->rects[i].left, region->rects[i].top, rect = get_device_rect( dev->hdc, region->rects[i].left, region->rects[i].top,
region->rects[i].right, region->rects[i].bottom, FALSE ); region->rects[i].right, region->rects[i].bottom, FALSE );
brush_rect( pdev, &rect ); brush_rect( pdev, &rect, GetROP2( dev->hdc ) );
} }
release_wine_region( rgn ); release_wine_region( rgn );
...@@ -602,7 +597,7 @@ BOOL dibdrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) ...@@ -602,7 +597,7 @@ BOOL dibdrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom )
rect.right -= 1; rect.right -= 1;
rect.bottom -= 1; rect.bottom -= 1;
brush_rect(pdev, &rect); brush_rect( pdev, &rect, GetROP2(dev->hdc) );
return TRUE; return TRUE;
} }
......
...@@ -1369,12 +1369,12 @@ COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) ...@@ -1369,12 +1369,12 @@ COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color )
* *
* Fill a number of rectangles with the solid brush * Fill a number of rectangles with the solid brush
*/ */
static BOOL solid_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects) static BOOL solid_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, INT rop)
{ {
rop_mask brush_color; rop_mask brush_color;
DWORD color = get_pixel_color( pdev, pdev->brush_colorref, TRUE ); DWORD color = get_pixel_color( pdev, pdev->brush_colorref, TRUE );
calc_rop_masks( pdev->brush_rop, color, &brush_color ); calc_rop_masks( rop, color, &brush_color );
dib->funcs->solid_rects( dib, num, rects, brush_color.and, brush_color.xor ); dib->funcs->solid_rects( dib, num, rects, brush_color.and, brush_color.xor );
return TRUE; return TRUE;
} }
...@@ -1433,7 +1433,7 @@ static const DWORD hatches[6][8] = ...@@ -1433,7 +1433,7 @@ static const DWORD hatches[6][8] =
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 } /* HS_DIAGCROSS */
}; };
static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev) static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev, BOOL *needs_reselect)
{ {
dib_info hatch; dib_info hatch;
rop_mask fg_mask, bg_mask; rop_mask fg_mask, bg_mask;
...@@ -1474,6 +1474,11 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev) ...@@ -1474,6 +1474,11 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev)
get_color_masks( pdev, pdev->brush_rop, pdev->brush_colorref, &fg_mask, &bg_mask ); get_color_masks( pdev, pdev->brush_rop, pdev->brush_colorref, &fg_mask, &bg_mask );
if (pdev->brush_colorref & (1 << 24)) /* PALETTEINDEX */
*needs_reselect = TRUE;
if (GetBkMode(pdev->dev.hdc) != TRANSPARENT && (GetBkColor(pdev->dev.hdc) & (1 << 24)))
*needs_reselect = TRUE;
ret = pdev->brush_dib.funcs->create_rop_masks( &pdev->brush_dib, &hatch, &fg_mask, &bg_mask, &mask_bits ); ret = pdev->brush_dib.funcs->create_rop_masks( &pdev->brush_dib, &hatch, &fg_mask, &bg_mask, &mask_bits );
if(!ret) free_pattern_brush_bits( pdev ); if(!ret) free_pattern_brush_bits( pdev );
...@@ -1591,11 +1596,17 @@ static BOOL select_pattern_brush( dibdrv_physdev *pdev, BOOL *needs_reselect ) ...@@ -1591,11 +1596,17 @@ static BOOL select_pattern_brush( dibdrv_physdev *pdev, BOOL *needs_reselect )
* Fill a number of rectangles with the pattern brush * Fill a number of rectangles with the pattern brush
* FIXME: Should we insist l < r && t < b? Currently we assume this. * FIXME: Should we insist l < r && t < b? Currently we assume this.
*/ */
static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects) static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, INT rop)
{ {
POINT origin; POINT origin;
BOOL needs_reselect = FALSE; BOOL needs_reselect = FALSE;
if (rop != pdev->brush_rop)
{
free_pattern_brush_bits( pdev );
pdev->brush_rop = rop;
}
if(pdev->brush_and_bits == NULL) if(pdev->brush_and_bits == NULL)
{ {
switch(pdev->brush_style) switch(pdev->brush_style)
...@@ -1608,7 +1619,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE ...@@ -1608,7 +1619,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
break; break;
case BS_HATCHED: case BS_HATCHED:
if(!create_hatch_brush_bits(pdev)) if(!create_hatch_brush_bits(pdev, &needs_reselect))
return FALSE; return FALSE;
break; break;
...@@ -1626,17 +1637,11 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE ...@@ -1626,17 +1637,11 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
return TRUE; return TRUE;
} }
static BOOL null_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects) static BOOL null_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, INT rop)
{ {
return TRUE; return TRUE;
} }
void update_brush_rop( dibdrv_physdev *pdev, INT rop )
{
pdev->brush_rop = rop;
free_pattern_brush_bits( pdev );
}
/*********************************************************************** /***********************************************************************
* dibdrv_SelectBrush * dibdrv_SelectBrush
*/ */
...@@ -1675,7 +1680,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap, ...@@ -1675,7 +1680,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
{ {
case BS_SOLID: case BS_SOLID:
pdev->brush_colorref = logbrush.lbColor; pdev->brush_colorref = logbrush.lbColor;
pdev->brush_rop = GetROP2( dev->hdc );
pdev->brush_rects = solid_brush; pdev->brush_rects = solid_brush;
break; break;
...@@ -1687,7 +1691,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap, ...@@ -1687,7 +1691,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
if(logbrush.lbHatch > HS_DIAGCROSS) return 0; if(logbrush.lbHatch > HS_DIAGCROSS) return 0;
pdev->brush_hatch = logbrush.lbHatch; pdev->brush_hatch = logbrush.lbHatch;
pdev->brush_colorref = logbrush.lbColor; pdev->brush_colorref = logbrush.lbColor;
pdev->brush_rop = GetROP2( dev->hdc );
pdev->brush_rects = pattern_brush; pdev->brush_rects = pattern_brush;
break; break;
...@@ -1712,13 +1715,13 @@ COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color ) ...@@ -1712,13 +1715,13 @@ COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF color )
return next->funcs->pSetDCBrushColor( next, color ); return next->funcs->pSetDCBrushColor( next, color );
} }
BOOL brush_rect(dibdrv_physdev *pdev, const RECT *rect) BOOL brush_rect(dibdrv_physdev *pdev, const RECT *rect, INT rop)
{ {
struct clipped_rects clipped_rects; struct clipped_rects clipped_rects;
BOOL ret; BOOL ret;
if (!get_clipped_rects( &pdev->dib, rect, pdev->clip, &clipped_rects )) return TRUE; if (!get_clipped_rects( &pdev->dib, rect, pdev->clip, &clipped_rects )) return TRUE;
ret = pdev->brush_rects( pdev, &pdev->dib, clipped_rects.count, clipped_rects.rects ); ret = pdev->brush_rects( pdev, &pdev->dib, clipped_rects.count, clipped_rects.rects, rop );
free_clipped_rects( &clipped_rects ); free_clipped_rects( &clipped_rects );
return ret; return ret;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment