Browse Source

Use vectors for OpenXRAPI memory management

devloglogan 7 months ago
parent
commit
c242cef627

+ 10 - 13
modules/openxr/extensions/platform/openxr_opengl_extension.cpp

@@ -228,33 +228,32 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
 	}
 	}
 
 
 #ifdef ANDROID_ENABLED
 #ifdef ANDROID_ENABLED
-	XrSwapchainImageOpenGLESKHR *images = (XrSwapchainImageOpenGLESKHR *)memalloc(sizeof(XrSwapchainImageOpenGLESKHR) * swapchain_length);
+	LocalVector<XrSwapchainImageOpenGLESKHR> images;
 #else
 #else
-	XrSwapchainImageOpenGLKHR *images = (XrSwapchainImageOpenGLKHR *)memalloc(sizeof(XrSwapchainImageOpenGLKHR) * swapchain_length);
+	LocalVector<XrSwapchainImageOpenGLKHR> images;
 #endif
 #endif
-	ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image");
+	images.resize(swapchain_length);
 
 
-	for (uint64_t i = 0; i < swapchain_length; i++) {
 #ifdef ANDROID_ENABLED
 #ifdef ANDROID_ENABLED
-		images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
+	for (XrSwapchainImageOpenGLESKHR &image : images) {
+		image.type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
 #else
 #else
-		images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
+	for (XrSwapchainImageOpenGLKHR &image : images) {
+		image.type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
 #endif
 #endif
-		images[i].next = nullptr;
-		images[i].image = 0;
+		image.next = nullptr;
+		image.image = 0;
 	}
 	}
 
 
-	result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images);
+	result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr());
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
 		print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
-		memfree(images);
 		return false;
 		return false;
 	}
 	}
 
 
 	SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
 	SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
 	if (data == nullptr) {
 	if (data == nullptr) {
 		print_line("OpenXR: Failed to allocate memory for swapchain data");
 		print_line("OpenXR: Failed to allocate memory for swapchain data");
-		memfree(images);
 		return false;
 		return false;
 	}
 	}
 	*r_swapchain_graphics_data = data;
 	*r_swapchain_graphics_data = data;
@@ -279,8 +278,6 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
 
 
 	data->texture_rids = texture_rids;
 	data->texture_rids = texture_rids;
 
 
-	memfree(images);
-
 	return true;
 	return true;
 }
 }
 
 

+ 9 - 15
modules/openxr/extensions/platform/openxr_vulkan_extension.cpp

@@ -239,7 +239,7 @@ void OpenXRVulkanExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_s
 }
 }
 
 
 bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
 bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
-	XrSwapchainImageVulkanKHR *images = nullptr;
+	LocalVector<XrSwapchainImageVulkanKHR> images;
 
 
 	RenderingServer *rendering_server = RenderingServer::get_singleton();
 	RenderingServer *rendering_server = RenderingServer::get_singleton();
 	ERR_FAIL_NULL_V(rendering_server, false);
 	ERR_FAIL_NULL_V(rendering_server, false);
@@ -253,27 +253,23 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
 		return false;
 		return false;
 	}
 	}
 
 
-	images = (XrSwapchainImageVulkanKHR *)memalloc(sizeof(XrSwapchainImageVulkanKHR) * swapchain_length);
-	ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image");
+	images.resize(swapchain_length);
 
 
-	for (uint64_t i = 0; i < swapchain_length; i++) {
-		images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
-		images[i].next = nullptr;
-		images[i].image = VK_NULL_HANDLE;
+	for (XrSwapchainImageVulkanKHR &image : images) {
+		image.type = XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR;
+		image.next = nullptr;
+		image.image = VK_NULL_HANDLE;
 	}
 	}
 
 
-	result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images);
+	result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr());
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
 		print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
-		memfree(images);
 		return false;
 		return false;
 	}
 	}
 
 
-	// SwapchainGraphicsData *data = (SwapchainGraphicsData *)memalloc(sizeof(SwapchainGraphicsData));
 	SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
 	SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
 	if (data == nullptr) {
 	if (data == nullptr) {
 		print_line("OpenXR: Failed to allocate memory for swapchain data");
 		print_line("OpenXR: Failed to allocate memory for swapchain data");
-		memfree(images);
 		return false;
 		return false;
 	}
 	}
 	*r_swapchain_graphics_data = data;
 	*r_swapchain_graphics_data = data;
@@ -357,13 +353,13 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
 	Vector<RID> texture_rids;
 	Vector<RID> texture_rids;
 
 
 	// create Godot texture objects for each entry in our swapchain
 	// create Godot texture objects for each entry in our swapchain
