diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-12-15 09:39:54 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-12-15 09:39:54 +0000 |
commit | c8e339edd31859820907115c8d618b0fec3ef227 (patch) | |
tree | 2030941fd516cb994b6bd0a20df84fa87b030283 /src | |
parent | f350a1369b3bd39ba0db8639f036864fe5df2f98 (diff) |
sna: Avoid recursive out-of-order operations in the middle of TearFree
During TearFree, if we have to wait for the shadow flip to complete, we
run the event handler for the device. This can then cause us to evaluate
pending completed vblank events, which may in turn then attempt to use
the shadow bo and recurse into the TearFree handler. Try to prevent this
and requeue the vblank event.
Reported-by: Pascal de Bruijn <pmjdebruijn@pcode.nl>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=72690
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_dri.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index 34d20447..bf970e04 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -1353,6 +1353,24 @@ void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event) if (draw == NULL) goto done; + if (sna->mode.shadow_flip && !sna->mode.shadow_damage) { + drmVBlank vbl; + + /* recursed from wait_for_shadow(), simply requeue */ + VG_CLEAR(vbl); + vbl.request.type = + DRM_VBLANK_RELATIVE | + DRM_VBLANK_EVENT | + pipe_select(info->pipe); + vbl.request.sequence = 1; + vbl.request.signal = (unsigned long)info; + + if (sna_wait_vblank(sna, &vbl)) + goto done; + + return; + } + switch (info->type) { case DRI2_FLIP: /* If we can still flip... */ @@ -1617,6 +1635,8 @@ static void sna_dri_flip_event(struct sna *sna, flip->fe_tv_usec, flip->type)); + assert(!sna->mode.shadow_flip); + if (flip->scanout[1].bo) { struct dri_bo *c = NULL; |