path: root/video
diff options
authorLongChair <>2018-02-02 08:25:43 +0100
committerKevin Mitchell <>2018-02-07 22:40:30 -0800
commitb01623e0d233f6f326523aee6b82ed06346b229a (patch)
tree9384f8302f0457f39d2eed31bf6561a19b4ad4f9 /video
parent9282a34fbf718618b4fb2a19b9043ec6f104eab3 (diff)
drmprime interop : Add frames triple buffering
Currently using the drmprime interop with external mpv intgration can lead to rendering issues because the current frame is being released too early. Typically using this with Qt results in one frame shift because Qt will do waitforvsync and swap, rather than swap and waitforvsync. This leads to tearing as the frambuffer is released while being displayed on screen. In order to avoid releasing the framebuffer that is displayed, We keep the framebuffer alive for one more frame with triple buffering to make sure that whatever rendering process is used, the framebuffer will not be released when it's still on screen. This was tested on RockChip Rock64
Diffstat (limited to 'video')
1 files changed, 8 insertions, 3 deletions
diff --git a/video/out/opengl/hwdec_drmprime_drm.c b/video/out/opengl/hwdec_drmprime_drm.c
index faa099a95e..e420bf4f33 100644
--- a/video/out/opengl/hwdec_drmprime_drm.c
+++ b/video/out/opengl/hwdec_drmprime_drm.c
@@ -50,7 +50,7 @@ struct priv {
struct mp_image_params params;
struct drm_atomic_context *ctx;
- struct drm_frame current_frame, old_frame;
+ struct drm_frame current_frame, last_frame, old_frame;
struct mp_rect src, dst;
@@ -71,8 +71,11 @@ static void set_current_frame(struct ra_hwdec *hw, struct drm_frame *frame)
drm_prime_destroy_framebuffer(p->log, p->ctx->fd, &p->old_frame.fb);
- mp_image_setrefp(&p->old_frame.image, p->current_frame.image);
- p->old_frame.fb = p->current_frame.fb;
+ mp_image_setrefp(&p->old_frame.image, p->last_frame.image);
+ p->old_frame.fb = p->last_frame.fb;
+ mp_image_setrefp(&p->last_frame.image, p->current_frame.image);
+ p->last_frame.fb = p->current_frame.fb;
if (frame) {
p->current_frame.fb = frame->fb;
@@ -80,6 +83,8 @@ static void set_current_frame(struct ra_hwdec *hw, struct drm_frame *frame)
} else {
memset(&p->current_frame.fb, 0, sizeof(p->current_frame.fb));
mp_image_setrefp(&p->current_frame.image, NULL);
+ mp_image_setrefp(&p->last_frame.image, NULL);
+ mp_image_setrefp(&p->old_frame.image, NULL);