summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etnaviv/etnaviv_render.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/etnaviv/etnaviv_render.c b/etnaviv/etnaviv_render.c
index 484e9f1..e11024d 100644
--- a/etnaviv/etnaviv_render.c
+++ b/etnaviv/etnaviv_render.c
@@ -396,7 +396,6 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
DrawablePtr drawable;
uint32_t colour;
xPoint src_offset;
- int tx, ty;
if (etnaviv_pict_solid_argb(pict, &colour)) {
vTemp = etnaviv_get_scratch_argb(pScreen, ppPixTemp,
@@ -417,6 +416,9 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
if (!vSrc)
goto fallback;
+ src_offset.x += drawable->x;
+ src_offset.y += drawable->y;
+
etnaviv_set_format(vSrc, pict);
if (!etnaviv_src_format_valid(etnaviv, vSrc->pict_format))
goto fallback;
@@ -424,11 +426,38 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
if (!picture_has_pixels(pict, *src_topleft, clip))
goto fallback;
- if (!transform_is_integer_translation(pict->transform, &tx, &ty))
- goto fallback;
+ if (pict->transform) {
+ struct pixman_transform inv;
+ struct pixman_vector vec;
+ int tx, ty;
+
+ if (!transform_is_integer_translation(pict->transform, &tx, &ty))
+ goto fallback;
+
+ /* Map the drawable source offsets to destination coords.
+ * The GPU calculates the source coordinate using:
+ * source coord = rotation(destination coord + source origin)
+ * where rotation() rotates around the center point of the
+ * source. Hence, for a 90° anti-clockwise:
+ * rotation(x, y) { return (source_width - y), x; }
+ * We need to do some fiddling here to calculate the source
+ * origin values.
+ */
+ vec.vector[0] = pixman_int_to_fixed(src_offset.x + tx);
+ vec.vector[1] = pixman_int_to_fixed(src_offset.y + ty);
+ vec.vector[2] = pixman_int_to_fixed(0);
+
+ pixman_transform_invert(&inv, pict->transform);
+ pixman_transform_point(&inv, &vec);
+
+ src_topleft->x += pixman_fixed_to_int(vec.vector[0]);
+ src_topleft->y += pixman_fixed_to_int(vec.vector[1]);
+ } else {
+ /* No transform, simple case */
+ src_topleft->x += src_offset.x;
+ src_topleft->y += src_offset.y;
+ }
- src_topleft->x += drawable->x + src_offset.x + tx;
- src_topleft->y += drawable->y + src_offset.y + ty;
if (force_vtemp)
goto copy_to_vtemp;