[cairo] Concerns about using filters for downscaling

Owen Taylor otaylor at redhat.com
Sat Mar 22 09:40:47 PDT 2014

On Sat, 2014-03-22 at 05:26 +0100, Krzysztof Kosiński wrote:
> 2014-03-22 4:26 GMT+01:00 Owen Taylor <otaylor at redhat.com>:
> > On Sat, 2014-03-22 at 03:24 +0100, Krzysztof Kosiński wrote:
> >> This would make Cairo 1.14 completely unusable for Inkscape, so we
> >> would have to postpone the long overdue 0.91 release for another year
> >> or more, and probably stop using Cairo.
> >
> > I don't quite understand this - presumably 0.91 will be the same in this
> > regard as previous versions of Inkscape. Is there some work-around in
> > older Inkscape that you are trying to remove?
> The previous version of Inkscape (0.48) used a completely different
> renderer, not based on Cairo at all, which has been removed. Moving to
> Cairo fixed around 50 long-standing rendering bugs, so going back is
> not really an option.


> >> The downscaling method used in
> >> 1.12 is simply incorrect and due to severe visual artifacts makes it
> >> impossible to use Inkscape to edit drawings that contain large
> >> bitmaps, e.g. photos. It's no use being fast if the result is wrong.
> >
> > Hmm, can you use BEST? That seems to be the right constant to use if you
> > quality is the absolute requirement and performance is secondary.
> Lanczos3 is far too slow for interactive rendering.

I'm not suggesting that you use Lanczos3 - I'm suggesting that you use
the constant BEST, and we make that something that is the best we can do
at a performance level that is "manageably slow" - about what GOOD is
in the current 1.13.x branch. 

> As a compromise, I propose the following mapping:
> BEST = Lanczos3 / Lanczos3
> GOOD = linear / box
> BILINEAR = linear / box
> DEFAULT = linear / impulse
> FAST = nearest / impulse

So DEFAULT isn't actually a constant - it's an internal #define. I'm
pretty sure we want the default state to be a state that is publicly
selectable patterns to start off in some magic state.

Assuming we don't want to add new constants, a variant of your
scheme might be:

           BEST = Lanczos3 / Lanczos3
           GOOD = linear / box
 [default] BILINEAR = linear / impulse
           FAST = nearest / impulse

(linear / impulse presumably implemented as currently rather than with
a convolution.)

There's a number of reasons I think this is non-ideal:

 * The slowdown for BEST with Lanczos3 in 1.13.x is really quite
   extreme. I think it's probably unfair to people who optimistically
   specified it in their code despite it doing the same thing as GOOD to
   slow down their programs by a factor of 50-100x. Yes, it is
   documented as 
   "performance may not be suitable for interactive use"
   but from experience, pointing to wording in docs when people complain
   that you broke their application is not that useful :-)

   If we want to introduce a real non-interactive scaling mode, 
   I think it needs to be a new constant CAIRO_FILTER_EVEN_MORE_BEST or

 * Similarly, people may be specifying GOOD instead
   of leaving filtering at the default state, and slowing that down
   by 5-10x will also be problematical.

   If we *only* slow down BEST by 5-10x, we still might break some
   application, but the set of code we break is much smaller than
   if we slow GOOD by 5-10x and BEST by 50-100x.

 * GOOD is documented to be:

   "A reasonable-performance filter, with quality similar to

   Obviously "reasonable performance" is subjective, but I'd say
   it's defined by what it is currently and we can't make it many
   times slower and say that it's still reasonable performance.

 * Creating large inter-backend differences for the performance and
   quality of GOOD doesn't seem like a good idea to me - if we're
   going to improve GOOD, we should wait until we can do something
   consistent across the common backends.

That's why I prefer the approach I suggested of only changing what
BEST does, and restricting ourselves there to 5-10x slower not 50-100x.

(Søren pointed out on IRC that the pixman implemention of convolution
is not SIMD optimized, so their would be future opportunity to improve
what we can do within the constraints of 5-10x slower.)

The final approach approach would be to extend the filter enumeration
with a specific value for what you want Inkscape - maybe make
CAIRO_FILTER_BOX be the LINEAR/BOX combination. Main downsides are
figuring out what it would do on other backends. Trigger fallbacks?
And having to carry it going forward.

- Owen

More information about the cairo mailing list