mirror of https://github.com/mpv-player/mpv
cocoa-cb: add support for 10bit opengl rendering
this will request a 16bit half-float framebuffer instead if a 8bit integer framebuffer. Fixes #3613
This commit is contained in:
parent
ff2aed2b56
commit
41f290f54e
|
@ -5075,6 +5075,13 @@ The following video options are currently all specific to ``--vo=gpu`` and
|
||||||
|
|
||||||
OS X only.
|
OS X only.
|
||||||
|
|
||||||
|
``--cocoa-cb-10bit-context=<yes|no>``
|
||||||
|
Creates a 10bit capable pixel format for the context creation (default: yes).
|
||||||
|
Instead of 8bit integer framebuffer a 16bit half-float framebuffer is
|
||||||
|
requested.
|
||||||
|
|
||||||
|
OS X only.
|
||||||
|
|
||||||
``--macos-title-bar-appearance=<appearance>``
|
``--macos-title-bar-appearance=<appearance>``
|
||||||
Sets the appearance of the title bar (default: auto). Not all combinations
|
Sets the appearance of the title bar (default: auto). Not all combinations
|
||||||
of appearances and ``--macos-title-bar-material`` materials make sense or
|
of appearances and ``--macos-title-bar-material`` materials make sense or
|
||||||
|
|
|
@ -139,12 +139,13 @@ class MPVHelper: NSObject {
|
||||||
return flags & UInt64(MPV_RENDER_UPDATE_FRAME.rawValue) > 0
|
return flags & UInt64(MPV_RENDER_UPDATE_FRAME.rawValue) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawRender(_ surface: NSSize, _ ctx: CGLContextObj, skip: Bool = false) {
|
func drawRender(_ surface: NSSize, _ depth: GLint, _ ctx: CGLContextObj, skip: Bool = false) {
|
||||||
deinitLock.lock()
|
deinitLock.lock()
|
||||||
if mpvRenderContext != nil {
|
if mpvRenderContext != nil {
|
||||||
var i: GLint = 0
|
var i: GLint = 0
|
||||||
var flip: CInt = 1
|
var flip: CInt = 1
|
||||||
var skip: CInt = skip ? 1 : 0
|
var skip: CInt = skip ? 1 : 0
|
||||||
|
var ditherDepth = depth
|
||||||
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
|
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
|
||||||
// CAOpenGLLayer has ownership of FBO zero yet can return it to us,
|
// CAOpenGLLayer has ownership of FBO zero yet can return it to us,
|
||||||
// so only utilize a newly received FBO ID if it is nonzero.
|
// so only utilize a newly received FBO ID if it is nonzero.
|
||||||
|
@ -157,6 +158,7 @@ class MPVHelper: NSObject {
|
||||||
var params: [mpv_render_param] = [
|
var params: [mpv_render_param] = [
|
||||||
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: &data),
|
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_FLIP_Y, data: &flip),
|
||||||
|
mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: &ditherDepth),
|
||||||
mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: &skip),
|
mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: &skip),
|
||||||
mpv_render_param()
|
mpv_render_param()
|
||||||
]
|
]
|
||||||
|
|
|
@ -23,6 +23,13 @@ extension NSAppearance.Name {
|
||||||
static let accessibilityHighContrastVibrantLight: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantLight")
|
static let accessibilityHighContrastVibrantLight: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantLight")
|
||||||
static let accessibilityHighContrastVibrantDark: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantDark")
|
static let accessibilityHighContrastVibrantDark: NSAppearance.Name = NSAppearance.Name(rawValue: "NSAppearanceNameAccessibilityVibrantDark")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
|
extension String {
|
||||||
|
static let RGBA16Float: String = kCAContentsFormatRGBA16Float
|
||||||
|
static let RGBA8Uint: String = kCAContentsFormatRGBA8Uint
|
||||||
|
static let gray8Uint: String = kCAContentsFormatGray8Uint
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extension NSPasteboard.PasteboardType {
|
extension NSPasteboard.PasteboardType {
|
||||||
|
@ -73,6 +80,13 @@ extension Array {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Array where Element == [CGLPixelFormatAttribute] {
|
||||||
|
|
||||||
|
func contains(_ obj: [CGLPixelFormatAttribute]) -> Bool {
|
||||||
|
return self.contains(where:{ $0 == obj })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension NSWindow.Level {
|
extension NSWindow.Level {
|
||||||
|
|
||||||
static func +(left: NSWindow.Level, right: Int) -> NSWindow.Level {
|
static func +(left: NSWindow.Level, right: Int) -> NSWindow.Level {
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct macos_opts {
|
||||||
struct m_color macos_title_bar_color;
|
struct m_color macos_title_bar_color;
|
||||||
int macos_fs_animation_duration;
|
int macos_fs_animation_duration;
|
||||||
int cocoa_cb_sw_renderer;
|
int cocoa_cb_sw_renderer;
|
||||||
|
int cocoa_cb_10bit_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
// multithreaded wrapper for mpv_main
|
// multithreaded wrapper for mpv_main
|
||||||
|
|
|
@ -63,6 +63,7 @@ const struct m_sub_options macos_conf = {
|
||||||
({"default", -1})),
|
({"default", -1})),
|
||||||
OPT_CHOICE("cocoa-cb-sw-renderer", cocoa_cb_sw_renderer, 0,
|
OPT_CHOICE("cocoa-cb-sw-renderer", cocoa_cb_sw_renderer, 0,
|
||||||
({"auto", -1}, {"no", 0}, {"yes", 1})),
|
({"auto", -1}, {"no", 0}, {"yes", 1})),
|
||||||
|
OPT_FLAG("cocoa-cb-10bit-context", cocoa_cb_10bit_context, 0),
|
||||||
OPT_REMOVED("macos-title-bar-style", "Split into --macos-title-bar-appearance "
|
OPT_REMOVED("macos-title-bar-style", "Split into --macos-title-bar-appearance "
|
||||||
"and --macos-title-bar-material"),
|
"and --macos-title-bar-material"),
|
||||||
{0}
|
{0}
|
||||||
|
@ -72,6 +73,7 @@ const struct m_sub_options macos_conf = {
|
||||||
.macos_title_bar_color = {0, 0, 0, 0},
|
.macos_title_bar_color = {0, 0, 0, 0},
|
||||||
.macos_fs_animation_duration = -1,
|
.macos_fs_animation_duration = -1,
|
||||||
.cocoa_cb_sw_renderer = -1,
|
.cocoa_cb_sw_renderer = -1,
|
||||||
|
.cocoa_cb_10bit_context = 1
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,16 @@ let glFormatSoftwareBase: [CGLPixelFormatAttribute] = [
|
||||||
kCGLPFADoubleBuffer
|
kCGLPFADoubleBuffer
|
||||||
]
|
]
|
||||||
|
|
||||||
let glFormatOptional: [CGLPixelFormatAttribute] = [
|
let glFormatOptional: [[CGLPixelFormatAttribute]] = [
|
||||||
kCGLPFABackingStore,
|
[kCGLPFABackingStore],
|
||||||
kCGLPFAAllowOfflineRenderers,
|
[kCGLPFAAllowOfflineRenderers],
|
||||||
kCGLPFASupportsAutomaticGraphicsSwitching
|
[kCGLPFASupportsAutomaticGraphicsSwitching]
|
||||||
|
]
|
||||||
|
|
||||||
|
let glFormat10Bit: [CGLPixelFormatAttribute] = [
|
||||||
|
kCGLPFAColorSize,
|
||||||
|
_CGLPixelFormatAttribute(rawValue: 64),
|
||||||
|
kCGLPFAColorFloat
|
||||||
]
|
]
|
||||||
|
|
||||||
let attributeLookUp: [UInt32:String] = [
|
let attributeLookUp: [UInt32:String] = [
|
||||||
|
@ -52,6 +58,8 @@ let attributeLookUp: [UInt32:String] = [
|
||||||
kCGLPFAAccelerated.rawValue: "kCGLPFAAccelerated",
|
kCGLPFAAccelerated.rawValue: "kCGLPFAAccelerated",
|
||||||
kCGLPFADoubleBuffer.rawValue: "kCGLPFADoubleBuffer",
|
kCGLPFADoubleBuffer.rawValue: "kCGLPFADoubleBuffer",
|
||||||
kCGLPFABackingStore.rawValue: "kCGLPFABackingStore",
|
kCGLPFABackingStore.rawValue: "kCGLPFABackingStore",
|
||||||
|
kCGLPFAColorSize.rawValue: "kCGLPFAColorSize",
|
||||||
|
kCGLPFAColorFloat.rawValue: "kCGLPFAColorFloat",
|
||||||
kCGLPFAAllowOfflineRenderers.rawValue: "kCGLPFAAllowOfflineRenderers",
|
kCGLPFAAllowOfflineRenderers.rawValue: "kCGLPFAAllowOfflineRenderers",
|
||||||
kCGLPFASupportsAutomaticGraphicsSwitching.rawValue: "kCGLPFASupportsAutomaticGraphicsSwitching",
|
kCGLPFASupportsAutomaticGraphicsSwitching.rawValue: "kCGLPFASupportsAutomaticGraphicsSwitching",
|
||||||
]
|
]
|
||||||
|
@ -67,6 +75,7 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
var needsFlip: Bool = false
|
var needsFlip: Bool = false
|
||||||
var forceDraw: Bool = false
|
var forceDraw: Bool = false
|
||||||
var surfaceSize: NSSize = NSSize(width: 0, height: 0)
|
var surfaceSize: NSSize = NSSize(width: 0, height: 0)
|
||||||
|
var bufferDepth: GLint = 8
|
||||||
|
|
||||||
enum Draw: Int { case normal = 1, atomic, atomicEnd }
|
enum Draw: Int { case normal = 1, atomic, atomicEnd }
|
||||||
var draw: Draw = .normal
|
var draw: Draw = .normal
|
||||||
|
@ -92,12 +101,16 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
|
|
||||||
init(cocoaCB ccb: CocoaCB) {
|
init(cocoaCB ccb: CocoaCB) {
|
||||||
cocoaCB = ccb
|
cocoaCB = ccb
|
||||||
cglPixelFormat = VideoLayer.createPixelFormat(ccb.mpv)
|
(cglPixelFormat, bufferDepth) = VideoLayer.createPixelFormat(ccb.mpv)
|
||||||
cglContext = VideoLayer.createContext(ccb.mpv, cglPixelFormat)
|
cglContext = VideoLayer.createContext(ccb.mpv, cglPixelFormat)
|
||||||
super.init()
|
super.init()
|
||||||
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
|
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
|
||||||
backgroundColor = NSColor.black.cgColor
|
backgroundColor = NSColor.black.cgColor
|
||||||
|
|
||||||
|
if #available(macOS 10.12, *), bufferDepth > 8 {
|
||||||
|
contentsFormat = .RGBA16Float
|
||||||
|
}
|
||||||
|
|
||||||
var i: GLint = 1
|
var i: GLint = 1
|
||||||
CGLSetParameter(cglContext, kCGLCPSwapInterval, &i)
|
CGLSetParameter(cglContext, kCGLCPSwapInterval, &i)
|
||||||
CGLSetCurrentContext(cglContext)
|
CGLSetCurrentContext(cglContext)
|
||||||
|
@ -150,7 +163,7 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSurfaceSize()
|
updateSurfaceSize()
|
||||||
mpv.drawRender(surfaceSize, ctx)
|
mpv.drawRender(surfaceSize, bufferDepth, ctx)
|
||||||
|
|
||||||
if needsICCUpdate {
|
if needsICCUpdate {
|
||||||
needsICCUpdate = false
|
needsICCUpdate = false
|
||||||
|
@ -206,7 +219,7 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
if isUpdate && needsFlip {
|
if isUpdate && needsFlip {
|
||||||
CGLSetCurrentContext(cglContext)
|
CGLSetCurrentContext(cglContext)
|
||||||
if mpv.isRenderUpdateFrame() {
|
if mpv.isRenderUpdateFrame() {
|
||||||
mpv.drawRender(NSZeroSize, cglContext, skip: true)
|
mpv.drawRender(NSZeroSize, bufferDepth, cglContext, skip: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayLock.unlock()
|
displayLock.unlock()
|
||||||
|
@ -222,17 +235,18 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class func createPixelFormat(_ mpv: MPVHelper) -> CGLPixelFormatObj {
|
class func createPixelFormat(_ mpv: MPVHelper) -> (CGLPixelFormatObj, GLint) {
|
||||||
var pix: CGLPixelFormatObj?
|
var pix: CGLPixelFormatObj?
|
||||||
|
var depth: GLint = 8
|
||||||
var err: CGLError = CGLError(rawValue: 0)
|
var err: CGLError = CGLError(rawValue: 0)
|
||||||
let swRender = mpv.macOpts?.cocoa_cb_sw_renderer ?? -1
|
let swRender = mpv.macOpts?.cocoa_cb_sw_renderer ?? -1
|
||||||
|
|
||||||
if swRender != 1 {
|
if swRender != 1 {
|
||||||
(pix, err) = VideoLayer.findPixelFormat(mpv)
|
(pix, depth, err) = VideoLayer.findPixelFormat(mpv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != kCGLNoError || pix == nil) && swRender != 0 {
|
if (err != kCGLNoError || pix == nil) && swRender != 0 {
|
||||||
(pix, err) = VideoLayer.findPixelFormat(mpv, software: true)
|
(pix, depth, err) = VideoLayer.findPixelFormat(mpv, software: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let pixelFormat = pix, err == kCGLNoError else {
|
guard let pixelFormat = pix, err == kCGLNoError else {
|
||||||
|
@ -240,10 +254,10 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixelFormat
|
return (pixelFormat, depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
class func findPixelFormat(_ mpv: MPVHelper, software: Bool = false) -> (CGLPixelFormatObj?, CGLError) {
|
class func findPixelFormat(_ mpv: MPVHelper, software: Bool = false) -> (CGLPixelFormatObj?, GLint, CGLError) {
|
||||||
var pix: CGLPixelFormatObj?
|
var pix: CGLPixelFormatObj?
|
||||||
var err: CGLError = CGLError(rawValue: 0)
|
var err: CGLError = CGLError(rawValue: 0)
|
||||||
var npix: GLint = 0
|
var npix: GLint = 0
|
||||||
|
@ -251,22 +265,27 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
for ver in glVersions {
|
for ver in glVersions {
|
||||||
var glBase = software ? glFormatSoftwareBase : glFormatBase
|
var glBase = software ? glFormatSoftwareBase : glFormatBase
|
||||||
glBase.insert(CGLPixelFormatAttribute(ver.rawValue), at: 1)
|
glBase.insert(CGLPixelFormatAttribute(ver.rawValue), at: 1)
|
||||||
var glFormat = glBase + glFormatOptional
|
|
||||||
|
|
||||||
for index in stride(from: glFormat.count-1, through: glBase.count-1, by: -1) {
|
var glFormat = [glBase]
|
||||||
let format = glFormat + [_CGLPixelFormatAttribute(rawValue: 0)]
|
if (mpv.macOpts?.cocoa_cb_10bit_context == 1) {
|
||||||
|
glFormat += [glFormat10Bit]
|
||||||
|
}
|
||||||
|
glFormat += glFormatOptional
|
||||||
|
|
||||||
|
for index in stride(from: glFormat.count-1, through: 0, by: -1) {
|
||||||
|
let format = glFormat.flatMap { $0 } + [_CGLPixelFormatAttribute(rawValue: 0)]
|
||||||
err = CGLChoosePixelFormat(format, &pix, &npix)
|
err = CGLChoosePixelFormat(format, &pix, &npix)
|
||||||
|
|
||||||
if err == kCGLBadAttribute || err == kCGLBadPixelFormat || pix == nil {
|
if err == kCGLBadAttribute || err == kCGLBadPixelFormat || pix == nil {
|
||||||
glFormat.remove(at: index)
|
glFormat.remove(at: index)
|
||||||
} else {
|
} else {
|
||||||
let attArray = glFormat.map({ (value: _CGLPixelFormatAttribute) -> String in
|
let attArray = format.map({ (value: _CGLPixelFormatAttribute) -> String in
|
||||||
return attributeLookUp[value.rawValue] ?? "unknown attribute"
|
return attributeLookUp[value.rawValue] ?? String(value.rawValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
mpv.sendVerbose("Created CGL pixel format with attributes: " +
|
mpv.sendVerbose("Created CGL pixel format with attributes: " +
|
||||||
"\(attArray.joined(separator: ", "))")
|
"\(attArray.joined(separator: ", "))")
|
||||||
return (pix, err)
|
return (pix, glFormat.contains(glFormat10Bit) ? 16 : 8, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +299,7 @@ class VideoLayer: CAOpenGLLayer {
|
||||||
mpv.sendWarning("Falling back to software renderer")
|
mpv.sendWarning("Falling back to software renderer")
|
||||||
}
|
}
|
||||||
|
|
||||||
return (pix, err)
|
return (pix, 8, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
class func createContext(_ mpv: MPVHelper, _ pixelFormat: CGLPixelFormatObj) -> CGLContextObj {
|
class func createContext(_ mpv: MPVHelper, _ pixelFormat: CGLPixelFormatObj) -> CGLContextObj {
|
||||||
|
|
Loading…
Reference in New Issue