summaryrefslogtreecommitdiffstats
path: root/platform/ios
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios')
-rw-r--r--platform/ios/SCsub63
-rw-r--r--platform/ios/detect.py2
-rw-r--r--platform/ios/display_server_ios.h12
-rw-r--r--platform/ios/display_server_ios.mm69
-rw-r--r--platform/ios/export/export_plugin.cpp10
-rw-r--r--platform/ios/godot_view.mm17
-rw-r--r--platform/ios/os_ios.h2
-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