-	for (uint64_t i = 0; i < swapchain_length; i++) {
+	for (const XrSwapchainImageVulkanKHR &swapchain_image : images) {
 		RID image_rid = rendering_device->texture_create_from_extension(
 		RID image_rid = rendering_device->texture_create_from_extension(
 				p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
 				p_array_size == 1 ? RenderingDevice::TEXTURE_TYPE_2D : RenderingDevice::TEXTURE_TYPE_2D_ARRAY,
 				format,
 				format,
 				samples,
 				samples,
 				usage_flags,
 				usage_flags,
-				(uint64_t)images[i].image,
+				(uint64_t)swapchain_image.image,
 				p_width,
 				p_width,
 				p_height,
 				p_height,
 				1,
 				1,
@@ -374,8 +370,6 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
 
 
 	data->texture_rids = texture_rids;
 	data->texture_rids = texture_rids;
 
 
-	memfree(images);
-
 	return true;
 	return true;
 }
 }
 
 

+ 110 - 210
modules/openxr/openxr_api.cpp

@@ -358,27 +358,27 @@ void OpenXRAPI::insert_debug_label(const String &p_label_name) {
 
 
 bool OpenXRAPI::load_layer_properties() {
 bool OpenXRAPI::load_layer_properties() {
 	// This queries additional layers that are available and can be initialized when we create our OpenXR instance
 	// This queries additional layers that are available and can be initialized when we create our OpenXR instance
-	if (layer_properties != nullptr) {
+	if (!layer_properties.is_empty()) {
 		// already retrieved this
 		// already retrieved this
 		return true;
 		return true;
 	}
 	}
 
 
 	// Note, instance is not yet setup so we can't use get_error_string to retrieve our error
 	// Note, instance is not yet setup so we can't use get_error_string to retrieve our error
+	uint32_t num_layer_properties = 0;
 	XrResult result = xrEnumerateApiLayerProperties(0, &num_layer_properties, nullptr);
 	XrResult result = xrEnumerateApiLayerProperties(0, &num_layer_properties, nullptr);
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of api layer properties");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of api layer properties");
 
 
-	layer_properties = (XrApiLayerProperties *)memalloc(sizeof(XrApiLayerProperties) * num_layer_properties);
-	ERR_FAIL_NULL_V(layer_properties, false);
-	for (uint32_t i = 0; i < num_layer_properties; i++) {
-		layer_properties[i].type = XR_TYPE_API_LAYER_PROPERTIES;
-		layer_properties[i].next = nullptr;
+	layer_properties.resize(num_layer_properties);
+	for (XrApiLayerProperties &layer : layer_properties) {
+		layer.type = XR_TYPE_API_LAYER_PROPERTIES;
+		layer.next = nullptr;
 	}
 	}
 
 
-	result = xrEnumerateApiLayerProperties(num_layer_properties, &num_layer_properties, layer_properties);
+	result = xrEnumerateApiLayerProperties(num_layer_properties, &num_layer_properties, layer_properties.ptr());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate api layer properties");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate api layer properties");
 
 
-	for (uint32_t i = 0; i < num_layer_properties; i++) {
-		print_verbose(String("OpenXR: Found OpenXR layer ") + layer_properties[i].layerName);
+	for (const XrApiLayerProperties &layer : layer_properties) {
+		print_verbose(vformat("OpenXR: Found OpenXR layer %s.", layer.layerName));
 	}
 	}
 
 
 	return true;
 	return true;
@@ -387,36 +387,36 @@ bool OpenXRAPI::load_layer_properties() {
 bool OpenXRAPI::load_supported_extensions() {
 bool OpenXRAPI::load_supported_extensions() {
 	// This queries supported extensions that are available and can be initialized when we create our OpenXR instance
 	// This queries supported extensions that are available and can be initialized when we create our OpenXR instance
 
 
-	if (supported_extensions != nullptr) {
+	if (!supported_extensions.is_empty()) {
 		// already retrieved this
 		// already retrieved this
 		return true;
 		return true;
 	}
 	}
 
 
 	// Note, instance is not yet setup so we can't use get_error_string to retrieve our error
 	// Note, instance is not yet setup so we can't use get_error_string to retrieve our error
+	uint32_t num_supported_extensions = 0;
 	XrResult result = xrEnumerateInstanceExtensionProperties(nullptr, 0, &num_supported_extensions, nullptr);
 	XrResult result = xrEnumerateInstanceExtensionProperties(nullptr, 0, &num_supported_extensions, nullptr);
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of extension properties");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of extension properties");
 
 
-	supported_extensions = (XrExtensionProperties *)memalloc(sizeof(XrExtensionProperties) * num_supported_extensions);
-	ERR_FAIL_NULL_V(supported_extensions, false);
+	supported_extensions.resize(num_supported_extensions);
 
 
 	// set our types
 	// set our types
-	for (uint32_t i = 0; i < num_supported_extensions; i++) {
-		supported_extensions[i].type = XR_TYPE_EXTENSION_PROPERTIES;
-		supported_extensions[i].next = nullptr;
+	for (XrExtensionProperties &extension : supported_extensions) {
+		extension.type = XR_TYPE_EXTENSION_PROPERTIES;
+		extension.next = nullptr;
 	}
 	}
-	result = xrEnumerateInstanceExtensionProperties(nullptr, num_supported_extensions, &num_supported_extensions, supported_extensions);
+	result = xrEnumerateInstanceExtensionProperties(nullptr, num_supported_extensions, &num_supported_extensions, supported_extensions.ptr());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate extension properties");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate extension properties");
 
 
-	for (uint32_t i = 0; i < num_supported_extensions; i++) {
-		print_verbose(String("OpenXR: Found OpenXR extension ") + supported_extensions[i].extensionName);
+	for (const XrExtensionProperties &extension : supported_extensions) {
+		print_verbose(vformat("OpenXR: Found OpenXR extension %s.", extension.extensionName));
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
 bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
 bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
-	for (uint32_t i = 0; i < num_supported_extensions; i++) {
-		if (supported_extensions[i].extensionName == p_extension) {
+	for (const XrExtensionProperties &extension : supported_extensions) {
+		if (extension.extensionName == p_extension) {
 			return true;
 			return true;
 		}
 		}
 	}
 	}
@@ -712,32 +712,28 @@ bool OpenXRAPI::load_supported_view_configuration_types() {
 
 
 	ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
 	ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
 
 
-	if (supported_view_configuration_types != nullptr) {
-		// free previous results
-		memfree(supported_view_configuration_types);
-		supported_view_configuration_types = nullptr;
-	}
+	supported_view_configuration_types.clear();
 
 
+	uint32_t num_view_configuration_types = 0;
 	XrResult result = xrEnumerateViewConfigurations(instance, system_id, 0, &num_view_configuration_types, nullptr);
 	XrResult result = xrEnumerateViewConfigurations(instance, system_id, 0, &num_view_configuration_types, nullptr);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
 		print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
 		return false;
 		return false;
 	}
 	}
 
 
-	supported_view_configuration_types = (XrViewConfigurationType *)memalloc(sizeof(XrViewConfigurationType) * num_view_configuration_types);
-	ERR_FAIL_NULL_V(supported_view_configuration_types, false);
+	supported_view_configuration_types.resize(num_view_configuration_types);
 
 
-	result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types);
+	result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types.ptr());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
 	ERR_FAIL_COND_V_MSG(num_view_configuration_types == 0, false, "OpenXR: Failed to enumerateview configurations"); // JIC there should be at least 1!
 	ERR_FAIL_COND_V_MSG(num_view_configuration_types == 0, false, "OpenXR: Failed to enumerateview configurations"); // JIC there should be at least 1!
 
 
-	for (uint32_t i = 0; i < num_view_configuration_types; i++) {
-		print_verbose(String("OpenXR: Found supported view configuration ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
+	for (const XrViewConfigurationType &view_configuration_type : supported_view_configuration_types) {
+		print_verbose(vformat("OpenXR: Found supported view configuration %s.", OpenXRUtil::get_view_configuration_name(view_configuration_type)));
 	}
 	}
 
 
 	// Check value we loaded at startup...
 	// Check value we loaded at startup...
 	if (!is_view_configuration_supported(view_configuration)) {
 	if (!is_view_configuration_supported(view_configuration)) {
-		print_verbose(String("OpenXR: ") + OpenXRUtil::get_view_configuration_name(view_configuration) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[0]));
+		print_verbose(vformat("OpenXR: %s isn't supported, defaulting to %s.", OpenXRUtil::get_view_configuration_name(view_configuration), OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[0])));
 
 
 		view_configuration = supported_view_configuration_types[0];
 		view_configuration = supported_view_configuration_types[0];
 	}
 	}
@@ -750,43 +746,30 @@ bool OpenXRAPI::load_supported_environmental_blend_modes() {
 
 
 	ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
 	ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
 
 
-	if (supported_environment_blend_modes != nullptr) {
-		// free previous results
-		memfree(supported_environment_blend_modes);
-		supported_environment_blend_modes = nullptr;
-		num_supported_environment_blend_modes = 0;
-	}
+	supported_environment_blend_modes.clear();
 
 
+	uint32_t num_supported_environment_blend_modes = 0;
 	XrResult result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, 0, &num_supported_environment_blend_modes, nullptr);
 	XrResult result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, 0, &num_supported_environment_blend_modes, nullptr);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get supported environmental blend mode count [", get_error_string(result), "]");
 		print_line("OpenXR: Failed to get supported environmental blend mode count [", get_error_string(result), "]");
 		return false;
 		return false;
 	}
 	}
 
 
