Compute style change based on values structs
authorMatthias Clasen <mclasen@redhat.com>
Tue, 28 Jan 2020 17:13:37 +0000 (18:13 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Wed, 29 Jan 2020 10:07:32 +0000 (11:07 +0100)
We can save some time here by comparing struct by
struct and avoiding individual values comparisons
as much as possible.

gtk/gtkcssstaticstyle.c
gtk/gtkcssstylechange.c
gtk/gtkcssstylechangeprivate.h
gtk/gtkcssstyleprivate.h

index da349e05341ff9958ecfe670bc5f95362c0d15cd..02cef3275850ab94f7518c73f224a0368eaa9bce 100644 (file)
@@ -173,6 +173,28 @@ static int other_props[] = {
 };
 
 #define DEFINE_VALUES(ENUM, TYPE, NAME) \
+void \
+gtk_css_## NAME ## _values_compute_changes_and_affects (GtkCssStyle *style1, \
+                                                        GtkCssStyle *style2, \
+                                                        GtkBitmask    **changes, \
+                                                        GtkCssAffects *affects) \
+{ \
+  GtkCssValues *g1 = (GtkCssValues *)style1->NAME; \
+  GtkCssValues *g2 = (GtkCssValues *)style2->NAME; \
+  int i; \
+  for (i = 0; i < G_N_ELEMENTS (NAME ## _props); i++) \
+    { \
+      GtkCssValue *v1 = g1->values[i] ? g1->values[i] : style1->core->color; \
+      GtkCssValue *v2 = g2->values[i] ? g2->values[i] : style2->core->color; \
+      if (!_gtk_css_value_equal (v1, v2)) \
+        { \
+          guint id = NAME ## _props[i]; \
+          *changes = _gtk_bitmask_set (*changes, id, TRUE); \
+          *affects |= _gtk_css_style_property_get_affects (_gtk_css_style_property_lookup_by_id (id)); \
+        } \
+    } \
+} \
+\
 static inline void \
 gtk_css_ ## NAME ## _values_new_compute (GtkCssStaticStyle *sstyle, \
                                          GtkStyleProvider *provider, \
@@ -195,7 +217,6 @@ gtk_css_ ## NAME ## _values_new_compute (GtkCssStaticStyle *sstyle, \
                                           lookup->values[id].section); \
     } \
 } \
-\
 static GtkBitmask * gtk_css_ ## NAME ## _values_mask; \
 static GtkCssValues * gtk_css_ ## NAME ## _initial_values; \
 \
index e538a82d3f95983285fbd8ac1db5c28c3315d62d..5a7263128df24ab03ad061b55f6ae76bbf9839bf 100644 (file)
 
 #include "gtkcssstylepropertyprivate.h"
 
+static void
+compute_change (GtkCssStyleChange *change)
+{
+  if (change->old_style->core != change->new_style->core)
+    gtk_css_core_values_compute_changes_and_affects (change->old_style,
+                                                     change->new_style,
+                                                     &change->changes,
+                                                     &change->affects);
+  if (change->old_style->background != change->new_style->background)
+    gtk_css_background_values_compute_changes_and_affects (change->old_style,
+                                                           change->new_style,
+                                                           &change->changes,
+                                                           &change->affects);
+  if (change->old_style->border != change->new_style->border)
+    gtk_css_border_values_compute_changes_and_affects (change->old_style,
+                                                       change->new_style,
+                                                       &change->changes,
+                                                       &change->affects);
+  if (change->old_style->icon != change->new_style->icon)
+    gtk_css_icon_values_compute_changes_and_affects (change->old_style,
+                                                     change->new_style,
+                                                     &change->changes,
+                                                     &change->affects);
+  if (change->old_style->outline != change->new_style->outline)
+    gtk_css_outline_values_compute_changes_and_affects (change->old_style,
+                                                        change->new_style,
+                                                        &change->changes,
+                                                        &change->affects);
+  if (change->old_style->font != change->new_style->font)
+    gtk_css_font_values_compute_changes_and_affects (change->old_style,
+                                                     change->new_style,
+                                                     &change->changes,
+                                                     &change->affects);
+  if (change->old_style->font_variant != change->new_style->font_variant)
+    gtk_css_font_variant_values_compute_changes_and_affects (change->old_style,
+                                                             change->new_style,
+                                                             &change->changes,
+                                                             &change->affects);
+  if (change->old_style->animation != change->new_style->animation)
+    gtk_css_animation_values_compute_changes_and_affects (change->old_style,
+                                                          change->new_style,
+                                                          &change->changes,
+                                                          &change->affects);
+  if (change->old_style->transition != change->new_style->transition)
+    gtk_css_transition_values_compute_changes_and_affects (change->old_style,
+                                                           change->new_style,
+                                                           &change->changes,
+                                                           &change->affects);
+  if (change->old_style->size != change->new_style->size)
+    gtk_css_size_values_compute_changes_and_affects (change->old_style,
+                                                     change->new_style,
+                                                     &change->changes,
+                                                     &change->affects);
+  if (change->old_style->other != change->new_style->other)
+    gtk_css_other_values_compute_changes_and_affects (change->old_style,
+                                                      change->new_style,
+                                                      &change->changes,
+                                                      &change->affects);
+}
+
 void
 gtk_css_style_change_init (GtkCssStyleChange *change,
                            GtkCssStyle       *old_style,
@@ -29,14 +89,11 @@ gtk_css_style_change_init (GtkCssStyleChange *change,
   change->old_style = g_object_ref (old_style);
   change->new_style = g_object_ref (new_style);
 
-  change->n_compared = 0;
-
   change->affects = 0;
   change->changes = _gtk_bitmask_new ();
   
-  /* Make sure we don't do extra work if old and new are equal. */
-  if (old_style == new_style)
-    change->n_compared = GTK_CSS_PROPERTY_N_PROPERTIES;
+  if (old_style != new_style)
+    compute_change (change);
 }
 
 void
@@ -59,54 +116,23 @@ gtk_css_style_change_get_new_style (GtkCssStyleChange *change)
   return change->new_style;
 }
 
