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:
parent
a0a2faefde
commit
89038ddb96
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue