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>
This commit is contained in:
Chris Wilson 2013-02-28 14:35:54 +00:00
parent a0a2faefde
commit 89038ddb96
8 changed files with 141 additions and 120 deletions

View File

@ -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
dst_width = pixmap->drawable.width;
dst_height = pixmap->drawable.height;
}
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));
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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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 */

View File

@ -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