sna: Allow some leeway when deciding to discard common translations
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 14 Mar 2014 13:08:43 +0000 (13:08 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 14 Mar 2014 13:40:55 +0000 (13:40 +0000)
Under PictFilterNearest, we can ignore fractional translations (not all
renderers discard those.) And if we are being approximate, we can loosen
our tolerance as well.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
src/sna/gen2_render.c
src/sna/gen3_render.c
src/sna/gen4_render.c
src/sna/gen5_render.c
src/sna/gen6_render.c
src/sna/gen7_render.c
src/sna/gen8_render.c
src/sna/sna.h
src/sna/sna_blt.c
src/sna/sna_composite.c
src/sna/sna_transform.c

index 2ebfde6..e3931e3 100644 (file)
@@ -1550,7 +1550,7 @@ gen2_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index 69f4668..bb98beb 100644 (file)
@@ -2859,7 +2859,7 @@ static bool gen3_gradient_setup(struct sna *sna,
        channel->card_format = MAPSURF_32BIT | MT_32BIT_ARGB8888;
        channel->filter = PictFilterNearest;
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, PictFilterNearest, false, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                ox += dx;
@@ -3086,7 +3086,7 @@ gen3_composite_picture(struct sna *sna,
        x += dx + picture->pDrawable->x;
        y += dy + picture->pDrawable->y;
 
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index f377315..88db06e 100644 (file)
@@ -1577,7 +1577,7 @@ gen4_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index e4db739..5508d49 100644 (file)
@@ -1516,7 +1516,7 @@ gen5_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index 577d1c0..f1f7946 100644 (file)
@@ -1713,8 +1713,8 @@ gen6_composite_picture(struct sna *sna,
        uint32_t color;
        int16_t dx, dy;
 
-       DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
-            __FUNCTION__, x, y, w, h, dst_x, dst_y));
+       DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d), precise=%d\n",
+            __FUNCTION__, x, y, w, h, dst_x, dst_y, precise));
 
        channel->is_solid = false;
        channel->card_format = -1;
@@ -1766,7 +1766,7 @@ gen6_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
@@ -1790,6 +1790,36 @@ gen6_composite_picture(struct sna *sna,
                                                  x, y, w, h, dst_x, dst_y);
        }
 
+       DBG(("%s: pixmap, repeat=%d, filter=%d, transform?=%d [affine? %d], format=%08x\n",
+            __FUNCTION__,
+            channel->repeat, channel->filter,
+            channel->transform != NULL, channel->is_affine,
+            channel->pict_format));
+       if (channel->transform) {
+#define f2d(x) (((double)(x))/65536.)
+               DBG(("%s: transform=[%f %f %f, %f %f %f, %f %f %f] (raw [%x %x %x, %x %x %x, %x %x %x])\n",
+                    __FUNCTION__,
+                    f2d(channel->transform->matrix[0][0]),
+                    f2d(channel->transform->matrix[0][1]),
+                    f2d(channel->transform->matrix[0][2]),
+                    f2d(channel->transform->matrix[1][0]),
+                    f2d(channel->transform->matrix[1][1]),
+                    f2d(channel->transform->matrix[1][2]),
+                    f2d(channel->transform->matrix[2][0]),
+                    f2d(channel->transform->matrix[2][1]),
+                    f2d(channel->transform->matrix[2][2]),
+                    channel->transform->matrix[0][0],
+                    channel->transform->matrix[0][1],
+                    channel->transform->matrix[0][2],
+                    channel->transform->matrix[1][0],
+                    channel->transform->matrix[1][1],
+                    channel->transform->matrix[1][2],
+                    channel->transform->matrix[2][0],
+                    channel->transform->matrix[2][1],
+                    channel->transform->matrix[2][2]));
+#undef f2d
+       }
+
        return sna_render_pixmap_bo(sna, channel, pixmap,
                                    x, y, w, h, dst_x, dst_y);
 }
