vo: set swapchain-depth to 1 in display sync modes

All the math and interpolation assumes immediate presentation of the
frame. VO is driven by VSYNC and it is expected that current frame that
we render will be displayed on current present call, without delay.
This commit is contained in:
Kacper Michajłow
2025-09-23 01:25:06 +02:00
parent f147b133f0
commit d7495e4ea6
16 changed files with 31 additions and 20 deletions
+2
View File
@@ -1999,6 +1999,8 @@ Video
upper limit, the implementation can use a lower latency than requested
internally. A setting of 1 means that the VO will wait for every frame to
become visible before starting to render the next frame. (Default: 3)
If ``--video-sync=display-*`` is used, this option is ignored and the depth
is always 1.
Audio
-----
+2 -2
View File
@@ -511,7 +511,7 @@ static bool d3d11_init(struct ra_ctx *ctx)
.allow_warp = p->opts->warp != 0,
.force_warp = p->opts->warp == 1,
.max_feature_level = p->opts->feature_level,
.max_frame_latency = ctx->vo->opts->swapchain_depth,
.max_frame_latency = vo_swapchain_depth(ctx->vo),
.adapter_name = p->opts->adapter_name,
};
if (!mp_d3d11_create_present_device(ctx->log, &dopts, &p->device))
@@ -550,7 +550,7 @@ static bool d3d11_init(struct ra_ctx *ctx)
.flip = p->opts->flip,
// Add one frame for the backbuffer and one frame of "slack" to reduce
// contention with the window manager when acquiring the backbuffer
.length = ctx->vo->opts->swapchain_depth + 2,
.length = vo_swapchain_depth(ctx->vo) + 2,
.usage = usage,
};
if (!mp_d3d11_create_swapchain(p->device, ctx->log, &scopts, &p->swapchain))
+1 -1
View File
@@ -1137,7 +1137,7 @@ bool vo_drm_init(struct vo *vo)
drm->ev.version = DRM_EVENT_CONTEXT_VERSION;
drm->ev.page_flip_handler = &drm_pflip_cb;
drm->present = mp_present_initialize(drm, drm->vo->opts, VO_MAX_SWAPCHAIN_DEPTH);
drm->present = mp_present_initialize(drm, drm->vo, VO_MAX_SWAPCHAIN_DEPTH);
return true;
+1 -1
View File
@@ -161,7 +161,7 @@ struct gpu_ctx *gpu_ctx_create(struct vo *vo, struct ra_ctx_opts *ctx_opts)
mppl_log_set_probing(ctx->pllog, false);
ctx->swapchain = pl_opengl_create_swapchain(opengl, pl_opengl_swapchain_params(
.max_swapchain_depth = vo->opts->swapchain_depth,
.max_swapchain_depth = vo_swapchain_depth(vo),
.framebuffer.flipped = gl->flipped,
));
if (!ctx->swapchain)
+1 -1
View File
@@ -290,7 +290,7 @@ void ra_gl_ctx_swap_buffers(struct ra_swapchain *sw)
check_pattern(p, step);
}
while (p->num_vsync_fences >= sw->ctx->vo->opts->swapchain_depth) {
while (p->num_vsync_fences >= vo_swapchain_depth(sw->ctx->vo)) {
gl->ClientWaitSync(p->vsync_fences[0], GL_SYNC_FLUSH_COMMANDS_BIT, 1e9);
gl->DeleteSync(p->vsync_fences[0]);
MP_TARRAY_REMOVE_AT(p->vsync_fences, p->num_vsync_fences, 0);
+2 -2
View File
@@ -225,7 +225,7 @@ static bool d3d11_device_create(struct ra_ctx *ctx)
.force_warp = o->d3d11_warp == 1,
.max_feature_level = o->d3d11_feature_level,
.min_feature_level = D3D_FEATURE_LEVEL_9_3,
.max_frame_latency = ctx->vo->opts->swapchain_depth,
.max_frame_latency = vo_swapchain_depth(ctx->vo),
};
if (!mp_d3d11_create_present_device(vo->log, &device_opts, &p->d3d11_device))
return false;
@@ -293,7 +293,7 @@ static bool d3d11_swapchain_surface_create(struct ra_ctx *ctx)
.flip = o->flip,
// Add one frame for the backbuffer and one frame of "slack" to reduce
// contention with the window manager when acquiring the backbuffer
.length = ctx->vo->opts->swapchain_depth + 2,
.length = vo_swapchain_depth(ctx->vo) + 2,
.usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT,
};
if (!mp_d3d11_create_swapchain(p->d3d11_device, vo->log, &swapchain_opts,
+1 -1
View File
@@ -385,7 +385,7 @@ static void drm_egl_swap_buffers(struct ra_ctx *ctx)
}
enqueue_bo(ctx, new_bo);
while (drm->redraw || p->gbm.num_bos > ctx->vo->opts->swapchain_depth ||
while (drm->redraw || p->gbm.num_bos > vo_swapchain_depth(ctx->vo) ||
!gbm_surface_has_free_buffers(p->gbm.surface)) {
if (drm->waiting_for_flip) {
vo_drm_wait_on_flip(drm);
+2 -2
View File
@@ -341,7 +341,7 @@ static void fill_presentparams(struct ra_ctx *ctx,
.BackBufferHeight = ctx->vo->dheight ? ctx->vo->dheight : 1,
// Add one frame for the backbuffer and one frame of "slack" to reduce
// contention with the window manager when acquiring the backbuffer
.BackBufferCount = ctx->vo->opts->swapchain_depth + 2,
.BackBufferCount = vo_swapchain_depth(ctx->vo) + 2,
.SwapEffect = IsWindows7OrGreater() ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_FLIP,
// Automatically get the backbuffer format from the display format
.BackBufferFormat = D3DFMT_UNKNOWN,
@@ -393,7 +393,7 @@ static int d3d_create(struct ra_ctx *ctx)
return -1;
}
IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, ctx->vo->opts->swapchain_depth);
IDirect3DDevice9Ex_SetMaximumFrameLatency(p->device, vo_swapchain_depth(ctx->vo));
// Register the Direct3D device with WGL_NV_dx_interop
p->device_h = gl->DXOpenDeviceNV(p->device);
+3 -3
View File
@@ -57,14 +57,14 @@ void present_sync_get_info(struct mp_present *present, struct vo_vsync_info *inf
LL_APPEND(list_node, present, cur);
}
struct mp_present *mp_present_initialize(void *talloc_ctx, struct mp_vo_opts *opts, int entries)
struct mp_present *mp_present_initialize(void *talloc_ctx, struct vo *vo, int entries)
{
struct mp_present *present = talloc_zero(talloc_ctx, struct mp_present);
for (int i = 0; i < entries; i++) {
struct mp_present_entry *entry = talloc_zero(present, struct mp_present_entry);
LL_APPEND(list_node, present, entry);
}
present->opts = opts;
present->vo = vo;
return present;
}
@@ -114,7 +114,7 @@ void present_sync_update_values(struct mp_present *present, int64_t ust,
struct mp_present_entry *cur = present->head;
int index = 0;
while (cur && ++index) {
if (!cur->ust || index == present->opts->swapchain_depth)
if (!cur->ust || index == vo_swapchain_depth(present->vo))
break;
cur = cur->list_node.next;
}
+2 -2
View File
@@ -39,10 +39,10 @@ struct mp_present_entry {
struct mp_present {
struct mp_present_entry *head, *tail;
struct mp_vo_opts *opts;
struct vo *vo;
};
struct mp_present *mp_present_initialize(void *talloc_ctx, struct mp_vo_opts *opts, int entries);
struct mp_present *mp_present_initialize(void *talloc_ctx, struct vo *vo, int entries);
// Used during the get_vsync call to deliver the presentation statistics to the VO.
void present_sync_get_info(struct mp_present *present, struct vo_vsync_info *info);
+7
View File
@@ -1533,3 +1533,10 @@ struct mp_image_params vo_get_target_params(struct vo *vo)
mp_mutex_unlock(&vo->params_mutex);
return p;
}
int vo_swapchain_depth(struct vo *vo)
{
if (!VS_IS_DISP(vo->opts->video_sync))
return vo->opts->swapchain_depth;
return 1;
}
+2
View File
@@ -578,4 +578,6 @@ struct vo_frame *vo_frame_ref(struct vo_frame *frame);
struct mp_image_params vo_get_current_params(struct vo *vo);
struct mp_image_params vo_get_target_params(struct vo *vo);
int vo_swapchain_depth(struct vo *vo);
#endif /* MPLAYER_VIDEO_OUT_H */
+2 -2
View File
@@ -343,7 +343,7 @@ static void flip_page(struct vo *vo)
if (!drm->active)
return;
while (drm->redraw || p->fb_queue_len > vo->opts->swapchain_depth) {
while (drm->redraw || p->fb_queue_len > vo_swapchain_depth(vo)) {
if (drm->waiting_for_flip) {
vo_drm_wait_on_flip(vo->drm);
swapchain_step(vo);
@@ -389,7 +389,7 @@ static int preinit(struct vo *vo)
goto err;
struct vo_drm_state *drm = vo->drm;
p->buf_count = vo->opts->swapchain_depth + 1;
p->buf_count = vo_swapchain_depth(vo) + 1;
p->bufs = talloc_zero_array(p, struct framebuffer *, p->buf_count);
p->front_buf = 0;
+1 -1
View File
@@ -419,7 +419,7 @@ bool ra_vk_ctx_init(struct ra_ctx *ctx, struct mpvk_ctx *vk,
struct pl_vulkan_swapchain_params pl_params = {
.surface = vk->surface,
.present_mode = preferred_mode,
.swapchain_depth = ctx->vo->opts->swapchain_depth,
.swapchain_depth = vo_swapchain_depth(ctx->vo),
};
if (p->opts->swap_mode >= 0) // user override
+1 -1
View File
@@ -4309,7 +4309,7 @@ bool vo_wayland_init(struct vo *vo)
wl->fback_pool->len = VO_MAX_SWAPCHAIN_DEPTH;
wl->fback_pool->fback = talloc_zero_array(wl->fback_pool, struct wp_presentation_feedback *,
wl->fback_pool->len);
wl->present = mp_present_initialize(wl, wl->opts, VO_MAX_SWAPCHAIN_DEPTH);
wl->present = mp_present_initialize(wl, wl->vo, VO_MAX_SWAPCHAIN_DEPTH);
} else {
MP_VERBOSE(wl, "Compositor doesn't support the %s protocol!\n",
wp_presentation_interface.name);
+1 -1
View File
@@ -695,7 +695,7 @@ bool vo_x11_init(struct vo *vo)
x11_error_output = x11->log;
XSetErrorHandler(x11_errorhandler);
x11->present = mp_present_initialize(x11, x11->opts, VO_MAX_SWAPCHAIN_DEPTH);
x11->present = mp_present_initialize(x11, vo, VO_MAX_SWAPCHAIN_DEPTH);
dispName = XDisplayName(NULL);