11diff --git forkSrcPrefix/meson.build forkDstPrefix/meson.build
2- index 7572769e0e6f280391668c6797d67e37e2dea30f..e6109987a3d38025a5eede04441c03ee23413255 100644
2+ index 7572769..e610998 100644
33--- forkSrcPrefix/meson.build
44+++ forkDstPrefix/meson.build
55@@ -1315,6 +1315,17 @@ if features['vulkan'] and features['x11']
66 sources += files('video/out/vulkan/context_xlib.c')
77 endif
8-
8+
99+ if host_machine.system() == 'darwin'
1010+ moltenvk = get_option('moltenvk').require(
1111+ features['vulkan'],
@@ -20,16 +20,28 @@ index 7572769e0e6f280391668c6797d67e37e2dea30f..e6109987a3d38025a5eede04441c03ee
2020 features += {'vk-khr-display': vulkan.type_name() == 'internal' or
2121 cc.has_function('vkCreateDisplayPlaneSurfaceKHR', prefix: '#include <vulkan/vulkan_core.h>',
2222 dependencies: [vulkan])}
23+ diff --git forkSrcPrefix/meson.options forkDstPrefix/meson.options
24+ index dae0a33..6ed28af 100644
25+ --- forkSrcPrefix/meson.options
26+ +++ forkDstPrefix/meson.options
27+ @@ -101,6 +101,7 @@ option('gl-dxinterop-d3d9', type: 'feature', value: 'auto', description: 'OpenGL
28+ option('ios-gl', type: 'feature', value: 'auto', description: 'iOS OpenGL ES interop support')
29+ option('videotoolbox-gl', type: 'feature', value: 'auto', description: 'Videotoolbox with OpenGL')
30+ option('videotoolbox-pl', type: 'feature', value: 'auto', description: 'Videotoolbox with libplacebo')
31+ + option('moltenvk', type: 'feature', value: 'auto', description: 'Moltenvk context')
32+
33+ # macOS features
34+ option('macos-10-15-4-features', type: 'feature', value: 'auto', description: 'macOS 10.15.4 SDK Features')
2335diff --git forkSrcPrefix/video/out/gpu/context.c forkDstPrefix/video/out/gpu/context.c
24- index 75dd804005ba3a1e36375b47dcc9d9bb756ab867..299841cb256372a04c3d1603f856695ce246ec01 100644
36+ index 75dd804..6389c3d 100644
2537--- forkSrcPrefix/video/out/gpu/context.c
2638+++ forkDstPrefix/video/out/gpu/context.c
2739@@ -50,6 +50,7 @@ extern const struct ra_ctx_fns ra_ctx_vulkan_xlib;
2840 extern const struct ra_ctx_fns ra_ctx_vulkan_android;
2941 extern const struct ra_ctx_fns ra_ctx_vulkan_display;
3042 extern const struct ra_ctx_fns ra_ctx_vulkan_mac;
3143+ extern const struct ra_ctx_fns ra_ctx_vulkan_moltenvk;
32-
44+
3345 /* Direct3D 11 */
3446 extern const struct ra_ctx_fns ra_ctx_d3d11;
3547@@ -93,6 +94,9 @@ static const struct ra_ctx_fns *contexts[] = {
@@ -43,7 +55,7 @@ index 75dd804005ba3a1e36375b47dcc9d9bb756ab867..299841cb256372a04c3d1603f856695c
4355 &ra_ctx_vulkan_mac,
4456 #endif
4557diff --git forkSrcPrefix/video/out/vulkan/common.h forkDstPrefix/video/out/vulkan/common.h
46- index e75cb228f8d99462ccecf7780098ea97ae7cfe02..afc17284773204563f4c90b4860758e61068d460 100644
58+ index e75cb22..afc1728 100644
4759--- forkSrcPrefix/video/out/vulkan/common.h
4860+++ forkDstPrefix/video/out/vulkan/common.h
4961@@ -22,6 +22,9 @@
@@ -58,10 +70,10 @@ index e75cb228f8d99462ccecf7780098ea97ae7cfe02..afc17284773204563f4c90b4860758e6
5870 #endif
5971diff --git forkSrcPrefix/video/out/vulkan/context_moltenvk.m forkDstPrefix/video/out/vulkan/context_moltenvk.m
6072new file mode 100644
61- index 0000000000000000000000000000000000000000..445b907f795b24b8df80389394d4ae7b3f94c6e5
73+ index 0000000..8c8354d
6274--- /dev/null
6375+++ forkDstPrefix/video/out/vulkan/context_moltenvk.m
64- @@ -0,0 +1,96 @@
76+ @@ -0,0 +1,139 @@
6577+ /*
6678+ * This file is part of mpv.
6779+ *
@@ -90,8 +102,36 @@ index 0000000000000000000000000000000000000000..445b907f795b24b8df80389394d4ae7b
90102+ struct priv {
91103+ struct mpvk_ctx vk;
92104+ CAMetalLayer *layer;
105+ + int last_width;
106+ + int last_height;
93107+ };
94108+
109+ + // Use CAMetalLayer.drawableSize as source of truth (not vo->dwidth/dheight)
110+ + // because in embedded WinID scenarios, mpv doesn't know the real window size.
111+ + static bool resize(struct ra_ctx *ctx)
112+ + {
113+ + struct priv *p = ctx->priv;
114+ + CGSize s = p->layer.drawableSize;
115+ + int width = (int)s.width;
116+ + int height = (int)s.height;
117+ +
118+ + if (width <= 0 || height <= 0)
119+ + return false;
120+ +
121+ + // ALWAYS set vo dimensions first, before checking if swapchain needs resize.
122+ + // This is critical because mpv's vo_reconfig overwrites them with video resolution.
123+ + ctx->vo->dwidth = width;
124+ + ctx->vo->dheight = height;
125+ +
126+ + if (width == p->last_width && height == p->last_height)
127+ + return true;
128+ +
129+ + p->last_width = width;
130+ + p->last_height = height;
131+ +
132+ + return ra_vk_ctx_resize(ctx, width, height);
133+ + }
134+ +
95135+ static void moltenvk_uninit(struct ra_ctx *ctx)
96136+ {
97137+ struct priv *p = ctx->priv;
@@ -114,23 +154,27 @@ index 0000000000000000000000000000000000000000..445b907f795b24b8df80389394d4ae7b
114154+ goto fail;
115155+
116156+ p->layer = (__bridge CAMetalLayer *)(intptr_t)ctx->vo->opts->WinID;
157+ +
117158+ VkMetalSurfaceCreateInfoEXT info = {
118- + .sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
119- + .pLayer = p->layer,
159+ + .sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
160+ + .pLayer = p->layer,
120161+ };
121162+
122- + struct ra_ctx_params params = {0};
123- +
124163+ VkInstance inst = vk->vkinst->instance;
125164+ VkResult res = vkCreateMetalSurfaceEXT(inst, &info, NULL, &vk->surface);
126165+ if (res != VK_SUCCESS) {
127166+ MP_MSG(ctx, msgl, "Failed creating MoltenVK surface\n");
128167+ goto fail;
129168+ }
130169+
131- + if (!ra_vk_ctx_init(ctx, vk, params , VK_PRESENT_MODE_FIFO_KHR))
170+ + if (!ra_vk_ctx_init(ctx, vk, (struct ra_ctx_params){0} , VK_PRESENT_MODE_FIFO_KHR))
132171+ goto fail;
133172+
173+ + // Force one initial resize from the layer size, if available.
174+ + p->last_width = 0;
175+ + p->last_height = 0;
176+ + resize(ctx);
177+ +
134178+ return true;
135179+ fail:
136180+ moltenvk_uninit(ctx);
@@ -139,34 +183,33 @@ index 0000000000000000000000000000000000000000..445b907f795b24b8df80389394d4ae7b
139183+
140184+ static bool moltenvk_reconfig(struct ra_ctx *ctx)
141185+ {
142- + struct priv *p = ctx->priv;
143- + CGSize s = p->layer.drawableSize;
144- + ra_vk_ctx_resize(ctx, s.width, s.height);
145- + return true;
186+ + return resize(ctx);
146187+ }
147188+
148189+ static int moltenvk_control(struct ra_ctx *ctx, int *events, int request, void *arg)
149190+ {
150- + return VO_NOTIMPL;
191+ + if (request != VOCTRL_CHECK_EVENTS)
192+ + return VO_NOTIMPL;
193+ +
194+ + struct priv *p = ctx->priv;
195+ + CGSize s = p->layer.drawableSize;
196+ + int w = (int)s.width;
197+ + int h = (int)s.height;
198+ +
199+ + if (w > 0 && h > 0 && (w != p->last_width || h != p->last_height)) {
200+ + if (!resize(ctx))
201+ + return VO_ERROR;
202+ + *events |= VO_EVENT_RESIZE;
203+ + }
204+ +
205+ + return VO_TRUE;
151206+ }
152207+
153208+ const struct ra_ctx_fns ra_ctx_vulkan_moltenvk = {
154- + .type = "vulkan",
155- + .name = "moltenvk",
156- + .reconfig = moltenvk_reconfig,
157- + .control = moltenvk_control,
158- + .init = moltenvk_init,
159- + .uninit = moltenvk_uninit,
209+ + .type = "vulkan",
210+ + .name = "moltenvk",
211+ + .reconfig = moltenvk_reconfig,
212+ + .control = moltenvk_control,
213+ + .init = moltenvk_init,
214+ + .uninit = moltenvk_uninit,
160215+ };
161- diff --git forkSrcPrefix/meson.options forkDstPrefix/meson.options
162- index dae0a333ef71b75a6bb36a236de7feebd99bda40..6ed28af20a09501b4997ca81e86bb198e75327fd 100644
163- --- forkSrcPrefix/meson.options
164- +++ forkDstPrefix/meson.options
165- @@ -101,6 +101,7 @@ option('gl-dxinterop-d3d9', type: 'feature', value: 'auto', description: 'OpenGL
166- option('ios-gl', type: 'feature', value: 'auto', description: 'iOS OpenGL ES interop support')
167- option('videotoolbox-gl', type: 'feature', value: 'auto', description: 'Videotoolbox with OpenGL')
168- option('videotoolbox-pl', type: 'feature', value: 'auto', description: 'Videotoolbox with libplacebo')
169- + option('moltenvk', type: 'feature', value: 'auto', description: 'Moltenvk context')
170-
171- # macOS features
172- option('macos-10-15-4-features', type: 'feature', value: 'auto', description: 'macOS 10.15.4 SDK Features')
0 commit comments