/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL Module
 * ---------------------------------------
 *
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Test the EGL_ANDROID_get_frame_timestamps extension.
 *//*--------------------------------------------------------------------*/

#include "teglGetFrameTimestampsTests.hpp"

#include "teglSimpleConfigCase.hpp"

#include "egluNativeWindow.hpp"
#include "egluUtil.hpp"
#include "egluUnique.hpp"
#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"

#include "gluDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"

#include "deClock.h"
#include "deMath.h"
#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deThread.hpp"

#include <algorithm>
#include <string>
#include <vector>
#include <sstream>

// Tentative EGL header definitions for EGL_ANDROID_get_Frame_timestamps.
// \todo [2017-01-25 brianderson] Remove once defined in the official headers.
#define EGL_TIMESTAMPS_ANDROID 0x3430
#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431
#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432
#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433
#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434
#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435
#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436
#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437
#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438
#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439
#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A
#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B
#define EGL_READS_DONE_TIME_ANDROID 0x343C
typedef deInt64 EGLnsecsANDROID;
typedef deUint64 EGLuint64KHR;
#define EGL_TIMESTAMP_PENDING_ANDROID (-2)
#define EGL_TIMESTAMP_INVALID_ANDROID (-1)
typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetNextFrameIdANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, EGLuint64KHR *frameId);
typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetCompositorTimingANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint numTimestamps, const eglw::EGLint *names, EGLnsecsANDROID *values);
typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetCompositorTimingSupportedANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint name);
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);
typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetFrameTimestampSupportedANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint timestamp);

#define CHECK_NAKED_EGL_CALL(EGLW, CALL)	do { CALL; eglu::checkError((EGLW).getError(), #CALL, __FILE__, __LINE__); } while (deGetFalse())

namespace deqp
{
namespace egl
{

using tcu::TestLog;
using std::string;
using std::vector;
using namespace eglw;

namespace
{

// Careful: This has microsecond precision, which can cause timestamps to
// appear non monotonic when compared to the nanosecond precision timestamps
// we get from the eglGetFrameTimestamps extension.
// Current test expectations only make sure microsecond precision timestamps
// are less than the nanosecond precision timestamps, so this is okay.
EGLnsecsANDROID getNanoseconds (void)
{
	return deGetMicroseconds() * 1000;
}

struct FrameTimes
{
	FrameTimes (void)
		: frameId						(-1)
		, swapBufferBeginNs				(-1)
		, compositeDeadline				(-1)
		, compositeInterval				(-1)
		, compositeToPresentLatency		(-1)
		, requestedPresent				(-1)
		, latch							(-1)
		, firstCompositionStart			(-1)
		, lastCompositionStart			(-1)
		, dequeueReady					(-1)
		, renderingComplete				(-1)
		, firstCompositionGpuFinished	(-1)
		, displayPresent				(-1)
		, readsDone						(-1)
	{
	}

	EGLuint64KHR	frameId;

	// Timestamps sampled by the test.
	EGLnsecsANDROID	swapBufferBeginNs;

	// Compositor info.
	EGLnsecsANDROID	compositeDeadline;
	EGLnsecsANDROID	compositeInterval;
	EGLnsecsANDROID	compositeToPresentLatency;

	// CPU Timeline.
	EGLnsecsANDROID	requestedPresent;
	EGLnsecsANDROID	latch;
	EGLnsecsANDROID	firstCompositionStart;
	EGLnsecsANDROID	lastCompositionStart;
	EGLnsecsANDROID	dequeueReady;

	// GPU Timeline.
	EGLnsecsANDROID	renderingComplete;
	EGLnsecsANDROID	firstCompositionGpuFinished;
	EGLnsecsANDROID	displayPresent;
	EGLnsecsANDROID	readsDone;
};


struct TimestampInfo
{
	TimestampInfo()
		: required(false)
		, supported(false)
		, supportedIndex(0)
	{
	}

	TimestampInfo(bool required_, bool supported_, size_t supportedIndex_)
		: required(required_)
		, supported(supported_)
		, supportedIndex(supportedIndex_)
	{
	}

