Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "Util_LatencyTest.h"
00017
00018 #include "../Kernel/OVR_Log.h"
00019 #include "../Kernel/OVR_Timer.h"
00020
00021 namespace OVR { namespace Util {
00022
00023 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10;
00024 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10;
00025 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5;
00026 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5;
00027 static const UInt32 DEFAULT_NUMBER_OF_SAMPLES = 10;
00028 static const UInt32 INITIAL_SAMPLES_TO_IGNORE = 4;
00029 static const UInt32 TIMEOUT_WAITING_FOR_TEST_STARTED = 1000;
00030 static const UInt32 TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000;
00031 static const Color CALIBRATE_BLACK(0, 0, 0);
00032 static const Color CALIBRATE_WHITE(255, 255, 255);
00033 static const Color COLOR1(0, 0, 0);
00034 static const Color COLOR2(255, 255, 255);
00035 static const Color SENSOR_DETECT_THRESHOLD(128, 255, 255);
00036 static const float BIG_FLOAT = 1000000.0f;
00037 static const float SMALL_FLOAT = -1000000.0f;
00038
00039
00040
00041
00042 LatencyTest::LatencyTest(LatencyTestDevice* device)
00043 : Handler(getThis())
00044 {
00045 if (device != NULL)
00046 {
00047 SetDevice(device);
00048 }
00049
00050 reset();
00051
00052 srand(Timer::GetTicksMs());
00053 }
00054
00055 LatencyTest::~LatencyTest()
00056 {
00057 clearMeasurementResults();
00058 }
00059
00060 bool LatencyTest::SetDevice(LatencyTestDevice* device)
00061 {
00062
00063 if (device != Device)
00064 {
00065 if (device != NULL)
00066 {
00067 if (device->GetMessageHandler() != NULL)
00068 {
00069 OVR_DEBUG_LOG(
00070 ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
00071 return false;
00072 }
00073 }
00074
00075 if (Device != NULL)
00076 {
00077 Device->SetMessageHandler(0);
00078 }
00079 Device = device;
00080
00081 if (Device != NULL)
00082 {
00083 Device->SetMessageHandler(&Handler);
00084
00085
00086 LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false);
00087 Device->SetConfiguration(configuration, true);
00088
00089
00090 LatencyTestDisplay ltd(2, 0x40400040);
00091 Device->SetDisplay(ltd);
00092 }
00093 }
00094
00095 return true;
00096 }
00097
00098 UInt32 LatencyTest::getRandomComponent(UInt32 range)
00099 {
00100 UInt32 val = rand() % range;
00101 return val;
00102 }
00103
00104 void LatencyTest::BeginTest()
00105 {
00106 if (State == State_WaitingForButton)
00107 {
00108
00109 RenderColor = CALIBRATE_BLACK;
00110
00111 State = State_WaitingForSettlePreCalibrationColorBlack;
00112 OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack."));
00113
00114 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
00115 }
00116 }
00117
00118 void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage)
00119 {
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 if (latencyTestMessage == LatencyTest_Timer)
00136 {
00137 if (!Device)
00138 {
00139 reset();
00140 return;
00141 }
00142
00143 if (State == State_WaitingForSettlePreCalibrationColorBlack)
00144 {
00145
00146 Device->SetCalibrate(CALIBRATE_BLACK);
00147
00148 State = State_WaitingForSettlePostCalibrationColorBlack;
00149 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack."));
00150
00151 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
00152 }
00153 else if (State == State_WaitingForSettlePostCalibrationColorBlack)
00154 {
00155
00156 RenderColor = CALIBRATE_WHITE;
00157
00158 State = State_WaitingForSettlePreCalibrationColorWhite;
00159 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite."));
00160
00161 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
00162 }
00163 else if (State == State_WaitingForSettlePreCalibrationColorWhite)
00164 {
00165
00166 Device->SetCalibrate(CALIBRATE_WHITE);
00167
00168 State = State_WaitingForSettlePostCalibrationColorWhite;
00169 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite."));
00170
00171 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
00172 }
00173 else if (State == State_WaitingForSettlePostCalibrationColorWhite)
00174 {
00175
00176 RenderColor = COLOR1;
00177
00178 State = State_WaitingForSettlePostMeasurement;
00179 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement."));
00180
00181 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
00182 setTimer(waitTime);
00183 }
00184 else if (State == State_WaitingForSettlePostMeasurement)
00185 {
00186
00187
00188
00189 MeasurementResult* pResult = new MeasurementResult();
00190 Results.PushBack(pResult);
00191
00192 State = State_WaitingToTakeMeasurement;
00193 OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement."));
00194 }
00195 else if (State == State_WaitingForTestStarted)
00196 {
00197
00198 getActiveResult()->TimedOutWaitingForTestStarted = true;
00199
00200 State = State_WaitingForSettlePostMeasurement;
00201 OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'."));
00202 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement."));
00203
00204 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
00205 setTimer(waitTime);
00206 }
00207 else if (State == State_WaitingForColorDetected)
00208 {
00209
00210 getActiveResult()->TimedOutWaitingForColorDetected = true;
00211
00212 State = State_WaitingForSettlePostMeasurement;
00213 OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'."));
00214 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
00215
00216 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
00217 setTimer(waitTime);
00218 }
00219 }
00220 else if (latencyTestMessage == LatencyTest_ProcessInputs)
00221 {
00222 if (State == State_WaitingToTakeMeasurement)
00223 {
00224 if (!Device)
00225 {
00226 reset();
00227 return;
00228 }
00229
00230
00231 if (RenderColor == COLOR1)
00232 {
00233 RenderColor = COLOR2;
00234 }
00235 else
00236 {
00237 RenderColor = COLOR1;
00238 }
00239
00240 getActiveResult()->TargetColor = RenderColor;
00241
00242
00243 getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
00244
00245 Device->SetStartTest(RenderColor);
00246
00247 State = State_WaitingForTestStarted;
00248 OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted."));
00249
00250 setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED);
00251
00252 LatencyTestDisplay ltd(2, 0x40090040);
00253 Device->SetDisplay(ltd);
00254 }
00255 }
00256 else if (msg.Type == Message_LatencyTestButton)
00257 {
00258 BeginTest();
00259 }
00260 else if (msg.Type == Message_LatencyTestStarted)
00261 {
00262 if (State == State_WaitingForTestStarted)
00263 {
00264 clearTimer();
00265
00266
00267 getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
00268
00269 State = State_WaitingForColorDetected;
00270 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
00271
00272 setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED);
00273 }
00274 }
00275 else if (msg.Type == Message_LatencyTestColorDetected)
00276 {
00277 if (State == State_WaitingForColorDetected)
00278 {
00279
00280 MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg;
00281 UInt16 elapsedTime = pDetected->Elapsed;
00282 OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime));
00283
00284 getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime;
00285
00286 if (areResultsComplete())
00287 {
00288
00289 processResults();
00290 reset();
00291 }
00292 else
00293 {
00294
00295 State = State_WaitingForSettlePostMeasurement;
00296 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
00297
00298 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
00299 setTimer(waitTime);
00300
00301 LatencyTestDisplay ltd(2, 0x40400040);
00302 Device->SetDisplay(ltd);
00303 }
00304 }
00305 }
00306 else if (msg.Type == Message_DeviceRemoved)
00307 {
00308 reset();
00309 }
00310 }
00311
00312 LatencyTest::MeasurementResult* LatencyTest::getActiveResult()
00313 {
00314 OVR_ASSERT(!Results.IsEmpty());
00315 return Results.GetLast();
00316 }
00317
00318 void LatencyTest::setTimer(UInt32 timeMilliS)
00319 {
00320 ActiveTimerMilliS = timeMilliS;
00321 }
00322
00323 void LatencyTest::clearTimer()
00324 {
00325 ActiveTimerMilliS = 0;
00326 }
00327
00328 void LatencyTest::reset()
00329 {
00330 clearMeasurementResults();
00331 State = State_WaitingForButton;
00332
00333 HaveOldTime = false;
00334 ActiveTimerMilliS = 0;
00335 }
00336
00337 void LatencyTest::clearMeasurementResults()
00338 {
00339 while(!Results.IsEmpty())
00340 {
00341 MeasurementResult* pElem = Results.GetFirst();
00342 pElem->RemoveNode();
00343 delete pElem;
00344 }
00345 }
00346
00347 LatencyTest::LatencyTestHandler::~LatencyTestHandler()
00348 {
00349 RemoveHandlerFromDevices();
00350 }
00351
00352 void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg)
00353 {
00354 pLatencyTestUtil->handleMessage(msg);
00355 }
00356
00357 void LatencyTest::ProcessInputs()
00358 {
00359 updateForTimeouts();
00360 handleMessage(Message(), LatencyTest_ProcessInputs);
00361 }
00362
00363 bool LatencyTest::DisplayScreenColor(Color& colorToDisplay)
00364 {
00365 updateForTimeouts();
00366
00367 if (State == State_WaitingForButton)
00368 {
00369 return false;
00370 }
00371
00372 colorToDisplay = RenderColor;
00373 return true;
00374 }
00375
00376 const char* LatencyTest::GetResultsString()
00377 {
00378 if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr())
00379 {
00380 ReturnedResultString = ResultsString;
00381 return ReturnedResultString.ToCStr();
00382 }
00383
00384 return NULL;
00385 }
00386
00387 bool LatencyTest::areResultsComplete()
00388 {
00389 UInt32 initialMeasurements = 0;
00390
00391 UInt32 measurements1to2 = 0;
00392 UInt32 measurements2to1 = 0;
00393
00394 MeasurementResult* pCurr = Results.GetFirst();
00395 while(true)
00396 {
00397
00398 if (!pCurr->TimedOutWaitingForTestStarted &&
00399 !pCurr->TimedOutWaitingForColorDetected)
00400 {
00401 initialMeasurements++;
00402
00403 if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE)
00404 {
00405 if (pCurr->TargetColor == COLOR2)
00406 {
00407 measurements1to2++;
00408 }
00409 else
00410 {
00411 measurements2to1++;
00412 }
00413 }
00414 }
00415
00416 if (Results.IsLast(pCurr))
00417 {
00418 break;
00419 }
00420 pCurr = Results.GetNext(pCurr);
00421 }
00422
00423 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
00424 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
00425 {
00426 return true;
00427 }
00428
00429 return false;
00430 }
00431
00432 void LatencyTest::processResults()
00433 {
00434
00435 UInt32 minTime1To2 = UINT_MAX;
00436 UInt32 maxTime1To2 = 0;
00437 float averageTime1To2 = 0.0f;
00438 UInt32 minTime2To1 = UINT_MAX;
00439 UInt32 maxTime2To1 = 0;
00440 float averageTime2To1 = 0.0f;
00441
00442 float minUSBTripMilliS = BIG_FLOAT;
00443 float maxUSBTripMilliS = SMALL_FLOAT;
00444 float averageUSBTripMilliS = 0.0f;
00445 UInt32 countUSBTripTime = 0;
00446
00447 UInt32 measurementsCount = 0;
00448 UInt32 measurements1to2 = 0;
00449 UInt32 measurements2to1 = 0;
00450
00451 MeasurementResult* pCurr = Results.GetFirst();
00452 UInt32 count = 0;
00453 while(true)
00454 {
00455 count++;
00456
00457 if (!pCurr->TimedOutWaitingForTestStarted &&
00458 !pCurr->TimedOutWaitingForColorDetected)
00459 {
00460 measurementsCount++;
00461
00462 if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE)
00463 {
00464 if (pCurr->TargetColor == COLOR2)
00465 {
00466 measurements1to2++;
00467
00468 if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES)
00469 {
00470 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
00471
00472 minTime1To2 = Alg::Min(elapsed, minTime1To2);
00473 maxTime1To2 = Alg::Max(elapsed, maxTime1To2);
00474
00475 averageTime1To2 += (float) elapsed;
00476 }
00477 }
00478 else
00479 {
00480 measurements2to1++;
00481
00482 if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES)
00483 {
00484 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
00485
00486 minTime2To1 = Alg::Min(elapsed, minTime2To1);
00487 maxTime2To1 = Alg::Max(elapsed, maxTime2To1);
00488
00489 averageTime2To1 += (float) elapsed;
00490 }
00491 }
00492
00493 float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
00494 minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
00495 maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
00496 averageUSBTripMilliS += usbRountripElapsedMilliS;
00497 countUSBTripTime++;
00498 }
00499 }
00500
00501 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
00502 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
00503 {
00504 break;
00505 }
00506
00507 if (Results.IsLast(pCurr))
00508 {
00509 break;
00510 }
00511 pCurr = Results.GetNext(pCurr);
00512 }
00513
00514 averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
00515 averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
00516
00517 averageUSBTripMilliS /= countUSBTripTime;
00518
00519 float finalResult = 0.5f * (averageTime1To2 + averageTime2To1);
00520 finalResult += averageUSBTripMilliS;
00521
00522 ResultsString.Clear();
00523 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]",
00524 finalResult,
00525 minTime1To2, averageTime1To2, maxTime1To2,
00526 minTime2To1, averageTime2To1, maxTime2To1,
00527 minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS,
00528 DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount);
00529
00530
00531 LatencyTestDisplay ltd(1, (int)finalResult);
00532 Device->SetDisplay(ltd);
00533 }
00534
00535 void LatencyTest::updateForTimeouts()
00536 {
00537 if (!HaveOldTime)
00538 {
00539 HaveOldTime = true;
00540 OldTime = Timer::GetTicksMs();
00541 return;
00542 }
00543
00544 UInt32 newTime = Timer::GetTicksMs();
00545 UInt32 elapsedMilliS = newTime - OldTime;
00546 if (newTime < OldTime)
00547 {
00548 elapsedMilliS = OldTime - newTime;
00549 elapsedMilliS = UINT_MAX - elapsedMilliS;
00550 }
00551 OldTime = newTime;
00552
00553 elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100);
00554
00555
00556 if (ActiveTimerMilliS == 0)
00557 {
00558 return;
00559 }
00560
00561 if (elapsedMilliS >= ActiveTimerMilliS)
00562 {
00563 ActiveTimerMilliS = 0;
00564 handleMessage(Message(), LatencyTest_Timer);
00565 return;
00566 }
00567
00568 ActiveTimerMilliS -= elapsedMilliS;
00569 }
00570
00571 }}