godot/modules/openxr/extensions/openxr_composition_layer_extension.cpp

/**************************************************************************/
/*  openxr_composition_layer_extension.cpp                                */
/**************************************************************************/
/*                         This file is part of:                          */
/*                             GODOT ENGINE                               */
/*                        https://godotengine.org                         */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
/*                                                                        */
/* Permission is hereby granted, free of charge, to any person obtaining  */
/* a copy of this software and associated documentation files (the        */
/* "Software"), to deal in the Software without restriction, including    */
/* without limitation the rights to use, copy, modify, merge, publish,    */
/* distribute, sublicense, and/or sell copies of the Software, and to     */
/* permit persons to whom the Software is furnished to do so, subject to  */
/* the following conditions:                                              */
/*                                                                        */
/* The above copyright notice and this permission notice shall be         */
/* included in all copies or substantial portions of the Software.        */
/*                                                                        */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
/**************************************************************************/

#include "openxr_composition_layer_extension.h"

#ifdef ANDROID_ENABLED
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#endif

#include "platform/android/api/java_class_wrapper.h"
#include "servers/rendering/rendering_server_globals.h"

////////////////////////////////////////////////////////////////////////////
// OpenXRCompositionLayerExtension

OpenXRCompositionLayerExtension *OpenXRCompositionLayerExtension::singleton =;

OpenXRCompositionLayerExtension *OpenXRCompositionLayerExtension::get_singleton() {}

OpenXRCompositionLayerExtension::OpenXRCompositionLayerExtension() {}

OpenXRCompositionLayerExtension::~OpenXRCompositionLayerExtension() {}

HashMap<String, bool *> OpenXRCompositionLayerExtension::get_requested_extensions() {}

void OpenXRCompositionLayerExtension::on_instance_created(const XrInstance p_instance) {}

void OpenXRCompositionLayerExtension::on_session_created(const XrSession p_session) {}

void OpenXRCompositionLayerExtension::on_session_destroyed() {}

void OpenXRCompositionLayerExtension::on_pre_render() {}

int OpenXRCompositionLayerExtension::get_composition_layer_count() {}

XrCompositionLayerBaseHeader *OpenXRCompositionLayerExtension::get_composition_layer(int p_index) {}

int OpenXRCompositionLayerExtension::get_composition_layer_order(int p_index) {}

void OpenXRCompositionLayerExtension::register_viewport_composition_layer_provider(OpenXRViewportCompositionLayerProvider *p_composition_layer) {}

void OpenXRCompositionLayerExtension::unregister_viewport_composition_layer_provider(OpenXRViewportCompositionLayerProvider *p_composition_layer) {}

bool OpenXRCompositionLayerExtension::is_available(XrStructureType p_which) {}

#ifdef ANDROID_ENABLED
bool OpenXRCompositionLayerExtension::create_android_surface_swapchain(XrSwapchainCreateInfo *p_info, XrSwapchain *r_swapchain, jobject *r_surface) {
	if (android_surface_ext_available) {
		OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
		ERR_FAIL_NULL_V(openxr_api, false);

		XrResult result = xrCreateSwapchainAndroidSurfaceKHR(openxr_api->get_session(), p_info, r_swapchain, r_surface);
		if (XR_FAILED(result)) {
			print_line("OpenXR: Failed to create Android surface swapchain [", openxr_api->get_error_string(result), "]");
			return false;
		}

		return true;
	}

	return false;
}

void OpenXRCompositionLayerExtension::free_android_surface_swapchain(XrSwapchain p_swapchain) {
	android_surface_swapchain_free_queue.push_back(p_swapchain);
}

void OpenXRCompositionLayerExtension::free_queued_android_surface_swapchains() {
	for (XrSwapchain swapchain : android_surface_swapchain_free_queue) {
		xrDestroySwapchain(swapchain);
	}
	android_surface_swapchain_free_queue.clear();
}
#endif

////////////////////////////////////////////////////////////////////////////
// OpenXRViewportCompositionLayerProvider

OpenXRViewportCompositionLayerProvider::OpenXRViewportCompositionLayerProvider(XrCompositionLayerBaseHeader *p_composition_layer) {}

OpenXRViewportCompositionLayerProvider::~OpenXRViewportCompositionLayerProvider() {}

void OpenXRViewportCompositionLayerProvider::set_alpha_blend(bool p_alpha_blend) {}

void OpenXRViewportCompositionLayerProvider::set_viewport(RID p_viewport, Size2i p_size) {}

void OpenXRViewportCompositionLayerProvider::set_use_android_surface(bool p_use_android_surface, Size2i p_size) {}

#ifdef ANDROID_ENABLED
void OpenXRViewportCompositionLayerProvider::create_android_surface() {
	ERR_FAIL_COND(android_surface.swapchain != XR_NULL_HANDLE || android_surface.surface.is_valid());
	ERR_FAIL_COND(!openxr_api || !openxr_api->is_running());

	void *next_pointer = nullptr;
	for (OpenXRExtensionWrapper *wrapper : openxr_api->get_registered_extension_wrappers()) {
		void *np = wrapper->set_android_surface_swapchain_create_info_and_get_next_pointer(extension_property_values, next_pointer);
		if (np != nullptr) {
			next_pointer = np;
		}
	}

	// The XR_FB_android_surface_swapchain_create extension mandates that format, sampleCount,
	// faceCount, arraySize, and mipCount must be zero.
	XrSwapchainCreateInfo info = {
		XR_TYPE_SWAPCHAIN_CREATE_INFO, // type
		next_pointer, // next
		0, // createFlags
		XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, // usageFlags
		0, // format
		0, // sampleCount
		(uint32_t)swapchain_size.x, // width
		(uint32_t)swapchain_size.y, // height
		0, // faceCount
		0, // arraySize
		0, // mipCount
	};

	jobject surface;
	composition_layer_extension->create_android_surface_swapchain(&info, &android_surface.swapchain, &surface);

	if (surface) {
		android_surface.surface.instantiate(JavaClassWrapper::get_singleton()->wrap("android.view.Surface"), surface);
	}
}
#endif

Ref<JavaObject> OpenXRViewportCompositionLayerProvider::get_android_surface() {}

void OpenXRViewportCompositionLayerProvider::set_extension_property_values(const Dictionary &p_extension_property_values) {}

void OpenXRViewportCompositionLayerProvider::on_pre_render() {}

XrCompositionLayerBaseHeader *OpenXRViewportCompositionLayerProvider::get_composition_layer() {}

void OpenXRViewportCompositionLayerProvider::update_swapchain_sub_image(XrSwapchainSubImage &r_subimage) {}

bool OpenXRViewportCompositionLayerProvider::update_and_acquire_swapchain(bool p_static_image) {}

void OpenXRViewportCompositionLayerProvider::free_swapchain() {}

RID OpenXRViewportCompositionLayerProvider::get_current_swapchain_texture() {}