ShadowEffect: Delay cache drop for switching shadow sizes performance improvements (#2061)

Co-authored-by: lenemter <lenemter@gmail.com>
This commit is contained in:
Leonhard 2024-11-23 17:04:32 +01:00 committed by GitHub
parent b9dd5cc60b
commit 74abd1ecd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 20 deletions

View File

@ -27,6 +27,18 @@
<update_contact>contact_at_elementary.io</update_contact>
<releases>
<release version="8.0.4" date="2024-11-23" urgency="medium">
<description>
<p>Improvements:</p>
<ul>
<li>Updated translations</li>
<li>Improved shadows performance</li>
</ul>
</description>
<issues>
</issues>
</release>
<release version="8.0.3" date="2024-11-20" urgency="medium">
<description>
<p>Improvements:</p>

View File

@ -18,11 +18,14 @@ 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<string, Shadow> shadow_cache;
// Delay the style context creation at render stage as Gtk need to access
// the current display.
// 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<string, uint> shadows_marked_for_dropping;
static construct {
shadow_cache = new Gee.HashMap<string, Shadow> ();
shadows_marked_for_dropping = new Gee.HashMap<string, uint> ();
}
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;
});
}
}