-	supported_environment_blend_modes = (XrEnvironmentBlendMode *)memalloc(sizeof(XrEnvironmentBlendMode) * num_supported_environment_blend_modes);
-	ERR_FAIL_NULL_V(supported_environment_blend_modes, false);
+	supported_environment_blend_modes.resize(num_supported_environment_blend_modes);
 
 
-	result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, num_supported_environment_blend_modes, &num_supported_environment_blend_modes, supported_environment_blend_modes);
+	result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, num_supported_environment_blend_modes, &num_supported_environment_blend_modes, supported_environment_blend_modes.ptrw());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate environmental blend modes");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate environmental blend modes");
 	ERR_FAIL_COND_V_MSG(num_supported_environment_blend_modes == 0, false, "OpenXR: Failed to enumerate environmental blend modes"); // JIC there should be at least 1!
 	ERR_FAIL_COND_V_MSG(num_supported_environment_blend_modes == 0, false, "OpenXR: Failed to enumerate environmental blend modes"); // JIC there should be at least 1!
 
 
-	for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
-		print_verbose(String("OpenXR: Found environmental blend mode ") + OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_modes[i]));
+	for (const XrEnvironmentBlendMode &supported_environment_blend_mode : supported_environment_blend_modes) {
+		print_verbose(vformat("OpenXR: Found environmental blend mode %s.", OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_mode)));
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
 bool OpenXRAPI::is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const {
 bool OpenXRAPI::is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const {
-	ERR_FAIL_NULL_V(supported_view_configuration_types, false);
-
-	for (uint32_t i = 0; i < num_view_configuration_types; i++) {
-		if (supported_view_configuration_types[i] == p_configuration_type) {
-			return true;
-		}
-	}
-
-	return false;
+	return supported_view_configuration_types.has(p_configuration_type);
 }
 }
 
 
 bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type) {
 bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type) {
@@ -798,58 +781,45 @@ bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType
 		return false;
 		return false;
 	}
 	}
 
 
-	if (view_configuration_views != nullptr) {
+	if (!view_configuration_views.is_empty()) {
 		// free previous results
 		// free previous results
-		memfree(view_configuration_views);
-		view_configuration_views = nullptr;
+		view_configuration_views.clear();
 	}
 	}
 
 
+	uint32_t view_count = 0;
 	XrResult result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, 0, &view_count, nullptr);
 	XrResult result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, 0, &view_count, nullptr);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
 		print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
 		return false;
 		return false;
 	}
 	}
 
 
-	view_configuration_views = (XrViewConfigurationView *)memalloc(sizeof(XrViewConfigurationView) * view_count);
-	ERR_FAIL_NULL_V(view_configuration_views, false);
+	view_configuration_views.resize(view_count);
 
 
-	for (uint32_t i = 0; i < view_count; i++) {
-		view_configuration_views[i].type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
-		view_configuration_views[i].next = nullptr;
+	for (XrViewConfigurationView &view_configuration_view : view_configuration_views) {
+		view_configuration_view.type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
+		view_configuration_view.next = nullptr;
 	}
 	}
 
 
