diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2020-05-06 18:56:39 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2020-05-06 19:03:18 +0100 |
commit | e781d43dadde342a7a5b8661b8bf4690b8a1bb6e (patch) | |
tree | 1776eba46db4fb4411019c707e4d9ffce44bc1d2 | |
parent | 846b53dacd96981329bcb9ef348e6acba0b53e94 (diff) |
sna/dri2: Prevent copying stale buffers
The back buffer of window/pixmap is invalidated by DRI2ScheduleSwap, and
is not available until the client calls DRI2GetBuffers. If they try to
use their old handles, they will only get stale data. Similarly if they
ask us to DRI2CopyRegion before the GetBuffers has reallocated a new
back buffer, that back buffer is stale. Since the back buffer is
out-of-date [likely containing data from a couple of swaps ago], we
should ignore the copy to avoid glitching [by hopefully having a less
noticeable glitch!] It's not entirely clear what the client intended at
this point...
Closes: https://gitlab.freedesktop.org/xorg/driver/xf86-video-intel/-/issues/195
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_dri2.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index f2f2c1d3..4ee76627 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -1421,25 +1421,30 @@ sna_dri2_copy_region(DrawablePtr draw, PixmapPtr pixmap = get_drawable_pixmap(draw); struct sna *sna = to_sna_from_pixmap(pixmap); - DBG(("%s: pixmap=%ld, src=%u (refs=%d/%d, flush=%d, attach=%d) , dst=%u (refs=%d/%d, flush=%d, attach=%d)\n", + DBG(("%s: pixmap=%ld, src=%u (attach=%d, refs=%d/%d, flush=%d, stale=%d) , dst=%u (attach=%d, refs=%d/%d, flush=%d, stale=%d)\n", __FUNCTION__, pixmap->drawable.serialNumber, get_private(src)->bo->handle, + src->attachment, get_private(src)->refcnt, get_private(src)->bo->refcnt, get_private(src)->bo->flush, - src->attachment, + get_private(src)->stale, get_private(dst)->bo->handle, + dst->attachment, get_private(dst)->refcnt, get_private(dst)->bo->refcnt, get_private(dst)->bo->flush, - dst->attachment)); + get_private(dst)->stale)); assert(src != dst); assert(get_private(src)->refcnt); assert(get_private(dst)->refcnt); + if (get_private(src)->stale) + return; + assert(get_private(src)->bo != get_private(dst)->bo); assert(get_private(src)->bo->refcnt); |