sna/gen3: Apply damage to video pixmap
Reported-by: Paul Neumann <paul104x@yahoo.de> References: https://bugs.freedesktop.org/show_bug.cgi?id=44504 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
ff4b8a03a4
commit
3d1bba033b
|
|
@ -3610,6 +3610,7 @@ gen3_render_video(struct sna *sna,
|
|||
short drw_w, short drw_h,
|
||||
PixmapPtr pixmap)
|
||||
{
|
||||
struct sna_pixmap *priv = sna_pixmap(pixmap);
|
||||
BoxPtr pbox = REGION_RECTS(dstRegion);
|
||||
int nbox = REGION_NUM_RECTS(dstRegion);
|
||||
int dxo = dstRegion->extents.x1;
|
||||
|
|
@ -3623,7 +3624,7 @@ gen3_render_video(struct sna *sna,
|
|||
|
||||
DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_w, src_h, drw_w, drw_h));
|
||||
|
||||
dst_bo = sna_pixmap_get_bo(pixmap);
|
||||
dst_bo = priv->gpu_bo;
|
||||
if (dst_bo == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -3721,7 +3722,7 @@ gen3_render_video(struct sna *sna,
|
|||
#endif
|
||||
sna_blt_copy_boxes(sna, GXcopy,
|
||||
dst_bo, -dxo, -dyo,
|
||||
sna_pixmap_get_bo(pixmap), pix_xoff, pix_yoff,
|
||||
priv->gpu_bo, pix_xoff, pix_yoff,
|
||||
pixmap->drawable.bitsPerPixel,
|
||||
REGION_RECTS(dstRegion),
|
||||
REGION_NUM_RECTS(dstRegion));
|
||||
|
|
@ -3729,6 +3730,22 @@ gen3_render_video(struct sna *sna,
|
|||
kgem_bo_destroy(&sna->kgem, dst_bo);
|
||||
}
|
||||
|
||||
if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
|
||||
if ((pix_xoff | pix_yoff) == 0) {
|
||||
sna_damage_add(&priv->gpu_damage, dstRegion);
|
||||
sna_damage_subtract(&priv->cpu_damage, dstRegion);
|
||||
} else {
|
||||
sna_damage_add_boxes(&priv->gpu_damage,
|
||||
REGION_RECTS(dstRegion),
|
||||
REGION_NUM_RECTS(dstRegion),
|
||||
pix_xoff, pix_yoff);
|
||||
sna_damage_subtract_boxes(&priv->cpu_damage,
|
||||
REGION_RECTS(dstRegion),
|
||||
REGION_NUM_RECTS(dstRegion),
|
||||
pix_xoff, pix_yoff);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,88 @@ fastcall struct sna_damage *_sna_damage_subtract_box(struct sna_damage *damage,
|
|||
}
|
||||
#endif
|
||||
|
||||
static struct sna_damage *__sna_damage_subtract_boxes(struct sna_damage *damage,
|
||||
const BoxRec *box, int n,
|
||||
int dx, int dy)
|
||||
{
|
||||
BoxRec extents;
|
||||
int i;
|
||||
|
||||
if (damage == NULL)
|
||||
return NULL;
|
||||
|
||||
assert(n);
|
||||
|
||||
extents = box[0];
|
||||
for (i = 1; i < n; i++) {
|
||||
if (extents.x1 > box[i].x1)
|
||||
extents.x1 = box[i].x1;
|
||||
if (extents.x2 < box[i].x2)
|
||||
extents.x2 = box[i].x2;
|
||||
if (extents.y1 > box[i].y1)
|
||||
extents.y1 = box[i].y1;
|
||||
if (extents.y2 < box[i].y2)
|
||||
extents.y2 = box[i].y2;
|
||||
}
|
||||
|
||||
assert(extents.y2 > extents.y1 && extents.x2 > extents.x1);
|
||||
|
||||
extents.x1 += dx;
|
||||
extents.x2 += dx;
|
||||
extents.y1 += dy;
|
||||
extents.y2 += dy;
|
||||
|
||||
if (!sna_damage_maybe_contains_box(damage, &extents))
|
||||
return damage;
|
||||
|
||||
if (n == 1)
|
||||
return __sna_damage_subtract_box(damage, &extents);
|
||||
|
||||
if (damage->mode != DAMAGE_SUBTRACT) {
|
||||
if (damage->dirty)
|
||||
__sna_damage_reduce(damage);
|
||||
|
||||
if (!pixman_region_not_empty(&damage->region)) {
|
||||
__sna_damage_destroy(damage);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
damage->mode = DAMAGE_SUBTRACT;
|
||||
}
|
||||
|
||||
return _sna_damage_create_elt_from_boxes(damage, box, n, dx, dy);
|
||||
}
|
||||
|
||||
#if DEBUG_DAMAGE
|
||||
fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage,
|
||||
const BoxRec *box, int n,
|
||||
int dx, int dy)
|
||||
{
|
||||
char damage_buf[1000];
|
||||
char region_buf[120];
|
||||
|
||||
ErrorF("%s(%s - [(%d,%d), (%d,%d)...x%d])...\n", __FUNCTION__,
|
||||
_debug_describe_damage(damage_buf, sizeof(damage_buf), damage),
|
||||
box->x1 + dx, box->y1 + dy,
|
||||
box->x2 + dx, box->y2 + dy,
|
||||
n);
|
||||
|
||||
damage = __sna_damage_subtract_boxes(damage, box, n, dx, dy);
|
||||
|
||||
ErrorF(" = %s\n",
|
||||
_debug_describe_damage(damage_buf, sizeof(damage_buf), damage));
|
||||
|
||||
return damage;
|
||||
}
|
||||
#else
|
||||
fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage,
|
||||
const BoxRec *box, int n,
|
||||
int dx, int dy)
|
||||
{
|
||||
return __sna_damage_subtract_boxes(damage, box, n, dx, dy);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __sna_damage_contains_box(struct sna_damage *damage,
|
||||
const BoxRec *box)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -153,6 +153,18 @@ static inline void sna_damage_subtract_box(struct sna_damage **damage,
|
|||
assert(*damage == NULL || (*damage)->mode != DAMAGE_ALL);
|
||||
}
|
||||
|
||||
fastcall struct sna_damage *_sna_damage_subtract_boxes(struct sna_damage *damage,
|
||||
const BoxRec *box, int n,
|
||||
int dx, int dy);
|
||||
static inline void sna_damage_subtract_boxes(struct sna_damage **damage,
|
||||
const BoxRec *box, int n,
|
||||
int dx, int dy)
|
||||
{
|
||||
*damage = _sna_damage_subtract_boxes(DAMAGE_PTR(*damage),
|
||||
box, n, dx, dy);
|
||||
assert(*damage == NULL || (*damage)->mode != DAMAGE_ALL);
|
||||
}
|
||||
|
||||
Bool _sna_damage_intersect(struct sna_damage *damage,
|
||||
RegionPtr region, RegionPtr result);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue