sna: Remove translation from affine HW cursor transformation

When the CRTC is transformed, we also want to apply that transformation
to the cursor image so that we can continue to use the HW cursor (but
have it appear relative to the output and not to the framebuffer).
However, we need to convert the CRTC transformation relative to the
cursor and convert it to a simple rotation/scaling/skew transformation
(we already verify it is an affine) by removing any translation.

Reported-by: Da Fox <da.fox.mail@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97236
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2016-08-08 11:31:51 +01:00
parent a77397a315
commit 52343d7da1
1 changed files with 46 additions and 8 deletions

View File

@ -5625,7 +5625,6 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
const uint32_t *argb;
uint32_t *image;
int width, height, pitch, size, x, y;
PictTransform cursor_to_fb;
bool transformed;
Rotation rotation;
@ -5677,16 +5676,53 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box);
size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
__DBG(("%s: transformed cursor %dx%d -> %dx%d\n",
__FUNCTION__ ,
sna->cursor.ref->bits->width,
sna->cursor.ref->bits->height,
box.x2 - box.x1, box.y2 - box.y1));
} else
size = sna->cursor.size;
if (crtc->transform_in_use)
RRTransformCompute(0, 0, size, size,
crtc->rotation,
crtc->transformPresent ? &crtc->transform : NULL,
&cursor_to_fb,
&to_sna_crtc(crtc)->cursor_to_fb,
&to_sna_crtc(crtc)->fb_to_cursor);
if (crtc->transform_in_use) {
RRTransformPtr T = NULL;
struct pixman_vector v;
if (crtc->transformPresent) {
T = &crtc->transform;
/* Cancel any translation from this affine
* transformation. We just want to rotate and scale
* the cursor image.
*/
v.vector[0] = 0;
v.vector[1] = 0;
v.vector[2] = pixman_fixed_1;
pixman_transform_point(&crtc->transform.transform, &v);
}
RRTransformCompute(0, 0, size, size, crtc->rotation, T, NULL,
&to_sna_crtc(crtc)->cursor_to_fb,
&to_sna_crtc(crtc)->fb_to_cursor);
if (T)
pixman_f_transform_translate(
&to_sna_crtc(crtc)->cursor_to_fb,
&to_sna_crtc(crtc)->fb_to_cursor,
-pixman_fixed_to_double(v.vector[0]),
-pixman_fixed_to_double(v.vector[1]));
__DBG(("%s: cursor_to_fb [%f %f %f, %f %f %f, %f %f %f]\n",
__FUNCTION__,
to_sna_crtc(crtc)->cursor_to_fb.m[0][0],
to_sna_crtc(crtc)->cursor_to_fb.m[0][1],
to_sna_crtc(crtc)->cursor_to_fb.m[0][2],
to_sna_crtc(crtc)->cursor_to_fb.m[1][0],
to_sna_crtc(crtc)->cursor_to_fb.m[1][1],
to_sna_crtc(crtc)->cursor_to_fb.m[1][2],
to_sna_crtc(crtc)->cursor_to_fb.m[2][0],
to_sna_crtc(crtc)->cursor_to_fb.m[2][1],
to_sna_crtc(crtc)->cursor_to_fb.m[2][2]));
}
cursor = to_sna_crtc(crtc)->cursor;
if (cursor && cursor->alloc < 4*size*size)
@ -5740,6 +5776,7 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
source += pitch;
}
if (transformed) {
__DBG(("%s: Applying affine BLT to bitmap\n", __FUNCTION__));
affine_blt(image, cursor->image, 32,
0, 0, width, height, size * 4,
0, 0, size, size, size * 4,
@ -5747,6 +5784,7 @@ static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
image = cursor->image;
}
} else if (transformed) {
__DBG(("%s: Applying affine BLT to ARGB\n", __FUNCTION__));
affine_blt(argb, cursor->image, 32,
0, 0, width, height, width * 4,
0, 0, size, size, size * 4,