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:
Dudemanguy committed 2025-02-23 18:42:16 +00:00
1 parent 8854c74271
commit 0959cdeb03
5 files changed
+17 -15

No files matched your search

+4
View File
@@ -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();
+5 -15
View File
@@ -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,
};
+6
View File
@@ -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)
{
+1
View File
@@ -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);
+1
View File
@@ -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;