comp/main: Windows work - got a window to appear!

This commit is contained in:
Ryan Pavlik 2020-11-23 13:44:58 -06:00 committed by Jakob Bornecrantz
parent 2743790180
commit 0cb64ce5bd
6 changed files with 257 additions and 1 deletions

View file

@ -117,7 +117,7 @@ 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_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_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_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 OR ANDROID" 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 OR WIN32" OFF)
cmake_dependent_option(XRT_FEATURE_OPENXR "Build OpenXR runtime target" ON "XRT_FEATURE_COMPOSITOR_MAIN" 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 "NOT WIN32" OFF) cmake_dependent_option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" ON "NOT WIN32" OFF)
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_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_FEATURE_SERVICE" OFF)

View file

@ -112,6 +112,12 @@ if(XRT_FEATURE_COMPOSITOR_MAIN)
main/comp_window_direct_nvidia.c main/comp_window_direct_nvidia.c
) )
endif() endif()
if(WIN32)
list(APPEND MAIN_SOURCE_FILES
main/comp_window_mswin.c
)
endif()
# generate wayland protocols # generate wayland protocols
if(XRT_HAVE_WAYLAND) if(XRT_HAVE_WAYLAND)

View file

@ -694,6 +694,11 @@ static const char *instance_extensions_android[] = {
COMP_INSTANCE_EXTENSIONS_COMMON, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME}; COMP_INSTANCE_EXTENSIONS_COMMON, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME};
#endif #endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
static const char *instance_extensions_windows[] = {
COMP_INSTANCE_EXTENSIONS_COMMON, VK_KHR_WIN32_SURFACE_EXTENSION_NAME};
#endif
// Note: Keep synchronized with comp_vk_glue - we should have everything they // Note: Keep synchronized with comp_vk_glue - we should have everything they
// do, plus VK_KHR_SWAPCHAIN_EXTENSION_NAME // do, plus VK_KHR_SWAPCHAIN_EXTENSION_NAME
static const char *device_extensions[] = { static const char *device_extensions[] = {
@ -766,6 +771,12 @@ select_instances_extensions(struct comp_compositor *c,
*out_exts = instance_extensions_android; *out_exts = instance_extensions_android;
*out_num = ARRAY_SIZE(instance_extensions_android); *out_num = ARRAY_SIZE(instance_extensions_android);
break; break;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
case WINDOW_MSWIN:
*out_exts = instance_extensions_windows;
*out_num = ARRAY_SIZE(instance_extensions_windows);
break;
#endif #endif
default: return VK_ERROR_INITIALIZATION_FAILED; default: return VK_ERROR_INITIALIZATION_FAILED;
} }
@ -1138,6 +1149,12 @@ compositor_init_window_pre_vulkan(struct comp_compositor *c)
c->settings.window_type = WINDOW_ANDROID; c->settings.window_type = WINDOW_ANDROID;
return true; return true;
} }
#endif
#ifdef XRT_OS_WINDOWS
if (compositor_try_window(c, comp_window_mswin_create(c))) {
c->settings.window_type = WINDOW_MSWIN;
return true;
}
#endif #endif
COMP_ERROR(c, "Failed to auto detect window support!"); COMP_ERROR(c, "Failed to auto detect window support!");
break; break;
@ -1169,6 +1186,13 @@ compositor_init_window_pre_vulkan(struct comp_compositor *c)
COMP_ERROR(c, "Android support not compiled in!"); COMP_ERROR(c, "Android support not compiled in!");
#endif #endif
break; break;
case WINDOW_MSWIN:
#ifdef XRT_OS_WINDOWS
compositor_try_window(c, comp_window_mswin_create(c));
#else
COMP_ERROR(c, "Windows support not compiled in!");
#endif
default: COMP_ERROR(c, "Unknown window type!"); break; default: COMP_ERROR(c, "Unknown window type!"); break;
} }

View file

@ -49,6 +49,7 @@ enum window_type
WINDOW_DIRECT_RANDR, WINDOW_DIRECT_RANDR,
WINDOW_DIRECT_NVIDIA, WINDOW_DIRECT_NVIDIA,
WINDOW_ANDROID, WINDOW_ANDROID,
WINDOW_MSWIN,
}; };

View file

