blob: 842d7fb640b4afa69677c63ede8e7027b4abc8dc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/************************************************************************************
Filename : CAPI_FrameLatencyTracker.h
Content : DK2 Latency Tester implementation
Created : Dec 12, 2013
Authors : Volga Aksoy, Michael Antonov
Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
Licensed under the Oculus VR Rift SDK License Version 3.2 (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.2
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_FrameLatencyTracker_h
#define OVR_CAPI_FrameLatencyTracker_h
#include <OVR_CAPI.h>
#include <Kernel/OVR_Timer.h>
#include <Extras/OVR_Math.h>
#include <Util/Util_Render_Stereo.h>
#include "CAPI_FrameTimeManager3.h"
namespace OVR { namespace CAPI {
//-------------------------------------------------------------------------------------
// ***** FrameLatencyData
// This structure contains the timing data for each frame that is tracked by the
// latency tester.
struct FrameLatencyData
{
uint8_t DrawColor; // Red channel color value drawn for the latency tester quad for this frame
double PresentTime; // (seconds) Time at which Vsync/Present occurred
double RenderIMUTime; // (seconds) Time when hardware sensors were sampled for render pose
double TimewarpIMUTime; // (seconds) Time when hardware sensors were sampled for timewarp pose
double TimewarpPredictedScanoutTime; // (seconds) Time at which we expected scanout to start at timewarp time
double RenderPredictedScanoutTime; // (seconds) Time at which we expected scanout to start at render time
};
//-------------------------------------------------------------------------------------
// ***** OutputLatencyTimings
// Latency timings returned to the application.
struct OutputLatencyTimings
{
double LatencyRender; // (seconds) Last time between render IMU sample and scanout
double LatencyTimewarp; // (seconds) Last time between timewarp IMU sample and scanout
double LatencyPostPresent; // (seconds) Average time between Vsync and scanout
double ErrorRender; // (seconds) Last error in render predicted scanout time
double ErrorTimewarp; // (seconds) Last error in timewarp predicted scanout time
void Clear()
{
LatencyRender = 0.;
LatencyTimewarp = 0.;
LatencyPostPresent = 0.;
ErrorRender = 0.;
ErrorTimewarp = 0.;
}
};
//-------------------------------------------------------------------------------------
// ***** 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(FrameLatencyData const & data);
void MatchRecord(Util::FrameTimeRecordSet const & r);
bool IsLatencyTimingAvailable();
void GetLatencyTimings(OutputLatencyTimings& timings);
// Returns time between vsync and scanout in seconds as measured by DK2 latency tester.
// Returns false if measurements are unavailable.
bool GetVsyncToScanout(double& vsyncToScanoutTime) const;
void Reset();
protected:
struct FrameTimeRecordEx : public Util::FrameTimeRecord
{
bool MatchedRecord;
FrameLatencyData FrameData;
};
void onRecordMatch(FrameTimeRecordEx& renderFrame,
Util::FrameTimeRecord const& scanoutFrame);
// 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 History[FramesTracked];
int FrameIndex;
// Median filter for (ScanoutTimeSeconds - PostPresent frame time)
mutable OVR::CAPI::FTM3::MedianCalculator FrameDeltas;
double LatencyRecordTime;
// Latency reporting results
OutputLatencyTimings OutputTimings;
};
}} // namespace OVR::CAPI
#endif // OVR_CAPI_FrameLatencyTracker_h
|