Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_LatencyTestImpl.cpp
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : OVR_LatencyTestImpl.cpp
4 Content : Oculus Latency Tester device implementation.
5 Created : March 7, 2013
6 Authors : Lee Cooper
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 "OVR_LatencyTestImpl.h"
28 #include "Kernel/OVR_Alg.h"
29 
30 namespace OVR {
31 
32 using namespace Alg;
33 
34 //-------------------------------------------------------------------------------------
35 // ***** Oculus Latency Tester specific packet data structures
36 
37 enum {
40 };
41 
42 static void UnpackSamples(const UByte* buffer, UByte* r, UByte* g, UByte* b)
43 {
44  *r = buffer[0];
45  *g = buffer[1];
46  *b = buffer[2];
47 }
48 
49 // Messages we handle.
51 {
59 };
60 
62 {
63  UByte Value[3];
64 };
65 
67 {
70 
71  LatencyTestSample Samples[20];
72 
73  LatencyTestMessageType Decode(const UByte* buffer, int size)
74  {
75  if (size < 64)
76  {
78  }
79 
80  SampleCount = buffer[1];
81  Timestamp = DecodeUInt16(buffer + 2);
82 
83  for (UByte i = 0; i < SampleCount; i++)
84  {
85  UnpackSamples(buffer + 4 + (3 * i), &Samples[i].Value[0], &Samples[i].Value[1], &Samples[i].Value[2]);
86  }
87 
89  }
90 };
91 
93 {
96 };
97 
99 {
100  memset(message, 0, sizeof(LatencyTestSamplesMessage));
101 
102  if (size < 64)
103  {
105  return false;
106  }
107 
108  switch (buffer[0])
109  {
111  message->Type = message->Samples.Decode(buffer, size);
112  break;
113 
114  default:
115  message->Type = LatencyTestMessage_Unknown;
116  break;
117  }
118 
119  return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
120 }
121 
123 {
127  UByte TriggerValue[3];
128  UByte TargetValue[3];
129 
130  LatencyTestMessageType Decode(const UByte* buffer, int size)
131  {
132  if (size < 13)
134 
135  CommandID = DecodeUInt16(buffer + 1);
136  Timestamp = DecodeUInt16(buffer + 3);
137  Elapsed = DecodeUInt16(buffer + 5);
138  memcpy(TriggerValue, buffer + 7, 3);
139  memcpy(TargetValue, buffer + 10, 3);
140 
142  }
143 };
144 
146 {
149 };
150 
152 {
153  memset(message, 0, sizeof(LatencyTestColorDetectedMessage));
154 
155  if (size < 13)
156  {
158  return false;
159  }
160 
161  switch (buffer[0])
162  {
164  message->Type = message->ColorDetected.Decode(buffer, size);
165  break;
166 
167  default:
168  message->Type = LatencyTestMessage_Unknown;
169  break;
170  }
171 
172  return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
173 }
174 
176 {
179  UByte TargetValue[3];
180 
181  LatencyTestMessageType Decode(const UByte* buffer, int size)
182  {
183  if (size < 8)
185 
186  CommandID = DecodeUInt16(buffer + 1);
187  Timestamp = DecodeUInt16(buffer + 3);
188  memcpy(TargetValue, buffer + 5, 3);
189 
191  }
192 };
193 
195 {
198 };
199 
201 {
202  memset(message, 0, sizeof(LatencyTestStartedMessage));
203 
204  if (size < 8)
205  {
207  return false;
208  }
209 
210  switch (buffer[0])
211  {
213  message->Type = message->TestStarted.Decode(buffer, size);
214  break;
215 
216  default:
217  message->Type = LatencyTestMessage_Unknown;
218  break;
219  }
220 
221  return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
222 }
223 
225 {
228 
229  LatencyTestMessageType Decode(const UByte* buffer, int size)
230  {
231  if (size < 5)
233 
234  CommandID = DecodeUInt16(buffer + 1);
235  Timestamp = DecodeUInt16(buffer + 3);
236 
238  }
239 };
240 
242 {
245 };
246 
248 {
249  memset(message, 0, sizeof(LatencyTestButtonMessage));
250 
251  if (size < 5)
252  {
254  return false;
255  }
256 
257  switch (buffer[0])
258  {
260  message->Type = message->Button.Decode(buffer, size);
261  break;
262 
263  default:
264  message->Type = LatencyTestMessage_Unknown;
265  break;
266  }
267 
268  return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
269 }
270 
272 {
273  enum { PacketSize = 5 };
274  UByte Buffer[PacketSize];
275 
277 
279  : Configuration(configuration)
280  {
281  Pack();
282  }
283 
284  void Pack()
285  {
286  Buffer[0] = 5;
287  Buffer[1] = UByte(Configuration.SendSamples);
288  Buffer[2] = Configuration.Threshold.R;
289  Buffer[3] = Configuration.Threshold.G;
290  Buffer[4] = Configuration.Threshold.B;
291  }
292 
293  void Unpack()
294  {
295  Configuration.SendSamples = Buffer[1] != 0 ? true : false;
296  Configuration.Threshold.R = Buffer[2];
297  Configuration.Threshold.G = Buffer[3];
298  Configuration.Threshold.B = Buffer[4];
299  }
300 };
301 
303 {
304  enum { PacketSize = 4 };
305  UByte Buffer[PacketSize];
306 
308 
309  LatencyTestCalibrateImpl(const Color& calibrationColor)
310  : CalibrationColor(calibrationColor)
311  {
312  Pack();
313  }
314 
315  void Pack()
316  {
317  Buffer[0] = 7;
318  Buffer[1] = CalibrationColor.R;
319  Buffer[2] = CalibrationColor.G;
320  Buffer[3] = CalibrationColor.B;
321  }
322 
323  void Unpack()
324  {
325  CalibrationColor.R = Buffer[1];
326  CalibrationColor.G = Buffer[2];
327  CalibrationColor.B = Buffer[3];
328  }
329 };
330 
332 {
333  enum { PacketSize = 6 };
334  UByte Buffer[PacketSize];
335 
337 
338  LatencyTestStartTestImpl(const Color& targetColor)
339  : TargetColor(targetColor)
340  {
341  Pack();
342  }
343 
344  void Pack()
345  {
346  UInt16 commandID = 1;
347 
348  Buffer[0] = 8;
349  EncodeUInt16(Buffer+1, commandID);
350  Buffer[3] = TargetColor.R;
351  Buffer[4] = TargetColor.G;
352  Buffer[5] = TargetColor.B;
353  }
354 
355  void Unpack()
356  {
357 // UInt16 commandID = DecodeUInt16(Buffer+1);
358  TargetColor.R = Buffer[3];
359  TargetColor.G = Buffer[4];
360  TargetColor.B = Buffer[5];
361  }
362 };
363 
365 {
366  enum { PacketSize = 6 };
367  UByte Buffer[PacketSize];
368 
370 
372  : Display(display)
373  {
374  Pack();
375  }
376 
377  void Pack()
378  {
379  Buffer[0] = 9;
380  Buffer[1] = Display.Mode;
381  EncodeUInt32(Buffer+2, Display.Value);
382  }
383 
384  void Unpack()
385  {
386  Display.Mode = Buffer[1];
387  Display.Value = DecodeUInt32(Buffer+2);
388  }
389 };
390 
391 //-------------------------------------------------------------------------------------
392 // ***** LatencyTestDeviceFactory
393 
395 {
396  static LatencyTestDeviceFactory instance;
397  return instance;
398 }
399 
401 {
402 
403  class LatencyTestEnumerator : public HIDEnumerateVisitor
404  {
405  // Assign not supported; suppress MSVC warning.
406  void operator = (const LatencyTestEnumerator&) { }
407 
408  DeviceFactory* pFactory;
409  EnumerateVisitor& ExternalVisitor;
410  public:
411  LatencyTestEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor)
412  : pFactory(factory), ExternalVisitor(externalVisitor) { }
413 
414  virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId)
415  {
416  return pFactory->MatchVendorProduct(vendorId, productId);
417  }
418 
419  virtual void Visit(HIDDevice& device, const HIDDeviceDesc& desc)
420  {
421  OVR_UNUSED(device);
422 
423  LatencyTestDeviceCreateDesc createDesc(pFactory, desc);
424  ExternalVisitor.Visit(createDesc);
425  }
426  };
427 
428  LatencyTestEnumerator latencyTestEnumerator(this, visitor);
429  GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&latencyTestEnumerator);
430 }
431 
433 {
434  return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId));
435 }
436 
438  const HIDDeviceDesc& desc)
439 {
440  if (MatchVendorProduct(desc.VendorId, desc.ProductId))
441  {
442  LatencyTestDeviceCreateDesc createDesc(this, desc);
443  return pdevMgr->AddDevice_NeedsLock(createDesc).GetPtr() != NULL;
444  }
445  return false;
446 }
447 
448 //-------------------------------------------------------------------------------------
449 // ***** LatencyTestDeviceCreateDesc
450 
452 {
453  return new LatencyTestDeviceImpl(this);
454 }
455 
457 {
458  if ((info->InfoClassType != Device_LatencyTester) &&
459  (info->InfoClassType != Device_None))
460  return false;
461 
462  info->Type = Device_LatencyTester;
463  info->ProductName = HIDDesc.Product;
464  info->Manufacturer = HIDDesc.Manufacturer;
465  info->Version = HIDDesc.VersionNumber;
466 
467  if (info->InfoClassType == Device_LatencyTester)
468  {
469  SensorInfo* sinfo = (SensorInfo*)info;
470  sinfo->VendorId = HIDDesc.VendorId;
471  sinfo->ProductId = HIDDesc.ProductId;
472  sinfo->SerialNumber = HIDDesc.SerialNumber;
473  }
474  return true;
475 }
476 
477 //-------------------------------------------------------------------------------------
478 // ***** LatencyTestDevice
479 
481  : OVR::HIDDeviceImpl<OVR::LatencyTestDevice>(createDesc, 0)
482 {
483 }
484 
486 {
487  // Check that Shutdown() was called.
488  OVR_ASSERT(!pCreateDesc->pDevice);
489 }
490 
491 // Internal creation APIs.
493 {
495  {
496  LogText("OVR::LatencyTestDevice initialized.\n");
497  return true;
498  }
499 
500  return false;
501 }
502 
504 {
506 
507  LogText("OVR::LatencyTestDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr());
508 }
509 
511 {
512 
513  bool processed = false;
514  if (!processed)
515  {
516  LatencyTestSamplesMessage message;
517  if (DecodeLatencyTestSamplesMessage(&message, pData, length))
518  {
519  processed = true;
520  onLatencyTestSamplesMessage(&message);
521  }
522  }
523 
524  if (!processed)
525  {
527  if (DecodeLatencyTestColorDetectedMessage(&message, pData, length))
528  {
529  processed = true;
531  }
532  }
533 
534  if (!processed)
535  {
536  LatencyTestStartedMessage message;
537  if (DecodeLatencyTestStartedMessage(&message, pData, length))
538  {
539  processed = true;
540  onLatencyTestStartedMessage(&message);
541  }
542  }
543 
544  if (!processed)
545  {
546  LatencyTestButtonMessage message;
547  if (DecodeLatencyTestButtonMessage(&message, pData, length))
548  {
549  processed = true;
550  onLatencyTestButtonMessage(&message);
551  }
552  }
553 }
554 
556 {
557  bool result = false;
559 
560  if (GetManagerImpl()->GetThreadId() != OVR::GetCurrentThreadId())
561  {
562  if (!waitFlag)
563  {
564  return queue->PushCall(this, &LatencyTestDeviceImpl::setConfiguration, configuration);
565  }
566 
567  if (!queue->PushCallAndWaitResult( this,
569  &result,
570  configuration))
571  {
572  return false;
573  }
574  }
575  else
576  return setConfiguration(configuration);
577 
578  return result;
579 }
580 
582 {
583  LatencyTestConfigurationImpl ltc(configuration);
585 }
586 
588 {
589  bool result = false;
590 
591  ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
592  if (!pQueue->PushCallAndWaitResult(this, &LatencyTestDeviceImpl::getConfiguration, &result, configuration))
593  return false;
594 
595  return result;
596 }
597 
599 {
600  LatencyTestConfigurationImpl ltc(*configuration);
602  {
603  ltc.Unpack();
604  *configuration = ltc.Configuration;
605  return true;
606  }
607 
608  return false;
609 }
610 
611 bool LatencyTestDeviceImpl::SetCalibrate(const Color& calibrationColor, bool waitFlag)
612 {
613  bool result = false;
615 
616  if (!waitFlag)
617  {
618  return queue->PushCall(this, &LatencyTestDeviceImpl::setCalibrate, calibrationColor);
619  }
620 
621  if (!queue->PushCallAndWaitResult( this,
623  &result,
624  calibrationColor))
625  {
626  return false;
627  }
628 
629  return result;
630 }
631 
632 bool LatencyTestDeviceImpl::setCalibrate(const Color& calibrationColor)
633 {
634  LatencyTestCalibrateImpl ltc(calibrationColor);
636 }
637 
638 bool LatencyTestDeviceImpl::SetStartTest(const Color& targetColor, bool waitFlag)
639 {
640  bool result = false;
642 
643  if (!waitFlag)
644  {
645  return queue->PushCall(this, &LatencyTestDeviceImpl::setStartTest, targetColor);
646  }
647 
648  if (!queue->PushCallAndWaitResult( this,
650  &result,
651  targetColor))
652  {
653  return false;
654  }
655 
656  return result;
657 }
658 
660 {
661  LatencyTestStartTestImpl ltst(targetColor);
663 }
664 
666 {
667  bool result = false;
669 
670  if (!waitFlag)
671  {
672  return queue->PushCall(this, &LatencyTestDeviceImpl::setDisplay, display);
673  }
674 
675  if (!queue->PushCallAndWaitResult( this,
677  &result,
678  display))
679  {
680  return false;
681  }
682 
683  return result;
684 }
685 
687 {
688  LatencyTestDisplayImpl ltd(display);
690 }
691 
693 {
694 
695  if (message->Type != LatencyTestMessage_Samples)
696  return;
697 
698  LatencyTestSamples& s = message->Samples;
699 
700  // Call OnMessage() within a lock to avoid conflicts with handlers.
701  Lock::Locker scopeLock(HandlerRef.GetLock());
702 
703  if (HandlerRef.HasHandlers())
704  {
705  MessageLatencyTestSamples samples(this);
706  for (UByte i = 0; i < s.SampleCount; i++)
707  {
708  samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2]));
709  }
710 
711  HandlerRef.Call(samples);
712  }
713 }
714 
716 {
717  if (message->Type != LatencyTestMessage_ColorDetected)
718  return;
719 
721 
722  // Call OnMessage() within a lock to avoid conflicts with handlers.
723  Lock::Locker scopeLock(HandlerRef.GetLock());
724 
725  if (HandlerRef.HasHandlers())
726  {
727  MessageLatencyTestColorDetected detected(this);
728  detected.Elapsed = s.Elapsed;
729  detected.DetectedValue = Color(s.TriggerValue[0], s.TriggerValue[1], s.TriggerValue[2]);
730  detected.TargetValue = Color(s.TargetValue[0], s.TargetValue[1], s.TargetValue[2]);
731 
732  HandlerRef.Call(detected);
733  }
734 }
735 
737 {
738  if (message->Type != LatencyTestMessage_TestStarted)
739  return;
740 
741  LatencyTestStarted& ts = message->TestStarted;
742 
743  // Call OnMessage() within a lock to avoid conflicts with handlers.
744  Lock::Locker scopeLock(HandlerRef.GetLock());
745 
746  if (HandlerRef.HasHandlers())
747  {
748  MessageLatencyTestStarted started(this);
749  started.TargetValue = Color(ts.TargetValue[0], ts.TargetValue[1], ts.TargetValue[2]);
750 
751  HandlerRef.Call(started);
752  }
753 }
754 
756 {
757  if (message->Type != LatencyTestMessage_Button)
758  return;
759 
760 // LatencyTestButton& s = message->Button;
761 
762  // Call OnMessage() within a lock to avoid conflicts with handlers.
763  Lock::Locker scopeLock(HandlerRef.GetLock());
764 
765  if (HandlerRef.HasHandlers())
766  {
767  MessageLatencyTestButton button(this);
768 
769  HandlerRef.Call(button);
770  }
771 }
772 
773 } // namespace OVR
DeviceType Type
Definition: OVR_Device.h:152
bool PushCall(R(C::*fn)(), bool wait=false)
void LogText(const char *fmt,...) OVR_LOG_VAARG_ATTRIBUTE(1
virtual bool SetCalibrate(const Color &calibrationColor, bool waitFlag=false)
void onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage *message)
virtual DeviceBase * NewDeviceInstance()
const DeviceType InfoClassType
Definition: OVR_Device.h:149
OVR::LatencyTestConfiguration Configuration
void EncodeUInt32(UByte *buffer, UInt32 val)
Definition: OVR_Alg.h:1027
bool setCalibrate(const Color &calibrationColor)
bool setConfiguration(const OVR::LatencyTestConfiguration &configuration)
LatencyTestStartTestImpl(const Color &targetColor)
virtual bool DetectHIDDevice(DeviceManager *pdevMgr, const HIDDeviceDesc &desc)
#define NULL
virtual void EnumerateDevices(EnumerateVisitor &visitor)
void onLatencyTestStartedMessage(LatencyTestStartedMessage *message)
__BEGIN_NAMESPACE_STD void * memcpy(void *__restrict __dest, const void *__restrict __src, size_t __n) __THROW __nonnull((1
void EncodeUInt16(UByte *buffer, UInt16 val)
Definition: OVR_Alg.h:1017
virtual ThreadCommandQueue * GetThreadQueue()=0
static LatencyTestDeviceFactory & GetInstance()
Ptr< DeviceCreateDesc > pCreateDesc
unsigned Version
Definition: OVR_Device.h:156
uint16_t UInt16
Definition: OVR_Types.h:251
void onLatencyTestSamplesMessage(LatencyTestSamplesMessage *message)
UInt32 DecodeUInt32(const UByte *buffer)
Definition: OVR_Alg.h:996
uint32_t UInt32
Definition: OVR_Types.h:253
bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage *message, UByte *buffer, int size)
LatencyTestMessageType Decode(const UByte *buffer, int size)
bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage *message, UByte *buffer, int size)
#define OVR_UNUSED(a)
UInt16 DecodeUInt16(const UByte *buffer)
Definition: OVR_Alg.h:986
bool setDisplay(const OVR::LatencyTestDisplay &display)
void onLatencyTestButtonMessage(LatencyTestButtonMessage *message)
uint8_t UByte
Definition: OVR_Types.h:249
bool HasHandlers() const
LatencyTestMessageType Decode(const UByte *buffer, int size)
virtual bool SetStartTest(const Color &targetColor, bool waitFlag=false)
LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc *createDesc)
virtual bool GetDeviceInfo(DeviceInfo *info) const
virtual bool SetDisplay(const LatencyTestDisplay &display, bool waitFlag=false)
virtual void Shutdown()
String ProductName
Definition: OVR_Device.h:154
String SerialNumber
Definition: OVR_Device.h:489
Lock * GetLock() const
#define OVR_ASSERT(p)
bool getConfiguration(OVR::LatencyTestConfiguration *configuration)
bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage *message, UByte *buffer, int size)
LatencyTestSample Samples[20]
virtual void OnInputReport(UByte *pData, UInt32 length)
MessageHandlerRef HandlerRef
bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage *message, UByte *buffer, int size)
LatencyTestMessageType Decode(const UByte *buffer, int size)
bool GetFeatureReport(UByte *data, UInt32 length)
DeviceManagerImpl * GetManagerImpl() const
virtual Ptr< DeviceCreateDesc > AddDevice_NeedsLock(const DeviceCreateDesc &createDesc)=0
virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
bool setStartTest(const Color &targetColor)
virtual bool GetConfiguration(OVR::LatencyTestConfiguration *configuration)
__BEGIN_NAMESPACE_STD void void __END_NAMESPACE_STD void __BEGIN_NAMESPACE_STD void * memset(void *__s, int __c, size_t __n) __THROW __nonnull((1))
LatencyTestMessageType Decode(const UByte *buffer, int size)
String Manufacturer
Definition: OVR_Device.h:155
virtual bool SetFeatureReport(UByte *data, UInt32 length)=0
virtual bool SetConfiguration(const OVR::LatencyTestConfiguration &configuration, bool waitFlag=false)
LatencyTestDisplayImpl(const OVR::LatencyTestDisplay &display)
LatencyTestCalibrateImpl(const Color &calibrationColor)
virtual bool Initialize(DeviceBase *parent)
static void UnpackSamples(const UByte *buffer, UByte *r, UByte *g, UByte *b)
void Call(const Message &msg)
LatencyTestConfigurationImpl(const OVR::LatencyTestConfiguration &configuration)
ThreadId GetCurrentThreadId()
OVR::LatencyTestDisplay Display
UInt16 ProductId
Definition: OVR_Device.h:485
bool PushCallAndWaitResult(R(C::*fn)(), R *ret)