1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-02 21:12:23 +00:00

cocoa-cb: fix stretched gl surface on window aspect ratio change

when resizing async it's possible that the layer, and the underlying gl
surface, is stretched on an aspect ratio change. to prevent that we do
an atomic resize (resize and draw at the same time). usually max one
unique frame should be dropped but it's possible, depending on the
performance, that more are dropped.
This commit is contained in:
Akemi 2018-02-25 14:35:13 +01:00 committed by Kevin Mitchell
parent 938ad6ebc0
commit 38d614d8d6
2 changed files with 48 additions and 2 deletions

View File

@ -31,6 +31,11 @@ class VideoLayer: CAOpenGLLayer {
var neededFlips: Int = 0
var cglContext: CGLContextObj? = nil
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
@ -42,8 +47,6 @@ class VideoLayer: CAOpenGLLayer {
}
}
var surfaceSize: NSSize?
var inLiveResize: Bool = false {
didSet {
if inLiveResize == false {
@ -97,9 +100,23 @@ 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 == .atomic {
draw = .atomicEnd
} else {
atomicDrawingEnd()
}
}
mpv.drawGLCB(surfaceSize!)
CGLFlushDrawable(ctx)
drawLock.unlock()
if needsICCUpdate {
needsICCUpdate = false
@ -119,6 +136,20 @@ class VideoLayer: CAOpenGLLayer {
}
}
func atomicDrawingStart() {
if draw == .normal && hasVideo {
NSDisableScreenUpdates()
draw = .atomic
}
}
func atomicDrawingEnd() {
if draw.rawValue >= Draw.atomic.rawValue {
NSEnableScreenUpdates()
draw = .normal
}
}
override func copyCGLPixelFormat(forDisplayMask mask: UInt32) -> CGLPixelFormatObj {
let glVersions: [CGLOpenGLProfile] = [
kCGLOGLPVersion_3_2_Core,

View File

@ -376,7 +376,22 @@ 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 {
Swift.print("drawUnLock")
cocoaCB.layer.drawLock.unlock()
}
if keepAspect {
contentAspectRatio = unfsContentFrame!.size