summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/drm_common.c9
-rw-r--r--video/out/drm_common.h1
-rw-r--r--video/out/opengl/context_drm_egl.c1
-rw-r--r--video/out/vo_drm.c1
4 files changed, 12 insertions, 0 deletions
diff --git a/video/out/drm_common.c b/video/out/drm_common.c
index 9c56227b9e..084cf22768 100644
--- a/video/out/drm_common.c
+++ b/video/out/drm_common.c
@@ -944,6 +944,15 @@ void drm_pflip_cb(int fd, unsigned int msc, unsigned int sec,
const uint64_t ust = (sec * 1000000LL) + usec;
const unsigned int msc_since_last_flip = msc - vsync->msc;
+ if (ready && msc == vsync->msc) {
+ // Seems like some drivers only increment msc every other page flip when
+ // running in interlaced mode (I'm looking at you nouveau). Obviously we
+ // can't work with this, so shame the driver and bail.
+ mp_err(closure->log,
+ "Got the same msc value twice: (msc: %u, vsync->msc: %u). This shouldn't happen. Possibly broken driver/interlaced mode?\n",
+ msc, vsync->msc);
+ goto fail;
+ }
vsync->ust = ust;
vsync->msc = msc;
diff --git a/video/out/drm_common.h b/video/out/drm_common.h
index 6ddd0994e3..aa08312ad2 100644
--- a/video/out/drm_common.h
+++ b/video/out/drm_common.h
@@ -66,6 +66,7 @@ struct drm_pflip_cb_closure {
struct drm_vsync_tuple *vsync; // vsync tuple of the latest page flip. drm_pflip_cb updates this
struct vo_vsync_info *vsync_info; // where the drm_pflip_cb routine writes its output
bool *waiting_for_flip; // drm_pflip_cb writes false here before returning
+ struct mp_log *log; // Needed to print error messages that shame bad drivers
};
bool vt_switcher_init(struct vt_switcher *s, struct mp_log *log);
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index 736db7a4ec..3b5dac64da 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -459,6 +459,7 @@ static void queue_flip(struct ra_ctx *ctx, struct gbm_frame *frame)
data->vsync = &p->vsync;
data->vsync_info = &p->vsync_info;
data->waiting_for_flip = &p->waiting_for_flip;
+ data->log = ctx->log;
if (atomic_ctx) {
drm_object_set_property(atomic_ctx->request, atomic_ctx->draw_plane, "FB_ID", p->fb->id);
diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c
index be5b0c52d9..7eee6c66c1 100644
--- a/video/out/vo_drm.c
+++ b/video/out/vo_drm.c
@@ -489,6 +489,7 @@ static void queue_flip(struct vo *vo, struct kms_frame *frame)
data->vsync = &p->vsync;
data->vsync_info = &p->vsync_info;
data->waiting_for_flip = &p->waiting_for_flip;
+ data->log = vo->log;
ret = drmModePageFlip(p->kms->fd, p->kms->crtc_id,
p->cur_fb->fb,