Browse Source

OpenXR: Safely set environment blend mode when rendering on a separate thread

David Snopek 4 months ago
parent
commit
13a643d78a
2 changed files with 42 additions and 21 deletions
  1. 20 9
      modules/openxr/openxr_api.cpp
  2. 22 12
      modules/openxr/openxr_api.h

+ 20 - 9
modules/openxr/openxr_api.cpp

@@ -2103,7 +2103,7 @@ bool OpenXRAPI::poll_events() {
 	}
 	}
 }
 }
 
 
-void OpenXRAPI::_allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer) {
+void OpenXRAPI::_allocate_view_buffers_rt(uint32_t p_view_count, bool p_submit_depth_buffer) {
 	// Must be called from rendering thread!
 	// Must be called from rendering thread!
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
@@ -2121,7 +2121,7 @@ void OpenXRAPI::_allocate_view_buffers(uint32_t p_view_count, bool p_submit_dept
 	}
 	}
 }
 }
 
 
-void OpenXRAPI::_set_render_session_running(bool p_is_running) {
+void OpenXRAPI::_set_render_session_running_rt(bool p_is_running) {
 	// Must be called from rendering thread!
 	// Must be called from rendering thread!
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
@@ -2130,7 +2130,7 @@ void OpenXRAPI::_set_render_session_running(bool p_is_running) {
 	openxr_api->render_state.running = p_is_running;
 	openxr_api->render_state.running = p_is_running;
 }
 }
 
 
-void OpenXRAPI::_set_render_display_info(XrTime p_predicted_display_time, bool p_should_render) {
+void OpenXRAPI::_set_render_display_info_rt(XrTime p_predicted_display_time, bool p_should_render) {
 	// Must be called from rendering thread!
 	// Must be called from rendering thread!
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
@@ -2140,7 +2140,16 @@ void OpenXRAPI::_set_render_display_info(XrTime p_predicted_display_time, bool p
 	openxr_api->render_state.should_render = p_should_render;
 	openxr_api->render_state.should_render = p_should_render;
 }
 }
 
 
-void OpenXRAPI::_set_render_play_space(uint64_t p_play_space) {
+void OpenXRAPI::_set_render_environment_blend_mode_rt(int32_t p_environment_blend_mode) {
+	// Must be called from rendering thread!
+	ERR_NOT_ON_RENDER_THREAD;
+
+	OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
+	ERR_FAIL_NULL(openxr_api);
+	openxr_api->render_state.environment_blend_mode = XrEnvironmentBlendMode(p_environment_blend_mode);
+}
+
+void OpenXRAPI::_set_render_play_space_rt(uint64_t p_play_space) {
 	// Must be called from rendering thread!
 	// Must be called from rendering thread!
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
@@ -2149,7 +2158,7 @@ void OpenXRAPI::_set_render_play_space(uint64_t p_play_space) {
 	openxr_api->render_state.play_space = XrSpace(p_play_space);
 	openxr_api->render_state.play_space = XrSpace(p_play_space);
 }
 }
 
 
-void OpenXRAPI::_set_render_state_multiplier(double p_render_target_size_multiplier) {
+void OpenXRAPI::_set_render_state_multiplier_rt(double p_render_target_size_multiplier) {
 	// Must be called from rendering thread!
 	// Must be called from rendering thread!
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
@@ -2158,7 +2167,7 @@ void OpenXRAPI::_set_render_state_multiplier(double p_render_target_size_multipl
 	openxr_api->render_state.render_target_size_multiplier = p_render_target_size_multiplier;
 	openxr_api->render_state.render_target_size_multiplier = p_render_target_size_multiplier;
 }
 }
 
 
-void OpenXRAPI::_set_render_state_render_region(const Rect2i &p_render_region) {
+void OpenXRAPI::_set_render_state_render_region_rt(const Rect2i &p_render_region) {
 	ERR_NOT_ON_RENDER_THREAD;
 	ERR_NOT_ON_RENDER_THREAD;
 
 
 	OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
 	OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
@@ -2491,7 +2500,7 @@ void OpenXRAPI::end_frame() {
 			XR_TYPE_FRAME_END_INFO, // type
 			XR_TYPE_FRAME_END_INFO, // type
 			nullptr, // next
 			nullptr, // next
 			render_state.predicted_display_time, // displayTime
 			render_state.predicted_display_time, // displayTime
-			environment_blend_mode, // environmentBlendMode
+			render_state.environment_blend_mode, // environmentBlendMode
 			0, // layerCount
 			0, // layerCount
 			nullptr // layers
 			nullptr // layers
 		};
 		};
@@ -2541,7 +2550,7 @@ void OpenXRAPI::end_frame() {
 	}
 	}
 
 
 	XrCompositionLayerFlags layer_flags = XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
 	XrCompositionLayerFlags layer_flags = XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
-	if (!projection_layer_is_first || environment_blend_mode != XR_ENVIRONMENT_BLEND_MODE_OPAQUE) {
+	if (!projection_layer_is_first || render_state.environment_blend_mode != XR_ENVIRONMENT_BLEND_MODE_OPAQUE) {
 		layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
 		layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
 	}
 	}
 
 
@@ -2586,7 +2595,7 @@ void OpenXRAPI::end_frame() {
 		XR_TYPE_FRAME_END_INFO, // type
 		XR_TYPE_FRAME_END_INFO, // type
 		frame_end_info_next_pointer, // next
 		frame_end_info_next_pointer, // next
 		render_state.predicted_display_time, // displayTime
 		render_state.predicted_display_time, // displayTime
-		environment_blend_mode, // environmentBlendMode
+		render_state.environment_blend_mode, // environmentBlendMode
 		static_cast<uint32_t>(layers_list.size()), // layerCount
 		static_cast<uint32_t>(layers_list.size()), // layerCount
 		layers_list.ptr() // layers
 		layers_list.ptr() // layers
 	};
 	};
@@ -3746,6 +3755,7 @@ bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode)
 	if (emulate_environment_blend_mode_alpha_blend && p_blend_mode == XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND) {
 	if (emulate_environment_blend_mode_alpha_blend && p_blend_mode == XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND) {
 		requested_environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND;
 		requested_environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND;
 		environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
 		environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
+		set_render_environment_blend_mode(environment_blend_mode);
 		return true;
 		return true;
 	}
 	}
 	// We allow setting this when not initialized and will check if it is supported when initializing.
 	// We allow setting this when not initialized and will check if it is supported when initializing.
@@ -3753,6 +3763,7 @@ bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode)
 	else if (!is_initialized() || is_environment_blend_mode_supported(p_blend_mode)) {
 	else if (!is_initialized() || is_environment_blend_mode_supported(p_blend_mode)) {
 		requested_environment_blend_mode = p_blend_mode;
 		requested_environment_blend_mode = p_blend_mode;
 		environment_blend_mode = p_blend_mode;
 		environment_blend_mode = p_blend_mode;
+		set_render_environment_blend_mode(environment_blend_mode);
 		return true;
 		return true;
 	}
 	}
 	return false;
 	return false;

+ 22 - 12
modules/openxr/openxr_api.h

@@ -337,6 +337,7 @@ private:
 		bool has_xr_viewport = false;
 		bool has_xr_viewport = false;
 		XrTime predicted_display_time = 0;
 		XrTime predicted_display_time = 0;
 		XrSpace play_space = XR_NULL_HANDLE;
 		XrSpace play_space = XR_NULL_HANDLE;
+		XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
 		double render_target_size_multiplier = 1.0;
 		double render_target_size_multiplier = 1.0;
 		uint64_t frame = 0;
 		uint64_t frame = 0;
 		Rect2i render_region;
 		Rect2i render_region;
@@ -363,19 +364,20 @@ private:
 		OpenXRSwapChainInfo main_swapchains[OPENXR_SWAPCHAIN_MAX];
 		OpenXRSwapChainInfo main_swapchains[OPENXR_SWAPCHAIN_MAX];
 	} render_state;
 	} render_state;
 
 
