diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-24 18:22:12 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-24 18:54:07 +0000 |
commit | 3d1bba033bc29fdf498dc082f3542c520a5ed39a (patch) | |
tree | e0ab0a419fd145f76e47657679961a8a1cefefc8 /src/sna/sna_damage.c | |
parent | ff4b8a03a40f7eb1d71b96aebb5daa1d8df83d2a (diff) |
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>
Diffstat (limited to 'src/sna/sna_damage.c')
-rw-r--r-- | src/sna/sna_damage.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/sna/sna_damage.c b/src/sna/sna_damage.c index 490e7a94..d15ec60a 100644 --- a/src/sna/sna_damage.c +++ b/src/sna/sna_damage.c @@ -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) { |