oculus1

annotate libovr/Src/Util/Util_LatencyTest.cpp @ 17:cfe4979ab3eb

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