Blame SOURCES/0001-surface-actor-Keep-track-of-ignored-damage.patch

d1d875
From 8a951218911168ab386642769b98de42f177a279 Mon Sep 17 00:00:00 2001
d1d875
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
d1d875
Date: Fri, 17 Jun 2016 17:45:20 +0200
d1d875
Subject: [PATCH] surface-actor: Keep track of ignored damage
d1d875
d1d875
We ignore all damage while a surface is frozen and queue a full
d1d875
update instead once it's thawed. While not super efficient, this
d1d875
isn't overly bad for the intended case of catching up with any
d1d875
updates that happened during a compositor effect. However when
d1d875
extended frame sync is used, surfaces are also frozen while the
d1d875
client is drawing a frame, in which case the current behavior is
d1d875
pretty damaging (pun intended), as we end up redrawing the entire
d1d875
window each frame. To address this, keep track of the actual damage
d1d875
we ignore and apply it when the surface is thawed.
d1d875
d1d875
https://bugzilla.gnome.org/show_bug.cgi?id=767798
d1d875
---
d1d875
 src/compositor/meta-surface-actor.c | 33 +++++++++++++++++++++------------
d1d875
 1 file changed, 21 insertions(+), 12 deletions(-)
d1d875
d1d875
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
d1d875
index bb85478..5844b37 100644
d1d875
--- a/src/compositor/meta-surface-actor.c
d1d875
+++ b/src/compositor/meta-surface-actor.c
d1d875
@@ -25,7 +25,7 @@ struct _MetaSurfaceActorPrivate
d1d875
   cairo_region_t *input_region;
d1d875
 
d1d875
   /* Freeze/thaw accounting */
d1d875
-  guint needs_damage_all : 1;
d1d875
+  cairo_region_t *pending_damage;
d1d875
   guint frozen : 1;
d1d875
 };
d1d875
 
d1d875
@@ -247,9 +247,8 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
d1d875
        * here on the off chance that this will stop the corresponding
d1d875
        * texture_from_pixmap from being update.
d1d875
        *
d1d875
-       * needs_damage_all tracks that some unknown damage happened while the
d1d875
-       * window was frozen so that when the window becomes unfrozen we can
d1d875
-       * issue a full window update to cover any lost damage.
d1d875
+       * pending_damage tracks any damage that happened while the window was
d1d875
+       * frozen so that when can apply it when the window becomes unfrozen.
d1d875
        *
d1d875
        * It should be noted that this is an unreliable mechanism since it's
d1d875
        * quite likely that drivers will aim to provide a zero-copy
d1d875
@@ -257,7 +256,12 @@ meta_surface_actor_process_damage (MetaSurfaceActor *self,
d1d875
        * any drawing done to the window is always immediately reflected in the
d1d875
        * texture regardless of damage event handling.
d1d875
        */
d1d875
-      priv->needs_damage_all = TRUE;
d1d875
+      cairo_rectangle_int_t rect = { .x = x, .y = y, .width = width, .height = height };
d1d875
+
d1d875
+      if (!priv->pending_damage)
d1d875
+        priv->pending_damage = cairo_region_create_rectangle (&rect);
d1d875
+      else
d1d875
+        cairo_region_union_rectangle (priv->pending_damage, &rect);
d1d875
       return;
d1d875
     }
d1d875
 
d1d875
@@ -318,16 +322,21 @@ meta_surface_actor_set_frozen (MetaSurfaceActor *self,
d1d875
 
d1d875
   priv->frozen = frozen;
d1d875
 
d1d875
-  if (!frozen && priv->needs_damage_all)
d1d875
+  if (!frozen && priv->pending_damage)
d1d875
     {
d1d875
+      int i, n_rects = cairo_region_num_rectangles (priv->pending_damage);
d1d875
+      cairo_rectangle_int_t rect;
d1d875
+
d1d875
       /* Since we ignore damage events while a window is frozen for certain effects
d1d875
-       * we may need to issue an update_area() covering the whole pixmap if we
d1d875
-       * don't know what real damage has happened. */
d1d875
+       * we need to apply the tracked damage now. */
d1d875
 
d1d875
-      meta_surface_actor_process_damage (self, 0, 0,
d1d875
-                                         clutter_actor_get_width (CLUTTER_ACTOR (priv->texture)),
d1d875
-                                         clutter_actor_get_height (CLUTTER_ACTOR (priv->texture)));
d1d875
-      priv->needs_damage_all = FALSE;
d1d875
+      for (i = 0; i < n_rects; i++)
d1d875
+        {
d1d875
+          cairo_region_get_rectangle (priv->pending_damage, i, &rect);
d1d875
+          meta_surface_actor_process_damage (self, rect.x, rect.y,
d1d875
+                                             rect.width, rect.height);
d1d875
+        }
d1d875
+      g_clear_pointer (&priv->pending_damage, cairo_region_destroy);
d1d875
     }
d1d875
 }
d1d875
 
d1d875
-- 
d1d875
2.7.4
d1d875