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.
This commit is contained in:
Matthias Clasen 2024-05-20 08:48:20 -04:00
parent e353117937
commit ecc2c953e5
3 changed files with 74 additions and 21 deletions

View File

@ -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++)
{

View File

@ -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);

View File

@ -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);
}