[clutter/wip/pango-share-atlas: 4/13] pango-glyph-cache: Try to put glyphs in the global atlas



commit b1b42d9c7565fdb42417bb7fe7b2a89e112dcd3a
Author: Neil Roberts <neil linux intel com>
Date:   Thu Feb 18 17:35:14 2010 +0000

    pango-glyph-cache: Try to put glyphs in the global atlas
    
    If mipmapping is disabled, it will now try to create a standalone
    atlas texture for a glyph rather than putting it in the atlas.
    
    If the atlas texture can't be created then it will fallback to the
    glyph cache.

 clutter/cogl/pango/cogl-pango-glyph-cache.c |  137 ++++++++++++++++++++-------
 1 files changed, 101 insertions(+), 36 deletions(-)
---
diff --git a/clutter/cogl/pango/cogl-pango-glyph-cache.c b/clutter/cogl/pango/cogl-pango-glyph-cache.c
index 0a6cc35..946b0ef 100644
--- a/clutter/cogl/pango/cogl-pango-glyph-cache.c
+++ b/clutter/cogl/pango/cogl-pango-glyph-cache.c
@@ -30,6 +30,7 @@
 #include "cogl-pango-glyph-cache.h"
 #include "cogl-pango-private.h"
 #include "cogl/cogl-atlas.h"
+#include "cogl/cogl-atlas-texture-private.h"
 
 typedef struct _CoglPangoGlyphCacheKey     CoglPangoGlyphCacheKey;
 
@@ -49,6 +50,10 @@ struct _CoglPangoGlyphCache
      optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid
      iterating the hash table if we know none of them are dirty */
   gboolean          has_dirty_glyphs;
+
+  /* Whether mipmapping is being used for this cache. This only
+     affects whether we decide to put the glyph in the global atlas */
+  gboolean          use_mipmapping;
 };
 
 struct _CoglPangoGlyphCacheKey
@@ -118,6 +123,8 @@ cogl_pango_glyph_cache_new (gboolean use_mipmapping)
 
   cache->has_dirty_glyphs = FALSE;
 
+  cache->use_mipmapping = use_mipmapping;
+
   return cache;
 }
 
@@ -179,6 +186,85 @@ cogl_pango_glyph_cache_reorganize_cb (void *user_data)
   g_hook_list_invoke (&cache->reorganize_callbacks, FALSE);
 }
 
+static gboolean
+cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache,
+                                            PangoFont *font,
+                                            PangoGlyph glyph,
+                                            CoglPangoGlyphCacheValue *value)
+{
+  CoglHandle texture;
+
+  /* If the cache is using mipmapping then we can't use the global
+     atlas because it would just get migrated back out */
+  if (cache->use_mipmapping)
+    return FALSE;
+
+  texture = _cogl_atlas_texture_new_with_size (value->draw_width,
+                                               value->draw_height,
+                                               COGL_TEXTURE_NONE,
+                                               COGL_PIXEL_FORMAT_RGBA_8888_PRE);
+
+  if (texture == COGL_INVALID_HANDLE)
+    return FALSE;
+
+  value->texture = texture;
+  value->tx1 = 0;
+  value->ty1 = 0;
+  value->tx2 = 1;
+  value->ty2 = 1;
+  value->tx_pixel = 0;
+  value->ty_pixel = 0;
+
+  return TRUE;
+}
+
+static gboolean
+cogl_pango_glyph_cache_add_to_local_atlas (CoglPangoGlyphCache *cache,
+                                           PangoFont *font,
+                                           PangoGlyph glyph,
+                                           CoglPangoGlyphCacheValue *value)
+{
+  CoglAtlas *atlas = NULL;
+  GSList *l;
+
+  /* Look for an atlas that can reserve the space */
+  for (l = cache->atlases; l; l = l->next)
+    if (_cogl_atlas_reserve_space (l->data,
+                                   value->draw_width + 1,
+                                   value->draw_height + 1,
+                                   value))
+      {
+        atlas = l->data;
+        break;
+      }
+
+  /* If we couldn't find one then start a new atlas */
+  if (atlas == NULL)
+    {
+      atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_A_8,
+                               TRUE,
+                               cogl_pango_glyph_cache_update_position_cb);
+      COGL_NOTE (ATLAS, "Created new atlas for glyphs: %p", atlas);
+      /* If we still can't reserve space then something has gone
+         seriously wrong so we'll just give up */
+      if (!_cogl_atlas_reserve_space (atlas,
+                                      value->draw_width + 1,
+                                      value->draw_height + 1,
+                                      value))
+        {
+          cogl_object_unref (atlas);
+          return FALSE;
+        }
+
+      _cogl_atlas_add_reorganize_callback
+        (atlas, cogl_pango_glyph_cache_reorganize_cb, NULL, cache);
+
+      cache->atlases = g_slist_prepend (cache->atlases, atlas);
+    }
+
+  return TRUE;
+}
+
 CoglPangoGlyphCacheValue *
 cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache,
                                gboolean             create,
@@ -197,52 +283,31 @@ cogl_pango_glyph_cache_lookup (CoglPangoGlyphCache *cache,
     {
       CoglPangoGlyphCacheKey *key;
       PangoRectangle ink_rect;
-      CoglAtlas *atlas = NULL;
-      GSList *l;
+
+      value = g_slice_new (CoglPangoGlyphCacheValue);
+      value->texture = COGL_INVALID_HANDLE;
+      value->dirty = TRUE;
 
       pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
       pango_extents_to_pixels (&ink_rect, NULL);
 
-      value = g_slice_new (CoglPangoGlyphCacheValue);
-      value->texture = COGL_INVALID_HANDLE;
       value->draw_x = ink_rect.x;
       value->draw_y = ink_rect.y;
       value->draw_width = ink_rect.width;
       value->draw_height = ink_rect.height;
-      value->dirty = TRUE;
 
-      /* Look for an atlas that can reserve the space */
-      for (l = cache->atlases; l; l = l->next)
-        if (_cogl_atlas_reserve_space (l->data,
-                                       ink_rect.width + 1, ink_rect.height + 1,
-                                       value))
-          {
-            atlas = l->data;
-            break;
-          }
-
-      /* If we couldn't find one then start a new atlas */
-      if (atlas == NULL)
+      /* Try adding the glyph to the global atlas... */
+      if (!cogl_pango_glyph_cache_add_to_global_atlas (cache,
+                                                       font,
+                                                       glyph,
+                                                       value) &&
+          !cogl_pango_glyph_cache_add_to_local_atlas (cache,
+                                                      font,
+                                                      glyph,
+                                                      value))
         {
-          atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_A_8,
-                                   TRUE,
-                                   cogl_pango_glyph_cache_update_position_cb);
-          COGL_NOTE (ATLAS, "Created new atlas for glyphs: %p", atlas);
-          /* If we still can't reserve space then something has gone
-             seriously wrong so we'll just give up */
-          if (!_cogl_atlas_reserve_space (atlas,
-                                          ink_rect.width + 1,
-                                          ink_rect.height + 1, value))
-            {
-              cogl_object_unref (atlas);
-              cogl_pango_glyph_cache_value_free (value);
-              return NULL;
-            }
-
-          _cogl_atlas_add_reorganize_callback
-            (atlas, cogl_pango_glyph_cache_reorganize_cb, NULL, cache);
-
-          cache->atlases = g_slist_prepend (cache->atlases, atlas);
+          cogl_pango_glyph_cache_value_free (value);
+          return NULL;
         }
 
       key = g_slice_new (CoglPangoGlyphCacheKey);



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