summaryrefslogtreecommitdiffstats
path: root/video/out/cocoa-cb/video_layer.swift
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/cocoa-cb/video_layer.swift')
-rw-r--r--video/out/cocoa-cb/video_layer.swift114
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()
}
}