diff options
Diffstat (limited to 'platform/ios')
-rw-r--r-- | platform/ios/SCsub | 63 | ||||
-rw-r--r-- | platform/ios/detect.py | 2 | ||||
-rw-r--r-- | platform/ios/display_server_ios.h | 12 | ||||
-rw-r--r-- | platform/ios/display_server_ios.mm | 69 | ||||
-rw-r--r-- | platform/ios/export/export_plugin.cpp | 10 | ||||
-rw-r--r-- | platform/ios/godot_view.mm | 17 | ||||
-rw-r--r-- | platform/ios/os_ios.h | 2 | ||||
-rw-r--r-- | platform/ios/rendering_context_driver_vulkan_ios.h (renamed from platform/ios/vulkan_context_ios.h) | 25 | ||||
-rw-r--r-- | platform/ios/rendering_context_driver_vulkan_ios.mm (renamed from platform/ios/vulkan_context_ios.mm) | 38 |
9 files changed, 177 insertions, 61 deletions
diff --git a/platform/ios/SCsub b/platform/ios/SCsub index 30d4216464..5a57f3840b 100644 --- a/platform/ios/SCsub +++ b/platform/ios/SCsub @@ -2,6 +2,62 @@ Import("env") +import os, json +from platform_methods import run_in_subprocess, architectures, lipo, get_build_version, detect_mvk +import subprocess +import shutil + + +def generate_bundle(target, source, env): + bin_dir = Dir("#bin").abspath + + # Template bundle. + app_prefix = "godot." + env["platform"] + rel_prefix = "libgodot." + env["platform"] + "." + "template_release" + dbg_prefix = "libgodot." + env["platform"] + "." + "template_debug" + if env.dev_build: + app_prefix += ".dev" + rel_prefix += ".dev" + dbg_prefix += ".dev" + if env["precision"] == "double": + app_prefix += ".double" + rel_prefix += ".double" + dbg_prefix += ".double" + + # Lipo template libraries. + rel_target_bin = lipo(bin_dir + "/" + rel_prefix, env.extra_suffix + ".a") + dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, env.extra_suffix + ".a") + rel_target_bin_sim = lipo(bin_dir + "/" + rel_prefix, ".simulator" + env.extra_suffix + ".a") + dbg_target_bin_sim = lipo(bin_dir + "/" + dbg_prefix, ".simulator" + env.extra_suffix + ".a") + + # Assemble Xcode project bundle. + app_dir = Dir("#bin/ios_xcode").abspath + templ = Dir("#misc/dist/ios_xcode").abspath + if os.path.exists(app_dir): + shutil.rmtree(app_dir) + shutil.copytree(templ, app_dir) + if rel_target_bin != "": + shutil.copy(rel_target_bin, app_dir + "/libgodot.ios.release.xcframework/ios-arm64/libgodot.a") + if dbg_target_bin != "": + shutil.copy(dbg_target_bin, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a") + if rel_target_bin_sim != "": + shutil.copy( + rel_target_bin_sim, app_dir + "/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a" + ) + if dbg_target_bin_sim != "": + shutil.copy( + dbg_target_bin_sim, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a" + ) + mvk_path = detect_mvk(env, "ios-arm64") + if mvk_path != "": + shutil.copytree(mvk_path, app_dir + "/MoltenVK.xcframework") + + # ZIP Xcode project bundle. + zip_dir = Dir("#bin/" + (app_prefix + env.extra_suffix).replace(".", "_")).abspath + shutil.make_archive(zip_dir, "zip", root_dir=app_dir) + shutil.rmtree(app_dir) + + ios_lib = [ "godot_ios.mm", "os_ios.mm", @@ -9,7 +65,7 @@ ios_lib = [ "app_delegate.mm", "view_controller.mm", "ios.mm", - "vulkan_context_ios.mm", + "rendering_context_driver_vulkan_ios.mm", "display_server_ios.mm", "joypad_ios.mm", "godot_view.mm", @@ -42,3 +98,8 @@ def combine_libs(target=None, source=None, env=None): combine_command = env_ios.Command("#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], combine_libs) + +if env["generate_bundle"]: + generate_bundle_command = env.Command("generate_bundle", [], generate_bundle) + command = env.AlwaysBuild(generate_bundle_command) + env.Depends(command, [combine_command]) diff --git a/platform/ios/detect.py b/platform/ios/detect.py index 23f688501b..f8468e3d9e 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -23,6 +23,7 @@ def get_opts(): from SCons.Variables import BoolVariable return [ + ("vulkan_sdk_path", "Path to the Vulkan SDK", ""), ( "IOS_TOOLCHAIN_PATH", "Path to iOS toolchain", @@ -31,6 +32,7 @@ def get_opts(): ("IOS_SDK_PATH", "Path to the iOS SDK", ""), BoolVariable("ios_simulator", "Build for iOS Simulator", False), ("ios_triple", "Triple for ios toolchain", ""), + BoolVariable("generate_bundle", "Generate an APP bundle after building iOS/macOS binaries", False), ] diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index 3fdcc07f0b..6f66783a47 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -39,7 +39,7 @@ #include "servers/rendering/rendering_device.h" #if defined(VULKAN_ENABLED) -#import "vulkan_context_ios.h" +#import "rendering_context_driver_vulkan_ios.h" #ifdef USE_VOLK #include <volk.h> @@ -62,7 +62,7 @@ class DisplayServerIOS : public DisplayServer { _THREAD_SAFE_CLASS_ #if defined(RD_ENABLED) - ApiContextRD *context_rd = nullptr; + RenderingContextDriver *rendering_context = nullptr; RenderingDevice *rendering_device = nullptr; #endif @@ -77,6 +77,8 @@ class DisplayServerIOS : public DisplayServer { Callable input_event_callback; Callable input_text_callback; + Callable system_theme_changed; + int virtual_keyboard_height = 0; void perform_event(const Ref<InputEvent> &p_event); @@ -109,6 +111,8 @@ public: void send_window_event(DisplayServer::WindowEvent p_event) const; void _window_callback(const Callable &p_callable, const Variant &p_arg) const; + void emit_system_theme_changed(); + // MARK: - Input // MARK: Touches and Apple Pencil @@ -145,6 +149,7 @@ public: virtual bool is_dark_mode_supported() const override; virtual bool is_dark_mode() const override; + virtual void set_system_theme_change_callback(const Callable &p_callable) override; virtual Rect2i get_display_safe_area() const override; @@ -159,8 +164,7 @@ public: virtual Vector<DisplayServer::WindowID> get_window_list() const override; - virtual WindowID - get_window_at_screen_position(const Point2i &p_position) const override; + virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override; virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index c660dc5697..ed69b91fdd 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -63,14 +63,14 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode } #if defined(RD_ENABLED) - context_rd = nullptr; + rendering_context = nullptr; rendering_device = nullptr; CALayer *layer = nullptr; union { #ifdef VULKAN_ENABLED - VulkanContextIOS::WindowPlatformData vulkan; + RenderingContextDriverVulkanIOS::WindowPlatformData vulkan; #endif } wpd; @@ -80,28 +80,34 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode if (!layer) { ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer."); } - wpd.vulkan.layer_ptr = &layer; - context_rd = memnew(VulkanContextIOS); + wpd.vulkan.layer_ptr = (CAMetalLayer *const *)&layer; + rendering_context = memnew(RenderingContextDriverVulkanIOS); } #endif - if (context_rd) { - if (context_rd->initialize() != OK) { - memdelete(context_rd); - context_rd = nullptr; - ERR_FAIL_MSG(vformat("Failed to initialize %s context", context_rd->get_api_name())); + if (rendering_context) { + if (rendering_context->initialize() != OK) { + ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); + memdelete(rendering_context); + rendering_context = nullptr; + return; } - Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale(); - if (context_rd->window_create(MAIN_WINDOW_ID, p_vsync_mode, size.width, size.height, &wpd) != OK) { - memdelete(context_rd); - context_rd = nullptr; + if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) { + ERR_PRINT(vformat("Failed to create %s window.", rendering_driver)); + memdelete(rendering_context); + rendering_context = nullptr; r_error = ERR_UNAVAILABLE; - ERR_FAIL_MSG(vformat("Failed to create %s window.", context_rd->get_api_name())); + return; } + Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale(); + rendering_context->window_set_size(MAIN_WINDOW_ID, size.width, size.height); + rendering_context->window_set_vsync_mode(MAIN_WINDOW_ID, p_vsync_mode); + rendering_device = memnew(RenderingDevice); - rendering_device->initialize(context_rd); + rendering_device->initialize(rendering_context, MAIN_WINDOW_ID); + rendering_device->screen_create(MAIN_WINDOW_ID); RendererCompositorRD::make_current(); } @@ -130,15 +136,15 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode DisplayServerIOS::~DisplayServerIOS() { #if defined(RD_ENABLED) if (rendering_device) { - rendering_device->finalize(); + rendering_device->screen_free(MAIN_WINDOW_ID); memdelete(rendering_device); rendering_device = nullptr; } - if (context_rd) { - context_rd->window_destroy(MAIN_WINDOW_ID); - memdelete(context_rd); - context_rd = nullptr; + if (rendering_context) { + rendering_context->window_destroy(MAIN_WINDOW_ID); + memdelete(rendering_context); + rendering_context = nullptr; } #endif } @@ -234,6 +240,7 @@ void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x ev->set_tilt(p_tilt); ev->set_position(Vector2(p_x, p_y)); ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); + ev->set_relative_screen_position(ev->get_relative()); perform_event(ev); } @@ -380,6 +387,16 @@ bool DisplayServerIOS::is_dark_mode() const { } } +void DisplayServerIOS::set_system_theme_change_callback(const Callable &p_callable) { + system_theme_changed = p_callable; +} + +void DisplayServerIOS::emit_system_theme_changed() { + if (system_theme_changed.is_valid()) { + system_theme_changed.call(); + } +} + Rect2i DisplayServerIOS::get_display_safe_area() const { UIEdgeInsets insets = UIEdgeInsetsZero; UIView *view = AppDelegate.viewController.godotView; @@ -711,8 +728,8 @@ void DisplayServerIOS::resize_window(CGSize viewSize) { Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale(); #if defined(RD_ENABLED) - if (context_rd) { - context_rd->window_resize(MAIN_WINDOW_ID, size.x, size.y); + if (rendering_context) { + rendering_context->window_set_size(MAIN_WINDOW_ID, size.x, size.y); } #endif @@ -723,8 +740,8 @@ void DisplayServerIOS::resize_window(CGSize viewSize) { void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(RD_ENABLED) - if (context_rd) { - context_rd->set_vsync_mode(p_window, p_vsync_mode); + if (rendering_context) { + rendering_context->window_set_vsync_mode(p_window, p_vsync_mode); } #endif } @@ -732,8 +749,8 @@ void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(RD_ENABLED) - if (context_rd) { - return context_rd->get_vsync_mode(p_window); + if (rendering_context) { + return rendering_context->window_get_vsync_mode(p_window); } #endif return DisplayServer::VSYNC_ENABLED; diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index d35819c34d..f518d7607b 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -1007,6 +1007,12 @@ Error EditorExportPlatformIOS::_convert_to_framework(const String &p_source, con // Creating Info.plist { + String lib_clean_name = file_name; + for (int i = 0; i < lib_clean_name.length(); i++) { + if (!is_ascii_alphanumeric_char(lib_clean_name[i]) && lib_clean_name[i] != '.' && lib_clean_name[i] != '-') { + lib_clean_name[i] = '-'; + } + } String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" "<plist version=\"1.0\">\n" @@ -1014,7 +1020,7 @@ Error EditorExportPlatformIOS::_convert_to_framework(const String &p_source, con " <key>CFBundleShortVersionString</key>\n" " <string>1.0</string>\n" " <key>CFBundleIdentifier</key>\n" - " <string>$id.framework.$name</string>\n" + " <string>$id.framework.$cl_name</string>\n" " <key>CFBundleName</key>\n" " <string>$name</string>\n" " <key>CFBundleExecutable</key>\n" @@ -1032,7 +1038,7 @@ Error EditorExportPlatformIOS::_convert_to_framework(const String &p_source, con " </dict>\n" "</plist>"; - String info_plist = info_plist_format.replace("$id", p_id).replace("$name", file_name); + String info_plist = info_plist_format.replace("$id", p_id).replace("$name", file_name).replace("$cl_name", lib_clean_name); Ref<FileAccess> f = FileAccess::open(p_destination.path_join("Info.plist"), FileAccess::WRITE); if (f.is_valid()) { diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index ff8a4f8921..4b87863fc5 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -167,6 +167,23 @@ static const float earth_gravity = 9.80665; } } +- (void)system_theme_changed { + DisplayServerIOS *ds = (DisplayServerIOS *)DisplayServer::get_singleton(); + if (ds) { + ds->emit_system_theme_changed(); + } +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + if (@available(iOS 13.0, *)) { + [super traitCollectionDidChange:previousTraitCollection]; + + if ([UITraitCollection currentTraitCollection].userInterfaceStyle != previousTraitCollection.userInterfaceStyle) { + [self system_theme_changed]; + } + } +} + - (void)stopRendering { if (!self.isActive) { return; diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h index 9248d30387..445623f587 100644 --- a/platform/ios/os_ios.h +++ b/platform/ios/os_ios.h @@ -45,7 +45,7 @@ #include "servers/rendering/rendering_device.h" #if defined(VULKAN_ENABLED) -#import "vulkan_context_ios.h" +#import "rendering_context_driver_vulkan_ios.h" #endif #endif diff --git a/platform/ios/vulkan_context_ios.h b/platform/ios/rendering_context_driver_vulkan_ios.h index cdc8b618af..dc85ff738d 100644 --- a/platform/ios/vulkan_context_ios.h +++ b/platform/ios/rendering_context_driver_vulkan_ios.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* vulkan_context_ios.h */ +/* rendering_context_driver_vulkan_ios.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,28 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef VULKAN_CONTEXT_IOS_H -#define VULKAN_CONTEXT_IOS_H +#ifndef RENDERING_CONTEXT_DRIVER_VULKAN_IOS_H +#define RENDERING_CONTEXT_DRIVER_VULKAN_IOS_H #ifdef VULKAN_ENABLED -#include "drivers/vulkan/vulkan_context.h" +#include "drivers/vulkan/rendering_context_driver_vulkan.h" -#import <UIKit/UIKit.h> +#import <QuartzCore/CAMetalLayer.h> -class VulkanContextIOS : public VulkanContext { +class RenderingContextDriverVulkanIOS : public RenderingContextDriverVulkan { +private: virtual const char *_get_platform_surface_extension() const override final; +protected: + SurfaceID surface_create(const void *p_platform_data) override final; + public: struct WindowPlatformData { - CALayer *const *layer_ptr; + CAMetalLayer *const *layer_ptr; }; - virtual Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) override final; - VulkanContextIOS(); - ~VulkanContextIOS(); + RenderingContextDriverVulkanIOS(); + ~RenderingContextDriverVulkanIOS(); }; #endif // VULKAN_ENABLED -#endif // VULKAN_CONTEXT_IOS_H +#endif // RENDERING_CONTEXT_DRIVER_VULKAN_IOS_H diff --git a/platform/ios/vulkan_context_ios.mm b/platform/ios/rendering_context_driver_vulkan_ios.mm index 014e05f2e6..6a6af1bc41 100644 --- a/platform/ios/vulkan_context_ios.mm +++ b/platform/ios/rendering_context_driver_vulkan_ios.mm @@ -1,5 +1,5 @@ /**************************************************************************/ -/* vulkan_context_ios.mm */ +/* rendering_context_driver_vulkan_ios.mm */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,36 +28,42 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#import "vulkan_context_ios.h" +#import "rendering_context_driver_vulkan_ios.h" #ifdef VULKAN_ENABLED #ifdef USE_VOLK #include <volk.h> #else -#include <vulkan/vulkan.h> +#include <vulkan/vulkan_metal.h> #endif -const char *VulkanContextIOS::_get_platform_surface_extension() const { - return VK_MVK_IOS_SURFACE_EXTENSION_NAME; +const char *RenderingContextDriverVulkanIOS::_get_platform_surface_extension() const { + return VK_EXT_METAL_SURFACE_EXTENSION_NAME; } -Error VulkanContextIOS::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, int p_width, int p_height, const void *p_platform_data) { - const WindowPlatformData *wpd = (const WindowPlatformData *)p_platform_data; +RenderingContextDriver::SurfaceID RenderingContextDriverVulkanIOS::surface_create(const void *p_platform_data) { + const WindowPlatformData *wpd = (const WindowPlatformData *)(p_platform_data); - VkIOSSurfaceCreateInfoMVK createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; - createInfo.pView = (__bridge const void *)(*wpd->layer_ptr); + VkMetalSurfaceCreateInfoEXT create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + create_info.pLayer = *wpd->layer_ptr; - VkSurfaceKHR surface = VK_NULL_HANDLE; - VkResult err = vkCreateIOSSurfaceMVK(get_instance(), &createInfo, nullptr, &surface); - ERR_FAIL_COND_V(err, ERR_CANT_CREATE); + VkSurfaceKHR vk_surface = VK_NULL_HANDLE; + VkResult err = vkCreateMetalSurfaceEXT(instance_get(), &create_info, nullptr, &vk_surface); + ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID()); - return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height); + Surface *surface = memnew(Surface); + surface->vk_surface = vk_surface; + return SurfaceID(surface); } -VulkanContextIOS::VulkanContextIOS() {} +RenderingContextDriverVulkanIOS::RenderingContextDriverVulkanIOS() { + // Does nothing. +} -VulkanContextIOS::~VulkanContextIOS() {} +RenderingContextDriverVulkanIOS::~RenderingContextDriverVulkanIOS() { + // Does nothing. +} #endif // VULKAN_ENABLED |