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 | |
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>
-rw-r--r-- | src/sna/gen3_render.c | 105 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 35 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 35 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 35 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 35 | ||||
-rw-r--r-- | src/sna/sna_render.h | 3 | ||||
-rw-r--r-- | src/sna/sna_video.c | 8 | ||||
-rw-r--r-- | src/sna/sna_video_textured.c | 5 |
8 files changed, 141 insertions, 120 deletions
diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index 0bac8d31..33116124 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -3024,8 +3024,10 @@ gen3_composite_picture(struct sna *sna, switch (source->type) { case SourcePictTypeSolidFill: - DBG(("%s: solid fill [%08x], format %x\n", - __FUNCTION__, source->solidFill.color, picture->format)); + DBG(("%s: solid fill [%08x], format %08x\n", + __FUNCTION__, + (unsigned)source->solidFill.color, + (unsigned)picture->format)); ret = gen3_init_solid(channel, source->solidFill.color); break; @@ -5103,10 +5105,8 @@ gen3_emit_video_state(struct sna *sna, OUT_BATCH(SS2_COLORSPACE_CONVERSION | (FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); - OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << - SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_CLAMP_EDGE << - SS3_TCY_ADDR_MODE_SHIFT) | + OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); @@ -5220,30 +5220,24 @@ gen3_emit_video_state(struct sna *sna, /* sampler 0 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); - OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << - SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_CLAMP_EDGE << - SS3_TCY_ADDR_MODE_SHIFT) | + OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (0 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 1 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); - OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << - SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_CLAMP_EDGE << - SS3_TCY_ADDR_MODE_SHIFT) | + OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (1 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); /* sampler 2 */ OUT_BATCH((FILTER_LINEAR << SS2_MAG_FILTER_SHIFT) | (FILTER_LINEAR << SS2_MIN_FILTER_SHIFT)); - OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << - SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_CLAMP_EDGE << - SS3_TCY_ADDR_MODE_SHIFT) | + OUT_BATCH((TEXCOORDMODE_CLAMP_EDGE << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_CLAMP_EDGE << SS3_TCY_ADDR_MODE_SHIFT) | (2 << SS3_TEXTUREMAP_INDEX_SHIFT) | SS3_NORMALIZED_COORDS); OUT_BATCH(0x00000000); @@ -5359,7 +5353,6 @@ gen3_emit_video_state(struct sna *sna, (sna->kgem.nbatch - id - 2); } } - } static void @@ -5395,37 +5388,51 @@ gen3_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_pixmap *priv = sna_pixmap(pixmap); BoxPtr pbox = REGION_RECTS(dstRegion); int nbox = REGION_NUM_RECTS(dstRegion); - int width = dstRegion->extents.x2 - dstRegion->extents.x1; - int height = dstRegion->extents.y2 - dstRegion->extents.y1; + 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 pix_xoff, pix_yoff; struct kgem_bo *dst_bo; bool bilinear; int copy = 0; - DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_w, src_h, drw_w, drw_h)); + DBG(("%s: src:%dx%d (frame:%dx%d) -> dst:%dx%d\n", __FUNCTION__, + src_width, src_height, frame->width, frame->height, dst_width, dst_height)); dst_bo = priv->gpu_bo; if (dst_bo == NULL) return false; + bilinear = src_width != dst_width || src_height != dst_height; + + src_scale_x = (float)src_width / dst_width / frame->width; + src_offset_x = (float)frame->src.x1 / frame->width - dstRegion->extents.x1 * src_scale_x; + + src_scale_y = (float)src_height / dst_height / frame->height; + src_offset_y = (float)frame->src.y1 / frame->height - dstRegion->extents.y1 * src_scale_y; + DBG(("%s: src offset (%f, %f), scale (%f, %f)\n", + __FUNCTION__, src_offset_x, src_offset_y, src_scale_x, src_scale_y)); + if (too_large(pixmap->drawable.width, pixmap->drawable.height) || !gen3_check_pitch_3d(dst_bo)) { int bpp = pixmap->drawable.bitsPerPixel; + if (too_large(dst_width, dst_height)) + return false; + dst_bo = kgem_create_2d(&sna->kgem, - width, height, bpp, + dst_width, dst_height, bpp, kgem_choose_tiling(&sna->kgem, I915_TILING_X, - width, height, bpp), + dst_width, dst_height, bpp), 0); if (!dst_bo) return false; @@ -5434,9 +5441,6 @@ gen3_render_video(struct sna *sna, pix_yoff = -dstRegion->extents.y1; copy = 1; } else { - width = pixmap->drawable.width; - height = pixmap->drawable.height; - /* Set up the offset for translating from the given region * (in screen coordinates) to the backing pixmap. */ @@ -5447,32 +5451,27 @@ gen3_render_video(struct sna *sna, pix_xoff = 0; pix_yoff = 0; #endif - } - bilinear = src_w != drw_w || src_h != drw_h; - - src_scale_x = ((float)src_w / frame->width) / drw_w; - src_scale_y = ((float)src_h / frame->height) / drw_h; - - DBG(("%s: src offset=(%d, %d), scale=(%f, %f), dst offset=(%d, %d)\n", - __FUNCTION__, - dx, dy, src_scale_x, src_scale_y, pix_xoff, pix_yoff)); + dst_width = pixmap->drawable.width; + dst_height = pixmap->drawable.height; + } gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, - dst_bo, width, height, bilinear); + dst_bo, dst_width, dst_height, bilinear); do { int nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); if (nbox_this_time == 0) { gen3_video_get_batch(sna, dst_bo); gen3_emit_video_state(sna, video, frame, pixmap, - dst_bo, width, height, bilinear); + dst_bo, dst_width, dst_height, bilinear); nbox_this_time = gen3_get_inline_rectangles(sna, nbox, 4); + assert(nbox_this_time); } nbox -= nbox_this_time; OUT_BATCH(PRIM3D_RECTLIST | (12 * nbox_this_time - 1)); - while (nbox_this_time--) { + do { int box_x1 = pbox->x1; int box_y1 = pbox->y1; int box_x2 = pbox->x2; @@ -5480,27 +5479,31 @@ gen3_render_video(struct sna *sna, pbox++; - DBG(("%s: box (%d, %d), (%d, %d)\n", - __FUNCTION__, box_x1, box_y1, box_x2, box_y2)); + DBG(("%s: dst (%d, %d), (%d, %d) + (%d, %d); src (%f, %f), (%f, %f)\n", + __FUNCTION__, box_x1, box_y1, box_x2, box_y2, pix_xoff, pix_yoff, + box_x1 * src_scale_x + src_offset_x, + box_y1 * src_scale_y + src_offset_y, + box_x2 * src_scale_x + src_offset_x, + box_y2 * src_scale_y + src_offset_y)); /* bottom right */ OUT_BATCH_F(box_x2 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); - OUT_BATCH_F((box_x2 - dx) * src_scale_x); - OUT_BATCH_F((box_y2 - dy) * src_scale_y); + OUT_BATCH_F(box_x2 * src_scale_x + src_offset_x); + OUT_BATCH_F(box_y2 * src_scale_y + src_offset_y); /* bottom left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y2 + pix_yoff); - OUT_BATCH_F((box_x1 - dx) * src_scale_x); - OUT_BATCH_F((box_y2 - dy) * src_scale_y); + OUT_BATCH_F(box_x1 * src_scale_x + src_offset_x); + OUT_BATCH_F(box_y2 * src_scale_y + src_offset_y); /* top left */ OUT_BATCH_F(box_x1 + pix_xoff); OUT_BATCH_F(box_y1 + pix_yoff); - OUT_BATCH_F((box_x1 - dx) * src_scale_x); - OUT_BATCH_F((box_y1 - dy) * src_scale_y); - } + OUT_BATCH_F(box_x1 * src_scale_x + src_offset_x); + OUT_BATCH_F(box_y1 * src_scale_y + src_offset_y); + } while (--nbox_this_time); } while (nbox); if (copy) { diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 4abcb97b..f78c5da1 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1315,18 +1315,21 @@ gen4_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) @@ -1341,7 +1344,7 @@ gen4_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; @@ -1375,9 +1378,11 @@ gen4_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); @@ -1392,16 +1397,16 @@ gen4_render_video(struct sna *sna, gen4_get_rectangles(sna, &tmp, 1, gen4_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); 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); diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 31953881..8d15bd80 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -1573,20 +1573,23 @@ gen6_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; unsigned filter; BoxPtr box; DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n", - __FUNCTION__, src_w, src_h, drw_w, drw_h, + __FUNCTION__, + src_width, src_height, dst_width, dst_height, REGION_NUM_RECTS(dstRegion), REGION_EXTENTS(NULL, dstRegion)->x1, REGION_EXTENTS(NULL, dstRegion)->y1, @@ -1611,7 +1614,7 @@ gen6_render_video(struct sna *sna, tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; - if (src_w == drw_w && src_h == drw_h) + if (src_width == dst_width && src_height == dst_height) filter = SAMPLER_FILTER_NEAREST; else filter = SAMPLER_FILTER_BILINEAR; @@ -1647,9 +1650,11 @@ gen6_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); @@ -1664,16 +1669,16 @@ gen6_render_video(struct sna *sna, gen6_get_rectangles(sna, &tmp, 1, gen6_emit_video_state); 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); diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 0dae8c43..4453797f 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -1715,20 +1715,23 @@ gen7_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; unsigned filter; BoxPtr box; DBG(("%s: src=(%d, %d), dst=(%d, %d), %dx[(%d, %d), (%d, %d)...]\n", - __FUNCTION__, src_w, src_h, drw_w, drw_h, + __FUNCTION__, + src_width, src_height, dst_width, dst_height, REGION_NUM_RECTS(dstRegion), REGION_EXTENTS(NULL, dstRegion)->x1, REGION_EXTENTS(NULL, dstRegion)->y1, @@ -1753,7 +1756,7 @@ gen7_render_video(struct sna *sna, tmp.floats_per_vertex = 3; tmp.floats_per_rect = 9; - if (src_w == drw_w && src_h == drw_h) + if (src_width == dst_width && src_height == dst_height) filter = SAMPLER_FILTER_NEAREST; else filter = SAMPLER_FILTER_BILINEAR; @@ -1789,9 +1792,11 @@ gen7_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); @@ -1806,16 +1811,16 @@ gen7_render_video(struct sna *sna, gen7_get_rectangles(sna, &tmp, 1, gen7_emit_video_state); 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); diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 01176c6a..1a15b70e 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -245,9 +245,6 @@ struct sna_render { 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); bool (*fill_boxes)(struct sna *sna, diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c index ecf52d21..a0eb0f4e 100644 --- a/src/sna/sna_video.c +++ b/src/sna/sna_video.c @@ -449,9 +449,9 @@ sna_video_copy_data(struct sna *sna, { uint8_t *dst; - DBG(("%s: handle=%d, size=%dx%d [%d], rotation=%d, is-texture=%d\n", + DBG(("%s: handle=%d, size=%dx%d [%d], pitch=[%d,%d] rotation=%d, is-texture=%d\n", __FUNCTION__, frame->bo ? frame->bo->handle : 0, - frame->width, frame->height, frame->size, + frame->width, frame->height, frame->size, frame->pitch[0], frame->pitch[1], video->rotation, video->textured)); DBG(("%s: image=(%d, %d), (%d, %d), source=(%d, %d), (%d, %d)\n", __FUNCTION__, @@ -462,6 +462,8 @@ sna_video_copy_data(struct sna *sna, /* In the common case, we can simply the upload in a single pwrite */ if (video->rotation == RR_Rotate_0 && !video->tiled) { + DBG(("%s: unrotated, untiled fast paths: is-planar?=%d\n", + __FUNCTION__, is_planar_fourcc(frame->id))); if (is_planar_fourcc(frame->id)) { int w = frame->image.x2 - frame->image.x1; int h = frame->image.y2 - frame->image.y1; @@ -508,6 +510,8 @@ sna_video_copy_data(struct sna *sna, return true; } } + + DBG(("%s: source cropped, fallback\n", __FUNCTION__)); } /* copy data, must use GTT so that we keep the overlay uncached */ diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c index e5cae859..bd203259 100644 --- a/src/sna/sna_video_textured.c +++ b/src/sna/sna_video_textured.c @@ -287,10 +287,7 @@ sna_video_textured_put_image(ScrnInfoPtr scrn, } ret = Success; - if (!sna->render.video(sna, video, &frame, clip, - src_w, src_h, drw_w, drw_h, - drw_x - src_x, drw_y - src_y, - pixmap)) { + if (!sna->render.video(sna, video, &frame, clip, pixmap)) { DBG(("%s: failed to render video\n", __FUNCTION__)); ret = BadAlloc; } else |