The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/survive: Count ahead of time how many configs to wait for

On recent libsurvive versions, loading the config of the HMD takes quite
long when only a HMD is active without controllers.

Instead of adjusting the timeout value all the time, rework how we wait for
the device configs.

Previously we just waited for device configs to arrive until no new configs
arrive for a predefined timeout.
Now we count how many objects of interest libsurvive actually knows, and then
only wait until the configs for this many devices are loaded.

This should make initialization of the survive driver faster and more robust.

+42 -9
+42 -9
src/xrt/drivers/survive/survive_driver.c
··· 52 52 53 53 #include "survive_driver.h" 54 54 55 - // reading usb config takes libsurvive about 50ms per device 56 - // to be safe, we wait 500 ms after the last device has been initialized 57 - #define DEFAULT_WAIT_TIMEOUT .75f 55 + // If we haven't gotten a config for devices this long after startup, just start without those devices 56 + #define DEFAULT_WAIT_TIMEOUT 3.5f 58 57 59 58 // index in sys->controllers[] array 60 59 #define SURVIVE_LEFT_CONTROLLER_INDEX 0 ··· 760 759 } 761 760 case SurviveSimpleEventType_ConfigEvent: { 762 761 const struct SurviveSimpleConfigEvent *e = survive_simple_get_config_event(event); 762 + enum SurviveSimpleObject_type t = survive_simple_object_get_type(e->object); 763 + const char *name = survive_simple_object_name(e->object); 764 + U_LOG_IFL_D(ss->ll, "Processing config for object name %s: type %d", name, t); 763 765 add_device(ss, e); 764 766 break; 765 767 } ··· 1192 1194 static bool 1193 1195 add_connected_devices(struct survive_system *ss) 1194 1196 { 1197 + /** @todo We don't know how many device added events we will get. 1198 + * After 25ms Index HMD + Controllers are added here. So 250ms should be a safe value. 1199 + * Device added just means libsurvive knows the usb devices, the config will then be loaded asynchronously. 1200 + */ 1201 + os_nanosleep(250 * 1000 * 1000); 1202 + 1203 + size_t objs = survive_simple_get_object_count(ss->ctx); 1204 + U_LOG_IFL_D(ss->ll, "Object count: %zu", objs); 1205 + 1195 1206 timepoint_ns start = os_monotonic_get_ns(); 1196 1207 1197 - while (true) { 1208 + // First count how many non-lighthouse objects libsurvive knows. 1209 + // Then poll events until we have gotten configs for this many, or until timeout. 1210 + int configs_to_wait_for = 0; 1211 + int configs_gotten = 0; 1212 + 1213 + for (const SurviveSimpleObject *sso = survive_simple_get_first_object(ss->ctx); sso; 1214 + sso = survive_simple_get_next_object(ss->ctx, sso)) { 1215 + enum SurviveSimpleObject_type t = survive_simple_object_get_type(sso); 1216 + const char *name = survive_simple_object_name(sso); 1217 + U_LOG_IFL_D(ss->ll, "Object name %s: type %d", name, t); 1218 + 1219 + // we only want to wait for configs of HMDs and controllers / trackers. 1220 + // Note: HMDs will be of type SurviveSimpleObject_OBJECT until the config is loaded. 1221 + if (t == SurviveSimpleObject_HMD || t == SurviveSimpleObject_OBJECT) { 1222 + configs_to_wait_for++; 1223 + } 1224 + } 1225 + 1226 + U_LOG_IFL_D(ss->ll, "Waiting for %d configs", configs_to_wait_for); 1227 + while (configs_gotten < configs_to_wait_for) { 1198 1228 struct SurviveSimpleEvent event = {0}; 1199 1229 while (survive_simple_next_event(ss->ctx, &event) != SurviveSimpleEventType_None) { 1200 1230 if (event.event_type == SurviveSimpleEventType_ConfigEvent) { 1201 1231 _process_event(ss, &event); 1202 - 1203 - // libsurvive processes sequentially, restart timeout 1204 - start = os_monotonic_get_ns(); 1232 + configs_gotten++; 1233 + U_LOG_IFL_D(ss->ll, "Got config from device: %d/%d", configs_gotten, 1234 + configs_to_wait_for); 1205 1235 } else { 1206 - U_LOG_IFL_T(ss->ll, "Skipping event\n"); 1236 + U_LOG_IFL_T(ss->ll, "Skipping event type %d", event.event_type); 1207 1237 } 1208 1238 } 1209 1239 1210 1240 if (time_ns_to_s(os_monotonic_get_ns() - start) > ss->wait_timeout) { 1241 + U_LOG_IFL_D(ss->ll, "Timed out after getting configs for %d/%d devices", configs_gotten, 1242 + configs_to_wait_for); 1211 1243 break; 1212 1244 } 1213 - os_nanosleep(1000); 1245 + os_nanosleep(500 * 1000); 1214 1246 } 1247 + U_LOG_IFL_D(ss->ll, "Waiting for configs took %f ms", time_ns_to_ms_f(os_monotonic_get_ns() - start)); 1215 1248 return true; 1216 1249 } 1217 1250