mirror of
https://github.com/mii443/rust-openvr.git
synced 2025-08-26 01:59:22 +00:00
added linux makefile
This commit is contained in:
570
modules/oculus_sdk_linux/LibOVR/Src/Util/Util_LatencyTest.cpp
Normal file
570
modules/oculus_sdk_linux/LibOVR/Src/Util/Util_LatencyTest.cpp
Normal file
@ -0,0 +1,570 @@
|
||||
/************************************************************************************
|
||||
|
||||
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
|
Reference in New Issue
Block a user