index 4f61661..6c1fe26 100644 (file)
@@ -2029,7 +2029,7 @@ gen7_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index ddf376b..9e63483 100644 (file)
@@ -1806,7 +1806,7 @@ gen8_composite_picture(struct sna *sna,
        y += dy + picture->pDrawable->y;
 
        channel->is_affine = sna_transform_is_affine(picture->transform);
-       if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
+       if (sna_transform_is_imprecise_integer_translation(picture->transform, picture->filter, precise, &dx, &dy)) {
                DBG(("%s: integer translation (%d, %d), removing\n",
                     __FUNCTION__, dx, dy));
                x += dx;
index 4651632..f0ddda5 100644 (file)
@@ -764,10 +764,13 @@ sna_get_transformed_coordinates_3d(int x, int y,
                                   float *x_out, float *y_out, float *z_out);
 
 bool sna_transform_is_affine(const PictTransform *t);
-bool sna_transform_is_integer_translation(const PictTransform *t,
-                                         int16_t *tx, int16_t *ty);
 bool sna_transform_is_translation(const PictTransform *t,
                                  pixman_fixed_t *tx, pixman_fixed_t *ty);
+bool sna_transform_is_integer_translation(const PictTransform *t,
+                                         int16_t *tx, int16_t *ty);
+bool sna_transform_is_imprecise_integer_translation(const PictTransform *t,
+                                              int filter, bool precise,
+                                              int16_t *tx, int16_t *ty);
 static inline bool
 sna_affine_transform_is_rotation(const PictTransform *t)
 {
index 302a00b..41058c6 100644 (file)
@@ -2515,7 +2515,9 @@ fill:
                return false;
        }
 
-       if (!sna_transform_is_integer_translation(src->transform, &tx, &ty)) {
+       if (sna_transform_is_imprecise_integer_translation(src->transform, src->filter,
+                                                          dst->polyMode == PolyModePrecise,
+                                                          &tx, &ty)) {
                DBG(("%s: source transform is not an integer translation\n",
                     __FUNCTION__));
                return false;
index 74dfc9e..d34b517 100644 (file)
@@ -527,7 +527,9 @@ sna_composite_fb(CARD8 op,
            src->filter != PictFilterConvolution &&
            (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(src->format))) &&
            (dst->format == src->format || dst->format == alphaless(src->format)) &&
-           sna_transform_is_integer_translation(src->transform, &tx, &ty)) {
+           sna_transform_is_imprecise_integer_translation(src->transform, src->filter,
+                                                          dst->polyMode == PolyModePrecise,
+                                                          &tx, &ty)) {
                PixmapPtr dst_pixmap = get_drawable_pixmap(dst->pDrawable);
                PixmapPtr src_pixmap = get_drawable_pixmap(src->pDrawable);
                int16_t sx = src_x + tx - (dst->pDrawable->x + dst_x);
index 55cc1ad..57d1987 100644 (file)
@@ -96,6 +96,50 @@ sna_transform_is_integer_translation(const PictTransform *t, int16_t *tx, int16_
        return true;
 }
 
+bool
+sna_transform_is_imprecise_integer_translation(const PictTransform *t,
+                                              int filter, bool precise,
+                                              int16_t *tx, int16_t *ty)
+{
+       if (t == NULL) {
+               *tx = *ty = 0;
+               return true;
+       }
+
+       if (t->matrix[0][0] != IntToxFixed(1) ||
+           t->matrix[0][1] != 0 ||
+           t->matrix[1][0] != 0 ||
+           t->matrix[1][1] != IntToxFixed(1) ||
+           t->matrix[2][0] != 0 ||
+           t->matrix[2][1] != 0 ||
+           t->matrix[2][2] != IntToxFixed(1))
+               return false;
+
+       DBG(("%s: filter=%d, translation (%x, %x), precise? %d\n",
+            __FUNCTION__, filter, t->matrix[0][2], t->matrix[1][2], precise));
+       if (filter != PictFilterNearest) {
+               if (precise) {
+                       if (pixman_fixed_fraction(t->matrix[0][2]) ||
+                           pixman_fixed_fraction(t->matrix[1][2]))
+                               return false;
+               } else {
+                       int f;
+
+                       f = pixman_fixed_fraction(t->matrix[0][2]);
+                       if (f < IntToxFixed(1)/4 || f > IntToxFixed(3)/4)
+                               return false;
+
+                       f = pixman_fixed_fraction(t->matrix[1][2]);
+                       if (f < IntToxFixed(1)/4 || f > IntToxFixed(3)/4)
+                               return false;
+               }
+       }
+
+       *tx = pixman_fixed_to_int(t->matrix[0][2] + IntToxFixed(1)/2);
+       *ty = pixman_fixed_to_int(t->matrix[1][2] + IntToxFixed(1)/2);
+       return true;
+}
+
 /**
  * Returns the floating-point coordinates transformed by the given transform.
  */