[gtk+] GtkSizeRequestCache: Don't store baselines in horizontal case



commit 5ad618cb95a99842305d53fea6409b6b1d86b315
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Mar 22 12:27:17 2013 +0100

    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.

 gtk/gtksizerequestcache.c        | 267 +++++++++++++++++++++++++++------------
 gtk/gtksizerequestcacheprivate.h |  24 +++-
 2 files changed, 208 insertions(+), 83 deletions(-)
---
diff --git a/gtk/gtksizerequestcache.c b/gtk/gtksizerequestcache.c
index e6107c7..becbc60 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 e458428..7b3efde 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]