From 01e20a6ba9e0cfa22e864c01b3395ba9568b061a Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 7 May 2019 18:08:13 +0800 Subject: [PATCH] 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; - 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); + 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); + + return changes; } void