diff options
Diffstat (limited to 'platform')
27 files changed, 233 insertions, 108 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index dc259da886..52f80b3080 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -223,7 +223,7 @@ void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector ev->set_pressed(false); ev->set_position(touch[i].pos); Input::get_singleton()->parse_input_event(ev); - touch.remove(i); + touch.remove_at(i); break; } diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 34f0064a5e..505e7ac0eb 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -119,7 +119,9 @@ DisplayServer::ScreenOrientation DisplayServerAndroid::screen_get_orientation(in 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(); + const int orientation = godot_io_java->get_screen_orientation(); + ERR_FAIL_INDEX_V_MSG(orientation, 7, SCREEN_LANDSCAPE, "Unrecognized screen orientation"); + return (ScreenOrientation)orientation; } int DisplayServerAndroid::get_screen_count() const { diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 18e9e20948..c5d3cbd966 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -751,9 +751,9 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> } int xr_mode_index = p_preset->get("xr_features/xr_mode"); - if (xr_mode_index == 1 /* XRMode.OVR */) { + if (xr_mode_index == XR_MODE_OPENXR) { int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required - if (hand_tracking_index > 0) { + if (hand_tracking_index > XR_HAND_TRACKING_NONE) { if (r_permissions.find("com.oculus.permission.HAND_TRACKING") == -1) { r_permissions.push_back("com.oculus.permission.HAND_TRACKING"); } @@ -964,6 +964,20 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p } } + if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") { + // Update the meta-data 'android:name' attribute based on the selected XR mode. + if (xr_mode_index == XR_MODE_OPENXR) { + string_table.write[attr_value] = "com.samsung.android.vr.application.mode"; + } + } + + if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") { + // Update the meta-data 'android:value' attribute based on the selected XR mode. + if (xr_mode_index == XR_MODE_OPENXR) { + string_table.write[attr_value] = "vr_only"; + } + } + iofs += 20; } @@ -978,7 +992,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p Vector<bool> feature_required_list; Vector<int> feature_versions; - if (xr_mode_index == 1 /* XRMode.OVR */) { + if (xr_mode_index == XR_MODE_OPENXR) { // Set degrees of freedom feature_names.push_back("android.hardware.vr.headtracking"); feature_required_list.push_back(true); @@ -986,11 +1000,19 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p // Check for hand tracking int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required - if (hand_tracking_index > 0) { + if (hand_tracking_index > XR_HAND_TRACKING_NONE) { feature_names.push_back("oculus.software.handtracking"); - feature_required_list.push_back(hand_tracking_index == 2); + feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED); feature_versions.push_back(-1); // no version attribute should be added. } + + // Check for passthrough + int passthrough_mode = p_preset->get("xr_features/passthrough"); + if (passthrough_mode > XR_PASSTHROUGH_NONE) { + feature_names.push_back("com.oculus.feature.PASSTHROUGH"); + feature_required_list.push_back(passthrough_mode == XR_PASSTHROUGH_REQUIRED); + feature_versions.push_back(-1); + } } if (feature_names.size() > 0) { @@ -1669,8 +1691,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true)); @@ -2137,10 +2160,17 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr // Validate the Xr features are properly populated int xr_mode_index = p_preset->get("xr_features/xr_mode"); int hand_tracking = p_preset->get("xr_features/hand_tracking"); - if (xr_mode_index != /* XRMode.OVR*/ 1) { - if (hand_tracking > 0) { + int passthrough_mode = p_preset->get("xr_features/passthrough"); + if (xr_mode_index != XR_MODE_OPENXR) { + if (hand_tracking > XR_HAND_TRACKING_NONE) { + valid = false; + err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"OpenXR\"."); + err += "\n"; + } + + if (passthrough_mode > XR_PASSTHROUGH_NONE) { valid = false; - err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."); + err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."); err += "\n"; } } @@ -2182,7 +2212,7 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP Vector<String> command_line_strings = cmdline.strip_edges().split(" "); for (int i = 0; i < command_line_strings.size(); i++) { if (command_line_strings[i].strip_edges().length() == 0) { - command_line_strings.remove(i); + command_line_strings.remove_at(i); i--; } } @@ -2202,8 +2232,8 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP } int xr_mode_index = p_preset->get("xr_features/xr_mode"); - if (xr_mode_index == 1) { - command_line_strings.push_back("--xr_mode_ovr"); + if (xr_mode_index == XR_MODE_OPENXR) { + command_line_strings.push_back("--xr_mode_openxr"); } else { // XRMode.REGULAR is the default. command_line_strings.push_back("--xr_mode_regular"); } diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index b0d623827e..658c0ecd0a 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -211,16 +211,24 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) { String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) { String manifest_xr_features; - bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; + int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode")); + bool uses_xr = xr_mode_index == XR_MODE_OPENXR; if (uses_xr) { manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n"; int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required - if (hand_tracking_index == 1) { + if (hand_tracking_index == XR_HAND_TRACKING_OPTIONAL) { manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n"; - } else if (hand_tracking_index == 2) { + } else if (hand_tracking_index == XR_HAND_TRACKING_REQUIRED) { manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"true\" />\n"; } + + int passthrough_mode = p_preset->get("xr_features/passthrough"); + if (passthrough_mode == XR_PASSTHROUGH_OPTIONAL) { + manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"false\" />\n"; + } else if (passthrough_mode == XR_PASSTHROUGH_REQUIRED) { + manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n"; + } } return manifest_xr_features; } @@ -239,7 +247,8 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) { } String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { - bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; + int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode")); + bool uses_xr = xr_mode_index == XR_MODE_OPENXR; String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String manifest_activity_text = vformat( " <activity android:name=\"com.godot.game.GodotApp\" " @@ -256,6 +265,8 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { } String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) { + int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode")); + bool uses_xr = xr_mode_index == XR_MODE_OPENXR; String manifest_application_text = vformat( " <application android:label=\"@string/godot_project_name_string\"\n" " android:allowBackup=\"%s\"\n" @@ -270,6 +281,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ bool_to_string(p_preset->get("package/retain_data_on_uninstall")), bool_to_string(p_has_storage_permission)); + if (uses_xr) { + manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n"; + } manifest_application_text += _get_activity_tag(p_preset); manifest_application_text += " </application>\n"; return manifest_application_text; diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 744022f1f9..db05c7534c 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -44,6 +44,21 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut </resources> )"; +// Supported XR modes. +// This should match the entries in 'platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java' +static const int XR_MODE_REGULAR = 0; +static const int XR_MODE_OPENXR = 1; + +// Supported XR hand tracking modes. +static const int XR_HAND_TRACKING_NONE = 0; +static const int XR_HAND_TRACKING_OPTIONAL = 1; +static const int XR_HAND_TRACKING_REQUIRED = 2; + +// Supported XR passthrough modes. +static const int XR_PASSTHROUGH_NONE = 0; +static const int XR_PASSTHROUGH_OPTIONAL = 1; +static const int XR_PASSTHROUGH_REQUIRED = 2; + struct CustomExportData { String assets_directory; bool debug; diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index d7bf6cef30..9ae6367b42 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -33,6 +33,11 @@ <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> <!-- Do these changes in the export preset. Adding new ones is fine. --> + <!-- XR mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> + <meta-data + android:name="xr_mode_metadata_name" + android:value="xr_mode_metadata_value" /> + <activity android:name=".GodotApp" android:label="@string/godot_project_name_string" 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 b6476fa61a..17ff3c75c0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -502,8 +502,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC boolean has_extra = i < command_line.length - 1; if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { xrMode = XRMode.REGULAR; - } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { - xrMode = XRMode.OVR; + } else if (command_line[i].equals(XRMode.OPENXR.cmdLineArg)) { + xrMode = XRMode.OPENXR; } else if (command_line[i].equals("--debug_opengl")) { use_debug_opengl = true; } else if (command_line[i].equals("--use_immersive")) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index 088b048502..d5b0b67903 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -174,7 +174,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView setPreserveEGLContextOnPause(true); setFocusableInTouchMode(true); switch (xrMode) { - case OVR: + case OPENXR: // Replace the default egl config chooser. setEGLConfigChooser(new OvrConfigChooser()); 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 d85d88ec6c..5f354b6b4c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -288,7 +288,34 @@ public class GodotIO { } public int getScreenOrientation() { - return activity.getRequestedOrientation(); + int orientation = activity.getRequestedOrientation(); + switch (orientation) { + case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: + return SCREEN_LANDSCAPE; + case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: + return SCREEN_PORTRAIT; + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: + return SCREEN_REVERSE_LANDSCAPE; + case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: + return SCREEN_REVERSE_PORTRAIT; + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: + case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE: + return SCREEN_SENSOR_LANDSCAPE; + case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT: + case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT: + return SCREEN_SENSOR_PORTRAIT; + case ActivityInfo.SCREEN_ORIENTATION_SENSOR: + case ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR: + case ActivityInfo.SCREEN_ORIENTATION_FULL_USER: + return SCREEN_SENSOR; + case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED: + case ActivityInfo.SCREEN_ORIENTATION_USER: + case ActivityInfo.SCREEN_ORIENTATION_BEHIND: + case ActivityInfo.SCREEN_ORIENTATION_NOSENSOR: + case ActivityInfo.SCREEN_ORIENTATION_LOCKED: + default: + return -1; + } } public void setEdit(GodotEditText _edit) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java index 0995477baf..58f02b0396 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java @@ -35,7 +35,7 @@ package org.godotengine.godot.xr; */ public enum XRMode { REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen - OVR(1, "Oculus Mobile VR", "--xr_mode_ovr", ""); + OPENXR(1, "OpenXR", "--xr_mode_openxr", ""); final int index; final String label; diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index fa9e6eed15..8d9ba82fd4 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -28,11 +28,11 @@ if env["javascript_eval"]: sys_env.AddJSLibraries(["js/libs/library_godot_javascript_singleton.js"]) for lib in sys_env["JS_LIBS"]: - sys_env.Append(LINKFLAGS=["--js-library", lib]) + sys_env.Append(LINKFLAGS=["--js-library", lib.abspath]) for js in env["JS_PRE"]: - sys_env.Append(LINKFLAGS=["--pre-js", env.File(js).path]) + sys_env.Append(LINKFLAGS=["--pre-js", js.abspath]) for ext in env["JS_EXTERNS"]: - sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.path + sys_env["ENV"]["EMCC_CLOSURE_ARGS"] += " --externs " + ext.abspath build = [] if env["gdnative_enabled"]: diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 891ae419bd..b57f3b3f16 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -180,6 +180,13 @@ def configure(env): env.Prepend(CPPPATH=["#platform/javascript"]) env.Append(CPPDEFINES=["JAVASCRIPT_ENABLED", "UNIX_ENABLED"]) + if env["opengl3"]: + env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"]) + # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. + env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"]) + # Allow use to take control of swapping WebGL buffers. + env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) + if env["javascript_eval"]: env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"]) @@ -218,25 +225,11 @@ def configure(env): # us since we don't know requirements at compile-time. env.Append(LINKFLAGS=["-s", "ALLOW_MEMORY_GROWTH=1"]) - # This setting just makes WebGL 2 APIs available, it does NOT disable WebGL 1. - env.Append(LINKFLAGS=["-s", "USE_WEBGL2=1"]) - # Do not call main immediately when the support code is ready. env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"]) - # Allow use to take control of swapping WebGL buffers. - env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"]) - # callMain for manual start, cwrap for the mono version. env.Append(LINKFLAGS=["-s", "EXPORTED_RUNTIME_METHODS=['callMain','cwrap']"]) # Add code that allow exiting runtime. env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"]) - - # TODO remove once we have GLES support back (temporary fix undefined symbols due to dead code elimination). - env.Append( - LINKFLAGS=[ - "-s", - "EXPORTED_FUNCTIONS=['_main', '_emscripten_webgl_get_current_context']", - ] - ) diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index d12e1aeee8..7648ddaf43 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -30,6 +30,9 @@ #include "platform/javascript/display_server_javascript.h" +#ifdef GLES3_ENABLED +#include "drivers/gles3/rasterizer_gles3.h" +#endif #include "platform/javascript/os_javascript.h" #include "servers/rendering/rasterizer_dummy.h" @@ -50,14 +53,6 @@ DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() { } // Window (canvas) -void DisplayServerJavaScript::focus_canvas() { - godot_js_display_canvas_focus(); -} - -bool DisplayServerJavaScript::is_canvas_focused() { - return godot_js_display_canvas_is_focused() != 0; -} - bool DisplayServerJavaScript::check_size_force_redraw() { return godot_js_display_size_update() != 0; } @@ -141,11 +136,12 @@ void DisplayServerJavaScript::key_callback(int p_pressed, int p_repeat, int p_mo int DisplayServerJavaScript::mouse_button_callback(int p_pressed, int p_button, double p_x, double p_y, int p_modifiers) { DisplayServerJavaScript *ds = get_singleton(); + Point2 pos(p_x, p_y); + Input::get_singleton()->set_mouse_position(pos); Ref<InputEventMouseButton> ev; ev.instantiate(); - ev->set_pressed(p_pressed); - ev->set_position(Point2(p_x, p_y)); - ev->set_global_position(ev->get_position()); + ev->set_position(pos); + ev->set_global_position(pos); ev->set_pressed(p_pressed); dom2godot_mod(ev, p_modifiers); @@ -222,13 +218,15 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double return; } + Point2 pos(p_x, p_y); + Input::get_singleton()->set_mouse_position(pos); Ref<InputEventMouseMotion> ev; ev.instantiate(); dom2godot_mod(ev, p_modifiers); ev->set_button_mask(input_mask); - ev->set_position(Point2(p_x, p_y)); - ev->set_global_position(ev->get_position()); + ev->set_position(pos); + ev->set_global_position(pos); ev->set_relative(Vector2(p_rel_x, p_rel_y)); Input::get_singleton()->set_mouse_position(ev->get_position()); @@ -397,6 +395,10 @@ DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const { return MOUSE_MODE_VISIBLE; } +Point2i DisplayServerJavaScript::mouse_get_position() const { + return Input::get_singleton()->get_mouse_position(); +} + // Wheel int DisplayServerJavaScript::mouse_wheel_callback(double p_delta_x, double p_delta_y) { if (!godot_js_display_canvas_is_focused()) { @@ -580,7 +582,9 @@ void DisplayServerJavaScript::process_joypads() { Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() { Vector<String> drivers; - drivers.push_back("dummy"); +#ifdef GLES3_ENABLED + drivers.push_back("opengl3"); +#endif return drivers; } @@ -678,40 +682,34 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive // Expose method for requesting quit. godot_js_os_request_quit_cb(request_quit_callback); - RasterizerDummy::make_current(); // TODO OpenGL in Godot 4.0... or webgpu? -#if 0 - EmscriptenWebGLContextAttributes attributes; - emscripten_webgl_init_context_attributes(&attributes); - attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed"); - attributes.antialias = false; - ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER); - - if (p_desired.layered) { - set_window_per_pixel_transparency_enabled(true); - } - - bool gl_initialization_error = false; - - if (RasterizerGLES3::is_viable() == OK) { - attributes.majorVersion = 1; - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - } else { - gl_initialization_error = true; - } - - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(canvas_id, &attributes); - if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) { - gl_initialization_error = true; +#ifdef GLES3_ENABLED + // TODO "vulkan" defaults to webgl2 for now. + bool wants_webgl2 = p_rendering_driver == "opengl3" || p_rendering_driver == "vulkan"; + bool webgl2_init_failed = wants_webgl2 && !godot_js_display_has_webgl(2); + if (wants_webgl2 && !webgl2_init_failed) { + EmscriptenWebGLContextAttributes attributes; + emscripten_webgl_init_context_attributes(&attributes); + //attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed"); + attributes.alpha = true; + attributes.antialias = false; + attributes.majorVersion = 2; + + webgl_ctx = emscripten_webgl_create_context(canvas_id, &attributes); + if (emscripten_webgl_make_context_current(webgl_ctx) != EMSCRIPTEN_RESULT_SUCCESS) { + webgl2_init_failed = true; + } else { + RasterizerGLES3::make_current(); + } } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.", + if (webgl2_init_failed) { + OS::get_singleton()->alert("Your browser does not seem to support WebGL2. Please update your browser version.", "Unable to initialize video driver"); - return ERR_UNAVAILABLE; } - - video_driver_index = p_video_driver; + if (!wants_webgl2 || webgl2_init_failed) { + RasterizerDummy::make_current(); + } +#else + RasterizerDummy::make_current(); #endif // JS Input interface (js/libs/library_godot_input.js) @@ -738,8 +736,12 @@ DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_drive } DisplayServerJavaScript::~DisplayServerJavaScript() { - //emscripten_webgl_commit_frame(); - //emscripten_webgl_destroy_context(webgl_ctx); +#ifdef GLES3_ENABLED + if (webgl_ctx) { + emscripten_webgl_commit_frame(); + emscripten_webgl_destroy_context(webgl_ctx); + } +#endif } bool DisplayServerJavaScript::has_feature(Feature p_feature) const { @@ -968,5 +970,9 @@ bool DisplayServerJavaScript::get_swap_cancel_ok() { } void DisplayServerJavaScript::swap_buffers() { - //emscripten_webgl_commit_frame(); +#ifdef GLES3_ENABLED + if (webgl_ctx) { + emscripten_webgl_commit_frame(); + } +#endif } diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h index 80ce772a79..843bb61984 100644 --- a/platform/javascript/display_server_javascript.h +++ b/platform/javascript/display_server_javascript.h @@ -51,6 +51,10 @@ private: }; JSKeyEvent key_event; +#ifdef GLES3_ENABLED + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE webgl_ctx = 0; +#endif + WindowMode window_mode = WINDOW_MODE_WINDOWED; ObjectID window_attached_instance_id = {}; @@ -72,8 +76,6 @@ private: bool swap_cancel_ok = false; // utilities - static void focus_canvas(); - static bool is_canvas_focused(); static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod); static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); @@ -121,6 +123,7 @@ public: // mouse virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; + virtual Point2i mouse_get_position() const override; // touch virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js index 587c320f35..3c1c05e44e 100644 --- a/platform/javascript/js/libs/library_godot_input.js +++ b/platform/javascript/js/libs/library_godot_input.js @@ -104,10 +104,14 @@ const GodotInputGamepads = { } } GodotEventListeners.add(window, 'gamepadconnected', function (evt) { - add(evt.gamepad); + if (evt.gamepad) { + add(evt.gamepad); + } }, false); GodotEventListeners.add(window, 'gamepaddisconnected', function (evt) { - onchange(evt.gamepad.index, 0); + if (evt.gamepad) { + onchange(evt.gamepad.index, 0); + } }, false); }, @@ -389,6 +393,11 @@ const GodotInput = { const rect = canvas.getBoundingClientRect(); const pos = GodotInput.computePosition(evt, rect); const modifiers = GodotInput.getModifiers(evt); + // Since the event is consumed, focus manually. + // NOTE: The iframe container may not have focus yet, so focus even when already active. + if (p_pressed) { + GodotConfig.canvas.focus(); + } if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) { evt.preventDefault(); } @@ -405,6 +414,11 @@ const GodotInput = { const func = GodotRuntime.get_func(callback); const canvas = GodotConfig.canvas; function touch_cb(type, evt) { + // Since the event is consumed, focus manually. + // NOTE: The iframe container may not have focus yet, so focus even when already active. + if (type === 0) { + GodotConfig.canvas.focus(); + } const rect = canvas.getBoundingClientRect(); const touches = evt.changedTouches; for (let i = 0; i < touches.length; i++) { diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index d053082d92..fbab95d33b 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -75,6 +75,7 @@ public: Error kill(const ProcessID &p_pid) override; int get_process_id() const override; int get_processor_count() const override; + int get_default_thread_pool_size() const override { return 1; } String get_executable_path() const override; Error shell_open(String p_uri) override; @@ -89,6 +90,7 @@ public: String get_user_data_dir() const override; bool is_userfs_persistent() const override; + bool is_single_window() const override { return true; } void alert(const String &p_alert, const String &p_title = "ALERT!") override; diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 2a62780410..74ec8b652f 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -286,7 +286,7 @@ void DisplayServerX11::_flush_mouse_motion() { XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data; if (event_data->evtype == XI_RawMotion) { XFreeEventData(x11_display, &event.xcookie); - polled_events.remove(event_index--); + polled_events.remove_at(event_index--); continue; } XFreeEventData(x11_display, &event.xcookie); diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp index 1c6afabfab..55cc21cc6c 100644 --- a/platform/linuxbsd/joypad_linux.cpp +++ b/platform/linuxbsd/joypad_linux.cpp @@ -253,7 +253,7 @@ void JoypadLinux::close_joypad(int p_id) { if (joy.fd != -1) { close(joy.fd); joy.fd = -1; - attached_devices.remove(attached_devices.find(joy.devpath)); + attached_devices.remove_at(attached_devices.find(joy.devpath)); input->joy_connection_changed(p_id, false, ""); }; } diff --git a/platform/osx/gl_manager_osx.mm b/platform/osx/gl_manager_osx.mm index cce58530ee..60e0706fc0 100644 --- a/platform/osx/gl_manager_osx.mm +++ b/platform/osx/gl_manager_osx.mm @@ -75,7 +75,7 @@ Error GLManager_OSX::window_create(DisplayServer::WindowID p_window_id, id p_vie win.window_view = p_view; if (_create_context(win) != OK) { - _windows.remove(_windows.size() - 1); + _windows.remove_at(_windows.size() - 1); return FAILED; } diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index 8405ed1da1..48d165d30b 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -264,7 +264,7 @@ void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) { input->joy_connection_changed(device_list[device].id, false, ""); device_list.write[device].free(); - device_list.remove(device); + device_list.remove_at(device); } static String _hex_str(uint8_t p_byte) { diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 45a81be80a..39608bdea8 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -178,7 +178,7 @@ class OSXTerminalLogger : public StdLogger { public: - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type = ERR_ERROR) { + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) { if (!should_log(true)) { return; } diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp index a54b85a803..192814efe4 100644 --- a/platform/uwp/export/export_plugin.cpp +++ b/platform/uwp/export/export_plugin.cpp @@ -376,7 +376,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p Vector<String> cl = ((String)p_preset->get("command_line/extra_args")).strip_edges().split(" "); for (int i = 0; i < cl.size(); i++) { if (cl[i].strip_edges().length() == 0) { - cl.remove(i); + cl.remove_at(i); i--; } } diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 20deb35089..aaaa50e729 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -206,6 +206,8 @@ def configure_msvc(env, manual_msvc_config): elif env["target"] == "debug": env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) + # Allow big objects. Only needed for debug, see MinGW branch for rationale. + env.AppendUnique(CCFLAGS=["/bigobj"]) env.Append(LINKFLAGS=["/DEBUG"]) if env["debug_symbols"]: @@ -227,7 +229,6 @@ def configure_msvc(env, manual_msvc_config): env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"]) env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding. - env.AppendUnique(CCFLAGS=["/bigobj"]) # Allow big objects, no drawbacks. env.AppendUnique(CXXFLAGS=["/TP"]) # assume all sources are C++ if manual_msvc_config: # should be automatic if SCons found it @@ -359,6 +360,10 @@ def configure_mingw(env): elif env["target"] == "debug": env.Append(CCFLAGS=["-g3"]) + # Allow big objects. It's supposed not to have drawbacks but seems to break + # GCC LTO, so enabling for debug builds only (which are not built with LTO + # and are the only ones with too big objects). + env.Append(CCFLAGS=["-Wa,-mbig-obj"]) if env["windows_subsystem"] == "gui": env.Append(LINKFLAGS=["-Wl,--subsystem,windows"]) @@ -422,7 +427,6 @@ def configure_mingw(env): ## Compile flags env.Append(CCFLAGS=["-mwindows"]) - env.Append(CCFLAGS=["-Wa,-mbig-obj"]) # Allow big objects, no drawbacks. env.Append(CPPDEFINES=["WINDOWS_ENABLED", "WASAPI_ENABLED", "WINMIDI_ENABLED"]) env.Append(CPPDEFINES=[("WINVER", env["target_win_version"]), ("_WIN32_WINNT", env["target_win_version"])]) diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows.cpp index 1ce8b0b040..fe98f8b0ba 100644 --- a/platform/windows/gl_manager_windows.cpp +++ b/platform/windows/gl_manager_windows.cpp @@ -77,7 +77,7 @@ int GLManager_Windows::_find_or_create_display(GLWindow &win) { if (err != OK) { // not good // delete the _display? - _displays.remove(new_display_id); + _displays.remove_at(new_display_id); return -1; } @@ -193,7 +193,7 @@ Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND if (win.gldisplay_id == -1) { // release DC? - _windows.remove(_windows.size() - 1); + _windows.remove_at(_windows.size() - 1); return FAILED; } diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2c21390d73..6a0a4790fc 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -447,7 +447,12 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS; +#ifndef DEBUG_ENABLED + dwCreationFlags |= CREATE_NO_WINDOW; +#endif + + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi); ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); WaitForSingleObject(pi.pi.hProcess, INFINITE); @@ -475,7 +480,12 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg ZeroMemory(&pi.pi, sizeof(pi.pi)); LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; - int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi); + DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS; +#ifndef DEBUG_ENABLED + dwCreationFlags |= CREATE_NO_WINDOW; +#endif + + int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi); ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); ProcessID pid = pi.pi.dwProcessId; @@ -760,7 +770,7 @@ String OS_Windows::get_user_data_dir() const { } } - return ProjectSettings::get_singleton()->get_resource_path(); + return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file("[unnamed project]"); } String OS_Windows::get_unique_id() const { diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index e54a61fdfd..d4148630f0 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -71,7 +71,7 @@ void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_er #endif } -void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { +void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type) { if (!should_log(true)) { return; } diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h index aacfe5869e..86b65ae30a 100644 --- a/platform/windows/windows_terminal_logger.h +++ b/platform/windows/windows_terminal_logger.h @@ -37,8 +37,8 @@ class WindowsTerminalLogger : public StdLogger { public: - virtual void logv(const char *p_format, va_list p_list, bool p_err); - virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + virtual void logv(const char *p_format, va_list p_list, bool p_err) override; + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR) override; virtual ~WindowsTerminalLogger(); }; |