-static gboolean
-gtk_css_style_compare_next_value (GtkCssStyleChange *change)
-{
-  if (change->n_compared == GTK_CSS_PROPERTY_N_PROPERTIES)
-    return FALSE;
-
-  if (!_gtk_css_value_equal (gtk_css_style_get_value (change->old_style, change->n_compared),
-                             gtk_css_style_get_value (change->new_style, change->n_compared)))
-    {
-      change->affects |= _gtk_css_style_property_get_affects (_gtk_css_style_property_lookup_by_id (change->n_compared));
-      change->changes = _gtk_bitmask_set (change->changes, change->n_compared, TRUE);
-    }
-
-  change->n_compared++;
-
-  return TRUE;
-}
-
 gboolean
 gtk_css_style_change_has_change (GtkCssStyleChange *change)
 {
-  do {
-    if (!_gtk_bitmask_is_empty (change->changes))
-      return TRUE;
-  } while (gtk_css_style_compare_next_value (change));
-
-  return FALSE;
+  return !_gtk_bitmask_is_empty (change->changes);
 }
 
 gboolean
 gtk_css_style_change_affects (GtkCssStyleChange *change,
                               GtkCssAffects      affects)
 {
-  do {
-    if (change->affects & affects)
-      return TRUE;
-  } while (gtk_css_style_compare_next_value (change));
-
-  return FALSE;
+  return (change->affects & affects) != 0;
 }
 
 gboolean
 gtk_css_style_change_changes_property (GtkCssStyleChange *change,
                                        guint              id)
 {
-  while (change->n_compared <= id)
-    gtk_css_style_compare_next_value (change);
-
   return _gtk_bitmask_get (change->changes, id);
 }
 
@@ -126,10 +152,6 @@ gtk_css_style_change_print (GtkCssStyleChange *change,
           GtkCssValue *value;
           const char *name;
 
-          if (_gtk_css_value_equal (gtk_css_style_get_value (change->old_style, i),
-                                     gtk_css_style_get_value (change->new_style, i)))
-            continue;
-
           prop = _gtk_css_style_property_lookup_by_id (i);
           name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop));
 
index 85b9a323ab55f29604fd75f5bf46700dd5e5f3ca..d71a9c87ef19e52ca9f5934b7addc03c070704e6 100644 (file)
@@ -28,8 +28,6 @@ struct _GtkCssStyleChange {
   GtkCssStyle   *old_style;
   GtkCssStyle   *new_style;
 
-  guint          n_compared;
-
   GtkCssAffects  affects;
   GtkBitmask    *changes;
 };
index d70b63893918f132b6a6c54174f68143e83d9293..929d200f4b8d67ee517f0db0e620ad5a8e4df1ea 100644 (file)
@@ -265,6 +265,50 @@ GtkCssValues *gtk_css_values_ref   (GtkCssValues     *values);
 void          gtk_css_values_unref (GtkCssValues     *values);
 GtkCssValues *gtk_css_values_copy  (GtkCssValues     *values);
 
+void gtk_css_core_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_background_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_border_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_icon_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_outline_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_font_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_font_variant_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_animation_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_transition_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_size_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
+void gtk_css_other_values_compute_changes_and_affects (GtkCssStyle *style1,
+                                                      GtkCssStyle *style2,
+                                                      GtkBitmask    **changes,
+                                                      GtkCssAffects *affects);
 
 G_END_DECLS