summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-04-28 20:33:55 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-05-28 13:26:20 -0400
commit2276b3c495bbe438b337730bd2d01f90b9f6cfd9 (patch)
treed723d0c68a4cc655d6ca2c9bccf1bf64921213f6
parent838763b3d7d674db50c4ac5c44f33f66b944b21b (diff)
Faster glyphs
-rw-r--r--glyphs.txt2
-rw-r--r--pixman/pixman-glyph.c92
-rw-r--r--pixman/pixman-private.h12
-rw-r--r--pixman/pixman.c12
4 files changed, 86 insertions, 32 deletions
diff --git a/glyphs.txt b/glyphs.txt
index ec7c531f..66823457 100644
--- a/glyphs.txt
+++ b/glyphs.txt
@@ -1,4 +1,4 @@
-TODO:
+done:
- uploading glyphs should be done through pixman images
- this is convenient for both cairo and X. And in fact
easier within pixman as well.
diff --git a/pixman/pixman-glyph.c b/pixman/pixman-glyph.c
index 444c3d1b..db790c4d 100644
--- a/pixman/pixman-glyph.c
+++ b/pixman/pixman-glyph.c
@@ -258,10 +258,10 @@ pixman_glyph_cache_insert (pixman_glyph_cache_t *cache,
height = image->bits.height;
if (cache->n_glyphs >= HASH_SIZE)
- return FALSE;
+ return NULL;
if (!(glyph = malloc (sizeof *glyph)))
- return FALSE;
+ return NULL;
glyph->font_key = font_key;
glyph->glyph_key = glyph_key;
@@ -270,7 +270,7 @@ pixman_glyph_cache_insert (pixman_glyph_cache_t *cache,
image->bits.format, width, height, NULL, -1)))
{
free (glyph);
- return FALSE;
+ return NULL;
}
pixman_image_composite32 (PIXMAN_OP_SRC,
@@ -285,6 +285,7 @@ pixman_glyph_cache_insert (pixman_glyph_cache_t *cache,
pixman_list_prepend (&cache->mru, &glyph->mru_link);
+ _pixman_image_validate (glyph->image);
insert_glyph (cache, glyph);
return glyph;
@@ -323,12 +324,12 @@ pixman_composite_glyphs_no_mask (pixman_op_t op,
{
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
- pixman_image_composite (op, src, glyph->image, dest,
- src_x + glyphs[i].x, src_y + glyphs[i].y,
- 0, 0,
- dest_x + glyphs[i].x, dest_y + glyphs[i].y,
- glyph->image->bits.width,
- glyph->image->bits.height);
+ pixman_image_composite32 (op, src, glyph->image, dest,
+ src_x + glyphs[i].x, src_y + glyphs[i].y,
+ 0, 0,
+ dest_x + glyphs[i].x, dest_y + glyphs[i].y,
+ glyph->image->bits.width,
+ glyph->image->bits.height);
pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
}
@@ -419,18 +420,69 @@ pixman_composite_glyphs (pixman_op_t op,
pixman_image_set_component_alpha (mask, TRUE);
}
- for (i = 0; i < n_glyphs; ++i)
{
- glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
-
- pixman_image_composite32 (
- PIXMAN_OP_ADD, glyph->image, NULL, mask,
- 0, 0, 0, 0,
- glyphs[i].x - extents.x1, glyphs[i].y - extents.y1,
- glyph->image->bits.width,
- glyph->image->bits.height);
-
- pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
+ uint32_t glyph_flags = 0;
+ pixman_format_code_t glyph_format = PIXMAN_null;
+ uint32_t dest_flags;
+ pixman_format_code_t dest_format;
+ pixman_implementation_t *implementation;
+ pixman_composite_func_t func = NULL;
+ pixman_composite_info_t info;
+ uint32_t extra = FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
+
+ _pixman_image_validate (mask);
+
+ dest_flags = mask->common.flags;
+ dest_format = mask->common.extended_format_code;
+
+ info.op = PIXMAN_OP_ADD;
+ info.mask_image = NULL;
+ info.dest_image = mask;
+ info.src_flags = glyph_flags | extra;
+ info.mask_flags = FAST_PATH_IS_OPAQUE;
+ info.dest_flags = dest_flags;
+ info.src_x = 0;
+ info.src_y = 0;
+ info.mask_x = 0;
+ info.mask_y = 0;
+
+ for (i = 0; i < n_glyphs; ++i)
+ {
+ glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
+ pixman_image_t *glyph_img = glyph->image;
+
+ if (glyph_img->common.extended_format_code != glyph_format ||
+ glyph_img->common.flags != glyph_flags)
+ {
+ glyph_format = glyph_img->common.extended_format_code;
+ glyph_flags = glyph_img->common.flags;
+
+ _pixman_lookup_composite_function (
+ get_implementation(), PIXMAN_OP_ADD,
+ glyph_format, glyph_flags | extra,
+ PIXMAN_null, FAST_PATH_IS_OPAQUE,
+ dest_format, dest_flags,
+ &implementation, &func);
+ }
+
+ if (func)
+ {
+ info.src_image = glyph_img;
+ info.dest_x = glyphs[i].x - extents.x1;
+ info.dest_y = glyphs[i].y - extents.y1;
+ info.width = glyph->image->bits.width;
+ info.height = glyph->image->bits.height;
+
+ if (info.dest_x + info.width > mask->bits.width)
+ info.width = mask->bits.width - info.dest_x;
+ if (info.dest_y + info.height > mask->bits.height)
+ info.height = mask->bits.height - info.dest_y;
+
+ func (implementation, &info);
+ }
+
+ pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
+ }
}
#if 0
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 4683174b..c2ed9e1f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -684,6 +684,18 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
dest, FAST_PATH_STD_DEST_FLAGS, \
func) }
+extern pixman_implementation_t *global_implementation;
+
+static force_inline pixman_implementation_t *
+get_implementation (void)
+{
+#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
+ if (!global_implementation)
+ global_implementation = _pixman_choose_implementation ();
+#endif
+ return global_implementation;
+}
+
/* Memory allocation helpers */
void *
pixman_malloc_ab (unsigned int n, unsigned int b);
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 8fb53568..7d841d3d 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -30,7 +30,7 @@
#include <stdlib.h>
-static pixman_implementation_t *global_implementation;
+pixman_implementation_t *global_implementation;
#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
static void __attribute__((constructor))
@@ -40,16 +40,6 @@ pixman_constructor (void)
}
#endif
-static force_inline pixman_implementation_t *
-get_implementation (void)
-{
-#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
- if (!global_implementation)
- global_implementation = _pixman_choose_implementation ();
-#endif
- return global_implementation;
-}
-
typedef struct operator_info_t operator_info_t;
struct operator_info_t