rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 Filename : CAPI_HMDState.h
|
nuclear@0
|
4 Content : State associated with a single HMD
|
nuclear@0
|
5 Created : January 24, 2014
|
nuclear@0
|
6 Authors : Michael Antonov
|
nuclear@0
|
7
|
nuclear@0
|
8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
9
|
nuclear@0
|
10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
12 which is provided at the time of installation or download, or which
|
nuclear@0
|
13 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
14
|
nuclear@0
|
15 You may obtain a copy of the License at
|
nuclear@0
|
16
|
nuclear@0
|
17 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
18
|
nuclear@0
|
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
20 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
22 See the License for the specific language governing permissions and
|
nuclear@0
|
23 limitations under the License.
|
nuclear@0
|
24
|
nuclear@0
|
25 ************************************************************************************/
|
nuclear@0
|
26
|
nuclear@0
|
27 #ifndef OVR_CAPI_HMDState_h
|
nuclear@0
|
28 #define OVR_CAPI_HMDState_h
|
nuclear@0
|
29
|
nuclear@0
|
30 #include "../Kernel/OVR_Math.h"
|
nuclear@0
|
31 #include "../Kernel/OVR_List.h"
|
nuclear@0
|
32 #include "../Kernel/OVR_Log.h"
|
nuclear@0
|
33 #include "../OVR_CAPI.h"
|
nuclear@0
|
34
|
nuclear@0
|
35 #include "CAPI_FrameTimeManager.h"
|
nuclear@0
|
36 #include "CAPI_LatencyStatistics.h"
|
nuclear@0
|
37 #include "CAPI_HMDRenderState.h"
|
nuclear@0
|
38 #include "CAPI_DistortionRenderer.h"
|
nuclear@0
|
39 #include "CAPI_HSWDisplay.h"
|
nuclear@0
|
40
|
nuclear@0
|
41 #include "../Service/Service_NetClient.h"
|
nuclear@0
|
42 #include "../Net/OVR_NetworkTypes.h"
|
nuclear@0
|
43 #include "../Util/Util_LatencyTest2Reader.h"
|
nuclear@0
|
44
|
nuclear@0
|
45 struct ovrHmdStruct { };
|
nuclear@0
|
46
|
nuclear@0
|
47 namespace OVR { namespace CAPI {
|
nuclear@0
|
48
|
nuclear@0
|
49
|
nuclear@0
|
50 using namespace OVR::Util::Render;
|
nuclear@0
|
51 using namespace OVR::Service;
|
nuclear@0
|
52 using namespace OVR::Net;
|
nuclear@0
|
53
|
nuclear@0
|
54
|
nuclear@0
|
55 //-------------------------------------------------------------------------------------
|
nuclear@0
|
56 // ***** ThreadChecker
|
nuclear@0
|
57
|
nuclear@0
|
58 // This helper class is used to verify that the API is used according to supported
|
nuclear@0
|
59 // thread safety constraints (is not re-entrant for this and related functions).
|
nuclear@0
|
60 class ThreadChecker
|
nuclear@0
|
61 {
|
nuclear@0
|
62 public:
|
nuclear@0
|
63
|
nuclear@0
|
64 #ifndef OVR_BUILD_DEBUG
|
nuclear@0
|
65
|
nuclear@0
|
66 // In release build, thread checks are disabled.
|
nuclear@0
|
67 ThreadChecker() { }
|
nuclear@0
|
68 void Begin(const char* functionName) { OVR_UNUSED1(functionName); }
|
nuclear@0
|
69 void End() { }
|
nuclear@0
|
70
|
nuclear@0
|
71 // Add thread-re-entrancy check for function scope
|
nuclear@0
|
72 struct Scope
|
nuclear@0
|
73 {
|
nuclear@0
|
74 Scope(ThreadChecker*, const char *) { }
|
nuclear@0
|
75 ~Scope() { }
|
nuclear@0
|
76 };
|
nuclear@0
|
77
|
nuclear@0
|
78
|
nuclear@0
|
79 #else // OVR_BUILD_DEBUG
|
nuclear@0
|
80 ThreadChecker() : pFunctionName(0), FirstThread(0)
|
nuclear@0
|
81 { }
|
nuclear@0
|
82
|
nuclear@0
|
83 void Begin(const char* functionName)
|
nuclear@0
|
84 {
|
nuclear@0
|
85 if (!pFunctionName)
|
nuclear@0
|
86 {
|
nuclear@0
|
87 pFunctionName = functionName;
|
nuclear@0
|
88 FirstThread = GetCurrentThreadId();
|
nuclear@0
|
89 }
|
nuclear@0
|
90 else
|
nuclear@0
|
91 {
|
nuclear@0
|
92 // pFunctionName may be not null here if function is called internally on the same thread.
|
nuclear@0
|
93 OVR_ASSERT_LOG((FirstThread == GetCurrentThreadId()),
|
nuclear@0
|
94 ("%s (threadId=%p) called at the same times as %s (threadId=%p)\n",
|
nuclear@0
|
95 functionName, GetCurrentThreadId(), pFunctionName, FirstThread) );
|
nuclear@0
|
96 }
|
nuclear@0
|
97 }
|
nuclear@0
|
98 void End()
|
nuclear@0
|
99 {
|
nuclear@0
|
100 pFunctionName = 0;
|
nuclear@0
|
101 FirstThread = 0;
|
nuclear@0
|
102 }
|
nuclear@0
|
103
|
nuclear@0
|
104 // Add thread-reentrancy check for function scope.
|
nuclear@0
|
105 struct Scope
|
nuclear@0
|
106 {
|
nuclear@0
|
107 Scope(ThreadChecker* threadChecker, const char *functionName) : pChecker(threadChecker)
|
nuclear@0
|
108 { pChecker->Begin(functionName); }
|
nuclear@0
|
109 ~Scope()
|
nuclear@0
|
110 { pChecker->End(); }
|
nuclear@0
|
111 private:
|
nuclear@0
|
112 ThreadChecker* pChecker;
|
nuclear@0
|
113 };
|
nuclear@0
|
114
|
nuclear@0
|
115 private:
|
nuclear@0
|
116 // If not 0, contains the name of the function that first entered the scope.
|
nuclear@0
|
117 const char * pFunctionName;
|
nuclear@0
|
118 ThreadId FirstThread;
|
nuclear@0
|
119
|
nuclear@0
|
120 #endif // OVR_BUILD_DEBUG
|
nuclear@0
|
121 };
|
nuclear@0
|
122
|
nuclear@0
|
123
|
nuclear@0
|
124 //-------------------------------------------------------------------------------------
|
nuclear@0
|
125 // ***** HMDState
|
nuclear@0
|
126
|
nuclear@0
|
127 // Describes a single HMD.
|
nuclear@0
|
128 class HMDState : public ListNode<HMDState>,
|
nuclear@0
|
129 public ovrHmdStruct, public NewOverrideBase
|
nuclear@0
|
130 {
|
nuclear@0
|
131 void operator=(const HMDState&) { } // Quiet warning.
|
nuclear@0
|
132
|
nuclear@0
|
133 protected:
|
nuclear@0
|
134 HMDState(const OVR::Service::HMDNetworkInfo& netInfo,
|
nuclear@0
|
135 const OVR::HMDInfo& hmdInfo,
|
nuclear@0
|
136 Profile* profile,
|
nuclear@0
|
137 Service::NetClient* client);
|
nuclear@0
|
138 HMDState(const HMDInfo& src, Profile* profile);
|
nuclear@0
|
139
|
nuclear@0
|
140 public:
|
nuclear@0
|
141 virtual ~HMDState();
|
nuclear@0
|
142
|
nuclear@0
|
143 static HMDState* CreateHMDState(Service::NetClient* client, const HMDNetworkInfo& netInfo);
|
nuclear@0
|
144 static HMDState* CreateHMDState(ovrHmdType hmdType); // Used for debug mode
|
nuclear@0
|
145 static const OVR::List<HMDState>& GetHMDStateList();
|
nuclear@0
|
146
|
nuclear@0
|
147 // *** Sensor Setup
|
nuclear@0
|
148
|
nuclear@0
|
149 bool ConfigureTracking(unsigned supportedCaps, unsigned requiredCaps);
|
nuclear@0
|
150 void ResetTracking();
|
nuclear@0
|
151 void RecenterPose();
|
nuclear@0
|
152 ovrTrackingState PredictedTrackingState(double absTime);
|
nuclear@0
|
153
|
nuclear@0
|
154 // Changes HMD Caps.
|
nuclear@0
|
155 // Capability bits that are not directly or logically tied to one system (such as sensor)
|
nuclear@0
|
156 // are grouped here. ovrHmdCap_VSync, for example, affects rendering and timing.
|
nuclear@0
|
157 void SetEnabledHmdCaps(unsigned caps);
|
nuclear@0
|
158 unsigned SetEnabledHmdCaps();
|
nuclear@0
|
159
|
nuclear@0
|
160 bool ProcessLatencyTest(unsigned char rgbColorOut[3]);
|
nuclear@0
|
161
|
nuclear@0
|
162 // *** Rendering Setup
|
nuclear@0
|
163 bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2],
|
nuclear@0
|
164 const ovrFovPort eyeFovIn[2],
|
nuclear@0
|
165 const ovrRenderAPIConfig* apiConfig,
|
nuclear@0
|
166 unsigned distortionCaps);
|
nuclear@0
|
167
|
nuclear@0
|
168 void UpdateRenderProfile(Profile* profile);
|
nuclear@0
|
169
|
nuclear@0
|
170
|
nuclear@0
|
171 void SubmitEyeTextures(const ovrPosef renderPose[2],
|
nuclear@0
|
172 const ovrTexture eyeTexture[2]);
|
nuclear@0
|
173
|
nuclear@0
|
174
|
nuclear@0
|
175 void sharedInit ( Profile *profile );
|
nuclear@0
|
176
|
nuclear@0
|
177 void applyProfileToSensorFusion();
|
nuclear@0
|
178
|
nuclear@0
|
179 // INlines so that they can be easily compiled out.
|
nuclear@0
|
180 // Does debug ASSERT checks for functions that require BeginFrame.
|
nuclear@0
|
181 // Also verifies that we are on the right thread.
|
nuclear@0
|
182 void checkBeginFrameScope(const char* functionName)
|
nuclear@0
|
183 {
|
nuclear@0
|
184 OVR_UNUSED1(functionName); // for Release build.
|
nuclear@0
|
185 OVR_ASSERT_LOG(BeginFrameCalled == true,
|
nuclear@0
|
186 ("%s called outside ovrHmd_BeginFrame.", functionName));
|
nuclear@0
|
187 OVR_DEBUG_LOG_COND(BeginFrameThreadId != OVR::GetCurrentThreadId(),
|
nuclear@0
|
188 ("%s called on a different thread then ovrHmd_BeginFrame.", functionName));
|
nuclear@0
|
189 }
|
nuclear@0
|
190
|
nuclear@0
|
191 void checkRenderingConfigured(const char* functionName)
|
nuclear@0
|
192 {
|
nuclear@0
|
193 OVR_UNUSED1(functionName); // for Release build.
|
nuclear@0
|
194 OVR_ASSERT_LOG(RenderingConfigured == true,
|
nuclear@0
|
195 ("%s called without ovrHmd_ConfigureRendering.", functionName));
|
nuclear@0
|
196 }
|
nuclear@0
|
197
|
nuclear@0
|
198 void checkBeginFrameTimingScope(const char* functionName)
|
nuclear@0
|
199 {
|
nuclear@0
|
200 OVR_UNUSED1(functionName); // for Release build.
|
nuclear@0
|
201 OVR_ASSERT_LOG(BeginFrameTimingCalled == true,
|
nuclear@0
|
202 ("%s called outside ovrHmd_BeginFrameTiming.", functionName));
|
nuclear@0
|
203 }
|
nuclear@0
|
204
|
nuclear@0
|
205 // Get properties by name.
|
nuclear@0
|
206 bool getBoolValue(const char* propertyName, bool defaultVal);
|
nuclear@0
|
207 bool setBoolValue(const char* propertyName, bool value);
|
nuclear@0
|
208 int getIntValue(const char* propertyName, int defaultVal);
|
nuclear@0
|
209 bool setIntValue(const char* propertyName, int value);
|
nuclear@0
|
210 float getFloatValue(const char* propertyName, float defaultVal);
|
nuclear@0
|
211 bool setFloatValue(const char* propertyName, float value);
|
nuclear@0
|
212 unsigned getFloatArray(const char* propertyName, float values[], unsigned arraySize);
|
nuclear@0
|
213 bool setFloatArray(const char* propertyName, float values[], unsigned arraySize);
|
nuclear@0
|
214 const char* getString(const char* propertyName, const char* defaultVal);
|
nuclear@0
|
215 bool setString(const char* propertyName, const char* value);
|
nuclear@0
|
216
|
nuclear@0
|
217 VirtualHmdId GetNetId() { return NetId; }
|
nuclear@0
|
218
|
nuclear@0
|
219 public:
|
nuclear@0
|
220 Ptr<Profile> pProfile;
|
nuclear@0
|
221 // Descriptor that gets allocated and returned to the user as ovrHmd.
|
nuclear@0
|
222 ovrHmdDesc* pHmdDesc;
|
nuclear@0
|
223 // Window handle passed in AttachWindow.
|
nuclear@0
|
224 void* pWindow;
|
nuclear@0
|
225
|
nuclear@0
|
226 // Network
|
nuclear@0
|
227 Service::NetClient* pClient;
|
nuclear@0
|
228 VirtualHmdId NetId;
|
nuclear@0
|
229 HMDNetworkInfo NetInfo;
|
nuclear@0
|
230
|
nuclear@0
|
231 // HMDInfo shouldn't change, as its string pointers are passed out.
|
nuclear@0
|
232 HMDInfo OurHMDInfo;
|
nuclear@0
|
233
|
nuclear@0
|
234 const char* pLastError;
|
nuclear@0
|
235
|
nuclear@0
|
236 // Caps enabled for the HMD.
|
nuclear@0
|
237 unsigned EnabledHmdCaps;
|
nuclear@0
|
238
|
nuclear@0
|
239 // Caps actually sent to the Sensor Service
|
nuclear@0
|
240 unsigned EnabledServiceHmdCaps;
|
nuclear@0
|
241
|
nuclear@0
|
242 // These are the flags actually applied to the Sensor device,
|
nuclear@0
|
243 // used to track whether SetDisplayReport calls are necessary.
|
nuclear@0
|
244 //unsigned HmdCapsAppliedToSensor;
|
nuclear@0
|
245
|
nuclear@0
|
246 // *** Sensor
|
nuclear@0
|
247 Tracking::CombinedSharedStateReader SharedStateReader;
|
nuclear@0
|
248 Tracking::SensorStateReader TheSensorStateReader;
|
nuclear@0
|
249 Util::RecordStateReader TheLatencyTestStateReader;
|
nuclear@0
|
250
|
nuclear@0
|
251 bool LatencyTestActive;
|
nuclear@0
|
252 unsigned char LatencyTestDrawColor[3];
|
nuclear@0
|
253
|
nuclear@0
|
254 bool LatencyTest2Active;
|
nuclear@0
|
255 unsigned char LatencyTest2DrawColor[3];
|
nuclear@0
|
256
|
nuclear@0
|
257 // Rendering part
|
nuclear@0
|
258 FrameTimeManager TimeManager;
|
nuclear@0
|
259 LagStatsCalculator LagStats;
|
nuclear@0
|
260 LatencyStatisticsCSV LagStatsCSV;
|
nuclear@0
|
261 HMDRenderState RenderState;
|
nuclear@0
|
262 Ptr<DistortionRenderer> pRenderer;
|
nuclear@0
|
263
|
nuclear@0
|
264 // Health and Safety Warning display.
|
nuclear@0
|
265 Ptr<HSWDisplay> pHSWDisplay;
|
nuclear@0
|
266
|
nuclear@0
|
267 // Last timing value reported by BeginFrame.
|
nuclear@0
|
268 double LastFrameTimeSeconds;
|
nuclear@0
|
269 // Last timing value reported by GetFrameTime. These are separate since the intended
|
nuclear@0
|
270 // use is from different threads. TBD: Move to FrameTimeManager? Make atomic?
|
nuclear@0
|
271 double LastGetFrameTimeSeconds;
|
nuclear@0
|
272
|
nuclear@0
|
273 // Last cached value returned by ovrHmd_GetString/ovrHmd_GetStringArray.
|
nuclear@0
|
274 char LastGetStringValue[256];
|
nuclear@0
|
275
|
nuclear@0
|
276 // Debug flag set after ovrHmd_ConfigureRendering succeeds.
|
nuclear@0
|
277 bool RenderingConfigured;
|
nuclear@0
|
278 // Set after BeginFrame succeeds, and its corresponding thread id for debug checks.
|
nuclear@0
|
279 bool BeginFrameCalled;
|
nuclear@0
|
280 ThreadId BeginFrameThreadId;
|
nuclear@0
|
281 // Graphics functions are not re-entrant from other threads.
|
nuclear@0
|
282 ThreadChecker RenderAPIThreadChecker;
|
nuclear@0
|
283 //
|
nuclear@0
|
284 bool BeginFrameTimingCalled;
|
nuclear@0
|
285 };
|
nuclear@0
|
286
|
nuclear@0
|
287
|
nuclear@0
|
288
|
nuclear@0
|
289
|
nuclear@0
|
290 //I appreciate this isn't an idea place for this function prototype, but needed
|
nuclear@0
|
291 //to be seen by OVR_CAPI.cpp and the various SDK renderers of CAPI,
|
nuclear@0
|
292 //and have everything defined. Please move to a better place if you know of one.
|
nuclear@0
|
293 ovrBool ovrHmd_CreateDistortionMeshInternal( ovrHmdStruct * hmd,
|
nuclear@0
|
294 ovrEyeType eyeType, ovrFovPort fov,
|
nuclear@0
|
295 unsigned int distortionCaps,
|
nuclear@0
|
296 ovrDistortionMesh *meshData,
|
nuclear@0
|
297 float overrideEyeReliefIfNonZero=0 );
|
nuclear@0
|
298
|
nuclear@0
|
299
|
nuclear@0
|
300
|
nuclear@0
|
301
|
nuclear@0
|
302 }} // namespace OVR::CAPI
|
nuclear@0
|
303
|
nuclear@0
|
304 #endif // OVR_CAPI_HMDState_h
|