The open source OpenXR runtime
at main 204 lines 7.3 kB view raw
1// Copyright 2020-2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief A mock native compositor to use when testing client compositors. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 */ 9 10#include "mock_compositor.h" 11 12#include "util/u_misc.h" 13#include "util/u_handles.h" 14 15static void 16mock_compositor_swapchain_destroy(struct xrt_swapchain *xsc) 17{ 18 struct mock_compositor_swapchain *mcsc = mock_compositor_swapchain(xsc); 19 struct mock_compositor *mc = mcsc->mc; 20 21 if (mc->swapchain_hooks.destroy) { 22 mc->swapchain_hooks.destroy(mc, mcsc); 23 } 24 for (uint32_t i = 0; i < mcsc->base.base.image_count; ++i) { 25 u_graphics_buffer_unref(&(mcsc->handles[i])); 26 } 27 free(xsc); 28} 29 30static xrt_result_t 31mock_compositor_swapchain_wait_image(struct xrt_swapchain *xsc, int64_t timeout_ns, uint32_t index) 32{ 33 struct mock_compositor_swapchain *mcsc = mock_compositor_swapchain(xsc); 34 struct mock_compositor *mc = mcsc->mc; 35 36 if (mc->swapchain_hooks.wait_image) { 37 return mc->swapchain_hooks.wait_image(mc, mcsc, timeout_ns, index); 38 } 39 mcsc->waited[index] = true; 40 return XRT_SUCCESS; 41} 42 43static xrt_result_t 44mock_compositor_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *out_index) 45{ 46 struct mock_compositor_swapchain *mcsc = mock_compositor_swapchain(xsc); 47 struct mock_compositor *mc = mcsc->mc; 48 49 if (mc->swapchain_hooks.acquire_image) { 50 return mc->swapchain_hooks.acquire_image(mc, mcsc, out_index); 51 } 52 uint32_t index = mcsc->next_to_acquire; 53 mcsc->next_to_acquire = (mcsc->next_to_acquire + 1) % mcsc->base.base.image_count; 54 mcsc->acquired[index] = true; 55 56 return XRT_SUCCESS; 57} 58 59static xrt_result_t 60mock_compositor_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index) 61{ 62 struct mock_compositor_swapchain *mcsc = mock_compositor_swapchain(xsc); 63 struct mock_compositor *mc = mcsc->mc; 64 65 if (mc->swapchain_hooks.acquire_image) { 66 return mc->swapchain_hooks.release_image(mc, mcsc, index); 67 } 68 mcsc->acquired[index] = false; 69 mcsc->waited[index] = false; 70 71 return XRT_SUCCESS; 72} 73 74 75static xrt_result_t 76mock_compositor_swapchain_create(struct xrt_compositor *xc, 77 const struct xrt_swapchain_create_info *info, 78 struct xrt_swapchain **out_xsc) 79{ 80 struct mock_compositor *mc = mock_compositor(xc); 81 // Mini implementation of get_swapchain_create_properties to avoid an actual call causing confusing traces in 82 // the mock 83 uint32_t image_count = (0 != (info->create & XRT_SWAPCHAIN_CREATE_STATIC_IMAGE)) ? 1 : 3; 84 constexpr bool use_dedicated_allocation = false; 85 86 87 struct mock_compositor_swapchain *mcsc = U_TYPED_CALLOC(struct mock_compositor_swapchain); 88 mcsc->base.base.image_count = image_count; 89 mcsc->base.base.wait_image = mock_compositor_swapchain_wait_image; 90 mcsc->base.base.acquire_image = mock_compositor_swapchain_acquire_image; 91 mcsc->base.base.release_image = mock_compositor_swapchain_release_image; 92 mcsc->base.base.destroy = mock_compositor_swapchain_destroy; 93 mcsc->base.base.reference.count = 1; 94 mcsc->mc = mc; 95 mcsc->id = mc->next_id; 96 mcsc->info = *info; 97 mc->next_id++; 98 99 *out_xsc = &mcsc->base.base; 100 if (mc->compositor_hooks.create_swapchain) { 101 return mc->compositor_hooks.create_swapchain(mc, mcsc, info, out_xsc); 102 } 103 104 for (uint32_t i = 0; i < image_count; i++) { 105 mcsc->base.images[i].handle = XRT_GRAPHICS_BUFFER_HANDLE_INVALID; 106 mcsc->base.images[i].use_dedicated_allocation = use_dedicated_allocation; 107 } 108 109 110 return XRT_SUCCESS; 111} 112 113static xrt_result_t 114mock_compositor_swapchain_import(struct xrt_compositor *xc, 115 const struct xrt_swapchain_create_info *info, 116 struct xrt_image_native *native_images, 117 uint32_t image_count, 118 struct xrt_swapchain **out_xsc) 119{ 120 struct mock_compositor *mc = mock_compositor(xc); 121 struct mock_compositor_swapchain *mcsc = U_TYPED_CALLOC(struct mock_compositor_swapchain); 122 mcsc->base.base.image_count = image_count; 123 mcsc->base.base.wait_image = mock_compositor_swapchain_wait_image; 124 mcsc->base.base.acquire_image = mock_compositor_swapchain_acquire_image; 125 mcsc->base.base.release_image = mock_compositor_swapchain_release_image; 126 mcsc->base.base.destroy = mock_compositor_swapchain_destroy; 127 mcsc->base.base.reference.count = 1; 128 mcsc->imported = true; 129 mcsc->mc = mc; 130 mcsc->id = mc->next_id; 131 mcsc->info = *info; 132 mc->next_id++; 133 134 *out_xsc = &mcsc->base.base; 135 if (mc->compositor_hooks.import_swapchain) { 136 return mc->compositor_hooks.import_swapchain(mc, mcsc, info, native_images, image_count, out_xsc); 137 } 138 139 for (uint32_t i = 0; i < image_count; i++) { 140 mcsc->handles[i] = native_images[i].handle; 141 mcsc->base.images[i] = native_images[i]; 142 } 143 144 return XRT_SUCCESS; 145} 146 147static xrt_result_t 148mock_compositor_get_swapchain_create_properties(struct xrt_compositor *xc, 149 const struct xrt_swapchain_create_info *info, 150 struct xrt_swapchain_create_properties *xsccp) 151{ 152 struct mock_compositor *mc = mock_compositor(xc); 153 154 if (mc->compositor_hooks.get_swapchain_create_properties) { 155 return mc->compositor_hooks.get_swapchain_create_properties(mc, info, xsccp); 156 } 157 // default "normal" impl 158 if (0 != (info->create & XRT_SWAPCHAIN_CREATE_STATIC_IMAGE)) { 159 xsccp->image_count = 1; 160 } else { 161 xsccp->image_count = 3; 162 } 163 return XRT_SUCCESS; 164} 165 166static void 167mock_compositor_destroy(struct xrt_compositor *xc) 168{ 169 struct mock_compositor *mc = mock_compositor(xc); 170 171 if (mc->compositor_hooks.destroy) { 172 return mc->compositor_hooks.destroy(mc); 173 } 174 free(mc); 175} 176 177struct xrt_compositor_native * 178mock_create_native_compositor() 179{ 180 struct mock_compositor *mc = U_TYPED_CALLOC(struct mock_compositor); 181 mc->base.base.get_swapchain_create_properties = mock_compositor_get_swapchain_create_properties; 182 mc->base.base.create_swapchain = mock_compositor_swapchain_create; 183 mc->base.base.import_swapchain = mock_compositor_swapchain_import; 184 // mc->base.base.create_semaphore = mock_compositor_semaphore_create; 185 // mc->base.base.begin_session = mock_compositor_begin_session; 186 // mc->base.base.end_session = mock_compositor_end_session; 187 // mc->base.base.wait_frame = mock_compositor_wait_frame; 188 // mc->base.base.begin_frame = mock_compositor_begin_frame; 189 // mc->base.base.discard_frame = mock_compositor_discard_frame; 190 // mc->base.base.layer_begin = mock_compositor_layer_begin; 191 // mc->base.base.layer_projection = mock_compositor_layer_projection; 192 // mc->base.base.layer_projection_depth = mock_compositor_layer_projection_depth; 193 // mc->base.base.layer_quad = mock_compositor_layer_quad; 194 // mc->base.base.layer_cube = mock_compositor_layer_cube; 195 // mc->base.base.layer_cylinder = mock_compositor_layer_cylinder; 196 // mc->base.base.layer_equirect1 = mock_compositor_layer_equirect1; 197 // mc->base.base.layer_equirect2 = mock_compositor_layer_equirect2; 198 // mc->base.base.layer_commit = mock_compositor_layer_commit; 199 // mc->base.base.layer_commit_with_semaphore = mock_compositor_layer_commit_with_semaphore; 200 // mc->base.base.poll_events = mock_compositor_poll_events; 201 mc->base.base.destroy = mock_compositor_destroy; 202 203 return &mc->base; 204}