Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CAPI_FrameTimeManager.h
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : CAPI_FrameTimeManager.h
4 Content : Manage frame timing and pose prediction for rendering
5 Created : November 30, 2013
6 Authors : Volga Aksoy, 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 #ifndef OVR_CAPI_FrameTimeManager_h
28 #define OVR_CAPI_FrameTimeManager_h
29 
30 #include "../OVR_CAPI.h"
31 #include "../Kernel/OVR_Timer.h"
32 #include "../Kernel/OVR_Math.h"
33 #include "../Util/Util_Render_Stereo.h"
34 #include "../Util/Util_LatencyTest2.h"
35 
36 namespace OVR { namespace CAPI {
37 
38 //-------------------------------------------------------------------------------------
39 
40 // Helper class to collect median times between frames, so that we know
41 // how long to wait.
43 {
45 
46  void AddTimeDelta(double timeSeconds);
47  void Clear() { Count = 0; }
48 
49  double GetMedianTimeDelta() const;
50 
51  double GetCount() const { return Count; }
52 
53  enum { Capacity = 12 };
54 private:
55  int Count;
57 };
58 
59 
60 //-------------------------------------------------------------------------------------
61 // ***** FrameLatencyTracker
62 
63 // FrameLatencyTracker tracks frame Present to display Scan-out timing, as reported by
64 // the DK2 internal latency tester pixel read-back. The computed value is used in
65 // FrameTimeManager for prediction. View Render and TimeWarp to scan-out latencies are
66 // also reported for debugging.
67 //
68 // The class operates by generating color values from GetNextDrawColor() that must
69 // be rendered on the back end and then looking for matching values in FrameTimeRecordSet
70 // structure as reported by HW.
71 
73 {
74 public:
75 
77 
79 
80  // DrawColor == 0 is special in that it doesn't need saving of timestamp
81  unsigned char GetNextDrawColor();
82 
83  void SaveDrawColor(unsigned char drawColor, double endFrameTime,
84  double renderIMUTime, double timewarpIMUTime );
85 
87 
88  void GetLatencyTimings(float latencies[3]);
89 
90  void Reset();
91 
92 public:
93 
95  {
99  };
100 
101  // True if rendering read-back is enabled.
103 
105  SampleWait_Zeroes, // We are waiting for a record with all zeros.
106  SampleWait_Match // We are issuing & matching colors.
107  };
108 
111  // Records of frame timings that we are trying to measure.
114  // Median filter for (ScanoutTimeSeconds - PostPresent frame time)
116  // Latency reporting results
120 };
121 
122 
123 
124 //-------------------------------------------------------------------------------------
125 // ***** FrameTimeManager
126 
127 // FrameTimeManager keeps track of rendered frame timing and handles predictions for
128 // orientations and time-warp.
129 
131 {
132 public:
133  FrameTimeManager(bool vsyncEnabled = true);
134 
135  // Data that affects frame timing computation.
137  {
138  // Hard-coded value or dynamic as reported by FrameTimeDeltas.GetMedianTimeDelta().
139  double FrameDelta;
140  // Screen delay from present to scan-out, as potentially reported by ScreenLatencyTracker.
141  double ScreenDelay;
142  // Negative value of how many seconds before EndFrame we start timewarp. 0.0 if not used.
144 
147  { }
148  };
149 
150  // Timing values for a specific frame.
151  struct Timing
152  {
154 
155  // Index of a frame that started at ThisFrameTime.
156  unsigned int FrameIndex;
157  // Predicted absolute times for when this frame will show up on screen.
158  // Generally, all values will be >= NextFrameTime, since that's the time we expect next
159  // vsync to succeed.
162  double NextFrameTime;
163  double MidpointTime;
164  double EyeRenderTimes[2];
165  double TimeWarpStartEndTimes[2][2];
166 
168  {
169  memset(this, 0, sizeof(Timing));
170  }
171 
172  void InitTimingFromInputs(const TimingInputs& inputs, HmdShutterTypeEnum shutterType,
173  double thisFrameTime, unsigned int frameIndex);
174  };
175 
176 
177  // Called on startup to provided data on HMD timing.
178  void Init(HmdRenderInfo& renderInfo);
179 
180  // Called with each new ConfigureRendering.
181  void ResetFrameTiming(unsigned frameIndex,
182  bool dynamicPrediction, bool sdkRender);
183 
184  void SetVsync(bool enabled) { VsyncEnabled = enabled; }
185 
186  // BeginFrame returns time of the call
187  // TBD: Should this be a predicted time value instead ?
188  double BeginFrame(unsigned frameIndex);
189  void EndFrame();
190 
191  // Thread-safe function to query timing for a future frame
192  Timing GetFrameTiming(unsigned frameIndex);
193 
194  double GetEyePredictionTime(ovrEyeType eye);
196 
197  void GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]);
198  void GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
199 
200  // Used by renderer to determine if it should time distortion rendering.
201  bool NeedDistortionTimeMeasurement() const;
202  void AddDistortionTimeMeasurement(double distortionTimeSeconds);
203 
204 
205  // DK2 Lateny test interface
206 
207  // Get next draw color for DK2 latency tester
210 
211  // Must be called after EndFrame() to update latency tester timings.
212  // Must pass color reported by NextFrameColor for this frame.
213  void UpdateFrameLatencyTrackingAfterEndFrame(unsigned char frameLatencyTestColor,
214  const Util::FrameTimeRecordSet& rs);
215 
216  void GetLatencyTimings(float latencies[3])
217  { return ScreenLatencyTracker.GetLatencyTimings(latencies); }
218 
219 
220  const Timing& GetFrameTiming() const { return FrameTiming; }
221 
222 private:
223 
224  double calcFrameDelta() const;
225  double calcScreenDelay() const;
226  double calcTimewarpWaitDelta() const;
227 
228 
230  // Timings are collected through a median filter, to avoid outliers.
234 
235  // Timing changes if we have no Vsync (all prediction is reduced to fixed interval).
237  // Set if we are rendering via the SDK, so DistortionRenderTimes is valid.
239  // Set if SDk is doing teh rendering.
240  bool SdkRender;
241 
242  // Total frame delay due to VsyncToFirstScanline, persistence and settle time.
243  // Computed from RenderInfor.Shutter.
247 
248  // Current (or last) frame timing info. Used as a source for LocklessTiming.
250  // TBD: Don't we need NextFrame here as well?
252 
253 
254  // IMU Read timings
257 };
258 
259 
260 }} // namespace OVR::CAPI
261 
262 #endif // OVR_CAPI_FrameTimeManager_h
263 
264 
void InitTimingFromInputs(const TimingInputs &inputs, HmdShutterTypeEnum shutterType, double thisFrameTime, unsigned int frameIndex)
void GetLatencyTimings(float latencies[3])
FrameTimeRecordEx FrameEndTimes[FramesTracked]
const Timing & GetFrameTiming() const
void SaveDrawColor(unsigned char drawColor, double endFrameTime, double renderIMUTime, double timewarpIMUTime)
double GetEyePredictionTime(ovrEyeType eye)
Transformf GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye)
TimeDeltaCollector DistortionRenderTimes
void Init(HmdRenderInfo &renderInfo)
FrameLatencyTracker ScreenLatencyTracker
ovrEyeType
Definition: OVR_CAPI.h:177
unsigned char GetFrameLatencyTestDrawColor()
void AddDistortionTimeMeasurement(double distortionTimeSeconds)
Definition: edid.h:54
void GetLatencyTimings(float latencies[3])
void GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2])
double BeginFrame(unsigned frameIndex)
void UpdateFrameLatencyTrackingAfterEndFrame(unsigned char frameLatencyTestColor, const Util::FrameTimeRecordSet &rs)
void AddTimeDelta(double timeSeconds)
void ResetFrameTiming(unsigned frameIndex, bool dynamicPrediction, bool sdkRender)
__BEGIN_NAMESPACE_STD void void __END_NAMESPACE_STD void __BEGIN_NAMESPACE_STD void * memset(void *__s, int __c, size_t __n) __THROW __nonnull((1))
void MatchRecord(const Util::FrameTimeRecordSet &r)
FrameTimeManager(bool vsyncEnabled=true)
LocklessUpdater< Timing > LocklessTiming
void GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2])