1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program EGL Module
3*35238bceSAndroid Build Coastguard Worker * ---------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2017 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Test the EGL_ANDROID_get_frame_timestamps extension.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "teglGetFrameTimestampsTests.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "teglSimpleConfigCase.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "egluNativeWindow.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "egluUtil.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "egluUnique.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "eglwLibrary.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "eglwEnums.hpp"
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker #include "gluDefs.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
37*35238bceSAndroid Build Coastguard Worker
38*35238bceSAndroid Build Coastguard Worker #include "tcuResultCollector.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "tcuTexture.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
45*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
46*35238bceSAndroid Build Coastguard Worker
47*35238bceSAndroid Build Coastguard Worker #include "deClock.h"
48*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
49*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
50*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
51*35238bceSAndroid Build Coastguard Worker #include "deThread.hpp"
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker #include <algorithm>
54*35238bceSAndroid Build Coastguard Worker #include <string>
55*35238bceSAndroid Build Coastguard Worker #include <vector>
56*35238bceSAndroid Build Coastguard Worker #include <sstream>
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker // Tentative EGL header definitions for EGL_ANDROID_get_Frame_timestamps.
59*35238bceSAndroid Build Coastguard Worker // \todo [2017-01-25 brianderson] Remove once defined in the official headers.
60*35238bceSAndroid Build Coastguard Worker #define EGL_TIMESTAMPS_ANDROID 0x3430
61*35238bceSAndroid Build Coastguard Worker #define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431
62*35238bceSAndroid Build Coastguard Worker #define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432
63*35238bceSAndroid Build Coastguard Worker #define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433
64*35238bceSAndroid Build Coastguard Worker #define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434
65*35238bceSAndroid Build Coastguard Worker #define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435
66*35238bceSAndroid Build Coastguard Worker #define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436
67*35238bceSAndroid Build Coastguard Worker #define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437
68*35238bceSAndroid Build Coastguard Worker #define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438
69*35238bceSAndroid Build Coastguard Worker #define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439
70*35238bceSAndroid Build Coastguard Worker #define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A
71*35238bceSAndroid Build Coastguard Worker #define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B
72*35238bceSAndroid Build Coastguard Worker #define EGL_READS_DONE_TIME_ANDROID 0x343C
73*35238bceSAndroid Build Coastguard Worker typedef int64_t EGLnsecsANDROID;
74*35238bceSAndroid Build Coastguard Worker typedef uint64_t EGLuint64KHR;
75*35238bceSAndroid Build Coastguard Worker #define EGL_TIMESTAMP_PENDING_ANDROID (-2)
76*35238bceSAndroid Build Coastguard Worker #define EGL_TIMESTAMP_INVALID_ANDROID (-1)
77*35238bceSAndroid Build Coastguard Worker typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglGetNextFrameIdANDROIDFunc)(eglw::EGLDisplay dpy,
78*35238bceSAndroid Build Coastguard Worker eglw::EGLSurface surface,
79*35238bceSAndroid Build Coastguard Worker EGLuint64KHR *frameId);
80*35238bceSAndroid Build Coastguard Worker typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglGetCompositorTimingANDROIDFunc)(eglw::EGLDisplay dpy,
81*35238bceSAndroid Build Coastguard Worker eglw::EGLSurface surface,
82*35238bceSAndroid Build Coastguard Worker eglw::EGLint numTimestamps,
83*35238bceSAndroid Build Coastguard Worker const eglw::EGLint *names,
84*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID *values);
85*35238bceSAndroid Build Coastguard Worker typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglGetCompositorTimingSupportedANDROIDFunc)(
86*35238bceSAndroid Build Coastguard Worker eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint name);
87*35238bceSAndroid Build Coastguard Worker typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglGetFrameTimestampsANDROIDFunc)(
88*35238bceSAndroid Build Coastguard Worker eglw::EGLDisplay dpy, eglw::EGLSurface surface, EGLuint64KHR frameId, eglw::EGLint numTimestamps,
89*35238bceSAndroid Build Coastguard Worker const eglw::EGLint *timestamps, EGLnsecsANDROID *values);
90*35238bceSAndroid Build Coastguard Worker typedef EGLW_APICALL eglw::EGLBoolean(EGLW_APIENTRY *eglGetFrameTimestampSupportedANDROIDFunc)(eglw::EGLDisplay dpy,
91*35238bceSAndroid Build Coastguard Worker eglw::EGLSurface surface,
92*35238bceSAndroid Build Coastguard Worker eglw::EGLint timestamp);
93*35238bceSAndroid Build Coastguard Worker
94*35238bceSAndroid Build Coastguard Worker #define CHECK_NAKED_EGL_CALL(EGLW, CALL) \
95*35238bceSAndroid Build Coastguard Worker do \
96*35238bceSAndroid Build Coastguard Worker { \
97*35238bceSAndroid Build Coastguard Worker CALL; \
98*35238bceSAndroid Build Coastguard Worker eglu::checkError((EGLW).getError(), #CALL, __FILE__, __LINE__); \
99*35238bceSAndroid Build Coastguard Worker } while (false)
100*35238bceSAndroid Build Coastguard Worker
101*35238bceSAndroid Build Coastguard Worker namespace deqp
102*35238bceSAndroid Build Coastguard Worker {
103*35238bceSAndroid Build Coastguard Worker namespace egl
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker using std::string;
107*35238bceSAndroid Build Coastguard Worker using std::vector;
108*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
109*35238bceSAndroid Build Coastguard Worker using namespace eglw;
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker namespace
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker
114*35238bceSAndroid Build Coastguard Worker // Careful: This has microsecond precision, which can cause timestamps to
115*35238bceSAndroid Build Coastguard Worker // appear non monotonic when compared to the nanosecond precision timestamps
116*35238bceSAndroid Build Coastguard Worker // we get from the eglGetFrameTimestamps extension.
117*35238bceSAndroid Build Coastguard Worker // Current test expectations only make sure microsecond precision timestamps
118*35238bceSAndroid Build Coastguard Worker // are less than the nanosecond precision timestamps, so this is okay.
getNanoseconds(void)119*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID getNanoseconds(void)
120*35238bceSAndroid Build Coastguard Worker {
121*35238bceSAndroid Build Coastguard Worker return deGetMicroseconds() * 1000;
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker
124*35238bceSAndroid Build Coastguard Worker struct FrameTimes
125*35238bceSAndroid Build Coastguard Worker {
FrameTimesdeqp::egl::__anond7b7b1f10111::FrameTimes126*35238bceSAndroid Build Coastguard Worker FrameTimes(void)
127*35238bceSAndroid Build Coastguard Worker : frameId(-1)
128*35238bceSAndroid Build Coastguard Worker , swapBufferBeginNs(-1)
129*35238bceSAndroid Build Coastguard Worker , compositeDeadline(-1)
130*35238bceSAndroid Build Coastguard Worker , compositeInterval(-1)
131*35238bceSAndroid Build Coastguard Worker , compositeToPresentLatency(-1)
132*35238bceSAndroid Build Coastguard Worker , requestedPresent(-1)
133*35238bceSAndroid Build Coastguard Worker , latch(-1)
134*35238bceSAndroid Build Coastguard Worker , firstCompositionStart(-1)
135*35238bceSAndroid Build Coastguard Worker , lastCompositionStart(-1)
136*35238bceSAndroid Build Coastguard Worker , dequeueReady(-1)
137*35238bceSAndroid Build Coastguard Worker , renderingComplete(-1)
138*35238bceSAndroid Build Coastguard Worker , firstCompositionGpuFinished(-1)
139*35238bceSAndroid Build Coastguard Worker , displayPresent(-1)
140*35238bceSAndroid Build Coastguard Worker , readsDone(-1)
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
144*35238bceSAndroid Build Coastguard Worker EGLuint64KHR frameId;
145*35238bceSAndroid Build Coastguard Worker
146*35238bceSAndroid Build Coastguard Worker // Timestamps sampled by the test.
147*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID swapBufferBeginNs;
148*35238bceSAndroid Build Coastguard Worker
149*35238bceSAndroid Build Coastguard Worker // Compositor info.
150*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID compositeDeadline;
151*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID compositeInterval;
152*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID compositeToPresentLatency;
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Worker // CPU Timeline.
155*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID requestedPresent;
156*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID latch;
157*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID firstCompositionStart;
158*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID lastCompositionStart;
159*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID dequeueReady;
160*35238bceSAndroid Build Coastguard Worker
161*35238bceSAndroid Build Coastguard Worker // GPU Timeline.
162*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID renderingComplete;
163*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID firstCompositionGpuFinished;
164*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID displayPresent;
165*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID readsDone;
166*35238bceSAndroid Build Coastguard Worker };
167*35238bceSAndroid Build Coastguard Worker
168*35238bceSAndroid Build Coastguard Worker struct TimestampInfo
169*35238bceSAndroid Build Coastguard Worker {
TimestampInfodeqp::egl::__anond7b7b1f10111::TimestampInfo170*35238bceSAndroid Build Coastguard Worker TimestampInfo() : required(false), supported(false), supportedIndex(0)
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker
TimestampInfodeqp::egl::__anond7b7b1f10111::TimestampInfo174*35238bceSAndroid Build Coastguard Worker TimestampInfo(bool required_, bool supported_, size_t supportedIndex_)
175*35238bceSAndroid Build Coastguard Worker : required(required_)
176*35238bceSAndroid Build Coastguard Worker , supported(supported_)
177*35238bceSAndroid Build Coastguard Worker , supportedIndex(supportedIndex_)
178*35238bceSAndroid Build Coastguard Worker {
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker
181*35238bceSAndroid Build Coastguard Worker bool required;
182*35238bceSAndroid Build Coastguard Worker bool supported;
183*35238bceSAndroid Build Coastguard Worker size_t supportedIndex;
184*35238bceSAndroid Build Coastguard Worker };
185*35238bceSAndroid Build Coastguard Worker
186*35238bceSAndroid Build Coastguard Worker typedef std::map<eglw::EGLint, TimestampInfo> TimestampInfoMap;
187*35238bceSAndroid Build Coastguard Worker
getTimestamp(eglw::EGLint name,TimestampInfoMap & map,const std::vector<EGLnsecsANDROID> & supportedValues)188*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID getTimestamp(eglw::EGLint name, TimestampInfoMap &map,
189*35238bceSAndroid Build Coastguard Worker const std::vector<EGLnsecsANDROID> &supportedValues)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker TimestampInfo &info = map[name];
192*35238bceSAndroid Build Coastguard Worker return info.supported ? supportedValues[info.supportedIndex] : EGL_TIMESTAMP_INVALID_ANDROID;
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker
populateFrameTimes(FrameTimes * frameTimes,TimestampInfoMap & map,const std::vector<EGLnsecsANDROID> & supportedValues)195*35238bceSAndroid Build Coastguard Worker void populateFrameTimes(FrameTimes *frameTimes, TimestampInfoMap &map,
196*35238bceSAndroid Build Coastguard Worker const std::vector<EGLnsecsANDROID> &supportedValues)
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker frameTimes->requestedPresent = getTimestamp(EGL_REQUESTED_PRESENT_TIME_ANDROID, map, supportedValues);
199*35238bceSAndroid Build Coastguard Worker frameTimes->renderingComplete = getTimestamp(EGL_RENDERING_COMPLETE_TIME_ANDROID, map, supportedValues);
200*35238bceSAndroid Build Coastguard Worker frameTimes->latch = getTimestamp(EGL_COMPOSITION_LATCH_TIME_ANDROID, map, supportedValues);
201*35238bceSAndroid Build Coastguard Worker frameTimes->firstCompositionStart = getTimestamp(EGL_FIRST_COMPOSITION_START_TIME_ANDROID, map, supportedValues);
202*35238bceSAndroid Build Coastguard Worker frameTimes->lastCompositionStart = getTimestamp(EGL_LAST_COMPOSITION_START_TIME_ANDROID, map, supportedValues);
203*35238bceSAndroid Build Coastguard Worker frameTimes->firstCompositionGpuFinished =
204*35238bceSAndroid Build Coastguard Worker getTimestamp(EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID, map, supportedValues);
205*35238bceSAndroid Build Coastguard Worker frameTimes->displayPresent = getTimestamp(EGL_DISPLAY_PRESENT_TIME_ANDROID, map, supportedValues);
206*35238bceSAndroid Build Coastguard Worker frameTimes->dequeueReady = getTimestamp(EGL_DEQUEUE_READY_TIME_ANDROID, map, supportedValues);
207*35238bceSAndroid Build Coastguard Worker frameTimes->readsDone = getTimestamp(EGL_READS_DONE_TIME_ANDROID, map, supportedValues);
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker
timestampValid(EGLnsecsANDROID timestamp)210*35238bceSAndroid Build Coastguard Worker bool timestampValid(EGLnsecsANDROID timestamp)
211*35238bceSAndroid Build Coastguard Worker {
212*35238bceSAndroid Build Coastguard Worker // \todo [2017-10-19 brianderson] Don't consider 0 invalid once kernel fix is in.
213*35238bceSAndroid Build Coastguard Worker return (timestamp > 0) || (timestamp == EGL_TIMESTAMP_PENDING_ANDROID);
214*35238bceSAndroid Build Coastguard Worker }
215*35238bceSAndroid Build Coastguard Worker
timestampPending(EGLnsecsANDROID timestamp)216*35238bceSAndroid Build Coastguard Worker bool timestampPending(EGLnsecsANDROID timestamp)
217*35238bceSAndroid Build Coastguard Worker {
218*35238bceSAndroid Build Coastguard Worker return timestamp == EGL_TIMESTAMP_PENDING_ANDROID;
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker
221*35238bceSAndroid Build Coastguard Worker template <typename T>
check_lt(tcu::ResultCollector & result,const T & a,const T & b,const std::string & msg)222*35238bceSAndroid Build Coastguard Worker void check_lt(tcu::ResultCollector &result, const T &a, const T &b, const std::string &msg)
223*35238bceSAndroid Build Coastguard Worker {
224*35238bceSAndroid Build Coastguard Worker if (a < b)
225*35238bceSAndroid Build Coastguard Worker return;
226*35238bceSAndroid Build Coastguard Worker std::string m = msg + "!(" + de::toString(a) + " < " + de::toString(b) + ")";
227*35238bceSAndroid Build Coastguard Worker result.fail(m);
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker template <typename T>
check_le(tcu::ResultCollector & result,const T & a,const T & b,const std::string & msg)231*35238bceSAndroid Build Coastguard Worker void check_le(tcu::ResultCollector &result, const T &a, const T &b, const std::string &msg)
232*35238bceSAndroid Build Coastguard Worker {
233*35238bceSAndroid Build Coastguard Worker if (a <= b)
234*35238bceSAndroid Build Coastguard Worker return;
235*35238bceSAndroid Build Coastguard Worker std::string m = msg + "!(" + de::toString(a) + " <= " + de::toString(b) + ")";
236*35238bceSAndroid Build Coastguard Worker result.fail(m);
237*35238bceSAndroid Build Coastguard Worker }
238*35238bceSAndroid Build Coastguard Worker
verifySingleFrame(const FrameTimes & frameTimes,tcu::ResultCollector & result,bool verifyReadsDone)239*35238bceSAndroid Build Coastguard Worker void verifySingleFrame(const FrameTimes &frameTimes, tcu::ResultCollector &result, bool verifyReadsDone)
240*35238bceSAndroid Build Coastguard Worker {
241*35238bceSAndroid Build Coastguard Worker // Verify CPU timeline is monotonic.
242*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.swapBufferBeginNs, frameTimes.latch, "Buffer latched before it was swapped.");
243*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.latch, frameTimes.firstCompositionStart, "Buffer composited before it was latched.");
244*35238bceSAndroid Build Coastguard Worker check_le(result, frameTimes.firstCompositionStart, frameTimes.lastCompositionStart,
245*35238bceSAndroid Build Coastguard Worker "First composition start after last composition start.");
246*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.lastCompositionStart, frameTimes.dequeueReady,
247*35238bceSAndroid Build Coastguard Worker "Buffer composited after it was ready to be dequeued.");
248*35238bceSAndroid Build Coastguard Worker
249*35238bceSAndroid Build Coastguard Worker // Verify GPU timeline is monotonic.
250*35238bceSAndroid Build Coastguard Worker if (timestampValid(frameTimes.firstCompositionGpuFinished))
251*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.renderingComplete, frameTimes.firstCompositionGpuFinished,
252*35238bceSAndroid Build Coastguard Worker "Buffer rendering completed after compositor GPU work finished.");
253*35238bceSAndroid Build Coastguard Worker
254*35238bceSAndroid Build Coastguard Worker if (timestampValid(frameTimes.displayPresent))
255*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.renderingComplete, frameTimes.displayPresent,
256*35238bceSAndroid Build Coastguard Worker "Buffer displayed before rendering completed.");
257*35238bceSAndroid Build Coastguard Worker
258*35238bceSAndroid Build Coastguard Worker if (timestampValid(frameTimes.firstCompositionGpuFinished) && timestampValid(frameTimes.displayPresent))
259*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.firstCompositionGpuFinished, frameTimes.displayPresent,
260*35238bceSAndroid Build Coastguard Worker "Buffer displayed before compositor GPU work completed");
261*35238bceSAndroid Build Coastguard Worker
262*35238bceSAndroid Build Coastguard Worker // Drivers may maintain shadow copies of the buffer, so the readsDone time
263*35238bceSAndroid Build Coastguard Worker // of the real buffer may be earlier than apparent dependencies. We can only
264*35238bceSAndroid Build Coastguard Worker // be sure that the readsDone time must be after the renderingComplete time.
265*35238bceSAndroid Build Coastguard Worker // It may also be equal to the renderingComplete time if no reads were
266*35238bceSAndroid Build Coastguard Worker // peformed.
267*35238bceSAndroid Build Coastguard Worker if (verifyReadsDone && timestampValid(frameTimes.readsDone))
268*35238bceSAndroid Build Coastguard Worker check_le(result, frameTimes.renderingComplete, frameTimes.readsDone,
269*35238bceSAndroid Build Coastguard Worker "Buffer rendering completed after reads completed.");
270*35238bceSAndroid Build Coastguard Worker
271*35238bceSAndroid Build Coastguard Worker // Verify CPU/GPU dependencies
272*35238bceSAndroid Build Coastguard Worker if (timestampValid(frameTimes.firstCompositionGpuFinished))
273*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.firstCompositionStart, frameTimes.firstCompositionGpuFinished,
274*35238bceSAndroid Build Coastguard Worker "Composition CPU work started after GPU work finished.");
275*35238bceSAndroid Build Coastguard Worker
276*35238bceSAndroid Build Coastguard Worker if (timestampValid(frameTimes.displayPresent))
277*35238bceSAndroid Build Coastguard Worker check_lt(result, frameTimes.firstCompositionStart, frameTimes.displayPresent,
278*35238bceSAndroid Build Coastguard Worker "Buffer displayed before it was composited.");
279*35238bceSAndroid Build Coastguard Worker }
280*35238bceSAndroid Build Coastguard Worker
verifyNeighboringFrames(const FrameTimes & frame1,const FrameTimes & frame2,tcu::ResultCollector & result)281*35238bceSAndroid Build Coastguard Worker void verifyNeighboringFrames(const FrameTimes &frame1, const FrameTimes &frame2, tcu::ResultCollector &result)
282*35238bceSAndroid Build Coastguard Worker {
283*35238bceSAndroid Build Coastguard Worker // CPU timeline.
284*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.swapBufferBeginNs, frame2.swapBufferBeginNs, "Swap begin times not monotonic.");
285*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.latch, frame2.latch, "Latch times not monotonic.");
286*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.lastCompositionStart, frame2.latch, "Old buffer composited after new buffer latched.");
287*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.lastCompositionStart, frame2.firstCompositionStart, "Composition times overlap.");
288*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.dequeueReady, frame2.dequeueReady, "Dequeue ready times not monotonic.");
289*35238bceSAndroid Build Coastguard Worker
290*35238bceSAndroid Build Coastguard Worker // GPU timeline.
291*35238bceSAndroid Build Coastguard Worker if (timestampValid(frame1.firstCompositionGpuFinished) && timestampValid(frame2.firstCompositionGpuFinished))
292*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.firstCompositionGpuFinished, frame2.firstCompositionGpuFinished,
293*35238bceSAndroid Build Coastguard Worker "Composition GPU work complete times not monotonic.");
294*35238bceSAndroid Build Coastguard Worker
295*35238bceSAndroid Build Coastguard Worker if (timestampValid(frame1.displayPresent) && timestampValid(frame2.displayPresent))
296*35238bceSAndroid Build Coastguard Worker check_lt(result, frame1.displayPresent, frame2.displayPresent, "Display present times not monotonic.");
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker
createGLES2Context(const Library & egl,EGLDisplay display,EGLConfig config)299*35238bceSAndroid Build Coastguard Worker EGLContext createGLES2Context(const Library &egl, EGLDisplay display, EGLConfig config)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker EGLContext context = EGL_NO_CONTEXT;
302*35238bceSAndroid Build Coastguard Worker const EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
303*35238bceSAndroid Build Coastguard Worker
304*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
305*35238bceSAndroid Build Coastguard Worker
306*35238bceSAndroid Build Coastguard Worker context = egl.createContext(display, config, EGL_NO_CONTEXT, attribList);
307*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglCreateContext() failed");
308*35238bceSAndroid Build Coastguard Worker TCU_CHECK(context);
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker return context;
311*35238bceSAndroid Build Coastguard Worker }
312*35238bceSAndroid Build Coastguard Worker
313*35238bceSAndroid Build Coastguard Worker class GetFrameTimestampTest : public SimpleConfigCase
314*35238bceSAndroid Build Coastguard Worker {
315*35238bceSAndroid Build Coastguard Worker public:
316*35238bceSAndroid Build Coastguard Worker GetFrameTimestampTest(EglTestContext &eglTestCtx, const NamedFilterList &filters);
317*35238bceSAndroid Build Coastguard Worker ~GetFrameTimestampTest(void);
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker private:
320*35238bceSAndroid Build Coastguard Worker void executeForConfig(EGLDisplay display, EGLConfig config);
321*35238bceSAndroid Build Coastguard Worker void initializeExtension(const Library &egl);
322*35238bceSAndroid Build Coastguard Worker
323*35238bceSAndroid Build Coastguard Worker // Not allowed
324*35238bceSAndroid Build Coastguard Worker GetFrameTimestampTest(const GetFrameTimestampTest &);
325*35238bceSAndroid Build Coastguard Worker GetFrameTimestampTest &operator=(const GetFrameTimestampTest &);
326*35238bceSAndroid Build Coastguard Worker
327*35238bceSAndroid Build Coastguard Worker // TODO: Move these to eglw::Library.
328*35238bceSAndroid Build Coastguard Worker eglGetNextFrameIdANDROIDFunc m_eglGetNextFrameIdANDROID;
329*35238bceSAndroid Build Coastguard Worker eglGetCompositorTimingANDROIDFunc m_eglGetCompositorTimingANDROID;
330*35238bceSAndroid Build Coastguard Worker eglGetCompositorTimingSupportedANDROIDFunc m_eglGetCompositorTimingSupportedANDROID;
331*35238bceSAndroid Build Coastguard Worker eglGetFrameTimestampsANDROIDFunc m_eglGetFrameTimestampsANDROID;
332*35238bceSAndroid Build Coastguard Worker eglGetFrameTimestampSupportedANDROIDFunc m_eglGetFrameTimestampSupportedANDROID;
333*35238bceSAndroid Build Coastguard Worker
334*35238bceSAndroid Build Coastguard Worker tcu::ResultCollector m_result;
335*35238bceSAndroid Build Coastguard Worker };
336*35238bceSAndroid Build Coastguard Worker
GetFrameTimestampTest(EglTestContext & eglTestCtx,const NamedFilterList & filters)337*35238bceSAndroid Build Coastguard Worker GetFrameTimestampTest::GetFrameTimestampTest(EglTestContext &eglTestCtx, const NamedFilterList &filters)
338*35238bceSAndroid Build Coastguard Worker : SimpleConfigCase(eglTestCtx, filters.getName(), filters.getDescription(), filters)
339*35238bceSAndroid Build Coastguard Worker , m_eglGetNextFrameIdANDROID(DE_NULL)
340*35238bceSAndroid Build Coastguard Worker , m_eglGetCompositorTimingANDROID(DE_NULL)
341*35238bceSAndroid Build Coastguard Worker , m_eglGetCompositorTimingSupportedANDROID(DE_NULL)
342*35238bceSAndroid Build Coastguard Worker , m_eglGetFrameTimestampsANDROID(DE_NULL)
343*35238bceSAndroid Build Coastguard Worker , m_eglGetFrameTimestampSupportedANDROID(DE_NULL)
344*35238bceSAndroid Build Coastguard Worker , m_result(m_testCtx.getLog())
345*35238bceSAndroid Build Coastguard Worker {
346*35238bceSAndroid Build Coastguard Worker }
347*35238bceSAndroid Build Coastguard Worker
~GetFrameTimestampTest(void)348*35238bceSAndroid Build Coastguard Worker GetFrameTimestampTest::~GetFrameTimestampTest(void)
349*35238bceSAndroid Build Coastguard Worker {
350*35238bceSAndroid Build Coastguard Worker }
351*35238bceSAndroid Build Coastguard Worker
initializeExtension(const Library & egl)352*35238bceSAndroid Build Coastguard Worker void GetFrameTimestampTest::initializeExtension(const Library &egl)
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker m_eglGetNextFrameIdANDROID =
355*35238bceSAndroid Build Coastguard Worker reinterpret_cast<eglGetNextFrameIdANDROIDFunc>(egl.getProcAddress("eglGetNextFrameIdANDROID"));
356*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "getProcAddress of eglGetNextFrameIdANDROID failed.");
357*35238bceSAndroid Build Coastguard Worker m_eglGetCompositorTimingANDROID =
358*35238bceSAndroid Build Coastguard Worker reinterpret_cast<eglGetCompositorTimingANDROIDFunc>(egl.getProcAddress("eglGetCompositorTimingANDROID"));
359*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingANDROID failed.");
360*35238bceSAndroid Build Coastguard Worker m_eglGetCompositorTimingSupportedANDROID = reinterpret_cast<eglGetCompositorTimingSupportedANDROIDFunc>(
361*35238bceSAndroid Build Coastguard Worker egl.getProcAddress("eglGetCompositorTimingSupportedANDROID"));
362*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingSupportedANDROID failed.");
363*35238bceSAndroid Build Coastguard Worker m_eglGetFrameTimestampsANDROID =
364*35238bceSAndroid Build Coastguard Worker reinterpret_cast<eglGetFrameTimestampsANDROIDFunc>(egl.getProcAddress("eglGetFrameTimestampsANDROID"));
365*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampsANDROID failed.");
366*35238bceSAndroid Build Coastguard Worker m_eglGetFrameTimestampSupportedANDROID = reinterpret_cast<eglGetFrameTimestampSupportedANDROIDFunc>(
367*35238bceSAndroid Build Coastguard Worker egl.getProcAddress("eglGetFrameTimestampSupportedANDROID"));
368*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampSupportedANDROID failed.");
369*35238bceSAndroid Build Coastguard Worker }
370*35238bceSAndroid Build Coastguard Worker
getConfigIdString(const Library & egl,EGLDisplay display,EGLConfig config)371*35238bceSAndroid Build Coastguard Worker string getConfigIdString(const Library &egl, EGLDisplay display, EGLConfig config)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker std::ostringstream stream;
374*35238bceSAndroid Build Coastguard Worker EGLint id;
375*35238bceSAndroid Build Coastguard Worker
376*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, getConfigAttrib(display, config, EGL_CONFIG_ID, &id));
377*35238bceSAndroid Build Coastguard Worker
378*35238bceSAndroid Build Coastguard Worker stream << id;
379*35238bceSAndroid Build Coastguard Worker
380*35238bceSAndroid Build Coastguard Worker return stream.str();
381*35238bceSAndroid Build Coastguard Worker }
382*35238bceSAndroid Build Coastguard Worker
createGLES2Program(const glw::Functions & gl,TestLog & log)383*35238bceSAndroid Build Coastguard Worker uint32_t createGLES2Program(const glw::Functions &gl, TestLog &log)
384*35238bceSAndroid Build Coastguard Worker {
385*35238bceSAndroid Build Coastguard Worker const char *const vertexShaderSource = "attribute highp vec2 a_pos;\n"
386*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
387*35238bceSAndroid Build Coastguard Worker "{\n"
388*35238bceSAndroid Build Coastguard Worker "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
389*35238bceSAndroid Build Coastguard Worker "}";
390*35238bceSAndroid Build Coastguard Worker
391*35238bceSAndroid Build Coastguard Worker const char *const fragmentShaderSource = "void main (void)\n"
392*35238bceSAndroid Build Coastguard Worker "{\n"
393*35238bceSAndroid Build Coastguard Worker "\tgl_FragColor = vec4(0.9, 0.1, 0.4, 1.0);\n"
394*35238bceSAndroid Build Coastguard Worker "}";
395*35238bceSAndroid Build Coastguard Worker
396*35238bceSAndroid Build Coastguard Worker uint32_t program = 0;
397*35238bceSAndroid Build Coastguard Worker uint32_t vertexShader = 0;
398*35238bceSAndroid Build Coastguard Worker uint32_t fragmentShader = 0;
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker int32_t vertexCompileStatus;
401*35238bceSAndroid Build Coastguard Worker string vertexInfoLog;
402*35238bceSAndroid Build Coastguard Worker int32_t fragmentCompileStatus;
403*35238bceSAndroid Build Coastguard Worker string fragmentInfoLog;
404*35238bceSAndroid Build Coastguard Worker int32_t linkStatus;
405*35238bceSAndroid Build Coastguard Worker string programInfoLog;
406*35238bceSAndroid Build Coastguard Worker
407*35238bceSAndroid Build Coastguard Worker try
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker program = gl.createProgram();
410*35238bceSAndroid Build Coastguard Worker vertexShader = gl.createShader(GL_VERTEX_SHADER);
411*35238bceSAndroid Build Coastguard Worker fragmentShader = gl.createShader(GL_FRAGMENT_SHADER);
412*35238bceSAndroid Build Coastguard Worker
413*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shaders and program");
414*35238bceSAndroid Build Coastguard Worker
415*35238bceSAndroid Build Coastguard Worker gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
416*35238bceSAndroid Build Coastguard Worker gl.compileShader(vertexShader);
417*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup vertex shader");
418*35238bceSAndroid Build Coastguard Worker
419*35238bceSAndroid Build Coastguard Worker gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
420*35238bceSAndroid Build Coastguard Worker gl.compileShader(fragmentShader);
421*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup fragment shader");
422*35238bceSAndroid Build Coastguard Worker
423*35238bceSAndroid Build Coastguard Worker {
424*35238bceSAndroid Build Coastguard Worker int32_t infoLogLength = 0;
425*35238bceSAndroid Build Coastguard Worker
426*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompileStatus);
427*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength);
428*35238bceSAndroid Build Coastguard Worker
429*35238bceSAndroid Build Coastguard Worker vertexInfoLog.resize(infoLogLength, '\0');
430*35238bceSAndroid Build Coastguard Worker
431*35238bceSAndroid Build Coastguard Worker gl.getShaderInfoLog(vertexShader, (glw::GLsizei)vertexInfoLog.length(), &infoLogLength,
432*35238bceSAndroid Build Coastguard Worker &(vertexInfoLog[0]));
433*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get vertex shader compile info");
434*35238bceSAndroid Build Coastguard Worker
435*35238bceSAndroid Build Coastguard Worker vertexInfoLog.resize(infoLogLength);
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker
438*35238bceSAndroid Build Coastguard Worker {
439*35238bceSAndroid Build Coastguard Worker int32_t infoLogLength = 0;
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentCompileStatus);
442*35238bceSAndroid Build Coastguard Worker gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength);
443*35238bceSAndroid Build Coastguard Worker
444*35238bceSAndroid Build Coastguard Worker fragmentInfoLog.resize(infoLogLength, '\0');
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker gl.getShaderInfoLog(fragmentShader, (glw::GLsizei)fragmentInfoLog.length(), &infoLogLength,
447*35238bceSAndroid Build Coastguard Worker &(fragmentInfoLog[0]));
448*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get fragment shader compile info");
449*35238bceSAndroid Build Coastguard Worker
450*35238bceSAndroid Build Coastguard Worker fragmentInfoLog.resize(infoLogLength);
451*35238bceSAndroid Build Coastguard Worker }
452*35238bceSAndroid Build Coastguard Worker
453*35238bceSAndroid Build Coastguard Worker gl.attachShader(program, vertexShader);
454*35238bceSAndroid Build Coastguard Worker gl.attachShader(program, fragmentShader);
455*35238bceSAndroid Build Coastguard Worker gl.linkProgram(program);
456*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup program");
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker {
459*35238bceSAndroid Build Coastguard Worker int32_t infoLogLength = 0;
460*35238bceSAndroid Build Coastguard Worker
461*35238bceSAndroid Build Coastguard Worker gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
462*35238bceSAndroid Build Coastguard Worker gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
463*35238bceSAndroid Build Coastguard Worker
464*35238bceSAndroid Build Coastguard Worker programInfoLog.resize(infoLogLength, '\0');
465*35238bceSAndroid Build Coastguard Worker
466*35238bceSAndroid Build Coastguard Worker gl.getProgramInfoLog(program, (glw::GLsizei)programInfoLog.length(), &infoLogLength, &(programInfoLog[0]));
467*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get program link info");
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker programInfoLog.resize(infoLogLength);
470*35238bceSAndroid Build Coastguard Worker }
471*35238bceSAndroid Build Coastguard Worker
472*35238bceSAndroid Build Coastguard Worker if (linkStatus == 0 || vertexCompileStatus == 0 || fragmentCompileStatus == 0)
473*35238bceSAndroid Build Coastguard Worker {
474*35238bceSAndroid Build Coastguard Worker
475*35238bceSAndroid Build Coastguard Worker log.startShaderProgram(linkStatus != 0, programInfoLog.c_str());
476*35238bceSAndroid Build Coastguard Worker
477*35238bceSAndroid Build Coastguard Worker log << TestLog::Shader(QP_SHADER_TYPE_VERTEX, vertexShaderSource, vertexCompileStatus != 0, vertexInfoLog);
478*35238bceSAndroid Build Coastguard Worker log << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, fragmentShaderSource, fragmentCompileStatus != 0,
479*35238bceSAndroid Build Coastguard Worker fragmentInfoLog);
480*35238bceSAndroid Build Coastguard Worker
481*35238bceSAndroid Build Coastguard Worker log.endShaderProgram();
482*35238bceSAndroid Build Coastguard Worker }
483*35238bceSAndroid Build Coastguard Worker
484*35238bceSAndroid Build Coastguard Worker gl.deleteShader(vertexShader);
485*35238bceSAndroid Build Coastguard Worker gl.deleteShader(fragmentShader);
486*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete shaders");
487*35238bceSAndroid Build Coastguard Worker
488*35238bceSAndroid Build Coastguard Worker TCU_CHECK(linkStatus != 0 && vertexCompileStatus != 0 && fragmentCompileStatus != 0);
489*35238bceSAndroid Build Coastguard Worker }
490*35238bceSAndroid Build Coastguard Worker catch (...)
491*35238bceSAndroid Build Coastguard Worker {
492*35238bceSAndroid Build Coastguard Worker if (program)
493*35238bceSAndroid Build Coastguard Worker gl.deleteProgram(program);
494*35238bceSAndroid Build Coastguard Worker
495*35238bceSAndroid Build Coastguard Worker if (vertexShader)
496*35238bceSAndroid Build Coastguard Worker gl.deleteShader(vertexShader);
497*35238bceSAndroid Build Coastguard Worker
498*35238bceSAndroid Build Coastguard Worker if (fragmentShader)
499*35238bceSAndroid Build Coastguard Worker gl.deleteShader(fragmentShader);
500*35238bceSAndroid Build Coastguard Worker
501*35238bceSAndroid Build Coastguard Worker throw;
502*35238bceSAndroid Build Coastguard Worker }
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker return program;
505*35238bceSAndroid Build Coastguard Worker }
506*35238bceSAndroid Build Coastguard Worker
executeForConfig(EGLDisplay display,EGLConfig config)507*35238bceSAndroid Build Coastguard Worker void GetFrameTimestampTest::executeForConfig(EGLDisplay display, EGLConfig config)
508*35238bceSAndroid Build Coastguard Worker {
509*35238bceSAndroid Build Coastguard Worker const Library &egl = m_eglTestCtx.getLibrary();
510*35238bceSAndroid Build Coastguard Worker
511*35238bceSAndroid Build Coastguard Worker if (!eglu::hasExtension(egl, display, "EGL_ANDROID_get_frame_timestamps"))
512*35238bceSAndroid Build Coastguard Worker TCU_THROW(NotSupportedError, "EGL_ANDROID_get_frame_timestamps is not supported");
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker initializeExtension(egl);
515*35238bceSAndroid Build Coastguard Worker
516*35238bceSAndroid Build Coastguard Worker const string configIdStr(getConfigIdString(egl, display, config));
517*35238bceSAndroid Build Coastguard Worker tcu::ScopedLogSection logSection(m_testCtx.getLog(), ("Config ID " + configIdStr).c_str(),
518*35238bceSAndroid Build Coastguard Worker ("Config ID " + configIdStr).c_str());
519*35238bceSAndroid Build Coastguard Worker const eglu::NativeWindowFactory &factory =
520*35238bceSAndroid Build Coastguard Worker eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
521*35238bceSAndroid Build Coastguard Worker
522*35238bceSAndroid Build Coastguard Worker {
523*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
524*35238bceSAndroid Build Coastguard Worker
525*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_RED_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_RED_SIZE)
526*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
527*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_GREEN_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_GREEN_SIZE)
528*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
529*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_BLUE_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_BLUE_SIZE)
530*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
531*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_ALPHA_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_ALPHA_SIZE)
532*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
533*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_DEPTH_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_DEPTH_SIZE)
534*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
535*35238bceSAndroid Build Coastguard Worker log << TestLog::Message
536*35238bceSAndroid Build Coastguard Worker << "EGL_STENCIL_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_STENCIL_SIZE)
537*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
538*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_SAMPLES: " << eglu::getConfigAttribInt(egl, display, config, EGL_SAMPLES)
539*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
540*35238bceSAndroid Build Coastguard Worker }
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker de::UniquePtr<eglu::NativeWindow> window(
543*35238bceSAndroid Build Coastguard Worker factory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL,
544*35238bceSAndroid Build Coastguard Worker eglu::WindowParams(128, 128, eglu::WindowParams::VISIBILITY_VISIBLE)));
545*35238bceSAndroid Build Coastguard Worker
546*35238bceSAndroid Build Coastguard Worker eglu::UniqueSurface surface(
547*35238bceSAndroid Build Coastguard Worker egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
548*35238bceSAndroid Build Coastguard Worker eglu::UniqueContext context(egl, display, createGLES2Context(egl, display, config));
549*35238bceSAndroid Build Coastguard Worker glw::Functions gl;
550*35238bceSAndroid Build Coastguard Worker uint32_t program = 0;
551*35238bceSAndroid Build Coastguard Worker
552*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, surfaceAttrib(display, *surface, EGL_TIMESTAMPS_ANDROID, EGL_TRUE));
553*35238bceSAndroid Build Coastguard Worker
554*35238bceSAndroid Build Coastguard Worker m_eglTestCtx.initGLFunctions(&gl, glu::ApiType::es(2, 0));
555*35238bceSAndroid Build Coastguard Worker
556*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, *context));
557*35238bceSAndroid Build Coastguard Worker
558*35238bceSAndroid Build Coastguard Worker try
559*35238bceSAndroid Build Coastguard Worker {
560*35238bceSAndroid Build Coastguard Worker // EGL_DISPLAY_PRESENT_TIME_ANDROID support is currently optional
561*35238bceSAndroid Build Coastguard Worker // but should be required once HWC1 is no longer supported.
562*35238bceSAndroid Build Coastguard Worker // All HWC2 devices should support EGL_DISPLAY_PRESENT_TIME_ANDROID.
563*35238bceSAndroid Build Coastguard Worker TimestampInfoMap timestamps;
564*35238bceSAndroid Build Coastguard Worker timestamps[EGL_REQUESTED_PRESENT_TIME_ANDROID] = TimestampInfo(true, false, 0);
565*35238bceSAndroid Build Coastguard Worker timestamps[EGL_RENDERING_COMPLETE_TIME_ANDROID] = TimestampInfo(true, false, 0);
566*35238bceSAndroid Build Coastguard Worker timestamps[EGL_COMPOSITION_LATCH_TIME_ANDROID] = TimestampInfo(true, false, 0);
567*35238bceSAndroid Build Coastguard Worker timestamps[EGL_FIRST_COMPOSITION_START_TIME_ANDROID] = TimestampInfo(true, false, 0);
568*35238bceSAndroid Build Coastguard Worker timestamps[EGL_LAST_COMPOSITION_START_TIME_ANDROID] = TimestampInfo(true, false, 0);
569*35238bceSAndroid Build Coastguard Worker timestamps[EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID] = TimestampInfo(true, false, 0);
570*35238bceSAndroid Build Coastguard Worker timestamps[EGL_DISPLAY_PRESENT_TIME_ANDROID] = TimestampInfo(false, false, 0);
571*35238bceSAndroid Build Coastguard Worker timestamps[EGL_DEQUEUE_READY_TIME_ANDROID] = TimestampInfo(true, false, 0);
572*35238bceSAndroid Build Coastguard Worker timestamps[EGL_READS_DONE_TIME_ANDROID] = TimestampInfo(true, false, 0);
573*35238bceSAndroid Build Coastguard Worker
574*35238bceSAndroid Build Coastguard Worker const eglw::EGLint invalidTimestampName = EGL_READS_DONE_TIME_ANDROID + 1;
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker // Verify required timestamps are supported and populate supportedNames.
577*35238bceSAndroid Build Coastguard Worker std::vector<eglw::EGLint> supportedNames;
578*35238bceSAndroid Build Coastguard Worker for (TimestampInfoMap::iterator i = timestamps.begin(); i != timestamps.end(); i++)
579*35238bceSAndroid Build Coastguard Worker {
580*35238bceSAndroid Build Coastguard Worker TimestampInfo &info = i->second;
581*35238bceSAndroid Build Coastguard Worker info.supported = m_eglGetFrameTimestampSupportedANDROID(display, *surface, i->first) != EGL_FALSE;
582*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");
583*35238bceSAndroid Build Coastguard Worker
584*35238bceSAndroid Build Coastguard Worker if (info.supported)
585*35238bceSAndroid Build Coastguard Worker {
586*35238bceSAndroid Build Coastguard Worker info.supportedIndex = supportedNames.size();
587*35238bceSAndroid Build Coastguard Worker supportedNames.push_back(i->first);
588*35238bceSAndroid Build Coastguard Worker }
589*35238bceSAndroid Build Coastguard Worker else
590*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(!info.required, "Required timestamp not supported.");
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker
593*35238bceSAndroid Build Coastguard Worker // Verify unsupported timestamps are reported properly.
594*35238bceSAndroid Build Coastguard Worker const bool invalidSupported =
595*35238bceSAndroid Build Coastguard Worker m_eglGetFrameTimestampSupportedANDROID(display, *surface, invalidTimestampName) != EGL_FALSE;
596*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");
597*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(!invalidSupported, "Non existant timestamp reports that it is supported.");
598*35238bceSAndroid Build Coastguard Worker
599*35238bceSAndroid Build Coastguard Worker // Verify compositor timings are supported.
600*35238bceSAndroid Build Coastguard Worker const bool deadlineSupported =
601*35238bceSAndroid Build Coastguard Worker m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_DEADLINE_ANDROID) != EGL_FALSE;
602*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
603*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(deadlineSupported, "EGL_COMPOSITE_DEADLINE_ANDROID not supported.");
604*35238bceSAndroid Build Coastguard Worker const bool intervalSupported =
605*35238bceSAndroid Build Coastguard Worker m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_INTERVAL_ANDROID) != EGL_FALSE;
606*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
607*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(intervalSupported, "EGL_COMPOSITE_INTERVAL_ANDROID not supported.");
608*35238bceSAndroid Build Coastguard Worker const bool latencySupported = m_eglGetCompositorTimingSupportedANDROID(
609*35238bceSAndroid Build Coastguard Worker display, *surface, EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID) != EGL_FALSE;
610*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
611*35238bceSAndroid Build Coastguard Worker TCU_CHECK_MSG(latencySupported, "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID not supported.");
612*35238bceSAndroid Build Coastguard Worker
613*35238bceSAndroid Build Coastguard Worker const float positions1[] = {0.00f, 0.00f, 0.75f, 0.00f, 0.75f, 0.75f,
614*35238bceSAndroid Build Coastguard Worker
615*35238bceSAndroid Build Coastguard Worker 0.75f, 0.75f, 0.00f, 0.75f, 0.00f, 0.00f};
616*35238bceSAndroid Build Coastguard Worker
617*35238bceSAndroid Build Coastguard Worker const float positions2[] = {-0.75f, -0.75f, 0.00f, -0.75f, 0.00f, 0.00f,
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker 0.00f, 0.00f, -0.75f, 0.00f, -0.75f, -0.75f};
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker uint32_t posLocation;
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker program = createGLES2Program(gl, m_testCtx.getLog());
624*35238bceSAndroid Build Coastguard Worker
625*35238bceSAndroid Build Coastguard Worker gl.useProgram(program);
626*35238bceSAndroid Build Coastguard Worker posLocation = gl.getAttribLocation(program, "a_pos");
627*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(posLocation);
628*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shader program for rendering");
629*35238bceSAndroid Build Coastguard Worker
630*35238bceSAndroid Build Coastguard Worker // Do extra rendering to allow frame pacing to stabilize.
631*35238bceSAndroid Build Coastguard Worker // The frame timestamp validation below assumes there is no frame janking,
632*35238bceSAndroid Build Coastguard Worker // however, this is not guaranteed.
633*35238bceSAndroid Build Coastguard Worker // e.g. on some hardware, the shader compilation causes first few frames
634*35238bceSAndroid Build Coastguard Worker // to jank. This will cause frame timestamps read back not matching with
635*35238bceSAndroid Build Coastguard Worker // expectations: compositeToPresentLatency < 4 * compositeInterval.
636*35238bceSAndroid Build Coastguard Worker // Do extra frames rendering to allow frames to stablize before measuring
637*35238bceSAndroid Build Coastguard Worker // and verifying frame timestamps.
638*35238bceSAndroid Build Coastguard Worker const size_t stablizeFramesCount = 120;
639*35238bceSAndroid Build Coastguard Worker for (size_t i = 0; i < stablizeFramesCount; ++i)
640*35238bceSAndroid Build Coastguard Worker {
641*35238bceSAndroid Build Coastguard Worker gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
642*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
643*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear surface");
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker const bool posSelect = ((i % 2) == 0);
646*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 2, GL_FLOAT, GL_FALSE, 0, posSelect ? positions1 : positions2);
647*35238bceSAndroid Build Coastguard Worker
648*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_TRIANGLES, 0, 6);
649*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, swapBuffers(display, *surface));
652*35238bceSAndroid Build Coastguard Worker }
653*35238bceSAndroid Build Coastguard Worker
654*35238bceSAndroid Build Coastguard Worker const size_t frameCount = 120;
655*35238bceSAndroid Build Coastguard Worker std::vector<FrameTimes> frameTimes(frameCount);
656*35238bceSAndroid Build Coastguard Worker for (size_t i = 0; i < frameCount; i++)
657*35238bceSAndroid Build Coastguard Worker {
658*35238bceSAndroid Build Coastguard Worker FrameTimes &frame = frameTimes[i];
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker const eglw::EGLint compositorTimingNames[] = {
661*35238bceSAndroid Build Coastguard Worker EGL_COMPOSITE_DEADLINE_ANDROID,
662*35238bceSAndroid Build Coastguard Worker EGL_COMPOSITE_INTERVAL_ANDROID,
663*35238bceSAndroid Build Coastguard Worker EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID,
664*35238bceSAndroid Build Coastguard Worker };
665*35238bceSAndroid Build Coastguard Worker const EGLint compositorTimingCount = DE_LENGTH_OF_ARRAY(compositorTimingNames);
666*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID compositorTimingValues[compositorTimingCount] = {-2};
667*35238bceSAndroid Build Coastguard Worker
668*35238bceSAndroid Build Coastguard Worker // Get the current time before making any API calls in case "now"
669*35238bceSAndroid Build Coastguard Worker // just happens to get sampled near one of the composite deadlines.
670*35238bceSAndroid Build Coastguard Worker EGLnsecsANDROID now = getNanoseconds();
671*35238bceSAndroid Build Coastguard Worker
672*35238bceSAndroid Build Coastguard Worker // Get the frame id.
673*35238bceSAndroid Build Coastguard Worker EGLuint64KHR nextFrameId = 0;
674*35238bceSAndroid Build Coastguard Worker CHECK_NAKED_EGL_CALL(egl, m_eglGetNextFrameIdANDROID(display, *surface, &nextFrameId));
675*35238bceSAndroid Build Coastguard Worker frame.frameId = nextFrameId;
676*35238bceSAndroid Build Coastguard Worker
677*35238bceSAndroid Build Coastguard Worker // Get the compositor timing.
678*35238bceSAndroid Build Coastguard Worker CHECK_NAKED_EGL_CALL(egl, m_eglGetCompositorTimingANDROID(display, *surface, compositorTimingCount,
679*35238bceSAndroid Build Coastguard Worker compositorTimingNames, compositorTimingValues));
680*35238bceSAndroid Build Coastguard Worker frame.compositeDeadline = compositorTimingValues[0];
681*35238bceSAndroid Build Coastguard Worker frame.compositeInterval = compositorTimingValues[1];
682*35238bceSAndroid Build Coastguard Worker frame.compositeToPresentLatency = compositorTimingValues[2];
683*35238bceSAndroid Build Coastguard Worker
684*35238bceSAndroid Build Coastguard Worker // Verify compositor timing is sane.
685*35238bceSAndroid Build Coastguard Worker check_lt<EGLnsecsANDROID>(m_result, 1000000, frame.compositeInterval,
686*35238bceSAndroid Build Coastguard Worker "Reported refresh rate greater than 1kHz.");
687*35238bceSAndroid Build Coastguard Worker check_lt<EGLnsecsANDROID>(m_result, frame.compositeInterval, 1000000000,
688*35238bceSAndroid Build Coastguard Worker "Reported refresh rate less than 1Hz.");
689*35238bceSAndroid Build Coastguard Worker check_lt<EGLnsecsANDROID>(m_result, 0, frame.compositeToPresentLatency,
690*35238bceSAndroid Build Coastguard Worker "Composite to present latency must be greater than 0.");
691*35238bceSAndroid Build Coastguard Worker check_lt(m_result, frame.compositeToPresentLatency, frame.compositeInterval * 4,
692*35238bceSAndroid Build Coastguard Worker "Composite to present latency is more than 4 vsyncs.");
693*35238bceSAndroid Build Coastguard Worker const EGLnsecsANDROID minDeadline = now;
694*35238bceSAndroid Build Coastguard Worker check_lt(m_result, minDeadline, frame.compositeDeadline, "Next composite deadline is in the past.");
695*35238bceSAndroid Build Coastguard Worker const EGLnsecsANDROID maxDeadline = now + frame.compositeInterval * 2;
696*35238bceSAndroid Build Coastguard Worker check_lt(m_result, frame.compositeDeadline, maxDeadline,
697*35238bceSAndroid Build Coastguard Worker "Next composite deadline over two intervals away.");
698*35238bceSAndroid Build Coastguard Worker
699*35238bceSAndroid Build Coastguard Worker const float colorAngle = (static_cast<float>(i) / static_cast<float>(frameCount)) * 6.28318f;
700*35238bceSAndroid Build Coastguard Worker gl.clearColor((1.0f + deFloatSin(colorAngle)) / 2.0f, 0.7f, (1.0f + deFloatCos(colorAngle)) / 2.0f, 1.0f);
701*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT);
702*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear surface");
703*35238bceSAndroid Build Coastguard Worker
704*35238bceSAndroid Build Coastguard Worker const bool posSelect = ((i % 2) == 0);
705*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(posLocation, 2, GL_FLOAT, GL_FALSE, 0, posSelect ? positions1 : positions2);
706*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_TRIANGLES, 0, 6);
707*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");
708*35238bceSAndroid Build Coastguard Worker
709*35238bceSAndroid Build Coastguard Worker frame.swapBufferBeginNs = getNanoseconds();
710*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, swapBuffers(display, *surface));
711*35238bceSAndroid Build Coastguard Worker
712*35238bceSAndroid Build Coastguard Worker // All timestamps from 6 frames ago should definitely be available.
713*35238bceSAndroid Build Coastguard Worker const size_t frameDelay = 6;
714*35238bceSAndroid Build Coastguard Worker if (i >= frameDelay)
715*35238bceSAndroid Build Coastguard Worker {
716*35238bceSAndroid Build Coastguard Worker // \todo [2017-01-25 brianderson] Remove this work around once reads done is fixed.
717*35238bceSAndroid Build Coastguard Worker const bool verifyReadsDone = i > (frameDelay + 3);
718*35238bceSAndroid Build Coastguard Worker FrameTimes &frame6ago = frameTimes[i - frameDelay];
719*35238bceSAndroid Build Coastguard Worker std::vector<EGLnsecsANDROID> supportedValues(supportedNames.size(), 0);
720*35238bceSAndroid Build Coastguard Worker
721*35238bceSAndroid Build Coastguard Worker CHECK_NAKED_EGL_CALL(egl,
722*35238bceSAndroid Build Coastguard Worker m_eglGetFrameTimestampsANDROID(display, *surface, frame6ago.frameId,
723*35238bceSAndroid Build Coastguard Worker static_cast<eglw::EGLint>(supportedNames.size()),
724*35238bceSAndroid Build Coastguard Worker &supportedNames[0], &supportedValues[0]));
725*35238bceSAndroid Build Coastguard Worker populateFrameTimes(&frame6ago, timestamps, supportedValues);
726*35238bceSAndroid Build Coastguard Worker
727*35238bceSAndroid Build Coastguard Worker verifySingleFrame(frame6ago, m_result, verifyReadsDone);
728*35238bceSAndroid Build Coastguard Worker if (i >= frameDelay + 1)
729*35238bceSAndroid Build Coastguard Worker {
730*35238bceSAndroid Build Coastguard Worker FrameTimes &frame7ago = frameTimes[i - frameDelay - 1];
731*35238bceSAndroid Build Coastguard Worker verifyNeighboringFrames(frame7ago, frame6ago, m_result);
732*35238bceSAndroid Build Coastguard Worker }
733*35238bceSAndroid Build Coastguard Worker }
734*35238bceSAndroid Build Coastguard Worker deSleep(static_cast<uint32_t>(frame.compositeInterval / 1000000));
735*35238bceSAndroid Build Coastguard Worker }
736*35238bceSAndroid Build Coastguard Worker
737*35238bceSAndroid Build Coastguard Worker // All timestamps for the most recently swapped frame should
738*35238bceSAndroid Build Coastguard Worker // become available by only polling eglGetFrametimestamps.
739*35238bceSAndroid Build Coastguard Worker // No additional swaps should be necessary.
740*35238bceSAndroid Build Coastguard Worker FrameTimes &lastFrame = frameTimes.back();
741*35238bceSAndroid Build Coastguard Worker const EGLnsecsANDROID pollingDeadline = lastFrame.swapBufferBeginNs + 1000000000;
742*35238bceSAndroid Build Coastguard Worker bool finalTimestampAvailable = false;
743*35238bceSAndroid Build Coastguard Worker
744*35238bceSAndroid Build Coastguard Worker do
745*35238bceSAndroid Build Coastguard Worker {
746*35238bceSAndroid Build Coastguard Worker std::vector<EGLnsecsANDROID> supportedValues(supportedNames.size(), 0);
747*35238bceSAndroid Build Coastguard Worker CHECK_NAKED_EGL_CALL(egl, m_eglGetFrameTimestampsANDROID(display, *surface, lastFrame.frameId,
748*35238bceSAndroid Build Coastguard Worker static_cast<eglw::EGLint>(supportedNames.size()),
749*35238bceSAndroid Build Coastguard Worker &supportedNames[0], &supportedValues[0]));
750*35238bceSAndroid Build Coastguard Worker populateFrameTimes(&lastFrame, timestamps, supportedValues);
751*35238bceSAndroid Build Coastguard Worker
752*35238bceSAndroid Build Coastguard Worker // Poll for present if it's supported.
753*35238bceSAndroid Build Coastguard Worker // Otherwise, poll for firstCompositionStart.
754*35238bceSAndroid Build Coastguard Worker if (timestamps[EGL_DISPLAY_PRESENT_TIME_ANDROID].supported)
755*35238bceSAndroid Build Coastguard Worker finalTimestampAvailable = !timestampPending(lastFrame.displayPresent);
756*35238bceSAndroid Build Coastguard Worker else
757*35238bceSAndroid Build Coastguard Worker finalTimestampAvailable = !timestampPending(lastFrame.firstCompositionStart);
758*35238bceSAndroid Build Coastguard Worker } while (!finalTimestampAvailable && (getNanoseconds() < pollingDeadline));
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker m_result.check(finalTimestampAvailable, "Timed out polling for timestamps of last swap.");
761*35238bceSAndroid Build Coastguard Worker m_result.check((lastFrame.requestedPresent >= 0), "Requested present of last swap not avaiable.");
762*35238bceSAndroid Build Coastguard Worker m_result.check((lastFrame.renderingComplete >= 0), "Rendering complete of last swap not avaiable.");
763*35238bceSAndroid Build Coastguard Worker m_result.check((lastFrame.latch >= 0), "Latch of last swap not avaiable.");
764*35238bceSAndroid Build Coastguard Worker m_result.check((lastFrame.firstCompositionStart >= 0), "First composite time of last swap not avaiable.");
765*35238bceSAndroid Build Coastguard Worker m_result.check((lastFrame.lastCompositionStart >= 0), "Last composite time of last swap not avaiable.");
766*35238bceSAndroid Build Coastguard Worker
767*35238bceSAndroid Build Coastguard Worker window->processEvents();
768*35238bceSAndroid Build Coastguard Worker gl.disableVertexAttribArray(posLocation);
769*35238bceSAndroid Build Coastguard Worker gl.useProgram(0);
770*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to release program state");
771*35238bceSAndroid Build Coastguard Worker
772*35238bceSAndroid Build Coastguard Worker gl.deleteProgram(program);
773*35238bceSAndroid Build Coastguard Worker program = 0;
774*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram()");
775*35238bceSAndroid Build Coastguard Worker
776*35238bceSAndroid Build Coastguard Worker m_result.setTestContextResult(m_testCtx);
777*35238bceSAndroid Build Coastguard Worker }
778*35238bceSAndroid Build Coastguard Worker catch (...)
779*35238bceSAndroid Build Coastguard Worker {
780*35238bceSAndroid Build Coastguard Worker if (program != 0)
781*35238bceSAndroid Build Coastguard Worker gl.deleteProgram(program);
782*35238bceSAndroid Build Coastguard Worker
783*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
784*35238bceSAndroid Build Coastguard Worker throw;
785*35238bceSAndroid Build Coastguard Worker }
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
788*35238bceSAndroid Build Coastguard Worker }
789*35238bceSAndroid Build Coastguard Worker
790*35238bceSAndroid Build Coastguard Worker class GetFrameTimestampsTests : public TestCaseGroup
791*35238bceSAndroid Build Coastguard Worker {
792*35238bceSAndroid Build Coastguard Worker public:
793*35238bceSAndroid Build Coastguard Worker GetFrameTimestampsTests(EglTestContext &eglTestCtx);
794*35238bceSAndroid Build Coastguard Worker void init(void);
795*35238bceSAndroid Build Coastguard Worker
796*35238bceSAndroid Build Coastguard Worker private:
797*35238bceSAndroid Build Coastguard Worker GetFrameTimestampsTests(const GetFrameTimestampsTests &);
798*35238bceSAndroid Build Coastguard Worker GetFrameTimestampsTests &operator=(const GetFrameTimestampsTests &);
799*35238bceSAndroid Build Coastguard Worker };
800*35238bceSAndroid Build Coastguard Worker
GetFrameTimestampsTests(EglTestContext & eglTestCtx)801*35238bceSAndroid Build Coastguard Worker GetFrameTimestampsTests::GetFrameTimestampsTests(EglTestContext &eglTestCtx)
802*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(eglTestCtx, "get_frame_timestamps", "Get frame timestamp tests")
803*35238bceSAndroid Build Coastguard Worker {
804*35238bceSAndroid Build Coastguard Worker }
805*35238bceSAndroid Build Coastguard Worker
isWindow(const eglu::CandidateConfig & c)806*35238bceSAndroid Build Coastguard Worker bool isWindow(const eglu::CandidateConfig &c)
807*35238bceSAndroid Build Coastguard Worker {
808*35238bceSAndroid Build Coastguard Worker return (c.surfaceType() & EGL_WINDOW_BIT) != 0;
809*35238bceSAndroid Build Coastguard Worker }
810*35238bceSAndroid Build Coastguard Worker
init(void)811*35238bceSAndroid Build Coastguard Worker void GetFrameTimestampsTests::init(void)
812*35238bceSAndroid Build Coastguard Worker {
813*35238bceSAndroid Build Coastguard Worker eglu::FilterList baseFilters;
814*35238bceSAndroid Build Coastguard Worker baseFilters << isWindow;
815*35238bceSAndroid Build Coastguard Worker
816*35238bceSAndroid Build Coastguard Worker vector<NamedFilterList> filterLists;
817*35238bceSAndroid Build Coastguard Worker getDefaultFilterLists(filterLists, baseFilters);
818*35238bceSAndroid Build Coastguard Worker
819*35238bceSAndroid Build Coastguard Worker for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
820*35238bceSAndroid Build Coastguard Worker addChild(new GetFrameTimestampTest(m_eglTestCtx, *i));
821*35238bceSAndroid Build Coastguard Worker }
822*35238bceSAndroid Build Coastguard Worker
823*35238bceSAndroid Build Coastguard Worker } // namespace
824*35238bceSAndroid Build Coastguard Worker
createGetFrameTimestampsTests(EglTestContext & eglTestCtx)825*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createGetFrameTimestampsTests(EglTestContext &eglTestCtx)
826*35238bceSAndroid Build Coastguard Worker {
827*35238bceSAndroid Build Coastguard Worker return new GetFrameTimestampsTests(eglTestCtx);
828*35238bceSAndroid Build Coastguard Worker }
829*35238bceSAndroid Build Coastguard Worker
830*35238bceSAndroid Build Coastguard Worker } // namespace egl
831*35238bceSAndroid Build Coastguard Worker } // namespace deqp
832