-	result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, view_count, &view_count, view_configuration_views);
+	result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, view_count, &view_count, view_configuration_views.ptr());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate view configurations");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate view configurations");
 
 
-	for (uint32_t i = 0; i < view_count; i++) {
+	for (const XrViewConfigurationView &view_configuration_view : view_configuration_views) {
 		print_verbose("OpenXR: Found supported view configuration view");
 		print_verbose("OpenXR: Found supported view configuration view");
-		print_verbose(String(" - width: ") + itos(view_configuration_views[i].maxImageRectWidth));
-		print_verbose(String(" - height: ") + itos(view_configuration_views[i].maxImageRectHeight));
-		print_verbose(String(" - sample count: ") + itos(view_configuration_views[i].maxSwapchainSampleCount));
-		print_verbose(String(" - recommended render width: ") + itos(view_configuration_views[i].recommendedImageRectWidth));
-		print_verbose(String(" - recommended render height: ") + itos(view_configuration_views[i].recommendedImageRectHeight));
-		print_verbose(String(" - recommended render sample count: ") + itos(view_configuration_views[i].recommendedSwapchainSampleCount));
+		print_verbose(String(" - width: ") + itos(view_configuration_view.maxImageRectWidth));
+		print_verbose(String(" - height: ") + itos(view_configuration_view.maxImageRectHeight));
+		print_verbose(String(" - sample count: ") + itos(view_configuration_view.maxSwapchainSampleCount));
+		print_verbose(String(" - recommended render width: ") + itos(view_configuration_view.recommendedImageRectWidth));
+		print_verbose(String(" - recommended render height: ") + itos(view_configuration_view.recommendedImageRectHeight));
+		print_verbose(String(" - recommended render sample count: ") + itos(view_configuration_view.recommendedSwapchainSampleCount));
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
 void OpenXRAPI::destroy_instance() {
 void OpenXRAPI::destroy_instance() {
-	if (view_configuration_views != nullptr) {
-		memfree(view_configuration_views);
-		view_configuration_views = nullptr;
-	}
-
-	if (supported_view_configuration_types != nullptr) {
-		memfree(supported_view_configuration_types);
-		supported_view_configuration_types = nullptr;
-	}
-
-	if (supported_environment_blend_modes != nullptr) {
-		memfree(supported_environment_blend_modes);
-		supported_environment_blend_modes = nullptr;
-		num_supported_environment_blend_modes = 0;
-	}
+	view_configuration_views.clear();
+	supported_view_configuration_types.clear();
+	supported_environment_blend_modes.clear();
 
 
 	if (instance != XR_NULL_HANDLE) {
 	if (instance != XR_NULL_HANDLE) {
 		for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 		for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
@@ -916,42 +886,30 @@ bool OpenXRAPI::load_supported_reference_spaces() {
 
 
 	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
 	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
 
 
-	if (supported_reference_spaces != nullptr) {
-		// free previous results
-		memfree(supported_reference_spaces);
-		supported_reference_spaces = nullptr;
-	}
+	supported_reference_spaces.clear();
 
 
+	uint32_t num_reference_spaces = 0;
 	XrResult result = xrEnumerateReferenceSpaces(session, 0, &num_reference_spaces, nullptr);
 	XrResult result = xrEnumerateReferenceSpaces(session, 0, &num_reference_spaces, nullptr);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get reference space count [", get_error_string(result), "]");
 		print_line("OpenXR: Failed to get reference space count [", get_error_string(result), "]");
 		return false;
 		return false;
 	}
 	}
 
 
-	supported_reference_spaces = (XrReferenceSpaceType *)memalloc(sizeof(XrReferenceSpaceType) * num_reference_spaces);
-	ERR_FAIL_NULL_V(supported_reference_spaces, false);
+	supported_reference_spaces.resize(num_reference_spaces);
 
 
-	result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces);
+	result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces.ptr());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
 	ERR_FAIL_COND_V_MSG(num_reference_spaces == 0, false, "OpenXR: Failed to enumerate reference spaces");
 	ERR_FAIL_COND_V_MSG(num_reference_spaces == 0, false, "OpenXR: Failed to enumerate reference spaces");
 
 
-	for (uint32_t i = 0; i < num_reference_spaces; i++) {
-		print_verbose(String("OpenXR: Found supported reference space ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
+	for (const XrReferenceSpaceType &supported_reference_space : supported_reference_spaces) {
+		print_verbose(vformat("OpenXR: Found supported reference space %s.", OpenXRUtil::get_reference_space_name(supported_reference_space)));
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
 bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_space) {
 bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_space) {
-	ERR_FAIL_NULL_V(supported_reference_spaces, false);
-
-	for (uint32_t i = 0; i < num_reference_spaces; i++) {
-		if (supported_reference_spaces[i] == p_reference_space) {
-			return true;
-		}
-	}
-
-	return false;
+	return supported_reference_spaces.has(p_reference_space);
 }
 }
 
 
 bool OpenXRAPI::setup_play_space() {
 bool OpenXRAPI::setup_play_space() {
@@ -1145,41 +1103,29 @@ bool OpenXRAPI::reset_emulated_floor_height() {
 bool OpenXRAPI::load_supported_swapchain_formats() {
 bool OpenXRAPI::load_supported_swapchain_formats() {
 	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
 	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
 
 
-	if (supported_swapchain_formats != nullptr) {
-		// free previous results
-		memfree(supported_swapchain_formats);
-		supported_swapchain_formats = nullptr;
-	}
+	supported_swapchain_formats.clear();
 
 
+	uint32_t num_swapchain_formats = 0;
 	XrResult result = xrEnumerateSwapchainFormats(session, 0, &num_swapchain_formats, nullptr);
 	XrResult result = xrEnumerateSwapchainFormats(session, 0, &num_swapchain_formats, nullptr);
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Failed to get swapchain format count [", get_error_string(result), "]");
 		print_line("OpenXR: Failed to get swapchain format count [", get_error_string(result), "]");
 		return false;
 		return false;
 	}
 	}
 
 
-	supported_swapchain_formats = (int64_t *)memalloc(sizeof(int64_t) * num_swapchain_formats);
-	ERR_FAIL_NULL_V(supported_swapchain_formats, false);
+	supported_swapchain_formats.resize(num_swapchain_formats);
 
 
-	result = xrEnumerateSwapchainFormats(session, num_swapchain_formats, &num_swapchain_formats, supported_swapchain_formats);
+	result = xrEnumerateSwapchainFormats(session, num_swapchain_formats, &num_swapchain_formats, supported_swapchain_formats.ptrw());
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate swapchain formats");
 	ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate swapchain formats");
 
 
-	for (uint32_t i = 0; i < num_swapchain_formats; i++) {
-		print_verbose(String("OpenXR: Found supported swapchain format ") + get_swapchain_format_name(supported_swapchain_formats[i]));
+	for (int64_t swapchain_format : supported_swapchain_formats) {
+		print_verbose(String("OpenXR: Found supported swapchain format ") + get_swapchain_format_name(swapchain_format));
 	}
 	}
 
 
 	return true;
 	return true;
 }
 }
 
 
 bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) {
 bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) {
-	ERR_FAIL_NULL_V(supported_swapchain_formats, false);
-
-	for (uint32_t i = 0; i < num_swapchain_formats; i++) {
-		if (supported_swapchain_formats[i] == p_swapchain_format) {
-			return true;
-		}
-	}
-
-	return false;
+	return supported_swapchain_formats.has(p_swapchain_format);
 }
 }
 
 
 bool OpenXRAPI::obtain_swapchain_formats() {
 bool OpenXRAPI::obtain_swapchain_formats() {
@@ -1252,7 +1198,7 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
 
 
 	// We start with our color swapchain...
 	// We start with our color swapchain...
 	if (color_swapchain_format != 0) {
 	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)) {
+		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_configuration_views.size())) {
 			return false;
 			return false;
 		}
 		}
 
 
@@ -1264,7 +1210,7 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
 	// - we support our depth layer extension
 	// - we support our depth layer extension
 	// - we have our spacewarp extension (not yet implemented)
 	// - we have our spacewarp extension (not yet implemented)
 	if (depth_swapchain_format != 0 && submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
 	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)) {
+		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_configuration_views.size())) {
 			return false;
 			return false;
 		}
 		}
 
 
