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:
parent
938ad6ebc0
commit
38d614d8d6
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user