<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body text="#000000" bgcolor="#ffffff">
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.<br>
<br>
the pixman patch attached adds one additional api + enum:<br>
<br>
<blockquote><tt>typedef enum</tt><br>
<tt>{</tt><br>
<tt> PIXMAN_COLOR_TOLERANCE_HIGH,</tt><br>
<tt> PIXMAN_COLOR_TOLERANCE_MEDIUM,</tt><br>
<tt> PIXMAN_COLOR_TOLERANCE_LOW</tt><br>
<tt>} pixman_color_tolerance_t;</tt><br>
<br>
<tt>void pixman_image_set_color_tolerance
(pixman_image_t *image,</tt><br>
<tt> pixman_color_tolerance_t
tolerance);</tt><br>
</blockquote>
<tt><br>
<br>
</tt>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.<br>
<br>
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.<br>
<br>
The cairo changes are a bit more invasive. it also has one additional
entry point and enum:<br>
<br>
<blockquote>typedef enum _cairo_color_tolerance_level {<br>
CAIRO_COLOR_TOLERANCE_HIGH,<br>
CAIRO_COLOR_TOLERANCE_MEDIUM,<br>
CAIRO_COLOR_TOLERANCE_LOW,<br>
} cairo_color_tolerance_t;<br>
<br>
cairo_public void<br>
cairo_pattern_set_color_tolerance (cairo_pattern_t *pattern,<br>
cairo_color_tolerance_t tolerance);<br>
</blockquote>
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.<br>
<br>
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).<br>
<br>
I think there's definitely more room for improvement, but this seems
like a good start.<br>
<br>
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.<br>
<br>
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.<br>
<br>
Chris<br>
<br>
<tt>[ # ] backend.content
test-size min(ticks) min(ms) median(ms) stddev. iterations
%-runtime<br>
<br>
[ 0] image.rgba big_radial-extend=NONE-tolerance=LOW.1024
593184422 593.184 593.479 0.10% 7 100%<br>
[ 1] image.rgba big_radial-extend=NONE-tolerance=MEDIUM.1024
292892298 292.892 293.004 0.03% 5 49.3%<br>
[ 2] image.rgba big_radial-extend=NONE-tolerance=HIGH.1024
292767094 292.767 292.882 0.05% 5 49.4%<br>
<br>
[ 3] image.rgba big_radial-extend=REPEAT-tolerance=LOW.1024
588661429 588.661 588.726 0.11% 5 100%<br>
[ 4] image.rgba big_radial-extend=REPEAT-tolerance=MEDIUM.1024
320540434 320.540 320.887 0.06% 5 54.4%<br>
[ 5] image.rgba big_radial-extend=REPEAT-tolerance=HIGH.1024
320151335 320.151 320.860 0.10% 5 54.5%<br>
<br>
[ 6] image.rgba big_radial-extend=REFLECT-tolerance=LOW.1024
588736760 588.737 589.199 0.13% 5 100%<br>
[ 7] image.rgba big_radial-extend=REFLECT-tolerance=MEDIUM.1024
285262562 285.263 288.178 0.61% 5 48.9%<br>
[ 8] image.rgba big_radial-extend=REFLECT-tolerance=HIGH.1024
284513347 284.513 284.897 0.22% 5 48.4%<br>
<br>
[ 9] image.rgba big_radial-extend=PAD-tolerance=LOW.1024
589746044 589.746 589.985 0.02% 3 100%<br>
[ 10] image.rgba big_radial-extend=PAD-tolerance=MEDIUM.1024
287017085 287.017 287.908 0.45% 5 48.8%<br>
[ 11] image.rgba big_radial-extend=PAD-tolerance=HIGH.1024
287350517 287.351 289.304 0.34% 5 49.0%<br>
<br>
[ 12] image.rgba
big_linear-vert-extend=NONE-tolerance=LOW.1024 5423419
5.423 5.601 1.47% 5 100%<br>
[ 13] image.rgba
big_linear-vert-extend=NONE-tolerance=MEDIUM.1024 5364000
5.364 5.377 0.17% 5 96.0%<br>
[ 14] image.rgba
big_linear-vert-extend=NONE-tolerance=HIGH.1024 5347908
5.348 5.350 0.03% 4 95.5%<br>
<br>
[ 15] image.rgba
big_linear-vert-extend=REPEAT-tolerance=LOW.1024 5323739
5.324 5.376 2.81% 66 100%<br>
[ 16] image.rgba
big_linear-vert-extend=REPEAT-tolerance=MEDIUM.1024 5270748
5.271 5.295 0.40% 7 98.5%<br>
[ 17] image.rgba
big_linear-vert-extend=REPEAT-tolerance=HIGH.1024 5250651
5.251 5.258 0.13% 5 97.8%<br>
<br>
[ 18] image.rgba
big_linear-vert-extend=REFLECT-tolerance=LOW.1024 5337249
5.337 5.343 0.11% 5 100%<br>
[ 19] image.rgba
big_linear-vert-extend=REFLECT-tolerance=MEDIUM.1024 5291639
5.292 5.293 0.06% 4 99.0%<br>
[ 20] image.rgba
big_linear-vert-extend=REFLECT-tolerance=HIGH.1024 5250729
5.251 5.270 0.19% 4 98.6%<br>
<br>
[ 21] image.rgba
big_linear-vert-extend=PAD-tolerance=LOW.1024 5490188
5.490 5.571 1.45% 5 100%<br>
[ 22] image.rgba
big_linear-vert-extend=PAD-tolerance=MEDIUM.1024 5438604
5.439 5.502 0.76% 5 98.8%<br>
[ 23] image.rgba
big_linear-vert-extend=PAD-tolerance=HIGH.1024 5287995
5.288 5.496 2.20% 5 98.7%<br>
<br>
[ 24] image.rgba
big_linear-horiz-extend=NONE-tolerance=LOW.1024 7698942
7.699 7.722 0.18% 4 100%<br>
[ 25] image.rgba
big_linear-horiz-extend=NONE-tolerance=MEDIUM.1024 7587441
7.587 7.675 0.53% 5 99.4%<br>
[ 26] image.rgba
big_linear-horiz-extend=NONE-tolerance=HIGH.1024 7599917
7.600 7.623 0.17% 4 98.7%<br>
<br>
[ 27] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=LOW.1024 10960624
10.961 11.066 1.20% 5 100%<br>
[ 28] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=MEDIUM.1024 10498111
10.498 11.107 2.39% 8 100.3%<br>
[ 29] image.rgba
big_linear-horiz-extend=REPEAT-tolerance=HIGH.1024 10709473
10.709 10.904 1.11% 5 98.5%<br>
<br>
[ 30] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=LOW.1024 11017285
11.017 11.196 1.12% 5 100%<br>
[ 31] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=MEDIUM.1024 10752350
10.752 10.775 0.11% 3 96.2%<br>
[ 32] image.rgba
big_linear-horiz-extend=REFLECT-tolerance=HIGH.1024 10510170
10.510 10.993 2.05% 5 98.2%<br>
<br>
[ 33] image.rgba
big_linear-horiz-extend=PAD-tolerance=LOW.1024 11356190
11.356 11.493 0.79% 8 100%<br>
[ 34] image.rgba
big_linear-horiz-extend=PAD-tolerance=MEDIUM.1024 10800220
10.800 10.879 2.00% 5 94.7%<br>
[ 35] image.rgba
big_linear-horiz-extend=PAD-tolerance=HIGH.1024 10711228
10.711 10.868 0.80% 5 94.6%<br>
</tt><br>
</body>
</html>