diff options
-rw-r--r-- | gtk/gtkprivate.h | 9 | ||||
-rw-r--r-- | gtk/gtksizerequest.c | 96 |
2 files changed, 69 insertions, 36 deletions
diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 9e5b4cf141..8fa1c9b9f0 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -117,12 +117,13 @@ gboolean _gtk_fnmatch (const char *pattern, /* With GtkSizeRequest, 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 3 typedef struct { - guint age; gint for_size; gint minimum_size; gint natural_size; @@ -131,8 +132,10 @@ typedef struct typedef struct { SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES]; SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES]; - guint8 cached_width_age; - guint8 cached_height_age; + guint cached_widths : 2; + guint cached_heights : 2; + guint last_cached_width : 2; + guint last_cached_height : 2; } SizeRequestCache; diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c index db7282611a..06a60f8622 100644 --- a/gtk/gtksizerequest.c +++ b/gtk/gtksizerequest.c @@ -144,29 +144,67 @@ gtk_size_request_default_init (GtkSizeRequestInterface *iface) * the Clutter toolkit. */ static gboolean -get_cached_size (gint for_size, - SizeRequest *cached_sizes, - SizeRequest **result) +get_cached_size (SizeRequestCache *cache, + GtkSizeGroupMode orientation, + gint for_size, + SizeRequest **result) { - guint i; + guint i, n_sizes; + SizeRequest *cached_sizes; - *result = &cached_sizes[0]; + if (orientation == GTK_SIZE_GROUP_HORIZONTAL) + { + cached_sizes = cache->widths; + n_sizes = cache->cached_widths; + } + else + { + cached_sizes = cache->heights; + n_sizes = cache->cached_widths; + } - for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES; i++) + /* Search for an already cached size */ + for (i = 0; i < n_sizes; i++) { - SizeRequest *cs; + if (cached_sizes[i].for_size == for_size) + { + *result = &cached_sizes[i]; + return TRUE; + } + } - cs = &cached_sizes[i]; + /* If not found, pull a new size from the cache, the returned size cache + * will immediately be used to cache the new computed size so we go ahead + * and increment the last_cached_width/height right away */ + if (orientation == GTK_SIZE_GROUP_HORIZONTAL) + { + if (cache->cached_widths < GTK_SIZE_REQUEST_CACHED_SIZES) + { + cache->cached_widths++; + cache->last_cached_width = cache->cached_widths - 1; + } + else + { + if (++cache->last_cached_width == GTK_SIZE_REQUEST_CACHED_SIZES) + cache->last_cached_width = 0; + } - if (cs->age > 0 && cs->for_size == for_size) - { - *result = cs; - return TRUE; - } - else if (cs->age < (*result)->age) - { - *result = cs; - } + *result = &cache->widths[cache->last_cached_width]; + } + else /* GTK_SIZE_GROUP_VERTICAL */ + { + if (cache->cached_heights < GTK_SIZE_REQUEST_CACHED_SIZES) + { + cache->cached_heights++; + cache->last_cached_height = cache->cached_heights - 1; + } + else + { + if (++cache->last_cached_height == GTK_SIZE_REQUEST_CACHED_SIZES) + cache->last_cached_height = 0; + } + + *result = &cache->heights[cache->last_cached_height]; } return FALSE; @@ -257,11 +295,12 @@ compute_size_for_orientation (GtkSizeRequest *request, cached_size = &cache->widths[0]; if (!GTK_WIDGET_WIDTH_REQUEST_NEEDED (request)) - found_in_cache = get_cached_size (for_size, cache->widths, &cached_size); + found_in_cache = get_cached_size (cache, orientation, for_size, &cached_size); else { memset (cache->widths, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); - cache->cached_width_age = 1; + cache->cached_widths = 1; + cache->last_cached_width = 0; } } else @@ -269,11 +308,12 @@ compute_size_for_orientation (GtkSizeRequest *request, cached_size = &cache->heights[0]; if (!GTK_WIDGET_HEIGHT_REQUEST_NEEDED (request)) - found_in_cache = get_cached_size (for_size, cache->heights, &cached_size); + found_in_cache = get_cached_size (cache, orientation, for_size, &cached_size); else { memset (cache->heights, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); - cache->cached_height_age = 1; + cache->cached_heights = 1; + cache->last_cached_height = 0; } } @@ -326,19 +366,9 @@ compute_size_for_orientation (GtkSizeRequest *request, cached_size->for_size = for_size; if (orientation == GTK_SIZE_GROUP_HORIZONTAL) - { - cached_size->age = cache->cached_width_age; - cache->cached_width_age++; - - GTK_PRIVATE_UNSET_FLAG (request, GTK_WIDTH_REQUEST_NEEDED); - } + GTK_PRIVATE_UNSET_FLAG (request, GTK_WIDTH_REQUEST_NEEDED); else - { - cached_size->age = cache->cached_height_age; - cache->cached_height_age++; - - GTK_PRIVATE_UNSET_FLAG (request, GTK_HEIGHT_REQUEST_NEEDED); - } + GTK_PRIVATE_UNSET_FLAG (request, GTK_HEIGHT_REQUEST_NEEDED); adjusted_min = cached_size->minimum_size; adjusted_natural = cached_size->natural_size; |