[cairo] [PATCHES] gradient color-tolerance/performance work
Chris Toshok
toshok at gmail.com
Mon Apr 5 21:58:44 PDT 2010
I've been working the past couple days on getting skia-like color lookup
tables into pixman, and the approach seems to have met with a measure of
success.
the pixman patch attached adds one additional api + enum:
typedef enum
{
PIXMAN_COLOR_TOLERANCE_HIGH,
PIXMAN_COLOR_TOLERANCE_MEDIUM,
PIXMAN_COLOR_TOLERANCE_LOW
} pixman_color_tolerance_t;
void pixman_image_set_color_tolerance
(pixman_image_t *image,
pixman_color_tolerance_t tolerance);
which is defined only for gradient images. TOLERANCE_LOW (the default)
gives the existing pixman behavior, and MEDIUM/LOW use the lookup
tables. They differ only in the number of colors allocated in the
tables: LOW is basically skia's implementation, at 256 colors, and
MEDIUM holds 512 colors. They both seem to offer roughly the same
performance in my tests, so the only difference between them is
(possibly, more later) visual, and 2x the memory.
I had originally inlined the color_cache lookup code directly in
radial_gradient_get_scanline_32, but in the interest of sharing it
across the other gradient types, moved it to pixman-gradient-walker.c.
This caused a 20% drop in performance, so I switched to
#including/inlining pixman-gradient-walker into each of the gradient
files, which brought the performance back up.
The cairo changes are a bit more invasive. it also has one additional
entry point and enum:
typedef enum _cairo_color_tolerance_level {
CAIRO_COLOR_TOLERANCE_HIGH,
CAIRO_COLOR_TOLERANCE_MEDIUM,
CAIRO_COLOR_TOLERANCE_LOW,
} cairo_color_tolerance_t;
cairo_public void
cairo_pattern_set_color_tolerance (cairo_pattern_t *pattern,
cairo_color_tolerance_t tolerance);
but there are a number of other changes which basically treat
pixman_images (at least those corresponding to gradients) as things that
should live a long time. Turns out cairo creates and destroys a *lot*
of pixman images, so much so that it was killing the performance gained
by the color cache. This also means that applications/tests will need
to keep patterns alive longer, or at least they might want to if they're
using MEDIUM/LOW tolerances.
The cairo patch includes a new perf/ test (big_gradients.c) which shows
the performance changes pretty well. Below is a run of the full suite
on my laptop. I had problems with the tests causing the cpu to drop
from 2.2GHz to 800Mhz over the course of the run, so I just pegged it at
800Mhz and ran the entire suite that way (hence the huge numbers).
I think there's definitely more room for improvement, but this seems
like a good start.
I would *love* comments/critiques, especially as this is something the
moonlight team would like to see in some form in future versions
pixman/cairo, as radial gradients are definitely killing us now.
Oh, about visual differences between LOW/MEDIUM. I was futzing with the
pixman gradient-test.c (the results of which should be in the patch) in
the hopes of creating a gradient that would cause visual differences
between LOW/MEDIUM (and indeed, between LOW/HIGH), but gave up after a
while. I'm thinking a large pixel range for a gradient filled coupled
with a lot of color stops might be the key, but I haven't noticed any
bad banding or anything.
Chris
[ # ] backend.content test-size
min(ticks) min(ms) median(ms) stddev. iterations %-runtime
[ 0] image.rgba big_radial-extend=NONE-tolerance=LOW.1024
593184422 593.184 593.479 0.10% 7 100%
[ 1] image.rgba big_radial-extend=NONE-tolerance=MEDIUM.1024
292892298 292.892 293.004 0.03% 5 49.3%
[ 2] image.rgba big_radial-extend=NONE-tolerance=HIGH.1024
292767094 292.767 292.882 0.05% 5 49.4%
[ 3] image.rgba big_radial-extend=REPEAT-tolerance=LOW.1024
588661429 588.661 588.726 0.11% 5 100%
[ 4] image.rgba big_radial-extend=REPEAT-tolerance=MEDIUM.1024
320540434 320.540 320.887 0.06% 5 54.4%
[ 5] image.rgba big_radial-extend=REPEAT-tolerance=HIGH.1024
320151335 320.151 320.860 0.10% 5 54.5%
[ 6] image.rgba big_radial-extend=REFLECT-tolerance=LOW.1024
588736760 588.737 589.199 0.13% 5 100%
[ 7] image.rgba big_radial-extend=REFLECT-tolerance=MEDIUM.1024
285262562 285.263 288.178 0.61% 5 48.9%
[ 8] image.rgba big_radial-extend=REFLECT-tolerance=HIGH.1024
284513347 284.513 284.897 0.22% 5 48.4%
[ 9] image.rgba big_radial-extend=PAD-tolerance=LOW.1024
589746044 589.746 589.985 0.02% 3 100%
[ 10] image.rgba big_radial-extend=PAD-tolerance=MEDIUM.1024
287017085 287.017 287.908 0.45% 5 48.8%
[ 11] image.rgba big_radial-extend=PAD-tolerance=HIGH.1024
287350517 287.351 289.304 0.34% 5 49.0%
[ 12] image.rgba
big_linear-vert-extend=NONE-tolerance=LOW.1024 5423419 5.423
5.601 1.47% 5 100%
[ 13] image.rgba
big_linear-vert-extend=NONE-tolerance=MEDIUM.1024 5364000 5.364
5.377 0.17% 5 96.0%
[ 14] image.rgba
big_linear-vert-extend=NONE-tolerance=HIGH.1024 5347908 5.348
5.350 0.03% 4 95.5%
[ 15] image.rgba
big_linear-vert-extend=REPEAT-tolerance=LOW.1024 5323739 5.324
5.376 2.81% 66 100%
[ 16] image.rgba
big_linear-vert-extend=REPEAT-tolerance=MEDIUM.1024 5270748 5.271
5.295 0.40% 7 98.5%
[ 17] image.rgba
big_linear-vert-extend=REPEAT-tolerance=HIGH.1024 5250651 5.251
5.258 0.13% 5 97.8%
[ 18] image.rgba
big_linear-vert-extend=REFLECT-tolerance=LOW.1024 5337249 5.337
5.343 0.11% 5 100%
[ 19] image.rgba
big_linear-vert-extend=REFLECT-tolerance=MEDIUM.1024 5291639 5.292
5.293 0.06% 4 99.0%
[ 20] image.rgba
big_linear-vert-extend=REFLECT-tolerance=HIGH.1024 5250729 5.251
5.270 0.19% 4 98.6%
[ 21] image.rgba
big_linear-vert-extend=PAD-tolerance=LOW.1024 5490188 5.490
5.571 1.45% 5 100%
[ 22] image.rgba
big_linear-vert-extend=PAD-tolerance=MEDIUM.1024 5438604 5.439
5.502 0.76% 5 98.8%
[ 23] image.rgba
big_linear-vert-extend=PAD-tolerance=HIGH.1024 5287995 5.288
5.496 2.20% 5 98.7%
[ 24] image.rgba
big_linear-horiz-extend=NONE-tolerance=LOW.1024 7698942 7.699
7.722 0.18% 4 100%
[ 25] image.rgba
big_linear-horiz-extend=NONE-tolerance=MEDIUM.1024 7587441 7.587
7.675 0.53% 5 99.4%
[ 26] image.rgba
big_linear-horiz-extend=NONE-tolerance=HIGH.1024 7599917 7.600
7.623 0.17% 4 98.7%
[ 27] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=LOW.1024 10960624 10.961
11.066 1.20% 5 100%
[ 28] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=MEDIUM.1024 10498111 10.498
11.107 2.39% 8 100.3%
[ 29] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=HIGH.1024 10709473 10.709
10.904 1.11% 5 98.5%
[ 30] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=LOW.1024 11017285
11.017 11.196 1.12% 5 100%
[ 31] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=MEDIUM.1024 10752350
10.752 10.775 0.11% 3 96.2%
[ 32] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=HIGH.1024 10510170
10.510 10.993 2.05% 5 98.2%
[ 33] image.rgba
big_linear-horiz-extend=PAD-tolerance=LOW.1024 11356190
11.356 11.493 0.79% 8 100%
[ 34] image.rgba
big_linear-horiz-extend=PAD-tolerance=MEDIUM.1024 10800220
10.800 10.879 2.00% 5 94.7%
[ 35] image.rgba
big_linear-horiz-extend=PAD-tolerance=HIGH.1024 10711228
10.711 10.868 0.80% 5 94.6%
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20100405/6bf63fb2/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pixman-gradient-work.diff
Type: text/x-patch
Size: 33058 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20100405/6bf63fb2/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cairo-gradient-work.diff
Type: text/x-patch
Size: 28786 bytes
Desc: not available
URL: <http://lists.cairographics.org/archives/cairo/attachments/20100405/6bf63fb2/attachment-0003.bin>
More information about the cairo
mailing list