diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-30 14:09:05 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-30 14:10:57 +0100 |
commit | e4ef6e9e5b2c8b637356621c60b28d064d40d29c (patch) | |
tree | a1bece9f03d6d6f21451bc765cb676f00e94621a /src/sna | |
parent | bca4e0e35e4ac27f2dcd1a8e5fcbf7ce69cec358 (diff) |
sna/dri2: Free the pending back buffer after use
The pending back buffer is only the pending copy, the actual info->back
stores the client's view of the current back buffer which may be more
recent than the pending copy. So store the current back buffer, swap in
the pending to do the normal swap, then free the resultant back (which
may have been exchanged with the front), before restoring the client's
current back buffer.
References: https://bugs.freedesktop.org/show_bug.cgi?id=95200
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/sna_dri2.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 18ff264e..bb7070ed 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -2648,7 +2648,9 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event) } if (info->pending.bo) { - DBG(("%s: swapping old back handle=%d [name=%d, active=%d] for pending handle=%d [name=%d, active=%d], front handle=%d [name=%d, active=%d]\n", + struct copy current_back; + + DBG(("%s: swapping back handle=%d [name=%d, active=%d] for pending handle=%d [name=%d, active=%d], front handle=%d [name=%d, active=%d]\n", __FUNCTION__, get_private(info->back)->bo->handle, info->back->name, get_private(info->back)->bo->active_scanout, info->pending.bo->handle, info->pending.name, info->pending.bo->active_scanout, @@ -2664,11 +2666,10 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event) assert(info->pending.bo->active_scanout > 0); info->pending.bo->active_scanout--; - sna_dri2_cache_bo(info->sna, info->draw, - get_private(info->back)->bo, - info->back->name, - get_private(info->back)->size, - info->back->flags); + current_back.bo = get_private(info->back)->bo; + current_back.size = get_private(info->back)->size; + current_back.name = info->back->name; + current_back.flags = info->back->flags; get_private(info->back)->bo = info->pending.bo; get_private(info->back)->size = info->pending.size; @@ -2688,6 +2689,23 @@ void sna_dri2_vblank_handler(struct drm_event_vblank *event) else __sna_dri2_copy_event(info, info->sync | DRI2_BO); + sna_dri2_cache_bo(info->sna, info->draw, + get_private(info->back)->bo, + info->back->name, + get_private(info->back)->size, + info->back->flags); + + get_private(info->back)->bo = current_back.bo; + get_private(info->back)->size = current_back.size; + info->back->name = current_back.name; + info->back->pitch = current_back.bo->pitch; + info->back->flags = current_back.flags; + + DBG(("%s: restored current back handle=%d [name=%d, active=%d], active=%d], front handle=%d [name=%d, active=%d]\n", + __FUNCTION__, + get_private(info->back)->bo->handle, info->back->name, get_private(info->back)->bo->active_scanout, + get_private(info->front)->bo->handle, info->front->name, get_private(info->front)->bo->active_scanout)); + assert(info->draw); info->keepalive++; info->signal = true; |