diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-06 22:50:28 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-04-06 22:55:39 +0100 |
commit | 74b755fe0a786d330d121c435d274e2418003581 (patch) | |
tree | 46a926678c534d993a7c48849b5a889f72aa56cb /src | |
parent | 2077272b12ab299e1f25a16408476da0b51477b7 (diff) |
sna/present: Clear flags on the vblank event's CRTC early
We store a flag on the vblank's CRTC to indicate whether we have marked
the target CRTC as having an immediately pending vblank. We should clear
this set of flags early so that we don't have to worry about the flag
whilst processing the vblank, and so that we don't get confused if we
have to requeue the vblank.
Reported-by: Christoph Haag <haagch@frickel.club>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94829#c32
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_present.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index 3998043a..6e1beaee 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -126,7 +126,7 @@ static void vblank_complete(struct sna_present_event *info, DBG(("%s: %d events complete\n", __FUNCTION__, info->n_event_id)); for (n = 0; n < info->n_event_id; n++) { DBG(("%s: pipe=%d tv=%d.%06d msc=%lld (target=%lld), event=%lld complete%s\n", __FUNCTION__, - sna_crtc_pipe(unmask_crtc(info->crtc)), + sna_crtc_pipe(info->crtc), (int)(ust / 1000000), (int)(ust % 1000000), (long long)msc, (long long)info->target_msc, (long long)info->event_id[n], @@ -360,18 +360,22 @@ void sna_present_vblank_handler(struct drm_event_vblank *event) { struct sna_present_event *info = to_present_event(event->user_data); - xf86CrtcPtr crtc = info->crtc; if (!info->queued) { DBG(("%s: arrived unexpectedly early (not queued)\n", __FUNCTION__)); + assert(!has_vblank(info->crtc)); return; } + if (has_vblank(info->crtc)) { + DBG(("%s: clearing immediate flag\n", __FUNCTION__)); + info->crtc = unmask_crtc(info->crtc); + sna_crtc_clear_vblank(info->crtc); + } + vblank_complete(info, ust64(event->tv_sec, event->tv_usec), - sna_crtc_record_event(unmask_crtc(crtc), event)); - if (has_vblank(crtc)) - sna_crtc_clear_vblank(unmask_crtc(crtc)); + sna_crtc_record_event(info->crtc, event)); } static int |