Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CAPI_HMDState.cpp
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : CAPI_HMDState.cpp
4 Content : State associated with a single HMD
5 Created : January 24, 2014
6 Authors : Michael Antonov
7 
8 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
9 
10 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
14 
15 You may obtain a copy of the License at
16 
17 http://www.oculusvr.com/licenses/LICENSE-3.1
18 
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24 
25 ************************************************************************************/
26 
27 #include "CAPI_HMDState.h"
28 #include "CAPI_GlobalState.h"
29 #include "../OVR_Profile.h"
30 
31 namespace OVR { namespace CAPI {
32 
33 //-------------------------------------------------------------------------------------
34 // ***** HMDState
35 
36 
38  : pHMD(device), HMDInfoW(device), HMDInfo(HMDInfoW.h),
39  EnabledHmdCaps(0), HmdCapsAppliedToSensor(0),
40  SensorStarted(0), SensorCreated(0), SensorCaps(0),
41  AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0),
42  RenderState(getThis(), pHMD->GetProfile(), HMDInfoW.h),
43  LastFrameTimeSeconds(0.0f), LastGetFrameTimeSeconds(0.0),
44  LatencyTestActive(false),
45  LatencyTest2Active(false)
46 {
47  pLastError = 0;
49 
50  // Should be in renderer?
52 
53  EyeRenderActive[0] = false;
54  EyeRenderActive[1] = false;
55 
56  LatencyTestDrawColor[0] = 0;
57  LatencyTestDrawColor[1] = 0;
58  LatencyTestDrawColor[2] = 0;
59 
60  OVR_CAPI_VISION_CODE( pPoseTracker = 0; )
61 
62  RenderingConfigured = false;
63  BeginFrameCalled = false;
65  BeginFrameTimingCalled = false;
66 }
67 
69  : pHMD(0), HMDInfoW(hmdType), HMDInfo(HMDInfoW.h),
70  EnabledHmdCaps(0),
71  SensorStarted(0), SensorCreated(0), SensorCaps(0),
72  AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0),
73  RenderState(getThis(), 0, HMDInfoW.h), // No profile.
74  LastFrameTimeSeconds(0.0), LastGetFrameTimeSeconds(0.0)
75 {
76  // TBD: We should probably be looking up the default profile for the given
77  // device type + user.
78 
79  pLastError = 0;
81 
82  // Should be in renderer?
84 
85  EyeRenderActive[0] = false;
86  EyeRenderActive[1] = false;
87 
88  OVR_CAPI_VISION_CODE( pPoseTracker = 0; )
89 
90  RenderingConfigured = false;
91  BeginFrameCalled = false;
93  BeginFrameTimingCalled = false;
94 }
95 
96 
98 {
100 
101  StopSensor();
102  ConfigureRendering(0,0,0,0);
103 
104  OVR_CAPI_VISION_CODE( OVR_ASSERT(pPoseTracker == 0); )
105 
106  GlobalState::pInstance->RemoveHMD(this);
107 }
108 
109 
110 
111 //-------------------------------------------------------------------------------------
112 // *** Sensor
113 
114 bool HMDState::StartSensor(unsigned supportedCaps, unsigned requiredCaps)
115 {
116  Lock::Locker lockScope(&DevicesLock);
117 
118  bool crystalCoveOrBetter = (HMDInfo.HmdType == HmdType_CrystalCoveProto) ||
120  bool sensorCreatedJustNow = false;
121 
122  // TBD: In case of sensor not being immediately available, it would be good to check
123  // yaw config availability to match it with ovrHmdCap_YawCorrection requirement.
124  //
125 
126  if (!crystalCoveOrBetter)
127  {
128  if (requiredCaps & ovrSensorCap_Position)
129  {
130  pLastError = "ovrSensorCap_Position not supported on this HMD.";
131  return false;
132  }
133  }
134 
135  supportedCaps |= requiredCaps;
136 
137  if (pHMD && !pSensor)
138  {
139  // Zero AddSensorCount before creation, in case it fails (or succeeds but then
140  // immediately gets disconnected) followed by another Add notification.
141  AddSensorCount = 0;
142  pSensor = *pHMD->GetSensor();
143  sensorCreatedJustNow= true;
144 
145  if (pSensor)
146  {
147  pSensor->SetReportRate(500);
150  }
151  else
152  {
153  if (requiredCaps & ovrSensorCap_Orientation)
154  {
155  pLastError = "Failed to create sensor.";
156  return false;
157  }
158  }
159  }
160 
161 
162  if ((requiredCaps & ovrSensorCap_YawCorrection) && !pSensor->IsMagCalibrated())
163  {
164  pLastError = "ovrHmdCap_YawCorrection not available.";
165  if (sensorCreatedJustNow)
166  {
168  SFusion.Reset();
169  pSensor.Clear();
170  }
171  return false;
172  }
173 
174  SFusion.SetYawCorrectionEnabled((supportedCaps & ovrSensorCap_YawCorrection) != 0);
175 
176  if (pSensor && sensorCreatedJustNow)
177  {
178  LogText("Sensor created.\n");
179  SensorCreated = true;
180  }
181 
182  updateDK2FeaturesTiedToSensor(sensorCreatedJustNow);
183 
184 
185 #ifdef OVR_CAPI_VISIONSUPPORT
186 
187  if (crystalCoveOrBetter && (supportedCaps & ovrSensorCap_Position))
188  {
189  if (!pPoseTracker)
190  {
191  pPoseTracker = new Vision::PoseTracker(SFusion);
192  if (pPoseTracker)
193  {
194  pPoseTracker->AssociateHMD(pSensor);
195  LogText("Sensor Pose tracker created.\n");
196  }
197  }
198 
199  // TBD: How do we verify that position tracking is actually available
200  // i.e. camera is plugged in?
201  }
202  else if (pPoseTracker)
203  {
204  // TBD: Internals not thread safe - must fix!!
205  delete pPoseTracker;
206  pPoseTracker = 0;
207  LogText("Sensor Pose tracker destroyed.\n");
208  }
209 
210 #endif // OVR_CAPI_VISIONSUPPORT
211 
212  SensorCaps = supportedCaps;
213  SensorStarted = true;
214 
215  return true;
216 }
217 
218 
219 // Stops sensor sampling, shutting down internal resources.
221 {
222  Lock::Locker lockScope(&DevicesLock);
223 
224  if (SensorStarted)
225  {
226 #ifdef OVR_CAPI_VISIONSUPPORT
227  if (pPoseTracker)
228  {
229  // TBD: Internals not thread safe - must fix!!
230  delete pPoseTracker;
231  pPoseTracker = 0;
232  LogText("Sensor Pose tracker destroyed.\n");
233  }
234 #endif // OVR_CAPI_VISION_CODE
235 
237  SFusion.Reset();
238  pSensor.Clear();
240  AddSensorCount = 0;
241  SensorCaps = 0;
242  SensorCreated = false;
243  SensorStarted = false;
244 
245  LogText("StopSensor succeeded.\n");
246  }
247 }
248 
249 // Resets sensor orientation.
251 {
252  SFusion.Reset();
253 }
254 
255 
256 // Returns prediction for time.
258 {
259  SensorState ss;
260 
261  // We are trying to keep this path lockless unless we are notified of new device
262  // creation while not having a sensor yet. It's ok to check SensorCreated volatile
263  // flag here, since GetSensorStateAtTime() is internally lockless and safe.
264 
266  {
267  ss = SFusion.GetSensorStateAtTime(absTime);
268 
270  {
271  Lock::Locker lockScope(&DevicesLock);
272 
273 #ifdef OVR_CAPI_VISIONSUPPORT
274  if (pPoseTracker)
275  {
276  // TBD: Internals not thread safe - must fix!!
277  delete pPoseTracker;
278  pPoseTracker = 0;
279  LogText("Sensor Pose tracker destroyed.\n");
280  }
281 #endif // OVR_CAPI_VISION_CODE
282  // Not needed yet; SFusion.AttachToSensor(0);
283  // This seems to reset orientation anyway...
284  pSensor.Clear();
285  SensorCreated = false;
287  }
288  }
289  else
290  {
291  // SensorState() defaults to 0s.
292  // ss.Pose.Orientation = Quatf();
293  // ..
294 
295  // John:
296  // We still want valid times so frames will get a delta-time
297  // and allow operation with a joypad when the sensor isn't
298  // connected.
299  ss.Recorded.TimeInSeconds = absTime;
300  ss.Predicted.TimeInSeconds = absTime;
301  }
302 
304  return ss;
305 }
306 
307 
309 {
311  return false;
312 
313  Lock::Locker lockScope(&DevicesLock);
314 
315  // Re-check condition once in the lock, in case the state changed.
317  {
318  if (pHMD)
319  {
320  AddSensorCount = 0;
321  pSensor = *pHMD->GetSensor();
322  }
323 
324  if (pSensor)
325  {
326  pSensor->SetReportRate(500);
330 
331 #ifdef OVR_CAPI_VISIONSUPPORT
333  {
334  pPoseTracker = new Vision::PoseTracker(SFusion);
335  if (pPoseTracker)
336  {
337  pPoseTracker->AssociateHMD(pSensor);
338  }
339  LogText("Sensor Pose tracker created.\n");
340  }
341 #endif // OVR_CAPI_VISION_CODE
342 
343  LogText("Sensor created.\n");
344 
345  SensorCreated = true;
346  return true;
347  }
348  }
349 
350  return SensorCreated;
351 }
352 
354 {
355  Lock::Locker lockScope(&DevicesLock);
356 
357  if (SensorCreated)
358  {
360  OVR::SensorInfo si;
361  pSensor->GetDeviceInfo(&si);
362  descOut->VendorId = si.VendorId;
363  descOut->ProductId = si.ProductId;
364  OVR_ASSERT(si.SerialNumber.GetSize() <= sizeof(descOut->SerialNumber));
365  OVR_strcpy(descOut->SerialNumber, sizeof(descOut->SerialNumber), si.SerialNumber.ToCStr());
366  return true;
367  }
368  return false;
369 }
370 
371 
373 {
374  if (!pHMD)
375  return;
376  Profile* profile = pHMD->GetProfile();
377  if (!profile)
378  {
379  OVR_ASSERT(false);
380  return;
381  }
383 }
384 
385 void HMDState::updateLowPersistenceMode(bool lowPersistence) const
386 {
388  DisplayReport dr;
389 
390  if (pSensor.GetPtr())
391  {
392  pSensor->GetDisplayReport(&dr);
393 
394  dr.Persistence = (UInt16) (dr.TotalRows * (lowPersistence ? 0.18f : 1.0f));
395  dr.Brightness = lowPersistence ? 255 : 0;
396 
397  pSensor->SetDisplayReport(dr);
398  }
399 }
400 
401 void HMDState::updateLatencyTestForHmd(bool latencyTesting)
402 {
403  if (pSensor.GetPtr())
404  {
405  DisplayReport dr;
406  pSensor->GetDisplayReport(&dr);
407 
408  dr.ReadPixel = latencyTesting;
409 
410  pSensor->SetDisplayReport(dr);
411  }
412 
413  if (latencyTesting)
414  {
416  }
417  else
418  {
420  }
421 }
422 
423 
424 void HMDState::updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow)
425 {
426  Lock::Locker lockScope(&DevicesLock);
427 
429  return;
430 
431  // Only send display reports if state changed or sensor initializing first time.
432  if (sensorCreatedJustNow ||
434  {
435  updateLowPersistenceMode((EnabledHmdCaps & ovrHmdCap_LowPersistence) ? true : false);
436  }
437 
438  if (sensorCreatedJustNow || ((HmdCapsAppliedToSensor ^ EnabledHmdCaps) & ovrHmdCap_LatencyTest))
439  {
440  updateLatencyTestForHmd((EnabledHmdCaps & ovrHmdCap_LatencyTest) != 0);
441  }
442 
443  HmdCapsAppliedToSensor = EnabledHmdCaps & (ovrHmdCap_LowPersistence|ovrHmdCap_LatencyTest);
444 }
445 
446 
447 
448 void HMDState::SetEnabledHmdCaps(unsigned hmdCaps)
449 {
450 
451  if (HMDInfo.HmdType == HmdType_DK2)
452  {
454  {
455  // DynamicPrediction change
457  (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false,
459  }
460  }
461 
462  if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoVSync)
463  {
464  TimeManager.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true);
465  }
466 
467 
470 
471  // Unfortunately, LowPersistance and other flags are tied to sensor.
472  // This flag will apply the state of sensor is created; otherwise this will be delayed
473  // till StartSensor.
474  // Such behavior is less then ideal, but should be resolved with the service model.
475 
477 }
478 
479 
480 //-------------------------------------------------------------------------------------
481 // ***** Property Access
482 
483 // TBD: This all needs to be cleaned up and organized into namespaces.
484 
485 float HMDState::getFloatValue(const char* propertyName, float defaultVal)
486 {
487  if (OVR_strcmp(propertyName, "LensSeparation") == 0)
488  {
490  }
491  else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
492  {
493  return SFusion.GetCenterPupilDepth();
494  }
495  else if (pHMD)
496  {
497  Profile* p = pHMD->GetProfile();
498  if (p)
499  {
500  return p->GetFloatValue(propertyName, defaultVal);
501  }
502  }
503  return defaultVal;
504 }
505 
506 bool HMDState::setFloatValue(const char* propertyName, float value)
507 {
508  if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
509  {
511  return true;
512  }
513  return false;
514 }
515 
516 
517 static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize,
518  float source[], unsigned sourceSize)
519 {
520  unsigned count = Alg::Min(destSize, sourceSize);
521  for (unsigned i = 0; i < count; i++)
522  dest[i] = source[i];
523  return count;
524 }
525 
526 
527 unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize)
528 {
529  if (arraySize)
530  {
531  if (OVR_strcmp(propertyName, "ScreenSize") == 0)
532  {
534 
535  return CopyFloatArrayWithLimit(values, arraySize, data, 2);
536  }
537  else if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
538  {
539  return CopyFloatArrayWithLimit(values, arraySize, RenderState.ClearColor, 4);
540  }
541  else if (OVR_strcmp(propertyName, "DK2Latency") == 0)
542  {
543  if (HMDInfo.HmdType != HmdType_DK2)
544  return 0;
545 
546  float data[3];
548 
549  return CopyFloatArrayWithLimit(values, arraySize, data, 3);
550  }
551 
552  /*
553  else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
554  {
555  if (arraySize >= 1)
556  {
557  values[0] = SFusion.GetCenterPupilDepth();
558  return 1;
559  }
560  return 0;
561  } */
562  else if (pHMD)
563  {
564  Profile* p = pHMD->GetProfile();
565 
566  // TBD: Not quite right. Should update profile interface, so that
567  // we can return 0 in all conditions if property doesn't exist.
568  if (p)
569  {
570  unsigned count = p->GetFloatValues(propertyName, values, arraySize);
571  return count;
572  }
573  }
574  }
575 
576  return 0;
577 }
578 
579 bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned arraySize)
580 {
581  if (!arraySize)
582  return false;
583 
584  if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
585  {
586  CopyFloatArrayWithLimit(RenderState.ClearColor, 4, values, arraySize);
587  return true;
588  }
589  return false;
590 }
591 
592 
593 const char* HMDState::getString(const char* propertyName, const char* defaultVal)
594 {
595  if (pHMD)
596  {
597  // For now, just access the profile.
598  Profile* p = pHMD->GetProfile();
599 
600  LastGetStringValue[0] = 0;
601  if (p && p->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue)))
602  {
603  return LastGetStringValue;
604  }
605  }
606 
607  return defaultVal;
608 }
609 
610 //-------------------------------------------------------------------------------------
611 // *** Latency Test
612 
613 bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3])
614 {
615  bool result = false;
616 
617  // Check create.
618  if (pLatencyTester)
619  {
620  if (pLatencyTester->IsConnected())
621  {
622  Color colorToDisplay;
623 
625  result = LatencyUtil.DisplayScreenColor(colorToDisplay);
626  rgbColorOut[0] = colorToDisplay.R;
627  rgbColorOut[1] = colorToDisplay.G;
628  rgbColorOut[2] = colorToDisplay.B;
629  }
630  else
631  {
632  // Disconnect.
634  pLatencyTester = 0;
635  LogText("LATENCY SENSOR disconnected.\n");
636  }
637  }
638  else if (AddLatencyTestCount > 0)
639  {
640  // This might have some unlikely race condition issue which could cause us to miss a device...
642 
643  pLatencyTester = *GlobalState::pInstance->GetManager()->
644  EnumerateDevices<LatencyTestDevice>().CreateDevice();
645  if (pLatencyTester)
646  {
647  LatencyUtil.SetDevice(pLatencyTester);
648  LogText("LATENCY TESTER connected\n");
649  }
650  }
651 
652  return result;
653 }
654 
655 void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime)
656 {
657  // Check create.
659  return;
660 
662  {
663  if (!pLatencyTesterDisplay->IsConnected())
664  {
666  }
667  }
668  else if (AddLatencyTestDisplayCount > 0)
669  {
670  // This might have some unlikely race condition issue
671  // which could cause us to miss a device...
673 
675  EnumerateDevices<LatencyTestDevice>().CreateDevice();
677  {
679  }
680  }
681 
682  if (LatencyUtil2.HasDevice() && pSensor && pSensor->IsConnected())
683  {
684  LatencyUtil2.BeginTest(startTime);
685 
686  Color colorToDisplay;
688  rgbColorOut[0] = colorToDisplay.R;
689  rgbColorOut[1] = colorToDisplay.G;
690  rgbColorOut[2] = colorToDisplay.B;
691  }
692  else
693  {
694  LatencyTest2Active = false;
695  }
696 }
697 
698 //-------------------------------------------------------------------------------------
699 // *** Rendering
700 
702  const ovrFovPort eyeFovIn[2],
703  const ovrRenderAPIConfig* apiConfig,
704  unsigned distortionCaps)
705 {
706  ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_ConfigureRendering");
707 
708  // null -> shut down.
709  if (!apiConfig)
710  {
711  if (pRenderer)
712  pRenderer.Clear();
713  RenderingConfigured = false;
714  return true;
715  }
716 
717  if (pRenderer &&
718  (apiConfig->Header.API != pRenderer->GetRenderAPI()))
719  {
720  // Shutdown old renderer.
721  if (pRenderer)
722  pRenderer.Clear();
723  }
724 
725 
726  // Step 1: do basic setup configuration
727  RenderState.setupRenderDesc(eyeRenderDescOut, eyeFovIn);
728  RenderState.EnabledHmdCaps = EnabledHmdCaps; // This is a copy... Any cleaner way?
729  RenderState.DistortionCaps = distortionCaps;
730 
732  (EnabledHmdCaps & ovrHmdCap_DynamicPrediction) ? true : false,
733  true);
734 
735  LastFrameTimeSeconds = 0.0f;
736 
737  // Set RenderingConfigured early to avoid ASSERTs in renderer initialization.
738  RenderingConfigured = true;
739 
740  if (!pRenderer)
741  {
743  [apiConfig->Header.API](this, TimeManager, RenderState);
744  }
745 
746  if (!pRenderer ||
747  !pRenderer->Initialize(apiConfig, distortionCaps))
748  {
749  RenderingConfigured = false;
750  return false;
751  }
752 
753  return true;
754 }
755 
756 
757 
759 {
760  // Debug checks.
761  checkBeginFrameScope("ovrHmd_BeginEyeRender");
762  ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_BeginEyeRender");
763 
764  // Unknown eyeId provided in ovrHmd_BeginEyeRender
765  OVR_ASSERT_LOG(eye == ovrEye_Left || eye == ovrEye_Right,
766  ("ovrHmd_BeginEyeRender eyeId out of range."));
767  OVR_ASSERT_LOG(EyeRenderActive[eye] == false,
768  ("Multiple calls to ovrHmd_BeginEyeRender for the same eye."));
769 
770  EyeRenderActive[eye] = true;
771 
772  // Only process latency tester for drawing the left eye (assumes left eye is drawn first)
773  if (pRenderer && eye == 0)
774  {
776  }
777 
778  return ovrHmd_GetEyePose(this, eye);
779 }
780 
781 
782 void HMDState::EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture)
783 {
784  // Debug checks.
785  checkBeginFrameScope("ovrHmd_EndEyeRender");
786  ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_EndEyeRender");
787 
788  if (!EyeRenderActive[eye])
789  {
790  OVR_ASSERT_LOG(false,
791  ("ovrHmd_EndEyeRender called without ovrHmd_BeginEyeRender."));
792  return;
793  }
794 
795  RenderState.EyeRenderPoses[eye] = renderPose;
796 
797  if (pRenderer)
798  pRenderer->SubmitEye(eye, eyeTexture);
799 
800  EyeRenderActive[eye] = false;
801 }
802 
803 }} // namespace OVR::CAPI
804 
SensorState GetSensorStateAtTime(double absoluteTime) const
void GetLatencyTimings(float latencies[3])
float GetCenterPupilDepth() const
void LogText(const char *fmt,...) OVR_LOG_VAARG_ATTRIBUTE(1
void SetCenterPupilDepth(float centerPupilDepth)
volatile bool SensorStarted
const char * GetValue(const char *key)
ovrHmdType
Definition: OVR_CAPI.h:113
Ptr< HMDDevice > pHMD
#define OVR_ASSERT_LOG(c, args)
Definition: OVR_Log.h:198
Size< float > ScreenSizeInMeters
Definition: OVR_Device.h:325
float GetFloatValue(const char *key, float default_val) const
Timing GetFrameTiming(unsigned frameIndex)
ovrRenderAPIType API
Definition: OVR_CAPI.h:356
#define NULL
SensorFusion SFusion
UByte R
Definition: OVR_Color.h:36
ThreadChecker RenderAPIThreadChecker
bool DisplayScreenColor(Color &colorToDisplay)
short VendorId
Definition: OVR_CAPI.h:273
uint16_t UInt16
Definition: OVR_Types.h:251
UByte G
Definition: OVR_Color.h:36
bool AttachToSensor(SensorDevice *sensor)
AtomicInt< int > AddLatencyTestCount
bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], const ovrFovPort eyeFovIn[2], const ovrRenderAPIConfig *apiConfig, unsigned distortionCaps)
HMDRenderState RenderState
void Init(HmdRenderInfo &renderInfo)
OVR_EXPORT ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye)
Definition: OVR_CAPI.cpp:621
bool ProcessLatencyTest(unsigned char rgbColorOut[3])
void updateLatencyTestForHmd(bool latencyTesting)
void BeginTest(double startTime=-1.0f)
unsigned int StatusFlags
char SerialNumber[24]
Definition: OVR_CAPI.h:276
char *OVR_CDECL OVR_strcpy(char *dest, UPInt destsize, const char *src)
Definition: OVR_Std.h:148
UByte B
Definition: OVR_Color.h:36
ovrEyeType
Definition: OVR_CAPI.h:177
void AddHMD(HMDState *hmd)
unsigned char LatencyTestDrawColor[3]
OVR_CAPI_VISION_CODE(Vision::PoseTracker *pPoseTracker;) Ptr< LatencyTestDevice > pLatencyTester
const char * ToCStr() const
Definition: OVR_String.h:186
unsigned getFloatArray(const char *propertyName, float values[], unsigned arraySize)
float LensSeparationInMeters
Definition: OVR_Device.h:328
bool StartSensor(unsigned supportedCaps, unsigned requiredCaps)
bool setFloatArray(const char *propertyName, float values[], unsigned arraySize)
ThreadId BeginFrameThreadId
void updateDK2FeaturesTiedToSensor(bool sensorCreatedJustNow)
String SerialNumber
Definition: OVR_Device.h:489
AtomicInt< int > AddLatencyTestDisplayCount
#define OVR_ASSERT(p)
void updateLowPersistenceMode(bool lowPersistence) const
void setupRenderDesc(ovrEyeRenderDesc eyeRenderDescOut[2], const ovrFovPort eyeFovIn[2])
void SetEnabledHmdCaps(unsigned caps)
DeviceManager * GetManager()
char LastGetStringValue[256]
Ptr< LatencyTestDevice > pLatencyTesterDisplay
const char * getString(const char *propertyName, const char *defaultVal)
int GetFloatValues(const char *key, float *values, int num_vals) const
unsigned HmdCapsAppliedToSensor
int OVR_CDECL OVR_strcmp(const char *dest, const char *src)
Definition: OVR_Std.h:181
void SetYawCorrectionEnabled(bool enable)
HMDState(HMDDevice *device)
ovrRenderAPIConfigHeader Header
Definition: OVR_CAPI.h:363
Ptr< SensorDevice > pSensor
bool DisplayScreenColor(Color &colorToDisplay)
ovrPosef BeginEyeRender(ovrEyeType eye)
bool SetDevice(LatencyTestDevice *device)
HmdTypeEnum HmdType
Definition: OVR_Device.h:323
Ptr< DistortionRenderer > pRenderer
void SetUserHeadDimensions(Profile const &profile, HmdRenderInfo const &hmdRenderInfo)
void checkBeginFrameScope(const char *functionName)
Util::LatencyTest LatencyUtil
void ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime)
UPInt GetSize() const
Definition: OVR_String.h:189
void ResetFrameTiming(unsigned frameIndex, bool dynamicPrediction, bool sdkRender)
Util::LatencyTest2 LatencyUtil2
bool SetDisplayDevice(LatencyTestDevice *device)
OVR_FORCE_INLINE const T Min(const T a, const T b)
Definition: OVR_Alg.h:46
AtomicInt< int > AddSensorCount
void EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture *eyeTexture)
FrameTimeManager TimeManager
static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, float source[], unsigned sourceSize)
volatile bool SensorCreated
bool SetSensorDevice(SensorDevice *device)
static GlobalState * pInstance
short ProductId
Definition: OVR_CAPI.h:274
bool setFloatValue(const char *propertyName, float value)
bool GetSensorDesc(ovrSensorDesc *descOut)
ovrSensorState PredictedSensorState(double absTime)
static CreateFunc APICreateRegistry[ovrRenderAPI_Count]
UInt16 ProductId
Definition: OVR_Device.h:485
const char * pLastError
float getFloatValue(const char *propertyName, float defaultVal)