]> git.pld-linux.org Git - packages/xorg-xserver-server.git/blob - pixman-cache.patch
2ec672b103448d9e50ad66731b320c0a43d628b4
[packages/xorg-xserver-server.git] / pixman-cache.patch
1 commit 9cbcb5bd6a5360a128d15b77a02d8d3351f74366
2 Author: Søren Sandmann Pedersen <ssp@redhat.com>
3 Date:   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
60 diff --git a/configure.ac b/configure.ac
61 index 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
73 diff --git a/fb/fb.h b/fb/fb.h
74 index 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   */
87 diff --git a/fb/fbpict.c b/fb/fbpict.c
88 index 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;
258 diff --git a/fb/fbscreen.c b/fb/fbscreen.c
259 index 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.044714 seconds and 2 git commands to generate.