#include "openxr_api.h"
#include "extensions/openxr_extension_wrapper_extension.h"
#include "openxr_interface.h"
#include "openxr_util.h"
#include "core/config/engine.h"
#include "core/config/project_settings.h"
#include "core/os/memory.h"
#include "core/version.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
#endif
#include "openxr_platform_inc.h"
#ifdef VULKAN_ENABLED
#include "extensions/platform/openxr_vulkan_extension.h"
#endif
#if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
#include "extensions/platform/openxr_opengl_extension.h"
#endif
#include "extensions/openxr_composition_layer_depth_extension.h"
#include "extensions/openxr_debug_utils_extension.h"
#include "extensions/openxr_eye_gaze_interaction.h"
#include "extensions/openxr_fb_display_refresh_rate_extension.h"
#include "extensions/openxr_fb_foveation_extension.h"
#include "extensions/openxr_fb_update_swapchain_extension.h"
#include "extensions/openxr_hand_tracking_extension.h"
#ifdef ANDROID_ENABLED
#define OPENXR_LOADER_NAME …
#endif
Vector<OpenXRAPI::OpenXRSwapChainInfo> OpenXRAPI::OpenXRSwapChainInfo::free_queue;
bool OpenXRAPI::OpenXRSwapChainInfo::create(XrSwapchainCreateFlags p_create_flags, XrSwapchainUsageFlags p_usage_flags, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size) { … }
void OpenXRAPI::OpenXRSwapChainInfo::queue_free() { … }
void OpenXRAPI::OpenXRSwapChainInfo::free_queued() { … }
void OpenXRAPI::OpenXRSwapChainInfo::free() { … }
bool OpenXRAPI::OpenXRSwapChainInfo::acquire(bool &p_should_render) { … }
bool OpenXRAPI::OpenXRSwapChainInfo::release() { … }
RID OpenXRAPI::OpenXRSwapChainInfo::get_image() { … }
OpenXRAPI *OpenXRAPI::singleton = …;
Vector<OpenXRExtensionWrapper *> OpenXRAPI::registered_extension_wrappers;
bool OpenXRAPI::openxr_is_enabled(bool p_check_run_in_editor) { … }
String OpenXRAPI::get_default_action_map_resource_name() { … }
String OpenXRAPI::get_error_string(XrResult result) const { … }
String OpenXRAPI::get_swapchain_format_name(int64_t p_swapchain_format) const { … }
void OpenXRAPI::set_object_name(XrObjectType p_object_type, uint64_t p_object_handle, const String &p_object_name) { … }
void OpenXRAPI::begin_debug_label_region(const String &p_label_name) { … }
void OpenXRAPI::end_debug_label_region() { … }
void OpenXRAPI::insert_debug_label(const String &p_label_name) { … }
bool OpenXRAPI::load_layer_properties() { … }
bool OpenXRAPI::load_supported_extensions() { … }
bool OpenXRAPI::is_extension_supported(const String &p_extension) const { … }
bool OpenXRAPI::is_extension_enabled(const String &p_extension) const { … }
bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) { … }
bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) { … }
bool OpenXRAPI::interaction_profile_supports_io_path(const String &p_ip_path, const String &p_io_path) { … }
void OpenXRAPI::copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len) { … }
bool OpenXRAPI::create_instance() { … }
bool OpenXRAPI::get_system_info() { … }
bool OpenXRAPI::load_supported_view_configuration_types() { … }
bool OpenXRAPI::load_supported_environmental_blend_modes() { … }
bool OpenXRAPI::is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const { … }
bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type) { … }
void OpenXRAPI::destroy_instance() { … }
bool OpenXRAPI::create_session() { … }
bool OpenXRAPI::load_supported_reference_spaces() { … }
bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_space) { … }
bool OpenXRAPI::setup_play_space() { … }
bool OpenXRAPI::setup_view_space() { … }
bool OpenXRAPI::reset_emulated_floor_height() { … }
bool OpenXRAPI::load_supported_swapchain_formats() { … }
bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) { … }
bool OpenXRAPI::obtain_swapchain_formats() { … }
bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
ERR_NOT_ON_RENDER_THREAD_V(false);
ERR_FAIL_NULL_V(graphics_extension, false);
ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
render_state.main_swapchain_size = p_size;
uint32_t sample_count = 1;
if (color_swapchain_format != 0) {
if (!render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].create(0, XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, color_swapchain_format, render_state.main_swapchain_size.width, render_state.main_swapchain_size.height, sample_count, view_count)) {
return false;
}
set_object_name(XR_OBJECT_TYPE_SWAPCHAIN, uint64_t(render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].get_swapchain()), "Main color swapchain");
}
if (depth_swapchain_format != 0 && submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
if (!render_state.main_swapchains[OPENXR_SWAPCHAIN_DEPTH].create(0, XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, depth_swapchain_format, render_state.main_swapchain_size.width, render_state.main_swapchain_size.height, sample_count, view_count)) {
return false;
}
set_object_name(XR_OBJECT_TYPE_SWAPCHAIN, uint64_t(render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].get_swapchain()), "Main depth swapchain");
}
{
}
for (uint32_t i = 0; i < render_state.view_count; i++) {
render_state.views[i].type = XR_TYPE_VIEW;
render_state.views[i].next = nullptr;
render_state.projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
render_state.projection_views[i].next = nullptr;
render_state.projection_views[i].subImage.swapchain = render_state.main_swapchains[OPENXR_SWAPCHAIN_COLOR].get_swapchain();
render_state.projection_views[i].subImage.imageArrayIndex = i;
render_state.projection_views[i].subImage.imageRect.offset.x = 0;
render_state.projection_views[i].subImage.imageRect.offset.y = 0;
render_state.projection_views[i].subImage.imageRect.extent.width = render_state.main_swapchain_size.width;
render_state.projection_views[i].subImage.imageRect.extent.height = render_state.main_swapchain_size.height;
if (render_state.submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && render_state.depth_views) {
render_state.projection_views[i].next = &render_state.depth_views[i];
render_state.depth_views[i].type = XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR;
render_state.depth_views[i].next = nullptr;
render_state.depth_views[i].subImage.swapchain = render_state.main_swapchains[OPENXR_SWAPCHAIN_DEPTH].get_swapchain();
render_state.depth_views[i].subImage.imageArrayIndex = i;
render_state.depth_views[i].subImage.imageRect.offset.x = 0;
render_state.depth_views[i].subImage.imageRect.offset.y = 0;
render_state.depth_views[i].subImage.imageRect.extent.width = render_state.main_swapchain_size.width;
render_state.depth_views[i].subImage.imageRect.extent.height = render_state.main_swapchain_size.height;
render_state.depth_views[i].minDepth = 0.0;
render_state.depth_views[i].maxDepth = 1.0;
render_state.depth_views[i].nearZ = 100.0;
render_state.depth_views[i].farZ = 0.01;
}
};
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_main_swapchains_created();
}
return true;
};
void OpenXRAPI::destroy_session() { … }
bool OpenXRAPI::on_state_idle() { … }
bool OpenXRAPI::on_state_ready() { … }
bool OpenXRAPI::on_state_synchronized() { … }
bool OpenXRAPI::on_state_visible() { … }
bool OpenXRAPI::on_state_focused() { … }
bool OpenXRAPI::on_state_stopping() { … }
bool OpenXRAPI::on_state_loss_pending() { … }
bool OpenXRAPI::on_state_exiting() { … }
void OpenXRAPI::set_form_factor(XrFormFactor p_form_factor) { … }
uint32_t OpenXRAPI::get_view_count() { … }
void OpenXRAPI::set_view_configuration(XrViewConfigurationType p_view_configuration) { … }
bool OpenXRAPI::set_requested_reference_space(XrReferenceSpaceType p_requested_reference_space) { … }
void OpenXRAPI::set_submit_depth_buffer(bool p_submit_depth_buffer) { … }
bool OpenXRAPI::is_initialized() { … }
bool OpenXRAPI::is_running() { … }
bool OpenXRAPI::openxr_loader_init() { … }
bool OpenXRAPI::resolve_instance_openxr_symbols() { … }
XrResult OpenXRAPI::try_get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) { … }
XrResult OpenXRAPI::get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) { … }
bool OpenXRAPI::initialize(const String &p_rendering_driver) { … }
bool OpenXRAPI::initialize_session() { … }
void OpenXRAPI::finish() { … }
void OpenXRAPI::set_xr_interface(OpenXRInterface *p_xr_interface) { … }
void OpenXRAPI::register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) { … }
void OpenXRAPI::unregister_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) { … }
const Vector<OpenXRExtensionWrapper *> &OpenXRAPI::get_registered_extension_wrappers() { … }
void OpenXRAPI::register_extension_metadata() { … }
void OpenXRAPI::cleanup_extension_wrappers() { … }
XrHandTrackerEXT OpenXRAPI::get_hand_tracker(int p_hand_index) { … }
Size2 OpenXRAPI::get_recommended_target_size() { … }
XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) { … }
bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) { … }
bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix) { … }
Vector2 OpenXRAPI::get_eye_focus(uint32_t p_view, float p_aspect) { … }
bool OpenXRAPI::poll_events() { … }
void OpenXRAPI::_allocate_view_buffers(uint32_t p_view_count, bool p_submit_depth_buffer) { … }
void OpenXRAPI::_set_render_session_running(bool p_is_running) { … }
void OpenXRAPI::_set_render_display_info(XrTime p_predicted_display_time, bool p_should_render) { … }
void OpenXRAPI::_set_render_play_space(uint64_t p_play_space) { … }
void OpenXRAPI::_set_render_state_multiplier(double p_render_target_size_multiplier) { … }
bool OpenXRAPI::process() { … }
void OpenXRAPI::free_main_swapchains() { … }
void OpenXRAPI::pre_render() { … }
bool OpenXRAPI::pre_draw_viewport(RID p_render_target) { … }
XrSwapchain OpenXRAPI::get_color_swapchain() { … }
RID OpenXRAPI::get_color_texture() { … }
RID OpenXRAPI::get_depth_texture() { … }
void OpenXRAPI::post_draw_viewport(RID p_render_target) {
ERR_NOT_ON_RENDER_THREAD;
if (instance == XR_NULL_HANDLE || session == XR_NULL_HANDLE || !render_state.running || !render_state.view_pose_valid || !render_state.should_render) {
return;
}
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_post_draw_viewport(p_render_target);
}
};
void OpenXRAPI::end_frame() { … }
float OpenXRAPI::get_display_refresh_rate() const { … }
void OpenXRAPI::set_display_refresh_rate(float p_refresh_rate) { … }
Array OpenXRAPI::get_available_display_refresh_rates() const { … }
double OpenXRAPI::get_render_target_size_multiplier() const { … }
void OpenXRAPI::set_render_target_size_multiplier(double multiplier) { … }
bool OpenXRAPI::is_foveation_supported() const { … }
int OpenXRAPI::get_foveation_level() const { … }
void OpenXRAPI::set_foveation_level(int p_foveation_level) { … }
bool OpenXRAPI::get_foveation_dynamic() const { … }
void OpenXRAPI::set_foveation_dynamic(bool p_foveation_dynamic) { … }
Size2 OpenXRAPI::get_play_space_bounds() const { … }
OpenXRAPI::OpenXRAPI() { … }
OpenXRAPI::~OpenXRAPI() { … }
Transform3D OpenXRAPI::transform_from_pose(const XrPosef &p_pose) { … }
template <typename T>
XRPose::TrackingConfidence _transform_from_location(const T &p_location, Transform3D &r_transform) { … }
XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrSpaceLocation &p_location, Transform3D &r_transform) { … }
XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform) { … }
void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) { … }
bool OpenXRAPI::xr_result(XrResult result, const char *format, Array args) const { … }
RID OpenXRAPI::get_tracker_rid(XrPath p_path) { … }
RID OpenXRAPI::find_tracker(const String &p_name) { … }
RID OpenXRAPI::tracker_create(const String p_name) { … }
String OpenXRAPI::tracker_get_name(RID p_tracker) { … }
void OpenXRAPI::tracker_check_profile(RID p_tracker, XrSession p_session) { … }
void OpenXRAPI::tracker_free(RID p_tracker) { … }
RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_name, const int p_priority) { … }
String OpenXRAPI::action_set_get_name(RID p_action_set) { … }
bool OpenXRAPI::attach_action_sets(const Vector<RID> &p_action_sets) { … }
void OpenXRAPI::action_set_free(RID p_action_set) { … }
RID OpenXRAPI::get_action_rid(XrAction p_action) { … }
RID OpenXRAPI::find_action(const String &p_name) { … }
RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_trackers) { … }
String OpenXRAPI::action_get_name(RID p_action) { … }
void OpenXRAPI::action_free(RID p_action) { … }
RID OpenXRAPI::get_interaction_profile_rid(XrPath p_path) { … }
XrPath OpenXRAPI::get_interaction_profile_path(RID p_interaction_profile) { … }
RID OpenXRAPI::interaction_profile_create(const String p_name) { … }
String OpenXRAPI::interaction_profile_get_name(RID p_interaction_profile) { … }
void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) { … }
bool OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String p_path) { … }
bool OpenXRAPI::interaction_profile_suggest_bindings(RID p_interaction_profile) { … }
void OpenXRAPI::interaction_profile_free(RID p_interaction_profile) { … }
bool OpenXRAPI::sync_action_sets(const Vector<RID> p_active_sets) { … }
bool OpenXRAPI::get_action_bool(RID p_action, RID p_tracker) { … }
float OpenXRAPI::get_action_float(RID p_action, RID p_tracker) { … }
Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_tracker) { … }
XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) { … }
bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns) { … }
void OpenXRAPI::register_composition_layer_provider(OpenXRCompositionLayerProvider *provider) { … }
void OpenXRAPI::unregister_composition_layer_provider(OpenXRCompositionLayerProvider *provider) { … }
const XrEnvironmentBlendMode *OpenXRAPI::get_supported_environment_blend_modes(uint32_t &count) { … }
bool OpenXRAPI::is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const { … }
bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode) { … }
void OpenXRAPI::set_emulate_environment_blend_mode_alpha_blend(bool p_enabled) { … }
OpenXRAPI::OpenXRAlphaBlendModeSupport OpenXRAPI::is_environment_blend_mode_alpha_blend_supported() { … }