	bool	required;
	bool	supported;
	size_t	supportedIndex;
};

typedef std::map<eglw::EGLint, TimestampInfo> TimestampInfoMap;

EGLnsecsANDROID getTimestamp(eglw::EGLint name, TimestampInfoMap& map, const std::vector<EGLnsecsANDROID>& supportedValues)
{
	TimestampInfo& info = map[name];
	return info.supported ? supportedValues[info.supportedIndex] : EGL_TIMESTAMP_INVALID_ANDROID;
}

void populateFrameTimes(FrameTimes* frameTimes, TimestampInfoMap& map, const std::vector<EGLnsecsANDROID>& supportedValues)
{
	frameTimes->requestedPresent			=	getTimestamp(EGL_REQUESTED_PRESENT_TIME_ANDROID, map, supportedValues);
	frameTimes->renderingComplete			=	getTimestamp(EGL_RENDERING_COMPLETE_TIME_ANDROID, map, supportedValues);
	frameTimes->latch						=	getTimestamp(EGL_COMPOSITION_LATCH_TIME_ANDROID, map, supportedValues);
	frameTimes->firstCompositionStart		=	getTimestamp(EGL_FIRST_COMPOSITION_START_TIME_ANDROID, map, supportedValues);
	frameTimes->lastCompositionStart		=	getTimestamp(EGL_LAST_COMPOSITION_START_TIME_ANDROID, map, supportedValues);
	frameTimes->firstCompositionGpuFinished	=	getTimestamp(EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID, map, supportedValues);
	frameTimes->displayPresent				=	getTimestamp(EGL_DISPLAY_PRESENT_TIME_ANDROID, map, supportedValues);
	frameTimes->dequeueReady				=	getTimestamp(EGL_DEQUEUE_READY_TIME_ANDROID, map, supportedValues);
	frameTimes->readsDone					=	getTimestamp(EGL_READS_DONE_TIME_ANDROID, map, supportedValues);
}

bool timestampValid (EGLnsecsANDROID timestamp)
{
	// \todo [2017-10-19 brianderson] Don't consider 0 invalid once kernel fix is in.
	return (timestamp > 0) || (timestamp == EGL_TIMESTAMP_PENDING_ANDROID);
}

bool timestampPending (EGLnsecsANDROID timestamp)
{
	return timestamp == EGL_TIMESTAMP_PENDING_ANDROID;
}

template<typename T>
void check_lt(tcu::ResultCollector& result, const T& a, const T& b, const std::string& msg) {
	if (a < b)
		return;
	std::string m = msg + "!(" + de::toString(a) + " < " + de::toString(b) + ")";
	result.fail(m);
}

template<typename T>
void check_le(tcu::ResultCollector& result, const T& a, const T& b, const std::string& msg) {
	if (a <= b)
		return;
	std::string m = msg + "!(" + de::toString(a) + " <= " + de::toString(b) + ")";
	result.fail(m);
}

void verifySingleFrame (const FrameTimes& frameTimes, tcu::ResultCollector& result, bool verifyReadsDone)
{
	// Verify CPU timeline is monotonic.
	check_lt(result, frameTimes.swapBufferBeginNs, frameTimes.latch, "Buffer latched before it was swapped.");
	check_lt(result, frameTimes.latch, frameTimes.firstCompositionStart, "Buffer composited before it was latched.");
	check_le(result, frameTimes.firstCompositionStart, frameTimes.lastCompositionStart, "First composition start after last composition start.");
	check_lt(result, frameTimes.lastCompositionStart, frameTimes.dequeueReady, "Buffer composited after it was ready to be dequeued.");

	// Verify GPU timeline is monotonic.
	if (timestampValid(frameTimes.firstCompositionGpuFinished))
		check_lt(result, frameTimes.renderingComplete, frameTimes.firstCompositionGpuFinished, "Buffer rendering completed after compositor GPU work finished.");

	if (timestampValid(frameTimes.displayPresent))
		check_lt(result, frameTimes.renderingComplete, frameTimes.displayPresent, "Buffer displayed before rendering completed.");

	if (timestampValid(frameTimes.firstCompositionGpuFinished) && timestampValid(frameTimes.displayPresent))
		check_lt(result, frameTimes.firstCompositionGpuFinished, frameTimes.displayPresent, "Buffer displayed before compositor GPU work completed");

	// Drivers may maintain shadow copies of the buffer, so the readsDone time
	// of the real buffer may be earlier than apparent dependencies. We can only
	// be sure that the readsDone time must be after the renderingComplete time.
    // It may also be equal to the renderingComplete time if no reads were
    // peformed.
	if (verifyReadsDone && timestampValid(frameTimes.readsDone))
		check_le(result, frameTimes.renderingComplete, frameTimes.readsDone, "Buffer rendering completed after reads completed.");

	// Verify CPU/GPU dependencies
	if (timestampValid(frameTimes.firstCompositionGpuFinished))
		check_lt(result, frameTimes.firstCompositionStart, frameTimes.firstCompositionGpuFinished, "Composition CPU work started after GPU work finished.");

	if (timestampValid(frameTimes.displayPresent))
		check_lt(result, frameTimes.firstCompositionStart, frameTimes.displayPresent, "Buffer displayed before it was composited.");
}

void verifyNeighboringFrames (const FrameTimes& frame1, const FrameTimes& frame2, tcu::ResultCollector& result)
{
	// CPU timeline.
	check_lt(result, frame1.swapBufferBeginNs, frame2.swapBufferBeginNs, "Swap begin times not monotonic.");
	check_lt(result, frame1.latch, frame2.latch, "Latch times not monotonic.");
	check_lt(result, frame1.lastCompositionStart, frame2.latch, "Old buffer composited after new buffer latched.");
	check_lt(result, frame1.lastCompositionStart, frame2.firstCompositionStart, "Composition times overlap.");
	check_lt(result, frame1.dequeueReady, frame2.dequeueReady, "Dequeue ready times not monotonic.");

	// GPU timeline.
	if (timestampValid(frame1.firstCompositionGpuFinished) && timestampValid(frame2.firstCompositionGpuFinished))
		check_lt(result, frame1.firstCompositionGpuFinished, frame2.firstCompositionGpuFinished, "Composition GPU work complete times not monotonic.");

	if (timestampValid(frame1.displayPresent) && timestampValid(frame2.displayPresent))
		check_lt(result, frame1.displayPresent, frame2.displayPresent, "Display present times not monotonic.");
}

EGLContext createGLES2Context (const Library& egl, EGLDisplay display, EGLConfig config)
{
	EGLContext		context = EGL_NO_CONTEXT;
	const EGLint	attribList[] =
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};

	EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));

	context = egl.createContext(display, config, EGL_NO_CONTEXT, attribList);
	EGLU_CHECK_MSG(egl, "eglCreateContext() failed");
	TCU_CHECK(context);

	return context;
}

class GetFrameTimestampTest : public SimpleConfigCase
{
public:
							GetFrameTimestampTest	(EglTestContext& eglTestCtx, const NamedFilterList& filters);
							~GetFrameTimestampTest	(void);

private:
	void					executeForConfig		(EGLDisplay display, EGLConfig config);
	void					initializeExtension		(const Library& egl);

	// Not allowed
							GetFrameTimestampTest	(const GetFrameTimestampTest&);
	GetFrameTimestampTest&	operator=				(const GetFrameTimestampTest&);

	// TODO: Move these to eglw::Library.
	eglGetNextFrameIdANDROIDFunc				m_eglGetNextFrameIdANDROID;
	eglGetCompositorTimingANDROIDFunc			m_eglGetCompositorTimingANDROID;
	eglGetCompositorTimingSupportedANDROIDFunc	m_eglGetCompositorTimingSupportedANDROID;
	eglGetFrameTimestampsANDROIDFunc			m_eglGetFrameTimestampsANDROID;
	eglGetFrameTimestampSupportedANDROIDFunc	m_eglGetFrameTimestampSupportedANDROID;

