[clutter/wip/pango-share-atlas: 11/13] cogl-pango: Don't set the special combine function for atlased textures



commit 2e8fda5f04b5d35f3fb3ce11acb25b772cf2b533
Author: Neil Roberts <neil linux intel com>
Date:   Fri Feb 26 13:01:54 2010 +0000

    cogl-pango: Don't set the special combine function for atlased textures
    
    The material cache will now only set the special combine mode if the
    texture only has an alpha component. The atlased textures will have
    all four components so it will leave the combine functions at the
    default. This increases the chances of batching between glyphs and
    images.
    
    When using the global atlas, the glyph from cairo is now rendered into
    an ARGB surface rather than an alpha-only surface.

 clutter/cogl/pango/cogl-pango-pipeline-cache.c |   61 +++++++++++++++++-------
 clutter/cogl/pango/cogl-pango-render.c         |   28 ++++++++++-
 2 files changed, 70 insertions(+), 19 deletions(-)
---
diff --git a/clutter/cogl/pango/cogl-pango-pipeline-cache.c b/clutter/cogl/pango/cogl-pango-pipeline-cache.c
index 62429ad..ff30ae2 100644
--- a/clutter/cogl/pango/cogl-pango-pipeline-cache.c
+++ b/clutter/cogl/pango/cogl-pango-pipeline-cache.c
@@ -35,7 +35,8 @@ struct _CoglPangoPipelineCache
 {
   GHashTable *hash_table;
 
-  CoglPipeline *base_texture_pipeline;
+  CoglPipeline *base_texture_alpha_pipeline;
+  CoglPipeline *base_texture_rgba_pipeline;
 
   gboolean use_mipmapping;
 };
@@ -85,7 +86,8 @@ _cogl_pango_pipeline_cache_new (gboolean use_mipmapping)
                            _cogl_pango_pipeline_cache_key_destroy,
                            _cogl_pango_pipeline_cache_value_destroy);
 
-  cache->base_texture_pipeline = NULL;
+  cache->base_texture_rgba_pipeline = NULL;
+  cache->base_texture_alpha_pipeline = NULL;
 
   cache->use_mipmapping = use_mipmapping;
 
@@ -93,13 +95,36 @@ _cogl_pango_pipeline_cache_new (gboolean use_mipmapping)
 }
 
 static CoglPipeline *
-get_base_texture_pipeline (CoglPangoPipelineCache *cache)
+get_base_texture_rgba_pipeline (CoglPangoPipelineCache *cache)
 {
-  if (cache->base_texture_pipeline == NULL)
+  if (cache->base_texture_rgba_pipeline == NULL)
     {
       CoglPipeline *pipeline;
 
-      pipeline = cache->base_texture_pipeline = cogl_pipeline_new ();
+      pipeline = cache->base_texture_rgba_pipeline = cogl_pipeline_new ();
+
+      cogl_pipeline_set_layer_wrap_mode (pipeline, 0,
+                                         COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);
+
+      if (cache->use_mipmapping)
+        cogl_pipeline_set_layer_filters
+          (pipeline, 0,
+           COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
+           COGL_PIPELINE_FILTER_LINEAR);
+    }
+
+  return cache->base_texture_rgba_pipeline;
+}
+
+static CoglPipeline *
+get_base_texture_alpha_pipeline (CoglPangoPipelineCache *cache)
+{
+  if (cache->base_texture_alpha_pipeline == NULL)
+    {
+      CoglPipeline *pipeline;
+
+      pipeline = cogl_pipeline_copy (get_base_texture_rgba_pipeline (cache));
+      cache->base_texture_alpha_pipeline = pipeline;
 
       /* The default combine mode of materials is to modulate (A x B)
        * the texture RGBA channels with the RGBA channels of the
@@ -118,17 +143,9 @@ get_base_texture_pipeline (CoglPangoPipelineCache *cache)
       cogl_pipeline_set_layer_combine (pipeline, 0, /* layer */
                                        "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
                                        NULL);
-      cogl_pipeline_set_layer_wrap_mode (pipeline, 0,
-                                         COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE);
-
-      if (cache->use_mipmapping)
-        cogl_pipeline_set_layer_filters
-          (pipeline, 0,
-           COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
-           COGL_PIPELINE_FILTER_LINEAR);
     }
 
