Basically whenever the VO does a redraw, we always have to flip buffers for vo_drm and drm_egl. The old way of doing this was checking if the video was paused and if the frame was still. This does work, but what really needs to be known is simply if the VO is redrawing. Since the added VOCTRL_REDRAW tells us this, we can shuffle around some logic and simplify greatly. drm_egl no longer needs its custom override for the submit_frame step so that can be eliminated along with the vo_gpu_next hack. Fixes 0959cdeb038de6484f75eada21f674bcc2407b89.
Unified · Split
| @@ -1046,10 +1046,9 @@ int vo_drm_control(struct vo *vo, int *events, int request, void *arg) · 1045 unmodified lines | |||
| 1046 | } | 1046 | } |
| 1047 | case VOCTRL_PAUSE: | 1047 | case VOCTRL_PAUSE: |
| 1048 | vo->want_redraw = true; | 1048 | vo->want_redraw = true; |
| 1049 | drm->paused = true; | ||
| 1050 | return VO_TRUE; | 1049 | return VO_TRUE; |
| 1051 | case VOCTRL_RESUME: | 1050 | case VOCTRL_REDRAW: |
| 1052 | drm->paused = false; | 1051 | drm->redraw = true; |
| 1053 | return VO_TRUE; | 1052 | return VO_TRUE; |
| 1054 | } | 1053 | } |
| 1055 | return VO_NOTIMPL; | 1054 | return VO_NOTIMPL; |
| @@ -141,8 +141,7 @@ struct vo_drm_state { · 140 unmodified lines | |||
| 141 | bool supported_colorspace; | 141 | bool supported_colorspace; |
| 142 | 142 | ||
| 143 | bool active; | 143 | bool active; |
| 144 | bool paused; | 144 | bool redraw; |
| 145 | bool still; | ||
| 146 | bool vt_switcher_active; | 145 | bool vt_switcher_active; |
| 147 | bool waiting_for_flip; | 146 | bool waiting_for_flip; |
| 148 | 147 | ||
| @@ -241,10 +241,6 @@ 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 | |||
| 248 | if (p->opts->use_glfinish) | 244 | if (p->opts->use_glfinish) |
| 249 | gl->Finish(); | 245 | gl->Finish(); |
| 250 | 246 | ||
| @@ -388,22 +388,11 @@ static void wait_fence(struct ra_ctx *ctx) · 387 unmodified lines | |||
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | static bool drm_egl_submit_frame(struct ra_swapchain *sw, const struct vo_frame *frame) | ||
| 392 | { | ||
| 393 | struct ra_ctx *ctx = sw->ctx; | ||
| 394 | struct vo_drm_state *drm = ctx->vo->drm; | ||
| 395 | |||
| 396 | drm->still = frame->still; | ||
| 397 | |||
| 398 | return ra_gl_ctx_submit_frame(sw, frame); | ||
| 399 | } | ||
| 400 | |||
| 401 | static void drm_egl_swap_buffers(struct ra_swapchain *sw) | 391 | static void drm_egl_swap_buffers(struct ra_swapchain *sw) |
| 402 | { | 392 | { |
| 403 | struct ra_ctx *ctx = sw->ctx; | 393 | struct ra_ctx *ctx = sw->ctx; |
| 404 | struct priv *p = ctx->priv; | 394 | struct priv *p = ctx->priv; |
| 405 | struct vo_drm_state *drm = ctx->vo->drm; | 395 | struct vo_drm_state *drm = ctx->vo->drm; |
| 406 | const bool drain = drm->paused || drm->still; // True when we need to drain the swapchain | ||
| 407 | 396 | ||
| 408 | if (!drm->atomic_context->request) { | 397 | if (!drm->atomic_context->request) { |
| 409 | drm->atomic_context->request = drmModeAtomicAlloc(); | 398 | drm->atomic_context->request = drmModeAtomicAlloc(); |
| @@ -425,7 +414,7 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw) · 15 unmodified lines | |||
| 425 | enqueue_bo(ctx, new_bo); | 414 | enqueue_bo(ctx, new_bo); |
| 426 | new_fence(ctx); | 415 | new_fence(ctx); |
| 427 | 416 | ||
| 428 | while (drain || p->gbm.num_bos > ctx->vo->opts->swapchain_depth || | 417 | while (drm->redraw || p->gbm.num_bos > ctx->vo->opts->swapchain_depth || |
| 429 | !gbm_surface_has_free_buffers(p->gbm.surface)) { | 418 | !gbm_surface_has_free_buffers(p->gbm.surface)) { |
| 430 | if (drm->waiting_for_flip) { | 419 | if (drm->waiting_for_flip) { |
| 431 | vo_drm_wait_on_flip(drm); | 420 | vo_drm_wait_on_flip(drm); |
| @@ -440,10 +429,10 @@ static void drm_egl_swap_buffers(struct ra_swapchain *sw) · 8 unmodified lines | |||
| 440 | } | 429 | } |
| 441 | queue_flip(ctx, p->gbm.bo_queue[1]); | 430 | queue_flip(ctx, p->gbm.bo_queue[1]); |
| 442 | } | 431 | } |
| 432 | drm->redraw = false; | ||
| 443 | } | 433 | } |
| 444 | 434 | ||
| 445 | static const struct ra_swapchain_fns drm_egl_swapchain = { | 435 | static const struct ra_swapchain_fns drm_egl_swapchain = { |
| 446 | .submit_frame = drm_egl_submit_frame, | ||
| 447 | .swap_buffers = drm_egl_swap_buffers, | 436 | .swap_buffers = drm_egl_swap_buffers, |
| 448 | }; | 437 | }; |
| 449 | 438 | ||
| @@ -860,12 +860,6 @@ 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 | ||
| 864 | bool vo_is_gpu_next(struct vo *vo) | ||
| 865 | { | ||
| 866 | return vo && vo->driver && vo->driver == &video_out_gpu_next; | ||
| 867 | } | ||
| 868 | |||
| 869 | // Check if the VO reports that the mpv window is visible. | 863 | // Check if the VO reports that the mpv window is visible. |
| 870 | bool vo_is_visible(struct vo *vo) | 864 | bool vo_is_visible(struct vo *vo) |
| 871 | { | 865 | { |
| @@ -534,7 +534,6 @@ int vo_reconfig2(struct vo *vo, struct mp_image *img); · 533 unmodified lines | |||
| 534 | 534 | ||
| 535 | int vo_control(struct vo *vo, int request, void *data); | 535 | int vo_control(struct vo *vo, int request, void *data); |
| 536 | void vo_control_async(struct vo *vo, int request, void *data); | 536 | void vo_control_async(struct vo *vo, int request, void *data); |
| 537 | bool vo_is_gpu_next(struct vo *vo); | ||
| 538 | bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts); | 537 | bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts); |
| 539 | bool vo_is_visible(struct vo *vo); | 538 | bool vo_is_visible(struct vo *vo); |
| 540 | void vo_queue_frame(struct vo *vo, struct vo_frame *frame); | 539 | void vo_queue_frame(struct vo *vo, struct vo_frame *frame); |
| @@ -308,8 +308,6 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame) · 307 unmodified lines | |||
| 308 | if (!drm->active) | 308 | if (!drm->active) |
| 309 | goto done; | 309 | goto done; |
| 310 | 310 | ||
| 311 | drm->still = frame->still; | ||
| 312 | |||
| 313 | // we redraw the entire image when OSD needs to be redrawn | 311 | // we redraw the entire image when OSD needs to be redrawn |
| 314 | struct framebuffer *fb = p->bufs[p->front_buf]; | 312 | struct framebuffer *fb = p->bufs[p->front_buf]; |
| 315 | const bool repeat = frame->repeat && !frame->redraw; | 313 | const bool repeat = frame->repeat && !frame->redraw; |
| @@ -341,12 +339,11 @@ static void flip_page(struct vo *vo) · 25 unmodified lines | |||
| 341 | { | 339 | { |
| 342 | struct priv *p = vo->priv; | 340 | struct priv *p = vo->priv; |
| 343 | struct vo_drm_state *drm = vo->drm; | 341 | struct vo_drm_state *drm = vo->drm; |
| 344 | const bool drain = drm->paused || drm->still; | ||
| 345 | 342 | ||
| 346 | if (!drm->active) | 343 | if (!drm->active) |
| 347 | return; | 344 | return; |
| 348 | 345 | ||
| 349 | while (drain || p->fb_queue_len > vo->opts->swapchain_depth) { | 346 | while (drm->redraw || p->fb_queue_len > vo->opts->swapchain_depth) { |
| 350 | if (drm->waiting_for_flip) { | 347 | if (drm->waiting_for_flip) { |
| 351 | vo_drm_wait_on_flip(vo->drm); | 348 | vo_drm_wait_on_flip(vo->drm); |
| 352 | swapchain_step(vo); | 349 | swapchain_step(vo); |
| @@ -360,6 +357,7 @@ static void flip_page(struct vo *vo) · 7 unmodified lines | |||
| 360 | } | 357 | } |
| 361 | queue_flip(vo, p->fb_queue[1]); | 358 | queue_flip(vo, p->fb_queue[1]); |
| 362 | } | 359 | } |
| 360 | drm->redraw = false; | ||
| 363 | } | 361 | } |
| 364 | 362 | ||
| 365 | static void get_vsync(struct vo *vo, struct vo_vsync_info *info) | 363 | static void get_vsync(struct vo *vo, struct vo_vsync_info *info) |
| @@ -1170,7 +1170,6 @@ done: · 1169 unmodified lines | |||
| 1170 | if (!valid) // clear with purple to indicate error | 1170 | 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 | ||
| 1174 | pl_gpu_flush(gpu); | 1173 | pl_gpu_flush(gpu); |
| 1175 | p->frame_pending = true; | 1174 | p->frame_pending = true; |
| 1176 | return VO_TRUE; | 1175 | return VO_TRUE; |