summaryrefslogtreecommitdiff
path: root/src/common_drm.c
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2016-01-28 15:14:55 +0000
committerRussell King <rmk@arm.linux.org.uk>2016-01-28 15:27:15 +0000
commit52b37c6528cce5d53f132406e5e3f4054fbb1bfe (patch)
treef9ab7e2c74c5d08eabc33f6bb034b0fa92df2ae3 /src/common_drm.c
parent248f32afc9acd3fc398b92be823a804653bc0f9b (diff)
src: dri2: fix MSC handling
The MSC handling was taken from the xf86-video-intel driver, but it seems to be lacking in that the wrap-handling is substandard; it can result in DRI2 applications stalling for a very long time. The problem is that xf86-video-intel is under the impression that the vblank counter can wind backwards. This is not true; the kernel only ever increments the counter (see functions that call store_vblank().) Hence, remove this logic, and always assume that a vblank sequence value that is less than a previously seen one means that it has wrapped. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
Diffstat (limited to 'src/common_drm.c')
-rw-r--r--src/common_drm.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/common_drm.c b/src/common_drm.c
index b5c7f0b..a3c017e 100644
--- a/src/common_drm.c
+++ b/src/common_drm.c
@@ -119,13 +119,20 @@ static uint64_t common_drm_frame_to_msc(xf86CrtcPtr crtc, uint32_t seq)
{
struct common_crtc_info *drmc = common_crtc(crtc);
- if (seq < drmc->last_seq) {
- if ((int32_t)(drmc->last_seq - seq) > 0x40000000)
- drmc->last_msc += 0x100000000ULL;
- else
- seq = drmc->last_seq;
- }
+ /*
+ * The sequence counter wrapped. Unlike the misleading comments in
+ * xf86-video-intel, the vblank counter is never wound backwards: it
+ * always runs forwards. However, since we don't monitor it with
+ * any regularity, it can appear to go backwards if we wait (eg)
+ * 0xc0000000 vblanks between calls. Hence, whenever we see the
+ * frame sequence less than the last sequence, assume that it has
+ * wrapped. (It may have wrapped more than once.)
+ */
+ if (seq < drmc->last_seq)
+ drmc->last_msc += 0x100000000ULL;
+
drmc->last_seq = seq;
+
return drmc->last_msc + seq;
}