[mutter] clutter/stage-cogl: Check for buffer age early



commit 92710d8f895188ffee99a50079c96f2a2354eebd
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Thu Mar 19 22:30:06 2020 +0100

    clutter/stage-cogl: Check for buffer age early
    
    Fix a regression that got introduced with
    c483b52d240136cf49b358cde2c0d2c0ed237e51 where we started passing the
    redraw_clip to paint_stage() instead of creating a temporary view_region
    for unclipped redraws: In case we detect an invalid buffer age, we fall
    back to doing an unclipped redraw after we passed the first check
    setting up may_use_clipped_redraw. That means we didn't reset the
    redraw_clip to the view_rect, and we're now going to redraw the stage
    using the original redraw clip even though we're swapping the full
    framebuffer without damage.
    
    To fix that, check for the buffer age before setting up the
    fb_clip_region and the redraw_clip and set may_use_clipped_redraw to
    FALSE if the buffer age is invalid, too. This ensures the redraw_clip is
    always going to be correctly set to the view rect when we want to force
    a full redraw.
    
    Fixes https://gitlab.gnome.org/GNOME/mutter/issues/1128

 clutter/clutter/cogl/clutter-stage-cogl.c | 102 ++++++++++++++----------------
 1 file changed, 46 insertions(+), 56 deletions(-)
---
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index f345313cf..d48e97641 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -628,6 +628,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   float fb_scale;
   int subpixel_compensation = 0;
   int fb_width, fb_height;
+  int buffer_age;
 
   wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
 
@@ -650,16 +651,26 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   else
     is_full_redraw = FALSE;
 
-  may_use_clipped_redraw = FALSE;
-  if (_clutter_stage_window_can_clip_redraws (stage_window) &&
-      (can_blit_sub_buffer || has_buffer_age) &&
-      !is_full_redraw &&
-      /* some drivers struggle to get going and produce some junk
-       * frames when starting up... */
-      cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
+  may_use_clipped_redraw =
+    _clutter_stage_window_can_clip_redraws (stage_window) &&
+    (can_blit_sub_buffer || has_buffer_age) &&
+    !is_full_redraw &&
+    /* some drivers struggle to get going and produce some junk
+     * frames when starting up... */
+    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
+
+  if (has_buffer_age)
     {
-      may_use_clipped_redraw = TRUE;
+      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
+      if (!valid_buffer_age (view_cogl, buffer_age))
+        {
+          CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", buffer_age);
+          may_use_clipped_redraw = FALSE;
+        }
+    }
 
+  if (may_use_clipped_redraw)
+    {
       fb_clip_region = offset_scale_and_clamp_region (redraw_clip,
                                                       -view_rect.x,
                                                       -view_rect.y,
@@ -715,64 +726,43 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
     {
       if (use_clipped_redraw && !clip_region_empty)
         {
-          int age;
-
-          age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
+          cairo_region_t *fb_damage;
+          cairo_region_t *view_damage;
+          int i;
 
-          if (valid_buffer_age (view_cogl, age))
-            {
-              cairo_region_t *fb_damage;
-              cairo_region_t *view_damage;
-              int i;
-
-              fill_current_damage_history (view, fb_clip_region);
+          fill_current_damage_history (view, fb_clip_region);
 
-              fb_damage = cairo_region_create ();
+          fb_damage = cairo_region_create ();
 
-              for (i = 1; i <= age; i++)
-                {
-                  int damage_index;
+          for (i = 1; i <= buffer_age; i++)
+            {
+              int damage_index;
 
-                  damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
-                  cairo_region_union (fb_damage,
-                                      view_priv->damage_history[damage_index]);
-                }
+              damage_index = DAMAGE_HISTORY (view_priv->damage_index - i - 1);
+              cairo_region_union (fb_damage,
+                                  view_priv->damage_history[damage_index]);
+            }
 
-              /* Update the fb clip region with the extra damage. */
-              cairo_region_union (fb_clip_region, fb_damage);
+          /* Update the fb clip region with the extra damage. */
+          cairo_region_union (fb_clip_region, fb_damage);
 
-              view_damage = offset_scale_and_clamp_region (fb_damage,
-                                                           0, 0,
-                                                           1.0f / fb_scale);
-              cairo_region_translate (view_damage, view_rect.x, view_rect.y);
-              cairo_region_intersect_rectangle (view_damage, &view_rect);
+          view_damage = offset_scale_and_clamp_region (fb_damage,
+                                                       0, 0,
+                                                       1.0f / fb_scale);
+          cairo_region_translate (view_damage, view_rect.x, view_rect.y);
+          cairo_region_intersect_rectangle (view_damage, &view_rect);
 
-              /* Update the redraw clip region with the extra damage. */
-              cairo_region_union (redraw_clip, view_damage);
+          /* Update the redraw clip region with the extra damage. */
+          cairo_region_union (redraw_clip, view_damage);
 
-              cairo_region_destroy (view_damage);
-              cairo_region_destroy (fb_damage);
+          cairo_region_destroy (view_damage);
+          cairo_region_destroy (fb_damage);
 
-              CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
-                            age,
-                            cairo_region_num_rectangles (fb_clip_region));
+          CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: num rects: %d\n",
+                        buffer_age,
+                        cairo_region_num_rectangles (fb_clip_region));
 
-              swap_with_damage = TRUE;
-            }
-          else
-            {
-              cairo_rectangle_int_t fb_damage;
-
-              CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
-              use_clipped_redraw = FALSE;
-              fb_damage = (cairo_rectangle_int_t) {
-                .x = 0,
-                .y = 0,
-                .width = ceilf (view_rect.width * fb_scale),
-                .height = ceilf (view_rect.height * fb_scale)
-              };
-              fill_current_damage_history_rectangle (view, &fb_damage);
-            }
+          swap_with_damage = TRUE;
         }
       else if (!use_clipped_redraw)
         {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]