From b80b465a653db0b04de7b0e384760333a39cf6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Fri, 6 Mar 2020 10:33:30 +0000 Subject: [PATCH] clutter/stage-cogl: Fix painting the redraw clip with the damage region The redraw clip that's painted together with the damage region has to be copied earlier than we do right now. That's because if PAINT_DAMAGE_REGION is enabled, buffer age is disabled and thus use_clipped_redraw is FALSE. That means the redraw_clip is updated and set to the full view-rect. If we copy the queued_redraw_clip after that, it's also going to be set to the full view-rect. So copy the redraw clip a bit earlier to make sure we're actually passing the real redraw clip to paint_damage_region(). Also keep the queued_redraw_clip around a bit longer so it can actually be used by paint_damage_region() and isn't freed before that. While at it, move paint_damage_region() from swap_framebuffer() into clutter_stage_cogl_redraw_view() so we don't have to pass things to swap_framebuffer() only for debugging. Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1104 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1208 (cherry picked from commit 793a9d45e14909b5c27219a7c41352c99b07f077) --- clutter/clutter/cogl/clutter-stage-cogl.c | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 28b33455f..9031f5291 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -403,15 +403,11 @@ static gboolean swap_framebuffer (ClutterStageWindow *stage_window, ClutterStageView *view, cairo_region_t *swap_region, - gboolean swap_with_damage, - cairo_region_t *queued_redraw_clip) + gboolean swap_with_damage) { CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); int *damage, n_rects, i; - if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))) - paint_damage_region (stage_window, view, swap_region, queued_redraw_clip); - n_rects = cairo_region_num_rectangles (swap_region); damage = g_newa (int, n_rects * 4); for (i = 0; i < n_rects; i++) @@ -648,7 +644,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, gboolean swap_with_damage; ClutterActor *wrapper; cairo_region_t *redraw_clip; - cairo_region_t *queued_redraw_clip; + cairo_region_t *queued_redraw_clip = NULL; cairo_region_t *fb_clip_region; cairo_region_t *swap_region; cairo_rectangle_int_t redraw_rect; @@ -672,6 +668,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled (); redraw_clip = clutter_stage_view_take_redraw_clip (view); + if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)) + queued_redraw_clip = cairo_region_copy (redraw_clip); /* NB: a NULL redraw clip == full stage redraw */ if (!redraw_clip) @@ -739,8 +737,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, redraw_clip = cairo_region_create_rectangle (&view_rect); } - queued_redraw_clip = cairo_region_copy (redraw_clip); - if (may_use_clipped_redraw && G_LIKELY (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_CLIPPED_REDRAWS))) use_clipped_redraw = TRUE; @@ -950,7 +946,6 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, } g_clear_pointer (&redraw_clip, cairo_region_destroy); - g_clear_pointer (&queued_redraw_clip, cairo_region_destroy); g_clear_pointer (&fb_clip_region, cairo_region_destroy); if (do_swap_buffer) @@ -971,11 +966,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, swap_region = transformed_swap_region; } + if (queued_redraw_clip) + { + paint_damage_region (stage_window, view, + swap_region, queued_redraw_clip); + cairo_region_destroy (queued_redraw_clip); + } + res = swap_framebuffer (stage_window, view, swap_region, - swap_with_damage, - queued_redraw_clip); + swap_with_damage); cairo_region_destroy (swap_region); @@ -983,6 +984,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window, } else { + g_clear_pointer (&queued_redraw_clip, cairo_region_destroy); return FALSE; } }