diff options
author | Russell King <rmk@armlinux.org.uk> | 2018-06-22 10:52:46 +0100 |
---|---|---|
committer | Russell King <rmk@armlinux.org.uk> | 2018-06-25 16:07:46 +0100 |
commit | d48cef9322a9e4f30d3aff9850f267316cd3f8f0 (patch) | |
tree | 29f072521eff2c5cde64844f1413a7ad45c386f3 | |
parent | eabc5d5a73a9e0183bf26e8016d6cf2947c76eb0 (diff) |
etnaviv: take account of transform for source origin
Prepare to support rotations by transforming the source pixmap offsets
to destination coordinates, which is the coordinate space used by the
GPU's source origin register.
Signed-off-by: Russell King <rmk@armlinux.org.uk>
-rw-r--r-- | etnaviv/etnaviv_render.c | 39 |
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; |