@@ -1277,7 +1223,7 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
 		// TBD
 		// TBD
 	}
 	}
 
 
-	for (uint32_t i = 0; i < render_state.view_count; i++) {
+	for (uint32_t i = 0; i < render_state.views.size(); i++) {
 		render_state.views[i].type = XR_TYPE_VIEW;
 		render_state.views[i].type = XR_TYPE_VIEW;
 		render_state.views[i].next = nullptr;
 		render_state.views[i].next = nullptr;
 
 
@@ -1290,7 +1236,7 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
 		render_state.projection_views[i].subImage.imageRect.extent.width = render_state.main_swapchain_size.width;
 		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;
 		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) {
+		if (render_state.submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && !render_state.depth_views.is_empty()) {
 			render_state.projection_views[i].next = &render_state.depth_views[i];
 			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].type = XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR;
@@ -1332,28 +1278,14 @@ void OpenXRAPI::destroy_session() {
 		render_state.running = false;
 		render_state.running = false;
 	}
 	}
 
 
-	if (render_state.views != nullptr) {
-		memfree(render_state.views);
-		render_state.views = nullptr;
-	}
-
-	if (render_state.projection_views != nullptr) {
-		memfree(render_state.projection_views);
-		render_state.projection_views = nullptr;
-	}
-
-	if (render_state.depth_views != nullptr) {
-		memfree(render_state.depth_views);
-		render_state.depth_views = nullptr;
-	}
+	render_state.views.clear();
+	render_state.projection_views.clear();
+	render_state.depth_views.clear();
 
 
 	free_main_swapchains();
 	free_main_swapchains();
 	OpenXRSwapChainInfo::free_queued();
 	OpenXRSwapChainInfo::free_queued();
 
 
-	if (supported_swapchain_formats != nullptr) {
-		memfree(supported_swapchain_formats);
-		supported_swapchain_formats = nullptr;
-	}
+	supported_swapchain_formats.clear();
 
 
 	// destroy our spaces
 	// destroy our spaces
 	if (play_space != XR_NULL_HANDLE) {
 	if (play_space != XR_NULL_HANDLE) {
@@ -1376,11 +1308,7 @@ void OpenXRAPI::destroy_session() {
 	local_floor_emulation.enabled = false;
 	local_floor_emulation.enabled = false;
 	local_floor_emulation.should_reset_floor_height = false;
 	local_floor_emulation.should_reset_floor_height = false;
 
 
-	if (supported_reference_spaces != nullptr) {
-		// free previous results
-		memfree(supported_reference_spaces);
-		supported_reference_spaces = nullptr;
-	}
+	supported_reference_spaces.clear();
 
 
 	if (session != XR_NULL_HANDLE) {
 	if (session != XR_NULL_HANDLE) {
 		for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
 		for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
@@ -1540,7 +1468,7 @@ void OpenXRAPI::set_form_factor(XrFormFactor p_form_factor) {
 }
 }
 
 
 uint32_t OpenXRAPI::get_view_count() {
 uint32_t OpenXRAPI::get_view_count() {
-	return view_count;
+	return view_configuration_views.size();
 }
 }
 
 
 void OpenXRAPI::set_view_configuration(XrViewConfigurationType p_view_configuration) {
 void OpenXRAPI::set_view_configuration(XrViewConfigurationType p_view_configuration) {
@@ -1777,7 +1705,7 @@ bool OpenXRAPI::initialize_session() {
 		return false;
 		return false;
 	}
 	}
 
 
-	allocate_view_buffers(view_count, submit_depth_buffer);
+	allocate_view_buffers(view_configuration_views.size(), submit_depth_buffer);
 
 
 	return true;
 	return true;
 }
 }
@@ -1835,7 +1763,7 @@ XrHandTrackerEXT OpenXRAPI::get_hand_tracker(int p_hand_index) {
 
 
 Size2 OpenXRAPI::get_recommended_target_size() {
 Size2 OpenXRAPI::get_recommended_target_size() {
 	RenderingServer *rendering_server = RenderingServer::get_singleton();
 	RenderingServer *rendering_server = RenderingServer::get_singleton();
-	ERR_FAIL_NULL_V(view_configuration_views, Size2());
+	ERR_FAIL_COND_V(view_configuration_views.is_empty(), Size2());
 
 
 	Size2 target_size;
 	Size2 target_size;
 
 
@@ -1913,7 +1841,7 @@ bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) {
 	}
 	}
 
 
 	// we don't have valid view info
 	// we don't have valid view info
-	if (render_state.views == nullptr || !render_state.view_pose_valid) {
+	if (render_state.views.is_empty() || !render_state.view_pose_valid) {
 		return false;
 		return false;
 	}
 	}
 
 
@@ -1932,16 +1860,16 @@ bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z
 	}
 	}
 
 
 	// we don't have valid view info
 	// we don't have valid view info
-	if (render_state.views == nullptr || !render_state.view_pose_valid) {
+	if (render_state.views.is_empty() || !render_state.view_pose_valid) {
 		return false;
 		return false;
 	}
 	}
 
 
 	// if we're using depth views, make sure we update our near and far there...
 	// if we're using depth views, make sure we update our near and far there...
-	if (render_state.depth_views != nullptr) {
-		for (uint32_t i = 0; i < render_state.view_count; i++) {
+	if (!render_state.depth_views.is_empty()) {
+		for (XrCompositionLayerDepthInfoKHR &depth_view : render_state.depth_views) {
 			// As we are using reverse-Z these need to be flipped.
 			// As we are using reverse-Z these need to be flipped.
-			render_state.depth_views[i].nearZ = p_z_far;
-			render_state.depth_views[i].farZ = p_z_near;
+			depth_view.nearZ = p_z_far;
+			depth_view.farZ = p_z_near;
 		}
 		}
 	}
 	}
 
 
@@ -1965,7 +1893,7 @@ Vector2 OpenXRAPI::get_eye_focus(uint32_t p_view, float p_aspect) {
 	}
 	}
 
 
 	// we don't have valid view info
 	// we don't have valid view info
-	if (render_state.views == nullptr || !render_state.view_pose_valid) {
+	if (render_state.views.is_empty() || !render_state.view_pose_valid) {
 		return Vector2();
 		return Vector2();
 	}
 	}
 
 
@@ -2111,22 +2039,14 @@ void OpenXRAPI::_allocate_view_buffers(uint32_t p_view_count, bool p_submit_dept
 	OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
 	OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
 	ERR_FAIL_NULL(openxr_api);
 	ERR_FAIL_NULL(openxr_api);
 
 
-	openxr_api->render_state.view_count = p_view_count;
 	openxr_api->render_state.submit_depth_buffer = p_submit_depth_buffer;
 	openxr_api->render_state.submit_depth_buffer = p_submit_depth_buffer;
 
 
 	// Allocate buffers we'll be populating with view information.
 	// Allocate buffers we'll be populating with view information.
-	openxr_api->render_state.views = (XrView *)memalloc(sizeof(XrView) * p_view_count);
-	ERR_FAIL_NULL_MSG(openxr_api->render_state.views, "OpenXR Couldn't allocate memory for views");
-	memset(openxr_api->render_state.views, 0, sizeof(XrView) * p_view_count);
-
-	openxr_api->render_state.projection_views = (XrCompositionLayerProjectionView *)memalloc(sizeof(XrCompositionLayerProjectionView) * p_view_count);
-	ERR_FAIL_NULL_MSG(openxr_api->render_state.projection_views, "OpenXR Couldn't allocate memory for projection views");
-	memset(openxr_api->render_state.projection_views, 0, sizeof(XrCompositionLayerProjectionView) * p_view_count);
+	openxr_api->render_state.views.resize(p_view_count);
+	openxr_api->render_state.projection_views.resize(p_view_count);
 
 
 	if (p_submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
 	if (p_submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
-		openxr_api->render_state.depth_views = (XrCompositionLayerDepthInfoKHR *)memalloc(sizeof(XrCompositionLayerDepthInfoKHR) * p_view_count);
-		ERR_FAIL_NULL_MSG(openxr_api->render_state.depth_views, "OpenXR Couldn't allocate memory for depth views");
-		memset(openxr_api->render_state.depth_views, 0, sizeof(XrCompositionLayerDepthInfoKHR) * p_view_count);
+		openxr_api->render_state.depth_views.resize(p_view_count);
 	}
 	}
 }
 }
 
 
@@ -2293,7 +2213,7 @@ void OpenXRAPI::pre_render() {
 		0 // viewStateFlags
 		0 // viewStateFlags
 	};
 	};
 	uint32_t view_count_output;
 	uint32_t view_count_output;
