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.
Unified · Split
| @@ -241,6 +241,10 @@ bool ra_gl_ctx_submit_frame(struct ra_swapchain *sw, const struct vo_frame *fram · 240 unmodified lines | ||
| 241 | 241 | struct priv *p = sw->priv; |
| 242 | 242 | GL *gl = p->gl; |
| 243 | 243 | |
| 244 | + // Dumb hack for drm_egl and vo_gpu_next. | |
| 245 | + if (vo_is_gpu_next(sw->ctx->vo)) | |
| 246 | + return true; | |
| 247 | + | |
| 244 | 248 | if (p->opts->use_glfinish) |
| 245 | 249 | gl->Finish(); |
| 246 | 250 | |
| @@ -388,20 +388,6 @@ static void wait_fence(struct ra_ctx *ctx) · 387 unmodified lines | ||
| 388 | 388 | } |
| 389 | 389 | } |
| 390 | 390 | |
| 391 | −static bool drm_egl_start_frame(struct ra_swapchain *sw, struct ra_fbo *out_fbo) | |
| 392 | −{ | |
| 393 | − struct ra_ctx *ctx = sw->ctx; | |
| 394 | − struct priv *p = ctx->priv; | |
| 395 | − struct vo_drm_state *drm = ctx->vo->drm; | |
| 396 | − | |
| 397 | − if (!drm->atomic_context->request) { | |
| 398 | − drm->atomic_context->request = drmModeAtomicAlloc(); | |
| 399 | − p->drm_params.atomic_request_ptr = &drm->atomic_context->request; | |
| 400 | − } | |
| 401 | − | |
| 402 | − return ra_gl_ctx_start_frame(sw, out_fbo); | |
| 403 | −} | |
| 404 | − | |
| 405 | 391 | static bool drm_egl_submit_frame(struct ra_swapchain *sw, const struct vo_frame *frame) |
| 406 | 392 | { |
| 407 | 393 | struct ra_ctx *ctx = sw->ctx; |
| @@ -419,6 +405,11 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw) · 11 unmodified lines | ||
| 419 | 405 | struct vo_drm_state *drm = ctx->vo->drm; |
| 420 | 406 | const bool drain = drm->paused || drm->still; // True when we need to drain the swapchain |
| 421 | 407 | |
| 408 | + if (!drm->atomic_context->request) { | |
| 409 | + drm->atomic_context->request = drmModeAtomicAlloc(); | |
| 410 | + p->drm_params.atomic_request_ptr = &drm->atomic_context->request; | |
| 411 | + } | |
| 412 | + | |
| 422 | 413 | if (!drm->active) |
| 423 | 414 | return; |
| 424 | 415 | |
| @@ -452,7 +443,6 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw) · 27 unmodified lines | ||
| 452 | 443 | } |
| 453 | 444 | |
| 454 | 445 | static const struct ra_swapchain_fns drm_egl_swapchain = { |
| 455 | − .start_frame = drm_egl_start_frame, | |
| 456 | 446 | .submit_frame = drm_egl_submit_frame, |
| 457 | 447 | .swap_buffers = drm_egl_swap_buffers, |
| 458 | 448 | }; |
| @@ -860,6 +860,12 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts) · 859 unmodified lines | ||
| 860 | 860 | return r; |
| 861 | 861 | } |
| 862 | 862 | |
| 863 | +// Needed by egl_drm | |
| 864 | +bool vo_is_gpu_next(struct vo *vo) | |
| 865 | +{ | |
| 866 | + return vo && vo->driver && vo->driver == &video_out_gpu_next; | |
| 867 | +} | |
| 868 | + | |
| 863 | 869 | // Check if the VO reports that the mpv window is visible. |
| 864 | 870 | bool vo_is_visible(struct vo *vo) |
| 865 | 871 | { |
| @@ -532,6 +532,7 @@ int vo_reconfig2(struct vo *vo, struct mp_image *img); · 531 unmodified lines | ||
| 532 | 532 | |
| 533 | 533 | int vo_control(struct vo *vo, int request, void *data); |
| 534 | 534 | void vo_control_async(struct vo *vo, int request, void *data); |
| 535 | +bool vo_is_gpu_next(struct vo *vo); | |
| 535 | 536 | bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts); |
| 536 | 537 | bool vo_is_visible(struct vo *vo); |
| 537 | 538 | void vo_queue_frame(struct vo *vo, struct vo_frame *frame); |
| @@ -1170,6 +1170,7 @@ done: · 1169 unmodified lines | ||
| 1170 | 1170 | if (!valid) // clear with purple to indicate error |
| 1171 | 1171 | pl_tex_clear(gpu, swframe.fbo, (float[4]){ 0.5, 0.0, 1.0, 1.0 }); |
| 1172 | 1172 | |
| 1173 | + sw->fns->submit_frame(sw, frame); // for drm_egl | |
| 1173 | 1174 | pl_gpu_flush(gpu); |
| 1174 | 1175 | p->frame_pending = true; |
| 1175 | 1176 | return VO_TRUE; |