From ed2884d7ece0d99e768074c7f4963e88dd41cfa0 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Thu, 24 Sep 2026 06:38:01 +0200 Subject: [PATCH] Stop mpv render from blocking until frame target time mpv_render_context_render slept until each frame's display time (~40ms at 25fps) inside CAOpenGLLayer.display(), blocking main-thread CoreAnimation commits and hitching UI scrolling during playback. Pass MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME=0 and let CGL vsync pace presentation instead. --- Yattee/Services/Player/MPV/MPVClient.swift | 26 +++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/Yattee/Services/Player/MPV/MPVClient.swift b/Yattee/Services/Player/MPV/MPVClient.swift index 62bc5a1c..8504995c 100644 --- a/Yattee/Services/Player/MPV/MPVClient.swift +++ b/Yattee/Services/Player/MPV/MPVClient.swift @@ -2271,18 +2271,28 @@ final class MPVClient: @unchecked Sendable { var flipY: Int32 = 1 var bufferDepth = depth + // Without this, mpv sleeps inside mpv_render_context_render until the + // frame's target display time (a full frame duration, ~40ms at 25fps). + // That sleep happens inside CAOpenGLLayer.display() and blocks the + // main thread's CoreAnimation commits for its whole duration, hitching + // UI scrolling during playback. Vsync on the CGL context paces + // presentation instead. + var blockForTargetTime: Int32 = 0 withUnsafeMutablePointer(to: &fboData) { fboPtr in withUnsafeMutablePointer(to: &flipY) { flipPtr in withUnsafeMutablePointer(to: &bufferDepth) { depthPtr in - var params: [mpv_render_param] = [ - mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: fboPtr), - mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: flipPtr), - mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: depthPtr), - mpv_render_param(type: MPV_RENDER_PARAM_INVALID, data: nil) - ] - _ = params.withUnsafeMutableBufferPointer { paramsPtr in - mpv_render_context_render(renderContext, paramsPtr.baseAddress) + withUnsafeMutablePointer(to: &blockForTargetTime) { blockPtr in + var params: [mpv_render_param] = [ + mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: fboPtr), + mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: flipPtr), + mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: depthPtr), + mpv_render_param(type: MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME, data: blockPtr), + mpv_render_param(type: MPV_RENDER_PARAM_INVALID, data: nil) + ] + _ = params.withUnsafeMutableBufferPointer { paramsPtr in + mpv_render_context_render(renderContext, paramsPtr.baseAddress) + } } } }