diff options
Diffstat (limited to 'platform')
21 files changed, 221 insertions, 127 deletions
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 4c45be5210..05cd63d935 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) { @@ -1667,11 +1689,11 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/depth_buffer_bits", PROPERTY_HINT_ENUM, "16 bits,24 bits [default],32 bits"), 1)); 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)); @@ -2138,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 \"Oculus Mobile VR\"."); + err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"OpenXR\"."); + err += "\n"; + } + + if (passthrough_mode > XR_PASSTHROUGH_NONE) { + valid = false; + err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\"."); err += "\n"; } } @@ -2203,18 +2232,12 @@ 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"); } - int depth_buffer_bits_index = p_preset->get("graphics/depth_buffer_bits"); - if (depth_buffer_bits_index >= 0 && depth_buffer_bits_index <= 2) { - int depth_buffer_bits = 16 + depth_buffer_bits_index * 8; - command_line_strings.push_back(vformat("--use_depth=%d", depth_buffer_bits)); - } - bool immersive = p_preset->get("screen/immersive_mode"); if (immersive) { command_line_strings.push_back("--use_immersive"); 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 d872d5ed8a..17ff3c75c0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -119,7 +119,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC private Button mWiFiSettingsButton; private XRMode xrMode = XRMode.REGULAR; - private int depth_buffer_bits = 24; private boolean use_immersive = false; private boolean use_debug_opengl = false; private boolean mStatePaused; @@ -266,8 +265,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC if (videoDriver.equals("vulkan")) { mRenderView = new GodotVulkanRenderView(activity, this); } else { - mRenderView = new GodotGLRenderView(activity, this, xrMode, depth_buffer_bits, - use_debug_opengl); + mRenderView = new GodotGLRenderView(activity, this, xrMode, use_debug_opengl); } View view = mRenderView.getView(); @@ -504,14 +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].startsWith("--use_depth=")) { - try { - depth_buffer_bits = Integer.parseInt(command_line[i].split("=")[1]); - } catch (Exception e) { - e.printStackTrace(); - } + } 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 8b77302491..d5b0b67903 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -78,10 +78,8 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView private final GodotRenderer godotRenderer; private PointerIcon pointerIcon; - public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, int p_depth_buffer_bits, - boolean p_use_debug_opengl) { + public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_debug_opengl) { super(context); - GLUtils.depth_buffer_bits = p_depth_buffer_bits; GLUtils.use_debug_opengl = p_use_debug_opengl; this.godot = godot; @@ -91,7 +89,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { pointerIcon = PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT); } - init(xrMode, false, 16, 0); + init(xrMode, false); } @Override @@ -172,11 +170,11 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView return pointerIcon; } - private void init(XRMode xrMode, boolean translucent, int depth, int stencil) { + private void init(XRMode xrMode, boolean translucent) { setPreserveEGLContextOnPause(true); setFocusableInTouchMode(true); switch (xrMode) { - case OVR: + case OPENXR: // Replace the default egl config chooser. setEGLConfigChooser(new OvrConfigChooser()); @@ -209,16 +207,9 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView * below. */ - RegularConfigChooser configChooser = - new RegularFallbackConfigChooser(8, 8, 8, 8, 16, stencil, - new RegularConfigChooser(5, 6, 5, 0, 16, stencil)); - if (GLUtils.depth_buffer_bits >= 24) { - configChooser = new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, configChooser); - if (GLUtils.depth_buffer_bits >= 32) { - configChooser = new RegularFallbackConfigChooser(8, 8, 8, 8, 32, stencil, configChooser); - } - } - setEGLConfigChooser(configChooser); + setEGLConfigChooser( + new RegularFallbackConfigChooser(8, 8, 8, 8, 24, 0, + new RegularConfigChooser(8, 8, 8, 8, 16, 0))); break; } 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/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java index 0d581785ab..09820fad5f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java @@ -44,7 +44,6 @@ public class GLUtils { public static final boolean DEBUG = false; - public static int depth_buffer_bits; // No need to reiterate the default here public static boolean use_debug_opengl = false; private static final String[] ATTRIBUTES_NAMES = new String[] { 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/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..d85d0d5335 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,9 @@ const GodotInput = { const rect = canvas.getBoundingClientRect(); const pos = GodotInput.computePosition(evt, rect); const modifiers = GodotInput.getModifiers(evt); + if (p_pressed && document.activeElement !== GodotConfig.canvas) { + GodotConfig.canvas.focus(); + } if (func(p_pressed, evt.button, pos[0], pos[1], modifiers)) { evt.preventDefault(); } @@ -405,6 +412,9 @@ const GodotInput = { const func = GodotRuntime.get_func(callback); const canvas = GodotConfig.canvas; function touch_cb(type, evt) { + if (type === 0 && document.activeElement !== GodotConfig.canvas) { + 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/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 2252d5eb4f..57bca7a5b9 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -134,8 +134,13 @@ static void handle_crash(int sig) { args.push_back("-o"); args.push_back(_execpath); +#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) args.push_back("-arch"); args.push_back("x86_64"); +#elif defined(__aarch64__) + args.push_back("-arch"); + args.push_back("arm64"); +#endif args.push_back("-l"); snprintf(str, 1024, "%p", load_addr); args.push_back(str); diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 6bd79c7d4f..f5c7731395 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -82,7 +82,7 @@ def configure(env): env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"]) env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"]) else: - print("Building for macOS 10.12+, platform x86-64.") + print("Building for macOS 10.12+, platform x86_64.") env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index d4ba7879f1..8405ed1da1 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -58,6 +58,7 @@ void joypad::free() { if (ff_device) { FFDeviceReleaseEffect(ff_device, ff_object); FFReleaseDevice(ff_device); + ff_device = nullptr; memfree(ff_axes); memfree(ff_directions); } @@ -243,7 +244,7 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) { if (is_joypad(p_device)) { configure_joypad(p_device, &new_joypad); #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (IOHIDDeviceGetService != nullptr) { + if (IOHIDDeviceGetService) { #endif const io_service_t ioservice = IOHIDDeviceGetService(p_device); if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK) && new_joypad.config_force_feedback(ioservice)) { @@ -348,6 +349,7 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { { \ if (ret != FF_OK) { \ FFReleaseDevice(ff_device); \ + ff_device = nullptr; \ return false; \ } \ } @@ -367,6 +369,7 @@ bool joypad::config_force_feedback(io_service_t p_service) { return true; } FFReleaseDevice(ff_device); + ff_device = nullptr; return false; } #undef FF_ERR @@ -601,7 +604,7 @@ JoypadOSX::JoypadOSX(Input *in) { if (array) { hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - if (hid_manager != nullptr) { + if (hid_manager) { config_hid_manager(array); } CFRelease(array); diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index 3048ecf39e..2ba7f0d950 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -68,8 +68,8 @@ struct joypad { io_service_t ffservice = 0; /* Interface for force feedback, 0 = no ff */ FFCONSTANTFORCE ff_constant_force; - FFDeviceObjectReference ff_device; - FFEffectObjectReference ff_object; + FFDeviceObjectReference ff_device = nullptr; + FFEffectObjectReference ff_object = nullptr; uint64_t ff_timestamp = 0; LONG *ff_directions = nullptr; FFEFFECT ff_effect; 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/os_windows.cpp b/platform/windows/os_windows.cpp index 2c21390d73..d8d4e92d9d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -760,7 +760,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 { |