[cairo] downscaling capabilities
frederic.plourde at polymtl.ca
Mon Apr 21 09:58:21 PDT 2008
I'm globally not in favor of using non-power-of-two integer scales for
mipmaping interpolation. The reason is simple : it's the good old memory
/ quality / speed tradeoff.
If you plan on using non-powers-of-two integer scales, then you cannot
really pre-calculate every possible mipmap levels that you would need
every time you wanna scale.. Hence, meaning that you're going to need to
compute the required mipmaps every single time that your scale factors
change by more than 1. (And remeber here, the mipmaps are prefiltered
versions of the source image) This way, you're unfortunately loosing any
cache coherence that you could have used. However, using that method,
you certainly avoid big quality discontinuities (sudden drops) when
switching from one mipmap pair to to next.
On the other hand, if you're planning on using power-of-two scale
factors, you're loosing a little bit of the quality (interpolation drops
will appear when switching mipmap pairs), but you certainly gain a lot
of speed. By precomputing the required mipmap levels, you can obtain a
perfect cache coherence when swithing from one mipmap pair to the next,
and back. Unfortunately, this solution comes with some CPU burden at the
beginning of the mipmaping generation process and this is the issue I'd
like to discuss with you guys.
another approach to mipmap generation is its "on-the-fly" flavor, in
which one creates a mipmap pair only when its required, keeping it in
memory for future use of course.
Bill Spitzak a écrit :
> Owen Taylor wrote:
>> On Sat, 2008-04-19 at 12:16 -0700, Bill Spitzak wrote:
>>>> Owen Taylor a écrit :
>>>>> I'm going to directly disagree here and suggest that for
>>>>> CAIRO_FILTER_GOOD, the right algorithm is:
>>>>> - Scale down by factors of 2 repeatedly until you are less than 2
>>>>> the target scale factor
>>>>> - Bilinearly sample from the result
>>>>> There are certainly disadvantages to this to this approach:
>>>>> - Works worse with non-uniform scales (that contract more in one
>>>>> direction than others)
>>> If you are going to do this each time it is quite possible to use a
>>> different power of 2 horizontally than vertically.
>> For pure scales, yes. But the transform could also contract the image
>> at a 45 degree angle to the axes.
> It would scale to the length of the transform of the vector (0,1) and
> the length of the transform of the vector(1,0). IE the scaled image
> would not be rotated, it would be transformed to be about the same
> size as the result, just not rotated or skewed.
> I'm thinking this will work. The biggest question is whether it will
> actually be faster. As I see it the advantages are that the
> integer-scale pass and the bilinear pass are so much simpler that they
> could be programmed to be far faster.
> Disadvantages are that it seems to require a temporary buffer for the
> scaled image, the fact that two passes are made over the data, and
> that it will think about pixels during the first pass that may be
> clipped off for the final image. Also it is not going to do a great
> job with skew, but most filtering acceleration fails at that anyway.
>> Yep. Locality is a bit more of an issue, overflow will be an issue at
>> some point (especially with mmx).
> If the scale goes over some factor it could switch the algorithim to a
> new one that does not overflow. For instance in some code I am using a
> scale of less than 1/64 just uses the 1/64 filter with the centers
> spaced further apart than 64 (ie it loses a lot of the pixels). At
> this scale it is so tiny that this seems acceptable.
> I don't know offhand how a scale
>> down of 2.7 times looks with bilinear interpolation from a 2-times
>> downscaled copy vs. a 3-time downscaled copy... if there is
>> a significant improvement or not.
> I'm pretty certain you want the nearer-to-1 integer scale. The current
> bilinear matches this for scales down to .5, and I don't think the
> artifacts become objectionable until .5.
More information about the cairo