diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-28 14:35:54 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-28 21:18:49 +0000 |
commit | 89038ddb96aabc4bc1f04402b2aca0ce546e8bf3 (patch) | |
tree | 9632a9a2eb30e7754d0b2798926070a1fe3fd639 /src/sna/gen5_render.c | |
parent | a0a2faefdefbea63669dfeb49f7e701196ab5631 (diff) |
sna/video: Correct scaling of source offsets
When applying pan and zoom to a mismatched video, it would inevitably
miscompute the origin and scale factors.
Reported-by: Matti Hamalainen <ccr@tnsp.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61610
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/gen5_render.c')
-rw-r--r-- | src/sna/gen5_render.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 9a9c223e..8c8a996f 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -1299,18 +1299,21 @@ gen5_render_video(struct sna *sna, struct sna_video *video, struct sna_video_frame *frame, RegionPtr dstRegion, - short src_w, short src_h, - short drw_w, short drw_h, - short dx, short dy, PixmapPtr pixmap) { struct sna_composite_op tmp; - int nbox, pix_xoff, pix_yoff; + int dst_width = dstRegion->extents.x2 - dstRegion->extents.x1; + int dst_height = dstRegion->extents.y2 - dstRegion->extents.y1; + int src_width = frame->src.x2 - frame->src.x1; + int src_height = frame->src.y2 - frame->src.y1; + float src_offset_x, src_offset_y; float src_scale_x, src_scale_y; + int nbox, pix_xoff, pix_yoff; struct sna_pixmap *priv; BoxPtr box; - DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_w, src_h, drw_w, drw_h)); + DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, + src_width, src_height, dst_width, dst_height)); priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE); if (priv == NULL) @@ -1325,7 +1328,7 @@ gen5_render_video(struct sna *sna, tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth); tmp.dst.bo = priv->gpu_bo; - if (src_w == drw_w && src_h == drw_h) + if (src_width == dst_width && src_height == dst_height) tmp.src.filter = SAMPLER_FILTER_NEAREST; else tmp.src.filter = SAMPLER_FILTER_BILINEAR; @@ -1359,9 +1362,11 @@ gen5_render_video(struct sna *sna, pix_yoff = 0; #endif - /* Use normalized texture coordinates */ - src_scale_x = ((float)src_w / frame->width) / (float)drw_w; - src_scale_y = ((float)src_h / frame->height) / (float)drw_h; + src_scale_x = (float)src_width / dst_width / frame->width; + src_offset_x = frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; + + src_scale_y = (float)src_height / dst_height / frame->height; + src_offset_y = frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; box = REGION_RECTS(dstRegion); nbox = REGION_NUM_RECTS(dstRegion); @@ -1376,16 +1381,16 @@ gen5_render_video(struct sna *sna, gen5_get_rectangles(sna, &tmp, 1, gen5_video_bind_surfaces); OUT_VERTEX(r.x2, r.y2); - OUT_VERTEX_F((box->x2 - dx) * src_scale_x); - OUT_VERTEX_F((box->y2 - dy) * src_scale_y); + OUT_VERTEX_F(box->x2 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(r.x1, r.y2); - OUT_VERTEX_F((box->x1 - dx) * src_scale_x); - OUT_VERTEX_F((box->y2 - dy) * src_scale_y); + OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y2 * src_scale_y + src_offset_y); OUT_VERTEX(r.x1, r.y1); - OUT_VERTEX_F((box->x1 - dx) * src_scale_x); - OUT_VERTEX_F((box->y1 - dy) * src_scale_y); + OUT_VERTEX_F(box->x1 * src_scale_x + src_offset_x); + OUT_VERTEX_F(box->y1 * src_scale_y + src_offset_y); if (!DAMAGE_IS_ALL(priv->gpu_damage)) { sna_damage_add_box(&priv->gpu_damage, &r); |