diff options
Diffstat (limited to 'video/out/cocoa-cb/video_layer.swift')
-rw-r--r-- | video/out/cocoa-cb/video_layer.swift | 114 |
1 files changed, 69 insertions, 45 deletions
diff --git a/video/out/cocoa-cb/video_layer.swift b/video/out/cocoa-cb/video_layer.swift index 2e347ba22e..ccc84f8fa8 100644 --- a/video/out/cocoa-cb/video_layer.swift +++ b/video/out/cocoa-cb/video_layer.swift @@ -28,10 +28,10 @@ class VideoLayer: CAOpenGLLayer { let videoLock = NSLock() let displayLock = NSLock() - var hasVideo: Bool = false var needsFlip: Bool = false - var canDrawOffScreen: Bool = false + var forceDraw: Bool = false var cglContext: CGLContextObj? = nil + var cglPixelFormat: CGLPixelFormatObj? = nil var surfaceSize: NSSize? enum Draw: Int { case normal = 1, atomic, atomicEnd } @@ -52,7 +52,7 @@ class VideoLayer: CAOpenGLLayer { if inLiveResize { isAsynchronous = true } - update() + update(force: true) } } @@ -61,7 +61,16 @@ class VideoLayer: CAOpenGLLayer { super.init() autoresizingMask = [.layerWidthSizable, .layerHeightSizable] backgroundColor = NSColor.black.cgColor - contentsScale = cocoaCB.window.backingScaleFactor + + cglPixelFormat = copyCGLPixelFormat(forDisplayMask: 0) + CGLCreateContext(cglPixelFormat!, nil, &cglContext) + var i: GLint = 1 + CGLSetParameter(cglContext!, kCGLCPSwapInterval, &i) + CGLSetCurrentContext(cglContext!) + + mpv.initRender() + mpv.setRenderUpdateCallback(updateCallback, context: self) + mpv.setRenderControlCallback(cocoaCB.controlCallback, context: cocoaCB) } override init(layer: Any) { @@ -74,12 +83,6 @@ class VideoLayer: CAOpenGLLayer { fatalError("init(coder:) has not been implemented") } - func setUpRender() { - mpv.initRender() - mpv.setRenderUpdateCallback(updateCallback, context: self) - mpv.setRenderControlCallback(cocoaCB.controlCallback, context: cocoaCB) - } - override func canDraw(inCGLContext ctx: CGLContextObj, pixelFormat pf: CGLPixelFormatObj, forLayerTime t: CFTimeInterval, @@ -87,7 +90,8 @@ class VideoLayer: CAOpenGLLayer { if inLiveResize == false { isAsynchronous = false } - return mpv != nil && cocoaCB.backendState == .init + return mpv != nil && cocoaCB.backendState == .initialized && + (forceDraw || mpv.isRenderUpdateFrame()) } override func draw(inCGLContext ctx: CGLContextObj, @@ -95,11 +99,8 @@ class VideoLayer: CAOpenGLLayer { forLayerTime t: CFTimeInterval, displayTime ts: UnsafePointer<CVTimeStamp>?) { needsFlip = false - canDrawOffScreen = true - draw(ctx) - } + forceDraw = false - func draw(_ ctx: CGLContextObj) { if draw.rawValue >= Draw.atomic.rawValue { if draw == .atomic { draw = .atomicEnd @@ -131,7 +132,7 @@ class VideoLayer: CAOpenGLLayer { } func atomicDrawingStart() { - if draw == .normal && hasVideo { + if draw == .normal { NSDisableScreenUpdates() draw = .atomic } @@ -145,6 +146,20 @@ class VideoLayer: CAOpenGLLayer { } override func copyCGLPixelFormat(forDisplayMask mask: UInt32) -> CGLPixelFormatObj { + if cglPixelFormat != nil { return cglPixelFormat! } + + let attributeLookUp: [UInt32:String] = [ + kCGLOGLPVersion_3_2_Core.rawValue: "kCGLOGLPVersion_3_2_Core", + kCGLOGLPVersion_Legacy.rawValue: "kCGLOGLPVersion_Legacy", + kCGLPFAOpenGLProfile.rawValue: "kCGLPFAOpenGLProfile", + kCGLPFAAccelerated.rawValue: "kCGLPFAAccelerated", + kCGLPFADoubleBuffer.rawValue: "kCGLPFADoubleBuffer", + kCGLPFABackingStore.rawValue: "kCGLPFABackingStore", + kCGLPFAAllowOfflineRenderers.rawValue: "kCGLPFAAllowOfflineRenderers", + kCGLPFASupportsAutomaticGraphicsSwitching.rawValue: "kCGLPFASupportsAutomaticGraphicsSwitching", + 0: "" + ] + let glVersions: [CGLOpenGLProfile] = [ kCGLOGLPVersion_3_2_Core, kCGLOGLPVersion_Legacy @@ -155,6 +170,8 @@ class VideoLayer: CAOpenGLLayer { var npix: GLint = 0 verLoop : for ver in glVersions { + if mpv.macOpts!.cocoa_cb_sw_renderer == 1 { break } + var glAttributes: [CGLPixelFormatAttribute] = [ kCGLPFAOpenGLProfile, CGLPixelFormatAttribute(ver.rawValue), kCGLPFAAccelerated, @@ -170,30 +187,48 @@ class VideoLayer: CAOpenGLLayer { if err == kCGLBadAttribute || err == kCGLBadPixelFormat || pix == nil { glAttributes.remove(at: index) } else { + var attArray = glAttributes.map({ (value: _CGLPixelFormatAttribute) -> String in + return attributeLookUp[value.rawValue]! + }) + attArray.removeLast() + + mpv.sendVerbose("Created CGL pixel format with attributes: " + + "\(attArray.joined(separator: ", "))") break verLoop } } } + if (err != kCGLNoError || pix == nil) && mpv.macOpts!.cocoa_cb_sw_renderer != 0 { + if mpv.macOpts!.cocoa_cb_sw_renderer == -1 { + let errS = String(cString: CGLErrorString(err)) + mpv.sendWarning("Couldn't create hardware accelerated CGL " + + "pixel format, falling back to software " + + "renderer: \(errS) (\(err.rawValue))") + } + + let glAttributes: [CGLPixelFormatAttribute] = [ + kCGLPFAOpenGLProfile, CGLPixelFormatAttribute(kCGLOGLPVersion_3_2_Core.rawValue), + kCGLPFARendererID, CGLPixelFormatAttribute(UInt32(kCGLRendererGenericFloatID)), + kCGLPFADoubleBuffer, + kCGLPFABackingStore, + _CGLPixelFormatAttribute(rawValue: 0) + ] + + err = CGLChoosePixelFormat(glAttributes, &pix, &npix) + } + if err != kCGLNoError || pix == nil { let errS = String(cString: CGLErrorString(err)) - print("Couldn't create CGL pixel format: \(errS) (\(err.rawValue))") + mpv.sendError("Couldn't create any CGL pixel format: \(errS) (\(err.rawValue))") exit(1) } return pix! } override func copyCGLContext(forPixelFormat pf: CGLPixelFormatObj) -> CGLContextObj { - let ctx = super.copyCGLContext(forPixelFormat: pf) - var i: GLint = 1 - CGLSetParameter(ctx, kCGLCPSwapInterval, &i) - CGLSetCurrentContext(ctx) - cglContext = ctx - - if let app = NSApp as? Application { - app.initMPVCore() - } - return ctx + contentsScale = cocoaCB.window.backingScaleFactor + return cglContext! } let updateCallback: mpv_render_update_fn = { (ctx) in @@ -206,33 +241,22 @@ class VideoLayer: CAOpenGLLayer { let isUpdate = needsFlip super.display() CATransaction.flush() - if isUpdate { - if !cocoaCB.window.occlusionState.contains(.visible) && - needsFlip && canDrawOffScreen - { - CGLSetCurrentContext(cglContext!) - draw(cglContext!) - } else if needsFlip { - update() + if isUpdate && needsFlip { + CGLSetCurrentContext(cglContext!) + if mpv.isRenderUpdateFrame() { + mpv.drawRender(NSZeroSize, skip: true) } } displayLock.unlock() } - func setVideo(_ state: Bool) { - videoLock.lock() - hasVideo = state - videoLock.unlock() - } - - func update() { + func update(force: Bool = false) { + if force { forceDraw = true } queue.async { - self.videoLock.lock() - if !self.inLiveResize && self.hasVideo { + if self.forceDraw || !self.inLiveResize { self.needsFlip = true self.display() } - self.videoLock.unlock() } } |