From b01623e0d233f6f326523aee6b82ed06346b229a Mon Sep 17 00:00:00 2001 From: LongChair Date: Fri, 2 Feb 2018 08:25:43 +0100 Subject: 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 --- video/out/opengl/hwdec_drmprime_drm.c | 11 ++++++++--- 1 file 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); } } -- cgit v1.2.3