summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-03-14 13:08:43 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-03-14 13:40:55 +0000
commitc64d2572bafeacae25e9b58c8372ce91858c3832 (patch)
tree0c79534b73c4da3bc44f67182bce058fd9b87456 /src
parentb61e6398f0cf94d3c483e30c05ceae4a8383d16c (diff)
sna: Allow some leeway when deciding to discard common translations
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>
Diffstat (limited to 'src')
-rw-r--r--src/sna/gen2_render.c2
-rw-r--r--src/sna/gen3_render.c4
-rw-r--r--src/sna/gen4_render.c2
-rw-r--r--src/sna/gen5_render.c2
-rw-r--r--src/sna/gen6_render.c36
-rw-r--r--src/sna/gen7_render.c2
-rw-r--r--src/sna/gen8_render.c2
-rw-r--r--src/sna/sna.h7
-rw-r--r--src/sna/sna_blt.c4
-rw-r--r--src/sna/sna_composite.c4
-rw-r--r--src/sna/sna_transform.c44
11 files changed, 95 insertions, 14 deletions
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 2ebfde67..e3931e3e 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -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;
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 69f46684..bb98bebc 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -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;
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index f3773153..88db06ef 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -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;
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c
index e4db739d..5508d491 100644
--- a/src/sna/gen5_render.c
+++ b/src/sna/gen5_render.c
@@ -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;
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c
index 577d1c0b..f1f79463 100644
--- a/src/sna/gen6_render.c
+++ b/src/sna/gen6_render.c
@@ -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);
}
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 4f616615..6c1fe267 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -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;
diff --git a/src/sna/gen8_render.c b/src/sna/gen8_render.c
index ddf376b7..9e634832 100644
--- a/src/sna/gen8_render.c
+++ b/src/sna/gen8_render.c
@@ -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;
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 46516322..f0ddda59 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -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)
{
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 302a00be..41058c68 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -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;
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 74dfc9ed..d34b5172 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -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);
diff --git a/src/sna/sna_transform.c b/src/sna/sna_transform.c
index 55cc1ade..57d1987a 100644
--- a/src/sna/sna_transform.c
+++ b/src/sna/sna_transform.c
@@ -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.
*/