From d9a584844a60542519d813b5dc1a62428f14a0ae Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Thu, 19 Jun 2014 17:03:28 +0200
Subject: Add OculusSDK 0.3.2 Linux Source Code w/o Samples, docs or binaries
 (libs or tools)

---
 LibOVR/Src/CAPI/CAPI_FrameTimeManager.h | 264 ++++++++++++++++++++++++++++++++
 1 file changed, 264 insertions(+)
 create mode 100644 LibOVR/Src/CAPI/CAPI_FrameTimeManager.h

(limited to 'LibOVR/Src/CAPI/CAPI_FrameTimeManager.h')

diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h
new file mode 100644
index 0000000..4693697
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h
@@ -0,0 +1,264 @@
+/************************************************************************************
+
+Filename    :   CAPI_FrameTimeManager.h
+Content     :   Manage frame timing and pose prediction for rendering
+Created     :   November 30, 2013
+Authors     :   Volga Aksoy, Michael Antonov
+
+Copyright   :   Copyright 2014 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License"); 
+you may not use the Oculus VR Rift SDK except in compliance with the License, 
+which is provided at the time of installation or download, or which 
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.1 
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK 
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#ifndef OVR_CAPI_FrameTimeManager_h
+#define OVR_CAPI_FrameTimeManager_h
+
+#include "../OVR_CAPI.h"
+#include "../Kernel/OVR_Timer.h"
+#include "../Kernel/OVR_Math.h"
+#include "../Util/Util_Render_Stereo.h"
+#include "../Util/Util_LatencyTest2.h"
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+
+// Helper class to collect median times between frames, so that we know
+// how long to wait. 
+struct TimeDeltaCollector
+{
+    TimeDeltaCollector() : Count(0) { }
+
+    void    AddTimeDelta(double timeSeconds);    
+    void    Clear() { Count = 0; }    
+
+    double  GetMedianTimeDelta() const;
+
+    double  GetCount() const { return Count; }
+
+    enum { Capacity = 12 };
+private:    
+    int     Count;
+    double  TimeBufferSeconds[Capacity];
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** FrameLatencyTracker
+
+// FrameLatencyTracker tracks frame Present to display Scan-out timing, as reported by
+// the DK2 internal latency tester pixel read-back. The computed value is used in
+// FrameTimeManager for prediction. View Render and TimeWarp to scan-out latencies are
+// also reported for debugging.
+//
+// The class operates by generating color values from GetNextDrawColor() that must
+// be rendered on the back end and then looking for matching values in FrameTimeRecordSet
+// structure as reported by HW.
+
+class FrameLatencyTracker
+{
+public:
+
+    enum { FramesTracked = Util::LT2_IncrementCount-1 };
+
+    FrameLatencyTracker();
+
+    // DrawColor == 0 is special in that it doesn't need saving of timestamp
+    unsigned char GetNextDrawColor();
+
+    void SaveDrawColor(unsigned char drawColor, double endFrameTime,
+                       double renderIMUTime, double timewarpIMUTime );
+
+    void MatchRecord(const Util::FrameTimeRecordSet &r);   
+
+    void GetLatencyTimings(float latencies[3]);
+
+    void Reset();
+
+public:
+
+    struct FrameTimeRecordEx : public Util::FrameTimeRecord
+    {
+        bool    MatchedRecord;
+        double  RenderIMUTimeSeconds;
+        double  TimewarpIMUTimeSeconds;
+    };
+
+    // True if rendering read-back is enabled.
+    bool                  TrackerEnabled;
+
+    enum SampleWaitType {
+        SampleWait_Zeroes, // We are waiting for a record with all zeros.
+        SampleWait_Match   // We are issuing & matching colors.
+    };
+    
+    SampleWaitType        WaitMode;
+    int                   MatchCount;
+    // Records of frame timings that we are trying to measure.
+    FrameTimeRecordEx     FrameEndTimes[FramesTracked];
+    int                   FrameIndex;
+    // Median filter for (ScanoutTimeSeconds - PostPresent frame time)
+    TimeDeltaCollector    FrameDeltas;
+    // Latency reporting results
+    double                RenderLatencySeconds;
+    double                TimewarpLatencySeconds;
+    double                LatencyRecordTime;
+};
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** FrameTimeManager
+
+// FrameTimeManager keeps track of rendered frame timing and handles predictions for
+// orientations and time-warp.
+
+class FrameTimeManager
+{
+public:
+    FrameTimeManager(bool vsyncEnabled = true);
+
+    // Data that affects frame timing computation.
+    struct TimingInputs
+    {
+        // Hard-coded value or dynamic as reported by FrameTimeDeltas.GetMedianTimeDelta().
+        double              FrameDelta;
+        // Screen delay from present to scan-out, as potentially reported by ScreenLatencyTracker.
+        double              ScreenDelay;
+        // Negative value of how many seconds before EndFrame we start timewarp. 0.0 if not used.
+        double              TimewarpWaitDelta;
+        
+        TimingInputs()
+            : FrameDelta(0), ScreenDelay(0), TimewarpWaitDelta(0)
+        { }
+    };
+
+    // Timing values for a specific frame.
+    struct Timing
+    {
+        TimingInputs        Inputs;
+        
+        // Index of a frame that started at ThisFrameTime.
+        unsigned int        FrameIndex;
+        // Predicted absolute times for when this frame will show up on screen.
+        // Generally, all values will be >= NextFrameTime, since that's the time we expect next
+        // vsync to succeed.
+        double              ThisFrameTime;
+        double              TimewarpPointTime;
+        double              NextFrameTime;        
+        double              MidpointTime;
+        double              EyeRenderTimes[2];
+        double              TimeWarpStartEndTimes[2][2];
+
+        Timing()
+        {
+            memset(this, 0, sizeof(Timing));
+        }
+
+        void InitTimingFromInputs(const TimingInputs& inputs, HmdShutterTypeEnum shutterType,
+                                  double thisFrameTime, unsigned int frameIndex);
+    };
+
+   
+    // Called on startup to provided data on HMD timing.
+    void    Init(HmdRenderInfo& renderInfo);
+
+    // Called with each new ConfigureRendering.
+    void    ResetFrameTiming(unsigned frameIndex,
+                             bool dynamicPrediction, bool sdkRender);
+
+    void    SetVsync(bool enabled) { VsyncEnabled = enabled; }
+
+    // BeginFrame returns time of the call
+    // TBD: Should this be a predicted time value instead ?
+    double  BeginFrame(unsigned frameIndex);
+    void    EndFrame();    
+
+    // Thread-safe function to query timing for a future frame
+    Timing  GetFrameTiming(unsigned frameIndex);
+ 
+    double  GetEyePredictionTime(ovrEyeType eye);
+    Transformf GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye);
+
+    void    GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]); 
+    void    GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
+
+    // Used by renderer to determine if it should time distortion rendering.
+    bool    NeedDistortionTimeMeasurement() const;
+    void    AddDistortionTimeMeasurement(double distortionTimeSeconds);
+
+    
+    // DK2 Lateny test interface
+
+    // Get next draw color for DK2 latency tester
+    unsigned char GetFrameLatencyTestDrawColor()
+    { return ScreenLatencyTracker.GetNextDrawColor(); }
+
+    // Must be called after EndFrame() to update latency tester timings.
+    // Must pass color reported by NextFrameColor for this frame.
+    void    UpdateFrameLatencyTrackingAfterEndFrame(unsigned char frameLatencyTestColor,
+                                                    const Util::FrameTimeRecordSet& rs);
+
+    void    GetLatencyTimings(float latencies[3])
+    { return ScreenLatencyTracker.GetLatencyTimings(latencies); }
+
+
+    const Timing& GetFrameTiming() const { return FrameTiming; }
+
+private:
+
+    double  calcFrameDelta() const;
+    double  calcScreenDelay() const;
+    double  calcTimewarpWaitDelta() const;    
+    
+    
+    HmdRenderInfo       RenderInfo;
+    // Timings are collected through a median filter, to avoid outliers.
+    TimeDeltaCollector  FrameTimeDeltas;
+    TimeDeltaCollector  DistortionRenderTimes;
+    FrameLatencyTracker ScreenLatencyTracker;
+
+    // Timing changes if we have no Vsync (all prediction is reduced to fixed interval).
+    bool                VsyncEnabled;
+    // Set if we are rendering via the SDK, so DistortionRenderTimes is valid.
+    bool                DynamicPrediction;
+    // Set if SDk is doing teh rendering.
+    bool                SdkRender;
+
+    // Total frame delay due to VsyncToFirstScanline, persistence and settle time.
+    // Computed from RenderInfor.Shutter.
+    double              VSyncToScanoutDelay;
+    double              NoVSyncToScanoutDelay;
+    double              ScreenSwitchingDelay;
+
+    // Current (or last) frame timing info. Used as a source for LocklessTiming.
+    Timing                  FrameTiming;
+    // TBD: Don't we need NextFrame here as well?
+    LocklessUpdater<Timing> LocklessTiming;
+
+
+    // IMU Read timings
+    double              RenderIMUTimeSeconds;
+    double              TimewarpIMUTimeSeconds;
+};
+
+
+}} // namespace OVR::CAPI
+
+#endif // OVR_CAPI_FrameTimeManager_h
+
+
-- 
cgit v1.2.3