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