summaryrefslogtreecommitdiff
path: root/src/sna
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
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')
-rw-r--r--src/sna/gen3_render.c105
-rw-r--r--src/sna/gen4_render.c35
-rw-r--r--src/sna/gen5_render.c35
-rw-r--r--src/sna/gen6_render.c35
-rw-r--r--src/sna/gen7_render.c35
-rw-r--r--src/sna/sna_render.h3
-rw-r--r--src/sna/sna_video.c8
-rw-r--r--src/sna/sna_video_textured.c5
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