[gtk+/rgba-texttags] Optimize queue_resize_on_widget()



commit 11a4097b292a5f0cbd56864bd64e5490e1bab8dc
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Mon Feb 7 16:55:25 2011 +0900

    Optimize queue_resize_on_widget()
    
    Optimized GtkSizeGroup code that is invoked for every queued resize
    and every request that is not previously cached by trading qdata on
    widgets for 3 extra bitfields on the GtkWidgetPrivate structure.

 gtk/gtksizegroup.c     |  113 +++++++++++------------------------------------
 gtk/gtkwidget.c        |   70 +++++++++++++++++++++++++++++
 gtk/gtkwidgetprivate.h |   12 +++++
 3 files changed, 109 insertions(+), 86 deletions(-)
---
diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c
index 54042a0..5a686a2 100644
--- a/gtk/gtksizegroup.c
+++ b/gtk/gtksizegroup.c
@@ -41,6 +41,7 @@ struct _GtkSizeGroupPrivate
   guint           have_width    : 1;
   guint           have_height   : 1;
   guint           ignore_hidden : 1;
+  guint           visited       : 1;
 };
 
 enum {
@@ -81,56 +82,16 @@ static void gtk_size_group_buildable_custom_finished (GtkBuildable  *buildable,
 						      const gchar   *tagname,
 						      gpointer       user_data);
 
-static GQuark size_groups_quark;
-static const gchar size_groups_tag[] = "gtk-size-groups";
-
-static GQuark visited_quark;
-static const gchar visited_tag[] = "gtk-size-group-visited";
-
-static GQuark bumping_quark;
-static const gchar bumping_tag[] = "gtk-size-group-bumping";
-
-static GSList *
-get_size_groups (GtkWidget *widget)
-{
-  return g_object_get_qdata (G_OBJECT (widget), size_groups_quark);
-}
-
 static void
-set_size_groups (GtkWidget *widget,
-		 GSList    *groups)
-{
-  g_object_set_qdata (G_OBJECT (widget), size_groups_quark, groups);
-}
-
-static void
-mark_visited (gpointer object)
-{
-  g_object_set_qdata (object, visited_quark, "visited");
-}
-
-static void
-mark_unvisited (gpointer object)
-{
-  g_object_set_qdata (object, visited_quark, NULL);
-}
-
-static gboolean
-is_visited (gpointer object)
+mark_group_unvisited (GtkSizeGroup *group)
 {
-  return g_object_get_qdata (object, visited_quark) != NULL;
+  group->priv->visited = FALSE;
 }
 
 static void
-mark_bumping (gpointer object, gboolean bumping)
-{
-  g_object_set_qdata (object, bumping_quark, bumping ? "bumping" : NULL);
-}
-
-static gboolean
-is_bumping (gpointer object)
+mark_widget_unvisited (GtkWidget *widget)
 {
-  return g_object_get_qdata (object, bumping_quark) != NULL;
+  _gtk_widget_set_sizegroup_visited (widget, FALSE);
 }
 
 static void
@@ -143,14 +104,14 @@ add_group_to_closure (GtkSizeGroup    *group,
   GSList *tmp_widgets;
   
   *groups = g_slist_prepend (*groups, group);
-  mark_visited (group);
+  priv->visited = TRUE;
 
   tmp_widgets = priv->widgets;
   while (tmp_widgets)
     {
       GtkWidget *tmp_widget = tmp_widgets->data;
       
-      if (!is_visited (tmp_widget))
+      if (!_gtk_widget_get_sizegroup_visited (tmp_widget))
 	add_widget_to_closure (tmp_widget, mode, groups, widgets);
       
       tmp_widgets = tmp_widgets->next;
@@ -166,16 +127,16 @@ add_widget_to_closure (GtkWidget       *widget,
   GSList *tmp_groups;
 
   *widgets = g_slist_prepend (*widgets, widget);
-  mark_visited (widget);
+  _gtk_widget_set_sizegroup_visited (widget, TRUE);
 
-  tmp_groups = get_size_groups (widget);
+  tmp_groups = _gtk_widget_get_sizegroups (widget);
   while (tmp_groups)
     {
-      GtkSizeGroup *tmp_group = tmp_groups->data;
-      GtkSizeGroupPrivate *tmp_priv = tmp_group->priv;
+      GtkSizeGroup        *tmp_group = tmp_groups->data;
+      GtkSizeGroupPrivate *tmp_priv  = tmp_group->priv;
 
       if ((tmp_priv->mode == GTK_SIZE_GROUP_BOTH || tmp_priv->mode == mode) &&
-	  !is_visited (tmp_group))
+	  !tmp_group->priv->visited)
 	add_group_to_closure (tmp_group, mode, groups, widgets);
 
       tmp_groups = tmp_groups->next;
@@ -243,7 +204,7 @@ queue_resize_on_widget (GtkWidget          *widget,
 	  continue;
 	}
       
-      widget_groups = get_size_groups (parent);
+      widget_groups = _gtk_widget_get_sizegroups (parent);
       if (!widget_groups)
 	{
 	  if (widget == parent)
@@ -257,8 +218,8 @@ queue_resize_on_widget (GtkWidget          *widget,
       widgets = NULL;
 	  
       add_widget_to_closure (parent, GTK_SIZE_GROUP_HORIZONTAL, &groups, &widgets);
-      g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
-      g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
+      g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
+      g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
 
       reset_group_sizes (groups);
 	      
@@ -287,8 +248,8 @@ queue_resize_on_widget (GtkWidget          *widget,
       widgets = NULL;
 	      
       add_widget_to_closure (parent, GTK_SIZE_GROUP_VERTICAL, &groups, &widgets);
-      g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
-      g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
+      g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
+      g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
 
       reset_group_sizes (groups);
 	      
@@ -327,17 +288,6 @@ queue_resize_on_group (GtkSizeGroup       *size_group)
 }
 
 static void
-initialize_size_group_quarks (void)
-{
-  if (!size_groups_quark)
-    {
-      size_groups_quark = g_quark_from_static_string (size_groups_tag);
-      visited_quark = g_quark_from_static_string (visited_tag);
-      bumping_quark = g_quark_from_static_string (bumping_tag);
-    }
-}
-
-static void
 gtk_size_group_class_init (GtkSizeGroupClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -372,8 +322,6 @@ gtk_size_group_class_init (GtkSizeGroupClass *klass)
 							 GTK_PARAM_READWRITE));
 
   g_type_class_add_private (klass, sizeof (GtkSizeGroupPrivate));
-
-  initialize_size_group_quarks ();
 }
 
 static void
@@ -391,6 +339,7 @@ gtk_size_group_init (GtkSizeGroup *size_group)
   priv->have_width = 0;
   priv->have_height = 0;
   priv->ignore_hidden = 0;
+  priv->visited  = FALSE;
 }
 
 static void
@@ -600,12 +549,11 @@ gtk_size_group_add_widget (GtkSizeGroup     *size_group,
 
   priv = size_group->priv;
 
-  groups = get_size_groups (widget);
+  groups = _gtk_widget_get_sizegroups (widget);
 
   if (!g_slist_find (groups, size_group))
     {
-      groups = g_slist_prepend (groups, size_group);
-      set_size_groups (widget, groups);
+      _gtk_widget_add_sizegroup (widget, size_group);
 
       priv->widgets = g_slist_prepend (priv->widgets, widget);
 
@@ -631,7 +579,6 @@ gtk_size_group_remove_widget (GtkSizeGroup *size_group,
 			      GtkWidget    *widget)
 {
   GtkSizeGroupPrivate *priv;
-  GSList *groups;
   
   g_return_if_fail (GTK_IS_SIZE_GROUP (size_group));
   g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -644,9 +591,7 @@ gtk_size_group_remove_widget (GtkSizeGroup *size_group,
 					gtk_size_group_widget_destroyed,
 					size_group);
   
-  groups = get_size_groups (widget);
-  groups = g_slist_remove (groups, size_group);
-  set_size_groups (widget, groups);
+  _gtk_widget_remove_sizegroup (widget, size_group);
 
   priv->widgets = g_slist_remove (priv->widgets, widget);
   queue_resize_on_group (size_group);
@@ -684,10 +629,9 @@ compute_dimension (GtkWidget        *widget,
   gint    min_result = 0, nat_result = 0;
 
   add_widget_to_closure (widget, mode, &groups, &widgets);
+  g_slist_foreach (widgets, (GFunc)mark_widget_unvisited, NULL);
+  g_slist_foreach (groups, (GFunc)mark_group_unvisited, NULL);
 
-  g_slist_foreach (widgets, (GFunc)mark_unvisited, NULL);
-  g_slist_foreach (groups, (GFunc)mark_unvisited, NULL);
-  
   g_slist_foreach (widgets, (GFunc)g_object_ref, NULL);
   
   if (!groups)
@@ -755,7 +699,6 @@ compute_dimension (GtkWidget        *widget,
 	      else
 		{
 		  tmp_priv->have_height = TRUE;
-
 		  tmp_priv->minimum_req.height = min_result;
 		  tmp_priv->natural_req.height = nat_result;
 		}
@@ -795,15 +738,15 @@ _gtk_size_group_bump_requisition (GtkWidget        *widget,
 				  gint             *minimum,
 				  gint             *natural)
 {
-  if (!is_bumping (widget))
+  if (!_gtk_widget_get_sizegroup_bumping (widget))
     {
       /* Avoid recursion here */
-      mark_bumping (widget, TRUE);
+      _gtk_widget_set_sizegroup_bumping (widget, TRUE);
 
-      if (get_size_groups (widget))
+      if (_gtk_widget_get_sizegroups (widget))
 	compute_dimension (widget, mode, minimum, natural);
 
-      mark_bumping (widget, FALSE);
+      _gtk_widget_set_sizegroup_bumping (widget, FALSE);
     }
 }
 
@@ -819,8 +762,6 @@ void
 _gtk_size_group_queue_resize (GtkWidget           *widget,
 			      GtkQueueResizeFlags  flags)
 {
-  initialize_size_group_quarks ();
-
   queue_resize_on_widget (widget, TRUE, flags);
 }
 
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index bea97d8..410f493 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -324,6 +324,8 @@ struct _GtkWidgetPrivate
   guint multidevice           : 1;
   guint has_shape_mask        : 1;
   guint in_reparent           : 1;
+
+  /* Queue-resize related flags */
   guint resize_pending        : 1;
   guint alloc_needed          : 1;
   guint width_request_needed  : 1;
@@ -338,6 +340,11 @@ struct _GtkWidgetPrivate
   guint hexpand_set           : 1; /* whether to use application-forced  */
   guint vexpand_set           : 1; /* instead of computing from children */
 
+  /* SizeGroup related flags */
+  guint sizegroup_visited     : 1;
+  guint sizegroup_bumping     : 1;
+  guint have_size_groups      : 1;
+
   /* The widget's name. If the widget does not have a name
    *  (the name is NULL), then its name (as returned by
    *  "gtk_widget_get_name") is its class's name.
@@ -697,6 +704,7 @@ static GQuark		quark_tooltip_window = 0;
 static GQuark		quark_visual = 0;
 static GQuark           quark_modifier_style = 0;
 static GQuark           quark_enabled_devices = 0;
+static GQuark           quark_size_groups = 0;
 GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
 GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
 
@@ -811,6 +819,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   quark_visual = g_quark_from_static_string ("gtk-widget-visual");
   quark_modifier_style = g_quark_from_static_string ("gtk-widget-modifier-style");
   quark_enabled_devices = g_quark_from_static_string ("gtk-widget-enabled-devices");
+  quark_size_groups = g_quark_from_static_string ("gtk-widget-size-groups");
 
   style_property_spec_pool = g_param_spec_pool_new (FALSE);
   _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
@@ -14064,6 +14073,67 @@ _gtk_widget_set_height_request_needed (GtkWidget *widget,
   widget->priv->height_request_needed = height_request_needed;
 }
 
+gboolean
+_gtk_widget_get_sizegroup_visited (GtkWidget    *widget)
+{
+  return widget->priv->sizegroup_visited;
+}
+
+void
+_gtk_widget_set_sizegroup_visited (GtkWidget    *widget,
+				   gboolean      visited)
+{
+  widget->priv->sizegroup_visited = visited;
+}
+
+gboolean
+_gtk_widget_get_sizegroup_bumping (GtkWidget    *widget)
+{
+  return widget->priv->sizegroup_bumping;
+}
+
+void
+_gtk_widget_set_sizegroup_bumping (GtkWidget    *widget,
+				   gboolean      bumping)
+{
+  widget->priv->sizegroup_bumping = bumping;
+}
+
+void
+_gtk_widget_add_sizegroup (GtkWidget    *widget,
+			   gpointer      group)
+{
+  GSList *groups;
+
+  groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
+  groups = g_slist_prepend (groups, group);
+  g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
+
+  widget->priv->have_size_groups = TRUE;
+}
+
+void
+_gtk_widget_remove_sizegroup (GtkWidget    *widget,
+			      gpointer      group)
+{
+  GSList *groups;
+
+  groups = g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
+  groups = g_slist_remove (groups, group);
+  g_object_set_qdata (G_OBJECT (widget), quark_size_groups, groups);
+
+  widget->priv->have_size_groups = groups != NULL;
+}
+
+GSList *
+_gtk_widget_get_sizegroups (GtkWidget    *widget)
+{
+  if (widget->priv->have_size_groups)
+    return g_object_get_qdata (G_OBJECT (widget), quark_size_groups);
+
+  return NULL;
+}
+
 /**
  * gtk_widget_get_path:
  * @widget: a #GtkWidget
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 778fff2..1e91290 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -79,6 +79,18 @@ gboolean     _gtk_widget_get_height_request_needed (GtkWidget *widget);
 void         _gtk_widget_set_height_request_needed (GtkWidget *widget,
                                                     gboolean   height_request_needed);
 
+gboolean     _gtk_widget_get_sizegroup_visited (GtkWidget    *widget);
+void         _gtk_widget_set_sizegroup_visited (GtkWidget    *widget,
+						gboolean      visited);
+gboolean     _gtk_widget_get_sizegroup_bumping (GtkWidget    *widget);
+void         _gtk_widget_set_sizegroup_bumping (GtkWidget    *widget,
+						gboolean      bumping);
+void         _gtk_widget_add_sizegroup         (GtkWidget    *widget,
+						gpointer      group);
+void         _gtk_widget_remove_sizegroup      (GtkWidget    *widget,
+						gpointer      group);
+GSList      *_gtk_widget_get_sizegroups        (GtkWidget    *widget);
+
 void _gtk_widget_override_size_request (GtkWidget *widget,
                                         int        width,
                                         int        height,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]