[Pixman] [PATCH 2/3] Optimize BILINEAR filter to NEAREST for identity transforms
sandmann at cs.au.dk
Tue May 24 09:47:15 PDT 2011
Siarhei Siamashka <siarhei.siamashka at gmail.com> writes:
> From: Siarhei Siamashka <siarhei.siamashka at nokia.com>
> When doing non-transformed composite operations with the source images
> having BILINEAR filter set, standard fast paths should be still
> perfectly usable just like for the NEAREST filter case.
> But because BILINEAR filter samples 2x2 pixel block in the source image
> for each corresponding destination pixel, FAST_PATH_SAMPLES_COVER_CLIP
> flag may not be set if the composite operation covers the whole source
> image including the last pixel in the scanline (the rightmost pixels of
> the last 2x2 block are considered to be outside of the source image
> bounds even though they have zero weight for interpolation).
To summarize the issue here, the problematic case is when an image
- has a bilinear filter set
- has a transformation that makes that filter reduce to nearest. (Most
importantly, this happens with identity transformations)
- and the area sampled from the image is equal to the image bounds
In this case the standard fast paths would work perfectly well, but we
can't use them because the analyze_extents() code decides that because
of the bilinear filter, it won't set the SAMPLES_COVER_CLIP flag.
The problem for the analyze_extents() code is that if it chooses to
provide the COVER flag, then some code might read common.filter and try
to read outside the image to do bilinear filtering. But without COVER,
the standard fast paths won't run.
It seems to me that the cause of the problem is that the meaning of
COVER depends on what the filter is: it means "there is enough space
around the sample area for the chosen filter", which then becomes wrong
when doing filter reductions.
So maybe a solution would be to provide two separate flags:
COVER_NEAREST: "there is enough space for a nearest filter"
COVER_BILINEAR: "there is enough space for a bilinear filter"
These are unambiguous and because either there is enough space for a
bilinear filter, or there isn't, they can be set independently of what
the filter actually is.
Code that currently depends on COVER generally also depends on filter,
at least implicitly, so there shouldn't be any problem picking the
correct version of COVER for existing fast paths.
This would solve the problem because in the problematic case, the flags
FILTER_NEAREST | COVER_NEAREST could be set, and the standard fast paths
would run, but at the same time, bilinear/cover paths wouldn't be
triggered because they would require FILTER_BILINEAR | COVER_BILINEAR.
As a side effect, this also means we can drop the code that worries
about what covering means when there is a convolution filter.
More information about the Pixman