-	XrResult result = xrLocateViews(session, &view_locate_info, &view_state, render_state.view_count, &view_count_output, render_state.views);
+	XrResult result = xrLocateViews(session, &view_locate_info, &view_state, render_state.views.size(), &view_count_output, render_state.views.ptr());
 	if (XR_FAILED(result)) {
 	if (XR_FAILED(result)) {
 		print_line("OpenXR: Couldn't locate views [", get_error_string(result), "]");
 		print_line("OpenXR: Couldn't locate views [", get_error_string(result), "]");
 		return;
 		return;
@@ -2448,18 +2368,18 @@ void OpenXRAPI::end_frame() {
 
 
 	Rect2i new_render_region = (render_state.render_region != Rect2i()) ? render_state.render_region : Rect2i(Point2i(0, 0), render_state.main_swapchain_size);
 	Rect2i new_render_region = (render_state.render_region != Rect2i()) ? render_state.render_region : Rect2i(Point2i(0, 0), render_state.main_swapchain_size);
 
 
-	for (uint32_t i = 0; i < render_state.view_count; i++) {
-		render_state.projection_views[i].subImage.imageRect.offset.x = new_render_region.position.x;
-		render_state.projection_views[i].subImage.imageRect.offset.y = new_render_region.position.y;
-		render_state.projection_views[i].subImage.imageRect.extent.width = new_render_region.size.width;
-		render_state.projection_views[i].subImage.imageRect.extent.height = new_render_region.size.height;
-	}
-	if (render_state.submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && render_state.depth_views) {
-		for (uint32_t i = 0; i < render_state.view_count; i++) {
-			render_state.depth_views[i].subImage.imageRect.offset.x = new_render_region.position.x;
-			render_state.depth_views[i].subImage.imageRect.offset.y = new_render_region.position.y;
-			render_state.depth_views[i].subImage.imageRect.extent.width = new_render_region.size.width;
-			render_state.depth_views[i].subImage.imageRect.extent.height = new_render_region.size.height;
+	for (XrCompositionLayerProjectionView &projection_view : render_state.projection_views) {
+		projection_view.subImage.imageRect.offset.x = new_render_region.position.x;
+		projection_view.subImage.imageRect.offset.y = new_render_region.position.y;
+		projection_view.subImage.imageRect.extent.width = new_render_region.size.width;
+		projection_view.subImage.imageRect.extent.height = new_render_region.size.height;
+	}
+	if (render_state.submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && !render_state.depth_views.is_empty()) {
+		for (XrCompositionLayerDepthInfoKHR &depth_view : render_state.depth_views) {
+			depth_view.subImage.imageRect.offset.x = new_render_region.position.x;
+			depth_view.subImage.imageRect.offset.y = new_render_region.position.y;
+			depth_view.subImage.imageRect.extent.width = new_render_region.size.width;
+			depth_view.subImage.imageRect.extent.height = new_render_region.size.height;
 		}
 		}
 	}
 	}
 
 
@@ -2496,7 +2416,7 @@ void OpenXRAPI::end_frame() {
 		}
 		}
 	}
 	}
 
 