	tcu::ResultCollector						m_result;
};

GetFrameTimestampTest::GetFrameTimestampTest (EglTestContext& eglTestCtx, const NamedFilterList& filters)
	: SimpleConfigCase							(eglTestCtx, filters.getName(), filters.getDescription(), filters)
	, m_eglGetNextFrameIdANDROID				(DE_NULL)
	, m_eglGetCompositorTimingANDROID			(DE_NULL)
	, m_eglGetCompositorTimingSupportedANDROID	(DE_NULL)
	, m_eglGetFrameTimestampsANDROID			(DE_NULL)
	, m_eglGetFrameTimestampSupportedANDROID	(DE_NULL)
	, m_result									(m_testCtx.getLog())
{
}

GetFrameTimestampTest::~GetFrameTimestampTest (void)
{
}

void GetFrameTimestampTest::initializeExtension (const Library& egl)
{
	m_eglGetNextFrameIdANDROID = reinterpret_cast<eglGetNextFrameIdANDROIDFunc>(egl.getProcAddress("eglGetNextFrameIdANDROID"));
	EGLU_CHECK_MSG(egl, "getProcAddress of eglGetNextFrameIdANDROID failed.");
	m_eglGetCompositorTimingANDROID = reinterpret_cast<eglGetCompositorTimingANDROIDFunc>(egl.getProcAddress("eglGetCompositorTimingANDROID"));
	EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingANDROID failed.");
	m_eglGetCompositorTimingSupportedANDROID = reinterpret_cast<eglGetCompositorTimingSupportedANDROIDFunc>(egl.getProcAddress("eglGetCompositorTimingSupportedANDROID"));
	EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingSupportedANDROID failed.");
	m_eglGetFrameTimestampsANDROID = reinterpret_cast<eglGetFrameTimestampsANDROIDFunc>(egl.getProcAddress("eglGetFrameTimestampsANDROID"));
	EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampsANDROID failed.");
	m_eglGetFrameTimestampSupportedANDROID = reinterpret_cast<eglGetFrameTimestampSupportedANDROIDFunc>(egl.getProcAddress("eglGetFrameTimestampSupportedANDROID"));
	EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampSupportedANDROID failed.");
}


string getConfigIdString (const Library& egl, EGLDisplay display, EGLConfig config)
{
	std::ostringstream	stream;
	EGLint				id;

	EGLU_CHECK_CALL(egl, getConfigAttrib(display, config , EGL_CONFIG_ID, &id));

	stream << id;

	return stream.str();
}

