From 7d769f35419cc78c954cf3d4a10db937c9313c52 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Wed, 14 Oct 2026 20:55:41 +0200 Subject: [PATCH] Skip mpv renders that land after the app went to the background Four build 270 crash logs abort inside the GL driver (GLDContextRec::flushContextInternal) from presentRenderbuffer, reached from the immediate render queued by appDidBecomeActive/resumeRendering. Only displayLinkFired checked isInBackground; renders dispatched directly to the render queue could run, or present, after the app was backgrounded again, where GPU work is not permitted. Check isInBackground at the top of performRender and again before presenting. PiP rendering is unaffected. --- Yattee/Services/Player/MPV/MPVRenderView.swift | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Yattee/Services/Player/MPV/MPVRenderView.swift b/Yattee/Services/Player/MPV/MPVRenderView.swift index 9ddb2106..8550bcd5 100644 --- a/Yattee/Services/Player/MPV/MPVRenderView.swift +++ b/Yattee/Services/Player/MPV/MPVRenderView.swift @@ -900,6 +900,16 @@ final class MPVRenderView: UIView { private func performRender() { defer { isRendering = false } + + // GPU work is not permitted in the background, and presenting there + // aborts inside the GL driver. The display link already checks this, + // but renders queued by appDidBecomeActive/resumeRendering can run + // after the app went back to the background. PiP keeps rendering. + guard !isInBackground || isPiPActive else { + MPVLogging.log("performRender: skipped (app in background)") + return + } + let frameStart = Date() let tFrameStart = CACurrentMediaTime() let gapSincePrevFrame = lastRenderStartMediaTime > 0 ? tFrameStart - lastRenderStartMediaTime : 0 @@ -967,8 +977,11 @@ final class MPVRenderView: UIView { let tRenderEnd = CACurrentMediaTime() - // Present the renderbuffer (skip when PiP is active - main view is hidden anyway) - if !isPiPActive { + // Present the renderbuffer (skip when PiP is active - main view is hidden anyway). + // Re-checked here: the app can enter the background while mpv renders. + if isInBackground && !isPiPActive { + MPVLogging.log("performRender: present skipped (app entered background)") + } else if !isPiPActive { glBindRenderbuffer(GLenum(GL_RENDERBUFFER), colorRenderbuffer) let presented = eaglContext.presentRenderbuffer(Int(GL_RENDERBUFFER)) if !presented {