summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2010-02-26 13:01:54 +0000
committerRobert Bragg <robert@linux.intel.com>2011-05-05 17:32:30 +0100
commit66c54e04de83b7a5333f9bc1930598a494ac6236 (patch)
treee2ec25fda8385b9807df70ef72ee13a090f5b8c3
parentcbf011dcd03f7e0fb385691d99b6ed633d646470 (diff)
downloadcogl-66c54e04de83b7a5333f9bc1930598a494ac6236.tar.gz
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.
-rw-r--r--pango/cogl-pango-pipeline-cache.c61
-rw-r--r--pango/cogl-pango-render.c28
2 files changed, 70 insertions, 19 deletions
diff --git a/pango/cogl-pango-pipeline-cache.c b/pango/cogl-pango-pipeline-cache.c
index ae1397c2..5f6a5a03 100644
--- a/pango/cogl-pango-pipeline-cache.c
+++ b/pango/cogl-pango-pipeline-cache.c
@@ -39,7 +39,8 @@ struct _CoglPangoPipelineCache
{
GHashTable *hash_table;
- CoglPipeline *base_texture_pipeline;
+ CoglPipeline *base_texture_alpha_pipeline;
+ CoglPipeline *base_texture_rgba_pipeline;
gboolean use_mipmapping;
};
@@ -89,7 +90,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;
@@ -97,13 +99,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
@@ -122,17 +147,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
@@ -169,8 +186,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);
}
@@ -202,8 +227,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/pango/cogl-pango-render.c b/pango/cogl-pango-render.c
index 7fa7c578..72cfbcb1 100644
--- a/pango/cogl-pango-render.c
+++ b/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));