The open source OpenXR runtime

a/util,ipc,xrt: Support multi-local_floor space

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2252>

authored by

Yu Li and committed by
Marge Bot
b00a37be 3b7f85cd

+106 -21
+31 -2
src/xrt/auxiliary/util/u_space_overseer.c
··· 827 827 } 828 828 829 829 static xrt_result_t 830 - create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space) 830 + create_local_space(struct xrt_space_overseer *xso, 831 + struct xrt_space **out_local_space, 832 + struct xrt_space **out_local_floor_space) 831 833 { 832 834 assert(xso->semantic.root != NULL); 833 835 ··· 847 849 xsr.pose.orientation.z = 0; 848 850 math_quat_normalize(&xsr.pose.orientation); 849 851 850 - return create_offset_space(xso, xso->semantic.root, &xsr.pose, out_space); 852 + xrt_result_t xret = XRT_SUCCESS; 853 + 854 + if (out_local_space != NULL) { 855 + xret = create_offset_space(xso, xso->semantic.root, &xsr.pose, out_local_space); 856 + if (xret != XRT_SUCCESS) { 857 + U_LOG_E("Failed to create offset space LOCAL!"); 858 + return xret; 859 + } 860 + } 861 + 862 + if (out_local_floor_space != NULL) { 863 + if (xso->semantic.stage != NULL) { 864 + struct u_space *ustage = u_space(xso->semantic.stage); 865 + xsr.pose.position.y = ustage->offset.pose.position.y; 866 + } else { 867 + xsr.pose.position.y = 0; 868 + } 869 + xret = create_offset_space(xso, xso->semantic.root, &xsr.pose, out_local_floor_space); 870 + if (xret != XRT_SUCCESS) { 871 + U_LOG_E("Failed to create offset space LOCAL_FLOOR!"); 872 + return xret; 873 + } 874 + } 875 + 876 + return xret; 851 877 } 852 878 853 879 static xrt_result_t ··· 1018 1044 for (int id = 0; id < XRT_MAX_CLIENT_SPACES; id++) { 1019 1045 struct xrt_space **xslocal_ptr = (struct xrt_space **)&xso->localspace[id]; 1020 1046 xrt_space_reference(xslocal_ptr, NULL); 1047 + 1048 + struct xrt_space **xslocalfloor_ptr = (struct xrt_space **)&xso->localfloorspace[id]; 1049 + xrt_space_reference(xslocalfloor_ptr, NULL); 1021 1050 } 1022 1051 1023 1052 pthread_rwlock_destroy(&uso->lock);
+13 -6
src/xrt/include/xrt/xrt_space.h
··· 110 110 111 111 //! Ptrs to the localspace 112 112 struct xrt_space *localspace[XRT_MAX_CLIENT_SPACES]; 113 + //! Ptrs to the localfloorspace 114 + struct xrt_space *localfloorspace[XRT_MAX_CLIENT_SPACES]; 113 115 114 116 /*! 115 117 * Create a space with a fixed offset to the parent space. ··· 291 293 const struct xrt_pose *offset); 292 294 293 295 /*! 294 - * Create a localspace. 296 + * Create a localspace and a localfloorspace. 295 297 * 296 298 * @param[in] xso Owning space overseer. 297 - * @param[out] out_space The newly created localspace. 299 + * @param[out] out_local_space The newly created localspace. 300 + * @param[out] out_local_floor_space The newly created localfloorspace. 298 301 */ 299 - xrt_result_t (*create_local_space)(struct xrt_space_overseer *xso, struct xrt_space **out_space); 302 + xrt_result_t (*create_local_space)(struct xrt_space_overseer *xso, 303 + struct xrt_space **out_local_space, 304 + struct xrt_space **out_local_floor_space); 300 305 301 306 /*! 302 307 * Destroy function. ··· 496 501 } 497 502 498 503 /*! 499 - * @copydoc xrt_space_overseer::create_localspace_space 504 + * @copydoc xrt_space_overseer::create_local_space 500 505 * 501 506 * Helper for calling through the function pointer. 502 507 * 503 508 * @public @memberof xrt_space_overseer 504 509 */ 505 510 static inline xrt_result_t 506 - xrt_space_overseer_create_local_space(struct xrt_space_overseer *xso, struct xrt_space **out_space) 511 + xrt_space_overseer_create_local_space(struct xrt_space_overseer *xso, 512 + struct xrt_space **out_local_space, 513 + struct xrt_space **out_local_floor_space) 507 514 { 508 - return xso->create_local_space(xso, out_space); 515 + return xso->create_local_space(xso, out_local_space, out_local_floor_space); 509 516 } 510 517 511 518 /*!
+4
src/xrt/ipc/server/ipc_server.h
··· 120 120 uint32_t local_space_index; 121 121 //! Index of localspace in space overseer. 122 122 uint32_t local_space_overseer_index; 123 + //! Index of localfloorspace in ipc client. 124 + uint32_t local_floor_space_index; 125 + //! Index of localfloorspace in space overseer. 126 + uint32_t local_floor_space_overseer_index; 123 127 124 128 //! Ptrs to the spaces. 125 129 struct xrt_space *xspcs[IPC_MAX_CLIENT_SPACES];
+51 -13
src/xrt/ipc/server/ipc_server_handler.c
··· 174 174 175 175 176 176 static xrt_result_t 177 - get_new_localspace_id(volatile struct ipc_client_state *ics, uint32_t *out_id) 177 + get_new_localspace_id(volatile struct ipc_client_state *ics, uint32_t *out_local_id, uint32_t *out_local_floor_id) 178 178 { 179 179 // Our handle is just the index for now. 180 180 uint32_t index = 0; ··· 203 203 } 204 204 205 205 ics->local_space_index = index; 206 - *out_id = index; 206 + *out_local_id = index; 207 + 208 + for (index = 0; index < IPC_MAX_CLIENT_SPACES; index++) { 209 + if (ics->server->xso->localfloorspace[index] == NULL) { 210 + break; 211 + } 212 + } 213 + 214 + if (index >= IPC_MAX_CLIENT_SPACES) { 215 + IPC_ERROR(ics->server, "Too many localfloorspaces!"); 216 + return XRT_ERROR_IPC_FAILURE; 217 + } 218 + 219 + ics->local_floor_space_overseer_index = index; 220 + 221 + for (index = 0; index < IPC_MAX_CLIENT_SPACES; index++) { 222 + if (ics->xspcs[index] == NULL && index != ics->local_space_index) { 223 + break; 224 + } 225 + } 226 + 227 + if (index >= IPC_MAX_CLIENT_SPACES) { 228 + IPC_ERROR(ics->server, "Too many spaces!"); 229 + return XRT_ERROR_IPC_FAILURE; 230 + } 231 + 232 + ics->local_floor_space_index = index; 233 + *out_local_floor_id = index; 207 234 208 235 return XRT_SUCCESS; 209 236 } 210 237 211 238 static xrt_result_t 212 - create_localspace(volatile struct ipc_client_state *ics, uint32_t *out_local_id) 239 + create_localspace(volatile struct ipc_client_state *ics, uint32_t *out_local_id, uint32_t *out_local_floor_id) 213 240 { 214 - uint32_t id = UINT32_MAX; 215 - xrt_result_t xret = get_new_localspace_id(ics, &id); 241 + uint32_t local_id = UINT32_MAX; 242 + uint32_t local_floor_id = UINT32_MAX; 243 + xrt_result_t xret = get_new_localspace_id(ics, &local_id, &local_floor_id); 216 244 if (xret != XRT_SUCCESS) { 217 245 return xret; 218 246 } 219 247 220 248 struct xrt_space_overseer *xso = ics->server->xso; 221 - struct xrt_space **xs_ptr = (struct xrt_space **)&ics->xspcs[id]; 222 - 223 - xrt_space_overseer_create_local_space(xso, &xso->localspace[ics->local_space_overseer_index]); 249 + struct xrt_space **xslocal_ptr = (struct xrt_space **)&ics->xspcs[local_id]; 250 + struct xrt_space **xslocalfloor_ptr = (struct xrt_space **)&ics->xspcs[local_floor_id]; 224 251 225 - xrt_space_reference(xs_ptr, xso->localspace[ics->local_space_overseer_index]); 226 - *out_local_id = id; 252 + xret = xrt_space_overseer_create_local_space(xso, &xso->localspace[ics->local_space_overseer_index], 253 + &xso->localfloorspace[ics->local_floor_space_overseer_index]); 254 + if (xret != XRT_SUCCESS) { 255 + return xret; 256 + } 257 + xrt_space_reference(xslocal_ptr, xso->localspace[ics->local_space_overseer_index]); 258 + xrt_space_reference(xslocalfloor_ptr, xso->localfloorspace[ics->local_floor_space_overseer_index]); 259 + *out_local_id = local_id; 260 + *out_local_floor_id = local_floor_id; 227 261 228 262 return XRT_SUCCESS; 229 263 } ··· 444 478 445 479 CREATE(root); 446 480 CREATE(view); 447 - CREATE(local_floor); 448 481 CREATE(stage); 449 482 CREATE(unbounded); 450 483 451 484 #undef CREATE 452 - create_localspace(ics, out_local_id); 453 - return XRT_SUCCESS; 485 + return create_localspace(ics, out_local_id, out_local_floor_id); 454 486 } 455 487 456 488 xrt_result_t ··· 728 760 struct xrt_space **xslocal_ptr = 729 761 (struct xrt_space **)&ics->server->xso->localspace[ics->local_space_overseer_index]; 730 762 xrt_space_reference(xslocal_ptr, NULL); 763 + } 764 + 765 + if (space_id == ics->local_floor_space_index) { 766 + struct xrt_space **xslocalfloor_ptr = 767 + (struct xrt_space **)&ics->server->xso->localfloorspace[ics->local_floor_space_overseer_index]; 768 + xrt_space_reference(xslocalfloor_ptr, NULL); 731 769 } 732 770 733 771 return XRT_SUCCESS;
+7
src/xrt/ipc/server/ipc_server_per_client_thread.c
··· 72 72 NULL); 73 73 } 74 74 75 + if (ics->local_floor_space_overseer_index < IPC_MAX_CLIENT_SPACES && // 76 + ics->local_floor_space_overseer_index >= 0) { 77 + xrt_space_reference( 78 + (struct xrt_space **)&ics->server->xso->localfloorspace[ics->local_floor_space_overseer_index], 79 + NULL); 80 + } 81 + 75 82 // Mark an still in use reference spaces as no longer used. 76 83 for (uint32_t i = 0; i < ARRAY_SIZE(ics->ref_space_used); i++) { 77 84 bool used = ics->ref_space_used[i];