summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Szpakowski <slime73@gmail.com>2019-08-05 12:35:32 -0300
committerAlex Szpakowski <slime73@gmail.com>2019-08-05 12:35:32 -0300
commit90828036d4b346a9b98e1db4fbda87764472fee9 (patch)
tree4336e0519f20dbcd2ad8d8302302d3a2ed1d34b4
parent07a11cf6cdb517932692667ccdcf0b3c4ac92c08 (diff)
downloadsdl-90828036d4b346a9b98e1db4fbda87764472fee9.tar.gz
Add public APIs for creating a Metal view attached to an SDL window. Add SDL_metal.h.
-rw-r--r--CMakeLists.txt99
-rw-r--r--Makefile.in1
-rw-r--r--Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj8
-rw-r--r--Xcode/SDL/SDL.xcodeproj/project.pbxproj4
-rwxr-xr-xconfigure23
-rw-r--r--configure.ac17
-rw-r--r--include/SDL.h1
-rw-r--r--include/SDL_config.h.cmake3
-rw-r--r--include/SDL_config.h.in3
-rw-r--r--include/SDL_config_iphoneos.h4
-rw-r--r--include/SDL_config_macosx.h23
-rw-r--r--include/SDL_metal.h91
-rw-r--r--src/dynapi/SDL_dynapi_overrides.h2
-rw-r--r--src/dynapi/SDL_dynapi_procs.h2
-rw-r--r--src/render/metal/SDL_render_metal.m46
-rw-r--r--src/video/SDL_sysvideo.h8
-rw-r--r--src/video/SDL_video.c21
-rw-r--r--src/video/cocoa/SDL_cocoametalview.h9
-rw-r--r--src/video/cocoa/SDL_cocoametalview.m40
-rw-r--r--src/video/cocoa/SDL_cocoavideo.m6
-rw-r--r--src/video/cocoa/SDL_cocoavulkan.m20
-rw-r--r--src/video/uikit/SDL_uikitmetalview.h13
-rw-r--r--src/video/uikit/SDL_uikitmetalview.m38
-rw-r--r--src/video/uikit/SDL_uikitvideo.m6
-rw-r--r--src/video/uikit/SDL_uikitvulkan.m18
25 files changed, 412 insertions, 94 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e36a8404..a4ed5414f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -373,8 +373,10 @@ set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE})
set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS})
set_option(WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS})
set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS})
+set_option(RENDER_METAL "Enable the Metal render driver" ${APPLE})
set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})
dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF)
+set_option(VIDEO_METAL "Enable Metal support" ${APPLE})
set_option(VIDEO_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS})
dep_option(KMSDRM_SHARED "Dynamically load KMS DRM support" ON "VIDEO_KMSDRM" OFF)
option_string(BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" "OFF")
@@ -1533,6 +1535,69 @@ elseif(APPLE)
set(HAVE_SDL_FILESYSTEM TRUE)
endif()
+ # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
+ if(SDL_VIDEO)
+ if (IOS)
+ set(SDL_VIDEO_DRIVER_UIKIT 1)
+ file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m)
+ set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES})
+ else()
+ CheckCOCOA()
+ if(VIDEO_OPENGL)
+ set(SDL_VIDEO_OPENGL 1)
+ set(SDL_VIDEO_OPENGL_CGL 1)
+ set(SDL_VIDEO_RENDER_OGL 1)
+ set(HAVE_VIDEO_OPENGL TRUE)
+ endif()
+
+ if(VIDEO_OPENGLES)
+ set(SDL_VIDEO_OPENGL_EGL 1)
+ set(SDL_VIDEO_OPENGL_ES2 1)
+ set(SDL_VIDEO_RENDER_OGL_ES2 1)
+ set(HAVE_VIDEO_OPENGLES TRUE)
+ endif()
+ endif()
+
+ if(VIDEO_VULKAN OR VIDEO_METAL OR RENDER_METAL)
+ set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x objective-c")
+ check_c_source_compiles("
+ #include <AvailabilityMacros.h>
+ #import <Metal/Metal.h>
+ #import <QuartzCore/CAMetalLayer.h>
+
+ #if TARGET_OS_SIMULATOR || (!TARGET_CPU_X86_64 && !TARGET_CPU_ARM64)
+ #error Metal doesn't work on this configuration
+ #endif
+ int main()
+ {
+ return 0;
+ }
+ " HAVE_FRAMEWORK_METAL)
+ set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
+ if(HAVE_FRAMEWORK_METAL)
+ set(SDL_FRAMEWORK_METAL 1)
+ set(SDL_FRAMEWORK_QUARTZCORE 1)
+ else()
+ set(VIDEO_VULKAN 0)
+ set(VIDEO_METAL 0)
+ set(RENDER_METAL 0)
+ endif()
+ endif()
+
+ if(VIDEO_METAL)
+ set(SDL_VIDEO_METAL 1)
+ set(HAVE_VIDEO_METAL TRUE)
+ endif()
+
+ if(RENDER_METAL)
+ file(GLOB RENDER_METAL_SOURCES ${SDL2_SOURCE_DIR}/src/render/metal/*.m)
+ set(SOURCE_FILES ${SOURCE_FILES} ${RENDER_METAL_SOURCES})
+ set(SDL_VIDEO_RENDER_METAL 1)
+ set(HAVE_RENDER_METAL TRUE)
+ endif()
+ endif()
+
# Actually load the frameworks at the end so we don't duplicate include.
if(SDL_FRAMEWORK_COREVIDEO)
find_library(COREVIDEO CoreVideo)
@@ -1562,28 +1627,20 @@ elseif(APPLE)
find_library(AUDIOTOOLBOX AudioToolbox)
list(APPEND EXTRA_LIBS ${AUDIOTOOLBOX})
endif()
-
- # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
- if(SDL_VIDEO)
- if (IOS)
- set(SDL_VIDEO_DRIVER_UIKIT 1)
- file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m)
- set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES})
+ if(SDL_FRAMEWORK_METAL)
+ if(IOS)
+ find_library(METAL Metal)
+ list(APPEND EXTRA_LIBS ${METAL})
else()
- CheckCOCOA()
- if(VIDEO_OPENGL)
- set(SDL_VIDEO_OPENGL 1)
- set(SDL_VIDEO_OPENGL_CGL 1)
- set(SDL_VIDEO_RENDER_OGL 1)
- set(HAVE_VIDEO_OPENGL TRUE)
- endif()
-
- if(VIDEO_OPENGLES)
- set(SDL_VIDEO_OPENGL_EGL 1)
- set(SDL_VIDEO_OPENGL_ES2 1)
- set(SDL_VIDEO_RENDER_OGL_ES2 1)
- set(HAVE_VIDEO_OPENGLES TRUE)
- endif()
+ list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,Metal")
+ endif()
+ endif()
+ if(SDL_FRAMEWORK_QUARTZCORE)
+ if(IOS)
+ find_library(QUARTZCORE QuartzCore)
+ list(APPEND EXTRA_LIBS ${QUARTZCORE})
+ else()
+ list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,QuartzCore")
endif()
endif()
diff --git a/Makefile.in b/Makefile.in
index 567624e90..6b4eecf73 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -84,6 +84,7 @@ HDRS = \
SDL_log.h \
SDL_main.h \
SDL_messagebox.h \
+ SDL_metal.h \
SDL_mouse.h \
SDL_mutex.h \
SDL_name.h \
diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
index ef8539b1a..3146cb3e4 100644
--- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
@@ -717,6 +717,7 @@
F3E3C75B224138AE007D243C /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3E3C657224069CE007D243C /* SDL_uikit_main.c */; };
FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */; };
FA1DC2731C62BE65008F99A0 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */; };
+ FA24348D21D4201400B8918A /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348C21D4201400B8918A /* SDL_metal.h */; };
FAB5981D1BB5C31500BE72C5 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
FAB5981E1BB5C31500BE72C5 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
FAB5981F1BB5C31500BE72C5 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.m */; };
@@ -1064,6 +1065,7 @@
F3E3C75F224138AE007D243C /* libSDLmain.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDLmain.a; sourceTree = BUILT_PRODUCTS_DIR; };
FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitclipboard.h; sourceTree = "<group>"; };
FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitclipboard.m; sourceTree = "<group>"; };
+ FA24348C21D4201400B8918A /* SDL_metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_metal.h; sourceTree = "<group>"; };
FAB598141BB5C1B100BE72C5 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; };
FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick_c.h; sourceTree = "<group>"; };
FD0BBFEF0E3933DD00D833B1 /* SDL_uikitview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitview.h; sourceTree = "<group>"; };
@@ -1576,15 +1578,14 @@
children = (
AA7558651595D55500BBD41B /* begin_code.h */,
AA7558661595D55500BBD41B /* close_code.h */,
- AA7558971595D55500BBD41B /* SDL.h */,
AA7558671595D55500BBD41B /* SDL_assert.h */,
AA7558681595D55500BBD41B /* SDL_atomic.h */,
AA7558691595D55500BBD41B /* SDL_audio.h */,
AADA5B8E16CCAB7C00107CF7 /* SDL_bits.h */,
AA75586A1595D55500BBD41B /* SDL_blendmode.h */,
AA75586B1595D55500BBD41B /* SDL_clipboard.h */,
- AA75586D1595D55500BBD41B /* SDL_config.h */,
AA75586C1595D55500BBD41B /* SDL_config_iphoneos.h */,
+ AA75586D1595D55500BBD41B /* SDL_config.h */,
AA75586E1595D55500BBD41B /* SDL_copying.h */,
AA75586F1595D55500BBD41B /* SDL_cpuinfo.h */,
AA7558701595D55500BBD41B /* SDL_endian.h */,
@@ -1602,6 +1603,7 @@
AA75587B1595D55500BBD41B /* SDL_log.h */,
AA75587C1595D55500BBD41B /* SDL_main.h */,
AA9FF9501637C6E5000DF050 /* SDL_messagebox.h */,
+ FA24348C21D4201400B8918A /* SDL_metal.h */,
AA75587D1595D55500BBD41B /* SDL_mouse.h */,
AA75587E1595D55500BBD41B /* SDL_mutex.h */,
AA75587F1595D55500BBD41B /* SDL_name.h */,
@@ -1630,6 +1632,7 @@
AA7558951595D55500BBD41B /* SDL_version.h */,
AA7558961595D55500BBD41B /* SDL_video.h */,
4D7516FE1EE1C5B400820EEA /* SDL_vulkan.h */,
+ AA7558971595D55500BBD41B /* SDL.h */,
);
name = "Public Headers";
path = ../../include;
@@ -2183,6 +2186,7 @@
AA75589D1595D55500BBD41B /* SDL_blendmode.h in Headers */,
F30D9C9E212CD0990047DF2E /* SDL_sensor_c.h in Headers */,
AA75589E1595D55500BBD41B /* SDL_clipboard.h in Headers */,
+ FA24348D21D4201400B8918A /* SDL_metal.h in Headers */,
AA75589F1595D55500BBD41B /* SDL_config_iphoneos.h in Headers */,
AA7558A01595D55500BBD41B /* SDL_config.h in Headers */,
AA7558A11595D55500BBD41B /* SDL_copying.h in Headers */,
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index 59c86f211..52f13896a 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -919,6 +919,7 @@
F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3950CD9212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3950CDA212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348A21D41FFB00B8918A /* SDL_metal.h */; };
FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
@@ -1252,6 +1253,7 @@
F59C710300D5CB5801000001 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ReadMe.txt; sourceTree = "<group>"; };
F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = "<group>"; };
F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; };
+ FA24348A21D41FFB00B8918A /* SDL_metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_metal.h; sourceTree = "<group>"; };
FA73671C19A540EF004122E4 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coreaudio.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -1342,6 +1344,7 @@
AA7557DD1595D4D800BBD41B /* SDL_log.h */,
AA7557DE1595D4D800BBD41B /* SDL_main.h */,
AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */,
+ FA24348A21D41FFB00B8918A /* SDL_metal.h */,
AA7557DF1595D4D800BBD41B /* SDL_mouse.h */,
AA7557E01595D4D800BBD41B /* SDL_mutex.h */,
AA7557E11595D4D800BBD41B /* SDL_name.h */,
@@ -2029,6 +2032,7 @@
AA75580E1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */,
AA7558101595D4D800BBD41B /* SDL_endian.h in Headers */,
AA7558121595D4D800BBD41B /* SDL_error.h in Headers */,
+ FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */,
AA7558141595D4D800BBD41B /* SDL_events.h in Headers */,
567E2F2117C44C35005F1892 /* SDL_filesystem.h in Headers */,
A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */,
diff --git a/configure b/configure
index 8e0cefb2a..cfd607842 100755
--- a/configure
+++ b/configure
@@ -869,6 +869,7 @@ enable_video_x11_xshape
enable_video_x11_vm
enable_video_vivante
enable_video_cocoa
+enable_video_metal
enable_render_metal
enable_video_directfb
enable_directfb_shared
@@ -1647,6 +1648,7 @@ Optional Features:
--enable-video-x11-vm use X11 VM extension for fullscreen [[default=yes]]
--enable-video-vivante use Vivante EGL video driver [[default=yes]]
--enable-video-cocoa use Cocoa video driver [[default=yes]]
+ --enable-video-metal include Metal support [[default=yes]]
--enable-render-metal enable the Metal render driver [[default=yes]]
--enable-video-directfb use DirectFB video driver [[default=no]]
--enable-directfb-shared
@@ -21530,6 +21532,13 @@ $as_echo "#define SDL_VIDEO_DRIVER_COCOA 1" >>confdefs.h
CheckMETAL()
{
+ # Check whether --enable-video-metal was given.
+if test "${enable_video_metal+set}" = set; then :
+ enableval=$enable_video_metal;
+else
+ enable_video_metal=yes
+fi
+
# Check whether --enable-render-metal was given.
if test "${enable_render_metal+set}" = set; then :
enableval=$enable_render_metal;
@@ -21537,7 +21546,7 @@ else
enable_render_metal=yes
fi
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video = xyes -a x$enable_video_metal = xyes; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -x objective-c"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Metal framework" >&5
@@ -21574,11 +21583,17 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
$as_echo "$have_metal" >&6; }
if test x$have_metal = xyes; then
+$as_echo "#define SDL_VIDEO_METAL 1" >>confdefs.h
+
+ if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+
$as_echo "#define SDL_VIDEO_RENDER_METAL 1" >>confdefs.h
- SOURCES="$SOURCES $srcdir/src/render/metal/*.m"
+ SOURCES="$SOURCES $srcdir/src/render/metal/*.m"
+ fi
SUMMARY_video="${SUMMARY_video} metal"
else
+ enable_video_metal=no
enable_render_metal=no
fi
fi
@@ -25064,7 +25079,7 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,UIKit"
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video_metal = xyes -o x$enable_video_vulkan = xyes; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Metal"
fi
;;
@@ -25158,7 +25173,7 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video_metal = xyes -o x$enable_video_vulkan = xyes; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,Metal"
fi
;;
diff --git a/configure.ac b/configure.ac
index c6fd37f44..62145acb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2048,10 +2048,13 @@ AS_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [[default=yes]]])
CheckMETAL()
{
+ AC_ARG_ENABLE(video-metal,
+AC_HELP_STRING([--enable-video-metal], [include Metal support [[default=yes]]]),
+ , enable_video_metal=yes)
AC_ARG_ENABLE(render-metal,
AS_HELP_STRING([--enable-render-metal], [enable the Metal render driver [[default=yes]]]),
, enable_render_metal=yes)
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video = xyes -a x$enable_video_metal = xyes; then
save_CFLAGS="$CFLAGS"
dnl Work around that we don't have Objective-C support in autoconf
CFLAGS="$CFLAGS -x objective-c"
@@ -2072,10 +2075,14 @@ AS_HELP_STRING([--enable-render-metal], [enable the Metal render driver [[defaul
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($have_metal)
if test x$have_metal = xyes; then
- AC_DEFINE(SDL_VIDEO_RENDER_METAL, 1, [ ])
- SOURCES="$SOURCES $srcdir/src/render/metal/*.m"
+ AC_DEFINE(SDL_VIDEO_METAL, 1, [ ])
+ if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ AC_DEFINE(SDL_VIDEO_RENDER_METAL, 1, [ ])
+ SOURCES="$SOURCES $srcdir/src/render/metal/*.m"
+ fi
SUMMARY_video="${SUMMARY_video} metal"
else
+ enable_video_metal=no
enable_render_metal=no
fi
fi
@@ -3828,7 +3835,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,UIKit"
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video_metal = xyes -o x$enable_video_vulkan = xyes; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Metal"
fi
;;
@@ -3910,7 +3917,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
- if test x$enable_render = xyes -a x$enable_render_metal = xyes; then
+ if test x$enable_video_metal = xyes -o x$enable_video_vulkan = xyes; then
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,Metal"
fi
;;
diff --git a/include/SDL.h b/include/SDL.h
index 88dce0c03..e43293959 100644
--- a/include/SDL.h
+++ b/include/SDL.h
@@ -47,6 +47,7 @@
#include "SDL_loadso.h"
#include "SDL_log.h"
#include "SDL_messagebox.h"
+#include "SDL_metal.h"
#include "SDL_mutex.h"
#include "SDL_power.h"
#include "SDL_render.h"
diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake
index 75ff0bb7a..65ba3ea70 100644
--- a/include/SDL_config.h.cmake
+++ b/include/SDL_config.h.cmake
@@ -388,6 +388,9 @@
/* Enable Vulkan support */
#cmakedefine SDL_VIDEO_VULKAN @SDL_VIDEO_VULKAN@
+/* Enable Metal support */
+#cmakedefine SDL_VIDEO_METAL @SDL_VIDEO_METAL@
+
/* Enable system power support */
#cmakedefine SDL_POWER_ANDROID @SDL_POWER_ANDROID@
#cmakedefine SDL_POWER_LINUX @SDL_POWER_LINUX@
diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in
index e4eb6f648..6d5d13ecc 100644
--- a/include/SDL_config.h.in
+++ b/include/SDL_config.h.in
@@ -383,6 +383,9 @@
/* Enable Vulkan support */
#undef SDL_VIDEO_VULKAN
+/* Enable Metal support */
+#undef SDL_VIDEO_METAL
+
/* Enable system power support */
#undef SDL_POWER_LINUX
#undef SDL_POWER_WINDOWS
diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h
index a3bf2e8ff..8137085ed 100644
--- a/include/SDL_config_iphoneos.h
+++ b/include/SDL_config_iphoneos.h
@@ -181,6 +181,10 @@
#define SDL_VIDEO_VULKAN 1
#endif
+#if SDL_PLATFORM_SUPPORTS_METAL
+#define SDL_VIDEO_METAL 1
+#endif
+
/* Enable system power support */
#define SDL_POWER_UIKIT 1
diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h
index 16d05097d..254c36d79 100644
--- a/include/SDL_config_macosx.h
+++ b/include/SDL_config_macosx.h
@@ -193,9 +193,15 @@
#define SDL_VIDEO_RENDER_OGL_ES2 1
#endif
-#ifndef SDL_VIDEO_RENDER_METAL
/* Metal only supported on 64-bit architectures with 10.11+ */
#if TARGET_CPU_X86_64 && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100)
+#define SDL_PLATFORM_SUPPORTS_METAL 1
+#else
+#define SDL_PLATFORM_SUPPORTS_METAL 0
+#endif
+
+#ifndef SDL_VIDEO_RENDER_METAL
+#if SDL_PLATFORM_SUPPORTS_METAL
#define SDL_VIDEO_RENDER_METAL 1
#else
#define SDL_VIDEO_RENDER_METAL 0
@@ -219,13 +225,22 @@
#define SDL_VIDEO_OPENGL_GLX 1
#endif
-/* Enable Vulkan support */
-/* Metal/Vulkan Portability only supported on 64-bit architectures with 10.11+ */
-#if TARGET_CPU_X86_64 && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100)
+/* Enable Vulkan and Metal support */
+#ifndef SDL_VIDEO_VULKAN
+#if SDL_PLATFORM_SUPPORTS_METAL
#define SDL_VIDEO_VULKAN 1
#else
#define SDL_VIDEO_VULKAN 0
#endif
+#endif
+
+#ifndef SDL_VIDEO_METAL
+#if SDL_PLATFORM_SUPPORTS_METAL
+#define SDL_VIDEO_METAL 1
+#else
+#define SDL_VIDEO_METAL 0
+#endif
+#endif
/* Enable system power support */
#define SDL_POWER_MACOSX 1
diff --git a/include/SDL_metal.h b/include/SDL_metal.h
new file mode 100644
index 000000000..0f1e0e94d
--- /dev/null
+++ b/include/SDL_metal.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/**
+ * \file SDL_metal.h
+ *
+ * Header file for functions to creating Metal layers and views on SDL windows.
+ */
+
+#ifndef SDL_metal_h_
+#define SDL_metal_h_
+
+#include "SDL_video.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief A handle to a CAMetalLayer-backed NSView (macOS) or UIView (iOS/tvOS).
+ *
+ * \note This can be cast directly to an NSView or UIView.
+ */
+typedef void *SDL_MetalView;
+
+/**
+ * \name Metal support functions
+ */
+/* @{ */
+
+/**
+ * \brief Create a CAMetalLayer-backed NSView/UIView and attach it to the
+ * specified window.
+ *
+ * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on its
+ * own. It is up to user code to do that.
+ *
+ * The returned handle can be casted directly to a NSView or UIView, and the
+ * CAMetalLayer can be accessed from the view's 'layer' property.
+ *
+ * \code
+ * SDL_MetalView metalview = SDL_Metal_CreateView(window);
+ * UIView *uiview = (__bridge UIView *)metalview;
+ * CAMetalLayer *metallayer = (CAMetalLayer *)uiview.layer;
+ * // [...]
+ * SDL_Metal_DestroyView(metalview);
+ * \endcode
+ *
+ * \sa SDL_Metal_DestroyView
+ */
+extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window);
+
+/**
+ * \brief Destroy an existing SDL_MetalView object.
+ *
+ * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was
+ * called after SDL_CreateWindow.
+ *
+ * \sa SDL_Metal_CreateView
+ */
+extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view);
+
+/* @} *//* Metal support functions */
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif /* SDL_metal_h_ */
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index f8c543348..c769582fd 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -724,3 +724,5 @@
#define SDL_RWwrite SDL_RWwrite_REAL
#define SDL_RWclose SDL_RWclose_REAL
#define SDL_LoadFile SDL_LoadFile_REAL
+#define SDL_Metal_CreateView SDL_Metal_CreateView_REAL
+#define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 5a2273695..de5edbad7 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -780,3 +780,5 @@ SDL_DYNAPI_PROC(size_t,SDL_RWread,(SDL_RWops *a, void *b, size_t c, size_t d),(a
SDL_DYNAPI_PROC(size_t,SDL_RWwrite,(SDL_RWops *a, const void *b, size_t c, size_t d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_RWclose,(SDL_RWops *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_LoadFile,(const char *a, size_t *b),(a,b),return)
+SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),)
diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 9233b8fee..ee080f86a 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -26,17 +26,17 @@
#include "SDL_log.h"
#include "SDL_assert.h"
#include "SDL_syswm.h"
+#include "SDL_metal.h"
#include "../SDL_sysrender.h"
-#ifdef __MACOSX__
-#include "../../video/cocoa/SDL_cocoametalview.h"
-#else
-#include "../../video/uikit/SDL_uikitmetalview.h"
-#endif
#include <Availability.h>
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
+#ifdef __MACOSX__
+#import <AppKit/NSView.h>
+#endif
+
/* Regenerate these with build-metal-shaders.sh */
#ifdef __MACOSX__
#include "SDL_shaders_metal_osx.h"
@@ -118,6 +118,7 @@ typedef struct METAL_ShaderPipelines
@property (nonatomic, retain) id<MTLSamplerState> mtlsamplerlinear;
@property (nonatomic, retain) id<MTLBuffer> mtlbufconstants;
@property (nonatomic, retain) id<MTLBuffer> mtlbufquadindices;
+ @property (nonatomic, assign) SDL_MetalView mtlview;
@property (nonatomic, retain) CAMetalLayer *mtllayer;
@property (nonatomic, retain) MTLRenderPassDescriptor *mtlpassdesc;
@property (nonatomic, assign) METAL_ShaderPipelines *activepipelines;
@@ -1475,6 +1476,8 @@ METAL_DestroyRenderer(SDL_Renderer * renderer)
}
DestroyAllPipelines(data.allpipelines, data.pipelinescount);
+
+ SDL_Metal_DestroyView(data.mtlview);
}
SDL_free(renderer);
@@ -1501,6 +1504,8 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
SDL_Renderer *renderer = NULL;
METAL_RenderData *data = NULL;
id<MTLDevice> mtldevice = nil;
+ SDL_MetalView view = NULL;
+ CAMetalLayer *layer = nil;
SDL_SysWMinfo syswm;
SDL_VERSION(&syswm.version);
@@ -1527,26 +1532,36 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
+ view = SDL_Metal_CreateView(window);
+
+ if (view == NULL) {
+ SDL_free(renderer);
+ return NULL;
+ }
+
// !!! FIXME: error checking on all of this.
data = [[METAL_RenderData alloc] init];
+ if (data == nil) {
+ SDL_Metal_DestroyView(view);
+ SDL_free(renderer);
+ return NULL;
+ }
+
renderer->driverdata = (void*)CFBridgingRetain(data);
renderer->window = window;
-#ifdef __MACOSX__
- NSView *view = Cocoa_Mtl_AddMetalView(window);
- CAMetalLayer *layer = (CAMetalLayer *)[view layer];
-
- layer.device = mtldevice;
-
- //layer.colorspace = nil;
+ data.mtlview = view;
+#ifdef __MACOSX__
+ layer = (CAMetalLayer *)[(NSView *)view layer];
#else
- UIView *view = UIKit_Mtl_AddMetalView(window);
- CAMetalLayer *layer = (CAMetalLayer *)[view layer];
+ layer = (CAMetalLayer *)[(__bridge UIView *)view layer];
#endif
- // Necessary for RenderReadPixels.
+ layer.device = mtldevice;
+
+ /* Necessary for RenderReadPixels. */
layer.framebufferOnly = NO;
data.mtldevice = layer.device;
@@ -1763,7 +1778,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
[mtlsamplerlinear release];
[mtlbufconstants release];
[mtlbufquadindices release];
- [view release];
[data release];
[mtldevice release];
#endif
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index e88a8b60e..ddaaf38a5 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -26,6 +26,7 @@
#include "SDL_messagebox.h"
#include "SDL_shape.h"
#include "SDL_thread.h"
+#include "SDL_metal.h"
#include "SDL_vulkan_internal.h"
@@ -276,6 +277,13 @@ struct SDL_VideoDevice
/* * * */
/*
+ * Metal support
+ */
+ SDL_MetalView (*Metal_CreateView) (_THIS, SDL_Window * window);
+ void (*Metal_DestroyView) (_THIS, SDL_MetalView view);
+
+ /* * * */
+ /*
* Event manager functions
*/
void (*PumpEvents) (_THIS);
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index c63f74631..35599f480 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -4183,4 +4183,25 @@ void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h)
}
}
+SDL_MetalView
+SDL_Metal_CreateView(SDL_Window * window)
+{
+ CHECK_WINDOW_MAGIC(window, NULL);
+
+ if (_this->Metal_CreateView) {
+ return _this->Metal_CreateView(_this, window);
+ } else {
+ SDL_SetError("Metal is not supported.");
+ return NULL;
+ }
+}
+
+void
+SDL_Metal_DestroyView(SDL_MetalView view)
+{
+ if (_this && view && _this->Metal_DestroyView) {
+ _this->Metal_DestroyView(_this, view);
+ }
+}
+
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/cocoa/SDL_cocoametalview.h b/src/video/cocoa/SDL_cocoametalview.h
index 6dafef3a3..77e7256be 100644
--- a/src/video/cocoa/SDL_cocoametalview.h
+++ b/src/video/cocoa/SDL_cocoametalview.h
@@ -31,7 +31,7 @@
#import "../SDL_sysvideo.h"
#import "SDL_cocoawindow.h"
-#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL)
+#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
#import <Cocoa/Cocoa.h>
#import <Metal/Metal.h>
@@ -51,11 +51,12 @@
@end
-SDL_cocoametalview* Cocoa_Mtl_AddMetalView(SDL_Window* window);
+SDL_MetalView Cocoa_Metal_CreateView(_THIS, SDL_Window * window);
+void Cocoa_Metal_DestroyView(_THIS, SDL_MetalView view);
-void Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
+void Cocoa_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h);
-#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL) */
+#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */
#endif /* SDL_cocoametalview_h_ */
diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m
index 3d7e147cb..b3b8b8434 100644
--- a/src/video/cocoa/SDL_cocoametalview.m
+++ b/src/video/cocoa/SDL_cocoametalview.m
@@ -27,7 +27,7 @@
#import "SDL_cocoametalview.h"
-#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL)
+#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
#include "SDL_assert.h"
@@ -100,22 +100,38 @@
@end
-SDL_cocoametalview*
-Cocoa_Mtl_AddMetalView(SDL_Window* window)
-{
+SDL_MetalView
+Cocoa_Metal_CreateView(_THIS, SDL_Window * window)
+{ @autoreleasepool {
SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata;
NSView *view = data->nswindow.contentView;
BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
- SDL_cocoametalview *metalview;
+ SDL_cocoametalview *newview;
+ SDL_MetalView metalview;
+
+ newview = [[SDL_cocoametalview alloc] initWithFrame:view.frame highDPI:highDPI];
+ if (newview == nil) {
+ return NULL;
+ }
+
+ [view addSubview:newview];
+
+ metalview = (SDL_MetalView)CFBridgingRetain(newview);
+ [newview release];
- metalview = [[SDL_cocoametalview alloc] initWithFrame:view.frame highDPI:highDPI];
- [view addSubview:metalview];
return metalview;
-}
+}}
void
-Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
-{
+Cocoa_Metal_DestroyView(_THIS, SDL_MetalView view)
+{ @autoreleasepool {
+ SDL_cocoametalview *metalview = CFBridgingRelease(view);
+ [metalview removeFromSuperview];
+}}
+
+void
+Cocoa_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h)
+{ @autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
NSView *view = data->nswindow.contentView;
SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
@@ -131,8 +147,8 @@ Cocoa_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
} else {
SDL_GetWindowSize(window, w, h);
}
-}
+}}
-#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_RENDER_METAL) */
+#endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m
index feb8e08a8..7384d6cef 100644
--- a/src/video/cocoa/SDL_cocoavideo.m
+++ b/src/video/cocoa/SDL_cocoavideo.m
@@ -27,6 +27,7 @@
#include "SDL_cocoavideo.h"
#include "SDL_cocoashape.h"
#include "SDL_cocoavulkan.h"
+#include "SDL_cocoametalview.h"
#include "SDL_assert.h"
/* Initialization/Query functions */
@@ -142,6 +143,11 @@ Cocoa_CreateDevice(int devindex)
device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize;
#endif
+#if SDL_VIDEO_METAL
+ device->Metal_CreateView = Cocoa_Metal_CreateView;
+ device->Metal_DestroyView = Cocoa_Metal_DestroyView;
+#endif
+
device->StartTextInput = Cocoa_StartTextInput;
device->StopTextInput = Cocoa_StopTextInput;
device->SetTextInputRect = Cocoa_SetTextInputRect;
diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m
index 4801d768b..fe2738c90 100644
--- a/src/video/cocoa/SDL_cocoavulkan.m
+++ b/src/video/cocoa/SDL_cocoavulkan.m
@@ -194,6 +194,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
"vkCreateMacOSSurfaceMVK");
VkMacOSSurfaceCreateInfoMVK createInfo = {};
VkResult result;
+ SDL_MetalView metalview;
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
@@ -205,23 +206,38 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
+
+ metalview = Cocoa_Metal_CreateView(_this, window);
+ if (metalview == NULL) {
+ return SDL_FALSE;
+ }
+
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
- createInfo.pView = Cocoa_Mtl_AddMetalView(window);
+ createInfo.pView = (const void *)metalview;
result = vkCreateMacOSSurfaceMVK(instance, &createInfo,
NULL, surface);
if (result != VK_SUCCESS) {
+ Cocoa_Metal_DestroyView(_this, metalview);
SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
+
+ /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call
+ * Metal_DestroyView from. Right now the metal view's ref count is +2 (one
+ * from returning a new view object in CreateView, and one because it's
+ * a subview of the window.) If we release the view here to make it +1, it
+ * will be destroyed when the window is destroyed. */
+ CFBridgingRelease(metalview);
+
return SDL_TRUE;
}
void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
- Cocoa_Mtl_GetDrawableSize(window, w, h);
+ Cocoa_Metal_GetDrawableSize(window, w, h);
}
#endif
diff --git a/src/video/uikit/SDL_uikitmetalview.h b/src/video/uikit/SDL_uikitmetalview.h
index 02d5671b9..ccafdcb03 100644
--- a/src/video/uikit/SDL_uikitmetalview.h
+++ b/src/video/uikit/SDL_uikitmetalview.h
@@ -29,10 +29,10 @@
#ifndef SDL_uikitmetalview_h_
#define SDL_uikitmetalview_h_
-#import "../SDL_sysvideo.h"
-#import "SDL_uikitwindow.h"
+#include "../SDL_sysvideo.h"
+#include "SDL_uikitwindow.h"
-#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
#import <UIKit/UIKit.h>
#import <Metal/Metal.h>
@@ -47,11 +47,12 @@
@end
-SDL_uikitmetalview* UIKit_Mtl_AddMetalView(SDL_Window* window);
+SDL_MetalView UIKit_Metal_CreateView(_THIS, SDL_Window * window);
+void UIKit_Metal_DestroyView(_THIS, SDL_MetalView view);
-void UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
+void UIKit_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h);
-#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */
#endif /* SDL_uikitmetalview_h_ */
diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m
index c9c93c0f1..548ed0ddb 100644
--- a/src/video/uikit/SDL_uikitmetalview.m
+++ b/src/video/uikit/SDL_uikitmetalview.m
@@ -28,7 +28,7 @@
#include "../../SDL_internal.h"
-#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
#import "../SDL_sysvideo.h"
#import "SDL_uikitwindow.h"
@@ -73,16 +73,12 @@
@end
-SDL_uikitmetalview*
-UIKit_Mtl_AddMetalView(SDL_Window* window)
-{
+SDL_MetalView
+UIKit_Metal_CreateView(_THIS, SDL_Window * window)
+{ @autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
- SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
CGFloat scale = 1.0;
-
- if ([view isKindOfClass:[SDL_uikitmetalview class]]) {
- return (SDL_uikitmetalview *)view;
- }
+ SDL_uikitmetalview *metalview;
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
/* Set the scale to the natural scale factor of the screen - then
@@ -96,16 +92,26 @@ UIKit_Mtl_AddMetalView(SDL_Window* window)
scale = data.uiwindow.screen.scale;
}
}
- SDL_uikitmetalview *metalview
- = [[SDL_uikitmetalview alloc] initWithFrame:view.frame
- scale:scale];
+
+ metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds
+ scale:scale];
[metalview setSDLWindow:window];
- return metalview;
-}
+ return (void*)CFBridgingRetain(metalview);
+}}
+
+void
+UIKit_Metal_DestroyView(_THIS, SDL_MetalView view)
+{ @autoreleasepool {
+ SDL_uikitmetalview *metalview = CFBridgingRelease(view);
+
+ if ([metalview isKindOfClass:[SDL_uikitmetalview class]]) {
+ [metalview setSDLWindow:NULL];
+ }
+}}
void
-UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
+UIKit_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h)
{
@autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
@@ -126,4 +132,4 @@ UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
}
}
-#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */
diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m
index cea40b239..26ff02aca 100644
--- a/src/video/uikit/SDL_uikitvideo.m
+++ b/src/video/uikit/SDL_uikitvideo.m
@@ -38,6 +38,7 @@
#include "SDL_uikitopengles.h"
#include "SDL_uikitclipboard.h"
#include "SDL_uikitvulkan.h"
+#include "SDL_uikitmetalview.h"
#define UIKITVID_DRIVER_NAME "uikit"
@@ -133,6 +134,11 @@ UIKit_CreateDevice(int devindex)
device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize;
#endif
+#if SDL_VIDEO_METAL
+ device->Metal_CreateView = UIKit_Metal_CreateView;
+ device->Metal_DestroyView = UIKit_Metal_DestroyView;
+#endif
+
device->gl_config.accelerated = 1;
return device;
diff --git a/src/video/uikit/SDL_uikitvulkan.m b/src/video/uikit/SDL_uikitvulkan.m
index c4b779d10..c95f6fe3d 100644
--- a/src/video/uikit/SDL_uikitvulkan.m
+++ b/src/video/uikit/SDL_uikitvulkan.m
@@ -200,6 +200,7 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
"vkCreateIOSSurfaceMVK");
VkIOSSurfaceCreateInfoMVK createInfo = {};
VkResult result;
+ SDL_MetalView metalview;
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
@@ -212,24 +213,37 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
return SDL_FALSE;
}
+ metalview = UIKit_Metal_CreateView(_this, window);
+ if (metalview == NULL) {
+ return SDL_FALSE;
+ }
+
createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
createInfo.flags = 0;
- createInfo.pView = (__bridge void *)UIKit_Mtl_AddMetalView(window);
+ createInfo.pView = (const void *)metalview;
result = vkCreateIOSSurfaceMVK(instance, &createInfo,
NULL, surface);
if (result != VK_SUCCESS) {
+ UIKit_Metal_DestroyView(_this, metalview);
SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
+ /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call
+ * Metal_DestroyView from. Right now the metal view's ref count is +2 (one
+ * from returning a new view object in CreateView, and one because it's
+ * a subview of the window.) If we release the view here to make it +1, it
+ * will be destroyed when the window is destroyed. */
+ CFBridgingRelease(metalview);
+
return SDL_TRUE;
}
void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
{
- UIKit_Mtl_GetDrawableSize(window, w, h);
+ UIKit_Metal_GetDrawableSize(window, w, h);
}
#endif