Vincent Povirk : gdiplus: Call GdiAlphaBlend only once per GdipFillRegion call.
Alexandre Julliard
julliard at winehq.org
Tue Mar 15 11:33:55 CDT 2011
Module: wine
Branch: master
Commit: 833316f91d428955744f88ee02c71f4bad38e4c2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=833316f91d428955744f88ee02c71f4bad38e4c2
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Thu Mar 10 15:58:22 2011 -0600
gdiplus: Call GdiAlphaBlend only once per GdipFillRegion call.
---
dlls/gdiplus/graphics.c | 93 ++++++++++++++++++++++++++++++++++++-----------
1 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 4d059f8..83e0f24 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -3856,39 +3856,90 @@ static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
if (stat == Ok)
{
- UINT max_size=0;
-
- for (i=0; i<scans_count; i++)
+ if (!graphics->image)
{
- UINT size = scans[i].Width * scans[i].Height;
+ /* If we have to go through gdi32, use as few alpha blends as possible. */
+ INT min_x, min_y, max_x, max_y;
+ UINT data_width, data_height;
- if (size > max_size)
- max_size = size;
- }
+ min_x = scans[0].X;
+ min_y = scans[0].Y;
+ max_x = scans[0].X+scans[0].Width;
+ max_y = scans[0].Y+scans[0].Height;
- pixel_data = GdipAlloc(sizeof(*pixel_data) * max_size);
- if (!pixel_data)
- stat = OutOfMemory;
+ for (i=1; i<scans_count; i++)
+ {
+ min_x = min(min_x, scans[i].X);
+ min_y = min(min_y, scans[i].Y);
+ max_x = max(max_x, scans[i].X+scans[i].Width);
+ max_y = max(max_y, scans[i].Y+scans[i].Height);
+ }
- if (stat == Ok)
- {
- for (i=0; i<scans_count; i++)
+ data_width = max_x - min_x;
+ data_height = max_y - min_y;
+
+ pixel_data = GdipAlloc(sizeof(*pixel_data) * data_width * data_height);
+ if (!pixel_data)
+ stat = OutOfMemory;
+
+ if (stat == Ok)
{
- stat = brush_fill_pixels(graphics, brush, pixel_data, &scans[i],
- scans[i].Width);
+ for (i=0; i<scans_count; i++)
+ {
+ stat = brush_fill_pixels(graphics, brush,
+ pixel_data + (scans[i].X - min_x) + (scans[i].Y - min_y) * data_width,
+ &scans[i], data_width);
+
+ if (stat != Ok)
+ break;
+ }
if (stat == Ok)
{
- stat = alpha_blend_pixels(graphics, scans[i].X, scans[i].Y,
- (BYTE*)pixel_data, scans[i].Width, scans[i].Height,
- scans[i].Width * 4);
+ stat = alpha_blend_pixels(graphics, min_x, min_y,
+ (BYTE*)pixel_data, data_width, data_height,
+ data_width * 4);
}
- if (stat != Ok)
- break;
+ GdipFree(pixel_data);
}
+ }
+ else
+ {
+ UINT max_size=0;
- GdipFree(pixel_data);
+ for (i=0; i<scans_count; i++)
+ {
+ UINT size = scans[i].Width * scans[i].Height;
+
+ if (size > max_size)
+ max_size = size;
+ }
+
+ pixel_data = GdipAlloc(sizeof(*pixel_data) * max_size);
+ if (!pixel_data)
+ stat = OutOfMemory;
+
+ if (stat == Ok)
+ {
+ for (i=0; i<scans_count; i++)
+ {
+ stat = brush_fill_pixels(graphics, brush, pixel_data, &scans[i],
+ scans[i].Width);
+
+ if (stat == Ok)
+ {
+ stat = alpha_blend_pixels(graphics, scans[i].X, scans[i].Y,
+ (BYTE*)pixel_data, scans[i].Width, scans[i].Height,
+ scans[i].Width * 4);
+ }
+
+ if (stat != Ok)
+ break;
+ }
+
+ GdipFree(pixel_data);
+ }
}
GdipFree(scans);
More information about the wine-cvs
mailing list