Commit aaedc7b6 authored by Benjamin Otte's avatar Benjamin Otte

stylecontext: Compute if things changed before invalidating

This is only a small performance boost by itself, but it's necessary
for animations, so we need it.

Benchmark numbers for my Glade benchmark for interested people:
        GTK 3.4.0    last commit  this commit
Raleigh
  real  0m41.879s    0m10.176s    0m9.900s
  user  0m41.394s    0m9.895s     0m9.628s
  sys   0m0.111s     0m0.096s     0m0.102s

Adwaita                                        (*)
  real  0m51.049s    0m13.432s    0m14.848s    0m12.253s
  user  0m50.487s    0m13.034s    0m13.218s    0m11.927s
  sys   0m0.117s     0m0.151s     0m0.147s     0m0.107s

Ambiance (patched to not use private GTK APIs)
  real  0m52.167s    0m13.115s    0m13.117s    0m12.944s
  user  0m51.576s    0m12.739s    0m12.768s    0m12.651s
  sys   0m0.119s     0m0.137s     0m0.136s     0m0.118s

(*) Adwaita and unico currently use custom properties, and
_gtk_css_value_compare() for custom properties always returns FALSE,
which makes this optimization never trigger. So I modified
_gtk_css_value_compare() to return TRUE for these properties instead and
reran the benchmark. Those are the numbers.
parent 95a4b46f
......@@ -227,3 +227,25 @@ _gtk_css_computed_values_get_section (GtkCssComputedValues *values,
return g_ptr_array_index (values->sections, id);
}
GtkBitmask *
_gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
GtkCssComputedValues *other)
{
GtkBitmask *result;
guint i, len;
len = MIN (values->values->len, other->values->len);
result = _gtk_bitmask_new ();
if (values->values->len != other->values->len)
result = _gtk_bitmask_invert_range (result, len, MAX (values->values->len, other->values->len));
for (i = 0; i < len; i++)
{
if (!_gtk_css_value_equal (g_ptr_array_index (values->values, i),
g_ptr_array_index (other->values, i)))
result = _gtk_bitmask_set (result, i, TRUE);
}
return result;
}
......@@ -22,6 +22,7 @@
#include <glib-object.h>
#include "gtk/gtkbitmaskprivate.h"
#include "gtk/gtkcsssection.h"
#include "gtk/gtkstylecontext.h"
#include "gtk/gtkcssvalueprivate.h"
......@@ -69,6 +70,8 @@ GtkCssValue * _gtk_css_computed_values_get_value (GtkCssCom
guint id);
GtkCssSection * _gtk_css_computed_values_get_section (GtkCssComputedValues *values,
guint id);
GtkBitmask * _gtk_css_computed_values_get_difference (GtkCssComputedValues *values,
GtkCssComputedValues *other);
G_END_DECLS
......
......@@ -2830,12 +2830,31 @@ _gtk_style_context_validate (GtkStyleContext *context,
if (priv->relevant_changes & change)
{
GtkStyleInfo *info = priv->info_stack->data;
GtkCssComputedValues *old, *new;
old = info->data ? g_object_ref (info->data->store) : NULL;
if ((priv->relevant_changes & change) & ~GTK_STYLE_CONTEXT_CACHED_CHANGE)
gtk_style_context_clear_cache (context);
else
info->data = NULL;
if (old)
{
GtkBitmask *bitmask;
new = style_data_lookup (context)->store;
bitmask = _gtk_css_computed_values_get_difference (new, old);
if (!_gtk_bitmask_is_empty (bitmask))
gtk_style_context_do_invalidate (context);
_gtk_bitmask_free (bitmask);
g_object_unref (old);
}
else
gtk_style_context_do_invalidate (context);
info->data = NULL;
gtk_style_context_do_invalidate (context);
}
change = _gtk_css_change_for_child (change);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment