summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-03-22 12:27:17 +0100
committerAlexander Larsson <alexl@redhat.com>2013-03-26 16:24:27 +0100
commit5cb27b3abfc99818dfa8cbeb843ba59efdce6b3b (patch)
treea6bf41bd6d63344838124ec3d525274a8900bab9
parenteda436a4be798915525adcab572dfbe7c0a8ff9d (diff)
downloadgtk+-5cb27b3abfc99818dfa8cbeb843ba59efdce6b3b.tar.gz
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.
-rw-r--r--gtk/gtksizerequestcache.c267
-rw-r--r--gtk/gtksizerequestcacheprivate.h24
2 files changed, 208 insertions, 83 deletions
diff --git a/gtk/gtksizerequestcache.c b/gtk/gtksizerequestcache.c
index e6107c7cb1..becbc60de5 100644
--- a/gtk/gtksizerequestcache.c
+++ b/gtk/gtksizerequestcache.c
@@ -32,31 +32,38 @@ _gtk_size_request_cache_init (SizeRequestCache *cache)
}
static void
-free_sizes (SizeRequest **sizes)
+free_sizes_x (SizeRequestX **sizes)
{
gint i;
for (i = 0; i < GTK_SIZE_REQUEST_CACHED_SIZES && sizes[i] != NULL; i++)
- g_slice_free (SizeRequest, sizes[i]);
-
- g_slice_free1 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES, sizes);
+ g_slice_free (SizeRequestX, sizes[i]);
+
+ 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
_gtk_size_request_cache_free (SizeRequestCache *cache)
{
- guint i;
-
- for (i = 0; i < 2; i++)
- {
- if (cache->requests[i])
- free_sizes (cache->requests[i]);
- }
+ if (cache->requests_x)
+ free_sizes_x (cache->requests_x);
+ if (cache->requests_x)
+ free_sizes_y (cache->requests_y);
}
void
_gtk_size_request_cache_clear (SizeRequestCache *cache)
-
{
_gtk_size_request_cache_free (cache);
_gtk_size_request_cache_init (cache);
@@ -71,17 +78,30 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
gint minimum_baseline,
gint natural_baseline)
{
- SizeRequest **cached_sizes;
- SizeRequest *cached_size;
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 */
if (for_size < 0)
{
- cache->cached_size[orientation].minimum_size = minimum_size;
- cache->cached_size[orientation].natural_size = natural_size;
- cache->cached_size[orientation].minimum_baseline = minimum_baseline;
- cache->cached_size[orientation].natural_baseline = natural_baseline;
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ cache->cached_size_x.minimum_size = minimum_size;
+ 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;
return;
}
@@ -90,49 +110,99 @@ _gtk_size_request_cache_commit (SizeRequestCache *cache,
* in the cache and if this result can be used to extend
* that cache entry
*/
- cached_sizes = cache->requests[orientation];
n_sizes = cache->flags[orientation].n_cached_requests;
- for (i = 0; i < n_sizes; i++)
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- 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)
+ SizeRequestX **cached_sizes;
+ SizeRequestX *cached_size;
+ cached_sizes = cache->requests_x;
+
+ for (i = 0; i < n_sizes; i++)
{
- 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 (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;
+ /* 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
{
- if (++cache->flags[orientation].last_cached_request == GTK_SIZE_REQUEST_CACHED_SIZES)
- cache->flags[orientation].last_cached_request = 0;
- }
+ SizeRequestY **cached_sizes;
+ SizeRequestY *cached_size;
+ cached_sizes = cache->requests_y;
- if (cache->requests[orientation] == NULL)
- cache->requests[orientation] = g_slice_alloc0 (sizeof (SizeRequest *) * GTK_SIZE_REQUEST_CACHED_SIZES);
+ 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[orientation][cache->flags[orientation].last_cached_request] == NULL)
- cache->requests[orientation][cache->flags[orientation].last_cached_request] = g_slice_new (SizeRequest);
+ if (cache->requests_y == NULL)
+ cache->requests_y = g_slice_alloc0 (sizeof (SizeRequestY *) * GTK_SIZE_REQUEST_CACHED_SIZES);
- 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;
+ 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;
+ }
}
/* 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 *natural_baseline)
{
- CachedSize *result = NULL;
-
- if (for_size < 0)
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
- if (cache->flags[orientation].cached_size_valid)
- result = &cache->cached_size[orientation];
+ CachedSizeX *result = NULL;
+
+ 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
{
- guint i;
-
- /* Search for an already cached size */
- for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
- {
- SizeRequest *cur = cache->requests[orientation][i];
-
- if (cur->lower_for_size <= for_size &&
- cur->upper_for_size >= for_size)
- {
- result = &cur->cached_size;
- break;
- }
- }
- }
+ CachedSizeY *result = NULL;
- if (result)
- {
- *minimum = result->minimum_size;
- *natural = result->natural_size;
- *minimum_baseline = result->minimum_baseline;
- *natural_baseline = result->natural_baseline;
- return TRUE;
+ if (for_size < 0)
+ {
+ if (cache->flags[orientation].cached_size_valid)
+ result = &cache->cached_size_y;
+ }
+ else
+ {
+ guint i;
+
+ /* Search for an already cached size */
+ for (i = 0; i < cache->flags[orientation].n_cached_requests; i++)
+ {
+ SizeRequestY *cur = cache->requests_y[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 = result->minimum_baseline;
+ *natural_baseline = result->natural_baseline;
+ return TRUE;
+ }
+ else
+ return FALSE;
}
- else
- return FALSE;
}
diff --git a/gtk/gtksizerequestcacheprivate.h b/gtk/gtksizerequestcacheprivate.h
index e458428021..7b3efdea66 100644
--- a/gtk/gtksizerequestcacheprivate.h
+++ b/gtk/gtksizerequestcacheprivate.h
@@ -41,21 +41,35 @@ G_BEGIN_DECLS
typedef struct {
gint minimum_size;
gint natural_size;
+} CachedSizeX;
+
+typedef struct {
+ gint minimum_size;
+ gint natural_size;
gint minimum_baseline;
gint natural_baseline;
-} CachedSize;
+} CachedSizeY;
+
+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 */
+ CachedSizeX cached_size;
+} 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 */
- CachedSize cached_size;
-} SizeRequest;
+ CachedSizeY cached_size;
+} SizeRequestY;
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;
guint request_mode_valid : 1;