History

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.

Dudemanguy committed 1 year ago

Commit 0959cde1 parent 8854c745 files · +17 −15Browse files

Unified · Split

5 files
  1. video/out/opengl/context.c +4 −0
  2. video/out/opengl/context_drm_egl.c +5 −15
  3. video/out/vo.c +6 −0
  4. video/out/vo.h +1 −0
  5. video/out/vo_gpu_next.c +1 −0
video/out/opengl/context.c+4−0
@@ -241,6 +241,10 @@ bool ra_gl_ctx_submit_frame(struct ra_swapchain *sw, const struct vo_frame *fram · 240 unmodified lines
241 struct priv *p = sw->priv;241 struct priv *p = sw->priv;
242 GL *gl = p->gl;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 if (p->opts->use_glfinish)248 if (p->opts->use_glfinish)
245 gl->Finish();249 gl->Finish();
246 250
video/out/opengl/context_drm_egl.c+5−15
@@ -388,20 +388,6 @@ static void wait_fence(struct ra_ctx *ctx) · 387 unmodified lines
388 }388 }
389}389}
390 390
391static 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
405static bool drm_egl_submit_frame(struct ra_swapchain *sw, const struct vo_frame *frame)391static bool drm_egl_submit_frame(struct ra_swapchain *sw, const struct vo_frame *frame)
406{392{
407 struct ra_ctx *ctx = sw->ctx;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 struct vo_drm_state *drm = ctx->vo->drm;405 struct vo_drm_state *drm = ctx->vo->drm;
420 const bool drain = drm->paused || drm->still; // True when we need to drain the swapchain406 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 if (!drm->active)413 if (!drm->active)
423 return;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
454static const struct ra_swapchain_fns drm_egl_swapchain = {445static const struct ra_swapchain_fns drm_egl_swapchain = {
455 .start_frame = drm_egl_start_frame,
456 .submit_frame = drm_egl_submit_frame,446 .submit_frame = drm_egl_submit_frame,
457 .swap_buffers = drm_egl_swap_buffers,447 .swap_buffers = drm_egl_swap_buffers,
458};448};
video/out/vo.c+6−0
@@ -860,6 +860,12 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts) · 859 unmodified lines
860 return r;860 return r;
861}861}
862 862
863// Needed by egl_drm
864bool vo_is_gpu_next(struct vo *vo)
865{
866 return vo && vo->driver && vo->driver == &video_out_gpu_next;
867}
868
863// Check if the VO reports that the mpv window is visible.869// Check if the VO reports that the mpv window is visible.
864bool vo_is_visible(struct vo *vo)870bool vo_is_visible(struct vo *vo)
865{871{
video/out/vo.h+1−0
@@ -532,6 +532,7 @@ int vo_reconfig2(struct vo *vo, struct mp_image *img); · 531 unmodified lines
532 532
533int vo_control(struct vo *vo, int request, void *data);533int vo_control(struct vo *vo, int request, void *data);
534void vo_control_async(struct vo *vo, int request, void *data);534void vo_control_async(struct vo *vo, int request, void *data);
535bool vo_is_gpu_next(struct vo *vo);
535bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts);536bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts);
536bool vo_is_visible(struct vo *vo);537bool vo_is_visible(struct vo *vo);
537void vo_queue_frame(struct vo *vo, struct vo_frame *frame);538void vo_queue_frame(struct vo *vo, struct vo_frame *frame);
video/out/vo_gpu_next.c+1−0
@@ -1170,6 +1170,7 @@ done: · 1169 unmodified lines
1170 if (!valid) // clear with purple to indicate error1170 if (!valid) // clear with purple to indicate error
1171 pl_tex_clear(gpu, swframe.fbo, (float[4]){ 0.5, 0.0, 1.0, 1.0 });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 pl_gpu_flush(gpu);1174 pl_gpu_flush(gpu);
1174 p->frame_pending = true;1175 p->frame_pending = true;
1175 return VO_TRUE;1176 return VO_TRUE;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t