summaryrefslogtreecommitdiffstats
path: root/abs/core/xorg-server/use-pixman-glyph-cache.patch
diff options
context:
space:
mode:
Diffstat (limited to 'abs/core/xorg-server/use-pixman-glyph-cache.patch')
-rw-r--r--abs/core/xorg-server/use-pixman-glyph-cache.patch270
1 files changed, 270 insertions, 0 deletions
diff --git a/abs/core/xorg-server/use-pixman-glyph-cache.patch b/abs/core/xorg-server/use-pixman-glyph-cache.patch
new file mode 100644
index 0000000..c1cd90d
--- /dev/null
+++ b/abs/core/xorg-server/use-pixman-glyph-cache.patch
@@ -0,0 +1,270 @@
+From 9cbcb5bd6a5360a128d15b77a02d8d3351f74366 Mon Sep 17 00:00:00 2001
+From: Søren Sandmann Pedersen <ssp@redhat.com>
+Date: Wed, 30 May 2012 09:19:08 +0000
+Subject: Use new pixman_glyph_cache_t API that will be in pixman 0.28.0
+
+This new API allows glyphs to be cached in a data structure in pixman,
+and entire glyph strings to be composited in one go.
+
+Also bump pixman dependency to 0.27.2.
+
+Results from the cairo peformance test suite running against Xvfb with
+a screen size of 1680x1050@32bpp:
+
+Speedups
+========
+ xlib firefox-talos-gfx 12416.63 -> 3603.93 3.45x speedup
+██▌
+ xlib xfce4-terminal-a1 1727.57 -> 1048.85: 1.65x speedup
+▋
+ xlib evolution 1370.49 -> 869.34: 1.58x speedup
+▋
+ xlib gnome-terminal-vim 1832.83 -> 1251.94: 1.46x speedup
+▌
+ xlib poppler 1519.70 -> 1204.05: 1.26x speedup
+▎
+ xlib firefox-planet-gnome 6982.55 -> 5598.16: 1.25x speedup
+▎
+ xlib ocitysmap 1142.77 -> 1071.53: 1.07x speedup
+▏
+
+No slowdowns were reported.
+
+Results of x11perf -aa10text:
+
+Before:
+
+ 8000000 reps @ 0.0007 msec (1450000.0/sec)
+ 8000000 reps @ 0.0007 msec (1460000.0/sec)
+ 8000000 reps @ 0.0007 msec (1460000.0/sec)
+ 8000000 reps @ 0.0007 msec (1470000.0/sec)
+ 8000000 reps @ 0.0007 msec (1480000.0/sec)
+ 40000000 trep @ 0.0007 msec (1460000.0/sec)
+
+After:
+
+ 32000000 reps @ 0.0002 msec (4910000.0/sec)
+ 32000000 reps @ 0.0002 msec (4830000.0/sec)
+ 32000000 reps @ 0.0002 msec (4890000.0/sec)
+ 32000000 reps @ 0.0002 msec (4830000.0/sec)
+ 32000000 reps @ 0.0002 msec (4900000.0/sec)
+ 160000000 trep @ 0.0002 msec (4870000.0/sec)
+
+Version 2: Destroy the glyph cache at server regen time
+
+Acked-by: Aaron Plattner <aplattner@nvidia.com>
+Reviewed-by: Keith Packard <keithp@keithp.com>
+Signed-off-by: Soren Sandmann <ssp@redhat.com>
+---
+diff --git a/configure.ac b/configure.ac
+index e686614..b6ed92c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -811,7 +811,7 @@ LIBPCIACCESS="pciaccess >= 0.12.901"
+ LIBUDEV="libudev >= 143"
+ LIBSELINUX="libselinux >= 2.0.86"
+ LIBDBUS="dbus-1 >= 1.0"
+-LIBPIXMAN="pixman-1 >= 0.21.8"
++LIBPIXMAN="pixman-1 >= 0.27.2"
+
+ dnl Pixman is always required, but we separate it out so we can link
+ dnl specific modules against it
+diff --git a/fb/fb.h b/fb/fb.h
+index 75596c5..b869d12 100644
+--- a/fb/fb.h
++++ b/fb/fb.h
+@@ -1344,6 +1344,9 @@ extern _X_EXPORT void
+ extern _X_EXPORT Bool
+ fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
++extern _X_EXPORT void
++fbDestroyGlyphCache(void);
++
+ /*
+ * fbpixmap.c
+ */
+diff --git a/fb/fbpict.c b/fb/fbpict.c
+index 097a1a6..2804ff4 100644
+--- a/fb/fbpict.c
++++ b/fb/fbpict.c
+@@ -70,6 +70,156 @@ fbComposite(CARD8 op,
+ free_pixman_pict(pDst, dest);
+ }
+
++static pixman_glyph_cache_t *glyphCache;
++
++void
++fbDestroyGlyphCache(void)
++{
++ if (glyphCache)
++ {
++ pixman_glyph_cache_destroy (glyphCache);
++ glyphCache = NULL;
++ }
++}
++
++static void
++fbUnrealizeGlyph(ScreenPtr pScreen,
++ GlyphPtr pGlyph)
++{
++ if (glyphCache)
++ pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
++}
++
++static void
++fbGlyphs(CARD8 op,
++ PicturePtr pSrc,
++ PicturePtr pDst,
++ PictFormatPtr maskFormat,
++ INT16 xSrc,
++ INT16 ySrc, int nlist,
++ GlyphListPtr list,
++ GlyphPtr *glyphs)
++{
++#define N_STACK_GLYPHS 512
++ ScreenPtr pScreen = pDst->pDrawable->pScreen;
++ pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
++ pixman_glyph_t *pglyphs = stack_glyphs;
++ pixman_image_t *srcImage, *dstImage;
++ int srcXoff, srcYoff, dstXoff, dstYoff;
++ GlyphPtr glyph;
++ int n_glyphs;
++ int x, y;
++ int i, n;
++ int xDst = list->xOff, yDst = list->yOff;
++
++ miCompositeSourceValidate(pSrc);
++
++ n_glyphs = 0;
++ for (i = 0; i < nlist; ++i)
++ n_glyphs += list[i].len;
++
++ if (!glyphCache)
++ glyphCache = pixman_glyph_cache_create();
++
++ pixman_glyph_cache_freeze (glyphCache);
++
++ if (n_glyphs > N_STACK_GLYPHS) {
++ if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
++ goto out;
++ }
++
++ i = 0;
++ x = y = 0;
++ while (nlist--) {
++ x += list->xOff;
++ y += list->yOff;
++ n = list->len;
++ while (n--) {
++ const void *g;
++
++ glyph = *glyphs++;
++
++ if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
++ pixman_image_t *glyphImage;
++ PicturePtr pPicture;
++ int xoff, yoff;
++
++ pPicture = GetGlyphPicture(glyph, pScreen);
++ if (!pPicture) {
++ n_glyphs--;
++ goto next;
++ }
++
++ if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
++ goto out;
++
++ g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
++ glyph->info.x,
++ glyph->info.y,
++ glyphImage);
++
++ free_pixman_pict(pPicture, glyphImage);
++
++ if (!g)
++ goto out;
++ }
++
++ pglyphs[i].x = x;
++ pglyphs[i].y = y;
++ pglyphs[i].glyph = g;
++ i++;
++
++ next:
++ x += glyph->info.xOff;
++ y += glyph->info.yOff;
++ }
++ list++;
++ }
++
++ if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
++ goto out;
++
++ if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
++ goto out_free_src;
++
++ if (maskFormat) {
++ pixman_format_code_t format;
++ pixman_box32_t extents;
++ int x, y;
++
++ format = maskFormat->format | (maskFormat->depth << 24);
++
++ pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
++
++ x = extents.x1;
++ y = extents.y1;
++
++ pixman_composite_glyphs(op, srcImage, dstImage, format,
++ xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
++ x, y,
++ x + dstXoff, y + dstYoff,
++ extents.x2 - extents.x1,
++ extents.y2 - extents.y1,
++ glyphCache, n_glyphs, pglyphs);
++ }
++ else {
++ pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
++ xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
++ dstXoff, dstYoff,
++ glyphCache, n_glyphs, pglyphs);
++ }
++
++ free_pixman_pict(pDst, dstImage);
++
++out_free_src:
++ free_pixman_pict(pSrc, srcImage);
++
++out:
++ pixman_glyph_cache_thaw(glyphCache);
++ if (pglyphs != stack_glyphs)
++ free(pglyphs);
++}
++
+ static pixman_image_t *
+ create_solid_fill_image(PicturePtr pict)
+ {
+@@ -357,7 +507,8 @@ fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+ return FALSE;
+ ps = GetPictureScreen(pScreen);
+ ps->Composite = fbComposite;
+- ps->Glyphs = miGlyphs;
++ ps->Glyphs = fbGlyphs;
++ ps->UnrealizeGlyph = fbUnrealizeGlyph;
+ ps->CompositeRects = miCompositeRects;
+ ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
+ ps->Trapezoids = fbTrapezoids;
+diff --git a/fb/fbscreen.c b/fb/fbscreen.c
+index 7c7d656..f9080a4 100644
+--- a/fb/fbscreen.c
++++ b/fb/fbscreen.c
+@@ -32,6 +32,7 @@ fbCloseScreen(ScreenPtr pScreen)
+ int d;
+ DepthPtr depths = pScreen->allowedDepths;
+
++ fbDestroyGlyphCache();
+ for (d = 0; d < pScreen->numDepths; d++)
+ free(depths[d].vids);
+ free(depths);
+--
+cgit v0.9.0.2-2-gbebe