rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 Filename : OVR_LatencyTestImpl.cpp
|
nuclear@1
|
4 Content : Oculus Latency Tester device implementation.
|
nuclear@1
|
5 Created : March 7, 2013
|
nuclear@1
|
6 Authors : Lee Cooper
|
nuclear@1
|
7
|
nuclear@1
|
8 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
9
|
nuclear@1
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
11 agreement provided at the time of installation or download, or which
|
nuclear@1
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
13
|
nuclear@1
|
14 *************************************************************************************/
|
nuclear@1
|
15
|
nuclear@1
|
16 #include "OVR_LatencyTestImpl.h"
|
nuclear@1
|
17
|
nuclear@1
|
18 namespace OVR {
|
nuclear@1
|
19
|
nuclear@1
|
20 //-------------------------------------------------------------------------------------
|
nuclear@1
|
21 // ***** Oculus Latency Tester specific packet data structures
|
nuclear@1
|
22
|
nuclear@1
|
23 enum {
|
nuclear@1
|
24 LatencyTester_VendorId = Oculus_VendorId,
|
nuclear@1
|
25 LatencyTester_ProductId = 0x0101,
|
nuclear@1
|
26 };
|
nuclear@1
|
27
|
nuclear@1
|
28 // Reported data is little-endian now
|
nuclear@1
|
29 static UInt16 DecodeUInt16(const UByte* buffer)
|
nuclear@1
|
30 {
|
nuclear@1
|
31 return (UInt16(buffer[1]) << 8) | UInt16(buffer[0]);
|
nuclear@1
|
32 }
|
nuclear@1
|
33
|
nuclear@1
|
34 /* Unreferenced
|
nuclear@1
|
35 static SInt16 DecodeSInt16(const UByte* buffer)
|
nuclear@1
|
36 {
|
nuclear@1
|
37 return (SInt16(buffer[1]) << 8) | SInt16(buffer[0]);
|
nuclear@1
|
38 }*/
|
nuclear@1
|
39
|
nuclear@1
|
40 static void UnpackSamples(const UByte* buffer, UByte* r, UByte* g, UByte* b)
|
nuclear@1
|
41 {
|
nuclear@1
|
42 *r = buffer[0];
|
nuclear@1
|
43 *g = buffer[1];
|
nuclear@1
|
44 *b = buffer[2];
|
nuclear@1
|
45 }
|
nuclear@1
|
46
|
nuclear@1
|
47 // Messages we handle.
|
nuclear@1
|
48 enum LatencyTestMessageType
|
nuclear@1
|
49 {
|
nuclear@1
|
50 LatencyTestMessage_None = 0,
|
nuclear@1
|
51 LatencyTestMessage_Samples = 1,
|
nuclear@1
|
52 LatencyTestMessage_ColorDetected = 2,
|
nuclear@1
|
53 LatencyTestMessage_TestStarted = 3,
|
nuclear@1
|
54 LatencyTestMessage_Button = 4,
|
nuclear@1
|
55 LatencyTestMessage_Unknown = 0x100,
|
nuclear@1
|
56 LatencyTestMessage_SizeError = 0x101,
|
nuclear@1
|
57 };
|
nuclear@1
|
58
|
nuclear@1
|
59 struct LatencyTestSample
|
nuclear@1
|
60 {
|
nuclear@1
|
61 UByte Value[3];
|
nuclear@1
|
62 };
|
nuclear@1
|
63
|
nuclear@1
|
64 struct LatencyTestSamples
|
nuclear@1
|
65 {
|
nuclear@1
|
66 UByte SampleCount;
|
nuclear@1
|
67 UInt16 Timestamp;
|
nuclear@1
|
68
|
nuclear@1
|
69 LatencyTestSample Samples[20];
|
nuclear@1
|
70
|
nuclear@1
|
71 LatencyTestMessageType Decode(const UByte* buffer, int size)
|
nuclear@1
|
72 {
|
nuclear@1
|
73 if (size < 64)
|
nuclear@1
|
74 {
|
nuclear@1
|
75 return LatencyTestMessage_SizeError;
|
nuclear@1
|
76 }
|
nuclear@1
|
77
|
nuclear@1
|
78 SampleCount = buffer[1];
|
nuclear@1
|
79 Timestamp = DecodeUInt16(buffer + 2);
|
nuclear@1
|
80
|
nuclear@1
|
81 for (UByte i = 0; i < SampleCount; i++)
|
nuclear@1
|
82 {
|
nuclear@1
|
83 UnpackSamples(buffer + 4 + (3 * i), &Samples[i].Value[0], &Samples[i].Value[1], &Samples[i].Value[2]);
|
nuclear@1
|
84 }
|
nuclear@1
|
85
|
nuclear@1
|
86 return LatencyTestMessage_Samples;
|
nuclear@1
|
87 }
|
nuclear@1
|
88 };
|
nuclear@1
|
89
|
nuclear@1
|
90 struct LatencyTestSamplesMessage
|
nuclear@1
|
91 {
|
nuclear@1
|
92 LatencyTestMessageType Type;
|
nuclear@1
|
93 LatencyTestSamples Samples;
|
nuclear@1
|
94 };
|
nuclear@1
|
95
|
nuclear@1
|
96 bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage* message, UByte* buffer, int size)
|
nuclear@1
|
97 {
|
nuclear@1
|
98 memset(message, 0, sizeof(LatencyTestSamplesMessage));
|
nuclear@1
|
99
|
nuclear@1
|
100 if (size < 64)
|
nuclear@1
|
101 {
|
nuclear@1
|
102 message->Type = LatencyTestMessage_SizeError;
|
nuclear@1
|
103 return false;
|
nuclear@1
|
104 }
|
nuclear@1
|
105
|
nuclear@1
|
106 switch (buffer[0])
|
nuclear@1
|
107 {
|
nuclear@1
|
108 case LatencyTestMessage_Samples:
|
nuclear@1
|
109 message->Type = message->Samples.Decode(buffer, size);
|
nuclear@1
|
110 break;
|
nuclear@1
|
111
|
nuclear@1
|
112 default:
|
nuclear@1
|
113 message->Type = LatencyTestMessage_Unknown;
|
nuclear@1
|
114 break;
|
nuclear@1
|
115 }
|
nuclear@1
|
116
|
nuclear@1
|
117 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
|
nuclear@1
|
118 }
|
nuclear@1
|
119
|
nuclear@1
|
120 struct LatencyTestColorDetected
|
nuclear@1
|
121 {
|
nuclear@1
|
122 UInt16 CommandID;
|
nuclear@1
|
123 UInt16 Timestamp;
|
nuclear@1
|
124 UInt16 Elapsed;
|
nuclear@1
|
125 UByte TriggerValue[3];
|
nuclear@1
|
126 UByte TargetValue[3];
|
nuclear@1
|
127
|
nuclear@1
|
128 LatencyTestMessageType Decode(const UByte* buffer, int size)
|
nuclear@1
|
129 {
|
nuclear@1
|
130 if (size < 13)
|
nuclear@1
|
131 return LatencyTestMessage_SizeError;
|
nuclear@1
|
132
|
nuclear@1
|
133 CommandID = DecodeUInt16(buffer + 1);
|
nuclear@1
|
134 Timestamp = DecodeUInt16(buffer + 3);
|
nuclear@1
|
135 Elapsed = DecodeUInt16(buffer + 5);
|
nuclear@1
|
136 memcpy(TriggerValue, buffer + 7, 3);
|
nuclear@1
|
137 memcpy(TargetValue, buffer + 10, 3);
|
nuclear@1
|
138
|
nuclear@1
|
139 return LatencyTestMessage_ColorDetected;
|
nuclear@1
|
140 }
|
nuclear@1
|
141 };
|
nuclear@1
|
142
|
nuclear@1
|
143 struct LatencyTestColorDetectedMessage
|
nuclear@1
|
144 {
|
nuclear@1
|
145 LatencyTestMessageType Type;
|
nuclear@1
|
146 LatencyTestColorDetected ColorDetected;
|
nuclear@1
|
147 };
|
nuclear@1
|
148
|
nuclear@1
|
149 bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message, UByte* buffer, int size)
|
nuclear@1
|
150 {
|
nuclear@1
|
151 memset(message, 0, sizeof(LatencyTestColorDetectedMessage));
|
nuclear@1
|
152
|
nuclear@1
|
153 if (size < 13)
|
nuclear@1
|
154 {
|
nuclear@1
|
155 message->Type = LatencyTestMessage_SizeError;
|
nuclear@1
|
156 return false;
|
nuclear@1
|
157 }
|
nuclear@1
|
158
|
nuclear@1
|
159 switch (buffer[0])
|
nuclear@1
|
160 {
|
nuclear@1
|
161 case LatencyTestMessage_ColorDetected:
|
nuclear@1
|
162 message->Type = message->ColorDetected.Decode(buffer, size);
|
nuclear@1
|
163 break;
|
nuclear@1
|
164
|
nuclear@1
|
165 default:
|
nuclear@1
|
166 message->Type = LatencyTestMessage_Unknown;
|
nuclear@1
|
167 break;
|
nuclear@1
|
168 }
|
nuclear@1
|
169
|
nuclear@1
|
170 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
|
nuclear@1
|
171 }
|
nuclear@1
|
172
|
nuclear@1
|
173 struct LatencyTestStarted
|
nuclear@1
|
174 {
|
nuclear@1
|
175 UInt16 CommandID;
|
nuclear@1
|
176 UInt16 Timestamp;
|
nuclear@1
|
177 UByte TargetValue[3];
|
nuclear@1
|
178
|
nuclear@1
|
179 LatencyTestMessageType Decode(const UByte* buffer, int size)
|
nuclear@1
|
180 {
|
nuclear@1
|
181 if (size < 8)
|
nuclear@1
|
182 return LatencyTestMessage_SizeError;
|
nuclear@1
|
183
|
nuclear@1
|
184 CommandID = DecodeUInt16(buffer + 1);
|
nuclear@1
|
185 Timestamp = DecodeUInt16(buffer + 3);
|
nuclear@1
|
186 memcpy(TargetValue, buffer + 5, 3);
|
nuclear@1
|
187
|
nuclear@1
|
188 return LatencyTestMessage_TestStarted;
|
nuclear@1
|
189 }
|
nuclear@1
|
190 };
|
nuclear@1
|
191
|
nuclear@1
|
192 struct LatencyTestStartedMessage
|
nuclear@1
|
193 {
|
nuclear@1
|
194 LatencyTestMessageType Type;
|
nuclear@1
|
195 LatencyTestStarted TestStarted;
|
nuclear@1
|
196 };
|
nuclear@1
|
197
|
nuclear@1
|
198 bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage* message, UByte* buffer, int size)
|
nuclear@1
|
199 {
|
nuclear@1
|
200 memset(message, 0, sizeof(LatencyTestStartedMessage));
|
nuclear@1
|
201
|
nuclear@1
|
202 if (size < 8)
|
nuclear@1
|
203 {
|
nuclear@1
|
204 message->Type = LatencyTestMessage_SizeError;
|
nuclear@1
|
205 return false;
|
nuclear@1
|
206 }
|
nuclear@1
|
207
|
nuclear@1
|
208 switch (buffer[0])
|
nuclear@1
|
209 {
|
nuclear@1
|
210 case LatencyTestMessage_TestStarted:
|
nuclear@1
|
211 message->Type = message->TestStarted.Decode(buffer, size);
|
nuclear@1
|
212 break;
|
nuclear@1
|
213
|
nuclear@1
|
214 default:
|
nuclear@1
|
215 message->Type = LatencyTestMessage_Unknown;
|
nuclear@1
|
216 break;
|
nuclear@1
|
217 }
|
nuclear@1
|
218
|
nuclear@1
|
219 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
|
nuclear@1
|
220 }
|
nuclear@1
|
221
|
nuclear@1
|
222 struct LatencyTestButton
|
nuclear@1
|
223 {
|
nuclear@1
|
224 UInt16 CommandID;
|
nuclear@1
|
225 UInt16 Timestamp;
|
nuclear@1
|
226
|
nuclear@1
|
227 LatencyTestMessageType Decode(const UByte* buffer, int size)
|
nuclear@1
|
228 {
|
nuclear@1
|
229 if (size < 5)
|
nuclear@1
|
230 return LatencyTestMessage_SizeError;
|
nuclear@1
|
231
|
nuclear@1
|
232 CommandID = DecodeUInt16(buffer + 1);
|
nuclear@1
|
233 Timestamp = DecodeUInt16(buffer + 3);
|
nuclear@1
|
234
|
nuclear@1
|
235 return LatencyTestMessage_Button;
|
nuclear@1
|
236 }
|
nuclear@1
|
237 };
|
nuclear@1
|
238
|
nuclear@1
|
239 struct LatencyTestButtonMessage
|
nuclear@1
|
240 {
|
nuclear@1
|
241 LatencyTestMessageType Type;
|
nuclear@1
|
242 LatencyTestButton Button;
|
nuclear@1
|
243 };
|
nuclear@1
|
244
|
nuclear@1
|
245 bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage* message, UByte* buffer, int size)
|
nuclear@1
|
246 {
|
nuclear@1
|
247 memset(message, 0, sizeof(LatencyTestButtonMessage));
|
nuclear@1
|
248
|
nuclear@1
|
249 if (size < 5)
|
nuclear@1
|
250 {
|
nuclear@1
|
251 message->Type = LatencyTestMessage_SizeError;
|
nuclear@1
|
252 return false;
|
nuclear@1
|
253 }
|
nuclear@1
|
254
|
nuclear@1
|
255 switch (buffer[0])
|
nuclear@1
|
256 {
|
nuclear@1
|
257 case LatencyTestMessage_Button:
|
nuclear@1
|
258 message->Type = message->Button.Decode(buffer, size);
|
nuclear@1
|
259 break;
|
nuclear@1
|
260
|
nuclear@1
|
261 default:
|
nuclear@1
|
262 message->Type = LatencyTestMessage_Unknown;
|
nuclear@1
|
263 break;
|
nuclear@1
|
264 }
|
nuclear@1
|
265
|
nuclear@1
|
266 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
|
nuclear@1
|
267 }
|
nuclear@1
|
268
|
nuclear@1
|
269 struct LatencyTestConfigurationImpl
|
nuclear@1
|
270 {
|
nuclear@1
|
271 enum { PacketSize = 5 };
|
nuclear@1
|
272 UByte Buffer[PacketSize];
|
nuclear@1
|
273
|
nuclear@1
|
274 OVR::LatencyTestConfiguration Configuration;
|
nuclear@1
|
275
|
nuclear@1
|
276 LatencyTestConfigurationImpl(const OVR::LatencyTestConfiguration& configuration)
|
nuclear@1
|
277 : Configuration(configuration)
|
nuclear@1
|
278 {
|
nuclear@1
|
279 Pack();
|
nuclear@1
|
280 }
|
nuclear@1
|
281
|
nuclear@1
|
282 void Pack()
|
nuclear@1
|
283 {
|
nuclear@1
|
284 Buffer[0] = 5;
|
nuclear@1
|
285 Buffer[1] = UByte(Configuration.SendSamples);
|
nuclear@1
|
286 Buffer[2] = Configuration.Threshold.R;
|
nuclear@1
|
287 Buffer[3] = Configuration.Threshold.G;
|
nuclear@1
|
288 Buffer[4] = Configuration.Threshold.B;
|
nuclear@1
|
289 }
|
nuclear@1
|
290
|
nuclear@1
|
291 void Unpack()
|
nuclear@1
|
292 {
|
nuclear@1
|
293 Configuration.SendSamples = Buffer[1] != 0 ? true : false;
|
nuclear@1
|
294 Configuration.Threshold.R = Buffer[2];
|
nuclear@1
|
295 Configuration.Threshold.G = Buffer[3];
|
nuclear@1
|
296 Configuration.Threshold.B = Buffer[4];
|
nuclear@1
|
297 }
|
nuclear@1
|
298 };
|
nuclear@1
|
299
|
nuclear@1
|
300 struct LatencyTestCalibrateImpl
|
nuclear@1
|
301 {
|
nuclear@1
|
302 enum { PacketSize = 4 };
|
nuclear@1
|
303 UByte Buffer[PacketSize];
|
nuclear@1
|
304
|
nuclear@1
|
305 Color CalibrationColor;
|
nuclear@1
|
306
|
nuclear@1
|
307 LatencyTestCalibrateImpl(const Color& calibrationColor)
|
nuclear@1
|
308 : CalibrationColor(calibrationColor)
|
nuclear@1
|
309 {
|
nuclear@1
|
310 Pack();
|
nuclear@1
|
311 }
|
nuclear@1
|
312
|
nuclear@1
|
313 void Pack()
|
nuclear@1
|
314 {
|
nuclear@1
|
315 Buffer[0] = 7;
|
nuclear@1
|
316 Buffer[1] = CalibrationColor.R;
|
nuclear@1
|
317 Buffer[2] = CalibrationColor.G;
|
nuclear@1
|
318 Buffer[3] = CalibrationColor.B;
|
nuclear@1
|
319 }
|
nuclear@1
|
320
|
nuclear@1
|
321 void Unpack()
|
nuclear@1
|
322 {
|
nuclear@1
|
323 CalibrationColor.R = Buffer[1];
|
nuclear@1
|
324 CalibrationColor.G = Buffer[2];
|
nuclear@1
|
325 CalibrationColor.B = Buffer[3];
|
nuclear@1
|
326 }
|
nuclear@1
|
327 };
|
nuclear@1
|
328
|
nuclear@1
|
329 struct LatencyTestStartTestImpl
|
nuclear@1
|
330 {
|
nuclear@1
|
331 enum { PacketSize = 6 };
|
nuclear@1
|
332 UByte Buffer[PacketSize];
|
nuclear@1
|
333
|
nuclear@1
|
334 Color TargetColor;
|
nuclear@1
|
335
|
nuclear@1
|
336 LatencyTestStartTestImpl(const Color& targetColor)
|
nuclear@1
|
337 : TargetColor(targetColor)
|
nuclear@1
|
338 {
|
nuclear@1
|
339 Pack();
|
nuclear@1
|
340 }
|
nuclear@1
|
341
|
nuclear@1
|
342 void Pack()
|
nuclear@1
|
343 {
|
nuclear@1
|
344 UInt16 commandID = 1;
|
nuclear@1
|
345
|
nuclear@1
|
346 Buffer[0] = 8;
|
nuclear@1
|
347 Buffer[1] = UByte(commandID & 0xFF);
|
nuclear@1
|
348 Buffer[2] = UByte(commandID >> 8);
|
nuclear@1
|
349 Buffer[3] = TargetColor.R;
|
nuclear@1
|
350 Buffer[4] = TargetColor.G;
|
nuclear@1
|
351 Buffer[5] = TargetColor.B;
|
nuclear@1
|
352 }
|
nuclear@1
|
353
|
nuclear@1
|
354 void Unpack()
|
nuclear@1
|
355 {
|
nuclear@1
|
356 // UInt16 commandID = Buffer[1] | (UInt16(Buffer[2]) << 8);
|
nuclear@1
|
357 TargetColor.R = Buffer[3];
|
nuclear@1
|
358 TargetColor.G = Buffer[4];
|
nuclear@1
|
359 TargetColor.B = Buffer[5];
|
nuclear@1
|
360 }
|
nuclear@1
|
361 };
|
nuclear@1
|
362
|
nuclear@1
|
363 struct LatencyTestDisplayImpl
|
nuclear@1
|
364 {
|
nuclear@1
|
365 enum { PacketSize = 6 };
|
nuclear@1
|
366 UByte Buffer[PacketSize];
|
nuclear@1
|
367
|
nuclear@1
|
368 OVR::LatencyTestDisplay Display;
|
nuclear@1
|
369
|
nuclear@1
|
370 LatencyTestDisplayImpl(const OVR::LatencyTestDisplay& display)
|
nuclear@1
|
371 : Display(display)
|
nuclear@1
|
372 {
|
nuclear@1
|
373 Pack();
|
nuclear@1
|
374 }
|
nuclear@1
|
375
|
nuclear@1
|
376 void Pack()
|
nuclear@1
|
377 {
|
nuclear@1
|
378 Buffer[0] = 9;
|
nuclear@1
|
379 Buffer[1] = Display.Mode;
|
nuclear@1
|
380 Buffer[2] = UByte(Display.Value & 0xFF);
|
nuclear@1
|
381 Buffer[3] = UByte((Display.Value >> 8) & 0xFF);
|
nuclear@1
|
382 Buffer[4] = UByte((Display.Value >> 16) & 0xFF);
|
nuclear@1
|
383 Buffer[5] = UByte((Display.Value >> 24) & 0xFF);
|
nuclear@1
|
384 }
|
nuclear@1
|
385
|
nuclear@1
|
386 void Unpack()
|
nuclear@1
|
387 {
|
nuclear@1
|
388 Display.Mode = Buffer[1];
|
nuclear@1
|
389 Display.Value = UInt32(Buffer[2]) |
|
nuclear@1
|
390 (UInt32(Buffer[3]) << 8) |
|
nuclear@1
|
391 (UInt32(Buffer[4]) << 16) |
|
nuclear@1
|
392 (UInt32(Buffer[5]) << 24);
|
nuclear@1
|
393 }
|
nuclear@1
|
394 };
|
nuclear@1
|
395
|
nuclear@1
|
396 //-------------------------------------------------------------------------------------
|
nuclear@1
|
397 // ***** LatencyTestDeviceFactory
|
nuclear@1
|
398
|
nuclear@1
|
399 LatencyTestDeviceFactory LatencyTestDeviceFactory::Instance;
|
nuclear@1
|
400
|
nuclear@1
|
401 void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
|
nuclear@1
|
402 {
|
nuclear@1
|
403
|
nuclear@1
|
404 class LatencyTestEnumerator : public HIDEnumerateVisitor
|
nuclear@1
|
405 {
|
nuclear@1
|
406 // Assign not supported; suppress MSVC warning.
|
nuclear@1
|
407 void operator = (const LatencyTestEnumerator&) { }
|
nuclear@1
|
408
|
nuclear@1
|
409 DeviceFactory* pFactory;
|
nuclear@1
|
410 EnumerateVisitor& ExternalVisitor;
|
nuclear@1
|
411 public:
|
nuclear@1
|
412 LatencyTestEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor)
|
nuclear@1
|
413 : pFactory(factory), ExternalVisitor(externalVisitor) { }
|
nuclear@1
|
414
|
nuclear@1
|
415 virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId)
|
nuclear@1
|
416 {
|
nuclear@1
|
417 return pFactory->MatchVendorProduct(vendorId, productId);
|
nuclear@1
|
418 }
|
nuclear@1
|
419
|
nuclear@1
|
420 virtual void Visit(HIDDevice& device, const HIDDeviceDesc& desc)
|
nuclear@1
|
421 {
|
nuclear@1
|
422 OVR_UNUSED(device);
|
nuclear@1
|
423
|
nuclear@1
|
424 LatencyTestDeviceCreateDesc createDesc(pFactory, desc);
|
nuclear@1
|
425 ExternalVisitor.Visit(createDesc);
|
nuclear@1
|
426 }
|
nuclear@1
|
427 };
|
nuclear@1
|
428
|
nuclear@1
|
429 LatencyTestEnumerator latencyTestEnumerator(this, visitor);
|
nuclear@1
|
430 GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&latencyTestEnumerator);
|
nuclear@1
|
431 }
|
nuclear@1
|
432
|
nuclear@1
|
433 bool LatencyTestDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
|
nuclear@1
|
434 {
|
nuclear@1
|
435 return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId));
|
nuclear@1
|
436 }
|
nuclear@1
|
437
|
nuclear@1
|
438 bool LatencyTestDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr,
|
nuclear@1
|
439 const HIDDeviceDesc& desc)
|
nuclear@1
|
440 {
|
nuclear@1
|
441 if (MatchVendorProduct(desc.VendorId, desc.ProductId))
|
nuclear@1
|
442 {
|
nuclear@1
|
443 LatencyTestDeviceCreateDesc createDesc(this, desc);
|
nuclear@1
|
444 return pdevMgr->AddDevice_NeedsLock(createDesc).GetPtr() != NULL;
|
nuclear@1
|
445 }
|
nuclear@1
|
446 return false;
|
nuclear@1
|
447 }
|
nuclear@1
|
448
|
nuclear@1
|
449 //-------------------------------------------------------------------------------------
|
nuclear@1
|
450 // ***** LatencyTestDeviceCreateDesc
|
nuclear@1
|
451
|
nuclear@1
|
452 DeviceBase* LatencyTestDeviceCreateDesc::NewDeviceInstance()
|
nuclear@1
|
453 {
|
nuclear@1
|
454 return new LatencyTestDeviceImpl(this);
|
nuclear@1
|
455 }
|
nuclear@1
|
456
|
nuclear@1
|
457 bool LatencyTestDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
|
nuclear@1
|
458 {
|
nuclear@1
|
459 if ((info->InfoClassType != Device_LatencyTester) &&
|
nuclear@1
|
460 (info->InfoClassType != Device_None))
|
nuclear@1
|
461 return false;
|
nuclear@1
|
462
|
nuclear@1
|
463 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, HIDDesc.Product.ToCStr());
|
nuclear@1
|
464 OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, HIDDesc.Manufacturer.ToCStr());
|
nuclear@1
|
465 info->Type = Device_LatencyTester;
|
nuclear@1
|
466 info->Version = 0;
|
nuclear@1
|
467
|
nuclear@1
|
468 if (info->InfoClassType == Device_LatencyTester)
|
nuclear@1
|
469 {
|
nuclear@1
|
470 SensorInfo* sinfo = (SensorInfo*)info;
|
nuclear@1
|
471 sinfo->VendorId = HIDDesc.VendorId;
|
nuclear@1
|
472 sinfo->ProductId = HIDDesc.ProductId;
|
nuclear@1
|
473 OVR_strcpy(sinfo->SerialNumber, sizeof(sinfo->SerialNumber),HIDDesc.SerialNumber.ToCStr());
|
nuclear@1
|
474 }
|
nuclear@1
|
475 return true;
|
nuclear@1
|
476 }
|
nuclear@1
|
477
|
nuclear@1
|
478 //-------------------------------------------------------------------------------------
|
nuclear@1
|
479 // ***** LatencyTestDevice
|
nuclear@1
|
480
|
nuclear@1
|
481 LatencyTestDeviceImpl::LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* createDesc)
|
nuclear@1
|
482 : OVR::HIDDeviceImpl<OVR::LatencyTestDevice>(createDesc, 0)
|
nuclear@1
|
483 {
|
nuclear@1
|
484 }
|
nuclear@1
|
485
|
nuclear@1
|
486 LatencyTestDeviceImpl::~LatencyTestDeviceImpl()
|
nuclear@1
|
487 {
|
nuclear@1
|
488 // Check that Shutdown() was called.
|
nuclear@1
|
489 OVR_ASSERT(!pCreateDesc->pDevice);
|
nuclear@1
|
490 }
|
nuclear@1
|
491
|
nuclear@1
|
492 // Internal creation APIs.
|
nuclear@1
|
493 bool LatencyTestDeviceImpl::Initialize(DeviceBase* parent)
|
nuclear@1
|
494 {
|
nuclear@1
|
495 if (HIDDeviceImpl<OVR::LatencyTestDevice>::Initialize(parent))
|
nuclear@1
|
496 {
|
nuclear@1
|
497 LogText("OVR::LatencyTestDevice initialized.\n");
|
nuclear@1
|
498 return true;
|
nuclear@1
|
499 }
|
nuclear@1
|
500
|
nuclear@1
|
501 return false;
|
nuclear@1
|
502 }
|
nuclear@1
|
503
|
nuclear@1
|
504 void LatencyTestDeviceImpl::Shutdown()
|
nuclear@1
|
505 {
|
nuclear@1
|
506 HIDDeviceImpl<OVR::LatencyTestDevice>::Shutdown();
|
nuclear@1
|
507
|
nuclear@1
|
508 LogText("OVR::LatencyTestDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr());
|
nuclear@1
|
509 }
|
nuclear@1
|
510
|
nuclear@1
|
511 void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length)
|
nuclear@1
|
512 {
|
nuclear@1
|
513
|
nuclear@1
|
514 bool processed = false;
|
nuclear@1
|
515 if (!processed)
|
nuclear@1
|
516 {
|
nuclear@1
|
517 LatencyTestSamplesMessage message;
|
nuclear@1
|
518 if (DecodeLatencyTestSamplesMessage(&message, pData, length))
|
nuclear@1
|
519 {
|
nuclear@1
|
520 processed = true;
|
nuclear@1
|
521 onLatencyTestSamplesMessage(&message);
|
nuclear@1
|
522 }
|
nuclear@1
|
523 }
|
nuclear@1
|
524
|
nuclear@1
|
525 if (!processed)
|
nuclear@1
|
526 {
|
nuclear@1
|
527 LatencyTestColorDetectedMessage message;
|
nuclear@1
|
528 if (DecodeLatencyTestColorDetectedMessage(&message, pData, length))
|
nuclear@1
|
529 {
|
nuclear@1
|
530 processed = true;
|
nuclear@1
|
531 onLatencyTestColorDetectedMessage(&message);
|
nuclear@1
|
532 }
|
nuclear@1
|
533 }
|
nuclear@1
|
534
|
nuclear@1
|
535 if (!processed)
|
nuclear@1
|
536 {
|
nuclear@1
|
537 LatencyTestStartedMessage message;
|
nuclear@1
|
538 if (DecodeLatencyTestStartedMessage(&message, pData, length))
|
nuclear@1
|
539 {
|
nuclear@1
|
540 processed = true;
|
nuclear@1
|
541 onLatencyTestStartedMessage(&message);
|
nuclear@1
|
542 }
|
nuclear@1
|
543 }
|
nuclear@1
|
544
|
nuclear@1
|
545 if (!processed)
|
nuclear@1
|
546 {
|
nuclear@1
|
547 LatencyTestButtonMessage message;
|
nuclear@1
|
548 if (DecodeLatencyTestButtonMessage(&message, pData, length))
|
nuclear@1
|
549 {
|
nuclear@1
|
550 processed = true;
|
nuclear@1
|
551 onLatencyTestButtonMessage(&message);
|
nuclear@1
|
552 }
|
nuclear@1
|
553 }
|
nuclear@1
|
554 }
|
nuclear@1
|
555
|
nuclear@1
|
556 bool LatencyTestDeviceImpl::SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag)
|
nuclear@1
|
557 {
|
nuclear@1
|
558 bool result = false;
|
nuclear@1
|
559 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
|
nuclear@1
|
560
|
nuclear@1
|
561 if (GetManagerImpl()->GetThreadId() != OVR::GetCurrentThreadId())
|
nuclear@1
|
562 {
|
nuclear@1
|
563 if (!waitFlag)
|
nuclear@1
|
564 {
|
nuclear@1
|
565 return queue->PushCall(this, &LatencyTestDeviceImpl::setConfiguration, configuration);
|
nuclear@1
|
566 }
|
nuclear@1
|
567
|
nuclear@1
|
568 if (!queue->PushCallAndWaitResult( this,
|
nuclear@1
|
569 &LatencyTestDeviceImpl::setConfiguration,
|
nuclear@1
|
570 &result,
|
nuclear@1
|
571 configuration))
|
nuclear@1
|
572 {
|
nuclear@1
|
573 return false;
|
nuclear@1
|
574 }
|
nuclear@1
|
575 }
|
nuclear@1
|
576 else
|
nuclear@1
|
577 return setConfiguration(configuration);
|
nuclear@1
|
578
|
nuclear@1
|
579 return result;
|
nuclear@1
|
580 }
|
nuclear@1
|
581
|
nuclear@1
|
582 bool LatencyTestDeviceImpl::setConfiguration(const OVR::LatencyTestConfiguration& configuration)
|
nuclear@1
|
583 {
|
nuclear@1
|
584 LatencyTestConfigurationImpl ltc(configuration);
|
nuclear@1
|
585 return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize);
|
nuclear@1
|
586 }
|
nuclear@1
|
587
|
nuclear@1
|
588 bool LatencyTestDeviceImpl::GetConfiguration(OVR::LatencyTestConfiguration* configuration)
|
nuclear@1
|
589 {
|
nuclear@1
|
590 bool result = false;
|
nuclear@1
|
591
|
nuclear@1
|
592 ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
|
nuclear@1
|
593 if (!pQueue->PushCallAndWaitResult(this, &LatencyTestDeviceImpl::getConfiguration, &result, configuration))
|
nuclear@1
|
594 return false;
|
nuclear@1
|
595
|
nuclear@1
|
596 return result;
|
nuclear@1
|
597 }
|
nuclear@1
|
598
|
nuclear@1
|
599 bool LatencyTestDeviceImpl::getConfiguration(OVR::LatencyTestConfiguration* configuration)
|
nuclear@1
|
600 {
|
nuclear@1
|
601 LatencyTestConfigurationImpl ltc(*configuration);
|
nuclear@1
|
602 if (GetInternalDevice()->GetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize))
|
nuclear@1
|
603 {
|
nuclear@1
|
604 ltc.Unpack();
|
nuclear@1
|
605 *configuration = ltc.Configuration;
|
nuclear@1
|
606 return true;
|
nuclear@1
|
607 }
|
nuclear@1
|
608
|
nuclear@1
|
609 return false;
|
nuclear@1
|
610 }
|
nuclear@1
|
611
|
nuclear@1
|
612 bool LatencyTestDeviceImpl::SetCalibrate(const Color& calibrationColor, bool waitFlag)
|
nuclear@1
|
613 {
|
nuclear@1
|
614 bool result = false;
|
nuclear@1
|
615 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
|
nuclear@1
|
616
|
nuclear@1
|
617 if (!waitFlag)
|
nuclear@1
|
618 {
|
nuclear@1
|
619 return queue->PushCall(this, &LatencyTestDeviceImpl::setCalibrate, calibrationColor);
|
nuclear@1
|
620 }
|
nuclear@1
|
621
|
nuclear@1
|
622 if (!queue->PushCallAndWaitResult( this,
|
nuclear@1
|
623 &LatencyTestDeviceImpl::setCalibrate,
|
nuclear@1
|
624 &result,
|
nuclear@1
|
625 calibrationColor))
|
nuclear@1
|
626 {
|
nuclear@1
|
627 return false;
|
nuclear@1
|
628 }
|
nuclear@1
|
629
|
nuclear@1
|
630 return result;
|
nuclear@1
|
631 }
|
nuclear@1
|
632
|
nuclear@1
|
633 bool LatencyTestDeviceImpl::setCalibrate(const Color& calibrationColor)
|
nuclear@1
|
634 {
|
nuclear@1
|
635 LatencyTestCalibrateImpl ltc(calibrationColor);
|
nuclear@1
|
636 return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestCalibrateImpl::PacketSize);
|
nuclear@1
|
637 }
|
nuclear@1
|
638
|
nuclear@1
|
639 bool LatencyTestDeviceImpl::SetStartTest(const Color& targetColor, bool waitFlag)
|
nuclear@1
|
640 {
|
nuclear@1
|
641 bool result = false;
|
nuclear@1
|
642 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
|
nuclear@1
|
643
|
nuclear@1
|
644 if (!waitFlag)
|
nuclear@1
|
645 {
|
nuclear@1
|
646 return queue->PushCall(this, &LatencyTestDeviceImpl::setStartTest, targetColor);
|
nuclear@1
|
647 }
|
nuclear@1
|
648
|
nuclear@1
|
649 if (!queue->PushCallAndWaitResult( this,
|
nuclear@1
|
650 &LatencyTestDeviceImpl::setStartTest,
|
nuclear@1
|
651 &result,
|
nuclear@1
|
652 targetColor))
|
nuclear@1
|
653 {
|
nuclear@1
|
654 return false;
|
nuclear@1
|
655 }
|
nuclear@1
|
656
|
nuclear@1
|
657 return result;
|
nuclear@1
|
658 }
|
nuclear@1
|
659
|
nuclear@1
|
660 bool LatencyTestDeviceImpl::setStartTest(const Color& targetColor)
|
nuclear@1
|
661 {
|
nuclear@1
|
662 LatencyTestStartTestImpl ltst(targetColor);
|
nuclear@1
|
663 return GetInternalDevice()->SetFeatureReport(ltst.Buffer, LatencyTestStartTestImpl::PacketSize);
|
nuclear@1
|
664 }
|
nuclear@1
|
665
|
nuclear@1
|
666 bool LatencyTestDeviceImpl::SetDisplay(const OVR::LatencyTestDisplay& display, bool waitFlag)
|
nuclear@1
|
667 {
|
nuclear@1
|
668 bool result = false;
|
nuclear@1
|
669 ThreadCommandQueue * queue = GetManagerImpl()->GetThreadQueue();
|
nuclear@1
|
670
|
nuclear@1
|
671 if (!waitFlag)
|
nuclear@1
|
672 {
|
nuclear@1
|
673 return queue->PushCall(this, &LatencyTestDeviceImpl::setDisplay, display);
|
nuclear@1
|
674 }
|
nuclear@1
|
675
|
nuclear@1
|
676 if (!queue->PushCallAndWaitResult( this,
|
nuclear@1
|
677 &LatencyTestDeviceImpl::setDisplay,
|
nuclear@1
|
678 &result,
|
nuclear@1
|
679 display))
|
nuclear@1
|
680 {
|
nuclear@1
|
681 return false;
|
nuclear@1
|
682 }
|
nuclear@1
|
683
|
nuclear@1
|
684 return result;
|
nuclear@1
|
685 }
|
nuclear@1
|
686
|
nuclear@1
|
687 bool LatencyTestDeviceImpl::setDisplay(const OVR::LatencyTestDisplay& display)
|
nuclear@1
|
688 {
|
nuclear@1
|
689 LatencyTestDisplayImpl ltd(display);
|
nuclear@1
|
690 return GetInternalDevice()->SetFeatureReport(ltd.Buffer, LatencyTestDisplayImpl::PacketSize);
|
nuclear@1
|
691 }
|
nuclear@1
|
692
|
nuclear@1
|
693 void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessage* message)
|
nuclear@1
|
694 {
|
nuclear@1
|
695
|
nuclear@1
|
696 if (message->Type != LatencyTestMessage_Samples)
|
nuclear@1
|
697 return;
|
nuclear@1
|
698
|
nuclear@1
|
699 LatencyTestSamples& s = message->Samples;
|
nuclear@1
|
700
|
nuclear@1
|
701 // Call OnMessage() within a lock to avoid conflicts with handlers.
|
nuclear@1
|
702 Lock::Locker scopeLock(HandlerRef.GetLock());
|
nuclear@1
|
703
|
nuclear@1
|
704 if (HandlerRef.GetHandler())
|
nuclear@1
|
705 {
|
nuclear@1
|
706 MessageLatencyTestSamples samples(this);
|
nuclear@1
|
707 for (UByte i = 0; i < s.SampleCount; i++)
|
nuclear@1
|
708 {
|
nuclear@1
|
709 samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2]));
|
nuclear@1
|
710 }
|
nuclear@1
|
711
|
nuclear@1
|
712 HandlerRef.GetHandler()->OnMessage(samples);
|
nuclear@1
|
713 }
|
nuclear@1
|
714 }
|
nuclear@1
|
715
|
nuclear@1
|
716 void LatencyTestDeviceImpl::onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message)
|
nuclear@1
|
717 {
|
nuclear@1
|
718 if (message->Type != LatencyTestMessage_ColorDetected)
|
nuclear@1
|
719 return;
|
nuclear@1
|
720
|
nuclear@1
|
721 LatencyTestColorDetected& s = message->ColorDetected;
|
nuclear@1
|
722
|
nuclear@1
|
723 // Call OnMessage() within a lock to avoid conflicts with handlers.
|
nuclear@1
|
724 Lock::Locker scopeLock(HandlerRef.GetLock());
|
nuclear@1
|
725
|
nuclear@1
|
726 if (HandlerRef.GetHandler())
|
nuclear@1
|
727 {
|
nuclear@1
|
728 MessageLatencyTestColorDetected detected(this);
|
nuclear@1
|
729 detected.Elapsed = s.Elapsed;
|
nuclear@1
|
730 detected.DetectedValue = Color(s.TriggerValue[0], s.TriggerValue[1], s.TriggerValue[2]);
|
nuclear@1
|
731 detected.TargetValue = Color(s.TargetValue[0], s.TargetValue[1], s.TargetValue[2]);
|
nuclear@1
|
732
|
nuclear@1
|
733 HandlerRef.GetHandler()->OnMessage(detected);
|
nuclear@1
|
734 }
|
nuclear@1
|
735 }
|
nuclear@1
|
736
|
nuclear@1
|
737 void LatencyTestDeviceImpl::onLatencyTestStartedMessage(LatencyTestStartedMessage* message)
|
nuclear@1
|
738 {
|
nuclear@1
|
739 if (message->Type != LatencyTestMessage_TestStarted)
|
nuclear@1
|
740 return;
|
nuclear@1
|
741
|
nuclear@1
|
742 LatencyTestStarted& ts = message->TestStarted;
|
nuclear@1
|
743
|
nuclear@1
|
744 // Call OnMessage() within a lock to avoid conflicts with handlers.
|
nuclear@1
|
745 Lock::Locker scopeLock(HandlerRef.GetLock());
|
nuclear@1
|
746
|
nuclear@1
|
747 if (HandlerRef.GetHandler())
|
nuclear@1
|
748 {
|
nuclear@1
|
749 MessageLatencyTestStarted started(this);
|
nuclear@1
|
750 started.TargetValue = Color(ts.TargetValue[0], ts.TargetValue[1], ts.TargetValue[2]);
|
nuclear@1
|
751
|
nuclear@1
|
752 HandlerRef.GetHandler()->OnMessage(started);
|
nuclear@1
|
753 }
|
nuclear@1
|
754 }
|
nuclear@1
|
755
|
nuclear@1
|
756 void LatencyTestDeviceImpl::onLatencyTestButtonMessage(LatencyTestButtonMessage* message)
|
nuclear@1
|
757 {
|
nuclear@1
|
758 if (message->Type != LatencyTestMessage_Button)
|
nuclear@1
|
759 return;
|
nuclear@1
|
760
|
nuclear@1
|
761 // LatencyTestButton& s = message->Button;
|
nuclear@1
|
762
|
nuclear@1
|
763 // Call OnMessage() within a lock to avoid conflicts with handlers.
|
nuclear@1
|
764 Lock::Locker scopeLock(HandlerRef.GetLock());
|
nuclear@1
|
765
|
nuclear@1
|
766 if (HandlerRef.GetHandler())
|
nuclear@1
|
767 {
|
nuclear@1
|
768 MessageLatencyTestButton button(this);
|
nuclear@1
|
769
|
nuclear@1
|
770 HandlerRef.GetHandler()->OnMessage(button);
|
nuclear@1
|
771 }
|
nuclear@1
|
772 }
|
nuclear@1
|
773
|
nuclear@1
|
774 } // namespace OVR
|