]> git.cworth.org Git - cworth.org/blob - src/exa/storing_glyphs_as_pixmaps.mdwn
Convert prefix directives to new syntax.
[cworth.org] / src / exa / storing_glyphs_as_pixmaps.mdwn
1 [[!meta title="Storing glyphs as Pixmaps"]]
2
3 [[!tag exa performance xorg]]
4
5 A few months ago I reached the conclusion that remaining cairo
6 performance problems were largely not in the cairo library itself, but
7 were in the X server, its acceleration architectures, or in the X
8 drivers for specific devices. So I started measuring with the
9 cairo-perf suite of micro-benchmarks and I identified what appeared to
10 be some [potential
11 problems](http://lists.freedesktop.org/archives/xorg/2007-April/024094.html). For
12 example, there are OVER operations that should degenerate into simple
13 blits but that seem to be running 2x slower than blits, (more on this
14 later).
15
16 Before pursuing those in detail, (or after chasing a
17 [non-problem](http://cworth.org/exa/mystery_solved/) for too long), I
18 decided to step back from micro benchmarks and instead look at some
19 [real-world tests](http://cworth.org/exa/mozilla_trender/) with the
20 Mozilla Trender suite to ensure I wasn't doing micro-optimization that
21 wouldn't have any significant impact. It was at that time that I also
22 switched my focus from an ATI r100, (which was just the graphics chip
23 that happened to be in my laptop), to looking at the Intel 965 chip
24 instead, (since Intel had donated one for me to work with).
25
26 The i965 is interesting because it's new, (ooh, shiny!), and coming
27 from a company that actually supports the free software community by
28 providing free software drivers. That support continues to improve as
29 last week, Intel made technical documentation on the i965 available to
30 myself and other Red Hat employees. (The documentation was made
31 available under an existing Intel-Red Hat NDA which means I cannot
32 share the documentation, but I can use the documentation to write,
33 improve, and release free-software drivers.) I'm optimistic that Intel
34 will be willing to setup a similar NDA with anyone interested in
35 improving the drivers, and even better, that Intel will eventually
36 convince itself it can share the documentation as freely as it is
37 currently sharing its driver source code.
38
39 And actually, the work I've done in the last week hasn't strictly
40 required the documentation at all. What has been necessary is to roll
41 up my sleeves and get more familiar with the X server source code. I'm
42 really grateful to Keith Packard, Eric Anholt, Dave Airlie, Kevin
43 Martin, Michel Dänzer, Adam Jackson, Daniel Stone and others who have
44 helped me get started here. There's really a very welcoming community
45 of very intelligent people around the X server who are glad to help
46 guide new people who want to help. And there's no shortage of things
47 that can be done.
48
49 It is a large code base to get familiar with, (using "git grep" to
50 find things helps a lot). And, being as old as it is, it does have
51 lots of "moldy" aspects to the way it's coded, but it's not as bad as
52 one might fear. So please, come join us if you're interested!
53
54 Guided by the problems showcased by the Mozilla test suite and the
55 i965 driver, I decided that the most obviously underperforming
56 operation is glyph compositing. And I also identified two
57 [underlying problems](http://cworth.org/exa/i965/emulating_speedups/):
58 excessive migration and synchronous compositing.
59
60 With the problems identified that concretely, I'm actually working on
61 fixing problems now instead of just reporting them. And for this
62 focused work, it makes sense to get back to micro-benchmarks for
63 tracking the specific things I'm working on. So I started out with
64 "x11perf -aa10text" to test glyph compositing performance. A more
65 general operation than glyph compositing is image compositing, but it
66 seems that x11perf has never acquired any Render-based image
67 compositing benchmarks, (maybe that explains why some compositing
68 performance regressions went unnoticed?). I did convince Keith to sit
69 down and write some x11perf-based compositing tests, which I expect
70 he'll push out shortly. And those tests should do a great job of
71 highlighting the problems I seemed to see with cairo-perf where
72 compositing with Over wasn't properly degenerating to blit performance
73 when there is no source alpha.
74
75 In exchange, Keith convinced me to do some work to change the way
76 glyph images are stored in the X server. Previously, glyph images have
77 been chunks of system memory, which means they were off-limits for
78 being used as part of any accelerated rendering. What EXA would do, is
79 every time a glyph was to be rendered, it would first copy it into a
80 video-memory Pixmap so that it could have some hope of accelerating
81 it. So the same glyph data would get copied from system memory to
82 video memory over and over again, (and likely overwhelm any
83 performance advantage from doing "accelerated" compositing with the
84 glyphs).
85
86 A fairly obvious solution is to move the canonical location for glyph
87 data to be video-memory Pixmaps in the first place. This has a few
88 potential problems:
89
90  1. Glyph images are sharable across the entire server, but Pixmaps
91     are specific to each individual "screen" within the server.
92
93  2. The X server uses the system-memory glyph data to compare when a
94     glyph is uploaded by a client that is identical to a glyph
95     uploaded previously by another client, (using a simple XOR-based
96     hash to do fewer comparisons---but always falling back to a full
97     compare after matching the hash).
98
99  3. Recent work that Dave Airlie, Kristian Høgsberg, and Eric Anholt
100     have been doing may result in there being a one-to-one
101     relationship between Pixmaps and "buffer objects". And these
102     buffer objects require page-alignment, so their minimal size will
103     be 4k, (which could be quite excessive for small, 10x10 glyph).
104
105 Another concern before any of those is whether glyphs are even worth
106 trying to accelerate in the first place. If they are small enough,
107 might the overhead of involving the GPU be excessive and it would be
108 better to simply let the CPU render them, (even if that requires some
109 read-modify-write for the compositing)? For this concern, see the
110 window-to-window copy results I just posted in
111 [[what_exa_gets_right]]. That shows that EXA (GPU based) copying can
112 be 5x faster that NoAccel (CPU based) even with regions as small as
113 10x10. Add compositing to that, and the GPU should be just as fast,
114 but the CPU should be slower. So we really should be able to win, even
115 with fairly tiny glyphs.
116
117 So, how to tackle the other technical problems. Here's what I've come
118 up with so far:
119
120  1. Per-screen Pixmaps: Suck it up for now. One, actually having
121     multiple "screens" in the X server isn't common. Things like
122     Xinerama that use one "screen" for multiple displays are much more
123     common. So, I've written code that allocates one Pixmap per screen
124     for every glyph. If this turns out to be a problem in practice, it
125     would be quite trivial to create the Pixmaps lazily for all but
126     one screen. And it would also be worthwhile, (but a much larger
127     change), to lift the per-screen restriction for objects like Pixmaps.
128
129  2. System-memory data for avoiding hash collisions: The goal is to
130     move the storage from system memory to a video-memory Pixmap. We
131     lose, (by spending excess memory), if we still have to keep a
132     system-memory image. To fix this, I've replaced the weak XOR-based
133     hash with a cryptographically strong hash (SHA1) that will be
134     (probabilistically) collision free. This does introduce a new
135     dependency of the X server on the openssl library.
136
137  3. 4k alignment constraints for buffer objects: This is likely a very
138     real issue, but something I'd like to address later. Presumably we
139     can alleviate the problem by pooling multiple glyphs within a
140     single Pixmap, (or multiple Pixmaps within a single buffer
141     object), or whatever necessary.
142
143 So, given those approaches, I've written a [series of 7
144 patches](http://gitweb.freedesktop.org/?p=users/cworth/xserver;a=shortlog;h=glyph-pixmaps)
145 implementing glyph storage as pixmaps.
146
147 On my i965 the patch series doesn't impact NoAccel or XAA performance
148 considerably, but does improve EXA performance a bit. Here are the
149 results for x11perf -aa10text and -aa24text:
150
151 [[glyph-pixmaps-aa10.png]]
152
153 [[glyph-pixmaps-aa24.png]]
154
155 Now, that was quite a bit of work, (and way too long of a blog post
156 already), but not yet any *huge* performance improvement. But I think
157 this is a good, and necessary step toward getting to fast compositing
158 of glyphs. Here are before-and-after performance charts for the
159 aa10text test with links to profiles:
160
161 <dl class="chart barchart">
162     <dt><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//system.oprofile">EXA-aa10text-before/</a> <a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//system.symbols">symbols profile</a></dt>
163     <dd style="width:100%;">
164         <ul>
165             <li class="vmlinux" style="width:30.8019%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//vmlinux.oprofile">vmlinux</a><span>31%</span></li>
166             <li class="libpixman" style="width:27.5861%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//libpixman.oprofile">libpixman</a><span>28%</span></li>
167             <li class="libc-2_5" style="width:12.3146%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//libc-2.5.oprofile">libc-2.5</a><span>12%</span></li>
168             <li class="libexa" style="width:11.8546%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//libexa.oprofile">libexa</a><span>12%</span></li>
169             <li class="Xorg" style="width:4.5072%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//Xorg.oprofile">Xorg</a><span>5%</span></li>
170             <li class="libfb" style="width:3.5515%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//libfb.oprofile">libfb</a><span>4%</span></li>
171             <li class="oprofiled" style="width:3.1117%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//oprofiled.oprofile">oprofiled</a><span>3%</span></li>
172             <li class="intel_drv" style="width:2.4672%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//intel_drv.oprofile">intel_drv</a><span>2%</span></li>
173             <li class="other" style="width:3.8052%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-before//other.oprofile">other</a><span>4%</span></li>
174         </ul>
175     </dd>
176     <dt><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//system.oprofile">EXA-aa10text-glyph-pixmaps/</a> <a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//system.symbols">symbols profile</a></dt>
177     <dd style="width:76.1658%;">
178         <ul>
179             <li class="libpixman" style="width:34.1057%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//libpixman.oprofile">libpixman</a><span>34%</span></li>
180             <li class="vmlinux" style="width:27.3427%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//vmlinux.oprofile">vmlinux</a><span>27%</span></li>
181             <li class="libexa" style="width:11.4250%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//libexa.oprofile">libexa</a><span>11%</span></li>
182             <li class="libc-2_5" style="width:10.9705%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//libc-2.5.oprofile">libc-2.5</a><span>11%</span></li>
183             <li class="Xorg" style="width:4.5651%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//Xorg.oprofile">Xorg</a><span>5%</span></li>
184             <li class="oprofiled" style="width:3.3481%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//oprofiled.oprofile">oprofiled</a><span>3%</span></li>
185             <li class="intel_drv" style="width:2.5036%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//intel_drv.oprofile">intel_drv</a><span>3%</span></li>
186             <li class="other" style="width:5.7393%;"><a href="file:///srv/cworth.org/www/exa/storing_glyphs_as_pixmaps/EXA-aa10text-glyph-pixmaps//other.oprofile">other</a><span>6%</span></li>
187         </ul>
188     </dd>
189 </dl>
190
191 We can see that some copying was eliminated, (note the fbBlt
192 contribution to libfb in the before profile has disappeared
193 completely). But there's still some migration going on somewhere, (see
194 the exaMemCpyBox stuff as well as a bunch of software rendering
195 happening in pixman). The assumption I'm operating on is that we
196 should be able to eliminate migration and software rendering
197 entirely. The hardware is very capable, very flexible and
198 programmable, and we have all the programming documentation. So there
199 should just be a little work here to see what's still falling back to
200 software and eliminating it.
201
202 Then, obviously, there's still the synchronous compositing
203 problem. I'm guessing that's where the big time spent in the kernel is
204 coming from. So imagine half of the pixman and kernel chunks going
205 away, along with 25% of the libexa chunk and over half of libc, (that
206 looks like the obvious hotspots from excessive migration synchronous
207 compositing). And then EXA text would at least catch up to XAA and
208 NoAccel.
209
210 But if we only match the performance, we're wasting our time and
211 should just use the NoAccel code paths in the first place. But I'm
212 optimistic that there's still quite a bit of optimization that could
213 happen after that. We'll see of course.