-  return cache->base_texture_pipeline;
+  return cache->base_texture_alpha_pipeline;
 }
 
 typedef struct
@@ -165,8 +182,16 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache,
 
   if (texture)
     {
+      CoglPipeline *base;
+
       entry->texture = cogl_handle_ref (texture);
-      entry->pipeline = cogl_pipeline_copy (get_base_texture_pipeline (cache));
+
+      if (cogl_texture_get_format (entry->texture) == COGL_PIXEL_FORMAT_A_8)
+        base = get_base_texture_alpha_pipeline (cache);
+      else
+        base = get_base_texture_rgba_pipeline (cache);
+
+      entry->pipeline = cogl_pipeline_copy (base);
 
       cogl_pipeline_set_layer_texture (entry->pipeline, 0 /* layer */, texture);
     }
@@ -198,8 +223,10 @@ _cogl_pango_pipeline_cache_get (CoglPangoPipelineCache *cache,
 void
 _cogl_pango_pipeline_cache_free (CoglPangoPipelineCache *cache)
 {
-  if (cache->base_texture_pipeline)
-    cogl_object_unref (cache->base_texture_pipeline);
+  if (cache->base_texture_rgba_pipeline)
+    cogl_object_unref (cache->base_texture_rgba_pipeline);
+  if (cache->base_texture_alpha_pipeline)
+    cogl_object_unref (cache->base_texture_alpha_pipeline);
 
   g_hash_table_destroy (cache->hash_table);
 
diff --git a/clutter/cogl/pango/cogl-pango-render.c b/clutter/cogl/pango/cogl-pango-render.c
index 7fa7c57..72cfbcb 100644
--- a/clutter/cogl/pango/cogl-pango-render.c
+++ b/clutter/cogl/pango/cogl-pango-render.c
@@ -467,6 +467,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
   cairo_t *cr;
   cairo_scaled_font_t *scaled_font;
   cairo_glyph_t cairo_glyph;
+  cairo_format_t format_cairo;
+  CoglPixelFormat format_cogl;
 
   COGL_NOTE (PANGO, "redrawing glyph %i", glyph);
 
@@ -475,7 +477,27 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
      here */
   g_return_if_fail (value->texture != COGL_INVALID_HANDLE);
 
-  surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
+  if (cogl_texture_get_format (value->texture) == COGL_PIXEL_FORMAT_A_8)
+    {
+      format_cairo = CAIRO_FORMAT_A8;
+      format_cogl = COGL_PIXEL_FORMAT_A_8;
+    }
+  else
+    {
+      format_cairo = CAIRO_FORMAT_ARGB32;
+
+      /* Cairo stores the data in native byte order as ARGB but Cogl's
+         pixel formats specify the actual byte order. Therefore we
+         need to use a different format depending on the
+         architecture */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+      format_cogl = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
+#else
+      format_cogl = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+#endif
+    }
+
+  surface = cairo_image_surface_create (format_cairo,
                                         value->draw_width,
                                         value->draw_height);
   cr = cairo_create (surface);
@@ -483,6 +505,8 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
   scaled_font = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
   cairo_set_scaled_font (cr, scaled_font);
 
+  cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+
   cairo_glyph.x = -value->draw_x;
   cairo_glyph.y = -value->draw_y;
   /* The PangoCairo glyph numbers directly map to Cairo glyph
@@ -503,7 +527,7 @@ cogl_pango_renderer_set_dirty_glyph (PangoFont *font,
                            value->draw_height, /* dst_height */
                            value->draw_width, /* width */
                            value->draw_height, /* height */
-                           COGL_PIXEL_FORMAT_A_8,
+                           format_cogl,
                            cairo_image_surface_get_stride (surface),
                            cairo_image_surface_get_data (surface));
 



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