From 74abd1ecd7cb5ce88116d810e74a5e0022ed8d68 Mon Sep 17 00:00:00 2001 From: Leonhard <106322251+leolost2605@users.noreply.github.com> Date: Sat, 23 Nov 2024 17:04:32 +0100 Subject: [PATCH] ShadowEffect: Delay cache drop for switching shadow sizes performance improvements (#2061) Co-authored-by: lenemter --- data/gala.metainfo.xml.in | 12 +++++++ lib/ShadowEffect.vala | 66 +++++++++++++++++++++++++++------------ 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/data/gala.metainfo.xml.in b/data/gala.metainfo.xml.in index 522214f8..1927ab86 100644 --- a/data/gala.metainfo.xml.in +++ b/data/gala.metainfo.xml.in @@ -27,6 +27,18 @@ contact_at_elementary.io + + +

Improvements:

+
    +
  • Updated translations
  • +
  • Improved shadows performance
  • +
+
+ + +
+

Improvements:

diff --git a/lib/ShadowEffect.vala b/lib/ShadowEffect.vala index 909edb29..79fd89dd 100644 --- a/lib/ShadowEffect.vala +++ b/lib/ShadowEffect.vala @@ -17,12 +17,15 @@ public class Gala.ShadowEffect : Clutter.Effect { // the sizes of the textures often repeat, especially for the background actor // so we keep a cache to avoid creating the same texture all over again. - private static Gee.HashMap shadow_cache; - // Delay the style context creation at render stage as Gtk need to access - // the current display. + private static Gee.HashMap shadow_cache; + + // Sometimes we use a shadow in only one place and rapidly switch between two shadows + // In order to not drop them and create them all over again we wait 5 seconds before finally dropping a shadow. + private static Gee.HashMap shadows_marked_for_dropping; static construct { - shadow_cache = new Gee.HashMap (); + shadow_cache = new Gee.HashMap (); + shadows_marked_for_dropping = new Gee.HashMap (); } private string _css_class; @@ -80,9 +83,9 @@ public class Gala.ShadowEffect : Clutter.Effect { decrement_shadow_users (old_key); } - Shadow? shadow = null; - if ((shadow = shadow_cache.@get (current_key)) != null) { - shadow.users++; + var shadow = shadow_cache.@get (current_key); + if (shadow != null) { + increment_shadow_users (current_key); return shadow.texture; } @@ -126,18 +129,6 @@ public class Gala.ShadowEffect : Clutter.Effect { } } - private void decrement_shadow_users (string key) { - var shadow = shadow_cache.@get (key); - - if (shadow == null) { - return; - } - - if (--shadow.users == 0) { - shadow_cache.unset (key); - } - } - public override void paint (Clutter.PaintNode node, Clutter.PaintContext context, Clutter.EffectPaintFlags flags) { var bounding_box = get_bounding_box (); var width = (int) (bounding_box.x2 - bounding_box.x1); @@ -159,7 +150,7 @@ public class Gala.ShadowEffect : Clutter.Effect { actor.continue_paint (context); } - public virtual Clutter.ActorBox get_bounding_box () { + private Clutter.ActorBox get_bounding_box () { var size = shadow_size * scale_factor; var bounding_box = Clutter.ActorBox (); @@ -184,4 +175,39 @@ public class Gala.ShadowEffect : Clutter.Effect { return true; } + + private static void increment_shadow_users (string key) { + var shadow = shadow_cache.@get (key); + + if (shadow == null) { + return; + } + + shadow.users++; + + uint timeout_id; + if (shadows_marked_for_dropping.unset (key, out timeout_id)) { + Source.remove (timeout_id); + } + } + + private static void decrement_shadow_users (string key) { + var shadow = shadow_cache.@get (key); + + if (shadow == null) { + return; + } + + if (--shadow.users == 0) { + queue_shadow_drop (key); + } + } + + private static void queue_shadow_drop (string key) { + shadows_marked_for_dropping[key] = Timeout.add_seconds (5, () => { + shadow_cache.unset (key); + shadows_marked_for_dropping.unset (key); + return Source.REMOVE; + }); + } }