summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-05-02 11:52:28 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-05-02 11:52:28 -0400
commit5eb61ac775cf5f81dbc28bb9f246e52fc4c45a0f (patch)
tree3cdfedff26090e05a444a69143c7463fe220e3ee
parentb7be1a10d0d0e40bd303a090793808905562ee7b (diff)
Initial glyph cachingrender
-rw-r--r--fb/fbpict.c132
-rw-r--r--fb/fbtrap.c2
2 files changed, 133 insertions, 1 deletions
diff --git a/fb/fbpict.c b/fb/fbpict.c
index d1fd0cbbd..a91fbfb54 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -34,6 +34,7 @@
#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
+#include "damage.h"
void
fbComposite (CARD8 op,
@@ -351,6 +352,135 @@ free_pixman_pict (PicturePtr pict, pixman_image_t *image)
fbFinishAccess (pict->pDrawable);
}
+#define N_STACK_GLYPHS (256)
+
+/* FIXME: clear this when the screen shuts down */
+static pixman_glyph_cache_t *glyph_cache;
+
+static void
+fbUnrealizeGlyph (ScreenPtr pScreen, GlyphPtr pGlyph)
+{
+ if (glyph_cache)
+ pixman_glyph_cache_remove (glyph_cache, NULL, pGlyph);
+}
+
+static void
+fbGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
+ pixman_glyph_t *pglyphs = stack_glyphs;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int dst_xoff, dst_yoff;
+ int src_xoff, src_yoff;
+ pixman_image_t *src, *dst;
+ int i;
+
+ if (!glyph_cache)
+ glyph_cache = pixman_glyph_cache_create();
+
+ src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
+ dst = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
+
+ if (src && dst)
+ {
+ int x, y;
+ int n_glyphs = 0;
+
+ for (i = 0; i < nlist; ++i)
+ n_glyphs += list[i].len;
+
+ if (n_glyphs > N_STACK_GLYPHS)
+ {
+ if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
+ goto bail;
+ }
+
+ n_glyphs = 0;
+ x = 0;
+ y = 0;
+ while (nlist--)
+ {
+ int n;
+
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+
+ pixman_glyph_cache_freeze (glyph_cache);
+ while (n--)
+ {
+ GlyphPtr glyph = *glyphs++;
+
+ if (!pixman_glyph_cache_contains (glyph_cache, NULL, glyph))
+ {
+ pixman_image_t *glyph_image;
+ PicturePtr pPicture;
+ int gx, gy;
+
+ pPicture = GlyphPicture (glyph)[pScreen->myNum];
+ if (pPicture)
+ {
+ if (!(glyph_image = image_from_pict (pPicture, FALSE, &gx, &gy)))
+ goto bail;
+
+ pixman_glyph_cache_insert (glyph_cache, NULL, glyph, glyph_image);
+
+ free_pixman_pict (pPicture, glyph_image);
+ }
+ }
+
+ pglyphs[n_glyphs].x = x - glyph->info.x;
+ pglyphs[n_glyphs].y = y - glyph->info.y;
+ pglyphs[n_glyphs].key = glyph;
+ n_glyphs++;
+
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ pixman_glyph_cache_thaw (glyph_cache);
+ }
+
+ /* FIXME: maybe be a little more precise here */
+ DamageRegionAppend (pDst->pDrawable, pDst->pCompositeClip);
+
+ if (maskFormat)
+ {
+ int bpp = maskFormat->depth;
+
+ if (bpp == 24)
+ bpp = 32;
+
+ pixman_composite_glyphs (op, src, dst, maskFormat->format | (bpp << 24),
+ xSrc, ySrc, dst_xoff, dst_yoff,
+ glyph_cache, NULL, n_glyphs, pglyphs);
+ }
+ else
+ {
+ pixman_composite_glyphs_no_mask (op, src, dst,
+ xSrc, ySrc, dst_xoff, dst_yoff,
+ glyph_cache, NULL, n_glyphs, pglyphs);
+ }
+
+ DamageRegionProcessPending (pDst->pDrawable);
+ }
+
+bail:
+ if (pglyphs != stack_glyphs)
+ free (pglyphs);
+
+ free_pixman_pict (pSrc, src);
+ free_pixman_pict (pDst, dst);
+}
+
Bool
fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
{
@@ -368,6 +498,8 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->AddTraps = fbAddTraps;
ps->AddTriangles = fbAddTriangles;
ps->Triangles = fbTriangles;
+ ps->Glyphs = fbGlyphs;
+ ps->UnrealizeGlyph = fbUnrealizeGlyph;
return TRUE;
}
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 0b5a6382e..55942aac8 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -123,7 +123,7 @@ fbShapes (CompositeShapesFunc composite,
pixman_format_code_t format;
DamageRegionAppend (pDst->pDrawable, pDst->pCompositeClip);
-
+
if (!maskFormat)
{
int i;