context_drm_egl: simplify and fix delayed rendering with vo_gpu_next
This backend is a special case where the state of the frame (i.e. is it still) needs to be taken into account when flipping the page because it does its own fencing. vo_gpu_next never calls the submit_frame API in ra_swapchain which meant the drm backend wasn't aware of the state of the frames and thus couldn't respond. This is a bit weird though because in vo_gpu we actually want the ra_gl_ctx_submit_frame call after the custom external drm_egl_submit_frame. But we don't want this in vo_gpu_next, we only want the state update. Be lazy and just compare the vo_drivers, but the way this is currently designed feels wrong. Fixes delayed OSD rendering when you play a still image like an audio file with cover art.
This commit is contained in:
1 parent
8854c74271
commit
0959cdeb03
5 files changed
+17
-15
No files matched your search
@@ -241,6 +241,10 @@ bool ra_gl_ctx_submit_frame(struct ra_swapchain *sw, const struct vo_frame *fram
|
||||
struct priv *p = sw->priv;
|
||||
GL *gl = p->gl;
|
||||
|
||||
// Dumb hack for drm_egl and vo_gpu_next.
|
||||
if (vo_is_gpu_next(sw->ctx->vo))
|
||||
return true;
|
||||
|
||||
if (p->opts->use_glfinish)
|
||||
gl->Finish();
|
||||
|
||||
|
||||
@@ -388,20 +388,6 @@ static void wait_fence(struct ra_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
static bool drm_egl_start_frame(struct ra_swapchain *sw, struct ra_fbo *out_fbo)
|
||||
{
|
||||
struct ra_ctx *ctx = sw->ctx;
|
||||
struct priv *p = ctx->priv;
|
||||
struct vo_drm_state *drm = ctx->vo->drm;
|
||||
|
||||
if (!drm->atomic_context->request) {
|
||||
drm->atomic_context->request = drmModeAtomicAlloc();
|
||||
p->drm_params.atomic_request_ptr = &drm->atomic_context->request;
|
||||
}
|
||||
|
||||
return ra_gl_ctx_start_frame(sw, out_fbo);
|
||||
}
|
||||
|
||||
static bool drm_egl_submit_frame(struct ra_swapchain *sw, const struct vo_frame *frame)
|
||||
{
|
||||
struct ra_ctx *ctx = sw->ctx;
|
||||
@@ -419,6 +405,11 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw)
|
||||
struct vo_drm_state *drm = ctx->vo->drm;
|
||||
const bool drain = drm->paused || drm->still; // True when we need to drain the swapchain
|
||||
|
||||
if (!drm->atomic_context->request) {
|
||||
drm->atomic_context->request = drmModeAtomicAlloc();
|
||||
p->drm_params.atomic_request_ptr = &drm->atomic_context->request;
|
||||
}
|
||||
|
||||
if (!drm->active)
|
||||
return;
|
||||
|
||||
@@ -452,7 +443,6 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw)
|
||||
}
|
||||
|
||||
static const struct ra_swapchain_fns drm_egl_swapchain = {
|
||||
.start_frame = drm_egl_start_frame,
|
||||
.submit_frame = drm_egl_submit_frame,
|
||||
.swap_buffers = drm_egl_swap_buffers,
|
||||
};
|
||||
|
||||
@@ -860,6 +860,12 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
|
||||
return r;
|
||||
}
|
||||
|
||||
// Needed by egl_drm
|
||||
bool vo_is_gpu_next(struct vo *vo)
|
||||
{
|
||||
return vo && vo->driver && vo->driver == &video_out_gpu_next;
|
||||
}
|
||||
|
||||
// Check if the VO reports that the mpv window is visible.
|
||||
bool vo_is_visible(struct vo *vo)
|
||||
{
|
||||
|
||||
@@ -532,6 +532,7 @@ int vo_reconfig2(struct vo *vo, struct mp_image *img);
|
||||
|
||||
int vo_control(struct vo *vo, int request, void *data);
|
||||
void vo_control_async(struct vo *vo, int request, void *data);
|
||||
bool vo_is_gpu_next(struct vo *vo);
|
||||
bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts);
|
||||
bool vo_is_visible(struct vo *vo);
|
||||
void vo_queue_frame(struct vo *vo, struct vo_frame *frame);
|
||||
|
||||
@@ -1170,6 +1170,7 @@ done:
|
||||
if (!valid) // clear with purple to indicate error
|
||||
pl_tex_clear(gpu, swframe.fbo, (float[4]){ 0.5, 0.0, 1.0, 1.0 });
|
||||
|
||||
sw->fns->submit_frame(sw, frame); // for drm_egl
|
||||
pl_gpu_flush(gpu);
|
||||
p->frame_pending = true;
|
||||
return VO_TRUE;
|
||||
|
||||
Reference in new issue
Block a user