summaryrefslogtreecommitdiff
path: root/src/sna/gen5_render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-02-28 14:35:54 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-02-28 21:18:49 +0000
commit89038ddb96aabc4bc1f04402b2aca0ce546e8bf3 (patch)
tree9632a9a2eb30e7754d0b2798926070a1fe3fd639 /src/sna/gen5_render.c
parenta0a2faefdefbea63669dfeb49f7e701196ab5631 (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.c35
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);