# min-version: 0.40.0 # Backport of upstream mpv commit f74adc4243bd9e1a8ee96d187c939e6232510650 # ("opengl/context: require swap_buffers param for FenceSync"), fixes # upstream #17217. v0.37.0 predates the refactor (commits 8854c74/ # 5ae0e0f) that introduced this regression - it used a different, # correct external_swapchain boolean flag structure that this patch's # field names don't match at all. Confirmed present (buggy) in v0.41.0. --- a/video/out/opengl/context.c 2026-07-13 00:13:22.285143606 +0000 +++ b/video/out/opengl/context.c 2026-07-13 00:13:32.092351785 +0000 @@ -232,7 +232,19 @@ if (p->opts->use_glfinish) gl->Finish(); - if (gl->FenceSync) { + // yauiclient/NextPVR: backport of upstream mpv commit + // f74adc4243bd9e1a8ee96d187c939e6232510650 ("opengl/context: require + // swap_buffers param for FenceSync"), fixes #17217. Commits 8854c74/ + // 5ae0e0f eliminated the external swapchain API vo_libmpv previously + // used to skip these FenceSync calls; that logic change wasn't + // accounted for, so vo_libmpv leaked one GLsync fence into + // p->vsync_fences (a heap-allocated array, not GPU-driver memory) on + // every single frame, since ra_gl_ctx_swap_buffers - the function + // that normally consumes/frees them - is never called for vo_libmpv + // specifically. This is exactly the embedded Render API backend + // (mpv_render_context_render() called repeatedly into an app-owned + // FBO) that yauiclient uses every frame. + if (gl->FenceSync && p->params.swap_buffers) { GLsync fence = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); if (fence) MP_TARRAY_APPEND(p, p->vsync_fences, p->num_vsync_fences, fence);