[Pixman] [PATCH v14 20/22] pixman-image: Detect all 8 transforms that can do nearest filter
spitzak at gmail.com
spitzak at gmail.com
Mon Mar 7 01:06:55 UTC 2016
From: Bill Spitzak <spitzak at gmail.com>
This patch consolidates the examination of the matrix into one place, and detects
the reflected versions of the transforms that can be done with nearest filter.
v14: Split this code from the GOOD/BEST as I think it will be accepted.
Signed-off-by: Bill Spitzak <spitzak at gmail.com>
---
pixman/pixman-image.c | 119 ++++++++++++++++++++++++--------------------------
1 file changed, 57 insertions(+), 62 deletions(-)
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 1ff1a49..8ad2891 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -266,52 +266,82 @@ compute_image_info (pixman_image_t *image)
{
pixman_format_code_t code;
uint32_t flags = 0;
+ int nearest_ok = FALSE;
+ pixman_fixed_t (*m)[3];
/* Transform */
if (!image->common.transform)
{
+ nearest_ok = TRUE;
flags |= (FAST_PATH_ID_TRANSFORM |
FAST_PATH_X_UNIT_POSITIVE |
FAST_PATH_Y_UNIT_ZERO |
FAST_PATH_AFFINE_TRANSFORM);
+ m = 0;
}
else
{
+ m = image->common.transform->matrix;
+
flags |= FAST_PATH_HAS_TRANSFORM;
- if (image->common.transform->matrix[2][0] == 0 &&
- image->common.transform->matrix[2][1] == 0 &&
- image->common.transform->matrix[2][2] == pixman_fixed_1)
+ if (m[2][0] == 0 &&
+ m[2][1] == 0 &&
+ m[2][2] == pixman_fixed_1)
{
flags |= FAST_PATH_AFFINE_TRANSFORM;
- if (image->common.transform->matrix[0][1] == 0 &&
- image->common.transform->matrix[1][0] == 0)
+ if (m[0][1] == 0 &&
+ m[1][0] == 0)
{
- if (image->common.transform->matrix[0][0] == -pixman_fixed_1 &&
- image->common.transform->matrix[1][1] == -pixman_fixed_1)
+ flags |= FAST_PATH_SCALE_TRANSFORM;
+ if (abs(m[0][0]) == pixman_fixed_1 &&
+ abs(m[1][1]) == pixman_fixed_1)
{
- flags |= FAST_PATH_ROTATE_180_TRANSFORM;
+ /* no scaling */
+ nearest_ok = TRUE;
+ if (m[0][0] < 0 && m[1][1] < 0)
+ flags |= FAST_PATH_ROTATE_180_TRANSFORM;
}
- flags |= FAST_PATH_SCALE_TRANSFORM;
}
- else if (image->common.transform->matrix[0][0] == 0 &&
- image->common.transform->matrix[1][1] == 0)
+ else if (m[0][0] == 0 &&
+ m[1][1] == 0)
{
- pixman_fixed_t m01 = image->common.transform->matrix[0][1];
- pixman_fixed_t m10 = image->common.transform->matrix[1][0];
+ /* x/y axis are swapped, 90 degree rotation */
+ if (abs(m[0][1]) == pixman_fixed_1 &&
+ abs(m[1][0]) == pixman_fixed_1)
+ {
+ /* no scaling */
+ nearest_ok = TRUE;
+ if (m[0][1] < 0 && m[1][0] > 0)
+ flags |= FAST_PATH_ROTATE_90_TRANSFORM;
+ else if (m[0][1] > 0 && m[1][0] < 0)
+ flags |= FAST_PATH_ROTATE_270_TRANSFORM;
+ }
+ }
- if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1)
- flags |= FAST_PATH_ROTATE_90_TRANSFORM;
- else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1)
- flags |= FAST_PATH_ROTATE_270_TRANSFORM;
+ if (nearest_ok)
+ {
+ /* reject non-integer translation: */
+ if (pixman_fixed_frac (m[0][2] | m[1][2]))
+ nearest_ok = FALSE;
+ /* 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.
+ */
+ else if (abs(m[0][2]) > pixman_int_to_fixed (30000) ||
+ abs(m[1][2]) > pixman_int_to_fixed (30000))
+ nearest_ok = FALSE;
}
}
- if (image->common.transform->matrix[0][0] > 0)
+ if (m[0][0] > 0)
flags |= FAST_PATH_X_UNIT_POSITIVE;
- if (image->common.transform->matrix[1][0] == 0)
+ if (m[1][0] == 0)
flags |= FAST_PATH_Y_UNIT_ZERO;
}
@@ -326,48 +356,10 @@ compute_image_info (pixman_image_t *image)
case PIXMAN_FILTER_BILINEAR:
case PIXMAN_FILTER_GOOD:
case PIXMAN_FILTER_BEST:
- flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
-
- /* 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;
- }
- }
+ if (nearest_ok)
+ flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
+ else
+ flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
break;
case PIXMAN_FILTER_CONVOLUTION:
@@ -378,7 +370,10 @@ compute_image_info (pixman_image_t *image)
break;
default:
- flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
+ if (nearest_ok)
+ flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
+ else
+ flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
break;
}
--
1.9.1
More information about the Pixman
mailing list