From ca0eb5da24e4f22d4d1887a1f3b79b6434ce5eb9 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Thu, 30 Oct 2025 17:40:52 -0500 Subject: [PATCH] OpenXR: Fix resizing viewports used by `OpenXRCompositionLayer` --- drivers/gles3/storage/texture_storage.cpp | 16 ++++++++++------ .../openxr_composition_layer_extension.cpp | 2 ++ .../openxr/scene/openxr_composition_layer.cpp | 12 ++++++++++++ modules/openxr/scene/openxr_composition_layer.h | 2 ++ .../renderer_rd/storage_rd/texture_storage.cpp | 4 ++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 56bb98278e8..bd7b1db65ca 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -2933,9 +2933,11 @@ void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSA WARN_PRINT("2D MSAA is not yet supported for GLES3."); - _clear_render_target(rt); - rt->msaa = p_msaa; - _update_render_target_color(rt); + if (rt->overridden.color.is_null()) { + _clear_render_target(rt); + rt->msaa = p_msaa; + _update_render_target_color(rt); + } } RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const { @@ -2953,9 +2955,11 @@ void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_h return; } - _clear_render_target(rt); - rt->hdr = p_use_hdr_2d; - _update_render_target_color(rt); + if (rt->overridden.color.is_null()) { + _clear_render_target(rt); + rt->hdr = p_use_hdr_2d; + _update_render_target_color(rt); + } } bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const { diff --git a/modules/openxr/extensions/openxr_composition_layer_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_extension.cpp index 8c450842107..ad9bdf207b9 100644 --- a/modules/openxr/extensions/openxr_composition_layer_extension.cpp +++ b/modules/openxr/extensions/openxr_composition_layer_extension.cpp @@ -232,6 +232,8 @@ void OpenXRCompositionLayerExtension::CompositionLayer::set_viewport(RID p_viewp free_swapchain(); subviewport.viewport_size = Size2i(); } + } else if (subviewport.viewport_size != p_size) { + subviewport.viewport_size = p_size; } } diff --git a/modules/openxr/scene/openxr_composition_layer.cpp b/modules/openxr/scene/openxr_composition_layer.cpp index aff1b5fb71e..a6fe5ae845d 100644 --- a/modules/openxr/scene/openxr_composition_layer.cpp +++ b/modules/openxr/scene/openxr_composition_layer.cpp @@ -244,6 +244,12 @@ void OpenXRCompositionLayer::_clear_composition_layer() { } } +void OpenXRCompositionLayer::_viewport_size_changed() { + if (layer_viewport && openxr_session_running && composition_layer_extension && is_natively_supported() && is_visible() && is_inside_tree()) { + composition_layer_extension->composition_layer_set_viewport(composition_layer, layer_viewport->get_viewport_rid(), layer_viewport->get_size()); + } +} + void OpenXRCompositionLayer::_on_openxr_session_begun() { openxr_session_running = true; if (_should_register()) { @@ -298,12 +304,18 @@ void OpenXRCompositionLayer::set_layer_viewport(SubViewport *p_viewport) { ERR_FAIL_COND_MSG(p_viewport != nullptr, RTR("Cannot set SubViewport on an OpenXR composition layer when using an Android surface.")); } + if (layer_viewport) { + layer_viewport->disconnect("size_changed", callable_mp(this, &OpenXRCompositionLayer::_viewport_size_changed)); + } + layer_viewport = p_viewport; if (_should_register()) { _setup_composition_layer(); } if (layer_viewport) { + layer_viewport->connect("size_changed", callable_mp(this, &OpenXRCompositionLayer::_viewport_size_changed)); + SubViewport::UpdateMode update_mode = layer_viewport->get_update_mode(); if (update_mode == SubViewport::UPDATE_WHEN_VISIBLE || update_mode == SubViewport::UPDATE_WHEN_PARENT_VISIBLE) { WARN_PRINT_ONCE("OpenXR composition layers cannot use SubViewports with UPDATE_WHEN_VISIBLE or UPDATE_WHEN_PARENT_VISIBLE. Switching to UPDATE_ALWAYS."); diff --git a/modules/openxr/scene/openxr_composition_layer.h b/modules/openxr/scene/openxr_composition_layer.h index df3bc6abfeb..1af849a9153 100644 --- a/modules/openxr/scene/openxr_composition_layer.h +++ b/modules/openxr/scene/openxr_composition_layer.h @@ -115,6 +115,8 @@ private: void _setup_composition_layer(); void _clear_composition_layer(); + void _viewport_size_changed(); + protected: OpenXRAPI *openxr_api = nullptr; OpenXRCompositionLayerExtension *composition_layer_extension = nullptr; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index d398bf25b87..d3af44708a7 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3542,6 +3542,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) { } void TextureStorage::_update_render_target(RenderTarget *rt) { + if (rt->overridden.color.is_valid()) { + return; + } + if (rt->texture.is_null()) { //create a placeholder until updated rt->texture = texture_allocate();