mirror of
https://github.com/yattee/yattee.git
synced 2026-07-31 04:12:03 +00:00
Fix crash in CAOpenGLLayer shadow-copy init on macOS 27 beta
macOS 27 beta routes contentsScale changes (window moving between screens) through Core Animation's implicit-animation path, which builds a presentation copy of the layer via init(layer:). Our override re-ran visual setters on that copy, and -[CAOpenGLLayer setColorspace:] dereferences render state the shadow copy doesn't own, crashing with EXC_BAD_ACCESS. Drop the redundant setter block (super.init(layer:) already copies presentation values) and disable implicit actions around the contentsScale writes in MPVOGLView so the presentation-copy path is never entered for scale updates.
This commit is contained in:
@@ -12,6 +12,7 @@ import AppKit
|
||||
import CoreMedia
|
||||
import CoreVideo
|
||||
import Libmpv
|
||||
import QuartzCore
|
||||
|
||||
// MARK: - MPVOGLView
|
||||
|
||||
@@ -168,8 +169,13 @@ final class MPVOGLView: NSView {
|
||||
stopDisplayLink()
|
||||
startDisplayLink()
|
||||
|
||||
// Update contents scale for new window
|
||||
// Update contents scale for new window. Disable implicit actions so
|
||||
// Core Animation never builds a presentation copy of the GL layer
|
||||
// for this change (crashes on macOS 27 beta).
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
videoLayer?.contentsScale = window.backingScaleFactor
|
||||
CATransaction.commit()
|
||||
|
||||
// Reattaching (e.g. macOS player sheet dismissed via ESC then re-expanded)
|
||||
// detaches this shared view without stopping playback. macOS drawing is
|
||||
@@ -182,9 +188,14 @@ final class MPVOGLView: NSView {
|
||||
override func viewDidChangeBackingProperties() {
|
||||
super.viewDidChangeBackingProperties()
|
||||
|
||||
// Update contents scale when backing properties change
|
||||
// Update contents scale when backing properties change. Disable implicit
|
||||
// actions so Core Animation never builds a presentation copy of the GL
|
||||
// layer for this change (crashes on macOS 27 beta).
|
||||
if let scale = window?.backingScaleFactor {
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
videoLayer?.contentsScale = scale
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
// Update display refresh rate
|
||||
|
||||
@@ -236,15 +236,12 @@ final class MPVOpenGLLayer: CAOpenGLLayer {
|
||||
self.bufferDepth = previousLayer.bufferDepth
|
||||
self.isSetup = previousLayer.isSetup
|
||||
|
||||
// super.init(layer:) already copies presentation values; re-invoking
|
||||
// setters like `colorspace` on the shadow copy dereferences render
|
||||
// state the copy doesn't own and crashes (macOS 27 beta routes
|
||||
// contentsScale changes through this path on screen changes).
|
||||
super.init(layer: layer)
|
||||
|
||||
autoresizingMask = previousLayer.autoresizingMask
|
||||
backgroundColor = previousLayer.backgroundColor
|
||||
isOpaque = previousLayer.isOpaque
|
||||
colorspace = previousLayer.colorspace
|
||||
contentsFormat = previousLayer.contentsFormat
|
||||
isAsynchronous = previousLayer.isAsynchronous
|
||||
|
||||
Task { @MainActor in
|
||||
LoggingService.shared.debug("MPVOpenGLLayer: created shadow copy", category: .mpv)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user