Skip to content

Commit d61d469

Browse files
committed
mac/vulkan: first moltenvk/vulkan mac test
use VK_PRESENT_MODE_FIFO_KHR for video-sync some more changes icc, size backport some fixes debugging shit fix 100% cpu usage, and some wrong frame sizes generalise moltenvk backend log cleanup generalisations add icc profile (incomplete) only clear when newly initialised mac override mac some cleanups mac vulkan use layer struct mac cleanup mac
1 parent a49cd09 commit d61d469

File tree

8 files changed

+443
-2
lines changed

8 files changed

+443
-2
lines changed

osdep/macOS_swift_bridge.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
// including IOKit here again doesn't make sense, but otherwise the swift
18+
// including frameworks here again doesn't make sense, but otherwise the swift
1919
// compiler doesn't include the needed header in our generated header file
2020
#import <IOKit/pwr_mgt/IOPMLib.h>
21+
#import <QuartzCore/QuartzCore.h>
2122

2223
#include "player/client.h"
2324
#include "video/out/libmpv.h"

video/out/gpu/context.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ extern const struct ra_ctx_fns ra_ctx_vulkan_wayland;
5050
extern const struct ra_ctx_fns ra_ctx_vulkan_win;
5151
extern const struct ra_ctx_fns ra_ctx_vulkan_xlib;
5252
extern const struct ra_ctx_fns ra_ctx_vulkan_android;
53+
extern const struct ra_ctx_fns ra_ctx_vulkan_macos;
5354

5455
/* Direct3D 11 */
5556
extern const struct ra_ctx_fns ra_ctx_d3d11;
@@ -106,6 +107,10 @@ static const struct ra_ctx_fns *contexts[] = {
106107
#if HAVE_X11
107108
&ra_ctx_vulkan_xlib,
108109
#endif
110+
// check for molten instead?
111+
#if HAVE_COCOA
112+
&ra_ctx_vulkan_macos,
113+
#endif
109114

110115
#endif
111116
};

video/out/mac/metal_layer.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* This file is part of mpv.
3+
*
4+
* mpv is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* mpv is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
import Cocoa
19+
20+
class MetalLayer: CAMetalLayer {
21+
unowned var common: MacCommon
22+
23+
init(common com: MacCommon) {
24+
common = com
25+
super.init()
26+
27+
//layer.framebufferOnly = false
28+
//layer.drawableSize = NSSize(width: 1024, height: 576)
29+
pixelFormat = .rgba16Float
30+
backgroundColor = NSColor.black.cgColor
31+
32+
if #available(macOS 10.13, *) {
33+
displaySyncEnabled = true
34+
}
35+
}
36+
37+
// necessary for when the layer containing window changes the screen
38+
override init(layer: Any) {
39+
guard let oldLayer = layer as? MetalLayer else {
40+
fatalError("init(layer: Any) passed an invalid layer")
41+
}
42+
common = oldLayer.common
43+
super.init()
44+
}
45+
46+
required init?(coder: NSCoder) {
47+
fatalError("init(coder:) has not been implemented")
48+
}
49+
}

