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:
Akemi 2018-03-05 02:11:25 +01:00 committed by Kevin Mitchell
parent 33cffdcbac
commit 8bfeecbc6f
3 changed files with 16 additions and 34 deletions

View File

@ -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] = [

View File

@ -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

View File

@ -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)
}
}