<!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>&nbsp; PIXMAN_COLOR_TOLERANCE_HIGH,</tt><br>
  <tt>&nbsp; PIXMAN_COLOR_TOLERANCE_MEDIUM,</tt><br>
  <tt>&nbsp; PIXMAN_COLOR_TOLERANCE_LOW</tt><br>
  <tt>} pixman_color_tolerance_t;</tt><br>
  <br>
  <tt>void&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pixman_image_set_color_tolerance&nbsp;&nbsp;&nbsp;&nbsp;
(pixman_image_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *image,</tt><br>
  <tt>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pixman_color_tolerance_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
tolerance);</tt><br>
</blockquote>
<tt><br>
<br>
</tt>which is defined only for gradient images.&nbsp; TOLERANCE_LOW (the
default) gives the existing pixman behavior, and MEDIUM/LOW use the
lookup tables.&nbsp; They differ only in the number of colors allocated in
the tables:&nbsp; LOW is basically skia's implementation, at 256 colors, and
MEDIUM holds 512 colors.&nbsp; 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.&nbsp;
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.&nbsp; it also has one additional
entry point and enum:<br>
<br>
<blockquote>typedef enum _cairo_color_tolerance_level {<br>
&nbsp;&nbsp;&nbsp; CAIRO_COLOR_TOLERANCE_HIGH,<br>
&nbsp;&nbsp;&nbsp; CAIRO_COLOR_TOLERANCE_MEDIUM,<br>
&nbsp;&nbsp;&nbsp; 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>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 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.&nbsp; 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.&nbsp; 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.&nbsp; Below is a run of the full suite
on my laptop.&nbsp; 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.&nbsp; 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.&nbsp; 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>[ # ]&nbsp; backend.content&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
test-size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; min(ticks)&nbsp; min(ms) median(ms) stddev. iterations&nbsp;
%-runtime<br>
<br>
[&nbsp; 0]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=NONE-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
593184422&nbsp; 593.184&nbsp; 593.479&nbsp; 0.10%&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[&nbsp; 1]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=NONE-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
292892298&nbsp; 292.892&nbsp; 293.004&nbsp; 0.03%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 49.3%<br>
[&nbsp; 2]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=NONE-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
292767094&nbsp; 292.767&nbsp; 292.882&nbsp; 0.05%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 49.4%<br>
<br>
[&nbsp; 3]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REPEAT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
588661429&nbsp; 588.661&nbsp; 588.726&nbsp; 0.11%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[&nbsp; 4]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REPEAT-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;&nbsp;
320540434&nbsp; 320.540&nbsp; 320.887&nbsp; 0.06%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 54.4%<br>
[&nbsp; 5]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REPEAT-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
320151335&nbsp; 320.151&nbsp; 320.860&nbsp; 0.10%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 54.5%<br>
<br>
[&nbsp; 6]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REFLECT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
588736760&nbsp; 588.737&nbsp; 589.199&nbsp; 0.13%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[&nbsp; 7]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REFLECT-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;
285262562&nbsp; 285.263&nbsp; 288.178&nbsp; 0.61%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 48.9%<br>
[&nbsp; 8]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=REFLECT-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
284513347&nbsp; 284.513&nbsp; 284.897&nbsp; 0.22%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 48.4%<br>
<br>
[&nbsp; 9]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=PAD-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
589746044&nbsp; 589.746&nbsp; 589.985&nbsp; 0.02%&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 10]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=PAD-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 287017085&nbsp; 287.017&nbsp; 287.908&nbsp; 0.45%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 48.8%<br>
[ 11]&nbsp;&nbsp;&nbsp; image.rgba&nbsp; big_radial-extend=PAD-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; 287350517&nbsp; 287.351&nbsp; 289.304&nbsp; 0.34%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 49.0%<br>
<br>
[ 12]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=NONE-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5423419&nbsp;&nbsp;&nbsp;
5.423&nbsp;&nbsp;&nbsp; 5.601&nbsp; 1.47%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 13]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=NONE-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp; 5364000&nbsp;&nbsp;&nbsp;
5.364&nbsp;&nbsp;&nbsp; 5.377&nbsp; 0.17%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 96.0%<br>
[ 14]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=NONE-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5347908&nbsp;&nbsp;&nbsp;
5.348&nbsp;&nbsp;&nbsp; 5.350&nbsp; 0.03%&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 95.5%<br>
<br>
[ 15]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REPEAT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp; 5323739&nbsp;&nbsp;&nbsp;
5.324&nbsp;&nbsp;&nbsp; 5.376&nbsp; 2.81%&nbsp; 66&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 16]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REPEAT-tolerance=MEDIUM.1024&nbsp; 5270748&nbsp;&nbsp;&nbsp;
5.271&nbsp;&nbsp;&nbsp; 5.295&nbsp; 0.40%&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp; 98.5%<br>
[ 17]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REPEAT-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp; 5250651&nbsp;&nbsp;&nbsp;
5.251&nbsp;&nbsp;&nbsp; 5.258&nbsp; 0.13%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 97.8%<br>
<br>
[ 18]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REFLECT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp; 5337249&nbsp;&nbsp;&nbsp;
5.337&nbsp;&nbsp;&nbsp; 5.343&nbsp; 0.11%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 19]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REFLECT-tolerance=MEDIUM.1024 5291639&nbsp;&nbsp;&nbsp;
5.292&nbsp;&nbsp;&nbsp; 5.293&nbsp; 0.06%&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 99.0%<br>
[ 20]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=REFLECT-tolerance=HIGH.1024&nbsp;&nbsp; 5250729&nbsp;&nbsp;&nbsp;
5.251&nbsp;&nbsp;&nbsp; 5.270&nbsp; 0.19%&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 98.6%<br>
<br>
[ 21]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=PAD-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5490188&nbsp;&nbsp;&nbsp;
5.490&nbsp;&nbsp;&nbsp; 5.571&nbsp; 1.45%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 22]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=PAD-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;&nbsp; 5438604&nbsp;&nbsp;&nbsp;
5.439&nbsp;&nbsp;&nbsp; 5.502&nbsp; 0.76%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 98.8%<br>
[ 23]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-vert-extend=PAD-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5287995&nbsp;&nbsp;&nbsp;
5.288&nbsp;&nbsp;&nbsp; 5.496&nbsp; 2.20%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 98.7%<br>
<br>
[ 24]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=NONE-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7698942&nbsp;&nbsp;&nbsp;
7.699&nbsp;&nbsp;&nbsp; 7.722&nbsp; 0.18%&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 25]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=NONE-tolerance=MEDIUM.1024&nbsp;&nbsp; 7587441&nbsp;&nbsp;&nbsp;
7.587&nbsp;&nbsp;&nbsp; 7.675&nbsp; 0.53%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 99.4%<br>
[ 26]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=NONE-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp; 7599917&nbsp;&nbsp;&nbsp;
7.600&nbsp;&nbsp;&nbsp; 7.623&nbsp; 0.17%&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp; 98.7%<br>
<br>
[ 27]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REPEAT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp; 10960624&nbsp;&nbsp;
10.961&nbsp;&nbsp; 11.066&nbsp; 1.20%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp; 100%<br>
[ 28]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REPEAT-tolerance=MEDIUM.1024 10498111&nbsp;&nbsp;
10.498&nbsp;&nbsp; 11.107&nbsp; 2.39%&nbsp;&nbsp; 8&nbsp;&nbsp; 100.3%<br>
[ 29]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REPEAT-tolerance=HIGH.1024&nbsp;&nbsp; 10709473&nbsp;&nbsp;
10.709&nbsp;&nbsp; 10.904&nbsp; 1.11%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp; 98.5%<br>
<br>
[ 30]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REFLECT-tolerance=LOW.1024&nbsp;&nbsp;&nbsp; 11017285&nbsp;&nbsp;
11.017&nbsp;&nbsp; 11.196&nbsp; 1.12%&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp; 100%<br>
[ 31]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REFLECT-tolerance=MEDIUM.1024 10752350&nbsp;&nbsp;
10.752&nbsp;&nbsp; 10.775&nbsp; 0.11%&nbsp;&nbsp; 3&nbsp;&nbsp; 96.2%<br>
[ 32]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=REFLECT-tolerance=HIGH.1024&nbsp;&nbsp; 10510170&nbsp;&nbsp;
10.510&nbsp;&nbsp; 10.993&nbsp; 2.05%&nbsp;&nbsp; 5&nbsp;&nbsp; 98.2%<br>
<br>
[ 33]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=PAD-tolerance=LOW.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11356190&nbsp;&nbsp;
11.356&nbsp;&nbsp; 11.493&nbsp; 0.79%&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp; 100%<br>
[ 34]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=PAD-tolerance=MEDIUM.1024&nbsp;&nbsp;&nbsp;&nbsp; 10800220&nbsp;&nbsp;
10.800&nbsp;&nbsp; 10.879&nbsp; 2.00%&nbsp;&nbsp; 5&nbsp;&nbsp; 94.7%<br>
[ 35]&nbsp;&nbsp;&nbsp; image.rgba&nbsp;
big_linear-horiz-extend=PAD-tolerance=HIGH.1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10711228&nbsp;&nbsp;
10.711&nbsp;&nbsp; 10.868&nbsp; 0.80%&nbsp;&nbsp; 5&nbsp;&nbsp; 94.6%<br>
</tt><br>
</body>
</html>