summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-07-18 15:38:14 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-07-18 15:38:14 +0200
commit1e81a946cc8e7c913c1267a4489f8b0f3fffd5b1 (patch)
tree258645a8837132523ccf720d4b757252e51fc8dc
parentd12030e6d7bb73cc182482ad120e2f33ddd69b7c (diff)
parent7a5a8597eb81b20b14d3ab1f8b2d6dace49a2603 (diff)
downloadredot-engine-1e81a946cc8e7c913c1267a4489f8b0f3fffd5b1.tar.gz
Merge pull request #94412 from dsnopek/xr-always-render
Always render when XR is enabled, even if no OS windows can draw
-rw-r--r--doc/classes/DisplayServer.xml21
-rw-r--r--main/main.cpp2
-rw-r--r--modules/openxr/openxr_interface.cpp6
-rw-r--r--servers/display_server.cpp15
-rw-r--r--servers/display_server.h6
5 files changed, 49 insertions, 1 deletions
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 62556ed38f..0bed5288bd 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -880,6 +880,12 @@
Registers callables to emit when the menu is respectively about to show or closed. Callback methods should have zero arguments.
</description>
</method>
+ <method name="has_additional_outputs" qualifiers="const">
+ <return type="bool" />
+ <description>
+ Returns [code]true[/code] if any additional outputs have been registered via [method register_additional_output].
+ </description>
+ </method>
<method name="has_feature" qualifiers="const">
<return type="bool" />
<param index="0" name="feature" type="int" enum="DisplayServer.Feature" />
@@ -1023,6 +1029,14 @@
Perform window manager processing, including input flushing. See also [method force_process_and_drop_events], [method Input.flush_buffered_events] and [member Input.use_accumulated_input].
</description>
</method>
+ <method name="register_additional_output">
+ <return type="void" />
+ <param index="0" name="object" type="Object" />
+ <description>
+ Registers an [Object] which represents an additional output that will be rendered too, beyond normal windows. The [Object] is only used as an identifier, which can be later passed to [method unregister_additional_output].
+ This can be used to prevent Godot from skipping rendering when no normal windows are visible.
+ </description>
+ </method>
<method name="screen_get_dpi" qualifiers="const">
<return type="int" />
<param index="0" name="screen" type="int" default="-1" />
@@ -1353,6 +1367,13 @@
[b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech.
</description>
</method>
+ <method name="unregister_additional_output">
+ <return type="void" />
+ <param index="0" name="object" type="Object" />
+ <description>
+ Unregisters an [Object] representing an additional output, that was registered via [method register_additional_output].
+ </description>
+ </method>
<method name="virtual_keyboard_get_height" qualifiers="const">
<return type="int" />
<description>
diff --git a/main/main.cpp b/main/main.cpp
index 1cabe43065..86abf94c0a 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -4107,7 +4107,7 @@ bool Main::iteration() {
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
- if (DisplayServer::get_singleton()->can_any_window_draw() &&
+ if ((DisplayServer::get_singleton()->can_any_window_draw() || DisplayServer::get_singleton()->has_additional_outputs()) &&
RenderingServer::get_singleton()->is_render_loop_enabled()) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (RenderingServer::get_singleton()->has_changed()) {
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index fbbc61a91c..cce9c09361 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -651,6 +651,10 @@ bool OpenXRInterface::initialize() {
// make this our primary interface
xr_server->set_primary_interface(this);
+ // Register an additional output with the display server, so rendering won't
+ // be skipped if no windows are visible.
+ DisplayServer::get_singleton()->register_additional_output(this);
+
initialized = true;
return initialized;
@@ -674,6 +678,8 @@ void OpenXRInterface::uninitialize() {
}
}
+ DisplayServer::get_singleton()->unregister_additional_output(this);
+
initialized = false;
}
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index b6e0d58af7..d362a4073a 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -759,6 +759,17 @@ DisplayServer::WindowID DisplayServer::get_focused_window() const {
void DisplayServer::set_context(Context p_context) {
}
+void DisplayServer::register_additional_output(Object *p_object) {
+ ObjectID id = p_object->get_instance_id();
+ if (!additional_outputs.has(id)) {
+ additional_outputs.push_back(id);
+ }
+}
+
+void DisplayServer::unregister_additional_output(Object *p_object) {
+ additional_outputs.erase(p_object->get_instance_id());
+}
+
void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature);
ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name);
@@ -997,6 +1008,10 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_window_transparency_available"), &DisplayServer::is_window_transparency_available);
+ ClassDB::bind_method(D_METHOD("register_additional_output", "object"), &DisplayServer::register_additional_output);
+ ClassDB::bind_method(D_METHOD("unregister_additional_output", "object"), &DisplayServer::unregister_additional_output);
+ ClassDB::bind_method(D_METHOD("has_additional_outputs"), &DisplayServer::has_additional_outputs);
+
#ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU);
#endif
diff --git a/servers/display_server.h b/servers/display_server.h
index 5d82b6c13c..8c7e92fdc3 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -53,6 +53,8 @@ class DisplayServer : public Object {
RID _get_rid_from_name(NativeMenu *p_nmenu, const String &p_menu_root) const;
#endif
+ LocalVector<ObjectID> additional_outputs;
+
public:
_FORCE_INLINE_ static DisplayServer *get_singleton() {
return singleton;
@@ -582,6 +584,10 @@ public:
virtual bool is_window_transparency_available() const { return false; }
+ void register_additional_output(Object *p_output);
+ void unregister_additional_output(Object *p_output);
+ bool has_additional_outputs() const { return additional_outputs.size() > 0; }
+
static void register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers);
static int get_create_function_count();
static const char *get_create_function_name(int p_index);