[mutter] surface-actor: Keep track of ignored damage



commit 53a94112552f6da49d395a9ac800c7f1bc858dbb
Author: Florian Müllner <fmuellner gnome org>
Date:   Fri Jun 17 17:45:20 2016 +0200

    surface-actor: Keep track of ignored damage
    
    We ignore all damage while a surface is frozen and queue a full
    update instead once it's thawed. While not super efficient, this
    isn't overly bad for the intended case of catching up with any
    updates that happened during a compositor effect. However when
    extended frame sync is used, surfaces are also frozen while the
    client is drawing a frame, in which case the current behavior is
    pretty damaging (pun intended), as we end up redrawing the entire
    window each frame. To address this, keep track of the actual damage
    we ignore and apply it when the surface is thawed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=767798

 src/compositor/meta-surface-actor.c |   33 +++++++++++++++++++++------------
 1 files changed, 21 insertions(+), 12 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 6f3a929..bf8c76f 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -25,7 +25,7 @@ struct _MetaSurfaceActorPrivate
   cairo_region_t *input_region;
 
   /* Freeze/thaw accounting */
-  guint needs_damage_all : 1;
+  cairo_region_t *pending_damage;
   guint frozen : 1;
 };
 
@@ -261,9 +261,8 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
        * here on the off chance that this will stop the corresponding
        * texture_from_pixmap from being update.
        *
-       * needs_damage_all tracks that some unknown damage happened while the
-       * window was frozen so that when the window becomes unfrozen we can
-       * issue a full window update to cover any lost damage.
+       * pending_damage tracks any damage that happened while the window was
+       * frozen so that when can apply it when the window becomes unfrozen.
        *
        * It should be noted that this is an unreliable mechanism since it's
        * quite likely that drivers will aim to provide a zero-copy
@@ -271,7 +270,12 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
        * any drawing done to the window is always immediately reflected in the
        * texture regardless of damage event handling.
        */
-      priv->needs_damage_all = TRUE;
+      cairo_rectangle_int_t rect = { .x = x, .y = y, .width = width, .height = height };
+
+      if (!priv->pending_damage)
+        priv->pending_damage = cairo_region_create_rectangle (&rect);
+      else
+        cairo_region_union_rectangle (priv->pending_damage, &rect);
       return;
     }
 
@@ -332,16 +336,21 @@ meta_surface_actor_set_frozen (MetaSurfaceActor *self,
 
   priv->frozen = frozen;
 
-  if (!frozen && priv->needs_damage_all)
+  if (!frozen && priv->pending_damage)
     {
+      int i, n_rects = cairo_region_num_rectangles (priv->pending_damage);
+      cairo_rectangle_int_t rect;
+
       /* Since we ignore damage events while a window is frozen for certain effects
-       * we may need to issue an update_area() covering the whole pixmap if we
-       * don't know what real damage has happened. */
+       * we need to apply the tracked damage now. */
 
-      meta_surface_actor_process_damage (self, 0, 0,
-                                         clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)),
-                                         clutter_actor_get_height (CLUTTER_ACTOR (priv->texture)));
-      priv->needs_damage_all = FALSE;
+      for (i = 0; i < n_rects; i++)
+        {
+          cairo_region_get_rectangle (priv->pending_damage, i, &rect);
+          meta_surface_actor_process_damage (self, rect.x, rect.y,
+                                             rect.width, rect.height);
+        }
+      g_clear_pointer (&priv->pending_damage, cairo_region_destroy);
     }
 }
 


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