-	for (uint32_t eye = 0; eye < render_state.view_count; eye++) {
+	for (uint32_t eye = 0; eye < render_state.views.size(); eye++) {
 		render_state.projection_views[eye].fov = render_state.views[eye].fov;
 		render_state.projection_views[eye].fov = render_state.views[eye].fov;
 		render_state.projection_views[eye].pose = render_state.views[eye].pose;
 		render_state.projection_views[eye].pose = render_state.views[eye].pose;
 	}
 	}
@@ -2529,11 +2449,11 @@ void OpenXRAPI::end_frame() {
 
 
 	render_state.projection_layer.layerFlags = layer_flags;
 	render_state.projection_layer.layerFlags = layer_flags;
 	render_state.projection_layer.space = render_state.play_space;
 	render_state.projection_layer.space = render_state.play_space;
-	render_state.projection_layer.viewCount = render_state.view_count;
-	render_state.projection_layer.views = render_state.projection_views;
+	render_state.projection_layer.viewCount = (uint32_t)render_state.projection_views.size();
+	render_state.projection_layer.views = render_state.projection_views.ptr();
 
 
 	if (projection_views_extensions.size() > 0) {
 	if (projection_views_extensions.size() > 0) {
-		for (uint32_t v = 0; v < render_state.view_count; v++) {
+		for (uint32_t v = 0; v < render_state.projection_views.size(); v++) {
 			void *next_pointer = nullptr;
 			void *next_pointer = nullptr;
 			for (OpenXRExtensionWrapper *wrapper : projection_views_extensions) {
 			for (OpenXRExtensionWrapper *wrapper : projection_views_extensions) {
 				void *np = wrapper->set_projection_views_and_get_next_pointer(v, next_pointer);
 				void *np = wrapper->set_projection_views_and_get_next_pointer(v, next_pointer);
@@ -2685,11 +2605,7 @@ Size2 OpenXRAPI::get_play_space_bounds() const {
 }
 }
 
 
 PackedInt64Array OpenXRAPI::get_supported_swapchain_formats() {
 PackedInt64Array OpenXRAPI::get_supported_swapchain_formats() {
-	PackedInt64Array supported_swapchain_list;
-	for (uint32_t i = 0; i < num_swapchain_formats; i++) {
-		supported_swapchain_list.push_back(supported_swapchain_formats[i]);
-	}
-	return supported_swapchain_list;
+	return supported_swapchain_formats;
 }
 }
 
 
 OpenXRAPI::OpenXRAPI() {
 OpenXRAPI::OpenXRAPI() {
@@ -2773,15 +2689,8 @@ OpenXRAPI::~OpenXRAPI() {
 	}
 	}
 	composition_layer_providers.clear();
 	composition_layer_providers.clear();
 
 
-	if (supported_extensions != nullptr) {
-		memfree(supported_extensions);
-		supported_extensions = nullptr;
-	}
-
-	if (layer_properties != nullptr) {
-		memfree(layer_properties);
-		layer_properties = nullptr;
-	}
+	supported_extensions.clear();
+	layer_properties.clear();
 
 
 #ifdef ANDROID_ENABLED
 #ifdef ANDROID_ENABLED
 	if (openxr_loader_library_handle) {
 	if (openxr_loader_library_handle) {
@@ -3703,21 +3612,12 @@ void OpenXRAPI::unregister_projection_views_extension(OpenXRExtensionWrapper *p_
 	projection_views_extensions.erase(p_extension);
 	projection_views_extensions.erase(p_extension);
 }
 }
 
 
-const XrEnvironmentBlendMode *OpenXRAPI::get_supported_environment_blend_modes(uint32_t &count) {
-	count = num_supported_environment_blend_modes;
+const Vector<XrEnvironmentBlendMode> OpenXRAPI::get_supported_environment_blend_modes() {
 	return supported_environment_blend_modes;
 	return supported_environment_blend_modes;
 }
 }
 
 
 bool OpenXRAPI::is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const {
 bool OpenXRAPI::is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const {
-	ERR_FAIL_NULL_V(supported_environment_blend_modes, false);
-
-	for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
-		if (supported_environment_blend_modes[i] == p_blend_mode) {
-			return true;
-		}
-	}
-
-	return false;
+	return supported_environment_blend_modes.has(p_blend_mode);
 }
 }
 
 
 bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode) {
 bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode) {

+ 11 - 19
modules/openxr/openxr_api.h

@@ -88,12 +88,10 @@ private:
 	OpenXRInterface *xr_interface = nullptr;
 	OpenXRInterface *xr_interface = nullptr;
 
 
 	// layers
 	// layers
-	uint32_t num_layer_properties = 0;
-	XrApiLayerProperties *layer_properties = nullptr;
+	LocalVector<XrApiLayerProperties> layer_properties;
 
 
 	// extensions
 	// extensions
-	uint32_t num_supported_extensions = 0;
-	XrExtensionProperties *supported_extensions = nullptr;
+	LocalVector<XrExtensionProperties> supported_extensions;
 	Vector<CharString> enabled_extensions;
 	Vector<CharString> enabled_extensions;
 
 
 	// composition layer providers
 	// composition layer providers
@@ -103,16 +101,13 @@ private:
 	Vector<OpenXRExtensionWrapper *> projection_views_extensions;
 	Vector<OpenXRExtensionWrapper *> projection_views_extensions;
 
 
 	// view configuration
 	// view configuration
-	uint32_t num_view_configuration_types = 0;
-	XrViewConfigurationType *supported_view_configuration_types = nullptr;
+	LocalVector<XrViewConfigurationType> supported_view_configuration_types;
 
 
 	// reference spaces
 	// reference spaces
-	uint32_t num_reference_spaces = 0;
-	XrReferenceSpaceType *supported_reference_spaces = nullptr;
+	LocalVector<XrReferenceSpaceType> supported_reference_spaces;
 
 
 	// swapchains (note these are platform dependent)
 	// swapchains (note these are platform dependent)
-	uint32_t num_swapchain_formats = 0;
-	int64_t *supported_swapchain_formats = nullptr;
+	PackedInt64Array supported_swapchain_formats;
 
 
 	// system info
 	// system info
 	String runtime_name;
 	String runtime_name;
@@ -128,8 +123,7 @@ private:
 	// blend mode
 	// blend mode
 	XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
 	XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
 	XrEnvironmentBlendMode requested_environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
 	XrEnvironmentBlendMode requested_environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
-	uint32_t num_supported_environment_blend_modes = 0;
-	XrEnvironmentBlendMode *supported_environment_blend_modes = nullptr;
+	Vector<XrEnvironmentBlendMode> supported_environment_blend_modes;
 	bool emulate_environment_blend_mode_alpha_blend = false;
 	bool emulate_environment_blend_mode_alpha_blend = false;
 
 
 	// state
 	// state
@@ -148,8 +142,7 @@ private:
 	OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr;
 	OpenXRGraphicsExtensionWrapper *graphics_extension = nullptr;
 	XrSystemGraphicsProperties graphics_properties;
 	XrSystemGraphicsProperties graphics_properties;
 
 
-	uint32_t view_count = 0;
-	XrViewConfigurationView *view_configuration_views = nullptr;
+	LocalVector<XrViewConfigurationView> view_configuration_views;
 
 
 	enum OpenXRSwapChainTypes {
 	enum OpenXRSwapChainTypes {
 		OPENXR_SWAPCHAIN_COLOR,
 		OPENXR_SWAPCHAIN_COLOR,
@@ -344,10 +337,9 @@ private:
 		uint64_t frame = 0;
 		uint64_t frame = 0;
 		Rect2i render_region;
 		Rect2i render_region;
 
 
-		uint32_t view_count = 0;
-		XrView *views = nullptr;
-		XrCompositionLayerProjectionView *projection_views = nullptr;
-		XrCompositionLayerDepthInfoKHR *depth_views = nullptr; // Only used by Composition Layer Depth Extension if available
+		LocalVector<XrView> views;
+		LocalVector<XrCompositionLayerProjectionView> projection_views;
+		LocalVector<XrCompositionLayerDepthInfoKHR> depth_views; // Only used by Composition Layer Depth Extension if available
 		bool submit_depth_buffer = false; // if set to true we submit depth buffers to OpenXR if a suitable extension is enabled.
 		bool submit_depth_buffer = false; // if set to true we submit depth buffers to OpenXR if a suitable extension is enabled.
 		bool view_pose_valid = false;
 		bool view_pose_valid = false;
 
 
@@ -590,7 +582,7 @@ public:
 	void register_projection_views_extension(OpenXRExtensionWrapper *p_extension);
 	void register_projection_views_extension(OpenXRExtensionWrapper *p_extension);
 	void unregister_projection_views_extension(OpenXRExtensionWrapper *p_extension);
 	void unregister_projection_views_extension(OpenXRExtensionWrapper *p_extension);
 
 
-	const XrEnvironmentBlendMode *get_supported_environment_blend_modes(uint32_t &count);
+	const Vector<XrEnvironmentBlendMode> get_supported_environment_blend_modes();
 	bool is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const;
 	bool is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const;
 	bool set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode);
 	bool set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode);
 	XrEnvironmentBlendMode get_environment_blend_mode() const { return requested_environment_blend_mode; }
 	XrEnvironmentBlendMode get_environment_blend_mode() const { return requested_environment_blend_mode; }

+ 4 - 9
modules/openxr/openxr_interface.cpp

@@ -1274,15 +1274,10 @@ Array OpenXRInterface::get_supported_environment_blend_modes() {
 		return modes;
 		return modes;
 	}
 	}
 
 
-	uint32_t count = 0;
-	const XrEnvironmentBlendMode *env_blend_modes = openxr_api->get_supported_environment_blend_modes(count);
+	const Vector<XrEnvironmentBlendMode> env_blend_modes = openxr_api->get_supported_environment_blend_modes();
 
 
-	if (!env_blend_modes) {
-		return modes;
-	}
-
-	for (uint32_t i = 0; i < count; i++) {
-		switch (env_blend_modes[i]) {
+	for (const XrEnvironmentBlendMode &env_blend_mode : env_blend_modes) {
+		switch (env_blend_mode) {
 			case XR_ENVIRONMENT_BLEND_MODE_OPAQUE:
 			case XR_ENVIRONMENT_BLEND_MODE_OPAQUE:
 				modes.push_back(XR_ENV_BLEND_MODE_OPAQUE);
 				modes.push_back(XR_ENV_BLEND_MODE_OPAQUE);
 				break;
 				break;
@@ -1293,7 +1288,7 @@ Array OpenXRInterface::get_supported_environment_blend_modes() {
 				modes.push_back(XR_ENV_BLEND_MODE_ALPHA_BLEND);
 				modes.push_back(XR_ENV_BLEND_MODE_ALPHA_BLEND);
 				break;
 				break;
 			default:
 			default:
-				WARN_PRINT("Unsupported blend mode found: " + String::num_int64(int64_t(env_blend_modes[i])));
+				WARN_PRINT(vformat("Unsupported blend mode found: %s.", String::num_int64(int64_t(env_blend_mode))));
 		}
 		}
 	}
 	}