deUint32 createGLES2Program (const glw::Functions& gl, TestLog& log)
{
	const char* const vertexShaderSource =
	"attribute highp vec2 a_pos;\n"
	"void main (void)\n"
	"{\n"
	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
	"}";

	const char* const fragmentShaderSource =
	"void main (void)\n"
	"{\n"
	"\tgl_FragColor = vec4(0.9, 0.1, 0.4, 1.0);\n"
	"}";

	deUint32	program			= 0;
	deUint32	vertexShader	= 0;
	deUint32	fragmentShader	= 0;

	deInt32		vertexCompileStatus;
	string		vertexInfoLog;
	deInt32		fragmentCompileStatus;
	string		fragmentInfoLog;
	deInt32		linkStatus;
	string		programInfoLog;

	try
	{
		program			= gl.createProgram();
		vertexShader	= gl.createShader(GL_VERTEX_SHADER);
		fragmentShader	= gl.createShader(GL_FRAGMENT_SHADER);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shaders and program");

		gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
		gl.compileShader(vertexShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup vertex shader");

		gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
		gl.compileShader(fragmentShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup fragment shader");

		{
			deInt32		infoLogLength = 0;

			gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompileStatus);
			gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength);

			vertexInfoLog.resize(infoLogLength, '\0');

			gl.getShaderInfoLog(vertexShader, (glw::GLsizei)vertexInfoLog.length(), &infoLogLength, &(vertexInfoLog[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get vertex shader compile info");

			vertexInfoLog.resize(infoLogLength);
		}

		{
			deInt32		infoLogLength = 0;

			gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentCompileStatus);
			gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength);

			fragmentInfoLog.resize(infoLogLength, '\0');

			gl.getShaderInfoLog(fragmentShader, (glw::GLsizei)fragmentInfoLog.length(), &infoLogLength, &(fragmentInfoLog[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get fragment shader compile info");

			fragmentInfoLog.resize(infoLogLength);
		}

		gl.attachShader(program, vertexShader);
		gl.attachShader(program, fragmentShader);
		gl.linkProgram(program);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup program");

		{
			deInt32		infoLogLength = 0;

			gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
			gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);

			programInfoLog.resize(infoLogLength, '\0');

			gl.getProgramInfoLog(program, (glw::GLsizei)programInfoLog.length(), &infoLogLength, &(programInfoLog[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get program link info");

			programInfoLog.resize(infoLogLength);
		}

		if (linkStatus == 0 || vertexCompileStatus == 0 || fragmentCompileStatus == 0)
		{

			log.startShaderProgram(linkStatus != 0, programInfoLog.c_str());

			log << TestLog::Shader(QP_SHADER_TYPE_VERTEX, vertexShaderSource, vertexCompileStatus != 0, vertexInfoLog);
			log << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, fragmentShaderSource, fragmentCompileStatus != 0, fragmentInfoLog);

			log.endShaderProgram();
		}

		gl.deleteShader(vertexShader);
		gl.deleteShader(fragmentShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete shaders");

		TCU_CHECK(linkStatus != 0 && vertexCompileStatus != 0 && fragmentCompileStatus != 0);
	}
	catch (...)
	{
		if (program)
			gl.deleteProgram(program);

		if (vertexShader)
			gl.deleteShader(vertexShader);

		if (fragmentShader)
			gl.deleteShader(fragmentShader);

		throw;
	}

	return program;
}

void GetFrameTimestampTest::executeForConfig (EGLDisplay display, EGLConfig config)
{
	const Library&						egl			= m_eglTestCtx.getLibrary();

	if (!eglu::hasExtension(egl, display, "EGL_ANDROID_get_frame_timestamps"))
		TCU_THROW(NotSupportedError, "EGL_ANDROID_get_frame_timestamps is not supported");

	initializeExtension(egl);

	const string						configIdStr	(getConfigIdString(egl, display, config));
	tcu::ScopedLogSection				logSection	(m_testCtx.getLog(), ("Config ID " + configIdStr).c_str(), ("Config ID " + configIdStr).c_str());
	const eglu::NativeWindowFactory&	factory		= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());

	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Message << "EGL_RED_SIZE: "		<< eglu::getConfigAttribInt(egl, display, config, EGL_RED_SIZE)		<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_GREEN_SIZE: "	<< eglu::getConfigAttribInt(egl, display, config, EGL_GREEN_SIZE)	<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_BLUE_SIZE: "	<< eglu::getConfigAttribInt(egl, display, config, EGL_BLUE_SIZE)	<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_ALPHA_SIZE: "	<< eglu::getConfigAttribInt(egl, display, config, EGL_ALPHA_SIZE)	<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_DEPTH_SIZE: "	<< eglu::getConfigAttribInt(egl, display, config, EGL_DEPTH_SIZE)	<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_STENCIL_SIZE: "	<< eglu::getConfigAttribInt(egl, display, config, EGL_STENCIL_SIZE)	<< TestLog::EndMessage;
		log << TestLog::Message << "EGL_SAMPLES: "		<< eglu::getConfigAttribInt(egl, display, config, EGL_SAMPLES)		<< TestLog::EndMessage;
	}

	de::UniquePtr<eglu::NativeWindow>	window	(factory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(128, 128, eglu::WindowParams::VISIBILITY_VISIBLE)));

	eglu::UniqueSurface					surface	(egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
	eglu::UniqueContext					context	(egl, display, createGLES2Context(egl, display, config));
	glw::Functions						gl;
	deUint32							program = 0;

	EGLU_CHECK_CALL(egl, surfaceAttrib(display, *surface, EGL_TIMESTAMPS_ANDROID, EGL_TRUE));

	m_eglTestCtx.initGLFunctions(&gl, glu::ApiType::es(2,0));

	EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, *context));

	try
	{
		// EGL_DISPLAY_PRESENT_TIME_ANDROID support is currently optional
		// but should be required once HWC1 is no longer supported.
		// All HWC2 devices should support EGL_DISPLAY_PRESENT_TIME_ANDROID.
		TimestampInfoMap timestamps;
		timestamps[EGL_REQUESTED_PRESENT_TIME_ANDROID]				=	TimestampInfo(true,		false, 0);
		timestamps[EGL_RENDERING_COMPLETE_TIME_ANDROID]				=	TimestampInfo(true,		false, 0);
		timestamps[EGL_COMPOSITION_LATCH_TIME_ANDROID]				=	TimestampInfo(true,		false, 0);
		timestamps[EGL_FIRST_COMPOSITION_START_TIME_ANDROID]		=	TimestampInfo(true,		false, 0);
		timestamps[EGL_LAST_COMPOSITION_START_TIME_ANDROID]			=	TimestampInfo(true,		false, 0);
		timestamps[EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID]	=	TimestampInfo(true,		false, 0);
		timestamps[EGL_DISPLAY_PRESENT_TIME_ANDROID]				=	TimestampInfo(false,	false, 0);
		timestamps[EGL_DEQUEUE_READY_TIME_ANDROID]					=	TimestampInfo(true,		false, 0);
		timestamps[EGL_READS_DONE_TIME_ANDROID]						=	TimestampInfo(true,		false, 0);

		const eglw::EGLint invalidTimestampName = EGL_READS_DONE_TIME_ANDROID + 1;

		// Verify required timestamps are supported and populate supportedNames.
		std::vector<eglw::EGLint> supportedNames;
		for (TimestampInfoMap::iterator i = timestamps.begin(); i != timestamps.end(); i++)
		{
			TimestampInfo& info = i->second;
			info.supported = m_eglGetFrameTimestampSupportedANDROID(display, *surface, i->first) != EGL_FALSE;
			EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");

			if (info.supported)
			{
				info.supportedIndex = supportedNames.size();
				supportedNames.push_back(i->first);
			}
			else
				TCU_CHECK_MSG(!info.required, "Required timestamp not supported.");
		}

		// Verify unsupported timestamps are reported properly.
		const bool invalidSupported = m_eglGetFrameTimestampSupportedANDROID(display, *surface, invalidTimestampName) != EGL_FALSE;
		EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");
		TCU_CHECK_MSG(!invalidSupported, "Non existant timestamp reports that it is supported.");

		// Verify compositor timings are supported.
		const bool deadlineSupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_DEADLINE_ANDROID) != EGL_FALSE;
		EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
		TCU_CHECK_MSG(deadlineSupported, "EGL_COMPOSITE_DEADLINE_ANDROID not supported.");
		const bool intervalSupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_INTERVAL_ANDROID) != EGL_FALSE;
		EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
		TCU_CHECK_MSG(intervalSupported, "EGL_COMPOSITE_INTERVAL_ANDROID not supported.");
		const bool latencySupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID) != EGL_FALSE;
		EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
		TCU_CHECK_MSG(latencySupported, "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID not supported.");

		const float positions1[] =
		{
			 0.00f,  0.00f,
			 0.75f,  0.00f,
			 0.75f,  0.75f,

			 0.75f,  0.75f,
			 0.00f,  0.75f,
			 0.00f,  0.00f
		};

		const float positions2[] =
		{
			-0.75f, -0.75f,
			 0.00f, -0.75f,
			 0.00f,  0.00f,

			 0.00f,  0.00f,
			-0.75f,  0.00f,
			-0.75f, -0.75f
		};

		deUint32 posLocation;

		program	= createGLES2Program(gl, m_testCtx.getLog());

		gl.useProgram(program);
		posLocation	= gl.getAttribLocation(program, "a_pos");
		gl.enableVertexAttribArray(posLocation);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shader program for rendering");

		const size_t frameCount = 120;
		std::vector<FrameTimes> frameTimes(frameCount);
		for (size_t i = 0; i < frameCount; i++)
		{
			FrameTimes& frame = frameTimes[i];

			const eglw::EGLint compositorTimingNames[] =
			{
				EGL_COMPOSITE_DEADLINE_ANDROID,
				EGL_COMPOSITE_INTERVAL_ANDROID,
				EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID,
			};
			const EGLint compositorTimingCount = DE_LENGTH_OF_ARRAY(compositorTimingNames);
			EGLnsecsANDROID compositorTimingValues[compositorTimingCount] = { -2 };

			// Get the current time before making any API calls in case "now"
			// just happens to get sampled near one of the composite deadlines.
			EGLnsecsANDROID now = getNanoseconds();

			// Get the frame id.
			EGLuint64KHR nextFrameId = 0;
			CHECK_NAKED_EGL_CALL(egl, m_eglGetNextFrameIdANDROID(display, *surface, &nextFrameId));
			frame.frameId				=	nextFrameId;

			// Get the compositor timing.
			CHECK_NAKED_EGL_CALL(egl, m_eglGetCompositorTimingANDROID(
				display, *surface, compositorTimingCount,
				compositorTimingNames, compositorTimingValues));
			frame.compositeDeadline			=	compositorTimingValues[0];
			frame.compositeInterval			=	compositorTimingValues[1];
			frame.compositeToPresentLatency	=	compositorTimingValues[2];

			// Verify compositor timing is sane.
			check_lt<EGLnsecsANDROID>(m_result, 1000000, frame.compositeInterval, "Reported refresh rate greater than 1kHz.");
			check_lt<EGLnsecsANDROID>(m_result, frame.compositeInterval, 1000000000, "Reported refresh rate less than 1Hz.");
			check_lt<EGLnsecsANDROID>(m_result, 0, frame.compositeToPresentLatency, "Composite to present latency must be greater than 0.");
			check_lt(m_result, frame.compositeToPresentLatency, frame.compositeInterval * 4, "Composite to present latency is more than 4 vsyncs.");
			const EGLnsecsANDROID minDeadline = now;
			check_lt(m_result, minDeadline, frame.compositeDeadline, "Next composite deadline is in the past.");
			const EGLnsecsANDROID maxDeadline = now + frame.compositeInterval * 2;
			check_lt(m_result, frame.compositeDeadline, maxDeadline, "Next composite deadline over two intervals away.");

			const float colorAngle = (static_cast<float>(i) / static_cast<float>(frameCount)) * 6.28318f;
			gl.clearColor((1.0f + deFloatSin(colorAngle)) / 2.0f, 0.7f, (1.0f + deFloatCos(colorAngle)) / 2.0f, 1.0f);
			gl.clear(GL_COLOR_BUFFER_BIT);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear surface");

			const bool posSelect  = ((i % 2) == 0);
			gl.vertexAttribPointer(posLocation, 2, GL_FLOAT, GL_FALSE, 0, posSelect ? positions1 : positions2);
			gl.drawArrays(GL_TRIANGLES, 0, 6);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");

			frame.swapBufferBeginNs = getNanoseconds();
			EGLU_CHECK_CALL(egl, swapBuffers(display, *surface));

			// All timestamps from 6 frames ago should definitely be available.
			const size_t frameDelay = 6;
			if (i >= frameDelay)
			{
				// \todo [2017-01-25 brianderson] Remove this work around once reads done is fixed.
				const bool verifyReadsDone	=	i > (frameDelay + 3);
				FrameTimes&		frame6ago	=	frameTimes[i-frameDelay];
				std::vector<EGLnsecsANDROID> supportedValues(supportedNames.size(), 0);

				CHECK_NAKED_EGL_CALL(egl, m_eglGetFrameTimestampsANDROID(
					display, *surface, frame6ago.frameId, static_cast<eglw::EGLint>(supportedNames.size()),
					&supportedNames[0], &supportedValues[0]));
				populateFrameTimes(&frame6ago, timestamps, supportedValues);

				verifySingleFrame(frame6ago, m_result, verifyReadsDone);
				if (i >= frameDelay + 1)
				{
					FrameTimes& frame7ago = frameTimes[i-frameDelay-1];
					verifyNeighboringFrames(frame7ago, frame6ago, m_result);
				}
			}
		}

		// All timestamps for the most recently swapped frame should
		// become available by only polling eglGetFrametimestamps.
		// No additional swaps should be necessary.
		FrameTimes&				lastFrame				=	frameTimes.back();
		const EGLnsecsANDROID	pollingDeadline			=	lastFrame.swapBufferBeginNs + 1000000000;
		bool					finalTimestampAvailable	=	false;

		do
		{
			std::vector<EGLnsecsANDROID> supportedValues(supportedNames.size(), 0);
			CHECK_NAKED_EGL_CALL(egl, m_eglGetFrameTimestampsANDROID(
				display, *surface, lastFrame.frameId, static_cast<eglw::EGLint>(supportedNames.size()),
				&supportedNames[0], &supportedValues[0]));
			populateFrameTimes(&lastFrame, timestamps, supportedValues);

			// Poll for present if it's supported.
			// Otherwise, poll for firstCompositionStart.
			if (timestamps[EGL_DISPLAY_PRESENT_TIME_ANDROID].supported)
				finalTimestampAvailable = !timestampPending(lastFrame.displayPresent);
			else
				finalTimestampAvailable = !timestampPending(lastFrame.firstCompositionStart);
		} while (!finalTimestampAvailable && (getNanoseconds() < pollingDeadline));

		m_result.check(finalTimestampAvailable, "Timed out polling for timestamps of last swap.");
		m_result.check((lastFrame.requestedPresent >= 0), "Requested present of last swap not avaiable.");
		m_result.check((lastFrame.renderingComplete >= 0), "Rendering complete of last swap not avaiable.");
		m_result.check((lastFrame.latch >= 0), "Latch of last swap not avaiable.");
		m_result.check((lastFrame.firstCompositionStart >= 0), "First composite time of last swap not avaiable.");
		m_result.check((lastFrame.lastCompositionStart >= 0), "Last composite time of last swap not avaiable.");

		window->processEvents();
		gl.disableVertexAttribArray(posLocation);
		gl.useProgram(0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to release program state");

		gl.deleteProgram(program);
		program = 0;
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram()");

		m_result.setTestContextResult(m_testCtx);
	}
	catch (...)
	{
		if (program != 0)
			gl.deleteProgram(program);

		EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
		throw;
	}

	EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
}

class GetFrameTimestampsTests : public TestCaseGroup
{
public:
								GetFrameTimestampsTests	(EglTestContext& eglTestCtx);
	void						init					(void);

private:
								GetFrameTimestampsTests	(const GetFrameTimestampsTests&);
	GetFrameTimestampsTests&	operator=				(const GetFrameTimestampsTests&);
};


GetFrameTimestampsTests::GetFrameTimestampsTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "get_frame_timestamps", "Get frame timestamp tests")
{
}

bool isWindow (const eglu::CandidateConfig& c)
{
	return (c.surfaceType() & EGL_WINDOW_BIT) != 0;
}

void GetFrameTimestampsTests::init (void)
{
	eglu::FilterList baseFilters;
	baseFilters << isWindow;

	vector<NamedFilterList> filterLists;
	getDefaultFilterLists(filterLists, baseFilters);

	for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
		addChild(new GetFrameTimestampTest(m_eglTestCtx, *i));
}

} // anonymous

TestCaseGroup* createGetFrameTimestampsTests (EglTestContext& eglTestCtx)
{
	return new GetFrameTimestampsTests(eglTestCtx);
}

} // egl
} // deqp
