diff options
Diffstat (limited to 'LibOVR/Src/Util/Util_LatencyTest.cpp')
-rw-r--r-- | LibOVR/Src/Util/Util_LatencyTest.cpp | 570 |
1 files changed, 0 insertions, 570 deletions
diff --git a/LibOVR/Src/Util/Util_LatencyTest.cpp b/LibOVR/Src/Util/Util_LatencyTest.cpp deleted file mode 100644 index 3017c72..0000000 --- a/LibOVR/Src/Util/Util_LatencyTest.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/************************************************************************************ - -Filename : Util_LatencyTest.cpp -Content : Wraps the lower level LatencyTester interface and adds functionality. -Created : February 14, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.1 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "Util_LatencyTest.h" - -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Timer.h" - -namespace OVR { namespace Util { - -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5; -static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5; -static const UInt32 DEFAULT_NUMBER_OF_SAMPLES = 10; // For both color 1->2 and color 2->1 transitions. -static const UInt32 INITIAL_SAMPLES_TO_IGNORE = 4; -static const UInt32 TIMEOUT_WAITING_FOR_TEST_STARTED = 1000; -static const UInt32 TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000; -static const Color CALIBRATE_BLACK(0, 0, 0); -static const Color CALIBRATE_WHITE(255, 255, 255); -static const Color COLOR1(0, 0, 0); -static const Color COLOR2(255, 255, 255); -static const Color SENSOR_DETECT_THRESHOLD(128, 255, 255); -static const float BIG_FLOAT = 1000000.0f; -static const float SMALL_FLOAT = -1000000.0f; - -//------------------------------------------------------------------------------------- -// ***** LatencyTest - -LatencyTest::LatencyTest(LatencyTestDevice* device) - : Handler(getThis()) -{ - if (device != NULL) - { - SetDevice(device); - } - - reset(); - - srand(Timer::GetTicksMs()); -} - -LatencyTest::~LatencyTest() -{ - clearMeasurementResults(); -} - -bool LatencyTest::SetDevice(LatencyTestDevice* device) -{ - - if (device != Device) - { - Handler.RemoveHandlerFromDevices(); - - Device = device; - - if (Device != NULL) - { - Device->AddMessageHandler(&Handler); - - // Set trigger threshold. - LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false); // No samples streaming. - Device->SetConfiguration(configuration, true); - - // Set display to initial (3 dashes). - LatencyTestDisplay ltd(2, 0x40400040); - Device->SetDisplay(ltd); - } - } - - return true; -} - -UInt32 LatencyTest::getRandomComponent(UInt32 range) -{ - UInt32 val = rand() % range; - return val; -} - -void LatencyTest::BeginTest() -{ - if (State == State_WaitingForButton) - { - // Set color to black and wait a while. - RenderColor = CALIBRATE_BLACK; - - State = State_WaitingForSettlePreCalibrationColorBlack; - OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION); - } -} - -void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage) -{ - // For debugging. -/* if (msg.Type == Message_LatencyTestSamples) - { - MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg; - - if (pSamples->Samples.GetSize() > 0) - { - // Just show the first one for now. - Color c = pSamples->Samples[0]; - OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B)); - } - return; - } -*/ - - if (latencyTestMessage == LatencyTest_Timer) - { - if (!Device) - { - reset(); - return; - } - - if (State == State_WaitingForSettlePreCalibrationColorBlack) - { - // Send calibrate message to device and wait a while. - Device->SetCalibrate(CALIBRATE_BLACK); - - State = State_WaitingForSettlePostCalibrationColorBlack; - OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION); - } - else if (State == State_WaitingForSettlePostCalibrationColorBlack) - { - // Change color to white and wait a while. - RenderColor = CALIBRATE_WHITE; - - State = State_WaitingForSettlePreCalibrationColorWhite; - OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION); - } - else if (State == State_WaitingForSettlePreCalibrationColorWhite) - { - // Send calibrate message to device and wait a while. - Device->SetCalibrate(CALIBRATE_WHITE); - - State = State_WaitingForSettlePostCalibrationColorWhite; - OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite.")); - - setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION); - } - else if (State == State_WaitingForSettlePostCalibrationColorWhite) - { - // Calibration is done. Switch to color 1 and wait for it to settle. - RenderColor = COLOR1; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - else if (State == State_WaitingForSettlePostMeasurement) - { - // Prepare for next measurement. - - // Create a new result object. - MeasurementResult* pResult = new MeasurementResult(); - Results.PushBack(pResult); - - State = State_WaitingToTakeMeasurement; - OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement.")); - } - else if (State == State_WaitingForTestStarted) - { - // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next. - getActiveResult()->TimedOutWaitingForTestStarted = true; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'.")); - OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - else if (State == State_WaitingForColorDetected) - { - // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next. - getActiveResult()->TimedOutWaitingForColorDetected = true; - - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'.")); - OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - } - } - else if (latencyTestMessage == LatencyTest_ProcessInputs) - { - if (State == State_WaitingToTakeMeasurement) - { - if (!Device) - { - reset(); - return; - } - - // Send 'StartTest' feature report with opposite target color. - if (RenderColor == COLOR1) - { - RenderColor = COLOR2; - } - else - { - RenderColor = COLOR1; - } - - getActiveResult()->TargetColor = RenderColor; - - // Record time so we can determine usb roundtrip time. - getActiveResult()->StartTestSeconds = Timer::GetSeconds(); - - Device->SetStartTest(RenderColor); - - State = State_WaitingForTestStarted; - OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted.")); - - setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED); - - LatencyTestDisplay ltd(2, 0x40090040); - Device->SetDisplay(ltd); - } - } - else if (msg.Type == Message_LatencyTestButton) - { - BeginTest(); - } - else if (msg.Type == Message_LatencyTestStarted) - { - if (State == State_WaitingForTestStarted) - { - clearTimer(); - - // Record time so we can determine usb roundtrip time. - getActiveResult()->TestStartedSeconds = Timer::GetSeconds(); - - State = State_WaitingForColorDetected; - OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected.")); - - setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED); - } - } - else if (msg.Type == Message_LatencyTestColorDetected) - { - if (State == State_WaitingForColorDetected) - { - // Record time to detect color. - MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg; - UInt16 elapsedTime = pDetected->Elapsed; - OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime)); - - getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime; - - if (areResultsComplete()) - { - // We're done. - processResults(); - reset(); - } - else - { - // Run another measurement. - State = State_WaitingForSettlePostMeasurement; - OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement.")); - - UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS); - setTimer(waitTime); - - LatencyTestDisplay ltd(2, 0x40400040); - Device->SetDisplay(ltd); - } - } - } - else if (msg.Type == Message_DeviceRemoved) - { - reset(); - } -} - -LatencyTest::MeasurementResult* LatencyTest::getActiveResult() -{ - OVR_ASSERT(!Results.IsEmpty()); - return Results.GetLast(); -} - -void LatencyTest::setTimer(UInt32 timeMilliS) -{ - ActiveTimerMilliS = timeMilliS; -} - -void LatencyTest::clearTimer() -{ - ActiveTimerMilliS = 0; -} - -void LatencyTest::reset() -{ - clearMeasurementResults(); - State = State_WaitingForButton; - - HaveOldTime = false; - ActiveTimerMilliS = 0; -} - -void LatencyTest::clearMeasurementResults() -{ - while(!Results.IsEmpty()) - { - MeasurementResult* pElem = Results.GetFirst(); - pElem->RemoveNode(); - delete pElem; - } -} - -LatencyTest::LatencyTestHandler::~LatencyTestHandler() -{ - RemoveHandlerFromDevices(); -} - -void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg) -{ - pLatencyTestUtil->handleMessage(msg); -} - -void LatencyTest::ProcessInputs() -{ - updateForTimeouts(); - handleMessage(Message(), LatencyTest_ProcessInputs); -} - -bool LatencyTest::DisplayScreenColor(Color& colorToDisplay) -{ - updateForTimeouts(); - - if (State == State_WaitingForButton) - { - return false; - } - - colorToDisplay = RenderColor; - return true; -} - -const char* LatencyTest::GetResultsString() -{ - if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr()) - { - ReturnedResultString = ResultsString; - return ReturnedResultString.ToCStr(); - } - - return NULL; -} - -bool LatencyTest::areResultsComplete() -{ - UInt32 initialMeasurements = 0; - - UInt32 measurements1to2 = 0; - UInt32 measurements2to1 = 0; - - MeasurementResult* pCurr = Results.GetFirst(); - while(true) - { - // Process. - if (!pCurr->TimedOutWaitingForTestStarted && - !pCurr->TimedOutWaitingForColorDetected) - { - initialMeasurements++; - - if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE) - { - if (pCurr->TargetColor == COLOR2) - { - measurements1to2++; - } - else - { - measurements2to1++; - } - } - } - - if (Results.IsLast(pCurr)) - { - break; - } - pCurr = Results.GetNext(pCurr); - } - - if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES && - measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES) - { - return true; - } - - return false; -} - -void LatencyTest::processResults() -{ - - UInt32 minTime1To2 = UINT_MAX; - UInt32 maxTime1To2 = 0; - float averageTime1To2 = 0.0f; - UInt32 minTime2To1 = UINT_MAX; - UInt32 maxTime2To1 = 0; - float averageTime2To1 = 0.0f; - - float minUSBTripMilliS = BIG_FLOAT; - float maxUSBTripMilliS = SMALL_FLOAT; - float averageUSBTripMilliS = 0.0f; - UInt32 countUSBTripTime = 0; - - UInt32 measurementsCount = 0; - UInt32 measurements1to2 = 0; - UInt32 measurements2to1 = 0; - - MeasurementResult* pCurr = Results.GetFirst(); - UInt32 count = 0; - while(true) - { - count++; - - if (!pCurr->TimedOutWaitingForTestStarted && - !pCurr->TimedOutWaitingForColorDetected) - { - measurementsCount++; - - if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE) - { - if (pCurr->TargetColor == COLOR2) - { - measurements1to2++; - - if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES) - { - UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS; - - minTime1To2 = Alg::Min(elapsed, minTime1To2); - maxTime1To2 = Alg::Max(elapsed, maxTime1To2); - - averageTime1To2 += (float) elapsed; - } - } - else - { - measurements2to1++; - - if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES) - { - UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS; - - minTime2To1 = Alg::Min(elapsed, minTime2To1); - maxTime2To1 = Alg::Max(elapsed, maxTime2To1); - - averageTime2To1 += (float) elapsed; - } - } - - float usbRountripElapsedMilliS = Timer::MsPerSecond * (float) (pCurr->TestStartedSeconds - pCurr->StartTestSeconds); - minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS); - maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS); - averageUSBTripMilliS += usbRountripElapsedMilliS; - countUSBTripTime++; - } - } - - if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES && - measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES) - { - break; - } - - if (Results.IsLast(pCurr)) - { - break; - } - pCurr = Results.GetNext(pCurr); - } - - averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES; - averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES; - - averageUSBTripMilliS /= countUSBTripTime; - - float finalResult = 0.5f * (averageTime1To2 + averageTime2To1); - finalResult += averageUSBTripMilliS; - - ResultsString.Clear(); - 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]", - finalResult, - minTime1To2, averageTime1To2, maxTime1To2, - minTime2To1, averageTime2To1, maxTime2To1, - minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS, - DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount); - - // Display result on latency tester display. - LatencyTestDisplay ltd(1, (int)finalResult); - Device->SetDisplay(ltd); -} - -void LatencyTest::updateForTimeouts() -{ - if (!HaveOldTime) - { - HaveOldTime = true; - OldTime = Timer::GetTicksMs(); - return; - } - - UInt32 newTime = Timer::GetTicksMs(); - UInt32 elapsedMilliS = newTime - OldTime; - if (newTime < OldTime) - { - elapsedMilliS = OldTime - newTime; - elapsedMilliS = UINT_MAX - elapsedMilliS; - } - OldTime = newTime; - - elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100); // Clamp at 100mS in case we're not being called very often. - - - if (ActiveTimerMilliS == 0) - { - return; - } - - if (elapsedMilliS >= ActiveTimerMilliS) - { - ActiveTimerMilliS = 0; - handleMessage(Message(), LatencyTest_Timer); - return; - } - - ActiveTimerMilliS -= elapsedMilliS; -} - -}} // namespace OVR::Util |