From a0bbca572d175fdecf201f6128e9956308d77e49 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Wed, 19 Aug 2020 14:53:25 -0500 Subject: [PATCH] comp: Basic Android compositor window. Also makes the service feature not depend on other options: it can be used without those other parts. comp/window_android: Remove unused EGL code for now, as it is crashing. comp/window_android: Use MonadoView async method to create surface. comp/window_android: Use custom surface as intended Co-authored-by: Lubosz Sarnecki --- CMakeLists.txt | 4 +- doc/changes/compositor/mr.547.md | 1 + src/xrt/compositor/CMakeLists.txt | 10 +- src/xrt/compositor/main/comp_compositor.c | 13 ++ src/xrt/compositor/main/comp_settings.h | 1 + src/xrt/compositor/main/comp_window.h | 15 ++ src/xrt/compositor/main/comp_window_android.c | 154 ++++++++++++++++++ 7 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 doc/changes/compositor/mr.547.md create mode 100644 src/xrt/compositor/main/comp_window_android.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e2b838152..35d3e830f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,9 +115,9 @@ cmake_dependent_option(XRT_HAVE_OPENGL "Enable OpenGL Graphics API support" ON " cmake_dependent_option(XRT_HAVE_OPENGLES "Enable OpenGL-ES Graphics API support" ON "OpenGLES_FOUND" OFF) cmake_dependent_option(XRT_HAVE_EGL "Enable OpenGL on EGL Graphics API support" ON "EGL_FOUND; XRT_HAVE_OPENGL OR XRT_HAVE_OPENGLES" OFF) cmake_dependent_option(XRT_HAVE_DBUS "Enable dbus support (for BLE support)" ON "DBUS_FOUND" OFF) -cmake_dependent_option(XRT_FEATURE_COMPOSITOR_MAIN "Build main compositor host functionality" ON "XRT_HAVE_VULKAN; XRT_HAVE_WAYLAND OR XRT_HAVE_XCB" OFF) +cmake_dependent_option(XRT_FEATURE_COMPOSITOR_MAIN "Build main compositor host functionality" ON "XRT_HAVE_VULKAN; XRT_HAVE_WAYLAND OR XRT_HAVE_XCB OR ANDROID" OFF) cmake_dependent_option(XRT_FEATURE_OPENXR "Build OpenXR runtime target" ON "XRT_FEATURE_COMPOSITOR_MAIN" OFF) -cmake_dependent_option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" ON "XRT_FEATURE_COMPOSITOR_MAIN AND XRT_FEATURE_OPENXR" OFF) +option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" ON) cmake_dependent_option(XRT_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_FEATURE_SERVICE" OFF) cmake_dependent_option(XRT_INSTALL_SYSTEMD_UNIT_FILES "Install user unit files for systemd socket activation on installation" ON "XRT_HAVE_SYSTEMD" OFF) cmake_dependent_option(XRT_INSTALL_ABSOLUTE_SYSTEMD_UNIT_FILES "Use an absolute path to monado-system in installed user unit files for systemd socket activation" ON "XRT_INSTALL_SYSTEMD_UNIT_FILES" OFF) diff --git a/doc/changes/compositor/mr.547.md b/doc/changes/compositor/mr.547.md new file mode 100644 index 000000000..9ccf266aa --- /dev/null +++ b/doc/changes/compositor/mr.547.md @@ -0,0 +1 @@ +Initial work on a port of the compositor to Android. diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt index 23159cd14..2c890b94b 100644 --- a/src/xrt/compositor/CMakeLists.txt +++ b/src/xrt/compositor/CMakeLists.txt @@ -139,6 +139,11 @@ if(XRT_FEATURE_COMPOSITOR_MAIN) main/comp_window_wayland.c ) endif() + if(ANDROID) + list(APPEND MAIN_SOURCE_FILES + main/comp_window_android.c + ) + endif() add_library(comp_main STATIC ${SHADER_HEADERS} ${MAIN_SOURCE_FILES} ${WL_PROTOS_SRC}) target_link_libraries(comp_main PUBLIC xrt-interfaces PRIVATE aux_util aux_os aux_vk) @@ -160,10 +165,13 @@ if(XRT_FEATURE_COMPOSITOR_MAIN) if(XRT_HAVE_XCB AND XRT_HAVE_XLIB) target_link_libraries(comp_main PRIVATE ${X11_X11_LIB}) endif() - if(XRT_HAVE_EGL) + if(XRT_HAVE_EGL AND XRT_HAVE_XCB) target_include_directories(comp_main SYSTEM PRIVATE ${EGL_INCLUDE_DIRS}) target_link_libraries(comp_main PRIVATE ${XCB_LIBRARIES}) endif() + if(ANDROID) + target_link_libraries(comp_main PRIVATE aux_ogl aux_android) + endif() add_subdirectory(shaders) endif() diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c index 802aae25e..afd58c7b1 100644 --- a/src/xrt/compositor/main/comp_compositor.c +++ b/src/xrt/compositor/main/comp_compositor.c @@ -1072,6 +1072,12 @@ compositor_init_window_pre_vulkan(struct comp_compositor *c) c->settings.window_type = WINDOW_XCB; return true; } +#endif +#ifdef XRT_OS_ANDROID + if (compositor_try_window(c, comp_window_android_create(c))) { + c->settings.window_type = WINDOW_ANDROID; + return true; + } #endif COMP_ERROR(c, "Failed to auto detect window support!"); break; @@ -1094,6 +1100,13 @@ compositor_init_window_pre_vulkan(struct comp_compositor *c) compositor_try_window(c, comp_window_direct_randr_create(c)); #else COMP_ERROR(c, "Direct mode support not compiled in!"); +#endif + break; + case WINDOW_ANDROID: +#ifdef XRT_OS_ANDROID + compositor_try_window(c, comp_window_android_create(c)); +#else + COMP_ERROR(c, "Android support not compiled in!"); #endif break; default: COMP_ERROR(c, "Unknown window type!"); break; diff --git a/src/xrt/compositor/main/comp_settings.h b/src/xrt/compositor/main/comp_settings.h index 208229de1..8a1dad62d 100644 --- a/src/xrt/compositor/main/comp_settings.h +++ b/src/xrt/compositor/main/comp_settings.h @@ -48,6 +48,7 @@ enum window_type WINDOW_WAYLAND, WINDOW_DIRECT_RANDR, WINDOW_DIRECT_NVIDIA, + WINDOW_ANDROID, }; diff --git a/src/xrt/compositor/main/comp_window.h b/src/xrt/compositor/main/comp_window.h index 550917cfd..eac0153e8 100644 --- a/src/xrt/compositor/main/comp_window.h +++ b/src/xrt/compositor/main/comp_window.h @@ -13,6 +13,8 @@ #include "main/comp_vk_swapchain.h" #include "main/comp_compositor.h" +#include "xrt/xrt_config_os.h" + #ifdef __cplusplus extern "C" { #endif @@ -100,6 +102,19 @@ comp_window_direct_nvidia_create(struct comp_compositor *c); #endif +#ifdef XRT_OS_ANDROID + +/*! + * Create a surface to an HMD on Android. + * + * @ingroup comp_main + * @public @memberof comp_window_android + */ +struct comp_window * +comp_window_android_create(struct comp_compositor *c); + +#endif // XRT_OS_ANDROID + #ifdef __cplusplus } #endif diff --git a/src/xrt/compositor/main/comp_window_android.c b/src/xrt/compositor/main/comp_window_android.c new file mode 100644 index 000000000..000db4210 --- /dev/null +++ b/src/xrt/compositor/main/comp_window_android.c @@ -0,0 +1,154 @@ +// Copyright 2019-2020, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Android window code. + * @author Ryan Pavlik + * @author Lubosz Sarnecki + * @author Jakob Bornecrantz + * @ingroup comp_main + */ + +#include +#include +#include +#include +#include +#include "xrt/xrt_compiler.h" +#include "main/comp_window.h" +#include "util/u_misc.h" +#include "android/android_globals.h" +#include "android/android_custom_surface.h" + +#include + + +/* + * + * Private structs. + * + */ + +/*! + * An Android window. + * + * @implements comp_window + */ +struct comp_window_android +{ + struct comp_window base; + struct android_custom_surface *custom_surface; +}; + +/* + * + * Functions. + * + */ + +static bool +comp_window_android_init(struct comp_window *w) +{ + struct comp_window_android *w_android = (struct comp_window_android *)w; + return true; +} +static void +comp_window_android_destroy(struct comp_window *w) +{ + struct comp_window_android *w_android = (struct comp_window_android *)w; + android_custom_surface_destroy(&w_android->custom_surface); + + free(w); +} + +static void +comp_window_android_update_window_title(struct comp_window *w, + const char *title) +{ + struct comp_window_android *w_android = (struct comp_window_android *)w; +} + +static VkResult +comp_window_android_create_surface(struct comp_window_android *w, + VkSurfaceKHR *vk_surface) +{ + struct vk_bundle *vk = w->base.swapchain.vk; + VkResult ret; + w->custom_surface = android_custom_surface_async_start( + android_globals_get_vm(), android_globals_get_activity()); + if (w->custom_surface == NULL) { + COMP_ERROR( + w->base.c, + "comp_window_android_create_surface: could not " + "start asynchronous attachment of our custom surface"); + return VK_ERROR_INITIALIZATION_FAILED; + } + struct ANativeWindow *window = + android_custom_surface_wait_get_surface(w->custom_surface, 2000); + if (window == NULL) { + COMP_ERROR(w->base.c, + "comp_window_android_create_surface: could not " + "convert surface to ANativeWindow"); + return VK_ERROR_INITIALIZATION_FAILED; + } + VkAndroidSurfaceCreateInfoKHR surface_info = { + .sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, + .flags = 0, + .window = window, + }; + + ret = vk->vkCreateAndroidSurfaceKHR(vk->instance, &surface_info, NULL, + vk_surface); + if (ret != VK_SUCCESS) { + COMP_ERROR(w->base.c, "vkCreateAndroidSurfaceKHR: %s", + vk_result_string(ret)); + return ret; + } + + return VK_SUCCESS; +} +static bool +comp_window_android_init_swapchain(struct comp_window *w, + uint32_t width, + uint32_t height) +{ + struct comp_window_android *w_android = (struct comp_window_android *)w; + VkResult ret; + + ret = comp_window_android_create_surface(w_android, + &w->swapchain.surface); + if (ret != VK_SUCCESS) { + COMP_ERROR(w->c, "Failed to create surface!"); + return false; + } + + vk_swapchain_create( + &w->swapchain, width, height, w->c->settings.color_format, + w->c->settings.color_space, w->c->settings.present_mode); + + return true; +} + + +static void +comp_window_android_flush(struct comp_window *w) +{ + struct comp_window_android *w_android = (struct comp_window_android *)w; +} + +struct comp_window * +comp_window_android_create(struct comp_compositor *c) +{ + struct comp_window_android *w = + U_TYPED_CALLOC(struct comp_window_android); + + w->base.name = "Android"; + w->base.destroy = comp_window_android_destroy; + w->base.flush = comp_window_android_flush; + w->base.init = comp_window_android_init; + w->base.init_swapchain = comp_window_android_init_swapchain; + w->base.update_window_title = comp_window_android_update_window_title; + w->base.c = c; + + return &w->base; +}