summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkemi <der.richter@gmx.de>2018-06-12 02:48:31 +0200
committerJan Ekström <jeebjp@gmail.com>2018-11-13 20:43:29 +0200
commit9e466ee6214ed302a6846dd40264cf06eb712b3a (patch)
tree174510e25423da823810d416cb7ceb0392c256b1
parent317d3ac26634d6719c2c70e3e88acbf0c108fd73 (diff)
downloadmpv-9e466ee6214ed302a6846dd40264cf06eb712b3a.tar.bz2
mpv-9e466ee6214ed302a6846dd40264cf06eb712b3a.tar.xz
cocoa-cb: use libmpv's advanced rendering control and timing
this adds support for GPU rendered screenshots, DR (theoretically) and possible other advanced functions in the future that need to be executed from the rendering thread. additionally frames that would be off screen or not be displayed when on screen are being dropped now.
-rw-r--r--osdep/macOS_mpv_helper.swift24
-rw-r--r--video/out/cocoa-cb/video_layer.swift40
-rw-r--r--video/out/cocoa-cb/window.swift6
-rw-r--r--video/out/cocoa_cb_common.swift4
4 files changed, 41 insertions, 33 deletions
diff --git a/osdep/macOS_mpv_helper.swift b/osdep/macOS_mpv_helper.swift
index a1bb03f508..8f6221d87c 100644
--- a/osdep/macOS_mpv_helper.swift
+++ b/osdep/macOS_mpv_helper.swift
@@ -36,6 +36,7 @@ class MPVHelper: NSObject {
var mpctx: UnsafeMutablePointer<MPContext>?
var macOpts: macos_opts?
var fbo: GLint = 1
+ let deinitLock = NSLock()
init(_ mpv: OpaquePointer) {
super.init()
@@ -58,6 +59,7 @@ class MPVHelper: NSObject {
}
func initRender() {
+ var advanced: CInt = 1
let api = UnsafeMutableRawPointer(mutating: (MPV_RENDER_API_TYPE_OPENGL as NSString).utf8String)
var pAddress = mpv_opengl_init_params(get_proc_address: getProcAddress,
get_proc_address_ctx: nil,
@@ -65,6 +67,7 @@ class MPVHelper: NSObject {
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_API_TYPE, data: api),
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, data: &pAddress),
+ mpv_render_param(type: MPV_RENDER_PARAM_ADVANCED_CONTROL, data: &advanced),
mpv_render_param()
]
@@ -110,13 +113,26 @@ class MPVHelper: NSObject {
func reportRenderFlip() {
if mpvRenderContext == nil { return }
- mpv_render_context_report_swap(mpvRenderContext)
+ mpv_render_context_report_swap(mpvRenderContext)
}
- func drawRender(_ surface: NSSize) {
+ func isRenderUpdateFrame() -> Bool {
+ deinitLock.lock()
+ if mpvRenderContext == nil {
+ deinitLock.unlock()
+ return false
+ }
+ let flags: UInt64 = mpv_render_context_update(mpvRenderContext)
+ deinitLock.unlock()
+ return flags & UInt64(MPV_RENDER_UPDATE_FRAME.rawValue) > 0
+ }
+
+ func drawRender(_ surface: NSSize, skip: Bool = false) {
+ deinitLock.lock()
if mpvRenderContext != nil {
var i: GLint = 0
var flip: CInt = 1
+ var skip: CInt = skip ? 1 : 0
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
// CAOpenGLLayer has ownership of FBO zero yet can return it to us,
// so only utilize a newly received FBO ID if it is nonzero.
@@ -129,6 +145,7 @@ class MPVHelper: NSObject {
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: &data),
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: &flip),
+ mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: &skip),
mpv_render_param()
]
mpv_render_context_render(mpvRenderContext, &params);
@@ -136,6 +153,7 @@ class MPVHelper: NSObject {
glClearColor(0, 0, 0, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
}
+ deinitLock.unlock()
}
func setRenderICCProfile(_ profile: NSColorSpace) {
@@ -258,8 +276,10 @@ class MPVHelper: NSObject {
func deinitRender() {
mpv_render_context_set_update_callback(mpvRenderContext, nil, nil)
mp_render_context_set_control_callback(mpvRenderContext, nil, nil)
+ deinitLock.lock()
mpv_render_context_free(mpvRenderContext)
mpvRenderContext = nil
+ deinitLock.unlock()
}
func deinitMPV(_ destroy: Bool = false) {
diff --git a/video/out/cocoa-cb/video_layer.swift b/video/out/cocoa-cb/video_layer.swift
index d6456abe9b..0e14e45dc3 100644
--- a/video/out/cocoa-cb/video_layer.swift
+++ b/video/out/cocoa-cb/video_layer.swift
@@ -28,9 +28,8 @@ 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?
@@ -53,7 +52,7 @@ class VideoLayer: CAOpenGLLayer {
if inLiveResize {
isAsynchronous = true
}
- update()
+ update(force: true)
}
}
@@ -91,7 +90,8 @@ class VideoLayer: CAOpenGLLayer {
if inLiveResize == false {
isAsynchronous = false
}
- return mpv != nil && cocoaCB.backendState == .initialized
+ return mpv != nil && cocoaCB.backendState == .initialized &&
+ (forceDraw || mpv.isRenderUpdateFrame())
}
override func draw(inCGLContext ctx: CGLContextObj,
@@ -99,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
@@ -135,7 +132,7 @@ class VideoLayer: CAOpenGLLayer {
}
func atomicDrawingStart() {
- if draw == .normal && hasVideo {
+ if draw == .normal {
NSDisableScreenUpdates()
draw = .atomic
}
@@ -225,33 +222,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()
}
}
diff --git a/video/out/cocoa-cb/window.swift b/video/out/cocoa-cb/window.swift
index 34a73f88d1..d11706f38b 100644
--- a/video/out/cocoa-cb/window.swift
+++ b/video/out/cocoa-cb/window.swift
@@ -613,6 +613,12 @@ class Window: NSWindow, NSWindowDelegate {
cocoaCB.updateCusorVisibility()
}
+ func windowDidChangeOcclusionState(_ notification: Notification) {
+ if occlusionState.contains(.visible) {
+ cocoaCB.layer.update(force: true)
+ }
+ }
+
func windowWillMove(_ notification: Notification) {
isMoving = true
}
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index 790a07deb8..355fa537e1 100644
--- a/video/out/cocoa_cb_common.swift
+++ b/video/out/cocoa_cb_common.swift
@@ -72,7 +72,6 @@ class CocoaCB: NSObject {
}
func uninit() {
- layer.setVideo(false)
window.orderOut(nil)
}
@@ -81,7 +80,6 @@ class CocoaCB: NSObject {
DispatchQueue.main.sync { self.initBackend(vo) }
} else {
DispatchQueue.main.async {
- self.layer.setVideo(true)
self.updateWindowSize(vo)
self.layer.update()
}
@@ -106,7 +104,6 @@ class CocoaCB: NSObject {
window.makeMain()
window.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
- layer.setVideo(true)
if Bool(opts.fullscreen) {
DispatchQueue.main.async {
@@ -449,7 +446,6 @@ class CocoaCB: NSObject {
func shutdown(_ destroy: Bool = false) {
setCursorVisiblility(true)
- layer.setVideo(false)
stopDisplaylink()
uninitLightSensor()
removeDisplayReconfigureObserver()