00001 /************************************************************************************ 00002 00003 PublicHeader: OVR.h 00004 Filename : OVR_Device.h 00005 Content : Definition of HMD-related Device interfaces 00006 Created : September 21, 2012 00007 Authors : Michael Antonov 00008 00009 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 00010 00011 Use of this software is subject to the terms of the Oculus license 00012 agreement provided at the time of installation or download, or which 00013 otherwise accompanies this software in either electronic or hard copy form. 00014 00015 *************************************************************************************/ 00016 00017 #ifndef OVR_Device_h 00018 #define OVR_Device_h 00019 00020 #include "OVR_DeviceConstants.h" 00021 #include "OVR_DeviceHandle.h" 00022 #include "OVR_DeviceMessages.h" 00023 #include "OVR_HIDDeviceBase.h" 00024 00025 #include "Kernel/OVR_Atomic.h" 00026 #include "Kernel/OVR_RefCount.h" 00027 #include "Kernel/OVR_String.h" 00028 00029 namespace OVR { 00030 00031 // Declared externally 00032 class Profile; 00033 class ProfileManager; // << Should be renamed for consistency 00034 00035 // Forward declarations 00036 class SensorDevice; 00037 class DeviceCommon; 00038 class DeviceManager; 00039 00040 // MessageHandler is a base class from which users derive to receive messages, 00041 // its OnMessage handler will be called for messages once it is installed on 00042 // a device. Same message handler can be installed on multiple devices. 00043 class MessageHandler 00044 { 00045 friend class MessageHandlerImpl; 00046 public: 00047 MessageHandler(); 00048 virtual ~MessageHandler(); 00049 00050 // Returns 'true' if handler is currently installed on any devices. 00051 bool IsHandlerInstalled() const; 00052 00053 // Should be called from derived class destructor to avoid handler 00054 // being called after it exits. 00055 void RemoveHandlerFromDevices(); 00056 00057 // Returns a pointer to the internal lock object that is locked by a 00058 // background thread while OnMessage() is called. 00059 // This lock guaranteed to survive until ~MessageHandler. 00060 Lock* GetHandlerLock() const; 00061 00062 00063 virtual void OnMessage(const Message&) { } 00064 00065 // Determines if handler supports a specific message type. Can 00066 // be used to filter out entire message groups. The result 00067 // returned by this function shouldn't change after handler creation. 00068 virtual bool SupportsMessageType(MessageType) const { return true; } 00069 00070 private: 00071 UPInt Internal[4]; 00072 }; 00073 00074 00075 //------------------------------------------------------------------------------------- 00076 // ***** DeviceBase 00077 00078 // DeviceBase is the base class for all OVR Devices. It provides the following basic 00079 // functionality: 00080 // - Reports device type, manager, and associated parent (if any). 00081 // - Supports installable message handlers, which are notified of device events. 00082 // - Device objects are created through DeviceHandle::CreateDevice or more commonly 00083 // through DeviceEnumerator<>::CreateDevice. 00084 // - Created devices are reference counted, starting with RefCount of 1. 00085 // - Device is resources are cleaned up when it is Released, although its handles 00086 // may survive longer if referenced. 00087 00088 class DeviceBase : public NewOverrideBase 00089 { 00090 friend class DeviceHandle; 00091 friend class DeviceManagerImpl; 00092 public: 00093 00094 // Enumerating DeviceBase enumerates all devices. 00095 enum { EnumDeviceType = Device_All }; 00096 00097 virtual ~DeviceBase() { } 00098 virtual void AddRef(); 00099 virtual void Release(); 00100 00101 virtual DeviceBase* GetParent() const; 00102 virtual DeviceManager* GetManager() const; 00103 00104 virtual void SetMessageHandler(MessageHandler* handler); 00105 virtual MessageHandler* GetMessageHandler() const; 00106 00107 virtual DeviceType GetType() const; 00108 virtual bool GetDeviceInfo(DeviceInfo* info) const; 00109 00110 // returns the MessageHandler's lock 00111 Lock* GetHandlerLock() const; 00112 protected: 00113 // Internal 00114 virtual DeviceCommon* getDeviceCommon() const = 0; 00115 }; 00116 00117 00118 //------------------------------------------------------------------------------------- 00119 // ***** DeviceInfo 00120 00121 // DeviceInfo describes a device and its capabilities, obtained by calling 00122 // GetDeviceInfo. This base class only contains device-independent functionality; 00123 // users will normally use a derived HMDInfo or SensorInfo classes for more 00124 // extensive device info. 00125 00126 class DeviceInfo 00127 { 00128 public: 00129 DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0) 00130 { ProductName[0] = Manufacturer[0] = 0; } 00131 00132 enum { MaxNameLength = 32 }; 00133 00134 // Type of device for which DeviceInfo is intended. 00135 // This will be set to Device_HMD for HMDInfo structure, note that this may be 00136 // different form the actual device type since (Device_None) is valid. 00137 const DeviceType InfoClassType; 00138 // Type of device this describes. This must be the same as InfoClassType when 00139 // InfoClassType != Device_None. 00140 DeviceType Type; 00141 // Name string describing the product: "Oculus Rift DK1", etc. 00142 char ProductName[MaxNameLength]; 00143 char Manufacturer[MaxNameLength]; 00144 unsigned Version; 00145 00146 protected: 00147 DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0) 00148 { ProductName[0] = Manufacturer[0] = 0; } 00149 void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed. 00150 }; 00151 00152 00153 //------------------------------------------------------------------------------------- 00154 // DeviceEnumerationArgs provides device enumeration argumenrs for DeviceManager::EnumerateDevicesEx. 00155 class DeviceEnumerationArgs 00156 { 00157 public: 00158 DeviceEnumerationArgs(DeviceType enumType, bool availableOnly) 00159 : EnumType(enumType), AvailableOnly(availableOnly) 00160 { } 00161 00162 // Helper; returns true if args match our enumeration criteria. 00163 bool MatchRule(DeviceType type, bool available) const 00164 { 00165 return ((EnumType == type) || (EnumType == Device_All)) && 00166 (available || !AvailableOnly); 00167 } 00168 00169 protected: 00170 DeviceType EnumType; 00171 bool AvailableOnly; 00172 }; 00173 00174 00175 // DeviceEnumerator<> is used to enumerate and create devices of specified class, 00176 // it is returned by calling MeviceManager::EnumerateDevices. Initially, the enumerator will 00177 // refer to the first device of specified type. Additional devices can be accessed by 00178 // calling Next(). 00179 00180 template<class T = DeviceBase> 00181 class DeviceEnumerator : public DeviceHandle 00182 { 00183 friend class DeviceManager; 00184 friend class DeviceManagerImpl; 00185 public: 00186 DeviceEnumerator() 00187 : DeviceHandle(), EnumArgs(Device_None, true) { } 00188 00189 // Next advances enumeration to the next device that first criteria. 00190 // Returns false if no more devices exist that match enumeration criteria. 00191 bool Next() { return enumerateNext(EnumArgs); } 00192 00193 // Creates an instance of the device referenced by enumerator; returns null 00194 // if enumerator does not refer to a valid device or device is unavailable. 00195 // If device was already created, the same object with incremented ref-count is returned. 00196 T* CreateDevice() { return static_cast<T*>(DeviceHandle::CreateDevice()); } 00197 00198 protected: 00199 DeviceEnumerator(const DeviceHandle &dev, const DeviceEnumerationArgs& args) 00200 : DeviceHandle(dev), EnumArgs(args) 00201 { } 00202 00203 DeviceEnumerationArgs EnumArgs; 00204 }; 00205 00206 //------------------------------------------------------------------------------------- 00207 // ***** DeviceManager 00208 00209 // DeviceManager maintains and provides access to devices supported by OVR, such as 00210 // HMDs and sensors. A single instance of DeviceManager is normally created at 00211 // program startup, allowing devices to be enumerated and created. DeviceManager is 00212 // reference counted and is AddRefed by its created child devices, causing it to 00213 // always be the last object that is released. 00214 // 00215 // Install MessageHandler on DeviceManager to detect when devices are inserted or removed. 00216 // 00217 // The following code will create the manager and its first available HMDDevice, 00218 // and then release it when not needed: 00219 // 00220 // DeviceManager* manager = DeviceManager::Create(); 00221 // HMDDevice* hmd = manager->EnumerateDevices<HMDDevice>().CreateDevice(); 00222 // 00223 // if (hmd) hmd->Release(); 00224 // if (manager) manager->Release(); 00225 00226 00227 class DeviceManager : public DeviceBase 00228 { 00229 public: 00230 00231 DeviceManager() 00232 { } 00233 00234 // DeviceBase implementation. 00235 virtual DeviceType GetType() const { return Device_Manager; } 00236 virtual DeviceManager* GetManager() const { return const_cast<DeviceManager*>(this); } 00237 00238 // Every DeviceManager has an associated profile manager, which us used to store 00239 // user settings that may affect device behavior. 00240 virtual ProfileManager* GetProfileManager() const = 0; 00241 00242 00243 // EnumerateDevices enumerates all of the available devices of the specified class, 00244 // returning an enumerator that references the first device. An empty enumerator is 00245 // returned if no devices are available. The following APIs are exposed through 00246 // DeviceEnumerator: 00247 // DeviceEnumerator::GetType() - Check device type. Returns Device_None 00248 // if no device was found/pointed to. 00249 // DeviceEnumerator::GetDeviceInfo() - Get more information on device. 00250 // DeviceEnumerator::CreateDevice() - Create an instance of device. 00251 // DeviceEnumerator::Next() - Move onto next device. 00252 template<class D> 00253 DeviceEnumerator<D> EnumerateDevices(bool availableOnly = true) 00254 { 00255 // TBD: A cleaner (but less efficient) alternative is though enumeratorFromHandle. 00256 DeviceEnumerator<> e = EnumerateDevicesEx(DeviceEnumerationArgs((DeviceType)D::EnumDeviceType, availableOnly)); 00257 return *reinterpret_cast<DeviceEnumerator<D>*>(&e); 00258 } 00259 00260 // EnumerateDevicesEx provides internal implementation for device enumeration, enumerating 00261 // devices based on dynamically specified DeviceType in DeviceEnumerationArgs. 00262 // End users should call DeumerateDevices<>() instead. 00263 virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args) = 0; 00264 00265 // Creates a new DeviceManager. Only one instance of DeviceManager should be created at a time. 00266 static DeviceManager* Create(); 00267 00268 // Static constant for this device type, used in template cast type checks. 00269 enum { EnumDeviceType = Device_Manager }; 00270 00271 00272 00273 // Adds a device (DeviceCreateDesc*) into Devices. Returns NULL, 00274 // if unsuccessful or device is already in the list. 00275 virtual Ptr<DeviceCreateDesc> AddDevice_NeedsLock(const DeviceCreateDesc& createDesc) = 0; 00276 00277 protected: 00278 DeviceEnumerator<> enumeratorFromHandle(const DeviceHandle& h, const DeviceEnumerationArgs& args) 00279 { return DeviceEnumerator<>(h, args); } 00280 00281 DeviceManager* getThis() { return this; } 00282 }; 00283 00284 00285 00286 //------------------------------------------------------------------------------------- 00287 // ***** HMDInfo 00288 00289 // This structure describes various aspects of the HMD allowing us to configure rendering. 00290 // 00291 // Currently included data: 00292 // - Physical screen dimensions, resolution, and eye distances. 00293 // (some of these will be configurable with a tool in the future). 00294 // These arguments allow us to properly setup projection across HMDs. 00295 // - DisplayDeviceName for identifying HMD screen; system-specific interpretation. 00296 // 00297 // TBD: 00298 // - Power on/ off? 00299 // - Sensor rates and capabilities 00300 // - Distortion radius/variables 00301 // - Screen update frequency 00302 // - Distortion needed flag 00303 // - Update modes: 00304 // Set update mode: Stereo (both sides together), mono (same in both eyes), 00305 // Alternating, Alternating scan-lines. 00306 00307 class HMDInfo : public DeviceInfo 00308 { 00309 public: 00310 // Size of the entire screen, in pixels. 00311 unsigned HResolution, VResolution; 00312 // Physical dimensions of the active screen in meters. Can be used to calculate 00313 // projection center while considering IPD. 00314 float HScreenSize, VScreenSize; 00315 // Physical offset from the top of the screen to the eye center, in meters. 00316 // This will usually, but not necessarily be half of VScreenSize. 00317 float VScreenCenter; 00318 // Distance from the eye to screen surface, in meters. 00319 // Useful for calculating FOV and projection. 00320 float EyeToScreenDistance; 00321 // Distance between physical lens centers useful for calculating distortion center. 00322 float LensSeparationDistance; 00323 // Configured distance between the user's eye centers, in meters. Defaults to 0.064. 00324 float InterpupillaryDistance; 00325 00326 // Radial distortion correction coefficients. 00327 // The distortion assumes that the input texture coordinates will be scaled 00328 // by the following equation: 00329 // uvResult = uvInput * (K0 + K1 * uvLength^2 + K2 * uvLength^4) 00330 // Where uvInput is the UV vector from the center of distortion in direction 00331 // of the mapped pixel, uvLength is the magnitude of that vector, and uvResult 00332 // the corresponding location after distortion. 00333 float DistortionK[4]; 00334 00335 float ChromaAbCorrection[4]; 00336 00337 // Desktop coordinate position of the screen (can be negative; may not be present on all platforms) 00338 int DesktopX, DesktopY; 00339 00340 // Windows: 00341 // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. 00342 char DisplayDeviceName[32]; 00343 00344 // MacOS: 00345 long DisplayId; 00346 00347 00348 HMDInfo() 00349 : DeviceInfo(Device_HMD), 00350 HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0), 00351 VScreenCenter(0), EyeToScreenDistance(0), 00352 LensSeparationDistance(0), InterpupillaryDistance(0), 00353 DesktopX(0), DesktopY(0), DisplayId(0) 00354 { 00355 DisplayDeviceName[0] = 0; 00356 memset(DistortionK, 0, sizeof(DistortionK)); 00357 DistortionK[0] = 1; 00358 ChromaAbCorrection[0] = ChromaAbCorrection[2] = 1; 00359 ChromaAbCorrection[1] = ChromaAbCorrection[3] = 0; 00360 } 00361 00362 // Operator = copies local fields only (base class must be correct already) 00363 void operator = (const HMDInfo& src) 00364 { 00365 HResolution = src.HResolution; 00366 VResolution = src.VResolution; 00367 HScreenSize = src.HScreenSize; 00368 VScreenSize = src.VScreenSize; 00369 VScreenCenter = src.VScreenCenter; 00370 EyeToScreenDistance = src.EyeToScreenDistance; 00371 LensSeparationDistance = src.LensSeparationDistance; 00372 InterpupillaryDistance = src.InterpupillaryDistance; 00373 DistortionK[0] = src.DistortionK[0]; 00374 DistortionK[1] = src.DistortionK[1]; 00375 DistortionK[2] = src.DistortionK[2]; 00376 DistortionK[3] = src.DistortionK[3]; 00377 ChromaAbCorrection[0] = src.ChromaAbCorrection[0]; 00378 ChromaAbCorrection[1] = src.ChromaAbCorrection[1]; 00379 ChromaAbCorrection[2] = src.ChromaAbCorrection[2]; 00380 ChromaAbCorrection[3] = src.ChromaAbCorrection[3]; 00381 DesktopX = src.DesktopX; 00382 DesktopY = src.DesktopY; 00383 memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName)); 00384 DisplayId = src.DisplayId; 00385 } 00386 00387 bool IsSameDisplay(const HMDInfo& o) const 00388 { 00389 return DisplayId == o.DisplayId && 00390 String::CompareNoCase(DisplayDeviceName, 00391 o.DisplayDeviceName) == 0; 00392 } 00393 00394 }; 00395 00396 00397 // HMDDevice represents an Oculus HMD device unit. An instance of this class 00398 // is typically created from the DeviceManager. 00399 // After HMD device is created, we its sensor data can be obtained by 00400 // first creating a Sensor object and then. 00401 00402 // TBD: 00403 // - Configure Sensor 00404 // - APIs to set On-Screen message, other states? 00405 00406 class HMDDevice : public DeviceBase 00407 { 00408 public: 00409 HMDDevice() 00410 { } 00411 00412 // Static constant for this device type, used in template cast type checks. 00413 enum { EnumDeviceType = Device_HMD }; 00414 00415 virtual DeviceType GetType() const { return Device_HMD; } 00416 00417 // Creates a sensor associated with this HMD. 00418 virtual SensorDevice* GetSensor() = 0; 00419 00420 00421 // Requests the currently used profile. This profile affects the 00422 // settings reported by HMDInfo. 00423 virtual Profile* GetProfile() const = 0; 00424 // Obtains the currently used profile name. This is initialized to the default 00425 // profile name, if any; it can then be changed per-device by SetProfileName. 00426 virtual const char* GetProfileName() const = 0; 00427 // Sets the profile user name, changing the data returned by GetProfileInfo. 00428 virtual bool SetProfileName(const char* name) = 0; 00429 00430 00431 // Disconnects from real HMD device. This HMDDevice remains as 'fake' HMD. 00432 // SensorDevice ptr is used to restore the 'fake' HMD (can be NULL). 00433 HMDDevice* Disconnect(SensorDevice*); 00434 00435 // Returns 'true' if HMD device is a 'fake' HMD (was created this way or 00436 // 'Disconnect' method was called). 00437 bool IsDisconnected() const; 00438 }; 00439 00440 00441 //------------------------------------------------------------------------------------- 00442 // ***** SensorRange & SensorInfo 00443 00444 // SensorRange specifies maximum value ranges that SensorDevice hardware is configured 00445 // to detect. Although this range doesn't affect the scale of MessageBodyFrame values, 00446 // physical motions whose positive or negative magnitude is outside the specified range 00447 // may get clamped or misreported. Setting lower values may result in higher precision 00448 // tracking. 00449 struct SensorRange 00450 { 00451 SensorRange(float maxAcceleration = 0.0f, float maxRotationRate = 0.0f, 00452 float maxMagneticField = 0.0f) 00453 : MaxAcceleration(maxAcceleration), MaxRotationRate(maxRotationRate), 00454 MaxMagneticField(maxMagneticField) 00455 { } 00456 00457 // Maximum detected acceleration in m/s^2. Up to 8*G equivalent support guaranteed, 00458 // where G is ~9.81 m/s^2. 00459 // Oculus DK1 HW has thresholds near: 2, 4 (default), 8, 16 G. 00460 float MaxAcceleration; 00461 // Maximum detected angular velocity in rad/s. Up to 8*Pi support guaranteed. 00462 // Oculus DK1 HW thresholds near: 1, 2, 4, 8 Pi (default). 00463 float MaxRotationRate; 00464 // Maximum detectable Magnetic field strength in Gauss. Up to 2.5 Gauss support guaranteed. 00465 // Oculus DK1 HW thresholds near: 0.88, 1.3, 1.9, 2.5 gauss. 00466 float MaxMagneticField; 00467 }; 00468 00469 // SensorInfo describes capabilities of the sensor device. 00470 class SensorInfo : public DeviceInfo 00471 { 00472 public: 00473 SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0) 00474 { 00475 SerialNumber[0] = 0; 00476 } 00477 00478 // HID Vendor and ProductId of the device. 00479 UInt16 VendorId; 00480 UInt16 ProductId; 00481 // MaxRanges report maximum sensor range values supported by HW. 00482 SensorRange MaxRanges; 00483 // Sensor (and display) serial number. 00484 char SerialNumber[20]; 00485 00486 private: 00487 void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed. 00488 }; 00489 00490 00491 //------------------------------------------------------------------------------------- 00492 // ***** SensorDevice 00493 00494 // SensorDevice is an interface to sensor data. 00495 // Install a MessageHandler of SensorDevice instance to receive MessageBodyFrame 00496 // notifications. 00497 // 00498 // TBD: Add Polling API? More HID interfaces? 00499 00500 class SensorDevice : public HIDDeviceBase, public DeviceBase 00501 { 00502 public: 00503 SensorDevice() 00504 { } 00505 00506 // Static constant for this device type, used in template cast type checks. 00507 enum { EnumDeviceType = Device_Sensor }; 00508 00509 virtual DeviceType GetType() const { return Device_Sensor; } 00510 00511 00512 // CoordinateFrame defines whether messages come in the coordinate frame 00513 // of the sensor device or HMD, which has a different internal sensor. 00514 // Sensors obtained form the HMD will automatically use HMD coordinates. 00515 enum CoordinateFrame 00516 { 00517 Coord_Sensor = 0, 00518 Coord_HMD = 1 00519 }; 00520 00521 virtual void SetCoordinateFrame(CoordinateFrame coordframe) = 0; 00522 virtual CoordinateFrame GetCoordinateFrame() const = 0; 00523 00524 // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call). 00525 // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be 00526 // called twice or thrice at the same 'tick'. 00527 // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three 00528 // times for each 'tick': the first call will contain averaged values, the second 00529 // and third calls will provide with most recent two recorded samples. 00530 virtual void SetReportRate(unsigned rateHz) = 0; 00531 // Returns currently set report rate, in Hz. If 0 - error occurred. 00532 // Note, this value may be different from the one provided for SetReportRate. The return 00533 // value will contain the actual rate. 00534 virtual unsigned GetReportRate() const = 0; 00535 00536 // Sets maximum range settings for the sensor described by SensorRange. 00537 // The function will fail if you try to pass values outside Maximum supported 00538 // by the HW, as described by SensorInfo. 00539 // Pass waitFlag == true to wait for command completion. For waitFlag == true, 00540 // returns true if the range was applied successfully (no HW error). 00541 // For waitFlag = false, return 'true' means that command was enqueued successfully. 00542 virtual bool SetRange(const SensorRange& range, bool waitFlag = false) = 0; 00543 00544 // Return the current sensor range settings for the device. These may not exactly 00545 // match the values applied through SetRange. 00546 virtual void GetRange(SensorRange* range) const = 0; 00547 }; 00548 00549 //------------------------------------------------------------------------------------- 00550 // ***** LatencyTestConfiguration 00551 // LatencyTestConfiguration specifies configuration information for the Oculus Latency Tester device. 00552 struct LatencyTestConfiguration 00553 { 00554 LatencyTestConfiguration(const Color& threshold, bool sendSamples = false) 00555 : Threshold(threshold), SendSamples(sendSamples) 00556 { 00557 } 00558 00559 // The color threshold for triggering a detected display change. 00560 Color Threshold; 00561 // Flag specifying whether we wish to receive a stream of color values from the sensor. 00562 bool SendSamples; 00563 }; 00564 00565 //------------------------------------------------------------------------------------- 00566 // ***** LatencyTestDisplay 00567 // LatencyTestDisplay sets the mode and contents of the Latency Tester LED display. 00568 // See the 'Latency Tester Specification' document for more details. 00569 struct LatencyTestDisplay 00570 { 00571 LatencyTestDisplay(UByte mode, UInt32 value) 00572 : Mode(mode), Value(value) 00573 { 00574 } 00575 00576 UByte Mode; // The display mode that we wish to select. 00577 UInt32 Value; // The value to display. 00578 }; 00579 00580 //------------------------------------------------------------------------------------- 00581 // ***** LatencyTestDevice 00582 00583 // LatencyTestDevice provides an interface to the Oculus Latency Tester which is used to test 'motion to photon' latency. 00584 class LatencyTestDevice : public HIDDeviceBase, public DeviceBase 00585 { 00586 public: 00587 LatencyTestDevice() 00588 { } 00589 00590 // Static constant for this device type, used in template cast type checks. 00591 enum { EnumDeviceType = Device_LatencyTester }; 00592 00593 virtual DeviceType GetType() const { return Device_LatencyTester; } 00594 00595 // Specifies configuration information including the threshold for triggering a detected color change, 00596 // and a flag to enable a stream of sensor values (typically used for debugging). 00597 virtual bool SetConfiguration(const LatencyTestConfiguration& configuration, bool waitFlag = false) = 0; 00598 00599 // Get configuration information from device. 00600 virtual bool GetConfiguration(LatencyTestConfiguration* configuration) = 0; 00601 00602 // Used to calibrate the latency tester at the start of a test. Display the specified color on the screen 00603 // beneath the latency tester and then call this method. Calibration information is lost 00604 // when power is removed from the device. 00605 virtual bool SetCalibrate(const Color& calibrationColor, bool waitFlag = false) = 0; 00606 00607 // Triggers the start of a measurement. This starts the millisecond timer on the device and 00608 // causes it to respond with the 'MessageLatencyTestStarted' message. 00609 virtual bool SetStartTest(const Color& targetColor, bool waitFlag = false) = 0; 00610 00611 // Used to set the value displayed on the LED display panel. 00612 virtual bool SetDisplay(const LatencyTestDisplay& display, bool waitFlag = false) = 0; 00613 00614 virtual DeviceBase* GetDevice() { return this; } 00615 }; 00616 00617 } // namespace OVR 00618 00619 #endif