diff options
author | LongChair <longchair@hotmail.com> | 2018-02-02 08:25:43 +0100 |
---|---|---|
committer | Kevin Mitchell <kevmitch@gmail.com> | 2018-02-07 22:40:30 -0800 |
commit | b01623e0d233f6f326523aee6b82ed06346b229a (patch) | |
tree | 9384f8302f0457f39d2eed31bf6561a19b4ad4f9 /video | |
parent | 9282a34fbf718618b4fb2a19b9043ec6f104eab3 (diff) | |
download | mpv-b01623e0d233f6f326523aee6b82ed06346b229a.tar.bz2 mpv-b01623e0d233f6f326523aee6b82ed06346b229a.tar.xz |
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')
-rw-r--r-- | video/out/opengl/hwdec_drmprime_drm.c | 11 |
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); } } |