mirror of
https://github.com/yattee/yattee.git
synced 2025-12-07 08:38:14 +00:00
Improve video layer rendering on macOS
Refactored glUpdate to use requestRedraw method for better control. Added needsRedraw flag to prevent redundant display calls. Enabled asynchronous drawing on VideoLayer for improved performance. Modified displayLinkCallback to only report swap without triggering display to avoid flooding the main thread.
This commit is contained in:
@@ -666,11 +666,8 @@ final class MPVClient: ObservableObject {
|
|||||||
func glUpdate(_ ctx: UnsafeMutableRawPointer?) {
|
func glUpdate(_ ctx: UnsafeMutableRawPointer?) {
|
||||||
let videoLayer = unsafeBitCast(ctx, to: VideoLayer.self)
|
let videoLayer = unsafeBitCast(ctx, to: VideoLayer.self)
|
||||||
|
|
||||||
videoLayer.client?.queue?.async {
|
// Request a redraw when MPV signals that new content is available
|
||||||
if !videoLayer.isAsynchronous {
|
videoLayer.requestRedraw()
|
||||||
videoLayer.display()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
func getProcAddress(_: UnsafeMutableRawPointer?, _ name: UnsafePointer<Int8>?) -> UnsafeMutableRawPointer? {
|
func getProcAddress(_: UnsafeMutableRawPointer?, _ name: UnsafePointer<Int8>?) -> UnsafeMutableRawPointer? {
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ import OpenGL.GL3
|
|||||||
|
|
||||||
final class VideoLayer: CAOpenGLLayer {
|
final class VideoLayer: CAOpenGLLayer {
|
||||||
var client: MPVClient!
|
var client: MPVClient!
|
||||||
|
private var needsRedraw = false
|
||||||
|
private let redrawQueue = DispatchQueue(label: "com.yattee.videolayer.redraw", qos: .userInteractive)
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
|
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
|
||||||
backgroundColor = NSColor.black.cgColor
|
backgroundColor = NSColor.black.cgColor
|
||||||
|
// Enable asynchronous drawing for better performance
|
||||||
|
isAsynchronous = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(*, unavailable)
|
@available(*, unavailable)
|
||||||
@@ -32,6 +36,8 @@ final class VideoLayer: CAOpenGLLayer {
|
|||||||
forLayerTime _: CFTimeInterval,
|
forLayerTime _: CFTimeInterval,
|
||||||
displayTime _: UnsafePointer<CVTimeStamp>?
|
displayTime _: UnsafePointer<CVTimeStamp>?
|
||||||
) {
|
) {
|
||||||
|
needsRedraw = false
|
||||||
|
|
||||||
var i: GLint = 0
|
var i: GLint = 0
|
||||||
var flip: CInt = 1
|
var flip: CInt = 1
|
||||||
var ditherDepth = 8
|
var ditherDepth = 8
|
||||||
@@ -92,13 +98,23 @@ final class VideoLayer: CAOpenGLLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func display() {
|
override func display() {
|
||||||
|
// Mark as needing display without blocking
|
||||||
|
guard !needsRedraw else { return }
|
||||||
|
needsRedraw = true
|
||||||
super.display()
|
super.display()
|
||||||
CATransaction.flush()
|
}
|
||||||
|
|
||||||
|
func requestRedraw() {
|
||||||
|
// Called from MPV's glUpdate callback - use setNeedsDisplay for efficient batching
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
self?.setNeedsDisplay()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let displayLinkCallback: CVDisplayLinkOutputCallback = { _, _, _, _, _, displayLinkContext -> CVReturn in
|
let displayLinkCallback: CVDisplayLinkOutputCallback = { _, _, _, _, _, displayLinkContext -> CVReturn in
|
||||||
let layer: VideoLayer = unsafeBitCast(displayLinkContext, to: VideoLayer.self)
|
let layer: VideoLayer = unsafeBitCast(displayLinkContext, to: VideoLayer.self)
|
||||||
if layer.client?.mpvGL != nil {
|
if layer.client?.mpvGL != nil {
|
||||||
|
// Just report swap - don't trigger display here to avoid flooding main thread
|
||||||
mpv_render_context_report_swap(layer.client.mpvGL)
|
mpv_render_context_report_swap(layer.client.mpvGL)
|
||||||
}
|
}
|
||||||
return kCVReturnSuccess
|
return kCVReturnSuccess
|
||||||
|
|||||||
Reference in New Issue
Block a user