From 843be48572e00d20e927cfb6f11ad4abba6e8e15 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Thu, 9 Sep 2010 15:02:56 +0900 Subject: [PATCH] Moved GtkSizeRequest cache to GtkWidget->priv Now that we have a private data installed directly on the GtkWidget instance it makes no sense to cache the size requests on widget qdata. This change will generally make GTK+ memory less fragmented as well as significantly speed up the size request process. --- gtk/gtkprivate.h | 22 +++++++++++++++ gtk/gtksizerequest.c | 65 +++++--------------------------------------- gtk/gtkwidget.c | 18 ++++++++++++ gtk/gtkwidget.h | 2 ++ 4 files changed, 49 insertions(+), 58 deletions(-) diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index e4505420fc..9e5b4cf141 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -114,6 +114,28 @@ gboolean _gtk_fnmatch (const char *pattern, #define GTK_DEFAULT_ACCEL_MOD_MASK GDK_META_MASK #endif + +/* With GtkSizeRequest, a widget may be requested + * its width for 2 or maximum 3 heights in one resize + */ +#define GTK_SIZE_REQUEST_CACHED_SIZES 3 + +typedef struct +{ + guint age; + gint for_size; + gint minimum_size; + gint natural_size; +} SizeRequest; + +typedef struct { + SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES]; + SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES]; + guint8 cached_width_age; + guint8 cached_height_age; +} SizeRequestCache; + + G_END_DECLS #endif /* __GTK_PRIVATE_H__ */ diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c index 4af24144f5..7c67c7eab9 100644 --- a/gtk/gtksizerequest.c +++ b/gtk/gtksizerequest.c @@ -98,34 +98,10 @@ #include "gtkprivate.h" #include "gtkintl.h" -/* With GtkSizeRequest, a widget may be requested - * its width for 2 or maximum 3 heights in one resize - */ -#define N_CACHED_SIZES 3 - -typedef struct -{ - guint age; - gint for_size; - gint minimum_size; - gint natural_size; -} SizeRequest; - -typedef struct { - SizeRequest widths[N_CACHED_SIZES]; - SizeRequest heights[N_CACHED_SIZES]; - guint8 cached_width_age; - guint8 cached_height_age; -} SizeRequestCache; - -static GQuark quark_cache = 0; - - typedef GtkSizeRequestIface GtkSizeRequestInterface; -G_DEFINE_INTERFACE_WITH_CODE (GtkSizeRequest, - gtk_size_request, - GTK_TYPE_WIDGET, - quark_cache = g_quark_from_static_string ("gtk-size-request-cache")); +G_DEFINE_INTERFACE (GtkSizeRequest, + gtk_size_request, + GTK_TYPE_WIDGET); static void @@ -149,7 +125,7 @@ get_cached_size (gint for_size, *result = &cached_sizes[0]; - for (i = 0; i < N_CACHED_SIZES; i++) + for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES; i++) { SizeRequest *cs; @@ -169,33 +145,6 @@ get_cached_size (gint for_size, return FALSE; } -static void -destroy_cache (SizeRequestCache *cache) -{ - g_slice_free (SizeRequestCache, cache); -} - -static SizeRequestCache * -get_cache (GtkSizeRequest *widget, - gboolean create) -{ - SizeRequestCache *cache; - - cache = g_object_get_qdata (G_OBJECT (widget), quark_cache); - if (!cache && create) - { - cache = g_slice_new0 (SizeRequestCache); - - cache->cached_width_age = 1; - cache->cached_height_age = 1; - - g_object_set_qdata_full (G_OBJECT (widget), quark_cache, cache, - (GDestroyNotify)destroy_cache); - } - - return cache; -} - static void do_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -222,7 +171,7 @@ compute_size_for_orientation (GtkSizeRequest *request, g_return_if_fail (minimum_size != NULL || natural_size != NULL); widget = GTK_WIDGET (request); - cache = get_cache (request, TRUE); + cache = _gtk_widget_peek_request_cache (widget); if (orientation == GTK_SIZE_GROUP_HORIZONTAL) { @@ -232,7 +181,7 @@ compute_size_for_orientation (GtkSizeRequest *request, found_in_cache = get_cached_size (for_size, cache->widths, &cached_size); else { - memset (cache->widths, 0, N_CACHED_SIZES * sizeof (SizeRequest)); + memset (cache->widths, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); cache->cached_width_age = 1; } } @@ -244,7 +193,7 @@ compute_size_for_orientation (GtkSizeRequest *request, found_in_cache = get_cached_size (for_size, cache->heights, &cached_size); else { - memset (cache->heights, 0, N_CACHED_SIZES * sizeof (SizeRequest)); + memset (cache->heights, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); cache->cached_height_age = 1; } } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index e21a56902d..9a032c5cc4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -168,6 +168,9 @@ struct _GtkWidgetPrivate */ GtkAllocation allocation; + /* The widget's requested sizes */ + SizeRequestCache requests; + /* The widget's window or its parent window if it does * not have a window. (Which will be indicated by the * GTK_NO_WINDOW flag being set). @@ -9071,6 +9074,21 @@ _gtk_widget_peek_colormap (void) return NULL; } +/** + * _gtk_widget_peek_request_cache: + * + * Returns the address of the widget's request cache (strictly for + * internal use in gtksizerequest.c) + * + * Return value: the address of @widget's size request cache. + **/ +gpointer +_gtk_widget_peek_request_cache (GtkWidget *widget) +{ + /* Don't bother slowing things down with the return_if_fail guards here */ + return &widget->priv->requests; +} + /* * _gtk_widget_set_device_window: * @widget: a #GtkWidget. diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index ad09ba7eea..b413e0d421 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -941,6 +941,8 @@ void _gtk_widget_synthesize_crossing (GtkWidget *from, GdkColormap* _gtk_widget_peek_colormap (void); +gpointer _gtk_widget_peek_request_cache (GtkWidget *widget); + void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget, GtkWidget *toplevel, gpointer user_data);