[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