Reduced overall SizeRequestCache size

This patch changes the 'age' counting previous approach taken
verbatim from clutter and changes it for a counter of validated
caches and an index to the last cached value which we use to
round-robin through the cache if ever a widget is requested
for more than 3 contextual sizes (cache is reduced by 3 * sizeof (int)
per widget private data).
This commit is contained in:
Tristan Van Berkom
2010-09-21 12:52:49 +09:00
parent 6ba904486c
commit ca251cf1d4
2 changed files with 70 additions and 37 deletions

View File

@ -117,12 +117,13 @@ gboolean _gtk_fnmatch (const char *pattern,
/* With GtkSizeRequest, a widget may be requested /* With GtkSizeRequest, a widget may be requested
* its width for 2 or maximum 3 heights in one resize * 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 #define GTK_SIZE_REQUEST_CACHED_SIZES 3
typedef struct typedef struct
{ {
guint age;
gint for_size; gint for_size;
gint minimum_size; gint minimum_size;
gint natural_size; gint natural_size;
@ -131,8 +132,10 @@ typedef struct
typedef struct { typedef struct {
SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES]; SizeRequest widths[GTK_SIZE_REQUEST_CACHED_SIZES];
SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES]; SizeRequest heights[GTK_SIZE_REQUEST_CACHED_SIZES];
guint8 cached_width_age; guint cached_widths : 2;
guint8 cached_height_age; guint cached_heights : 2;
guint last_cached_width : 2;
guint last_cached_height : 2;
} SizeRequestCache; } SizeRequestCache;

View File

@ -144,29 +144,67 @@ gtk_size_request_default_init (GtkSizeRequestInterface *iface)
* the Clutter toolkit. * the Clutter toolkit.
*/ */
static gboolean static gboolean
get_cached_size (gint for_size, get_cached_size (SizeRequestCache *cache,
SizeRequest *cached_sizes, GtkSizeGroupMode orientation,
gint for_size,
SizeRequest **result) SizeRequest **result)
{ {
guint i; guint i, n_sizes;
SizeRequest *cached_sizes;
*result = &cached_sizes[0]; if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES; i++)
{ {
SizeRequest *cs; cached_sizes = cache->widths;
n_sizes = cache->cached_widths;
cs = &cached_sizes[i]; }
else
if (cs->age > 0 && cs->for_size == for_size)
{ {
*result = cs; cached_sizes = cache->heights;
n_sizes = cache->cached_widths;
}
/* Search for an already cached size */
for (i = 0; i < n_sizes; i++)
{
if (cached_sizes[i].for_size == for_size)
{
*result = &cached_sizes[i];
return TRUE; return TRUE;
} }
else if (cs->age < (*result)->age)
{
*result = cs;
} }
/* 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;
}
*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; return FALSE;
@ -257,11 +295,12 @@ compute_size_for_orientation (GtkSizeRequest *request,
cached_size = &cache->widths[0]; cached_size = &cache->widths[0];
if (!GTK_WIDGET_WIDTH_REQUEST_NEEDED (request)) 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 else
{ {
memset (cache->widths, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); 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 else
@ -269,11 +308,12 @@ compute_size_for_orientation (GtkSizeRequest *request,
cached_size = &cache->heights[0]; cached_size = &cache->heights[0];
if (!GTK_WIDGET_HEIGHT_REQUEST_NEEDED (request)) 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 else
{ {
memset (cache->heights, 0, GTK_SIZE_REQUEST_CACHED_SIZES * sizeof (SizeRequest)); 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; cached_size->for_size = for_size;
if (orientation == GTK_SIZE_GROUP_HORIZONTAL) 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 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_min = cached_size->minimum_size;
adjusted_natural = cached_size->natural_size; adjusted_natural = cached_size->natural_size;