From a80eafe8d761af0f91138777f11998c74f21532e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 27 Dec 2011 16:40:48 +0100 Subject: [PATCH] gdi32: Re-create the brush bits only when the ROP has really changed. --- dlls/gdi32/dibdrv/bitblt.c | 9 +++------ dlls/gdi32/dibdrv/dc.c | 17 ++--------------- dlls/gdi32/dibdrv/dibdrv.h | 7 +++---- dlls/gdi32/dibdrv/graphics.c | 11 +++-------- dlls/gdi32/dibdrv/objects.c | 35 +++++++++++++++++++---------------- 5 files changed, 30 insertions(+), 49 deletions(-) diff --git a/dlls/gdi32/dibdrv/bitblt.c b/dlls/gdi32/dibdrv/bitblt.c index 64ded699cc0..6e0d425c2cf 100644 --- a/dlls/gdi32/dibdrv/bitblt.c +++ b/dlls/gdi32/dibdrv/bitblt.c @@ -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) ); break; case OP_ARGS(PAT,DST): - update_brush_rop( pdev, OP_ROP(*opcode) ); - pdev->brush_rects( pdev, dibs[DST], clipped_rects->count, clipped_rects->rects ); - update_brush_rop( pdev, GetROP2(pdev->dev.hdc) ); + pdev->brush_rects( pdev, dibs[DST], clipped_rects->count, clipped_rects->rects, + OP_ROP(*opcode) ); break; case OP_ARGS(PAT,SRC): - update_brush_rop( pdev, OP_ROP(*opcode) ); - pdev->brush_rects( pdev, dibs[SRC], 1, &rects[SRC] ); - update_brush_rop( pdev, GetROP2(pdev->dev.hdc) ); + pdev->brush_rects( pdev, dibs[SRC], 1, &rects[SRC], OP_ROP(*opcode) ); break; } } diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index d9bb6f9ce79..7001b464611 100644 --- a/dlls/gdi32/dibdrv/dc.c +++ b/dlls/gdi32/dibdrv/dc.c @@ -389,24 +389,11 @@ static UINT dibdrv_SetDIBColorTable( PHYSDEV dev, UINT pos, UINT count, const RG dibdrv_physdev *pdev = get_dibdrv_pdev(dev); 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 ); } -/*********************************************************************** - * 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 = { @@ -523,7 +510,7 @@ const struct gdi_dc_funcs dib_driver = dibdrv_SetPixel, /* pSetPixel */ NULL, /* pSetPixelFormat */ NULL, /* pSetPolyFillMode */ - dibdrv_SetROP2, /* pSetROP2 */ + NULL, /* pSetROP2 */ NULL, /* pSetRelAbs */ NULL, /* pSetStretchBltMode */ NULL, /* pSetTextAlign */ diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h index a100e803e84..31c878379da 100644 --- a/dlls/gdi32/dibdrv/dibdrv.h +++ b/dlls/gdi32/dibdrv/dibdrv.h @@ -93,7 +93,7 @@ typedef struct dibdrv_physdev /* brush */ UINT brush_style; 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; dib_info brush_dib; void *brush_and_bits, *brush_xor_bits; @@ -101,7 +101,7 @@ typedef struct dibdrv_physdev void *brush_pattern_bits; UINT brush_pattern_usage; 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; #define DEFER_PEN 2 @@ -220,7 +220,6 @@ struct clipped_rects }; 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 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; @@ -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 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 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 clip_line(const POINT *start, const POINT *end, const RECT *clip, const bres_params *params, POINT *pt1, POINT *pt2) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c index 0c31c567cc1..e8daa698d91 100644 --- a/dlls/gdi32/dibdrv/graphics.c +++ b/dlls/gdi32/dibdrv/graphics.c @@ -476,15 +476,10 @@ static inline INT get_rop2_from_rop(INT rop) BOOL dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) { 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); - update_brush_rop( pdev, rop2 ); - ret = brush_rect( pdev, &dst->visrect ); - update_brush_rop( pdev, GetROP2(dev->hdc) ); - return ret; + return brush_rect( pdev, &dst->visrect, get_rop2_from_rop(rop) ); } /*********************************************************************** @@ -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, region->rects[i].right, region->rects[i].bottom, FALSE ); - brush_rect( pdev, &rect ); + brush_rect( pdev, &rect, GetROP2( dev->hdc ) ); } release_wine_region( rgn ); @@ -602,7 +597,7 @@ BOOL dibdrv_Rectangle( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) rect.right -= 1; rect.bottom -= 1; - brush_rect(pdev, &rect); + brush_rect( pdev, &rect, GetROP2(dev->hdc) ); return TRUE; } diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c index 7a381e7ad9a..626511c4f65 100644 --- a/dlls/gdi32/dibdrv/objects.c +++ b/dlls/gdi32/dibdrv/objects.c @@ -1369,12 +1369,12 @@ COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) * * 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; 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 ); return TRUE; } @@ -1433,7 +1433,7 @@ static const DWORD hatches[6][8] = { 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; rop_mask fg_mask, bg_mask; @@ -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 ); + 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 ); if(!ret) free_pattern_brush_bits( pdev ); @@ -1591,11 +1596,17 @@ static BOOL select_pattern_brush( dibdrv_physdev *pdev, BOOL *needs_reselect ) * Fill a number of rectangles with the pattern brush * 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; BOOL needs_reselect = FALSE; + if (rop != pdev->brush_rop) + { + free_pattern_brush_bits( pdev ); + pdev->brush_rop = rop; + } + if(pdev->brush_and_bits == NULL) { switch(pdev->brush_style) @@ -1608,7 +1619,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE break; case BS_HATCHED: - if(!create_hatch_brush_bits(pdev)) + if(!create_hatch_brush_bits(pdev, &needs_reselect)) return FALSE; break; @@ -1626,17 +1637,11 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE 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; } -void update_brush_rop( dibdrv_physdev *pdev, INT rop ) -{ - pdev->brush_rop = rop; - free_pattern_brush_bits( pdev ); -} - /*********************************************************************** * dibdrv_SelectBrush */ @@ -1675,7 +1680,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap, { case BS_SOLID: pdev->brush_colorref = logbrush.lbColor; - pdev->brush_rop = GetROP2( dev->hdc ); pdev->brush_rects = solid_brush; break; @@ -1687,7 +1691,6 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap, if(logbrush.lbHatch > HS_DIAGCROSS) return 0; pdev->brush_hatch = logbrush.lbHatch; pdev->brush_colorref = logbrush.lbColor; - pdev->brush_rop = GetROP2( dev->hdc ); pdev->brush_rects = pattern_brush; break; @@ -1712,13 +1715,13 @@ COLORREF dibdrv_SetDCBrushColor( PHYSDEV dev, COLORREF 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; BOOL ret; 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 ); return ret; }