mirror of
https://github.com/yattee/yattee.git
synced 2025-08-09 20:24:06 +00:00
Fixes for MPV in macOS
This commit is contained in:
118
macOS/VideoLayer.swift
Normal file
118
macOS/VideoLayer.swift
Normal file
@@ -0,0 +1,118 @@
|
||||
import Cocoa
|
||||
import OpenGL.GL
|
||||
import OpenGL.GL3
|
||||
|
||||
final class VideoLayer: CAOpenGLLayer {
|
||||
var client: MPVClient!
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
|
||||
backgroundColor = NSColor.black.cgColor
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder _: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func canDraw(
|
||||
inCGLContext _: CGLContextObj,
|
||||
pixelFormat _: CGLPixelFormatObj,
|
||||
forLayerTime _: CFTimeInterval,
|
||||
displayTime _: UnsafePointer<CVTimeStamp>?
|
||||
) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
override func draw(
|
||||
inCGLContext ctx: CGLContextObj,
|
||||
pixelFormat _: CGLPixelFormatObj,
|
||||
forLayerTime _: CFTimeInterval,
|
||||
displayTime _: UnsafePointer<CVTimeStamp>?
|
||||
) {
|
||||
var i: GLint = 0
|
||||
var flip: CInt = 1
|
||||
var ditherDepth = 8
|
||||
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
|
||||
|
||||
if client.mpvGL != nil {
|
||||
var data = mpv_opengl_fbo(fbo: Int32(i),
|
||||
w: Int32(bounds.size.width),
|
||||
h: Int32(bounds.size.height),
|
||||
internal_format: 0)
|
||||
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_DEPTH, data: &ditherDepth),
|
||||
mpv_render_param()
|
||||
]
|
||||
mpv_render_context_render(client.mpvGL, ¶ms)
|
||||
} else {
|
||||
glClearColor(0, 0, 0, 1)
|
||||
glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
|
||||
}
|
||||
|
||||
CGLFlushDrawable(ctx)
|
||||
}
|
||||
|
||||
override func copyCGLPixelFormat(forDisplayMask _: UInt32) -> CGLPixelFormatObj {
|
||||
let attrs: [CGLPixelFormatAttribute] = [
|
||||
kCGLPFAOpenGLProfile, CGLPixelFormatAttribute(kCGLOGLPVersion_3_2_Core.rawValue),
|
||||
kCGLPFADoubleBuffer,
|
||||
kCGLPFAAllowOfflineRenderers,
|
||||
kCGLPFABackingStore,
|
||||
kCGLPFAAccelerated,
|
||||
kCGLPFASupportsAutomaticGraphicsSwitching,
|
||||
_CGLPixelFormatAttribute(rawValue: 0)
|
||||
]
|
||||
|
||||
var npix: GLint = 0
|
||||
var pix: CGLPixelFormatObj?
|
||||
CGLChoosePixelFormat(attrs, &pix, &npix)
|
||||
|
||||
return pix!
|
||||
}
|
||||
|
||||
override func copyCGLContext(forPixelFormat pf: CGLPixelFormatObj) -> CGLContextObj {
|
||||
let ctx = super.copyCGLContext(forPixelFormat: pf)
|
||||
|
||||
var i: GLint = 1
|
||||
CGLSetParameter(ctx, kCGLCPSwapInterval, &i)
|
||||
CGLEnable(ctx, kCGLCEMPEngine)
|
||||
CGLSetCurrentContext(ctx)
|
||||
|
||||
client.create()
|
||||
initDisplayLink()
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
override func display() {
|
||||
super.display()
|
||||
CATransaction.flush()
|
||||
}
|
||||
|
||||
let displayLinkCallback: CVDisplayLinkOutputCallback = { _, _, _, _, _, displayLinkContext -> CVReturn in
|
||||
let layer: VideoLayer = unsafeBitCast(displayLinkContext, to: VideoLayer.self)
|
||||
if layer.client?.mpvGL != nil {
|
||||
mpv_render_context_report_swap(layer.client.mpvGL)
|
||||
}
|
||||
return kCVReturnSuccess
|
||||
}
|
||||
|
||||
func initDisplayLink() {
|
||||
let displayId = UInt32(NSScreen.main?.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as! Int)
|
||||
|
||||
CVDisplayLinkCreateWithCGDisplay(displayId, &client.link)
|
||||
CVDisplayLinkSetOutputCallback(client.link!, displayLinkCallback,
|
||||
UnsafeMutableRawPointer(Unmanaged.passUnretained(client.layer).toOpaque()))
|
||||
CVDisplayLinkStart(client.link!)
|
||||
}
|
||||
|
||||
func uninitDisplaylink() {
|
||||
if CVDisplayLinkIsRunning(client.link!) {
|
||||
CVDisplayLinkStop(client.link!)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user