From 9bb5b02694e1bbd5c0cdd28606d80fb2d2d701ee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 21 Mar 2012 20:08:15 +0000 Subject: [PATCH] win32: Fix damage flushing The damage wasn't being created on the right surface, so the damage to the fallback image surface was not being tracked. Perform a little bit of juggling so that we track dirty regions on the fallback surface itself. Signed-off-by: Chris Wilson --- src/win32/cairo-win32-display-surface.c | 42 ++++++++++++++++++------- src/win32/cairo-win32-gdi-compositor.c | 5 +-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c index 9e18f8d4b..a66a23eff 100644 --- a/src/win32/cairo-win32-display-surface.c +++ b/src/win32/cairo-win32-display-surface.c @@ -460,9 +460,6 @@ _cairo_win32_display_surface_map_to_image (void *abstract_sur } surface = to_win32_display_surface (surface->fallback); - if (surface->image->damage == NULL) - surface->image->damage = _cairo_damage_create (); - done: GdiFlush(); return _cairo_image_surface_map_to_image (surface->image, extents); @@ -475,14 +472,31 @@ err: } static cairo_int_status_t -_cairo_win32_display_surface_unmap_image (void *surface, +_cairo_win32_display_surface_unmap_image (void *abstract_surface, cairo_image_surface_t *image) { + cairo_win32_display_surface_t *surface = abstract_surface; + /* Delay the download until the next flush, which means we also need * to make sure our sources rare flushed. */ TRACE ((stderr, "%s (surface=%d)\n", __FUNCTION__, to_win32_surface(surface)->base.unique_id)); + + if (surface->fallback) { + cairo_rectangle_int_t r; + + r.x = image->base.device_transform_inverse.x0; + r.y = image->base.device_transform_inverse.y0; + r.width = image->width; + r.height = image->height; + + TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n", + __FUNCTION__, r.x, r.y, r.width, r.height)); + surface->fallback->damage = + _cairo_damage_add_rectangle (surface->fallback->damage, &r); + } + return CAIRO_INT_STATUS_SUCCESS; } @@ -490,7 +504,6 @@ static cairo_status_t _cairo_win32_display_surface_flush (void *abstract_surface) { cairo_win32_display_surface_t *surface = abstract_surface; - cairo_win32_display_surface_t *fallback; cairo_status_t status = CAIRO_STATUS_SUCCESS; TRACE ((stderr, "%s (surface=%d)\n", @@ -498,14 +511,18 @@ _cairo_win32_display_surface_flush (void *abstract_surface) if (surface->fallback == NULL) return CAIRO_STATUS_SUCCESS; - fallback = to_win32_display_surface (surface->fallback); - assert (fallback->image); - - if (fallback->image->damage) { + if (surface->fallback->damage) { + cairo_win32_display_surface_t *fallback; cairo_damage_t *damage; - damage = _cairo_damage_reduce (fallback->image->damage); - fallback->image->damage = NULL; + damage = _cairo_damage_reduce (surface->fallback->damage); + surface->fallback->damage = NULL; + + fallback = to_win32_display_surface (surface->fallback); + assert (fallback->image); + + TRACE ((stderr, "%s: flushing damage x %d\n", __FUNCTION__, + damage->region ? cairo_region_num_rectangles (damage->region) : 0)); if (damage->status) { if (!BitBlt (surface->win32.dc, @@ -522,6 +539,9 @@ _cairo_win32_display_surface_flush (void *abstract_surface) cairo_rectangle_int_t rect; cairo_region_get_rectangle (damage->region, i, &rect); + TRACE ((stderr, "%s: damage (%d,%d)x(%d,%d)\n", __FUNCTION__, + rect.x, rect.y, + rect.width, rect.height)); if (!BitBlt (surface->win32.dc, rect.x, rect.y, rect.width, rect.height, diff --git a/src/win32/cairo-win32-gdi-compositor.c b/src/win32/cairo-win32-gdi-compositor.c index 054d9f248..2bdac6680 100644 --- a/src/win32/cairo-win32-gdi-compositor.c +++ b/src/win32/cairo-win32-gdi-compositor.c @@ -343,7 +343,7 @@ alpha_blend_boxes (cairo_win32_display_surface_t *dst, if (surface == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; } - if (pattern->surface->type != CAIRO_SURFACE_TYPE_WIN32) + if (surface->type != CAIRO_SURFACE_TYPE_WIN32) return CAIRO_INT_STATUS_UNSUPPORTED; if (! _cairo_matrix_is_integer_translation (&source->matrix, @@ -410,7 +410,8 @@ draw_boxes (cairo_composite_rectangles_t *composite, _cairo_pattern_is_opaque (src, &composite->bounded)) op = CAIRO_OPERATOR_SOURCE; - if (dst->win32.base.is_clear && op == CAIRO_OPERATOR_OVER) + if (dst->win32.base.is_clear && + (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD)) op = CAIRO_OPERATOR_SOURCE; if (op == CAIRO_OPERATOR_SOURCE) {