-	static void _allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer);
-	static void _set_render_session_running(bool p_is_running);
-	static void _set_render_display_info(XrTime p_predicted_display_time, bool p_should_render);
-	static void _set_render_play_space(uint64_t p_play_space);
-	static void _set_render_state_multiplier(double p_render_target_size_multiplier);
-	static void _set_render_state_render_region(const Rect2i &p_render_region);
+	static void _allocate_view_buffers_rt(uint32_t p_view_count, bool p_submit_depth_buffer);
+	static void _set_render_session_running_rt(bool p_is_running);
+	static void _set_render_display_info_rt(XrTime p_predicted_display_time, bool p_should_render);
+	static void _set_render_play_space_rt(uint64_t p_play_space);
+	static void _set_render_environment_blend_mode_rt(int32_t p_environment_blend_mode);
+	static void _set_render_state_multiplier_rt(double p_render_target_size_multiplier);
+	static void _set_render_state_render_region_rt(const Rect2i &p_render_region);
 
 
 	_FORCE_INLINE_ void allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer) {
 	_FORCE_INLINE_ void allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer) {
 		// If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
 		// If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_allocate_view_buffers).bind(p_view_count, p_submit_depth_buffer));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_allocate_view_buffers_rt).bind(p_view_count, p_submit_depth_buffer));
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_render_session_running(bool p_is_running) {
 	_FORCE_INLINE_ void set_render_session_running(bool p_is_running) {
@@ -383,7 +385,7 @@ private:
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_session_running).bind(p_is_running));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_session_running_rt).bind(p_is_running));
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_render_display_info(XrTime p_predicted_display_time, bool p_should_render) {
 	_FORCE_INLINE_ void set_render_display_info(XrTime p_predicted_display_time, bool p_should_render) {
@@ -391,7 +393,7 @@ private:
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_display_info).bind(p_predicted_display_time, p_should_render));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_display_info_rt).bind(p_predicted_display_time, p_should_render));
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_render_play_space(XrSpace p_play_space) {
 	_FORCE_INLINE_ void set_render_play_space(XrSpace p_play_space) {
@@ -399,7 +401,15 @@ private:
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_play_space).bind(uint64_t(p_play_space)));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_play_space_rt).bind(uint64_t(p_play_space)));
+	}
+
+	_FORCE_INLINE_ void set_render_environment_blend_mode(XrEnvironmentBlendMode p_mode) {
+		// If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
+		RenderingServer *rendering_server = RenderingServer::get_singleton();
+		ERR_FAIL_NULL(rendering_server);
+
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_environment_blend_mode_rt).bind((int32_t)p_mode));
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_render_state_multiplier(double p_render_target_size_multiplier) {
 	_FORCE_INLINE_ void set_render_state_multiplier(double p_render_target_size_multiplier) {
@@ -407,14 +417,14 @@ private:
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_multiplier).bind(p_render_target_size_multiplier));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_multiplier_rt).bind(p_render_target_size_multiplier));
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_render_state_render_region(const Rect2i &p_render_region) {
 	_FORCE_INLINE_ void set_render_state_render_region(const Rect2i &p_render_region) {
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		RenderingServer *rendering_server = RenderingServer::get_singleton();
 		ERR_FAIL_NULL(rendering_server);
 		ERR_FAIL_NULL(rendering_server);
 
 
-		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_render_region).bind(p_render_region));
+		rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_set_render_state_render_region_rt).bind(p_render_region));
 	}
 	}
 
 
 public:
 public: