summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-12-15 09:39:54 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-12-15 09:39:54 +0000
commitc8e339edd31859820907115c8d618b0fec3ef227 (patch)
tree2030941fd516cb994b6bd0a20df84fa87b030283
parentf350a1369b3bd39ba0db8639f036864fe5df2f98 (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>
-rw-r--r--src/sna/sna_dri.c20
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;