summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkemi <der.richter@gmx.de>2018-02-25 14:35:13 +0100
committerKevin Mitchell <kevmitch@gmail.com>2018-02-28 00:48:44 -0800
commit38d614d8d668f1255f092f825ac4223f774f5991 (patch)
tree3db2740fd1413d7d831778af1d902f59ae9a2145
parent938ad6ebc037ebb32b41619a31b15f8ade712867 (diff)
downloadmpv-38d614d8d668f1255f092f825ac4223f774f5991.tar.bz2
mpv-38d614d8d668f1255f092f825ac4223f774f5991.tar.xz
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.
-rw-r--r--video/out/cocoa-cb/video_layer.swift35
-rw-r--r--video/out/cocoa-cb/window.swift15
2 files changed, 48 insertions, 2 deletions
diff --git a/video/out/cocoa-cb/video_layer.swift b/video/out/cocoa-cb/video_layer.swift
index 2cea79bf3a..8e2eee621b 100644
--- a/video/out/cocoa-cb/video_layer.swift
+++ b/video/out/cocoa-cb/video_layer.swift
@@ -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,
diff --git a/video/out/cocoa-cb/window.swift b/video/out/cocoa-cb/window.swift
index bd94330dcb..f720205e5c 100644
--- a/video/out/cocoa-cb/window.swift
+++ b/video/out/cocoa-cb/window.swift
@@ -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