From ecc2c953e5de16cde3962af518323893f5f1750c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 20 May 2024 08:48:20 -0400 Subject: [PATCH] css: Avoid more recomputation Pass a reason into gtk_css_animated_style_recompute, and avoid recomputing properties that aren't affected. The possible reasons for now are that variables of color changes. Better tracking for currentColor in properties will allow us to improve this later. --- gtk/gtkcssanimatedstyle.c | 71 +++++++++++++++++++++++++------- gtk/gtkcssanimatedstyleprivate.h | 9 +++- gtk/gtkcssanimation.c | 15 ++++--- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c index 1f7af1d6d6..1bfc52b4a6 100644 --- a/gtk/gtkcssanimatedstyle.c +++ b/gtk/gtkcssanimatedstyle.c @@ -42,10 +42,37 @@ G_DEFINE_TYPE (GtkCssAnimatedStyle, gtk_css_animated_style, GTK_TYPE_CSS_STYLE) +static inline gboolean +property_has_color (guint id) +{ + switch (id) + { + case GTK_CSS_PROPERTY_COLOR: + case GTK_CSS_PROPERTY_ICON_PALETTE: + case GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR: + case GTK_CSS_PROPERTY_TEXT_SHADOW: + case GTK_CSS_PROPERTY_BOX_SHADOW: + case GTK_CSS_PROPERTY_BORDER_TOP_COLOR: + case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR: + case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR: + case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR: + case GTK_CSS_PROPERTY_OUTLINE_COLOR: + case GTK_CSS_PROPERTY_BACKGROUND_IMAGE: + case GTK_CSS_PROPERTY_ICON_SOURCE: + case GTK_CSS_PROPERTY_ICON_SHADOW: + case GTK_CSS_PROPERTY_CARET_COLOR: + case GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR: + return TRUE; + default: + return FALSE; + } +} + #define DEFINE_VALUES(ENUM, TYPE, NAME) \ static inline void \ -gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ - GtkCssComputeContext *context) \ +gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ + GtkCssComputeContext *context, \ + GtkCssAnimationChange change) \ { \ GtkCssStyle *style = (GtkCssStyle *)animated; \ GtkCssValue **values = (GtkCssValue **)((guint8*)(animated->style->NAME) + sizeof (GtkCssValues)); \ @@ -55,6 +82,7 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ { \ guint id = NAME ## _props[i]; \ GtkCssValue *original, *computed; \ + gboolean needs_recompute = FALSE; \ \ if (values[i] == NULL) \ continue; \ @@ -62,6 +90,17 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ original = gtk_css_style_get_original_value (style, id); \ if (original == NULL) \ continue; \ +\ + if ((change & GTK_CSS_ANIMATION_CHANGE_VARIABLES) && \ + gtk_css_value_contains_variables (original)) \ + needs_recompute = TRUE; \ +\ + if ((change & GTK_CSS_ANIMATION_CHANGE_COLOR) && \ + property_has_color (id)) \ + needs_recompute = TRUE; \ +\ + if (!needs_recompute) \ + continue; \ \ computed = gtk_css_value_compute (original, \ id, \ @@ -70,6 +109,9 @@ gtk_css_ ## NAME ## _values_recompute (GtkCssAnimatedStyle *animated, \ continue; \ \ gtk_css_animated_style_set_animated_value (animated, id, computed); \ +\ + if (id == GTK_CSS_PROPERTY_COLOR) \ + change |= GTK_CSS_ANIMATION_CHANGE_COLOR; \ } \ } @@ -630,7 +672,8 @@ gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated, } void -gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style) +gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style, + GtkCssAnimationChange change) { GtkCssComputeContext context = { NULL, }; GtkCssValue *shorthands[GTK_CSS_SHORTHAND_PROPERTY_N_PROPERTIES] = { NULL, }; @@ -640,17 +683,17 @@ gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style) context.parent_style = style->parent_style; context.shorthands = shorthands; - gtk_css_core_values_recompute (style, &context); - gtk_css_background_values_recompute (style, &context); - gtk_css_border_values_recompute (style, &context); - gtk_css_icon_values_recompute (style, &context); - gtk_css_outline_values_recompute (style, &context); - gtk_css_font_values_recompute (style, &context); - gtk_css_font_variant_values_recompute (style, &context); - gtk_css_animation_values_recompute (style, &context); - gtk_css_transition_values_recompute (style, &context); - gtk_css_size_values_recompute (style, &context); - gtk_css_other_values_recompute (style, &context); + gtk_css_core_values_recompute (style, &context, change); + gtk_css_background_values_recompute (style, &context, change); + gtk_css_border_values_recompute (style, &context, change); + gtk_css_icon_values_recompute (style, &context, change); + gtk_css_outline_values_recompute (style, &context, change); + gtk_css_font_values_recompute (style, &context, change); + gtk_css_font_variant_values_recompute (style, &context, change); + gtk_css_animation_values_recompute (style, &context, change); + gtk_css_transition_values_recompute (style, &context, change); + gtk_css_size_values_recompute (style, &context, change); + gtk_css_other_values_recompute (style, &context, change); for (unsigned int i = 0; i < GTK_CSS_SHORTHAND_PROPERTY_N_PROPERTIES; i++) { diff --git a/gtk/gtkcssanimatedstyleprivate.h b/gtk/gtkcssanimatedstyleprivate.h index 58a7a2e236..ada5ad75f8 100644 --- a/gtk/gtkcssanimatedstyleprivate.h +++ b/gtk/gtkcssanimatedstyleprivate.h @@ -73,7 +73,14 @@ GtkCssValue * gtk_css_animated_style_get_intrinsic_value (GtkCssAnimat void gtk_css_animated_style_set_animated_custom_value (GtkCssAnimatedStyle *animated, int id, GtkCssVariableValue *value); -void gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style); + +typedef enum { + GTK_CSS_ANIMATION_CHANGE_VARIABLES = 1 << 0, + GTK_CSS_ANIMATION_CHANGE_COLOR = 1 << 1, +} GtkCssAnimationChange; + +void gtk_css_animated_style_recompute (GtkCssAnimatedStyle *style, + GtkCssAnimationChange change); GtkCssVariableValue * gtk_css_animated_style_get_intrinsic_custom_value (GtkCssAnimatedStyle *style, int id); diff --git a/gtk/gtkcssanimation.c b/gtk/gtkcssanimation.c index bd5f6b9cd5..d920d4d71a 100644 --- a/gtk/gtkcssanimation.c +++ b/gtk/gtkcssanimation.c @@ -95,7 +95,7 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, GtkCssKeyframes *resolved_keyframes; double progress; guint i; - gboolean needs_recompute = FALSE; + GtkCssAnimationChange change = 0; if (!gtk_css_animation_is_executing (animation)) return; @@ -130,17 +130,14 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, gtk_css_variable_value_unref (value); - needs_recompute = TRUE; + change |= GTK_CSS_ANIMATION_CHANGE_VARIABLES; } - if (needs_recompute) - gtk_css_animated_style_recompute (style); - for (i = 0; i < _gtk_css_keyframes_get_n_properties (resolved_keyframes); i++) { GtkCssValue *value; guint property_id; - + property_id = _gtk_css_keyframes_get_property_id (resolved_keyframes, i); value = _gtk_css_keyframes_get_value (resolved_keyframes, @@ -148,8 +145,14 @@ gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, progress, gtk_css_animated_style_get_intrinsic_value (style, property_id)); gtk_css_animated_style_set_animated_value (style, property_id, value); + + if (property_id == GTK_CSS_PROPERTY_COLOR) + change |= GTK_CSS_ANIMATION_CHANGE_COLOR; } + if (change != 0) + gtk_css_animated_style_recompute (style, change); + _gtk_css_keyframes_unref (resolved_keyframes); }