Merge pull request #94412 from dsnopek/xr-always-render

Always render when XR is enabled, even if no OS windows can draw
This commit is contained in:
Rémi Verschelde 2024-07-18 15:38:14 +02:00
commit 1e81a946cc
No known key found for this signature in database
GPG Key ID: C3336907360768E1
5 changed files with 49 additions and 1 deletions

View File

@ -880,6 +880,12 @@
Registers callables to emit when the menu is respectively about to show or closed. Callback methods should have zero arguments. Registers callables to emit when the menu is respectively about to show or closed. Callback methods should have zero arguments.
</description> </description>
</method> </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"> <method name="has_feature" qualifiers="const">
<return type="bool" /> <return type="bool" />
<param index="0" name="feature" type="int" enum="DisplayServer.Feature" /> <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]. 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> </description>
</method> </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"> <method name="screen_get_dpi" qualifiers="const">
<return type="int" /> <return type="int" />
<param index="0" name="screen" type="int" default="-1" /> <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. [b]Note:[/b] [member ProjectSettings.audio/general/text_to_speech] should be [code]true[/code] to use text-to-speech.
</description> </description>
</method> </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"> <method name="virtual_keyboard_get_height" qualifiers="const">
<return type="int" /> <return type="int" />
<description> <description>

View File

@ -4107,7 +4107,7 @@ bool Main::iteration() {
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames. 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()) { RenderingServer::get_singleton()->is_render_loop_enabled()) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) { if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (RenderingServer::get_singleton()->has_changed()) { if (RenderingServer::get_singleton()->has_changed()) {

View File

@ -651,6 +651,10 @@ bool OpenXRInterface::initialize() {
// make this our primary interface // make this our primary interface
xr_server->set_primary_interface(this); 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; initialized = true;
return initialized; return initialized;
@ -674,6 +678,8 @@ void OpenXRInterface::uninitialize() {
} }
} }
DisplayServer::get_singleton()->unregister_additional_output(this);
initialized = false; initialized = false;
} }

View File

@ -759,6 +759,17 @@ DisplayServer::WindowID DisplayServer::get_focused_window() const {
void DisplayServer::set_context(Context p_context) { 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() { void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature); ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature);
ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name); 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("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 #ifndef DISABLE_DEPRECATED
BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU); BIND_ENUM_CONSTANT(FEATURE_GLOBAL_MENU);
#endif #endif

View File

@ -53,6 +53,8 @@ class DisplayServer : public Object {
RID _get_rid_from_name(NativeMenu *p_nmenu, const String &p_menu_root) const; RID _get_rid_from_name(NativeMenu *p_nmenu, const String &p_menu_root) const;
#endif #endif
LocalVector<ObjectID> additional_outputs;
public: public:
_FORCE_INLINE_ static DisplayServer *get_singleton() { _FORCE_INLINE_ static DisplayServer *get_singleton() {
return singleton; return singleton;
@ -582,6 +584,10 @@ public:
virtual bool is_window_transparency_available() const { return false; } 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 void register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers);
static int get_create_function_count(); static int get_create_function_count();
static const char *get_create_function_name(int p_index); static const char *get_create_function_name(int p_index);