forked from AuroraMiddleware/gtk
GtkSizeRequestCache: Don't store baselines in horizontal case
This saves memory for every widget (maximum 48 bytes per widget) at a cost of a few duplicated codepaths in the size request cache.
This commit is contained in:
parent
77e0f18eda
commit
5ad618cb95
@ -32,31 +32,38 @@ _gtk_size_request_cache_init (SizeRequestCache *cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_sizes (SizeRequest **sizes)
|
free_sizes_x (SizeRequestX **sizes)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||||
g_slice_free (SizeRequest, sizes[i]);
|
g_slice_free (SizeRequestX, sizes[i]);
|
||||||
|
|
||||||
g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
g_slice_free1 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_sizes_y (SizeRequestY **sizes)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
|
||||||
|
g_slice_free (SizeRequestY, sizes[i]);
|
||||||
|
|
||||||
|
g_slice_free1 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_size_request_cache_free (SizeRequestCache *cache)
|
_gtk_size_request_cache_free (SizeRequestCache *cache)
|
||||||
{
|
{
|
||||||
guint i;
|
if (cache->requests_x)
|
||||||
|
free_sizes_x (cache->requests_x);
|
||||||
for (i = 0; i < 2; i++)
|
if (cache->requests_x)
|
||||||
{
|
free_sizes_y (cache->requests_y);
|
||||||
if (cache->requests[i])
|
|
||||||
free_sizes (cache->requests[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gtk_size_request_cache_clear (SizeRequestCache *cache)
|
_gtk_size_request_cache_clear (SizeRequestCache *cache)
|
||||||
|
|
||||||
{
|
{
|
||||||
_gtk_size_request_cache_free (cache);
|
_gtk_size_request_cache_free (cache);
|
||||||
_gtk_size_request_cache_init (cache);
|
_gtk_size_request_cache_init (cache);
|
||||||
@ -71,17 +78,30 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
|||||||
gint minimum_baseline,
|
gint minimum_baseline,
|
||||||
gint natural_baseline)
|
gint natural_baseline)
|
||||||
{
|
{
|
||||||
SizeRequest **cached_sizes;
|
|
||||||
SizeRequest *cached_size;
|
|
||||||
guint i, n_sizes;
|
guint i, n_sizes;
|
||||||
|
|
||||||
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
{
|
||||||
|
g_assert (minimum_baseline == -1);
|
||||||
|
g_assert (natural_baseline == -1);
|
||||||
|
}
|
||||||
|
|
||||||
/* First handle caching of the base requests */
|
/* First handle caching of the base requests */
|
||||||
if (for_size < 0)
|
if (for_size < 0)
|
||||||
{
|
{
|
||||||
cache->cached_size[orientation].minimum_size = minimum_size;
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
cache->cached_size[orientation].natural_size = natural_size;
|
{
|
||||||
cache->cached_size[orientation].minimum_baseline = minimum_baseline;
|
cache->cached_size_x.minimum_size = minimum_size;
|
||||||
cache->cached_size[orientation].natural_baseline = natural_baseline;
|
cache->cached_size_x.natural_size = natural_size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache->cached_size_y.minimum_size = minimum_size;
|
||||||
|
cache->cached_size_y.natural_size = natural_size;
|
||||||
|
cache->cached_size_y.minimum_baseline = minimum_baseline;
|
||||||
|
cache->cached_size_y.natural_baseline = natural_baseline;
|
||||||
|
}
|
||||||
|
|
||||||
cache->flags[orientation].cached_size_valid = TRUE;
|
cache->flags[orientation].cached_size_valid = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -90,49 +110,99 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
|
|||||||
* in the cache and if this result can be used to extend
|
* in the cache and if this result can be used to extend
|
||||||
* that cache entry
|
* that cache entry
|
||||||
*/
|
*/
|
||||||
cached_sizes = cache->requests[orientation];
|
|
||||||
n_sizes = cache->flags[orientation].n_cached_requests;
|
n_sizes = cache->flags[orientation].n_cached_requests;
|
||||||
|
|
||||||
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 &&
|
|
||||||
cached_sizes[i]->cached_size.minimum_baseline == minimum_baseline &&
|
|
||||||
cached_sizes[i]->cached_size.natural_baseline == natural_baseline)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not found, pull a new size from the cache, the returned size cache
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
* will immediately be used to cache the new computed size so we go ahead
|
|
||||||
* and increment the last_cached_request right away */
|
|
||||||
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
|
||||||
{
|
{
|
||||||
cache->flags[orientation].n_cached_requests++;
|
SizeRequestX **cached_sizes;
|
||||||
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
SizeRequestX *cached_size;
|
||||||
|
cached_sizes = cache->requests_x;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_request right away */
|
||||||
|
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||||
|
{
|
||||||
|
cache->flags[orientation].n_cached_requests++;
|
||||||
|
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||||
|
cache->flags[orientation].last_cached_request = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->requests_x == NULL)
|
||||||
|
cache->requests_x = g_slice_alloc0 (sizeof (SizeRequestX *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||||
|
|
||||||
|
if (cache->requests_x[cache->flags[orientation].last_cached_request] == NULL)
|
||||||
|
cache->requests_x[cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequestX);
|
||||||
|
|
||||||
|
cached_size = cache->requests_x[cache->flags[orientation].last_cached_request];
|
||||||
|
cached_size->lower_for_size = for_size;
|
||||||
|
cached_size->upper_for_size = for_size;
|
||||||
|
cached_size->cached_size.minimum_size = minimum_size;
|
||||||
|
cached_size->cached_size.natural_size = natural_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
SizeRequestY **cached_sizes;
|
||||||
cache->flags[orientation].last_cached_request = 0;
|
SizeRequestY *cached_size;
|
||||||
|
cached_sizes = cache->requests_y;
|
||||||
|
|
||||||
|
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 &&
|
||||||
|
cached_sizes[i]->cached_size.minimum_baseline == minimum_baseline &&
|
||||||
|
cached_sizes[i]->cached_size.natural_baseline == natural_baseline)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_request right away */
|
||||||
|
if (n_sizes < GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||||
|
{
|
||||||
|
cache->flags[orientation].n_cached_requests++;
|
||||||
|
cache->flags[orientation].last_cached_request = cache->flags[orientation].n_cached_requests - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
|
||||||
|
cache->flags[orientation].last_cached_request = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache->requests_y == NULL)
|
||||||
|
cache->requests_y = g_slice_alloc0 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
||||||
|
|
||||||
|
if (cache->requests_y[cache->flags[orientation].last_cached_request] == NULL)
|
||||||
|
cache->requests_y[cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequestY);
|
||||||
|
|
||||||
|
cached_size = cache->requests_y[cache->flags[orientation].last_cached_request];
|
||||||
|
cached_size->lower_for_size = for_size;
|
||||||
|
cached_size->upper_for_size = for_size;
|
||||||
|
cached_size->cached_size.minimum_size = minimum_size;
|
||||||
|
cached_size->cached_size.natural_size = natural_size;
|
||||||
|
cached_size->cached_size.minimum_baseline = minimum_baseline;
|
||||||
|
cached_size->cached_size.natural_baseline = natural_baseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->requests[orientation] == NULL)
|
|
||||||
cache->requests[orientation] = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
|
|
||||||
|
|
||||||
if (cache->requests[orientation][cache->flags[orientation].last_cached_request] == NULL)
|
|
||||||
cache->requests[orientation][cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequest);
|
|
||||||
|
|
||||||
cached_size = cache->requests[orientation][cache->flags[orientation].last_cached_request];
|
|
||||||
cached_size->lower_for_size = for_size;
|
|
||||||
cached_size->upper_for_size = for_size;
|
|
||||||
cached_size->cached_size.minimum_size = minimum_size;
|
|
||||||
cached_size->cached_size.natural_size = natural_size;
|
|
||||||
cached_size->cached_size.minimum_baseline = minimum_baseline;
|
|
||||||
cached_size->cached_size.natural_baseline = natural_baseline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* looks for a cached size request for this for_size.
|
/* looks for a cached size request for this for_size.
|
||||||
@ -149,40 +219,81 @@ _gtk_size_request_cache_lookup (SizeRequestCache *cache,
|
|||||||
gint *minimum_baseline,
|
gint *minimum_baseline,
|
||||||
gint *natural_baseline)
|
gint *natural_baseline)
|
||||||
{
|
{
|
||||||
CachedSize *result = NULL;
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
|
|
||||||
if (for_size < 0)
|
|
||||||
{
|
{
|
||||||
if (cache->flags[orientation].cached_size_valid)
|
CachedSizeX *result = NULL;
|
||||||
result = &cache->cached_size[orientation];
|
|
||||||
|
if (for_size < 0)
|
||||||
|
{
|
||||||
|
if (cache->flags[orientation].cached_size_valid)
|
||||||
|
result = &cache->cached_size_x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
/* Search for an already cached size */
|
||||||
|
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||||
|
{
|
||||||
|
SizeRequestX *cur = cache->requests_x[i];
|
||||||
|
|
||||||
|
if (cur->lower_for_size <= for_size &&
|
||||||
|
cur->upper_for_size >= for_size)
|
||||||
|
{
|
||||||
|
result = &cur->cached_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
*minimum = result->minimum_size;
|
||||||
|
*natural = result->natural_size;
|
||||||
|
*minimum_baseline = -1;
|
||||||
|
*natural_baseline = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
guint i;
|
CachedSizeY *result = NULL;
|
||||||
|
|
||||||
/* Search for an already cached size */
|
if (for_size < 0)
|
||||||
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
{
|
||||||
{
|
if (cache->flags[orientation].cached_size_valid)
|
||||||
SizeRequest *cur = cache->requests[orientation][i];
|
result = &cache->cached_size_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
if (cur->lower_for_size <= for_size &&
|
/* Search for an already cached size */
|
||||||
cur->upper_for_size >= for_size)
|
for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
|
||||||
{
|
{
|
||||||
result = &cur->cached_size;
|
SizeRequestY *cur = cache->requests_y[i];
|
||||||
break;
|
|
||||||
}
|
if (cur->lower_for_size <= for_size &&
|
||||||
}
|
cur->upper_for_size >= for_size)
|
||||||
|
{
|
||||||
|
result = &cur->cached_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
*minimum = result->minimum_size;
|
||||||
|
*natural = result->natural_size;
|
||||||
|
*minimum_baseline = result->minimum_baseline;
|
||||||
|
*natural_baseline = result->natural_baseline;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
*minimum = result->minimum_size;
|
|
||||||
*natural = result->natural_size;
|
|
||||||
*minimum_baseline = result->minimum_baseline;
|
|
||||||
*natural_baseline = result->natural_baseline;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,24 +38,38 @@ G_BEGIN_DECLS
|
|||||||
*/
|
*/
|
||||||
#define GTK_SIZE_REQUEST_CACHED_SIZES (5)
|
#define GTK_SIZE_REQUEST_CACHED_SIZES (5)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gint minimum_size;
|
||||||
|
gint natural_size;
|
||||||
|
} CachedSizeX;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gint minimum_size;
|
gint minimum_size;
|
||||||
gint natural_size;
|
gint natural_size;
|
||||||
gint minimum_baseline;
|
gint minimum_baseline;
|
||||||
gint natural_baseline;
|
gint natural_baseline;
|
||||||
} CachedSize;
|
} CachedSizeY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
gint lower_for_size; /* The minimum for_size with the same result */
|
gint lower_for_size; /* The minimum for_size with the same result */
|
||||||
gint upper_for_size; /* The maximum for_size with the same result */
|
gint upper_for_size; /* The maximum for_size with the same result */
|
||||||
CachedSize cached_size;
|
CachedSizeX cached_size;
|
||||||
} SizeRequest;
|
} SizeRequestX;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
CachedSizeY cached_size;
|
||||||
|
} SizeRequestY;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SizeRequest **requests[2];
|
SizeRequestX **requests_x;
|
||||||
|
SizeRequestY **requests_y;
|
||||||
|
|
||||||
CachedSize cached_size[2];
|
CachedSizeX cached_size_x;
|
||||||
|
CachedSizeY cached_size_y;
|
||||||
|
|
||||||
GtkSizeRequestMode request_mode : 3;
|
GtkSizeRequestMode request_mode : 3;
|
||||||
guint request_mode_valid : 1;
|
guint request_mode_valid : 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user