[gtk+/gtk-3-0] Revert "Cache heights-for-range-of-widths instead of height for every width."
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-3-0] Revert "Cache heights-for-range-of-widths instead of height for every width."
- Date: Sat, 2 Apr 2011 18:11:36 +0000 (UTC)
commit 7790f3091b2fc5ac5483d14a153d4907458a0da1
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Apr 2 11:11:31 2011 -0400
Revert "Cache heights-for-range-of-widths instead of height for every width."
This reverts commit edb44589dc141565aeb33891f0e54f6dfec0ebe2.
gtk/gtksizerequest.c | 411 ++++++++++++++++++++----------------------------
gtk/gtkwidget.c | 3 +-
gtk/gtkwidgetprivate.h | 42 +++---
3 files changed, 192 insertions(+), 264 deletions(-)
---
diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c
index 976b56f..e299c40 100644
--- a/gtk/gtksizerequest.c
+++ b/gtk/gtksizerequest.c
@@ -31,235 +31,126 @@
#include "gtksizegroup-private.h"
#include "gtkwidgetprivate.h"
+/* looks for a cached size request for this for_size. If not
+ * found, returns the oldest entry so it can be overwritten
+ *
+ * Note that this caching code was originally derived from
+ * the Clutter toolkit.
+ */
-#ifndef G_DISABLE_CHECKS
-static GQuark recursion_check_quark = 0;
-#endif /* G_DISABLE_CHECKS */
-
-static void
-push_recursion_check (GtkWidget *widget,
- GtkSizeGroupMode orientation,
- gint for_size)
-{
-#ifndef G_DISABLE_CHECKS
- const char *previous_method;
- const char *method;
-
- if (recursion_check_quark == 0)
- recursion_check_quark = g_quark_from_static_string ("gtk-size-request-in-progress");
-
- previous_method = g_object_get_qdata (G_OBJECT (widget), recursion_check_quark);
-
- if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
- {
- method = for_size < 0 ? "get_width" : "get_width_for_height";
- }
- else
- {
- method = for_size < 0 ? "get_height" : "get_height_for_width";
- }
-
- if (previous_method != NULL)
- {
- g_warning ("%s %p: widget tried to gtk_widget_%s inside "
- " GtkWidget ::%s implementation. "
- "Should just invoke GTK_WIDGET_GET_CLASS(widget)->%s "
- "directly rather than using gtk_widget_%s",
- G_OBJECT_TYPE_NAME (widget), widget,
- method, previous_method,
- method, method);
- }
-
- g_object_set_qdata (G_OBJECT (widget), recursion_check_quark, (char*) method);
-#endif /* G_DISABLE_CHECKS */
-}
-
-static void
-pop_recursion_check (GtkWidget *widget,
- GtkSizeGroupMode orientation)
-{
-#ifndef G_DISABLE_CHECKS
- g_object_set_qdata (G_OBJECT (widget), recursion_check_quark, NULL);
-#endif
-}
-
-
-static void
-clear_cache (SizeRequestCache *cache,
- GtkSizeGroupMode orientation)
-{
- SizeRequest **sizes;
- gint i;
-
- if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
- {
- sizes = cache->widths;
-
- cache->widths = NULL;
- cache->cached_widths = 0;
- cache->last_cached_width = 0;
- cache->cached_base_width = FALSE;
- }
- else
- {
- sizes = cache->heights;
-
- cache->heights = NULL;
- cache->cached_heights = 0;
- cache->last_cached_height = 0;
- cache->cached_base_height = FALSE;
- }
-
- if (sizes)
- {
- for (i = 0; sizes[i] != NULL; i++)
- g_slice_free (SizeRequest, sizes[i]);
-
- g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
- }
-}
-
-void
-_gtk_widget_free_cached_sizes (GtkWidget *widget)
-{
- SizeRequestCache *cache;
-
- cache = _gtk_widget_peek_request_cache (widget);
-
- clear_cache (cache, GTK_SIZE_GROUP_HORIZONTAL);
- clear_cache (cache, GTK_SIZE_GROUP_VERTICAL);
-}
/* This function checks if 'request_needed' flag is present
* and resets the cache state if a request is needed for
* a given orientation.
*/
static SizeRequestCache *
-init_cache (GtkWidget *widget)
+init_cache (GtkWidget *widget,
+ GtkSizeGroupMode orientation)
{
- SizeRequestCache *cache;
+ GtkSizeRequestMode mode;
+ SizeRequestCache *cache;
cache = _gtk_widget_peek_request_cache (widget);
- if (_gtk_widget_get_width_request_needed (widget))
- clear_cache (cache, GTK_SIZE_GROUP_HORIZONTAL);
- else if (_gtk_widget_get_height_request_needed (widget))
- clear_cache (cache, GTK_SIZE_GROUP_VERTICAL);
-
- return cache;
-}
-
-/* looks for a cached size request for this for_size. If not
- * found, returns the oldest entry so it can be overwritten
- *
- * Note that this caching code was originally derived from
- * the Clutter toolkit but has evolved for other GTK+ requirements.
- */
-static gboolean
-get_cached_size (GtkWidget *widget,
- GtkSizeGroupMode orientation,
- gint for_size,
- CachedSize **result)
-{
- SizeRequestCache *cache;
- SizeRequest **cached_sizes;
- guint i, n_sizes;
-
- cache = init_cache (widget);
-
- if (for_size < 0)
+ if (orientation == GTK_SIZE_GROUP_HORIZONTAL &&
+ _gtk_widget_get_width_request_needed (widget))
{
- if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
+ mode = gtk_widget_get_request_mode (widget);
+
+ if (mode == GTK_SIZE_REQUEST_CONSTANT_SIZE)
{
- *result = &cache->cached_width;
- return cache->cached_base_width;
+ if (cache->sizes)
+ {
+ g_slice_free (ContextualSizes, cache->sizes);
+ cache->sizes = NULL;
+ }
}
else
{
- *result = &cache->cached_height;
- return cache->cached_base_height;
+ if (!cache->sizes)
+ cache->sizes = g_slice_new0 (ContextualSizes);
+
+ memset (cache->sizes->widths, 0x0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
+ cache->sizes->cached_widths = 0;
+ cache->sizes->last_cached_width = 0;
}
- }
- if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
- {
- cached_sizes = cache->widths;
- n_sizes = cache->cached_widths;
+ cache->cached_width.minimum_size = -1;
+ cache->cached_width.natural_size = -1;
}
- else
+ else if (orientation == GTK_SIZE_GROUP_VERTICAL &&
+ _gtk_widget_get_height_request_needed (widget))
{
- cached_sizes = cache->heights;
- n_sizes = cache->cached_heights;
- }
+ mode = gtk_widget_get_request_mode (widget);
- /* Search for an already cached size */
- for (i = 0; i < n_sizes; i++)
- {
- if (cached_sizes[i]->lower_for_size <= for_size &&
- cached_sizes[i]->upper_for_size >= for_size)
+ if (mode == GTK_SIZE_REQUEST_CONSTANT_SIZE)
{
- *result = &cached_sizes[i]->cached_size;
- return TRUE;
+ if (cache->sizes)
+ {
+ g_slice_free (ContextualSizes, cache->sizes);
+ cache->sizes = NULL;
+ }
}
+ else
+ {
+ if (!cache->sizes)
+ cache->sizes = g_slice_new0 (ContextualSizes);
+
+ memset (cache->sizes->heights, 0x0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest));
+ cache->sizes->cached_heights = 0;
+ cache->sizes->last_cached_height = 0;
+ }
+
+ cache->cached_height.minimum_size = -1;
+ cache->cached_height.natural_size = -1;
}
- return FALSE;
+ return cache;
}
-static void
-commit_cached_size (GtkWidget *widget,
- GtkSizeGroupMode orientation,
- gint for_size,
- gint minimum_size,
- gint natural_size)
+static gboolean
+get_cached_size (GtkWidget *widget,
+ GtkSizeGroupMode orientation,
+ gint for_size,
+ CachedSize **result)
{
- SizeRequestCache *cache;
- SizeRequest **cached_sizes;
- guint i, n_sizes;
+ SizeRequestCache *cache;
+ SizeRequest *cached_sizes;
+ guint i, n_sizes;
- cache = _gtk_widget_peek_request_cache (widget);
+ cache = init_cache (widget, orientation);
- /* First handle caching of the base requests */
if (for_size < 0)
{
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
- {
- cache->cached_width.minimum_size = minimum_size;
- cache->cached_width.natural_size = natural_size;
- cache->cached_base_width = TRUE;
- }
+ *result = &cache->cached_width;
else
- {
- cache->cached_height.minimum_size = minimum_size;
- cache->cached_height.natural_size = natural_size;
- cache->cached_base_height = TRUE;
- }
- return;
+ *result = &cache->cached_height;
+
+ if ((*result)->minimum_size < 0)
+ return FALSE;
+ else
+ return TRUE;
}
- /* Check if the minimum_size and natural_size is already
- * in the cache and if this result can be used to extend
- * that cache entry
- */
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
{
- cached_sizes = cache->widths;
- n_sizes = cache->cached_widths;
+ cached_sizes = cache->sizes->widths;
+ n_sizes = cache->sizes->cached_widths;
}
else
{
- cached_sizes = cache->heights;
- n_sizes = cache->cached_heights;
+ cached_sizes = cache->sizes->heights;
+ n_sizes = cache->sizes->cached_widths;
}
+ /* Search for an already cached size */
for (i = 0; i < n_sizes; i++)
{
- if (cached_sizes[i]->cached_size.minimum_size == minimum_size &&
- cached_sizes[i]->cached_size.natural_size == natural_size)
+ if (cached_sizes[i].for_size == for_size)
{
- cached_sizes[i]->lower_for_size = MIN (cached_sizes[i]->lower_for_size, for_size);
- cached_sizes[i]->upper_for_size = MAX (cached_sizes[i]->upper_for_size, for_size);
- return;
+ *result = &cached_sizes[i].cached_size;
+ return TRUE;
}
}
@@ -268,52 +159,90 @@ commit_cached_size (GtkWidget *widget,
* and increment the last_cached_width/height right away */
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
{
- if (cache->cached_widths < GTK_SIZE_REQUEST_CACHED_SIZES)
+ if (cache->sizes->cached_widths < GTK_SIZE_REQUEST_CACHED_SIZES)
{
- cache->cached_widths++;
- cache->last_cached_width = cache->cached_widths - 1;
+ cache->sizes->cached_widths++;
+ cache->sizes->last_cached_width = cache->sizes->cached_widths - 1;
}
else
{
- if (++cache->last_cached_width == GTK_SIZE_REQUEST_CACHED_SIZES)
- cache->last_cached_width = 0;
+ if (++cache->sizes->last_cached_width == GTK_SIZE_REQUEST_CACHED_SIZES)
+ cache->sizes->last_cached_width = 0;
}
- if (!cache->widths)
- cache->widths = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
-
- if (!cache->widths[cache->last_cached_width])
- cache->widths[cache->last_cached_width] = g_slice_new (SizeRequest);
-
- cache->widths[cache->last_cached_width]->lower_for_size = for_size;
- cache->widths[cache->last_cached_width]->upper_for_size = for_size;
- cache->widths[cache->last_cached_width]->cached_size.minimum_size = minimum_size;
- cache->widths[cache->last_cached_width]->cached_size.natural_size = natural_size;
+ cache->sizes->widths[cache->sizes->last_cached_width].for_size = for_size;
+ *result = &cache->sizes->widths[cache->sizes->last_cached_width].cached_size;
}
else /* GTK_SIZE_GROUP_VERTICAL */
{
- if (cache->cached_heights < GTK_SIZE_REQUEST_CACHED_SIZES)
+ if (cache->sizes->cached_heights < GTK_SIZE_REQUEST_CACHED_SIZES)
{
- cache->cached_heights++;
- cache->last_cached_height = cache->cached_heights - 1;
+ cache->sizes->cached_heights++;
+ cache->sizes->last_cached_height = cache->sizes->cached_heights - 1;
}
else
{
- if (++cache->last_cached_height == GTK_SIZE_REQUEST_CACHED_SIZES)
- cache->last_cached_height = 0;
+ if (++cache->sizes->last_cached_height == GTK_SIZE_REQUEST_CACHED_SIZES)
+ cache->sizes->last_cached_height = 0;
}
- if (!cache->heights)
- cache->heights = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
+ cache->sizes->heights[cache->sizes->last_cached_height].for_size = for_size;
+ *result = &cache->sizes->heights[cache->sizes->last_cached_height].cached_size;
+ }
+
+ return FALSE;
+}
+
- if (!cache->heights[cache->last_cached_height])
- cache->heights[cache->last_cached_height] = g_slice_new (SizeRequest);
+#ifndef G_DISABLE_CHECKS
+static GQuark recursion_check_quark = 0;
+#endif /* G_DISABLE_CHECKS */
- cache->heights[cache->last_cached_height]->lower_for_size = for_size;
- cache->heights[cache->last_cached_height]->upper_for_size = for_size;
- cache->heights[cache->last_cached_height]->cached_size.minimum_size = minimum_size;
- cache->heights[cache->last_cached_height]->cached_size.natural_size = natural_size;
+static void
+push_recursion_check (GtkWidget *widget,
+ GtkSizeGroupMode orientation,
+ gint for_size)
+{
+#ifndef G_DISABLE_CHECKS
+ const char *previous_method;
+ const char *method;
+
+ if (recursion_check_quark == 0)
+ recursion_check_quark = g_quark_from_static_string ("gtk-size-request-in-progress");
+
+ previous_method = g_object_get_qdata (G_OBJECT (widget), recursion_check_quark);
+
+ if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
+ {
+ method = for_size < 0 ? "get_width" : "get_width_for_height";
+ }
+ else
+ {
+ method = for_size < 0 ? "get_height" : "get_height_for_width";
+ }
+
+ if (previous_method != NULL)
+ {
+ g_warning ("%s %p: widget tried to gtk_widget_%s inside "
+ " GtkWidget ::%s implementation. "
+ "Should just invoke GTK_WIDGET_GET_CLASS(widget)->%s "
+ "directly rather than using gtk_widget_%s",
+ G_OBJECT_TYPE_NAME (widget), widget,
+ method, previous_method,
+ method, method);
}
+
+ g_object_set_qdata (G_OBJECT (widget), recursion_check_quark, (char*) method);
+#endif /* G_DISABLE_CHECKS */
+}
+
+static void
+pop_recursion_check (GtkWidget *widget,
+ GtkSizeGroupMode orientation)
+{
+#ifndef G_DISABLE_CHECKS
+ g_object_set_qdata (G_OBJECT (widget), recursion_check_quark, NULL);
+#endif
}
/* This is the main function that checks for a cached size and
@@ -330,14 +259,14 @@ compute_size_for_orientation (GtkWidget *widget,
{
CachedSize *cached_size;
gboolean found_in_cache = FALSE;
- gint min_size = 0;
- gint nat_size = 0;
+ gint adjusted_min, adjusted_natural;
found_in_cache = get_cached_size (widget, orientation, for_size, &cached_size);
if (!found_in_cache)
{
- gint adjusted_min, adjusted_natural, adjusted_for_size = for_size;
+ gint min_size = 0;
+ gint nat_size = 0;
gtk_widget_ensure_style (widget);
@@ -365,11 +294,11 @@ compute_size_for_orientation (GtkWidget *widget,
&minimum_height,
&natural_height,
&ignored_position,
- &adjusted_for_size);
+ &for_size);
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget,
- MAX (adjusted_for_size, minimum_height),
+ MAX (for_size, minimum_height),
&min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
@@ -384,9 +313,9 @@ compute_size_for_orientation (GtkWidget *widget,
}
else
{
- gint ignored_position = 0;
- gint minimum_width;
- gint natural_width;
+ int ignored_position = 0;
+ int minimum_width;
+ int natural_width;
/* Pull the base natural width from the cache as it's needed to adjust
* the proposed 'for_size' */
@@ -398,11 +327,11 @@ compute_size_for_orientation (GtkWidget *widget,
&minimum_width,
&natural_width,
&ignored_position,
- &adjusted_for_size);
+ &for_size);
push_recursion_check (widget, orientation, for_size);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget,
- MAX (adjusted_for_size, minimum_width),
+ MAX (for_size, minimum_width),
&min_size, &nat_size);
pop_recursion_check (widget, orientation);
}
@@ -414,13 +343,16 @@ compute_size_for_orientation (GtkWidget *widget,
G_OBJECT_TYPE_NAME (widget), widget, min_size, nat_size);
}
+ cached_size->minimum_size = min_size;
+ cached_size->natural_size = nat_size;
+
if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
_gtk_widget_set_width_request_needed (widget, FALSE);
else
_gtk_widget_set_height_request_needed (widget, FALSE);
- adjusted_min = min_size;
- adjusted_natural = nat_size;
+ adjusted_min = cached_size->minimum_size;
+ adjusted_natural = cached_size->natural_size;
GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
orientation == GTK_SIZE_GROUP_HORIZONTAL ?
GTK_ORIENTATION_HORIZONTAL :
@@ -428,14 +360,14 @@ compute_size_for_orientation (GtkWidget *widget,
&adjusted_min,
&adjusted_natural);
- if (adjusted_min < min_size ||
- adjusted_natural < nat_size)
+ if (adjusted_min < cached_size->minimum_size ||
+ adjusted_natural < cached_size->natural_size)
{
g_warning ("%s %p adjusted size %s min %d natural %d must not decrease below min %d natural %d",
G_OBJECT_TYPE_NAME (widget), widget,
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
adjusted_min, adjusted_natural,
- min_size, nat_size);
+ cached_size->minimum_size, cached_size->natural_size);
/* don't use the adjustment */
}
else if (adjusted_min > adjusted_natural)
@@ -444,14 +376,14 @@ compute_size_for_orientation (GtkWidget *widget,
G_OBJECT_TYPE_NAME (widget), widget,
orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
adjusted_min, adjusted_natural,
- min_size, nat_size);
+ cached_size->minimum_size, cached_size->natural_size);
/* don't use the adjustment */
}
else
{
/* adjustment looks good */
- min_size = adjusted_min;
- nat_size = adjusted_natural;
+ cached_size->minimum_size = adjusted_min;
+ cached_size->natural_size = adjusted_natural;
}
/* Update size-groups with our request and update our cached requests
@@ -459,31 +391,26 @@ compute_size_for_orientation (GtkWidget *widget,
*/
_gtk_size_group_bump_requisition (widget,
orientation,
- &min_size,
- &nat_size);
-
- commit_cached_size (widget, orientation, for_size, min_size, nat_size);
- }
- else
- {
- min_size = cached_size->minimum_size;
- nat_size = cached_size->natural_size;
+ &cached_size->minimum_size,
+ &cached_size->natural_size);
}
if (minimum_size)
- *minimum_size = min_size;
+ *minimum_size = cached_size->minimum_size;
if (natural_size)
- *natural_size = nat_size;
+ *natural_size = cached_size->natural_size;
- g_assert (min_size <= nat_size);
+ g_assert (cached_size->minimum_size <= cached_size->natural_size);
GTK_NOTE (SIZE_REQUEST,
g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
widget, G_OBJECT_TYPE_NAME (widget),
orientation == GTK_SIZE_GROUP_HORIZONTAL ?
"width for height" : "height for width" ,
- for_size, min_size, nat_size,
+ for_size,
+ cached_size->minimum_size,
+ cached_size->natural_size,
found_in_cache ? "yes" : "no"));
}
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 4c18fc1..b72b80b 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10647,7 +10647,8 @@ gtk_widget_finalize (GObject *object)
if (priv->context)
g_object_unref (priv->context);
- _gtk_widget_free_cached_sizes (widget);
+ if (priv->requests.sizes)
+ g_slice_free (ContextualSizes, priv->requests.sizes);
if (g_object_is_floating (object))
g_warning ("A floating object was finalized. This means that someone\n"
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 7d298c6..9dfec65 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -29,13 +29,12 @@
G_BEGIN_DECLS
-/* Cache as many ranges of height-for-width
- * (or width-for-height) as can be rational
- * for a said widget to have, if a label can
- * only wrap to 3 lines, only 3 caches will
- * ever be allocated for it.
+/* With GtkWidget, a widget may be requested
+ * its width for 2 or maximum 3 heights in one resize
+ * (Note this define is limited by the bitfield sizes
+ * defined on the SizeRequestCache structure).
*/
-#define GTK_SIZE_REQUEST_CACHED_SIZES (5)
+#define GTK_SIZE_REQUEST_CACHED_SIZES (2)
typedef struct {
gint minimum_size;
@@ -44,24 +43,26 @@ typedef struct {
typedef struct
{
- gint lower_for_size; /* The minimum for_size with the same result */
- gint upper_for_size; /* The maximum for_size with the same result */
+ /* the size this request is for */
+ gint for_size;
CachedSize cached_size;
} SizeRequest;
typedef struct {
- SizeRequest **widths;
- SizeRequest **heights;
-
- CachedSize cached_width;
- CachedSize cached_height;
-
- guint cached_widths : 3;
- guint cached_heights : 3;
- guint last_cached_width : 3;
- guint last_cached_height : 3;
- guint cached_base_width : 1;
- guint cached_base_height : 1;
+ SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES];
+ SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES];
+
+ guint cached_widths : 2;
+ guint cached_heights : 2;
+ guint last_cached_width : 2;
+ guint last_cached_height : 2;
+} ContextualSizes;
+
+typedef struct {
+ ContextualSizes *sizes;
+
+ CachedSize cached_width;
+ CachedSize cached_height;
} SizeRequestCache;
void _gtk_widget_set_visible_flag (GtkWidget *widget,
@@ -113,7 +114,6 @@ gboolean _gtk_widget_get_translation_to_window (GtkWidget *widget,
GdkWindow *window,
int *x,
int *y);
-void _gtk_widget_free_cached_sizes (GtkWidget *widget);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]