mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-29 07:06:59 +08:00
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:
@@ -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
|
||||
-----
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user