From b863c91c6c9218e2ad9458231b24385be177ed08 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 12 Nov 2012 01:31:01 -0800 Subject: Mon Nov 12 01:30:54 PST 2012 --- extra/xorg-server/use-pixman-glyph-cache.patch | 270 +++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 extra/xorg-server/use-pixman-glyph-cache.patch (limited to 'extra/xorg-server/use-pixman-glyph-cache.patch') diff --git a/extra/xorg-server/use-pixman-glyph-cache.patch b/extra/xorg-server/use-pixman-glyph-cache.patch new file mode 100644 index 000000000..c1cd90d3a --- /dev/null +++ b/extra/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 +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 +Reviewed-by: Keith Packard +Signed-off-by: Soren Sandmann +--- +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 -- cgit v1.2.3-54-g00ecf