video/out/mac_common.swift

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
/*
2+
* This file is part of mpv.
3+
*
4+
* mpv is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* mpv is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
import Cocoa
19+
20+
class MacCommon: Common {
21+
@objc var layer: MetalLayer?
22+
23+
@objc init(_ vo: UnsafeMutablePointer<vo>) {
24+
let newlog = mp_log_new(vo, vo.pointee.log, "mac")
25+
super.init(newlog)
26+
mpv = MPVHelper(vo, log)
27+
28+
DispatchQueue.main.sync {
29+
layer = MetalLayer(common: self)
30+
initMisc(vo)
31+
}
32+
}
33+
34+
@objc func config(_ vo: UnsafeMutablePointer<vo>) -> Bool {
35+
mpv?.vo = vo
36+
37+
DispatchQueue.main.sync {
38+
initApp()
39+
40+
let (mpv, _, wr) = getInitProperties(vo)
41+
42+
guard let layer = self.layer else {
43+
log.sendError("Something went wrong, no MetalLayer was initialized")
44+
exit(1)
45+
}
46+
47+
print(mpv.vout.dwidth)
48+
print(mpv.vout.dheight)
49+
50+
if window == nil {
51+
initView(vo, layer)
52+
initWindow(vo)
53+
initWindowState()
54+
}
55+
56+
print(mpv.vout.dwidth)
57+
print(mpv.vout.dheight)
58+
print(wr)
59+
60+
if !NSEqualSizes(
61+
window?.unfsContentFramePixel.size ?? NSZeroSize,
62+
NSSize(width: Int(mpv.vout.dwidth), height: Int(mpv.vout.dheight))
63+
) {
64+
print("----update window size")
65+
window?.updateSize(wr.size)
66+
}
67+
68+
mpv.vo.pointee.dwidth = Int32(wr.size.width)
69+
mpv.vo.pointee.dheight = Int32(wr.size.height)
70+
71+
//window?.setOnTop(Bool(mpv.opts.ontop), Int(mpv.opts.ontop_level))
72+
//window?.title = title
73+
74+
// dumb workaround for updating the icc profile on init
75+
// needs to after the first draw
76+
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
77+
self.updateICCProfile()
78+
}
79+
}
80+
81+
return true
82+
}
83+
84+
@objc func uninit(_ vo: UnsafeMutablePointer<vo>) {
85+
window?.waitForAnimation()
86+
87+
DispatchQueue.main.sync {
88+
window?.delegate = nil
89+
window?.close()
90+
91+
uninitCommon()
92+
}
93+
}
94+
95+
func updateRenderSize(_ size: NSSize) {
96+
mpv?.vo.pointee.dwidth = Int32(size.width)
97+
mpv?.vo.pointee.dheight = Int32(size.height)
98+
print("---..--\(size)")
99+
flagEvents(VO_EVENT_RESIZE | VO_EVENT_EXPOSE)
100+
}
101+
102+
// TODO draw in background
103+
104+
// TODO implement this
105+
/*func updateWindowSize(_ vo: UnsafeMutablePointer<vo>) {
106+
guard let opts: mp_vo_opts = mpv.opts,
107+
let targetScreen = getScreenBy(id: Int(opts.screen_id)) ?? NSScreen.main else
108+
{
109+
log.sendWarning("Couldn't update Window size, no Screen available")
110+
return
111+
}
112+
113+
let wr = getWindowGeometry(forScreen: targetScreen, videoOut: vo)
114+
if !(window?.isVisible ?? false) &&
115+
!(window?.isMiniaturized ?? false) &&
116+
!NSApp.isHidden
117+
{
118+
window?.makeKeyAndOrderFront(nil)
119+
}
120+
layer?.atomicDrawingStart()
121+
window?.updateSize(wr.size)
122+
}*/
123+
124+
override func lightSensorUpdate() {
125+
flagEvents(VO_EVENT_AMBIENT_LIGHTING_CHANGED)
126+
}
127+
128+
@objc override func updateICCProfile() {
129+
guard let colorSpace = window?.screen?.colorSpace else {
130+
log.sendWarning("Couldn't update ICC Profile, no color space available")
131+
return
132+
}
133+
134+
if #available(macOS 10.11, *) {
135+
layer?.colorspace = colorSpace.cgColorSpace
136+
}
137+
}
138+
139+
override func windowDidResize(){
140+
print("---window did resize \(window?.frame) \(window?.framePixel.size)")
141+
// TODO broken shit, none optional size
142+
updateRenderSize(window?.framePixel.size ?? NSSize(width: 960, height: 480))
143+
}
144+
145+
override func windowDidChangeScreenProfile() {
146+
updateICCProfile()
147+
flagEvents(VO_EVENT_ICC_PROFILE_CHANGED)
148+
}
149+
150+
override func windowDidChangeBackingProperties() {
151+
layer?.contentsScale = window?.backingScaleFactor ?? 1
152+
windowDidResize()
153+
}
154+
155+
/*
156+
157+
var mpv: MPVHelper
158+
@objc var isShuttingDown: Bool = false
159+
enum State {
160+
case uninitialized
161+
case needsInit
162+
case initialized
163+
}
164+
var backendState: State = .uninitialized
165+
func preinit(_ vo: UnsafeMutablePointer<vo>) {
166+
if backendState == .uninitialized {
167+
backendState = .needsInit
168+
view = View(cocoaCB: self)
169+
view?.layer = layer
170+
view?.wantsLayer = true
171+
view?.layerContentsPlacement = .scaleProportionallyToFit
172+
startDisplayLink(vo)
173+
initLightSensor()
174+
addDisplayReconfigureObserver()
175+
}
176+
}
177+
func reconfig(_ vo: UnsafeMutablePointer<vo>) {
178+
mpv.vo = vo
179+
if backendState == .needsInit {
180+
DispatchQueue.main.sync { self.initBackend(vo) }
181+
} else {
182+
DispatchQueue.main.async {
183+
self.updateWindowSize(vo)
184+
self.layer?.update()
185+
}
186+
}
187+
}
188+
189+
func checkShutdown() {
190+
if isShuttingDown {
191+
shutdown(true)
192+
}
193+
}
194+
195+
func shutdown(_ destroy: Bool = false) {
196+
isShuttingDown = window?.isAnimating ?? false ||
197+
window?.isInFullscreen ?? false && Bool(mpv.opts.native_fs ?? 1)
198+
if window?.isInFullscreen ?? false && !(window?.isAnimating ?? false) {
199+
window?.close()
200+
}
201+
if isShuttingDown { return }
202+
203+
uninit()
204+
setCursorVisiblility(true)
205+
stopDisplaylink()
206+
uninitLightSensor()
207+
removeDisplayReconfigureObserver()
208+
mpv.deinitRender()
209+
mpv.deinitMPV(destroy)
210+
}
211+
212+
@objc func processEvent(_ event: UnsafePointer<mpv_event>) {
213+
switch event.pointee.event_id {
214+
case MPV_EVENT_SHUTDOWN:
215+
shutdown()
216+
case MPV_EVENT_PROPERTY_CHANGE:
217+
if backendState == .initialized {
218+
handlePropertyChange(event)
219+
}
220+
default:
221+
break
222+
}
223+
}
224+
225+
func handlePropertyChange(_ event: UnsafePointer<mpv_event>) {
226+
let pData = OpaquePointer(event.pointee.data)
227+
guard let property = UnsafePointer<mpv_event_property>(pData)?.pointee else {
228+
return
229+
}
230+
231+
switch String(cString: property.name) {
232+
case "macos-title-bar-appearance":
233+
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
234+
titleBar?.set(appearance: data)
235+
}
236+
case "macos-title-bar-material":
237+
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
238+
titleBar?.set(material: data)
239+
}
240+
case "macos-title-bar-color":
241+
if let data = LibmpvHelper.mpvStringArrayToString(property.data) {
242+
titleBar?.set(color: data)
243+
}
244+
default:
245+
break
246+
}
247+
}
248+
*/
249+
}

video/out/vulkan/common.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#if HAVE_WIN32_DESKTOP
2323
#define VK_USE_PLATFORM_WIN32_KHR
2424
#endif
25+
// check for molten instead?
26+
#if HAVE_COCOA
27+
#define VK_USE_PLATFORM_MACOS_MVK
28+
#define VK_USE_PLATFORM_METAL_EXT
29+
#endif
2530

2631
#include <libplacebo/vulkan.h>
2732

0 commit comments

Comments
 (0)