The open source OpenXR runtime
1// Copyright 2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief OpenGL tests.
6 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
7 */
8
9
10#include "mock/mock_compositor.h"
11#include "client/comp_gl_client.h"
12
13#include "catch_amalgamated.hpp"
14#include "util/u_handles.h"
15#include "ogl/ogl_api.h"
16
17#include "xrt/xrt_config_os.h"
18#include "xrt/xrt_config_vulkan.h"
19#include "xrt/xrt_deleters.hpp"
20
21#include <SDL2/SDL.h>
22#include <SDL2/SDL_syswm.h>
23
24#if defined(XRT_OS_WINDOWS)
25#include "client/comp_gl_win32_client.h"
26#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
27#include "client/comp_gl_xlib_client.h"
28#else
29#error "not implemented"
30#endif
31
32#include <stdint.h>
33
34TEST_CASE("opengl_client_compositor", "[.][needgpu]")
35{
36 xrt_compositor_native *xcn = mock_create_native_compositor();
37 struct mock_compositor *mc = mock_compositor(&(xcn->base));
38
39 REQUIRE(SDL_Init(SDL_INIT_VIDEO) == 0);
40
41 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
42 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
43 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
44 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
45 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
46 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
47
48 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
49 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
50 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
51 auto *window = SDL_CreateWindow("Tests", 100, 100, 320, 240, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
52 REQUIRE(window);
53 SDL_SysWMinfo info{};
54 SDL_VERSION(&info.version);
55 REQUIRE(SDL_GetWindowWMInfo(window, &info));
56
57 auto context = SDL_GL_CreateContext(window);
58
59 SDL_GL_MakeCurrent(window, context);
60
61#if defined(XRT_OS_WINDOWS)
62 HDC hDC = info.info.win.hdc;
63 HGLRC hGLRC = wglGetCurrentContext();
64 struct client_gl_win32_compositor *c = client_gl_win32_compositor_create(xcn, hDC, hGLRC);
65#elif defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT)
66 Display *display = info.info.x11.display;
67 struct client_gl_xlib_compositor *c =
68 client_gl_xlib_compositor_create(xcn, display, 0, nullptr, nullptr, (GLXContext)context);
69#else
70#error "not implemented"
71#endif
72 REQUIRE(c);
73 struct xrt_compositor *xc = &c->base.base.base;
74
75 SECTION("Swapchain create and import")
76 {
77 struct Data
78 {
79 bool nativeCreateCalled = false;
80
81 bool nativeImportCalled = false;
82 } data;
83 mc->userdata = &data;
84 mc->compositor_hooks.create_swapchain =
85 [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc,
86 const struct xrt_swapchain_create_info *info, struct xrt_swapchain **out_xsc) {
87 auto *data = static_cast<Data *>(mc->userdata);
88 data->nativeCreateCalled = true;
89 return XRT_SUCCESS;
90 };
91 mc->compositor_hooks.import_swapchain =
92 [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc,
93 const struct xrt_swapchain_create_info *info, struct xrt_image_native *native_images,
94 uint32_t image_count, struct xrt_swapchain **out_xscc) {
95 auto *data = static_cast<Data *>(mc->userdata);
96 data->nativeImportCalled = true;
97 // need to release the native handles to avoid leaks
98 for (uint32_t i = 0; i < image_count; ++i) {
99 u_graphics_buffer_unref(&native_images[i].handle);
100 }
101 return XRT_SUCCESS;
102 };
103 xrt_swapchain_create_info xsci{};
104 xsci.format = GL_SRGB8_ALPHA8;
105 xsci.bits = (xrt_swapchain_usage_bits)(XRT_SWAPCHAIN_USAGE_COLOR | XRT_SWAPCHAIN_USAGE_SAMPLED);
106 xsci.sample_count = 1;
107 xsci.width = 800;
108 xsci.height = 600;
109 xsci.face_count = 1;
110 xsci.array_size = 1;
111 xsci.mip_count = 1;
112 SECTION("Swapchain Create")
113 {
114 struct xrt_swapchain *xsc = nullptr;
115 // This will fail because the mock compositor doesn't actually import, but it will get far
116 // enough to trigger our hook and update the flag.
117 xrt_comp_create_swapchain(xc, &xsci, &xsc);
118 // OpenGL should always create using the native compositor
119 CHECK_FALSE(data.nativeImportCalled);
120 CHECK(data.nativeCreateCalled);
121 xrt_swapchain_reference(&xsc, nullptr);
122 }
123 }
124
125 xrt_comp_destroy(&xc);
126 xrt_comp_native_destroy(&xcn);
127
128 SDL_GL_DeleteContext(context);
129 SDL_DestroyWindow(window);
130 SDL_Quit();
131}