summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2020-04-09 00:16:26 +0200
committerGitHub <noreply@github.com>2020-04-09 00:16:26 +0200
commit23d786d6fbcd374f464155c5f17f1951a664ece9 (patch)
tree689d5fdef20ddf5a9bb82e2fe9347fa2d473b4af
parentb3310a00743d65d8baa2b5730ecfaed8bf8842a6 (diff)
parente167af37373dd14e9d1fe888bcc482d0bd071951 (diff)
Merge pull request #36919 from nekomatata/android-vulkan-rendering
Vulkan rendering support on Android
-rw-r--r--.gitignore1
-rw-r--r--drivers/vulkan/SCsub12
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp12
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h2
-rw-r--r--drivers/vulkan/vulkan_context.h4
-rw-r--r--platform/android/SCsub4
-rw-r--r--platform/android/detect.py8
-rw-r--r--platform/android/display_server_android.cpp655
-rw-r--r--platform/android/display_server_android.h174
-rw-r--r--platform/android/java/lib/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/build.gradle1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java59
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java (renamed from platform/android/java/lib/src/org/godotengine/godot/GodotView.java)39
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java40
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java (renamed from platform/android/vulkan/vk_renderer_jni.h)29
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java142
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java32
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java42
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java22
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt43
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java1
-rw-r--r--platform/android/java_godot_io_wrapper.cpp41
-rw-r--r--platform/android/java_godot_io_wrapper.h10
-rw-r--r--platform/android/java_godot_lib_jni.cpp88
-rw-r--r--platform/android/java_godot_lib_jni.h2
-rw-r--r--platform/android/os_android.cpp521
-rw-r--r--platform/android/os_android.h115
-rw-r--r--platform/android/vulkan/vulkan_context_android.cpp68
-rw-r--r--platform/android/vulkan/vulkan_context_android.h (renamed from platform/android/vulkan/vk_renderer_jni.cpp)35
-rw-r--r--servers/display_server.h2
35 files changed, 1377 insertions, 860 deletions
diff --git a/.gitignore b/.gitignore
index 9096ff228a..19490b9878 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ project.properties
platform/android/java/lib/.cxx/
platform/android/java/libs/*
platform/android/java/app/libs/*
+platform/android/java/lib/.cxx/*
# General c++ generated files
*.lib
diff --git a/drivers/vulkan/SCsub b/drivers/vulkan/SCsub
index 7ffdac27d5..35c2d61530 100644
--- a/drivers/vulkan/SCsub
+++ b/drivers/vulkan/SCsub
@@ -4,7 +4,17 @@ Import("env")
env.add_source_files(env.drivers_sources, "*.cpp")
-if env["builtin_vulkan"]:
+if env["platform"] == "android":
+ # Use NDK Vulkan headers
+ thirdparty_dir = env["ANDROID_NDK_ROOT"] + "/sources/third_party/vulkan/src"
+ thirdparty_includes = [
+ thirdparty_dir,
+ thirdparty_dir + "/include",
+ thirdparty_dir + "/layers",
+ thirdparty_dir + "/layers/generated",
+ ]
+ env.Prepend(CPPPATH=thirdparty_includes)
+elif env["builtin_vulkan"]:
# Use bundled Vulkan headers
thirdparty_dir = "#thirdparty/vulkan"
env.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "/include", thirdparty_dir + "/loader"])
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 01da97cfd5..09f10ef8b1 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1565,15 +1565,20 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = nullptr;
image_create_info.flags = 0;
- VkImageFormatListCreateInfoKHR format_list_create_info;
- Vector<VkFormat> allowed_formats;
-
+#ifndef _MSC_VER
+#warning TODO check for support via RenderingDevice to enable on mobile when possible
+#endif
+ // vkCreateImage fails with format list on Android (VK_ERROR_OUT_OF_HOST_MEMORY)
+#ifndef ANDROID_ENABLED
if (p_format.shareable_formats.size()) {
image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+
+ Vector<VkFormat> allowed_formats;
for (int i = 0; i < p_format.shareable_formats.size(); i++) {
allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]);
}
+ VkImageFormatListCreateInfoKHR format_list_create_info;
format_list_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
format_list_create_info.pNext = nullptr;
format_list_create_info.viewFormatCount = allowed_formats.size();
@@ -1585,6 +1590,7 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(),
"If supplied a list of shareable formats, the current view format override must be present in the list");
}
+#endif
if (p_format.type == TEXTURE_TYPE_CUBE || p_format.type == TEXTURE_TYPE_CUBE_ARRAY) {
image_create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index a46b80e2f4..88a12c7e44 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -37,8 +37,10 @@
#include "servers/rendering/rendering_device.h"
#ifdef DEBUG_ENABLED
+#ifndef _DEBUG
#define _DEBUG
#endif
+#endif
#include "vk_mem_alloc.h"
#include <vulkan/vulkan.h>
//todo:
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 2f10fbfdef..e587104e3c 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -45,8 +45,6 @@ class VulkanContext {
FRAME_LAG = 2
};
- bool use_validation_layers;
-
VkInstance inst;
VkSurfaceKHR surface;
VkPhysicalDevice gpu;
@@ -181,6 +179,8 @@ protected:
bool buffers_prepared;
+ bool use_validation_layers;
+
public:
VkDevice get_device();
VkPhysicalDevice get_physical_device();
diff --git a/platform/android/SCsub b/platform/android/SCsub
index f39eb8b889..ec42bc42b5 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -17,8 +17,8 @@ android_files = [
"java_godot_io_wrapper.cpp",
"jni_utils.cpp",
"android_keys_utils.cpp",
- "vulkan/vk_renderer_jni.cpp",
- "plugin/godot_plugin_jni.cpp",
+ "display_server_android.cpp",
+ "vulkan/vulkan_context_android.cpp",
]
env_android = env.Clone()
diff --git a/platform/android/detect.py b/platform/android/detect.py
index ed0643e3b3..6da1e5f3d6 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -25,7 +25,7 @@ def get_opts():
return [
("ANDROID_NDK_ROOT", "Path to the Android NDK", os.environ.get("ANDROID_NDK_ROOT", 0)),
- ("ndk_platform", 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
+ ("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")),
BoolVariable("android_neon", "Enable NEON support (armv7 only)", True),
]
@@ -102,7 +102,7 @@ def configure(env):
neon_text = ""
if env["android_arch"] == "armv7" and env["android_neon"]:
neon_text = " (with NEON)"
- print("Building for Android (" + env["android_arch"] + ")" + neon_text)
+ print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")" + neon_text)
can_vectorize = True
if env["android_arch"] == "x86":
@@ -314,8 +314,8 @@ def configure(env):
)
env.Prepend(CPPPATH=["#platform/android"])
- env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "NO_FCNTL"])
- env.Append(LIBS=["OpenSLES", "EGL", "GLESv3", "GLESv2", "android", "log", "z", "dl"])
+ env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "VULKAN_ENABLED", "NO_FCNTL"])
+ env.Append(LIBS=["OpenSLES", "EGL", "GLESv2", "vulkan", "android", "log", "z", "dl"])
# Return NDK version string in source.properties (adapted from the Chromium project).
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
new file mode 100644
index 0000000000..9534387d35
--- /dev/null
+++ b/platform/android/display_server_android.cpp
@@ -0,0 +1,655 @@
+/*************************************************************************/
+/* display_server_android.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "display_server_android.h"
+
+#include "android_keys_utils.h"
+#include "core/project_settings.h"
+#include "java_godot_io_wrapper.h"
+#include "java_godot_wrapper.h"
+#include "os_android.h"
+
+#if defined(OPENGL_ENABLED)
+#include "drivers/gles2/rasterizer_gles2.h"
+#endif
+#if defined(VULKAN_ENABLED)
+#include "drivers/vulkan/rendering_device_vulkan.h"
+#include "platform/android/vulkan/vulkan_context_android.h"
+#include "servers/rendering/rasterizer_rd/rasterizer_rd.h"
+#endif
+
+DisplayServerAndroid *DisplayServerAndroid::get_singleton() {
+ return (DisplayServerAndroid *)DisplayServer::get_singleton();
+}
+
+bool DisplayServerAndroid::has_feature(Feature p_feature) const {
+ switch (p_feature) {
+ //case FEATURE_CONSOLE_WINDOW:
+ //case FEATURE_CURSOR_SHAPE:
+ //case FEATURE_CUSTOM_CURSOR_SHAPE:
+ //case FEATURE_GLOBAL_MENU:
+ //case FEATURE_HIDPI:
+ //case FEATURE_ICON:
+ //case FEATURE_IME:
+ //case FEATURE_MOUSE:
+ //case FEATURE_MOUSE_WARP:
+ //case FEATURE_NATIVE_DIALOG:
+ //case FEATURE_NATIVE_ICON:
+ //case FEATURE_NATIVE_VIDEO:
+ //case FEATURE_WINDOW_TRANSPARENCY:
+ case FEATURE_CLIPBOARD:
+ case FEATURE_KEEP_SCREEN_ON:
+ case FEATURE_ORIENTATION:
+ case FEATURE_TOUCHSCREEN:
+ case FEATURE_VIRTUAL_KEYBOARD:
+ return true;
+ default:
+ return false;
+ }
+}
+
+String DisplayServerAndroid::get_name() const {
+ return "Android";
+}
+
+void DisplayServerAndroid::clipboard_set(const String &p_text) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ if (godot_java->has_set_clipboard()) {
+ godot_java->set_clipboard(p_text);
+ } else {
+ DisplayServer::clipboard_set(p_text);
+ }
+}
+
+String DisplayServerAndroid::clipboard_get() const {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND_V(!godot_java, String());
+
+ if (godot_java->has_get_clipboard()) {
+ return godot_java->get_clipboard();
+ } else {
+ return DisplayServer::clipboard_get();
+ }
+}
+
+void DisplayServerAndroid::screen_set_keep_on(bool p_enable) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ godot_java->set_keep_screen_on(p_enable);
+ keep_screen_on = p_enable;
+}
+
+bool DisplayServerAndroid::screen_is_kept_on() const {
+ return keep_screen_on;
+}
+
+void DisplayServerAndroid::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ godot_io_java->set_screen_orientation(p_orientation);
+}
+
+DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(int p_screen) const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, SCREEN_LANDSCAPE);
+
+ return (ScreenOrientation)godot_io_java->get_screen_orientation();
+}
+
+int DisplayServerAndroid::get_screen_count() const {
+ return 1;
+}
+
+Point2i DisplayServerAndroid::screen_get_position(int p_screen) const {
+ return Point2i(0, 0);
+}
+
+Size2i DisplayServerAndroid::screen_get_size(int p_screen) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+Rect2i DisplayServerAndroid::screen_get_usable_rect(int p_screen) const {
+ Size2i display_size = OS_Android::get_singleton()->get_display_size();
+ return Rect2i(0, 0, display_size.width, display_size.height);
+}
+
+int DisplayServerAndroid::screen_get_dpi(int p_screen) const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, 0);
+
+ return godot_io_java->get_screen_dpi();
+}
+
+bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const {
+ return true;
+}
+
+void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length) {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ if (godot_io_java->has_vk()) {
+ godot_io_java->show_vk(p_existing_text, p_max_length);
+ } else {
+ ERR_PRINT("Virtual keyboard not available");
+ }
+}
+
+void DisplayServerAndroid::virtual_keyboard_hide() {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND(!godot_io_java);
+
+ if (godot_io_java->has_vk()) {
+ godot_io_java->hide_vk();
+ } else {
+ ERR_PRINT("Virtual keyboard not available");
+ }
+}
+
+int DisplayServerAndroid::virtual_keyboard_get_height() const {
+ GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+ ERR_FAIL_COND_V(!godot_io_java, 0);
+
+ return godot_io_java->get_vk_height();
+}
+
+void DisplayServerAndroid::window_set_window_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ window_event_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_input_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ input_event_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_input_text_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ input_text_callback = p_callable;
+}
+
+void DisplayServerAndroid::window_set_rect_changed_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
+ if (!p_callable.is_null()) {
+ const Variant *argp = &p_arg;
+ Variant ret;
+ Callable::CallError ce;
+ p_callable.call((const Variant **)&argp, 1, ret, ce);
+ }
+}
+
+void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event) const {
+ _window_callback(window_event_callback, int(p_event));
+}
+
+void DisplayServerAndroid::send_input_event(const Ref<InputEvent> &p_event) const {
+ _window_callback(input_event_callback, p_event);
+}
+
+void DisplayServerAndroid::send_input_text(const String &p_text) const {
+ _window_callback(input_text_callback, p_text);
+}
+
+void DisplayServerAndroid::_dispatch_input_events(const Ref<InputEvent> &p_event) {
+ DisplayServerAndroid::get_singleton()->send_input_event(p_event);
+}
+
+Vector<DisplayServer::WindowID> DisplayServerAndroid::get_window_list() const {
+ Vector<WindowID> ret;
+ ret.push_back(MAIN_WINDOW_ID);
+ return ret;
+}
+
+DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(const Point2i &p_position) const {
+ return MAIN_WINDOW_ID;
+}
+
+void DisplayServerAndroid::window_attach_instance_id(ObjectID p_instance, DisplayServer::WindowID p_window) {
+ window_attached_instance_id = p_instance;
+}
+
+ObjectID DisplayServerAndroid::window_get_attached_instance_id(DisplayServer::WindowID p_window) const {
+ return window_attached_instance_id;
+}
+
+void DisplayServerAndroid::window_set_title(const String &p_title, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+int DisplayServerAndroid::window_get_current_screen(DisplayServer::WindowID p_window) const {
+ return SCREEN_OF_MAIN_WINDOW;
+}
+
+void DisplayServerAndroid::window_set_current_screen(int p_screen, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Point2i DisplayServerAndroid::window_get_position(DisplayServer::WindowID p_window) const {
+ return Point2i();
+}
+
+void DisplayServerAndroid::window_set_position(const Point2i &p_position, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_transient(DisplayServer::WindowID p_window, DisplayServer::WindowID p_parent) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_set_max_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_max_size(DisplayServer::WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerAndroid::window_set_min_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_min_size(DisplayServer::WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerAndroid::window_set_size(const Size2i p_size, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+Size2i DisplayServerAndroid::window_get_size(DisplayServer::WindowID p_window) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+Size2i DisplayServerAndroid::window_get_real_size(DisplayServer::WindowID p_window) const {
+ return OS_Android::get_singleton()->get_display_size();
+}
+
+void DisplayServerAndroid::window_set_mode(DisplayServer::WindowMode p_mode, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+DisplayServer::WindowMode DisplayServerAndroid::window_get_mode(DisplayServer::WindowID p_window) const {
+ return WINDOW_MODE_FULLSCREEN;
+}
+
+bool DisplayServerAndroid::window_is_maximize_allowed(DisplayServer::WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerAndroid::window_set_flag(DisplayServer::WindowFlags p_flag, bool p_enabled, DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+bool DisplayServerAndroid::window_get_flag(DisplayServer::WindowFlags p_flag, DisplayServer::WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerAndroid::window_request_attention(DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_window) {
+ // Not supported on Android.
+}
+
+bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const {
+ return true;
+}
+
+bool DisplayServerAndroid::can_any_window_draw() const {
+ return true;
+}
+
+void DisplayServerAndroid::alert(const String &p_alert, const String &p_title) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_COND(!godot_java);
+
+ godot_java->alert(p_alert, p_title);
+}
+
+void DisplayServerAndroid::process_events() {
+ // Nothing to do
+}
+
+Vector<String> DisplayServerAndroid::get_rendering_drivers_func() {
+ Vector<String> drivers;
+
+#ifdef OPENGL_ENABLED
+ drivers.push_back("opengl");
+#endif
+#ifdef VULKAN_ENABLED
+ drivers.push_back("vulkan");
+#endif
+
+ return drivers;
+}
+
+DisplayServer *DisplayServerAndroid::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerAndroid(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+}
+
+void DisplayServerAndroid::register_android_driver() {
+ register_create_function("android", create_func, get_rendering_drivers_func);
+}
+
+DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ rendering_driver = p_rendering_driver;
+
+ // TODO: rendering_driver is broken, change when different drivers are supported again
+ rendering_driver = "vulkan";
+
+ keep_screen_on = GLOBAL_GET("display/window/energy_saving/keep_screen_on");
+
+#if defined(OPENGL_ENABLED)
+ if (rendering_driver == "opengl") {
+ bool gl_initialization_error = false;
+
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ gl_initialization_error = true;
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
+ "Please try updating your Android version.",
+ "Unable to initialize video driver");
+ return;
+ }
+ }
+#endif
+
+#if defined(VULKAN_ENABLED)
+ context_vulkan = nullptr;
+ rendering_device_vulkan = nullptr;
+
+ if (rendering_driver == "vulkan") {
+ ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
+ ERR_FAIL_COND(!native_window);
+
+ context_vulkan = memnew(VulkanContextAndroid);
+ if (context_vulkan->initialize() != OK) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
+ ERR_FAIL_MSG("Failed to initialize Vulkan context");
+ }
+
+ Size2i display_size = OS_Android::get_singleton()->get_display_size();
+ if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
+ ERR_FAIL_MSG("Failed to create Vulkan window.");
+ }
+
+ rendering_device_vulkan = memnew(RenderingDeviceVulkan);
+ rendering_device_vulkan->initialize(context_vulkan);
+
+ RasterizerRD::make_current();
+ }
+#endif
+
+ InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+}
+
+DisplayServerAndroid::~DisplayServerAndroid() {
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ }
+
+ if (context_vulkan) {
+ memdelete(context_vulkan);
+ }
+ }
+#endif
+}
+
+void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) {
+ switch (p_event.type) {
+ case JOY_EVENT_BUTTON:
+ InputFilter::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed);
+ break;
+ case JOY_EVENT_AXIS:
+ InputFilter::JoyAxis value;
+ value.min = -1;
+ value.value = p_event.value;
+ InputFilter::get_singleton()->joy_axis(p_event.device, p_event.index, value);
+ break;
+ case JOY_EVENT_HAT:
+ InputFilter::get_singleton()->joy_hat(p_event.device, p_event.hat);
+ break;
+ default:
+ return;
+ }
+}
+
+void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed) {
+ Ref<InputEventKey> ev;
+ ev.instance();
+ int val = p_unicode_char;
+ int keycode = android_get_keysym(p_keycode);
+ int phy_keycode = android_get_keysym(p_scancode);
+ ev->set_keycode(keycode);
+ ev->set_physical_keycode(phy_keycode);
+ ev->set_unicode(val);
+ ev->set_pressed(p_pressed);
+
+ if (val == '\n') {
+ ev->set_keycode(KEY_ENTER);
+ } else if (val == 61448) {
+ ev->set_keycode(KEY_BACKSPACE);
+ ev->set_unicode(KEY_BACKSPACE);
+ } else if (val == 61453) {
+ ev->set_keycode(KEY_ENTER);
+ ev->set_unicode(KEY_ENTER);
+ } else if (p_keycode == 4) {
+ OS_Android::get_singleton()->main_loop_request_go_back();
+ }
+
+ InputFilter::get_singleton()->parse_input_event(ev);
+}
+
+void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) {
+ switch (p_what) {
+ case 0: { //gesture begin
+ if (touch.size()) {
+ //end all if exist
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+ }
+
+ touch.resize(p_points.size());
+ for (int i = 0; i < p_points.size(); i++) {
+ touch.write[i].id = p_points[i].id;
+ touch.write[i].pos = p_points[i].pos;
+ }
+
+ //send touch
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(true);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+
+ } break;
+ case 1: { //motion
+ ERR_FAIL_COND(touch.size() != p_points.size());
+
+ for (int i = 0; i < touch.size(); i++) {
+
+ int idx = -1;
+ for (int j = 0; j < p_points.size(); j++) {
+
+ if (touch[i].id == p_points[j].id) {
+ idx = j;
+ break;
+ }
+ }
+
+ ERR_CONTINUE(idx == -1);
+
+ if (touch[i].pos == p_points[idx].pos)
+ continue; //no move unncesearily
+
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_position(p_points[idx].pos);
+ ev->set_relative(p_points[idx].pos - touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ touch.write[i].pos = p_points[idx].pos;
+ }
+
+ } break;
+ case 2: { //release
+ if (touch.size()) {
+ //end all if exist
+ for (int i = 0; i < touch.size(); i++) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ }
+ touch.clear();
+ }
+ } break;
+ case 3: { // add touch
+ for (int i = 0; i < p_points.size(); i++) {
+ if (p_points[i].id == p_pointer) {
+ TouchPos tp = p_points[i];
+ touch.push_back(tp);
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(tp.id);
+ ev->set_pressed(true);
+ ev->set_position(tp.pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+
+ break;
+ }
+ }
+ } break;
+ case 4: { // remove touch
+ for (int i = 0; i < touch.size(); i++) {
+ if (touch[i].id == p_pointer) {
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ touch.remove(i);
+
+ break;
+ }
+ }
+ } break;
+ }
+}
+
+void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
+ // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
+ switch (p_type) {
+ case 7: // hover move
+ case 9: // hover enter
+ case 10: { // hover exit
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_global_position(p_pos);
+ ev->set_relative(p_pos - hover_prev_pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ hover_prev_pos = p_pos;
+ } break;
+ }
+}
+
+void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_global_position(p_pos);
+ ev->set_pressed(false);
+ ev->set_doubleclick(true);
+ InputFilter::get_singleton()->parse_input_event(ev);
+}
+
+void DisplayServerAndroid::process_scroll(Point2 p_pos) {
+ Ref<InputEventPanGesture> ev;
+ ev.instance();
+ ev->set_position(p_pos);
+ ev->set_delta(p_pos - scroll_prev_pos);
+ InputFilter::get_singleton()->parse_input_event(ev);
+ scroll_prev_pos = p_pos;
+}
+
+void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) {
+ InputFilter::get_singleton()->set_accelerometer(p_accelerometer);
+}
+
+void DisplayServerAndroid::process_gravity(const Vector3 &p_gravity) {
+ InputFilter::get_singleton()->set_gravity(p_gravity);
+}
+
+void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) {
+ InputFilter::get_singleton()->set_magnetometer(p_magnetometer);
+}
+
+void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
+ InputFilter::get_singleton()->set_gyroscope(p_gyroscope);
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
new file mode 100644
index 0000000000..2096ba68f1
--- /dev/null
+++ b/platform/android/display_server_android.h
@@ -0,0 +1,174 @@
+/*************************************************************************/
+/* display_server_android.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DISPLAY_SERVER_ANDROID_H
+#define DISPLAY_SERVER_ANDROID_H
+
+#include "servers/display_server.h"
+
+#if defined(VULKAN_ENABLED)
+class VulkanContextAndroid;
+class RenderingDeviceVulkan;
+#endif
+
+class DisplayServerAndroid : public DisplayServer {
+public:
+ struct TouchPos {
+ int id;
+ Point2 pos;
+ };
+
+ enum {
+ JOY_EVENT_BUTTON = 0,
+ JOY_EVENT_AXIS = 1,
+ JOY_EVENT_HAT = 2
+ };
+
+ struct JoypadEvent {
+
+ int device;
+ int type;
+ int index;
+ bool pressed;
+ float value;
+ int hat;
+ };
+
+private:
+ String rendering_driver;
+
+ bool keep_screen_on;
+
+ Vector<TouchPos> touch;
+ Point2 hover_prev_pos; // needed to calculate the relative position on hover events
+ Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
+
+#if defined(VULKAN_ENABLED)
+ VulkanContextAndroid *context_vulkan;
+ RenderingDeviceVulkan *rendering_device_vulkan;
+#endif
+
+ ObjectID window_attached_instance_id;
+
+ Callable window_event_callback;
+ Callable input_event_callback;
+ Callable input_text_callback;
+
+ void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
+
+ static void _dispatch_input_events(const Ref<InputEvent> &p_event);
+
+public:
+ static DisplayServerAndroid *get_singleton();
+
+ virtual bool has_feature(Feature p_feature) const;
+ virtual String get_name() const;
+
+ virtual void clipboard_set(const String &p_text);
+ virtual String clipboard_get() const;
+
+ virtual void screen_set_keep_on(bool p_enable);
+ virtual bool screen_is_kept_on() const;
+
+ virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW);
+ virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ virtual int get_screen_count() const;
+ virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1);
+ virtual void virtual_keyboard_hide();
+ virtual int virtual_keyboard_get_height() const;
+
+ virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+
+ void send_window_event(WindowEvent p_event) const;
+ void send_input_event(const Ref<InputEvent> &p_event) const;
+ void send_input_text(const String &p_text) const;
+
+ virtual Vector<WindowID> get_window_list() const;
+ virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
+ virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID);
+ virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+ virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_transient(WindowID p_window, WindowID p_parent);
+ virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool can_any_window_draw() const;
+
+ virtual void alert(const String &p_alert, const String &p_title);
+
+ virtual void process_events();
+
+ void process_accelerometer(const Vector3 &p_accelerometer);
+ void process_gravity(const Vector3 &p_gravity);
+ void process_magnetometer(const Vector3 &p_magnetometer);
+ void process_gyroscope(const Vector3 &p_gyroscope);
+ void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
+ void process_hover(int p_type, Point2 p_pos);
+ void process_double_tap(Point2 p_pos);
+ void process_scroll(Point2 p_pos);
+ void process_joy_event(JoypadEvent p_event);
+ void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
+
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static Vector<String> get_rendering_drivers_func();
+ static void register_android_driver();
+
+ DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerAndroid();
+};
+
+#endif // DISPLAY_SERVER_ANDROID_H
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index b133585f99..fa39bc0f1d 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -13,7 +13,7 @@
<instrumentation
android:icon="@mipmap/icon"
android:label="@string/godot_project_name_string"
- android:name=".GodotInstrumentation"
+ android:name="org.godotengine.godot.GodotInstrumentation"
android:targetPackage="org.godotengine.godot" />
</manifest>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 062f91e08e..c69e19fbfa 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -1,4 +1,5 @@
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
dependencies {
implementation libraries.supportCoreUtils
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 1798a1df3a..bf0d1c6273 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -153,7 +153,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
private String[] command_line;
private boolean use_apk_expansion;
- public GodotView mView;
+ public GodotRenderView mRenderView;
private boolean godot_initialized = false;
private SensorManager mSensorManager;
@@ -213,34 +213,41 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
setContentView(layout);
// GodotEditText layout
- GodotEditText edittext = new GodotEditText(this);
- edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+ GodotEditText editText = new GodotEditText(this);
+ editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// ...add to FrameLayout
- layout.addView(edittext);
+ layout.addView(editText);
- mView = new GodotView(this, xrMode, use_32_bits, use_debug_opengl);
- layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- edittext.setView(mView);
- io.setEdit(edittext);
+ GodotLib.setup(command_line);
- mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ final String videoDriver = GodotLib.getGlobal("rendering/quality/driver/driver_name");
+ if (videoDriver.equals("Vulkan")) {
+ mRenderView = new GodotVulkanRenderView(this);
+ } else {
+ mRenderView = new GodotGLRenderView(this, xrMode, use_32_bits, use_debug_opengl);
+ }
+
+ View view = mRenderView.getView();
+ layout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ editText.setView(mRenderView);
+ io.setEdit(editText);
+
+ view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Point fullSize = new Point();
getWindowManager().getDefaultDisplay().getSize(fullSize);
Rect gameSize = new Rect();
- mView.getWindowVisibleDisplayFrame(gameSize);
+ mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
final int keyboardHeight = fullSize.y - gameSize.bottom;
GodotLib.setVirtualKeyboardHeight(keyboardHeight);
}
});
- final String[] current_command_line = command_line;
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
- GodotLib.setup(current_command_line);
// Must occur after GodotLib.setup has completed.
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
@@ -384,7 +391,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
*/
@Keep
private Surface getSurface() {
- return mView.getHolder().getSurface();
+ return mRenderView.getView().getHolder().getSurface();
}
/**
@@ -617,7 +624,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
return;
}
- mView.onPause();
+ mRenderView.onActivityPaused();
mSensorManager.unregisterListener(this);
@@ -655,7 +662,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
return;
}
- mView.onResume();
+ mRenderView.onActivityResumed();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME);
@@ -721,8 +728,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
final float z = adjustedValues[2];
final int typeOfSensor = event.sensor.getType();
- if (mView != null) {
- mView.queueEvent(new Runnable() {
+ if (mRenderView != null) {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) {
@@ -773,8 +780,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
}
- if (shouldQuit && mView != null) {
- mView.queueEvent(new Runnable() {
+ if (shouldQuit && mRenderView != null) {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
GodotLib.back();
@@ -789,8 +796,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
* This must be called after the render thread has started.
*/
public final void runOnRenderThread(@NonNull Runnable action) {
- if (mView != null) {
- mView.queueEvent(action);
+ if (mRenderView != null) {
+ mRenderView.queueOnRenderThread(action);
}
}
@@ -847,7 +854,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
if (evcount == 0)
return true;
- if (mView != null) {
+ if (mRenderView != null) {
final int[] arr = new int[event.getPointerCount() * 3];
for (int i = 0; i < event.getPointerCount(); i++) {
@@ -860,7 +867,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
//System.out.printf("gaction: %d\n",event.getAction());
final int action = event.getAction() & MotionEvent.ACTION_MASK;
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
switch (action) {
@@ -911,7 +918,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
;
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
// This method will be called on the rendering thread:
public void run() {
for (int i = 0, n = cc.length; i < n; i++) {
@@ -1033,6 +1040,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
progress.mOverallTotal));
}
public void initInputDevices() {
- mView.initInputDevices();
+ mRenderView.initInputDevices();
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 8d3c2ae319..9be93243b8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotView.java */
+/* GodotGLRenderView.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -35,6 +35,7 @@ import android.opengl.GLSurfaceView;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SurfaceView;
import org.godotengine.godot.input.GodotGestureHandler;
import org.godotengine.godot.input.GodotInputHandler;
import org.godotengine.godot.utils.GLUtils;
@@ -64,16 +65,14 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
-public class GodotView extends GLSurfaceView {
-
- private static String TAG = GodotView.class.getSimpleName();
+public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView {
private final Godot activity;
private final GodotInputHandler inputHandler;
private final GestureDetector detector;
private final GodotRenderer godotRenderer;
- public GodotView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) {
+ public GodotGLRenderView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) {
super(activity);
GLUtils.use_32 = p_use_32_bits;
GLUtils.use_debug_opengl = p_use_debug_opengl;
@@ -85,10 +84,36 @@ public class GodotView extends GLSurfaceView {
init(xrMode, false, 16, 0);
}
+ @Override
+ public SurfaceView getView() {
+ return this;
+ }
+
+ @Override
public void initInputDevices() {
this.inputHandler.initInputDevices();
}
+ @Override
+ public void queueOnRenderThread(Runnable event) {
+ queueEvent(event);
+ }
+
+ @Override
+ public void onActivityPaused() {
+ onPause();
+ }
+
+ @Override
+ public void onActivityResumed() {
+ onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ activity.onBackPressed();
+ }
+
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
@@ -170,10 +195,6 @@ public class GodotView extends GLSurfaceView {
setRenderer(godotRenderer);
}
- public void onBackPressed() {
- activity.onBackPressed();
- }
-
@Override
public void onResume() {
super.onResume();
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 68ce40ba10..016a3a8d18 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -53,8 +53,6 @@ public class GodotIO {
Godot activity;
GodotEditText edit;
- MediaPlayer mediaPlayer;
-
final int SCREEN_LANDSCAPE = 0;
final int SCREEN_PORTRAIT = 1;
final int SCREEN_REVERSE_LANDSCAPE = 2;
@@ -530,44 +528,14 @@ public class GodotIO {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
} break;
}
- };
-
- public void setEdit(GodotEditText _edit) {
- edit = _edit;
- }
-
- public void playVideo(String p_path) {
- Uri filePath = Uri.parse(p_path);
- mediaPlayer = new MediaPlayer();
-
- try {
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
- mediaPlayer.setDataSource(activity.getApplicationContext(), filePath);
- mediaPlayer.prepare();
- mediaPlayer.start();
- } catch (IOException e) {
- System.out.println("IOError while playing video");
- }
}
- public boolean isVideoPlaying() {
- if (mediaPlayer != null) {
- return mediaPlayer.isPlaying();
- }
- return false;
+ public int getScreenOrientation() {
+ return activity.getRequestedOrientation();
}
- public void pauseVideo() {
- if (mediaPlayer != null) {
- mediaPlayer.pause();
- }
- }
-
- public void stopVideo() {
- if (mediaPlayer != null) {
- mediaPlayer.release();
- mediaPlayer = null;
- }
+ public void setEdit(GodotEditText _edit) {
+ edit = _edit;
}
public static final int SYSTEM_DIR_DESKTOP = 0;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 89a65aea24..71fe822233 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -32,6 +32,7 @@ package org.godotengine.godot;
import android.app.Activity;
import android.hardware.SensorEvent;
+import android.view.Surface;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
@@ -72,11 +73,11 @@ public class GodotLib {
public static native void resize(int width, int height);
/**
- * Invoked on the GL thread when the underlying Android surface is created or recreated.
+ * Invoked on the render thread when the underlying Android surface is created or recreated.
+ * @param p_surface
* @param p_32_bits
- * @see android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)
*/
- public static native void newcontext(boolean p_32_bits);
+ public static native void newcontext(Surface p_surface, boolean p_32_bits);
/**
* Forward {@link Activity#onBackPressed()} event from the main thread to the GL thread.
diff --git a/platform/android/vulkan/vk_renderer_jni.h b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 017766fea2..170c433c9c 100644
--- a/platform/android/vulkan/vk_renderer_jni.h
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vk_renderer_jni.h */
+/* GodotRenderView.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,19 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef VK_RENDERER_JNI_H
-#define VK_RENDERER_JNI_H
+package org.godotengine.godot;
-#include <android/log.h>
-#include <jni.h>
+import android.view.SurfaceView;
-extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj);
-}
+public interface GodotRenderView {
+
+ abstract public SurfaceView getView();
+
+ abstract public void initInputDevices();
-#endif // VK_RENDERER_JNI_H
+ abstract public void queueOnRenderThread(Runnable event);
+
+ abstract public void onActivityPaused();
+ abstract public void onActivityResumed();
+
+ abstract public void onBackPressed();
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index ee9a2aee4f..3e5bb4a4c9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -70,7 +70,7 @@ class GodotRenderer implements GLSurfaceView.Renderer {
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- GodotLib.newcontext(GLUtils.use_32);
+ GodotLib.newcontext(null, GLUtils.use_32);
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onGLSurfaceCreated(gl, config);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
new file mode 100644
index 0000000000..30197d5729
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -0,0 +1,142 @@
+/*************************************************************************/
+/* GodotVulkanRenderView.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.godot;
+
+import android.annotation.SuppressLint;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
+import org.godotengine.godot.input.GodotGestureHandler;
+import org.godotengine.godot.input.GodotInputHandler;
+import org.godotengine.godot.vulkan.VkRenderer;
+import org.godotengine.godot.vulkan.VkSurfaceView;
+
+public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
+
+ private final Godot mActivity;
+ private final GodotInputHandler mInputHandler;
+ private final GestureDetector mGestureDetector;
+ private final VkRenderer mRenderer;
+
+ public GodotVulkanRenderView(Godot activity) {
+ super(activity);
+
+ mActivity = activity;
+ mInputHandler = new GodotInputHandler(this);
+ mGestureDetector = new GestureDetector(mActivity, new GodotGestureHandler(this));
+ mRenderer = new VkRenderer();
+
+ setFocusableInTouchMode(true);
+ startRenderer(mRenderer);
+ }
+
+ @Override
+ public SurfaceView getView() {
+ return this;
+ }
+
+ @Override
+ public void initInputDevices() {
+ mInputHandler.initInputDevices();
+ }
+
+ @Override
+ public void queueOnRenderThread(Runnable event) {
+ queueOnVkThread(event);
+ }
+
+ @Override
+ public void onActivityPaused() {
+ onPause();
+ }
+
+ @Override
+ public void onActivityResumed() {
+ onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ mActivity.onBackPressed();
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ super.onTouchEvent(event);
+ mGestureDetector.onTouchEvent(event);
+ return mActivity.gotTouchEvent(event);
+ }
+
+ @Override
+ public boolean onKeyUp(final int keyCode, KeyEvent event) {
+ return mInputHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyDown(final int keyCode, KeyEvent event) {
+ return mInputHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ return mInputHandler.onGenericMotionEvent(event) || super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ queueOnVkThread(new Runnable() {
+ @Override
+ public void run() {
+ // Resume the renderer
+ mRenderer.onVkResume();
+ GodotLib.focusin();
+ }
+ });
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ queueOnVkThread(new Runnable() {
+ @Override
+ public void run() {
+ GodotLib.focusout();
+ // Pause the renderer
+ mRenderer.onVkPause();
+ }
+ });
+ }
+}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index e901b4b36d..92bb118e44 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -51,7 +51,7 @@ public class GodotEditText extends EditText {
// ===========================================================
// Fields
// ===========================================================
- private GodotView mView;
+ private GodotRenderView mRenderView;
private GodotTextInputWrapper mInputWrapper;
private EditHandler sHandler = new EditHandler(this);
private String mOriginText;
@@ -76,22 +76,22 @@ public class GodotEditText extends EditText {
// ===========================================================
public GodotEditText(final Context context) {
super(context);
- this.initView();
+ initView();
}
public GodotEditText(final Context context, final AttributeSet attrs) {
super(context, attrs);
- this.initView();
+ initView();
}
public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
- this.initView();
+ initView();
}
protected void initView() {
- this.setPadding(0, 0, 0, 0);
- this.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+ setPadding(0, 0, 0, 0);
+ setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
}
private void handleMessage(final Message msg) {
@@ -106,7 +106,7 @@ public class GodotEditText extends EditText {
edit.mInputWrapper.setOriginText(text);
edit.addTextChangedListener(edit.mInputWrapper);
setMaxInputLength(edit, msg.arg1);
- final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, 0);
}
} break;
@@ -115,9 +115,9 @@ public class GodotEditText extends EditText {
GodotEditText edit = (GodotEditText)msg.obj;
edit.removeTextChangedListener(mInputWrapper);
- final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edit.getWindowToken(), 0);
- edit.mView.requestFocus();
+ edit.mRenderView.getView().requestFocus();
} break;
}
}
@@ -135,12 +135,12 @@ public class GodotEditText extends EditText {
// ===========================================================
// Getter & Setter
// ===========================================================
- public void setView(final GodotView view) {
- this.mView = view;
+ public void setView(final GodotRenderView view) {
+ mRenderView = view;
if (mInputWrapper == null)
- mInputWrapper = new GodotTextInputWrapper(mView, this);
- this.setOnEditorActionListener(mInputWrapper);
- view.requestFocus();
+ mInputWrapper = new GodotTextInputWrapper(mRenderView, this);
+ setOnEditorActionListener(mInputWrapper);
+ view.getView().requestFocus();
}
// ===========================================================
@@ -152,7 +152,7 @@ public class GodotEditText extends EditText {
/* Let GlSurfaceView get focus if back key is input. */
if (keyCode == KeyEvent.KEYCODE_BACK) {
- this.mView.requestFocus();
+ mRenderView.getView().requestFocus();
}
return true;
@@ -162,7 +162,7 @@ public class GodotEditText extends EditText {
// Methods
// ===========================================================
public void showKeyboard(String p_existing_text, int p_max_input_length) {
- this.mOriginText = p_existing_text;
+ mOriginText = p_existing_text;
final Message msg = new Message();
msg.what = HANDLER_OPEN_IME_KEYBOARD;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index 1a38a9c3d2..b1e0f66373 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -34,22 +34,22 @@ import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotView;
+import org.godotengine.godot.GodotRenderView;
/**
- * Handles gesture input related events for the {@link GodotView} view.
+ * Handles gesture input related events for the {@link GodotRenderView} view.
* https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener
*/
public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener {
- private final GodotView godotView;
+ private final GodotRenderView mRenderView;
- public GodotGestureHandler(GodotView godotView) {
- this.godotView = godotView;
+ public GodotGestureHandler(GodotRenderView godotView) {
+ mRenderView = godotView;
}
private void queueEvent(Runnable task) {
- godotView.queueEvent(task);
+ mRenderView.queueOnRenderThread(task);
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index e00ca86c41..0e4fc65119 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -42,27 +42,27 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotView;
+import org.godotengine.godot.GodotRenderView;
import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
/**
- * Handles input related events for the {@link GodotView} view.
+ * Handles input related events for the {@link GodotRenderView} view.
*/
public class GodotInputHandler implements InputDeviceListener {
- private final ArrayList<Joystick> joysticksDevices = new ArrayList<Joystick>();
+ private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>();
- private final GodotView godotView;
- private final InputManagerCompat inputManager;
+ private final GodotRenderView mRenderView;
+ private final InputManagerCompat mInputManager;
- public GodotInputHandler(GodotView godotView) {
- this.godotView = godotView;
- this.inputManager = InputManagerCompat.Factory.getInputManager(godotView.getContext());
- this.inputManager.registerInputDeviceListener(this, null);
+ public GodotInputHandler(GodotRenderView godotView) {
+ mRenderView = godotView;
+ mInputManager = InputManagerCompat.Factory.getInputManager(mRenderView.getView().getContext());
+ mInputManager.registerInputDeviceListener(this, null);
}
private void queueEvent(Runnable task) {
- godotView.queueEvent(task);
+ mRenderView.queueOnRenderThread(task);
}
private boolean isKeyEvent_GameDevice(int source) {
@@ -113,7 +113,7 @@ public class GodotInputHandler implements InputDeviceListener {
public boolean onKeyDown(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- godotView.onBackPressed();
+ mRenderView.onBackPressed();
// press 'back' button should not terminate program
//normal handle 'back' event in game logic
return true;
@@ -164,7 +164,7 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the device exists
if (device_id > -1) {
- Joystick joy = joysticksDevices.get(device_id);
+ Joystick joy = mJoysticksDevices.get(device_id);
for (int i = 0; i < joy.axes.size(); i++) {
InputDevice.MotionRange range = joy.axes.get(i);
@@ -208,11 +208,11 @@ public class GodotInputHandler implements InputDeviceListener {
public void initInputDevices() {
/* initially add input devices*/
- int[] deviceIds = inputManager.getInputDeviceIds();
+ int[] deviceIds = mInputManager.getInputDeviceIds();
for (int deviceId : deviceIds) {
- InputDevice device = inputManager.getInputDevice(deviceId);
+ InputDevice device = mInputManager.getInputDevice(deviceId);
if (DEBUG) {
- Log.v("GodotView", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName()));
+ Log.v("GodotInputHandler", String.format("init() deviceId:%d, Name:%s\n", deviceId, device.getName()));
}
onInputDeviceAdded(deviceId);
}
@@ -224,13 +224,13 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the device has not been already added
if (id < 0) {
- InputDevice device = inputManager.getInputDevice(deviceId);
+ InputDevice device = mInputManager.getInputDevice(deviceId);
//device can be null if deviceId is not found
if (device != null) {
int sources = device.getSources();
if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ||
((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) {
- id = joysticksDevices.size();
+ id = mJoysticksDevices.size();
Joystick joy = new Joystick();
joy.device_id = deviceId;
@@ -249,7 +249,7 @@ public class GodotInputHandler implements InputDeviceListener {
}
}
- joysticksDevices.add(joy);
+ mJoysticksDevices.add(joy);
final int device_id = id;
final String name = joy.name;
@@ -270,7 +270,7 @@ public class GodotInputHandler implements InputDeviceListener {
// Check if the evice has not been already removed
if (device_id > -1) {
- joysticksDevices.remove(device_id);
+ mJoysticksDevices.remove(device_id);
queueEvent(new Runnable() {
@Override
@@ -360,8 +360,8 @@ public class GodotInputHandler implements InputDeviceListener {
}
private int findJoystickDevice(int device_id) {
- for (int i = 0; i < joysticksDevices.size(); i++) {
- if (joysticksDevices.get(i).device_id == device_id) {
+ for (int i = 0; i < mJoysticksDevices.size(); i++) {
+ if (mJoysticksDevices.get(i).device_id == device_id) {
return i;
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index 18f2d57661..e12ff266bf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -48,7 +48,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// ===========================================================
// Fields
// ===========================================================
- private final GodotView mView;
+ private final GodotRenderView mRenderView;
private final GodotEditText mEdit;
private String mOriginText;
@@ -56,9 +56,9 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// Constructors
// ===========================================================
- public GodotTextInputWrapper(final GodotView view, final GodotEditText edit) {
- this.mView = view;
- this.mEdit = edit;
+ public GodotTextInputWrapper(final GodotRenderView view, final GodotEditText edit) {
+ mRenderView = view;
+ mEdit = edit;
}
// ===========================================================
@@ -66,13 +66,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
// ===========================================================
private boolean isFullScreenEdit() {
- final TextView textField = this.mEdit;
+ final TextView textField = mEdit;
final InputMethodManager imm = (InputMethodManager)textField.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
return imm.isFullscreenMode();
}
public void setOriginText(final String originText) {
- this.mOriginText = originText;
+ mOriginText = originText;
}
// ===========================================================
@@ -87,7 +87,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) {
//Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after);
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < count; ++i) {
@@ -106,7 +106,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
for (int i = start; i < start + count; ++i) {
newChars[i - start] = pCharSequence.charAt(i);
}
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < count; ++i) {
@@ -124,10 +124,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
@Override
public boolean onEditorAction(final TextView pTextView, final int pActionID, final KeyEvent pKeyEvent) {
- if (this.mEdit == pTextView && this.isFullScreenEdit()) {
+ if (mEdit == pTextView && isFullScreenEdit()) {
final String characters = pKeyEvent.getCharacters();
- mView.queueEvent(new Runnable() {
+ mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < characters.length(); i++) {
@@ -144,7 +144,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
- this.mView.requestFocus();
+ mRenderView.getView().requestFocus();
return true;
}
return false;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
index 67faad8ddd..608ad48df9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
@@ -33,6 +33,11 @@ package org.godotengine.godot.vulkan
import android.view.Surface
+import org.godotengine.godot.Godot
+import org.godotengine.godot.GodotLib
+import org.godotengine.godot.plugin.GodotPlugin
+import org.godotengine.godot.plugin.GodotPluginRegistry
+
/**
* Responsible to setting up and driving the Vulkan rendering logic.
*
@@ -48,52 +53,64 @@ import android.view.Surface
*/
internal class VkRenderer {
+ private val pluginRegistry: GodotPluginRegistry = GodotPluginRegistry.getPluginRegistry()
+
/**
* Called when the surface is created and signals the beginning of rendering.
*/
fun onVkSurfaceCreated(surface: Surface) {
- nativeOnVkSurfaceCreated(surface)
+ // TODO: properly implement surface re-creation:
+ // GodotLib.newcontext should be called here once it's done.
+ //GodotLib.newcontext(surface, false)
+
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkSurfaceCreated(surface)
+ }
}
/**
* Called after the surface is created and whenever its size changes.
*/
fun onVkSurfaceChanged(surface: Surface, width: Int, height: Int) {
- nativeOnVkSurfaceChanged(surface, width, height)
+ GodotLib.resize(width, height)
+
+ // TODO: properly implement surface re-creation:
+ // Update the native renderer instead of restarting the app.
+ // GodotLib.newcontext should not be called here once it's done.
+ GodotLib.newcontext(surface, false)
+
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkSurfaceChanged(surface, width, height)
+ }
}
/**
* Called to draw the current frame.
*/
fun onVkDrawFrame() {
- nativeOnVkDrawFrame()
+ GodotLib.step()
+ for (plugin in pluginRegistry.getAllPlugins()) {
+ plugin.onVkDrawFrame()
+ }
}
/**
* Called when the rendering thread is resumed.
*/
fun onVkResume() {
- nativeOnVkResume()
+ GodotLib.onRendererResumed()
}
/**
* Called when the rendering thread is paused.
*/
fun onVkPause() {
- nativeOnVkPause()
+ GodotLib.onRendererPaused()
}
/**
* Called when the rendering thread is destroyed and used as signal to tear down the Vulkan logic.
*/
fun onVkDestroy() {
- nativeOnVkDestroy()
}
-
- private external fun nativeOnVkSurfaceCreated(surface: Surface)
- private external fun nativeOnVkSurfaceChanged(surface: Surface, width: Int, height: Int)
- private external fun nativeOnVkResume()
- private external fun nativeOnVkDrawFrame()
- private external fun nativeOnVkPause()
- private external fun nativeOnVkDestroy()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
index 1c594f3201..6b0e12b21a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkSurfaceView.kt
@@ -49,7 +49,7 @@ import android.view.SurfaceView
* UI thread.
* </ul>
*/
-internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {
+open internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {
companion object {
fun checkState(expression: Boolean, errorMessage: Any) {
@@ -100,7 +100,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo
*
* Must not be called before a [VkRenderer] has been set.
*/
- fun onResume() {
+ open fun onResume() {
vkThread.onResume()
}
@@ -109,7 +109,7 @@ internal class VkSurfaceView(context: Context) : SurfaceView(context), SurfaceHo
*
* Must not be called before a [VkRenderer] has been set.
*/
- fun onPause() {
+ open fun onPause() {
vkThread.onPause()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
index 2e332840bf..7557c8aa22 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt
@@ -219,9 +219,9 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk
vkRenderer.onVkDrawFrame()
}
} catch (ex: InterruptedException) {
- Log.i(TAG, ex.message)
+ Log.i(TAG, "InterruptedException", ex)
} catch (ex: IllegalStateException) {
- Log.i(TAG, ex.message)
+ Log.i(TAG, "IllegalStateException", ex)
} finally {
threadExiting()
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index f2b4c95a2c..31cf696195 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -51,7 +51,6 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
- String driver_name = GodotLib.getGlobal("rendering/quality/driver/driver_name");
// FIXME: Add support for Vulkan.
Log.w(TAG, "creating OpenGL ES 2.0 context :");
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index 8d075f8e97..0da0bd6387 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -56,11 +56,8 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V");
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
+ _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;");
- _play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V");
- _is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z");
- _pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V");
- _stop_video = p_env->GetMethodID(cls, "stopVideo", "()V");
}
}
@@ -157,40 +154,22 @@ void GodotIOJavaWrapper::set_screen_orientation(int p_orient) {
}
}
-String GodotIOJavaWrapper::get_system_dir(int p_dir) {
- if (_get_system_dir) {
+int GodotIOJavaWrapper::get_screen_orientation() {
+ if (_get_screen_orientation) {
JNIEnv *env = ThreadAndroid::get_env();
- jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
- return jstring_to_string(s, env);
+ return env->CallIntMethod(godot_io_instance, _get_screen_orientation);
} else {
- return String(".");
+ return 0;
}
}
-void GodotIOJavaWrapper::play_video(const String &p_path) {
- // Why is this not here?!?!
-}
-
-bool GodotIOJavaWrapper::is_video_playing() {
- if (_is_video_playing) {
+String GodotIOJavaWrapper::get_system_dir(int p_dir) {
+ if (_get_system_dir) {
JNIEnv *env = ThreadAndroid::get_env();
- return env->CallBooleanMethod(godot_io_instance, _is_video_playing);
+ jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir);
+ return jstring_to_string(s, env);
} else {
- return false;
- }
-}
-
-void GodotIOJavaWrapper::pause_video() {
- if (_pause_video) {
- JNIEnv *env = ThreadAndroid::get_env();
- env->CallVoidMethod(godot_io_instance, _pause_video);
- }
-}
-
-void GodotIOJavaWrapper::stop_video() {
- if (_stop_video) {
- JNIEnv *env = ThreadAndroid::get_env();
- env->CallVoidMethod(godot_io_instance, _stop_video);
+ return String(".");
}
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index 7dfed52187..dbb3b564f6 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -54,11 +54,8 @@ private:
jmethodID _show_keyboard = 0;
jmethodID _hide_keyboard = 0;
jmethodID _set_screen_orientation = 0;
+ jmethodID _get_screen_orientation = 0;
jmethodID _get_system_dir = 0;
- jmethodID _play_video = 0;
- jmethodID _is_video_playing = 0;
- jmethodID _pause_video = 0;
- jmethodID _stop_video = 0;
public:
GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instance);
@@ -78,11 +75,8 @@ public:
int get_vk_height();
void set_vk_height(int p_height);
void set_screen_orientation(int p_orient);
+ int get_screen_orientation();
String get_system_dir(int p_dir);
- void play_video(const String &p_path);
- bool is_video_playing();
- void pause_video();
- void stop_video();
};
#endif /* !JAVA_GODOT_IO_WRAPPER_H */
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 9d44ab4619..c103e74222 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -34,13 +34,13 @@
#include "java_godot_wrapper.h"
#include "android/asset_manager_jni.h"
-#include "android_keys_utils.h"
#include "api/java_class_wrapper.h"
#include "audio_driver_jandroid.h"
#include "core/engine.h"
#include "core/input/input_filter.h"
#include "core/project_settings.h"
#include "dir_access_jandroid.h"
+#include "display_server_android.h"
#include "file_access_android.h"
#include "file_access_jandroid.h"
#include "jni_utils.h"
@@ -52,6 +52,8 @@
#include <unistd.h>
+#include <android/native_window_jni.h>
+
static JavaClassWrapper *java_class_wrapper = nullptr;
static OS_Android *os_android = nullptr;
static GodotJavaWrapper *godot_java = nullptr;
@@ -165,17 +167,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height) {
if (os_android)
- os_android->set_display_size(Size2(width, height));
+ os_android->set_display_size(Size2i(width, height));
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits) {
-
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) {
if (os_android) {
if (step == 0) {
// During startup
os_android->set_context_is_16_bits(!p_32_bits);
+ if (p_surface) {
+ ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface);
+ os_android->set_native_window(native_window);
+ }
} else {
- // GL context recreated because it was lost; restart app to let it reload everything
+ // Rendering context recreated because it was lost; restart app to let it reload everything
os_android->main_loop_end();
godot_java->restart(env);
step = -1; // Ensure no further steps are attempted
@@ -195,7 +200,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
return;
if (step == 0) {
-
// Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id,
// but for Godot purposes, the main thread is the one running the game loop
Main::setup2(Thread::get_caller_id());
@@ -213,10 +217,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
++step;
}
- os_android->process_accelerometer(accelerometer);
- os_android->process_gravity(gravity);
- os_android->process_magnetometer(magnetometer);
- os_android->process_gyroscope(gyroscope);
+ DisplayServerAndroid::get_singleton()->process_accelerometer(accelerometer);
+ DisplayServerAndroid::get_singleton()->process_gravity(gravity);
+ DisplayServerAndroid::get_singleton()->process_magnetometer(magnetometer);
+ DisplayServerAndroid::get_singleton()->process_gyroscope(gyroscope);
if (os_android->main_loop_iterate()) {
@@ -229,18 +233,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jc
if (step == 0)
return;
- Vector<OS_Android::TouchPos> points;
+ Vector<DisplayServerAndroid::TouchPos> points;
for (int i = 0; i < count; i++) {
jint p[3];
env->GetIntArrayRegion(positions, i * 3, 3, p);
- OS_Android::TouchPos tp;
+ DisplayServerAndroid::TouchPos tp;
tp.pos = Point2(p[1], p[2]);
tp.id = p[0];
points.push_back(tp);
}
- os_android->process_touch(ev, pointer, points);
+ DisplayServerAndroid::get_singleton()->process_touch(ev, pointer, points);
/*
if (os_android)
@@ -252,78 +256,78 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jc
if (step == 0)
return;
- os_android->process_hover(p_type, Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_hover(p_type, Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
if (step == 0)
return;
- os_android->process_double_tap(Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_double_tap(Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
if (step == 0)
return;
- os_android->process_scroll(Point2(p_x, p_y));
+ DisplayServerAndroid::get_singleton()->process_scroll(Point2(p_x, p_y));
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_BUTTON;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_BUTTON;
jevent.index = p_button;
jevent.pressed = p_pressed;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_AXIS;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_AXIS;
jevent.index = p_axis;
jevent.value = p_value;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jclass clazz, jint p_device, jint p_hat_x, jint p_hat_y) {
if (step == 0)
return;
- OS_Android::JoypadEvent jevent;
+ DisplayServerAndroid::JoypadEvent jevent;
jevent.device = p_device;
- jevent.type = OS_Android::JOY_EVENT_HAT;
+ jevent.type = DisplayServerAndroid::JOY_EVENT_HAT;
int hat = 0;
if (p_hat_x != 0) {
if (p_hat_x < 0)
- hat |= InputDefault::HAT_MASK_LEFT;
+ hat |= InputFilter::HAT_MASK_LEFT;
else
- hat |= InputDefault::HAT_MASK_RIGHT;
+ hat |= InputFilter::HAT_MASK_RIGHT;
}
if (p_hat_y != 0) {
if (p_hat_y < 0)
- hat |= InputDefault::HAT_MASK_UP;
+ hat |= InputFilter::HAT_MASK_UP;
else
- hat |= InputDefault::HAT_MASK_DOWN;
+ hat |= InputFilter::HAT_MASK_DOWN;
}
jevent.hat = hat;
- os_android->process_joy_event(jevent);
+ DisplayServerAndroid::get_singleton()->process_joy_event(jevent);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) {
if (os_android) {
String name = jstring_to_string(p_name, env);
- os_android->joy_connection_changed(p_device, p_connected, name);
+ InputFilter::get_singleton()->joy_connection_changed(p_device, p_connected, name);
}
}
@@ -331,29 +335,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jcla
if (step == 0)
return;
- Ref<InputEventKey> ievent;
- ievent.instance();
- int val = p_unicode_char;
- int keycode = android_get_keysym(p_keycode);
- int phy_keycode = android_get_keysym(p_scancode);
- ievent->set_keycode(keycode);
- ievent->set_physical_keycode(phy_keycode);
- ievent->set_unicode(val);
- ievent->set_pressed(p_pressed);
-
- if (val == '\n') {
- ievent->set_keycode(KEY_ENTER);
- } else if (val == 61448) {
- ievent->set_keycode(KEY_BACKSPACE);
- ievent->set_unicode(KEY_BACKSPACE);
- } else if (val == 61453) {
- ievent->set_keycode(KEY_ENTER);
- ievent->set_unicode(KEY_ENTER);
- } else if (p_keycode == 4) {
- os_android->main_loop_request_go_back();
- }
-
- os_android->process_event(ievent);
+ DisplayServerAndroid::get_singleton()->process_key_event(p_keycode, p_scancode, p_unicode_char, p_pressed);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jclass clazz, jfloat x, jfloat y, jfloat z) {
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index a7a5970440..221d701e2b 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -41,7 +41,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 344377d673..760157595c 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -32,15 +32,11 @@
#include "core/io/file_access_buffered_fa.h"
#include "core/project_settings.h"
-#if defined(OPENGL_ENABLED)
-#include "drivers/gles2/rasterizer_gles2.h"
-#endif
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "file_access_android.h"
#include "main/main.h"
-#include "servers/rendering/rendering_server_raster.h"
-#include "servers/rendering/rendering_server_wrap_mt.h"
+#include "platform/android/display_server_android.h"
#include "dir_access_jandroid.h"
#include "file_access_jandroid.h"
@@ -60,29 +56,6 @@ public:
virtual ~AndroidLogger() {}
};
-int OS_Android::get_video_driver_count() const {
-
- return 2;
-}
-
-const char *OS_Android::get_video_driver_name(int p_driver) const {
-
- switch (p_driver) {
- case VIDEO_DRIVER_GLES2:
- return "GLES2";
- }
- ERR_FAIL_V_MSG(nullptr, "Invalid video driver index: " + itos(p_driver) + ".");
-}
-int OS_Android::get_audio_driver_count() const {
-
- return 1;
-}
-
-const char *OS_Android::get_audio_driver_name(int p_driver) const {
-
- return "Android";
-}
-
void OS_Android::initialize_core() {
OS_Unix::initialize_core();
@@ -110,71 +83,33 @@ void OS_Android::initialize_core() {
NetSocketAndroid::make_default();
}
-void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
-
- ERR_FAIL_COND(!p_gl_extensions);
- gl_extensions = p_gl_extensions;
-}
-
-int OS_Android::get_current_video_driver() const {
- return video_driver_index;
+void OS_Android::initialize() {
+ initialize_core();
}
-Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
+void OS_Android::initialize_joypads() {
+ InputFilter::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping());
- // FIXME: Add Vulkan support. Readd fallback code from Vulkan to GLES2?
-
-#if defined(OPENGL_ENABLED)
- if (video_driver_index == VIDEO_DRIVER_GLES2) {
- bool gl_initialization_error = false;
-
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n"
- "Please try updating your Android version.",
- "Unable to initialize video driver");
- return ERR_UNAVAILABLE;
- }
- }
-#endif
-
- video_driver_index = p_video_driver;
-
- rendering_server = memnew(RenderingServerRaster);
- if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- rendering_server = memnew(RenderingServerWrapMT(rendering_server, false));
- }
-
- rendering_server->init();
-
- AudioDriverManager::initialize(p_audio_driver);
-
- input = memnew(InputDefault);
- input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
-
- return OK;
+ // This queries/updates the currently connected devices/joypads.
+ godot_java->init_input_devices();
}
void OS_Android::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
- input->set_main_loop(p_main_loop);
}
void OS_Android::delete_main_loop() {
-
- memdelete(main_loop);
+ if (main_loop) {
+ memdelete(main_loop);
+ main_loop = nullptr;
+ }
}
void OS_Android::finalize() {
+}
- memdelete(input);
+OS_Android *OS_Android::get_singleton() {
+ return (OS_Android *)OS::get_singleton();
}
GodotJavaWrapper *OS_Android::get_godot_java() {
@@ -185,12 +120,6 @@ GodotIOJavaWrapper *OS_Android::get_godot_io_java() {
return godot_io_java;
}
-void OS_Android::alert(const String &p_alert, const String &p_title) {
-
- //print("ALERT: %s\n", p_alert.utf8().get_data());
- godot_java->alert(p_alert, p_title);
-}
-
bool OS_Android::request_permission(const String &p_name) {
return godot_java->request_permission(p_name);
@@ -212,63 +141,6 @@ Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_han
return OK;
}
-void OS_Android::set_mouse_show(bool p_show) {
-
- //android has no mouse...
-}
-
-void OS_Android::set_mouse_grab(bool p_grab) {
-
- //it really has no mouse...!
-}
-
-bool OS_Android::is_mouse_grab_enabled() const {
-
- //*sigh* technology has evolved so much since i was a kid..
- return false;
-}
-
-Point2 OS_Android::get_mouse_position() const {
-
- return Point2();
-}
-
-int OS_Android::get_mouse_button_state() const {
-
- return 0;
-}
-
-void OS_Android::set_window_title(const String &p_title) {
- //This queries/updates the currently connected devices/joypads
- //Set_window_title is called when initializing the main loop (main.cpp)
- //therefore this place is found to be suitable (I found no better).
- godot_java->init_input_devices();
-}
-
-void OS_Android::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-}
-
-OS::VideoMode OS_Android::get_video_mode(int p_screen) const {
-
- return default_videomode;
-}
-
-void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
- p_list->push_back(default_videomode);
-}
-
-void OS_Android::set_keep_screen_on(bool p_enabled) {
- OS::set_keep_screen_on(p_enabled);
-
- godot_java->set_keep_screen_on(p_enabled);
-}
-
-Size2 OS_Android::get_window_size() const {
-
- return Vector2(default_videomode.width, default_videomode.height);
-}
-
String OS_Android::get_name() const {
return "Android";
@@ -279,11 +151,6 @@ MainLoop *OS_Android::get_main_loop() const {
return main_loop;
}
-bool OS_Android::can_draw() const {
-
- return true; //always?
-}
-
void OS_Android::main_loop_begin() {
if (main_loop)
@@ -304,277 +171,17 @@ void OS_Android::main_loop_end() {
}
void OS_Android::main_loop_focusout() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_FOCUS_OUT);
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
audio_driver_android.set_pause(true);
}
void OS_Android::main_loop_focusin() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_FOCUS_IN);
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
audio_driver_android.set_pause(false);
}
-void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) {
-
- switch (p_event.type) {
- case JOY_EVENT_BUTTON:
- input->joy_button(p_event.device, p_event.index, p_event.pressed);
- break;
- case JOY_EVENT_AXIS:
- InputDefault::JoyAxis value;
- value.min = -1;
- value.value = p_event.value;
- input->joy_axis(p_event.device, p_event.index, value);
- break;
- case JOY_EVENT_HAT:
- input->joy_hat(p_event.device, p_event.hat);
- break;
- default:
- return;
- }
-}
-
-void OS_Android::process_event(Ref<InputEvent> p_event) {
-
- input->parse_input_event(p_event);
-}
-
-void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
-
- switch (p_what) {
- case 0: { //gesture begin
-
- if (touch.size()) {
- //end all if exist
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
- }
-
- touch.resize(p_points.size());
- for (int i = 0; i < p_points.size(); i++) {
- touch.write[i].id = p_points[i].id;
- touch.write[i].pos = p_points[i].pos;
- }
-
- //send touch
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(true);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
-
- } break;
- case 1: { //motion
-
- ERR_FAIL_COND(touch.size() != p_points.size());
-
- for (int i = 0; i < touch.size(); i++) {
-
- int idx = -1;
- for (int j = 0; j < p_points.size(); j++) {
-
- if (touch[i].id == p_points[j].id) {
- idx = j;
- break;
- }
- }
-
- ERR_CONTINUE(idx == -1);
-
- if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
-
- Ref<InputEventScreenDrag> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_position(p_points[idx].pos);
- ev->set_relative(p_points[idx].pos - touch[i].pos);
- input->parse_input_event(ev);
- touch.write[i].pos = p_points[idx].pos;
- }
-
- } break;
- case 2: { //release
-
- if (touch.size()) {
- //end all if exist
- for (int i = 0; i < touch.size(); i++) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- }
- touch.clear();
- }
- } break;
- case 3: { // add touch
-
- for (int i = 0; i < p_points.size(); i++) {
- if (p_points[i].id == p_pointer) {
- TouchPos tp = p_points[i];
- touch.push_back(tp);
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
-
- ev->set_index(tp.id);
- ev->set_pressed(true);
- ev->set_position(tp.pos);
- input->parse_input_event(ev);
-
- break;
- }
- }
- } break;
- case 4: { // remove touch
-
- for (int i = 0; i < touch.size(); i++) {
- if (touch[i].id == p_pointer) {
-
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- ev->set_index(touch[i].id);
- ev->set_pressed(false);
- ev->set_position(touch[i].pos);
- input->parse_input_event(ev);
- touch.remove(i);
-
- break;
- }
- }
- } break;
- }
-}
-
-void OS_Android::process_hover(int p_type, Point2 p_pos) {
- // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
- switch (p_type) {
- case 7: // hover move
- case 9: // hover enter
- case 10: { // hover exit
- Ref<InputEventMouseMotion> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_global_position(p_pos);
- ev->set_relative(p_pos - hover_prev_pos);
- input->parse_input_event(ev);
- hover_prev_pos = p_pos;
- } break;
- }
-}
-
-void OS_Android::process_double_tap(Point2 p_pos) {
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_global_position(p_pos);
- ev->set_pressed(false);
- ev->set_doubleclick(true);
- input->parse_input_event(ev);
-}
-
-void OS_Android::process_scroll(Point2 p_pos) {
- Ref<InputEventPanGesture> ev;
- ev.instance();
- ev->set_position(p_pos);
- ev->set_delta(p_pos - scroll_prev_pos);
- input->parse_input_event(ev);
- scroll_prev_pos = p_pos;
-}
-
-void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) {
-
- input->set_accelerometer(p_accelerometer);
-}
-
-void OS_Android::process_gravity(const Vector3 &p_gravity) {
-
- input->set_gravity(p_gravity);
-}
-
-void OS_Android::process_magnetometer(const Vector3 &p_magnetometer) {
-
- input->set_magnetometer(p_magnetometer);
-}
-
-void OS_Android::process_gyroscope(const Vector3 &p_gyroscope) {
-
- input->set_gyroscope(p_gyroscope);
-}
-
-bool OS_Android::has_touchscreen_ui_hint() const {
-
- return true;
-}
-
-bool OS_Android::has_virtual_keyboard() const {
-
- return true;
-}
-
-int OS_Android::get_virtual_keyboard_height() const {
- return godot_io_java->get_vk_height();
-
- // ERR_PRINT("Cannot obtain virtual keyboard height.");
- // return 0;
-}
-
-void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
-
- if (godot_io_java->has_vk()) {
- godot_io_java->show_vk(p_existing_text, p_max_input_length);
- } else {
-
- ERR_PRINT("Virtual keyboard not available");
- };
-}
-
-void OS_Android::hide_virtual_keyboard() {
-
- if (godot_io_java->has_vk()) {
-
- godot_io_java->hide_vk();
- } else {
-
- ERR_PRINT("Virtual keyboard not available");
- };
-}
-
-void OS_Android::init_video_mode(int p_video_width, int p_video_height) {
-
- default_videomode.width = p_video_width;
- default_videomode.height = p_video_height;
- default_videomode.fullscreen = true;
- default_videomode.resizable = false;
-}
-
void OS_Android::main_loop_request_go_back() {
-
- if (main_loop)
- main_loop->notification(NOTIFICATION_WM_GO_BACK_REQUEST);
-}
-
-void OS_Android::set_display_size(Size2 p_size) {
-
- default_videomode.width = p_size.x;
- default_videomode.height = p_size.y;
+ DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_GO_BACK_REQUEST);
}
Error OS_Android::shell_open(String p_uri) {
@@ -597,26 +204,6 @@ String OS_Android::get_locale() const {
return OS_Unix::get_locale();
}
-void OS_Android::set_clipboard(const String &p_text) {
-
- // DO we really need the fallback to OS_Unix here?!
- if (godot_java->has_set_clipboard()) {
- godot_java->set_clipboard(p_text);
- } else {
- OS_Unix::set_clipboard(p_text);
- }
-}
-
-String OS_Android::get_clipboard() const {
-
- // DO we really need the fallback to OS_Unix here?!
- if (godot_java->has_get_clipboard()) {
- return godot_java->get_clipboard();
- }
-
- return OS_Unix::get_clipboard();
-}
-
String OS_Android::get_model_name() const {
String model = godot_io_java->get_model();
@@ -626,11 +213,6 @@ String OS_Android::get_model_name() const {
return OS_Unix::get_model_name();
}
-int OS_Android::get_screen_dpi(int p_screen) const {
-
- return godot_io_java->get_screen_dpi();
-}
-
String OS_Android::get_user_data_dir() const {
if (data_dir_cache != String())
@@ -662,11 +244,6 @@ String OS_Android::get_user_data_dir() const {
return ".";
}
-void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
-
- godot_io_java->set_screen_orientation(p_orientation);
-}
-
String OS_Android::get_unique_id() const {
String unique_id = godot_io_java->get_unique_id();
@@ -676,50 +253,46 @@ String OS_Android::get_unique_id() const {
return OS::get_unique_id();
}
-Error OS_Android::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
- // FIXME: Add support for volume, audio and subtitle tracks
-
- godot_io_java->play_video(p_path);
- return OK;
-}
-
-bool OS_Android::native_video_is_playing() const {
-
- return godot_io_java->is_video_playing();
-}
-
-void OS_Android::native_video_pause() {
-
- godot_io_java->pause_video();
-}
-
String OS_Android::get_system_dir(SystemDir p_dir) const {
return godot_io_java->get_system_dir(p_dir);
}
-void OS_Android::native_video_stop() {
+void OS_Android::set_display_size(const Size2i &p_size) {
+ display_size = p_size;
+}
- godot_io_java->stop_video();
+Size2i OS_Android::get_display_size() const {
+ return display_size;
}
void OS_Android::set_context_is_16_bits(bool p_is_16) {
-
+#if defined(OPENGL_ENABLED)
//use_16bits_fbo = p_is_16;
//if (rasterizer)
// rasterizer->set_force_16_bits_fbo(p_is_16);
+#endif
}
-void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) {
- return input->joy_connection_changed(p_device, p_connected, p_name, "");
+void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
+#if defined(OPENGL_ENABLED)
+ ERR_FAIL_COND(!p_gl_extensions);
+ gl_extensions = p_gl_extensions;
+#endif
}
-bool OS_Android::is_joy_known(int p_device) {
- return input->is_joy_mapped(p_device);
+void OS_Android::set_native_window(ANativeWindow *p_native_window) {
+#if defined(VULKAN_ENABLED)
+ native_window = p_native_window;
+#endif
}
-String OS_Android::get_joy_guid(int p_device) const {
- return input->get_joy_guid_remapped(p_device);
+ANativeWindow *OS_Android::get_native_window() const {
+#if defined(VULKAN_ENABLED)
+ return native_window;
+#else
+ return nullptr;
+#endif
}
void OS_Android::vibrate_handheld(int p_duration_ms) {
@@ -747,19 +320,21 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
}
OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion) {
+ display_size.width = 800;
+ display_size.height = 600;
use_apk_expansion = p_use_apk_expansion;
- default_videomode.width = 800;
- default_videomode.height = 600;
- default_videomode.fullscreen = true;
- default_videomode.resizable = false;
main_loop = nullptr;
+
+#if defined(OPENGL_ENABLED)
gl_extensions = nullptr;
- //rasterizer = nullptr;
use_gl2 = false;
+#endif
- rendering_server = nullptr;
+#if defined(VULKAN_ENABLED)
+ native_window = nullptr;
+#endif
godot_java = p_godot_java;
godot_io_java = p_godot_io_java;
@@ -769,6 +344,8 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
_set_logger(memnew(CompositeLogger(loggers)));
AudioDriverManager::add_driver(&audio_driver_android);
+
+ DisplayServerAndroid::register_android_driver();
}
OS_Android::~OS_Android() {
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 8a91412ef6..cac7efaa88 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -33,78 +33,45 @@
#include "audio_driver_jandroid.h"
#include "audio_driver_opensl.h"
-#include "core/input/input_filter.h"
#include "core/os/main_loop.h"
#include "drivers/unix/os_unix.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
class GodotJavaWrapper;
class GodotIOJavaWrapper;
-class OS_Android : public OS_Unix {
-public:
- struct TouchPos {
- int id;
- Point2 pos;
- };
-
- enum {
- JOY_EVENT_BUTTON = 0,
- JOY_EVENT_AXIS = 1,
- JOY_EVENT_HAT = 2
- };
-
- struct JoypadEvent {
-
- int device;
- int type;
- int index;
- bool pressed;
- float value;
- int hat;
- };
+struct ANativeWindow;
+class OS_Android : public OS_Unix {
private:
- Vector<TouchPos> touch;
- Point2 hover_prev_pos; // needed to calculate the relative position on hover events
- Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
+ Size2i display_size;
- bool use_gl2;
bool use_apk_expansion;
+#if defined(OPENGL_ENABLED)
bool use_16bits_fbo;
+ const char *gl_extensions;
+#endif
- RenderingServer *rendering_server;
+#if defined(VULKAN_ENABLED)
+ ANativeWindow *native_window;
+#endif
mutable String data_dir_cache;
//AudioDriverAndroid audio_driver_android;
AudioDriverOpenSL audio_driver_android;
- const char *gl_extensions;
-
- InputDefault *input;
- VideoMode default_videomode;
MainLoop *main_loop;
GodotJavaWrapper *godot_java;
GodotIOJavaWrapper *godot_io_java;
- int video_driver_index;
-
public:
- // functions used by main to initialize/deinitialize the OS
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
-
- virtual int get_current_video_driver() const;
-
virtual void initialize_core();
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
+ virtual void initialize();
+
+ virtual void initialize_joypads();
virtual void set_main_loop(MainLoop *p_main_loop);
virtual void delete_main_loop();
@@ -113,37 +80,19 @@ public:
typedef int64_t ProcessID;
- static OS *get_singleton();
+ static OS_Android *get_singleton();
GodotJavaWrapper *get_godot_java();
GodotIOJavaWrapper *get_godot_io_java();
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual bool request_permission(const String &p_name);
virtual bool request_permissions();
virtual Vector<String> get_granted_permissions() const;
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
- virtual void set_mouse_show(bool p_show);
- virtual void set_mouse_grab(bool p_grab);
- virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_position() const;
- virtual int get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
- virtual void set_keep_screen_on(bool p_enabled);
-
- virtual Size2 get_window_size() const;
-
virtual String get_name() const;
virtual MainLoop *get_main_loop() const;
- virtual bool can_draw() const;
-
void main_loop_begin();
bool main_loop_iterate();
void main_loop_request_go_back();
@@ -151,53 +100,25 @@ public:
void main_loop_focusout();
void main_loop_focusin();
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
- virtual void hide_virtual_keyboard();
- virtual int get_virtual_keyboard_height() const;
-
- void set_opengl_extensions(const char *p_gl_extensions);
- void set_display_size(Size2 p_size);
+ void set_display_size(const Size2i &p_size);
+ Size2i get_display_size() const;
void set_context_is_16_bits(bool p_is_16);
+ void set_opengl_extensions(const char *p_gl_extensions);
- virtual void set_screen_orientation(ScreenOrientation p_orientation);
+ void set_native_window(ANativeWindow *p_native_window);
+ ANativeWindow *get_native_window() const;
virtual Error shell_open(String p_uri);
virtual String get_user_data_dir() const;
virtual String get_resource_dir() const;
virtual String get_locale() const;
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
virtual String get_model_name() const;
- virtual int get_screen_dpi(int p_screen = 0) const;
virtual String get_unique_id() const;
virtual String get_system_dir(SystemDir p_dir) const;
- void process_accelerometer(const Vector3 &p_accelerometer);
- void process_gravity(const Vector3 &p_gravity);
- void process_magnetometer(const Vector3 &p_magnetometer);
- void process_gyroscope(const Vector3 &p_gyroscope);
- void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
- void process_hover(int p_type, Point2 p_pos);
- void process_double_tap(Point2 p_pos);
- void process_scroll(Point2 p_pos);
- void process_joy_event(JoypadEvent p_event);
- void process_event(Ref<InputEvent> p_event);
- void init_video_mode(int p_video_width, int p_video_height);
-
- virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- virtual bool native_video_is_playing() const;
- virtual void native_video_pause();
- virtual void native_video_stop();
-
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
- void joy_connection_changed(int p_device, bool p_connected, String p_name);
void vibrate_handheld(int p_duration_ms);
virtual bool _check_internal_feature_support(const String &p_feature);
diff --git a/platform/android/vulkan/vulkan_context_android.cpp b/platform/android/vulkan/vulkan_context_android.cpp
new file mode 100644
index 0000000000..b238f849fc
--- /dev/null
+++ b/platform/android/vulkan/vulkan_context_android.cpp
@@ -0,0 +1,68 @@
+/*************************************************************************/
+/* vulkan_context_android.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "vulkan_context_android.h"
+#include <vulkan/vulkan_android.h>
+
+#define VMA_IMPLEMENTATION
+#ifdef DEBUG_ENABLED
+#ifndef _DEBUG
+#define _DEBUG
+#endif
+#endif
+#include <vk_mem_alloc.h>
+
+const char *VulkanContextAndroid::_get_platform_surface_extension() const {
+ return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
+}
+
+int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, int p_height) {
+ VkAndroidSurfaceCreateInfoKHR createInfo;
+ createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = nullptr;
+ createInfo.flags = 0;
+ createInfo.window = p_window;
+
+ VkSurfaceKHR surface;
+ VkResult err = vkCreateAndroidSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
+ if (err != VK_SUCCESS) {
+ ERR_FAIL_V_MSG(-1, "vkCreateAndroidSurfaceKHR failed with error " + itos(err));
+ }
+
+ return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
+}
+
+VulkanContextAndroid::VulkanContextAndroid() {
+ // TODO: fix validation layers
+ use_validation_layers = false;
+}
+
+VulkanContextAndroid::~VulkanContextAndroid() {
+}
diff --git a/platform/android/vulkan/vk_renderer_jni.cpp b/platform/android/vulkan/vulkan_context_android.h
index 3026e7daad..7e698ada4f 100644
--- a/platform/android/vulkan/vk_renderer_jni.cpp
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* vk_renderer_jni.cpp */
+/* vulkan_context_android.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,31 +28,22 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "vk_renderer_jni.h"
+#ifndef VULKAN_CONTEXT_ANDROID_H
+#define VULKAN_CONTEXT_ANDROID_H
-extern "C" {
+#include "drivers/vulkan/vulkan_context.h"
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceCreated(JNIEnv *env, jobject obj, jobject j_surface) {
- // TODO: complete
-}
+struct ANativeWindow;
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkSurfaceChanged(JNIEnv *env, jobject object, jobject j_surface, jint width, jint height) {
- // TODO: complete
-}
+class VulkanContextAndroid : public VulkanContext {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkResume(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+ virtual const char *_get_platform_surface_extension() const;
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDrawFrame(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+public:
+ int window_create(ANativeWindow *p_window, int p_width, int p_height);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkPause(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
+ VulkanContextAndroid();
+ ~VulkanContextAndroid();
+};
-JNIEXPORT void JNICALL Java_org_godotengine_godot_vulkan_VkRenderer_nativeOnVkDestroy(JNIEnv *env, jobject obj) {
- // TODO: complete
-}
-}
+#endif // VULKAN_CONTEXT_ANDROID_H
diff --git a/servers/display_server.h b/servers/display_server.h
index 1956bcafca..93db7ef844 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -180,7 +180,7 @@ public:
};
virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW);
- ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual void screen_set_keep_on(bool p_enable); //disable screensaver
virtual bool screen_is_kept_on() const;