[mutter] compositor: Don't emit size-changed when only position changes



commit 01e20a6ba9e0cfa22e864c01b3395ba9568b061a
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Tue May 7 18:08:13 2019 +0800

    compositor: Don't emit size-changed when only position changes
    
    Waking up gnome-shell and triggering JavaScript listeners of
    `size-changed` every time a window was only moved was wasting a lot
    of CPU.
    
    This cuts the CPU requirement for dragging windows by around 22%.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/568

 src/compositor/compositor.c                |  8 ++++--
 src/compositor/meta-window-actor-private.h | 12 +++++++--
 src/compositor/meta-window-actor.c         | 43 +++++++++++++++++++++++++-----
 3 files changed, 52 insertions(+), 11 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index ba05451ad..42a0dc272 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -1134,8 +1134,12 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
                                       gboolean        did_placement)
 {
   MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
-  meta_window_actor_sync_actor_geometry (window_actor, did_placement);
-  meta_plugin_manager_event_size_changed (compositor->plugin_mgr, window_actor);
+  MetaWindowActorChanges changes;
+
+  changes = meta_window_actor_sync_actor_geometry (window_actor, did_placement);
+
+  if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
+    meta_plugin_manager_event_size_changed (compositor->plugin_mgr, window_actor);
 }
 
 static void
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 9a97d53e2..396e84a8a 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -28,6 +28,12 @@ struct _MetaWindowActorClass
   void (*queue_destroy) (MetaWindowActor *actor);
 };
 
+typedef enum
+{
+  META_WINDOW_ACTOR_CHANGE_SIZE     = 1 << 0,
+  META_WINDOW_ACTOR_CHANGE_POSITION = 1 << 1
+} MetaWindowActorChanges;
+
 void meta_window_actor_queue_destroy   (MetaWindowActor *self);
 
 void meta_window_actor_show (MetaWindowActor *self,
@@ -59,8 +65,10 @@ void     meta_window_actor_set_unredirected    (MetaWindowActor *self,
                                                 gboolean         unredirected);
 
 gboolean meta_window_actor_effect_in_progress  (MetaWindowActor *self);
-void     meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
-                                                gboolean         did_placement);
+
+MetaWindowActorChanges meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
+                                                              gboolean         did_placement);
+
 void     meta_window_actor_update_shape        (MetaWindowActor *self);
 void     meta_window_actor_update_opacity      (MetaWindowActor *self);
 void     meta_window_actor_mapped              (MetaWindowActor *self);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 1e049ceb1..f558bfd1b 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1120,13 +1120,15 @@ meta_window_actor_queue_destroy (MetaWindowActor *self)
     clutter_actor_destroy (CLUTTER_ACTOR (self));
 }
 
-void
+MetaWindowActorChanges
 meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
                                        gboolean         did_placement)
 {
   MetaWindowActorPrivate *priv =
     meta_window_actor_get_instance_private (self);
   MetaRectangle window_rect;
+  ClutterActor *actor = CLUTTER_ACTOR (self);
+  MetaWindowActorChanges changes = 0;
 
   meta_window_get_buffer_rect (priv->window, &window_rect);
 
@@ -1144,15 +1146,42 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
    * updates.
    */
   if (is_frozen (self) && !did_placement)
-    return;
+    return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
 
   if (meta_window_actor_effect_in_progress (self))
-    return;
+    return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
+
+  if (clutter_actor_has_allocation (actor))
+    {
+      ClutterActorBox box;
+      float old_x, old_y;
+      float old_width, old_height;
+
+      clutter_actor_get_allocation_box (actor, &box);
+
+      old_x = box.x1;
+      old_y = box.y1;
+      old_width = box.x2 - box.x1;
+      old_height = box.y2 - box.y1;
+
+      if (old_x != window_rect.x || old_y != window_rect.y)
+        changes |= META_WINDOW_ACTOR_CHANGE_POSITION;
+
+      if (old_width != window_rect.width || old_height != window_rect.height)
+        changes |= META_WINDOW_ACTOR_CHANGE_SIZE;
+    }
+  else
+    {
+      changes = META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
+    }
+
+  if (changes & META_WINDOW_ACTOR_CHANGE_POSITION)
+    clutter_actor_set_position (actor, window_rect.x, window_rect.y);
+
+  if (changes & META_WINDOW_ACTOR_CHANGE_SIZE)
+    clutter_actor_set_size (actor, window_rect.width, window_rect.height);
 
-  clutter_actor_set_position (CLUTTER_ACTOR (self),
-                              window_rect.x, window_rect.y);
-  clutter_actor_set_size (CLUTTER_ACTOR (self),
-                          window_rect.width, window_rect.height);
+  return changes;
 }
 
 void


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