Fixed creating a metal renderer without specifying a metal window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 1b308ba..2a90c15 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -47,6 +47,9 @@
/* Apple Metal renderer implementation */
+/* Used to re-create the window with Metal capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
/* macOS requires constants in a buffer to have a 256 byte alignment. */
/* Use native type alignments from https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf */
#ifdef __MACOSX__
@@ -1578,6 +1581,8 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_MetalView view = NULL;
CAMetalLayer *layer = nil;
SDL_SysWMinfo syswm;
+ Uint32 window_flags;
+ SDL_bool changed_window = SDL_FALSE;
SDL_VERSION(&syswm.version);
if (!SDL_GetWindowWMInfo(window, &syswm)) {
@@ -1588,10 +1593,18 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
+ window_flags = SDL_GetWindowFlags(window);
+ if (!(window_flags & SDL_WINDOW_METAL)) {
+ changed_window = SDL_TRUE;
+ if (SDL_RecreateWindow(window, (window_flags & ~SDL_WINDOW_OPENGL) | SDL_WINDOW_METAL) < 0) {
+ goto error;
+ }
+ }
+
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
SDL_OutOfMemory();
- return NULL;
+ goto error;
}
// !!! FIXME: MTLCopyAllDevices() can find other GPUs on macOS...
@@ -1600,7 +1613,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
if (mtldevice == nil) {
SDL_free(renderer);
SDL_SetError("Failed to obtain Metal device");
- return NULL;
+ goto error;
}
view = SDL_Metal_CreateView(window);
@@ -1610,7 +1623,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
[mtldevice release];
#endif
SDL_free(renderer);
- return NULL;
+ goto error;
}
// !!! FIXME: error checking on all of this.
@@ -1622,7 +1635,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
#endif
SDL_Metal_DestroyView(view);
SDL_free(renderer);
- return NULL;
+ goto error;
}
renderer->driverdata = (void*)CFBridgingRetain(data);
@@ -1861,6 +1874,13 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
#endif
return renderer;
+
+error:
+ if (changed_window) {
+ /* Uh oh, better try to put it back... */
+ SDL_RecreateWindow(window, window_flags);
+ }
+ return NULL;
}}
SDL_RenderDriver METAL_RenderDriver = {
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 5cb82b6..bebd566 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1706,10 +1706,12 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
return -1;
}
+ /*
if ((window->flags & SDL_WINDOW_METAL) != (flags & SDL_WINDOW_METAL)) {
SDL_SetError("Can't change SDL_WINDOW_METAL window flag");
return -1;
}
+ */
if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
SDL_SetError("Vulkan and OpenGL not supported on same window");