summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiarhei Siamashka <siarhei.siamashka@nokia.com>2011-05-22 22:51:00 +0300
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-09-21 18:55:25 -0400
commit9126f36b964c71b83c69235df4c3a46ab81ab5d5 (patch)
tree48905913c4d7e90e2974d58abe447c798a9fe3b5
parentad5c6bbb36c1c5e72313f7c7bc7c6e6b7e79daba (diff)
BILINEAR->NEAREST filter optimization for simple rotation and translation
Simple rotation and translation are the additional cases when BILINEAR filter can be safely reduced to NEAREST.
-rw-r--r--pixman/pixman-image.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 88262f71..a3bb9b63 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -251,9 +251,46 @@ compute_image_info (pixman_image_t *image)
case PIXMAN_FILTER_BEST:
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
- /* Reduce BILINEAR to NEAREST for identity transforms */
+ /* Here we have a chance to optimize BILINEAR filter to NEAREST if
+ * they are equivalent for the currently used transformation matrix.
+ */
if (flags & FAST_PATH_ID_TRANSFORM)
+ {
flags |= FAST_PATH_NEAREST_FILTER;
+ }
+ else if (
+ /* affine and integer translation components in matrix ... */
+ ((flags & FAST_PATH_AFFINE_TRANSFORM) &&
+ !pixman_fixed_frac (image->common.transform->matrix[0][2] |
+ image->common.transform->matrix[1][2])) &&
+ (
+ /* ... combined with a simple rotation */
+ (flags & (FAST_PATH_ROTATE_90_TRANSFORM |
+ FAST_PATH_ROTATE_180_TRANSFORM |
+ FAST_PATH_ROTATE_270_TRANSFORM)) ||
+ /* ... or combined with a simple non-rotated translation */
+ (image->common.transform->matrix[0][0] == pixman_fixed_1 &&
+ image->common.transform->matrix[1][1] == pixman_fixed_1 &&
+ image->common.transform->matrix[0][1] == 0 &&
+ image->common.transform->matrix[1][0] == 0)
+ )
+ )
+ {
+ /* FIXME: there are some affine-test failures, showing that
+ * handling of BILINEAR and NEAREST filter is not quite
+ * equivalent when getting close to 32K for the translation
+ * components of the matrix. That's likely some bug, but for
+ * now just skip BILINEAR->NEAREST optimization in this case.
+ */
+ pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
+ if (image->common.transform->matrix[0][2] <= magic_limit &&
+ image->common.transform->matrix[1][2] <= magic_limit &&
+ image->common.transform->matrix[0][2] >= -magic_limit &&
+ image->common.transform->matrix[1][2] >= -magic_limit)
+ {
+ flags |= FAST_PATH_NEAREST_FILTER;
+ }
+ }
break;
case PIXMAN_FILTER_CONVOLUTION: