]> git.pld-linux.org Git - packages/xorg-xserver-server.git/blame - pixman-cache.patch
- rel 3; use pixman glyph
[packages/xorg-xserver-server.git] / pixman-cache.patch
CommitLineData
a7622652
AM
1commit 9cbcb5bd6a5360a128d15b77a02d8d3351f74366
2Author: Søren Sandmann Pedersen <ssp@redhat.com>
3Date: Wed May 30 05:19:08 2012 -0400
4
5 Use new pixman_glyph_cache_t API that will be in pixman 0.28.0
6
7 This new API allows glyphs to be cached in a data structure in pixman,
8 and entire glyph strings to be composited in one go.
9
10 Also bump pixman dependency to 0.27.2.
11
12 Results from the cairo peformance test suite running against Xvfb with
13 a screen size of 1680x1050@32bpp:
14
15 Speedups
16 ========
17 xlib firefox-talos-gfx 12416.63 -> 3603.93 3.45x speedup
18 ██▌
19 xlib xfce4-terminal-a1 1727.57 -> 1048.85: 1.65x speedup
20
21 xlib evolution 1370.49 -> 869.34: 1.58x speedup
22
23 xlib gnome-terminal-vim 1832.83 -> 1251.94: 1.46x speedup
24
25 xlib poppler 1519.70 -> 1204.05: 1.26x speedup
26
27 xlib firefox-planet-gnome 6982.55 -> 5598.16: 1.25x speedup
28
29 xlib ocitysmap 1142.77 -> 1071.53: 1.07x speedup
30
31
32 No slowdowns were reported.
33
34 Results of x11perf -aa10text:
35
36 Before:
37
38 8000000 reps @ 0.0007 msec (1450000.0/sec)
39 8000000 reps @ 0.0007 msec (1460000.0/sec)
40 8000000 reps @ 0.0007 msec (1460000.0/sec)
41 8000000 reps @ 0.0007 msec (1470000.0/sec)
42 8000000 reps @ 0.0007 msec (1480000.0/sec)
43 40000000 trep @ 0.0007 msec (1460000.0/sec)
44
45 After:
46
47 32000000 reps @ 0.0002 msec (4910000.0/sec)
48 32000000 reps @ 0.0002 msec (4830000.0/sec)
49 32000000 reps @ 0.0002 msec (4890000.0/sec)
50 32000000 reps @ 0.0002 msec (4830000.0/sec)
51 32000000 reps @ 0.0002 msec (4900000.0/sec)
52 160000000 trep @ 0.0002 msec (4870000.0/sec)
53
54 Version 2: Destroy the glyph cache at server regen time
55
56 Acked-by: Aaron Plattner <aplattner@nvidia.com>
57 Reviewed-by: Keith Packard <keithp@keithp.com>
58 Signed-off-by: Soren Sandmann <ssp@redhat.com>
59
60diff --git a/configure.ac b/configure.ac
61index e686614..b6ed92c 100644
62--- a/configure.ac
63+++ b/configure.ac
64@@ -811,7 +811,7 @@ LIBPCIACCESS="pciaccess >= 0.12.901"
65 LIBUDEV="libudev >= 143"
66 LIBSELINUX="libselinux >= 2.0.86"
67 LIBDBUS="dbus-1 >= 1.0"
68-LIBPIXMAN="pixman-1 >= 0.21.8"
69+LIBPIXMAN="pixman-1 >= 0.27.2"
70
71 dnl Pixman is always required, but we separate it out so we can link
72 dnl specific modules against it
73diff --git a/fb/fb.h b/fb/fb.h
74index 75596c5..b869d12 100644
75--- a/fb/fb.h
76+++ b/fb/fb.h
77@@ -1344,6 +1344,9 @@ extern _X_EXPORT void
78 extern _X_EXPORT Bool
79 fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats);
80
81+extern _X_EXPORT void
82+fbDestroyGlyphCache(void);
83+
84 /*
85 * fbpixmap.c
86 */
87diff --git a/fb/fbpict.c b/fb/fbpict.c
88index 097a1a6..2804ff4 100644
89--- a/fb/fbpict.c
90+++ b/fb/fbpict.c
91@@ -70,6 +70,156 @@ fbComposite(CARD8 op,
92 free_pixman_pict(pDst, dest);
93 }
94
95+static pixman_glyph_cache_t *glyphCache;
96+
97+void
98+fbDestroyGlyphCache(void)
99+{
100+ if (glyphCache)
101+ {
102+ pixman_glyph_cache_destroy (glyphCache);
103+ glyphCache = NULL;
104+ }
105+}
106+
107+static void
108+fbUnrealizeGlyph(ScreenPtr pScreen,
109+ GlyphPtr pGlyph)
110+{
111+ if (glyphCache)
112+ pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
113+}
114+
115+static void
116+fbGlyphs(CARD8 op,
117+ PicturePtr pSrc,
118+ PicturePtr pDst,
119+ PictFormatPtr maskFormat,
120+ INT16 xSrc,
121+ INT16 ySrc, int nlist,
122+ GlyphListPtr list,
123+ GlyphPtr *glyphs)
124+{
125+#define N_STACK_GLYPHS 512
126+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
127+ pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
128+ pixman_glyph_t *pglyphs = stack_glyphs;
129+ pixman_image_t *srcImage, *dstImage;
130+ int srcXoff, srcYoff, dstXoff, dstYoff;
131+ GlyphPtr glyph;
132+ int n_glyphs;
133+ int x, y;
134+ int i, n;
135+ int xDst = list->xOff, yDst = list->yOff;
136+
137+ miCompositeSourceValidate(pSrc);
138+
139+ n_glyphs = 0;
140+ for (i = 0; i < nlist; ++i)
141+ n_glyphs += list[i].len;
142+
143+ if (!glyphCache)
144+ glyphCache = pixman_glyph_cache_create();
145+
146+ pixman_glyph_cache_freeze (glyphCache);
147+
148+ if (n_glyphs > N_STACK_GLYPHS) {
149+ if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
150+ goto out;
151+ }
152+
153+ i = 0;
154+ x = y = 0;
155+ while (nlist--) {
156+ x += list->xOff;
157+ y += list->yOff;
158+ n = list->len;
159+ while (n--) {
160+ const void *g;
161+
162+ glyph = *glyphs++;
163+
164+ if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
165+ pixman_image_t *glyphImage;
166+ PicturePtr pPicture;
167+ int xoff, yoff;
168+
169+ pPicture = GetGlyphPicture(glyph, pScreen);
170+ if (!pPicture) {
171+ n_glyphs--;
172+ goto next;
173+ }
174+
175+ if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
176+ goto out;
177+
178+ g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
179+ glyph->info.x,
180+ glyph->info.y,
181+ glyphImage);
182+
183+ free_pixman_pict(pPicture, glyphImage);
184+
185+ if (!g)
186+ goto out;
187+ }
188+
189+ pglyphs[i].x = x;
190+ pglyphs[i].y = y;
191+ pglyphs[i].glyph = g;
192+ i++;
193+
194+ next:
195+ x += glyph->info.xOff;
196+ y += glyph->info.yOff;
197+ }
198+ list++;
199+ }
200+
201+ if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
202+ goto out;
203+
204+ if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
205+ goto out_free_src;
206+
207+ if (maskFormat) {
208+ pixman_format_code_t format;
209+ pixman_box32_t extents;
210+ int x, y;
211+
212+ format = maskFormat->format | (maskFormat->depth << 24);
213+
214+ pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
215+
216+ x = extents.x1;
217+ y = extents.y1;
218+
219+ pixman_composite_glyphs(op, srcImage, dstImage, format,
220+ xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
221+ x, y,
222+ x + dstXoff, y + dstYoff,
223+ extents.x2 - extents.x1,
224+ extents.y2 - extents.y1,
225+ glyphCache, n_glyphs, pglyphs);
226+ }
227+ else {
228+ pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
229+ xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
230+ dstXoff, dstYoff,
231+ glyphCache, n_glyphs, pglyphs);
232+ }
233+
234+ free_pixman_pict(pDst, dstImage);
235+
236+out_free_src:
237+ free_pixman_pict(pSrc, srcImage);
238+
239+out:
240+ pixman_glyph_cache_thaw(glyphCache);
241+ if (pglyphs != stack_glyphs)
242+ free(pglyphs);
243+}
244+
245 static pixman_image_t *
246 create_solid_fill_image(PicturePtr pict)
247 {
248@@ -357,7 +507,8 @@ fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
249 return FALSE;
250 ps = GetPictureScreen(pScreen);
251 ps->Composite = fbComposite;
252- ps->Glyphs = miGlyphs;
253+ ps->Glyphs = fbGlyphs;
254+ ps->UnrealizeGlyph = fbUnrealizeGlyph;
255 ps->CompositeRects = miCompositeRects;
256 ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
257 ps->Trapezoids = fbTrapezoids;
258diff --git a/fb/fbscreen.c b/fb/fbscreen.c
259index 7c7d656..f9080a4 100644
260--- a/fb/fbscreen.c
261+++ b/fb/fbscreen.c
262@@ -32,6 +32,7 @@ fbCloseScreen(ScreenPtr pScreen)
263 int d;
264 DepthPtr depths = pScreen->allowedDepths;
265
266+ fbDestroyGlyphCache();
267 for (d = 0; d < pScreen->numDepths; d++)
268 free(depths[d].vids);
269 free(depths);
This page took 0.148466 seconds and 4 git commands to generate.