oculus1

annotate libovr/Src/Util/Util_LatencyTest.cpp @ 1:e2f9e4603129

added LibOVR and started a simple vr wrapper.
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 14 Sep 2013 16:14:59 +0300
parents
children b069a5c27388
rev   line source
nuclear@1 1 /************************************************************************************
nuclear@1 2
nuclear@1 3 Filename : Util_LatencyTest.cpp
nuclear@1 4 Content : Wraps the lower level LatencyTester interface and adds functionality.
nuclear@1 5 Created : February 14, 2013
nuclear@1 6 Authors : Lee Cooper
nuclear@1 7
nuclear@1 8 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
nuclear@1 9
nuclear@1 10 Use of this software is subject to the terms of the Oculus license
nuclear@1 11 agreement provided at the time of installation or download, or which
nuclear@1 12 otherwise accompanies this software in either electronic or hard copy form.
nuclear@1 13
nuclear@1 14 *************************************************************************************/
nuclear@1 15
nuclear@1 16 #include "Util_LatencyTest.h"
nuclear@1 17
nuclear@1 18 #include "../Kernel/OVR_Log.h"
nuclear@1 19 #include "../Kernel/OVR_Timer.h"
nuclear@1 20
nuclear@1 21 namespace OVR { namespace Util {
nuclear@1 22
nuclear@1 23 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10;
nuclear@1 24 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10;
nuclear@1 25 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5;
nuclear@1 26 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5;
nuclear@1 27 static const UInt32 DEFAULT_NUMBER_OF_SAMPLES = 10; // For both color 1->2 and color 2->1 transitions.
nuclear@1 28 static const UInt32 INITIAL_SAMPLES_TO_IGNORE = 4;
nuclear@1 29 static const UInt32 TIMEOUT_WAITING_FOR_TEST_STARTED = 1000;
nuclear@1 30 static const UInt32 TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000;
nuclear@1 31 static const Color CALIBRATE_BLACK(0, 0, 0);
nuclear@1 32 static const Color CALIBRATE_WHITE(255, 255, 255);
nuclear@1 33 static const Color COLOR1(0, 0, 0);
nuclear@1 34 static const Color COLOR2(255, 255, 255);
nuclear@1 35 static const Color SENSOR_DETECT_THRESHOLD(128, 255, 255);
nuclear@1 36 static const float BIG_FLOAT = 1000000.0f;
nuclear@1 37 static const float SMALL_FLOAT = -1000000.0f;
nuclear@1 38
nuclear@1 39 //-------------------------------------------------------------------------------------
nuclear@1 40 // ***** LatencyTest
nuclear@1 41
nuclear@1 42 LatencyTest::LatencyTest(LatencyTestDevice* device)
nuclear@1 43 : Handler(getThis())
nuclear@1 44 {
nuclear@1 45 if (device != NULL)
nuclear@1 46 {
nuclear@1 47 SetDevice(device);
nuclear@1 48 }
nuclear@1 49
nuclear@1 50 reset();
nuclear@1 51
nuclear@1 52 srand(Timer::GetTicksMs());
nuclear@1 53 }
nuclear@1 54
nuclear@1 55 LatencyTest::~LatencyTest()
nuclear@1 56 {
nuclear@1 57 clearMeasurementResults();
nuclear@1 58 }
nuclear@1 59
nuclear@1 60 bool LatencyTest::SetDevice(LatencyTestDevice* device)
nuclear@1 61 {
nuclear@1 62
nuclear@1 63 if (device != Device)
nuclear@1 64 {
nuclear@1 65 if (device != NULL)
nuclear@1 66 {
nuclear@1 67 if (device->GetMessageHandler() != NULL)
nuclear@1 68 {
nuclear@1 69 OVR_DEBUG_LOG(
nuclear@1 70 ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
nuclear@1 71 return false;
nuclear@1 72 }
nuclear@1 73 }
nuclear@1 74
nuclear@1 75 if (Device != NULL)
nuclear@1 76 {
nuclear@1 77 Device->SetMessageHandler(0);
nuclear@1 78 }
nuclear@1 79 Device = device;
nuclear@1 80
nuclear@1 81 if (Device != NULL)
nuclear@1 82 {
nuclear@1 83 Device->SetMessageHandler(&Handler);
nuclear@1 84
nuclear@1 85 // Set trigger threshold.
nuclear@1 86 LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false); // No samples streaming.
nuclear@1 87 Device->SetConfiguration(configuration, true);
nuclear@1 88
nuclear@1 89 // Set display to intial (3 dashes).
nuclear@1 90 LatencyTestDisplay ltd(2, 0x40400040);
nuclear@1 91 Device->SetDisplay(ltd);
nuclear@1 92 }
nuclear@1 93 }
nuclear@1 94
nuclear@1 95 return true;
nuclear@1 96 }
nuclear@1 97
nuclear@1 98 UInt32 LatencyTest::getRandomComponent(UInt32 range)
nuclear@1 99 {
nuclear@1 100 UInt32 val = rand() % range;
nuclear@1 101 return val;
nuclear@1 102 }
nuclear@1 103
nuclear@1 104 void LatencyTest::BeginTest()
nuclear@1 105 {
nuclear@1 106 if (State == State_WaitingForButton)
nuclear@1 107 {
nuclear@1 108 // Set color to black and wait a while.
nuclear@1 109 RenderColor = CALIBRATE_BLACK;
nuclear@1 110
nuclear@1 111 State = State_WaitingForSettlePreCalibrationColorBlack;
nuclear@1 112 OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack."));
nuclear@1 113
nuclear@1 114 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
nuclear@1 115 }
nuclear@1 116 }
nuclear@1 117
nuclear@1 118 void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage)
nuclear@1 119 {
nuclear@1 120 // For debugging.
nuclear@1 121 /* if (msg.Type == Message_LatencyTestSamples)
nuclear@1 122 {
nuclear@1 123 MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg;
nuclear@1 124
nuclear@1 125 if (pSamples->Samples.GetSize() > 0)
nuclear@1 126 {
nuclear@1 127 // Just show the first one for now.
nuclear@1 128 Color c = pSamples->Samples[0];
nuclear@1 129 OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B));
nuclear@1 130 }
nuclear@1 131 return;
nuclear@1 132 }
nuclear@1 133 */
nuclear@1 134
nuclear@1 135 if (latencyTestMessage == LatencyTest_Timer)
nuclear@1 136 {
nuclear@1 137 if (!Device)
nuclear@1 138 {
nuclear@1 139 reset();
nuclear@1 140 return;
nuclear@1 141 }
nuclear@1 142
nuclear@1 143 if (State == State_WaitingForSettlePreCalibrationColorBlack)
nuclear@1 144 {
nuclear@1 145 // Send calibrate message to device and wait a while.
nuclear@1 146 Device->SetCalibrate(CALIBRATE_BLACK);
nuclear@1 147
nuclear@1 148 State = State_WaitingForSettlePostCalibrationColorBlack;
nuclear@1 149 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack."));
nuclear@1 150
nuclear@1 151 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
nuclear@1 152 }
nuclear@1 153 else if (State == State_WaitingForSettlePostCalibrationColorBlack)
nuclear@1 154 {
nuclear@1 155 // Change color to white and wait a while.
nuclear@1 156 RenderColor = CALIBRATE_WHITE;
nuclear@1 157
nuclear@1 158 State = State_WaitingForSettlePreCalibrationColorWhite;
nuclear@1 159 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite."));
nuclear@1 160
nuclear@1 161 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
nuclear@1 162 }
nuclear@1 163 else if (State == State_WaitingForSettlePreCalibrationColorWhite)
nuclear@1 164 {
nuclear@1 165 // Send calibrate message to device and wait a while.
nuclear@1 166 Device->SetCalibrate(CALIBRATE_WHITE);
nuclear@1 167
nuclear@1 168 State = State_WaitingForSettlePostCalibrationColorWhite;
nuclear@1 169 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite."));
nuclear@1 170
nuclear@1 171 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
nuclear@1 172 }
nuclear@1 173 else if (State == State_WaitingForSettlePostCalibrationColorWhite)
nuclear@1 174 {
nuclear@1 175 // Calibration is done. Switch to color 1 and wait for it to settle.
nuclear@1 176 RenderColor = COLOR1;
nuclear@1 177
nuclear@1 178 State = State_WaitingForSettlePostMeasurement;
nuclear@1 179 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement."));
nuclear@1 180
nuclear@1 181 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
nuclear@1 182 setTimer(waitTime);
nuclear@1 183 }
nuclear@1 184 else if (State == State_WaitingForSettlePostMeasurement)
nuclear@1 185 {
nuclear@1 186 // Prepare for next measurement.
nuclear@1 187
nuclear@1 188 // Create a new result object.
nuclear@1 189 MeasurementResult* pResult = new MeasurementResult();
nuclear@1 190 Results.PushBack(pResult);
nuclear@1 191
nuclear@1 192 State = State_WaitingToTakeMeasurement;
nuclear@1 193 OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement."));
nuclear@1 194 }
nuclear@1 195 else if (State == State_WaitingForTestStarted)
nuclear@1 196 {
nuclear@1 197 // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next.
nuclear@1 198 getActiveResult()->TimedOutWaitingForTestStarted = true;
nuclear@1 199
nuclear@1 200 State = State_WaitingForSettlePostMeasurement;
nuclear@1 201 OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'."));
nuclear@1 202 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement."));
nuclear@1 203
nuclear@1 204 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
nuclear@1 205 setTimer(waitTime);
nuclear@1 206 }
nuclear@1 207 else if (State == State_WaitingForColorDetected)
nuclear@1 208 {
nuclear@1 209 // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next.
nuclear@1 210 getActiveResult()->TimedOutWaitingForColorDetected = true;
nuclear@1 211
nuclear@1 212 State = State_WaitingForSettlePostMeasurement;
nuclear@1 213 OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'."));
nuclear@1 214 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
nuclear@1 215
nuclear@1 216 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
nuclear@1 217 setTimer(waitTime);
nuclear@1 218 }
nuclear@1 219 }
nuclear@1 220 else if (latencyTestMessage == LatencyTest_ProcessInputs)
nuclear@1 221 {
nuclear@1 222 if (State == State_WaitingToTakeMeasurement)
nuclear@1 223 {
nuclear@1 224 if (!Device)
nuclear@1 225 {
nuclear@1 226 reset();
nuclear@1 227 return;
nuclear@1 228 }
nuclear@1 229
nuclear@1 230 // Send 'StartTest' feature report with opposite target color.
nuclear@1 231 if (RenderColor == COLOR1)
nuclear@1 232 {
nuclear@1 233 RenderColor = COLOR2;
nuclear@1 234 }
nuclear@1 235 else
nuclear@1 236 {
nuclear@1 237 RenderColor = COLOR1;
nuclear@1 238 }
nuclear@1 239
nuclear@1 240 getActiveResult()->TargetColor = RenderColor;
nuclear@1 241
nuclear@1 242 // Record time so we can determine usb roundtrip time.
nuclear@1 243 getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
nuclear@1 244
nuclear@1 245 Device->SetStartTest(RenderColor);
nuclear@1 246
nuclear@1 247 State = State_WaitingForTestStarted;
nuclear@1 248 OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted."));
nuclear@1 249
nuclear@1 250 setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED);
nuclear@1 251
nuclear@1 252 LatencyTestDisplay ltd(2, 0x40090040);
nuclear@1 253 Device->SetDisplay(ltd);
nuclear@1 254 }
nuclear@1 255 }
nuclear@1 256 else if (msg.Type == Message_LatencyTestButton)
nuclear@1 257 {
nuclear@1 258 BeginTest();
nuclear@1 259 }
nuclear@1 260 else if (msg.Type == Message_LatencyTestStarted)
nuclear@1 261 {
nuclear@1 262 if (State == State_WaitingForTestStarted)
nuclear@1 263 {
nuclear@1 264 clearTimer();
nuclear@1 265
nuclear@1 266 // Record time so we can determine usb roundtrip time.
nuclear@1 267 getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
nuclear@1 268
nuclear@1 269 State = State_WaitingForColorDetected;
nuclear@1 270 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
nuclear@1 271
nuclear@1 272 setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED);
nuclear@1 273 }
nuclear@1 274 }
nuclear@1 275 else if (msg.Type == Message_LatencyTestColorDetected)
nuclear@1 276 {
nuclear@1 277 if (State == State_WaitingForColorDetected)
nuclear@1 278 {
nuclear@1 279 // Record time to detect color.
nuclear@1 280 MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg;
nuclear@1 281 UInt16 elapsedTime = pDetected->Elapsed;
nuclear@1 282 OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime));
nuclear@1 283
nuclear@1 284 getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime;
nuclear@1 285
nuclear@1 286 if (areResultsComplete())
nuclear@1 287 {
nuclear@1 288 // We're done.
nuclear@1 289 processResults();
nuclear@1 290 reset();
nuclear@1 291 }
nuclear@1 292 else
nuclear@1 293 {
nuclear@1 294 // Run another measurement.
nuclear@1 295 State = State_WaitingForSettlePostMeasurement;
nuclear@1 296 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
nuclear@1 297
nuclear@1 298 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
nuclear@1 299 setTimer(waitTime);
nuclear@1 300
nuclear@1 301 LatencyTestDisplay ltd(2, 0x40400040);
nuclear@1 302 Device->SetDisplay(ltd);
nuclear@1 303 }
nuclear@1 304 }
nuclear@1 305 }
nuclear@1 306 else if (msg.Type == Message_DeviceRemoved)
nuclear@1 307 {
nuclear@1 308 reset();
nuclear@1 309 }
nuclear@1 310 }
nuclear@1 311
nuclear@1 312 LatencyTest::MeasurementResult* LatencyTest::getActiveResult()
nuclear@1 313 {
nuclear@1 314 OVR_ASSERT(!Results.IsEmpty());
nuclear@1 315 return Results.GetLast();
nuclear@1 316 }
nuclear@1 317
nuclear@1 318 void LatencyTest::setTimer(UInt32 timeMilliS)
nuclear@1 319 {
nuclear@1 320 ActiveTimerMilliS = timeMilliS;
nuclear@1 321 }
nuclear@1 322
nuclear@1 323 void LatencyTest::clearTimer()
nuclear@1 324 {
nuclear@1 325 ActiveTimerMilliS = 0;
nuclear@1 326 }
nuclear@1 327
nuclear@1 328 void LatencyTest::reset()
nuclear@1 329 {
nuclear@1 330 clearMeasurementResults();
nuclear@1 331 State = State_WaitingForButton;
nuclear@1 332
nuclear@1 333 HaveOldTime = false;
nuclear@1 334 ActiveTimerMilliS = 0;
nuclear@1 335 }
nuclear@1 336
nuclear@1 337 void LatencyTest::clearMeasurementResults()
nuclear@1 338 {
nuclear@1 339 while(!Results.IsEmpty())
nuclear@1 340 {
nuclear@1 341 MeasurementResult* pElem = Results.GetFirst();
nuclear@1 342 pElem->RemoveNode();
nuclear@1 343 delete pElem;
nuclear@1 344 }
nuclear@1 345 }
nuclear@1 346
nuclear@1 347 LatencyTest::LatencyTestHandler::~LatencyTestHandler()
nuclear@1 348 {
nuclear@1 349 RemoveHandlerFromDevices();
nuclear@1 350 }
nuclear@1 351
nuclear@1 352 void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg)
nuclear@1 353 {
nuclear@1 354 pLatencyTestUtil->handleMessage(msg);
nuclear@1 355 }
nuclear@1 356
nuclear@1 357 void LatencyTest::ProcessInputs()
nuclear@1 358 {
nuclear@1 359 updateForTimeouts();
nuclear@1 360 handleMessage(Message(), LatencyTest_ProcessInputs);
nuclear@1 361 }
nuclear@1 362
nuclear@1 363 bool LatencyTest::DisplayScreenColor(Color& colorToDisplay)
nuclear@1 364 {
nuclear@1 365 updateForTimeouts();
nuclear@1 366
nuclear@1 367 if (State == State_WaitingForButton)
nuclear@1 368 {
nuclear@1 369 return false;
nuclear@1 370 }
nuclear@1 371
nuclear@1 372 colorToDisplay = RenderColor;
nuclear@1 373 return true;
nuclear@1 374 }
nuclear@1 375
nuclear@1 376 const char* LatencyTest::GetResultsString()
nuclear@1 377 {
nuclear@1 378 if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr())
nuclear@1 379 {
nuclear@1 380 ReturnedResultString = ResultsString;
nuclear@1 381 return ReturnedResultString.ToCStr();
nuclear@1 382 }
nuclear@1 383
nuclear@1 384 return NULL;
nuclear@1 385 }
nuclear@1 386
nuclear@1 387 bool LatencyTest::areResultsComplete()
nuclear@1 388 {
nuclear@1 389 UInt32 initialMeasurements = 0;
nuclear@1 390
nuclear@1 391 UInt32 measurements1to2 = 0;
nuclear@1 392 UInt32 measurements2to1 = 0;
nuclear@1 393
nuclear@1 394 MeasurementResult* pCurr = Results.GetFirst();
nuclear@1 395 while(true)
nuclear@1 396 {
nuclear@1 397 // Process.
nuclear@1 398 if (!pCurr->TimedOutWaitingForTestStarted &&
nuclear@1 399 !pCurr->TimedOutWaitingForColorDetected)
nuclear@1 400 {
nuclear@1 401 initialMeasurements++;
nuclear@1 402
nuclear@1 403 if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE)
nuclear@1 404 {
nuclear@1 405 if (pCurr->TargetColor == COLOR2)
nuclear@1 406 {
nuclear@1 407 measurements1to2++;
nuclear@1 408 }
nuclear@1 409 else
nuclear@1 410 {
nuclear@1 411 measurements2to1++;
nuclear@1 412 }
nuclear@1 413 }
nuclear@1 414 }
nuclear@1 415
nuclear@1 416 if (Results.IsLast(pCurr))
nuclear@1 417 {
nuclear@1 418 break;
nuclear@1 419 }
nuclear@1 420 pCurr = Results.GetNext(pCurr);
nuclear@1 421 }
nuclear@1 422
nuclear@1 423 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
nuclear@1 424 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
nuclear@1 425 {
nuclear@1 426 return true;
nuclear@1 427 }
nuclear@1 428
nuclear@1 429 return false;
nuclear@1 430 }
nuclear@1 431
nuclear@1 432 void LatencyTest::processResults()
nuclear@1 433 {
nuclear@1 434
nuclear@1 435 UInt32 minTime1To2 = UINT_MAX;
nuclear@1 436 UInt32 maxTime1To2 = 0;
nuclear@1 437 float averageTime1To2 = 0.0f;
nuclear@1 438 UInt32 minTime2To1 = UINT_MAX;
nuclear@1 439 UInt32 maxTime2To1 = 0;
nuclear@1 440 float averageTime2To1 = 0.0f;
nuclear@1 441
nuclear@1 442 float minUSBTripMilliS = BIG_FLOAT;
nuclear@1 443 float maxUSBTripMilliS = SMALL_FLOAT;
nuclear@1 444 float averageUSBTripMilliS = 0.0f;
nuclear@1 445 UInt32 countUSBTripTime = 0;
nuclear@1 446
nuclear@1 447 UInt32 measurementsCount = 0;
nuclear@1 448 UInt32 measurements1to2 = 0;
nuclear@1 449 UInt32 measurements2to1 = 0;
nuclear@1 450
nuclear@1 451 MeasurementResult* pCurr = Results.GetFirst();
nuclear@1 452 UInt32 count = 0;
nuclear@1 453 while(true)
nuclear@1 454 {
nuclear@1 455 count++;
nuclear@1 456
nuclear@1 457 if (!pCurr->TimedOutWaitingForTestStarted &&
nuclear@1 458 !pCurr->TimedOutWaitingForColorDetected)
nuclear@1 459 {
nuclear@1 460 measurementsCount++;
nuclear@1 461
nuclear@1 462 if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE)
nuclear@1 463 {
nuclear@1 464 if (pCurr->TargetColor == COLOR2)
nuclear@1 465 {
nuclear@1 466 measurements1to2++;
nuclear@1 467
nuclear@1 468 if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES)
nuclear@1 469 {
nuclear@1 470 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
nuclear@1 471
nuclear@1 472 minTime1To2 = Alg::Min(elapsed, minTime1To2);
nuclear@1 473 maxTime1To2 = Alg::Max(elapsed, maxTime1To2);
nuclear@1 474
nuclear@1 475 averageTime1To2 += (float) elapsed;
nuclear@1 476 }
nuclear@1 477 }
nuclear@1 478 else
nuclear@1 479 {
nuclear@1 480 measurements2to1++;
nuclear@1 481
nuclear@1 482 if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES)
nuclear@1 483 {
nuclear@1 484 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
nuclear@1 485
nuclear@1 486 minTime2To1 = Alg::Min(elapsed, minTime2To1);
nuclear@1 487 maxTime2To1 = Alg::Max(elapsed, maxTime2To1);
nuclear@1 488
nuclear@1 489 averageTime2To1 += (float) elapsed;
nuclear@1 490 }
nuclear@1 491 }
nuclear@1 492
nuclear@1 493 float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
nuclear@1 494 minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
nuclear@1 495 maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
nuclear@1 496 averageUSBTripMilliS += usbRountripElapsedMilliS;
nuclear@1 497 countUSBTripTime++;
nuclear@1 498 }
nuclear@1 499 }
nuclear@1 500
nuclear@1 501 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
nuclear@1 502 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
nuclear@1 503 {
nuclear@1 504 break;
nuclear@1 505 }
nuclear@1 506
nuclear@1 507 if (Results.IsLast(pCurr))
nuclear@1 508 {
nuclear@1 509 break;
nuclear@1 510 }
nuclear@1 511 pCurr = Results.GetNext(pCurr);
nuclear@1 512 }
nuclear@1 513
nuclear@1 514 averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
nuclear@1 515 averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
nuclear@1 516
nuclear@1 517 averageUSBTripMilliS /= countUSBTripTime;
nuclear@1 518
nuclear@1 519 float finalResult = 0.5f * (averageTime1To2 + averageTime2To1);
nuclear@1 520 finalResult += averageUSBTripMilliS;
nuclear@1 521
nuclear@1 522 ResultsString.Clear();
nuclear@1 523 ResultsString.AppendFormat("RESULT=%.1f (add half Tracker period) [b->w %d|%.1f|%d] [w->b %d|%.1f|%d] [usb rndtrp %.1f|%.1f|%.1f] [cnt %d] [tmouts %d]",
nuclear@1 524 finalResult,
nuclear@1 525 minTime1To2, averageTime1To2, maxTime1To2,
nuclear@1 526 minTime2To1, averageTime2To1, maxTime2To1,
nuclear@1 527 minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS,
nuclear@1 528 DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount);
nuclear@1 529
nuclear@1 530 // Display result on latency tester display.
nuclear@1 531 LatencyTestDisplay ltd(1, (int)finalResult);
nuclear@1 532 Device->SetDisplay(ltd);
nuclear@1 533 }
nuclear@1 534
nuclear@1 535 void LatencyTest::updateForTimeouts()
nuclear@1 536 {
nuclear@1 537 if (!HaveOldTime)
nuclear@1 538 {
nuclear@1 539 HaveOldTime = true;
nuclear@1 540 OldTime = Timer::GetTicksMs();
nuclear@1 541 return;
nuclear@1 542 }
nuclear@1 543
nuclear@1 544 UInt32 newTime = Timer::GetTicksMs();
nuclear@1 545 UInt32 elapsedMilliS = newTime - OldTime;
nuclear@1 546 if (newTime < OldTime)
nuclear@1 547 {
nuclear@1 548 elapsedMilliS = OldTime - newTime;
nuclear@1 549 elapsedMilliS = UINT_MAX - elapsedMilliS;
nuclear@1 550 }
nuclear@1 551 OldTime = newTime;
nuclear@1 552
nuclear@1 553 elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100); // Clamp at 100mS in case we're not being called very often.
nuclear@1 554
nuclear@1 555
nuclear@1 556 if (ActiveTimerMilliS == 0)
nuclear@1 557 {
nuclear@1 558 return;
nuclear@1 559 }
nuclear@1 560
nuclear@1 561 if (elapsedMilliS >= ActiveTimerMilliS)
nuclear@1 562 {
nuclear@1 563 ActiveTimerMilliS = 0;
nuclear@1 564 handleMessage(Message(), LatencyTest_Timer);
nuclear@1 565 return;
nuclear@1 566 }
nuclear@1 567
nuclear@1 568 ActiveTimerMilliS -= elapsedMilliS;
nuclear@1 569 }
nuclear@1 570
nuclear@1 571 }} // namespace OVR::Util