@ -82,6 +82,19 @@ comp_window_android_create(struct comp_compositor *c);
#endif // XRT_OS_ANDROID #endif // XRT_OS_ANDROID
#ifdef XRT_OS_WINDOWS
/*!
* Create a rendering window on Windows.
*
* @ingroup comp_main
* @public @memberof comp_window_mswin
*/
struct comp_target *
comp_window_mswin_create(struct comp_compositor *c);
#endif // XRT_OS_WINDOWS
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -0,0 +1,212 @@
// Copyright 2019-2020, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Wayland window code.
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup comp_main
*/
#include <stdlib.h>
#include <string.h>
#include "xrt/xrt_compiler.h"
#include "main/comp_window.h"
#include "util/u_misc.h"
/*
*
* Private structs.
*
*/
/*!
* A Microsoft Windows window.
*
* @implements comp_target_swapchain
*/
struct comp_window_mswin
{
struct comp_target_swapchain base;
HINSTANCE instance;
HWND window;
bool fullscreen_requested;
};
static WCHAR szWindowClass[] = L"Monado";
/*
*
* Functions.
*
*/
static LRESULT CALLBACK
WndProc(HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_PAINT: {
// paint the main window
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
EndPaint(hWnd, &ps);
} break;
case WM_DESTROY:
// Post a quit message and return.
//! @todo set quit flag
PostQuitMessage(0);
break;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
static inline struct vk_bundle *
get_vk(struct comp_window_mswin *cwm)
{
return &cwm->base.base.c->vk;
}
static void
comp_window_mswin_destroy(struct comp_target *ct)
{
struct comp_window_mswin *cwm = (struct comp_window_mswin *)ct;
comp_target_swapchain_cleanup(&cwm->base);
//! @todo
free(ct);
}
static void
comp_window_mswin_update_window_title(struct comp_target *ct, const char *title)
{
struct comp_window_mswin *cwm = (struct comp_window_mswin *)ct;
//! @todo
}
static void
comp_window_mswin_fullscreen(struct comp_window_mswin *w)
{
//! @todo
}
static VkResult
comp_window_mswin_create_surface(struct comp_window_mswin *w,
VkSurfaceKHR *vk_surface)
{
struct vk_bundle *vk = get_vk(w);
VkResult ret;
VkWin32SurfaceCreateInfoKHR surface_info = {
.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
.hinstance = w->instance,
.hwnd = w->window,
};
ret = vk->vkCreateWin32SurfaceKHR(vk->instance, &surface_info, NULL,
vk_surface);
if (ret != VK_SUCCESS) {
COMP_ERROR(w->base.base.c, "vkCreateWin32SurfaceKHR: %s",
vk_result_string(ret));
return ret;
}
return VK_SUCCESS;
}
static bool
comp_window_mswin_init_swapchain(struct comp_target *ct,
uint32_t width,
uint32_t height)
{
struct comp_window_mswin *cwm = (struct comp_window_mswin *)ct;
VkResult ret;
ret = comp_window_mswin_create_surface(cwm, &cwm->base.surface.handle);
if (ret != VK_SUCCESS) {
COMP_ERROR(ct->c, "Failed to create surface!");
return false;
}
//! @todo
return true;
}
static void
comp_window_mswin_flush(struct comp_target *ct)
{
struct comp_window_mswin *cwm = (struct comp_window_mswin *)ct;
}
static bool
comp_window_mswin_init(struct comp_target *ct)
{
struct comp_window_mswin *cwm = (struct comp_window_mswin *)ct;
cwm->instance = GetModuleHandle(NULL);
WNDCLASSEXW wcex;
U_ZERO(&wcex);
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = cwm->instance;
wcex.lpszClassName = szWindowClass;
//! @todo icon
#if 0
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SAMPLEGUI));
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_SAMPLEGUI);
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
#endif
RegisterClassExW(&wcex);
cwm->window =
CreateWindowW(szWindowClass, L"Monado (Windowed)",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT,
0, NULL, NULL, cwm->instance, NULL);
return true;
}
static void
comp_window_mswin_configure(struct comp_window_mswin *w,
int32_t width,
int32_t height)
{
if (w->base.base.c->settings.fullscreen && !w->fullscreen_requested) {
COMP_DEBUG(w->base.base.c, "Setting full screen");
comp_window_mswin_fullscreen(w);
w->fullscreen_requested = true;
}
}
struct comp_target *
comp_window_mswin_create(struct comp_compositor *c)
{
struct comp_window_mswin *w = U_TYPED_CALLOC(struct comp_window_mswin);
comp_target_swapchain_init_set_fnptrs(&w->base);
w->base.base.name = "MS Windows";
w->base.base.destroy = comp_window_mswin_destroy;
w->base.base.flush = comp_window_mswin_flush;
w->base.base.init_pre_vulkan = comp_window_mswin_init;
w->base.base.init_post_vulkan = comp_window_mswin_init_swapchain;
w->base.base.set_title = comp_window_mswin_update_window_title;
w->base.base.c = c;
return &w->base.base;
}