From: Bill Spitzak <spit...@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 <spit...@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

_______________________________________________
Pixman mailing list
Pixman@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/pixman

Reply via email to