mirror of https://github.com/mpv-player/mpv
cocoa-cb: change handling of window aspect ratio changes
i tried being smart and handle aspect ratio differences manually via atomic drawing and resizing to aspect fitted frames. there were a few issues with that. like unexpected visibility of certain System GUI elements on entering fullscreen or visually dropped frames due to the atomic drawing. now we rely on system mechanics to keep the proper aspect ratio of our layer, the recommended way. as a side effect it also fixes a segfault. Fixes #5581
This commit is contained in:
parent
33cffdcbac
commit
8bfeecbc6f
|
@ -30,11 +30,10 @@ class VideoLayer: CAOpenGLLayer {
|
|||
var hasVideo: Bool = false
|
||||
var neededFlips: Int = 0
|
||||
var cglContext: CGLContextObj? = nil
|
||||
var surfaceSize: NSSize?
|
||||
|
||||
enum Draw: Int { case normal = 1, atomic, atomicEnd }
|
||||
var draw: Draw = .normal
|
||||
let drawLock = NSLock()
|
||||
var surfaceSize: NSSize?
|
||||
|
||||
var canDrawOffScreen: Bool = false
|
||||
var lastThread: Thread? = nil
|
||||
|
@ -49,10 +48,7 @@ class VideoLayer: CAOpenGLLayer {
|
|||
|
||||
var inLiveResize: Bool = false {
|
||||
didSet {
|
||||
if inLiveResize == false {
|
||||
isAsynchronous = false
|
||||
neededFlips += 1
|
||||
} else {
|
||||
if inLiveResize {
|
||||
isAsynchronous = true
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +82,9 @@ class VideoLayer: CAOpenGLLayer {
|
|||
pixelFormat pf: CGLPixelFormatObj,
|
||||
forLayerTime t: CFTimeInterval,
|
||||
displayTime ts: UnsafePointer<CVTimeStamp>?) -> Bool {
|
||||
if inLiveResize == false {
|
||||
isAsynchronous = false
|
||||
}
|
||||
return mpv != nil && cocoaCB.backendState == .init
|
||||
}
|
||||
|
||||
|
@ -100,13 +99,7 @@ class VideoLayer: CAOpenGLLayer {
|
|||
}
|
||||
|
||||
func draw(_ ctx: CGLContextObj) {
|
||||
drawLock.lock()
|
||||
updateSurfaceSize()
|
||||
|
||||
let aspectRatioDiff = fabs( (surfaceSize!.width/surfaceSize!.height) -
|
||||
(bounds.size.width/bounds.size.height) )
|
||||
|
||||
if aspectRatioDiff <= 0.005 && draw.rawValue >= Draw.atomic.rawValue {
|
||||
if draw.rawValue >= Draw.atomic.rawValue {
|
||||
if draw == .atomic {
|
||||
draw = .atomicEnd
|
||||
} else {
|
||||
|
@ -114,9 +107,9 @@ class VideoLayer: CAOpenGLLayer {
|
|||
}
|
||||
}
|
||||
|
||||
updateSurfaceSize()
|
||||
mpv.drawRender(surfaceSize!)
|
||||
CGLFlushDrawable(ctx)
|
||||
drawLock.unlock()
|
||||
|
||||
if needsICCUpdate {
|
||||
needsICCUpdate = false
|
||||
|
@ -148,7 +141,7 @@ class VideoLayer: CAOpenGLLayer {
|
|||
NSEnableScreenUpdates()
|
||||
draw = .normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func copyCGLPixelFormat(forDisplayMask mask: UInt32) -> CGLPixelFormatObj {
|
||||
let glVersions: [CGLOpenGLProfile] = [
|
||||
|
|
|
@ -246,20 +246,18 @@ class Window: NSWindow, NSWindowDelegate {
|
|||
}
|
||||
|
||||
func window(_ window: NSWindow, startCustomAnimationToEnterFullScreenWithDuration duration: TimeInterval) {
|
||||
let cRect = contentRect(forFrameRect: frame)
|
||||
var intermediateFrame = aspectFit(rect: cRect, in: targetScreen!.frame)
|
||||
intermediateFrame = frameRect(forContentRect: intermediateFrame)
|
||||
cocoaCB.view.layerContentsPlacement = .scaleProportionallyToFit
|
||||
hideTitleBar()
|
||||
|
||||
NSAnimationContext.runAnimationGroup({ (context) -> Void in
|
||||
context.duration = getFsAnimationDuration(duration - 0.05)
|
||||
window.animator().setFrame(intermediateFrame, display: true)
|
||||
window.animator().setFrame(targetScreen!.frame, display: true)
|
||||
}, completionHandler: { })
|
||||
}
|
||||
|
||||
func window(_ window: NSWindow, startCustomAnimationToExitFullScreenWithDuration duration: TimeInterval) {
|
||||
let newFrame = calculateWindowPosition(for: targetScreen!, withoutBounds: targetScreen == screen)
|
||||
let intermediateFrame = aspectFit(rect: newFrame, in: screen!.frame)
|
||||
cocoaCB.view.layerContentsPlacement = .scaleProportionallyToFill
|
||||
hideTitleBar()
|
||||
setFrame(intermediateFrame, display: true)
|
||||
|
||||
|
@ -281,6 +279,7 @@ class Window: NSWindow, NSWindowDelegate {
|
|||
isInFullscreen = false
|
||||
cocoaCB.flagEvents(VO_EVENT_FULLSCREEN_STATE)
|
||||
endAnimation(calculateWindowPosition(for: targetScreen!, withoutBounds: targetScreen == screen))
|
||||
cocoaCB.view.layerContentsPlacement = .scaleProportionallyToFit
|
||||
}
|
||||
|
||||
func windowDidFailToEnterFullScreen(_ window: NSWindow) {
|
||||
|
@ -293,6 +292,7 @@ class Window: NSWindow, NSWindowDelegate {
|
|||
let newFrame = targetScreen!.frame
|
||||
setFrame(newFrame, display: true)
|
||||
endAnimation()
|
||||
cocoaCB.view.layerContentsPlacement = .scaleProportionallyToFit
|
||||
}
|
||||
|
||||
func endAnimation(_ newFrame: NSRect = NSZeroRect) {
|
||||
|
@ -304,6 +304,7 @@ class Window: NSWindow, NSWindowDelegate {
|
|||
}
|
||||
|
||||
isAnimating = false
|
||||
cocoaCB.layer.neededFlips += 1
|
||||
cocoaCB.isShuttingDown = false
|
||||
}
|
||||
|
||||
|
@ -385,21 +386,7 @@ class Window: NSWindow, NSWindowDelegate {
|
|||
override func setFrame(_ frameRect: NSRect, display flag: Bool) {
|
||||
let newFrame = !isAnimating && isInFullscreen ? targetScreen!.frame :
|
||||
frameRect
|
||||
let aspectRatioDiff = fabs( (newFrame.width/newFrame.height) -
|
||||
(frame.width/frame.height) )
|
||||
|
||||
let isNotUserLiveResize = isAnimating || !(!isAnimating && inLiveResize)
|
||||
if aspectRatioDiff > 0.005 && isNotUserLiveResize {
|
||||
cocoaCB.layer.drawLock.lock()
|
||||
cocoaCB.layer.atomicDrawingStart()
|
||||
}
|
||||
|
||||
super.setFrame(newFrame, display: flag)
|
||||
cocoaCB.layer.neededFlips += 1
|
||||
|
||||
if aspectRatioDiff > 0.005 && isNotUserLiveResize {
|
||||
cocoaCB.layer.drawLock.unlock()
|
||||
}
|
||||
|
||||
if keepAspect {
|
||||
contentAspectRatio = unfsContentFrame!.size
|
||||
|
|
|
@ -57,6 +57,7 @@ class CocoaCB: NSObject {
|
|||
layer = VideoLayer(cocoaCB: self)
|
||||
view.layer = layer
|
||||
view.wantsLayer = true
|
||||
view.layerContentsPlacement = .scaleProportionallyToFit
|
||||
}
|
||||
|
||||
func setMpvHandle(_ ctx: OpaquePointer) {
|
||||
|
@ -133,6 +134,7 @@ class CocoaCB: NSObject {
|
|||
if !window.isVisible {
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
layer.atomicDrawingStart()
|
||||
window.updateSize(wr.size)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue