/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL Module
 * ---------------------------------------
 *
 * Copyright 2015 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 EXT_buffer_age
 *//*--------------------------------------------------------------------*/

#include "teglBufferAgeTests.hpp"

#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"

#include "egluNativeWindow.hpp"
#include "egluUtil.hpp"
#include "egluConfigFilter.hpp"

#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"

#include "gluDefs.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"

#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "deRandom.hpp"
#include "deString.h"

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

using std::string;
using std::vector;
using glw::GLubyte;
using tcu::IVec2;

using namespace eglw;

namespace deqp
{
namespace egl
{
namespace
{

typedef	tcu::Vector<GLubyte, 3> Color;

class GLES2Renderer;

class ReferenceRenderer;

class BufferAgeTest : public TestCase
{
public:
	enum DrawType
	{
		DRAWTYPE_GLES2_CLEAR,
		DRAWTYPE_GLES2_RENDER
	};

	enum ResizeType
	{
		RESIZETYPE_NONE = 0,
		RESIZETYPE_BEFORE_SWAP,
		RESIZETYPE_AFTER_SWAP,

		RESIZETYPE_LAST
	};

								BufferAgeTest	(EglTestContext&			eglTestCtx,
												 bool						preserveColorBuffer,
												 const vector<DrawType>&	oddFrameDrawType,
												 const vector<DrawType>&	evenFrameDrawType,
												 ResizeType					resizeType,
												 const char*				name,
												 const char*				description);

								~BufferAgeTest	(void);

	void						init			(void);
	void						deinit			(void);
	IterateResult				iterate			(void);

private:
	void						initEGLSurface (EGLConfig config);
	void						initEGLContext (EGLConfig config);

	const int					m_seed;
	const bool					m_preserveColorBuffer;
	const vector<DrawType>		m_oddFrameDrawType;
	const vector<DrawType>		m_evenFrameDrawType;
	const ResizeType			m_resizeType;

	EGLDisplay					m_eglDisplay;
	eglu::NativeWindow*			m_window;
	EGLSurface					m_eglSurface;
	EGLConfig					m_eglConfig;
	EGLContext					m_eglContext;
	glw::Functions				m_gl;

	GLES2Renderer*				m_gles2Renderer;
	ReferenceRenderer*			m_refRenderer;

};

struct ColoredRect
{
public:
							ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_);
	IVec2					bottomLeft;
	IVec2					topRight;
	Color					color;
};

ColoredRect::ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_)
	: bottomLeft(bottomLeft_)
	, topRight	(topRight_)
	, color		(color_)
{
}

struct DrawCommand
{
							DrawCommand (const BufferAgeTest::DrawType drawType_, const ColoredRect& rect_);
	BufferAgeTest::DrawType drawType;
	ColoredRect				rect;
};

DrawCommand::DrawCommand (const BufferAgeTest::DrawType drawType_, const ColoredRect& rect_)
	: drawType(drawType_)
	, rect    (rect_)
{
}

struct Frame
{
						Frame (int width_, int height_);
	int					width;
	int					height;
	vector<DrawCommand> draws;
};

Frame::Frame (int width_, int height_)
	: width(width_)
	, height(height_)
{
}


// (x1,y1) lie in the lower-left quadrant while (x2,y2) lie in the upper-right.
// the coords are multiplied by 4 to amplify the minimial difference between coords to 4 (if not zero)
// to avoid the situation where two edges are too close to each other which makes the rounding error
// intoleratable by compareToReference()
void generateRandomFrame (Frame* dst, const vector<BufferAgeTest::DrawType>& drawTypes, de::Random& rnd)
{
	for (size_t ndx = 0; ndx < drawTypes.size(); ndx++)
	{
		const int			x1			= rnd.getInt(0, (dst->width-1)/8) * 4;
		const int			y1			= rnd.getInt(0, (dst->height-1)/8) * 4;
		const int			x2			= rnd.getInt((dst->width-1)/8, (dst->width-1)/4) * 4;
		const int			y2			= rnd.getInt((dst->height-1)/8, (dst->height-1)/4) * 4;
		const GLubyte		r			= rnd.getUint8();
		const GLubyte		g			= rnd.getUint8();
		const GLubyte		b			= rnd.getUint8();
		const ColoredRect	coloredRect	(IVec2(x1, y1), IVec2(x2, y2), Color(r, g, b));
		const DrawCommand	drawCommand (drawTypes[ndx], coloredRect);
		(*dst).draws.push_back(drawCommand);
	}
}

typedef vector<Frame> FrameSequence;

//helper function declaration
EGLConfig		getEGLConfig					(const Library& egl, EGLDisplay eglDisplay, bool preserveColorBuffer);
void			clearColorScreen				(const glw::Functions& gl, const tcu::Vec4& clearColor);
void			clearColorReference				(tcu::Surface* ref, const tcu::Vec4& clearColor);
void			readPixels						(const glw::Functions& gl, tcu::Surface* screen);
float			windowToDeviceCoordinates		(int x, int length);
bool			compareToReference				(tcu::TestLog& log, const tcu::Surface& reference, const tcu::Surface& buffer, int frameNdx, int bufferNum);
vector<int>		getFramesOnBuffer				(const vector<int>& bufferAges, int frameNdx);

class GLES2Renderer
{
public:
							GLES2Renderer		(const glw::Functions& gl);
							~GLES2Renderer		(void);
	void					render				(int width, int height, const Frame& frame) const;

private:
							GLES2Renderer		(const GLES2Renderer&);
	GLES2Renderer&			operator=			(const GLES2Renderer&);

	const glw::Functions&	m_gl;
	glu::ShaderProgram		m_glProgram;
	glw::GLuint				m_coordLoc;
	glw::GLuint				m_colorLoc;
};

// generate sources for vertex and fragment buffer
glu::ProgramSources getSources (void)
{
	const char* const vertexShaderSource =
		"attribute mediump vec4 a_pos;\n"
		"attribute mediump vec4 a_color;\n"
		"varying mediump vec4 v_color;\n"
		"void main(void)\n"
		"{\n"
		"\tv_color = a_color;\n"
		"\tgl_Position = a_pos;\n"
		"}";

	const char* const fragmentShaderSource =
		"varying mediump vec4 v_color;\n"
		"void main(void)\n"
		"{\n"
		"\tgl_FragColor = v_color;\n"
		"}";

	return glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource);
}

GLES2Renderer::GLES2Renderer (const glw::Functions& gl)
	: m_gl		  (gl)
	, m_glProgram (gl, getSources())
	, m_coordLoc  ((glw::GLuint)-1)
	, m_colorLoc  ((glw::GLuint)-1)
{
	m_colorLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_color");
	m_coordLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_pos");
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to get attribute locations");
}

GLES2Renderer::~GLES2Renderer (void)
{
}

void GLES2Renderer::render (int width, int height, const Frame& frame) const
{
	for (size_t drawNdx = 0; drawNdx < frame.draws.size(); drawNdx++)
	{
		const ColoredRect& coloredRect = frame.draws[drawNdx].rect;
		if (frame.draws[drawNdx].drawType == BufferAgeTest::DRAWTYPE_GLES2_RENDER)
		{
			float x1 = windowToDeviceCoordinates(coloredRect.bottomLeft.x(), width);
			float y1 = windowToDeviceCoordinates(coloredRect.bottomLeft.y(), height);
			float x2 = windowToDeviceCoordinates(coloredRect.topRight.x(), width);
			float y2 = windowToDeviceCoordinates(coloredRect.topRight.y(), height);

			const glw::GLfloat coords[] =
			{
				x1, y1, 0.0f, 1.0f,
				x1, y2, 0.0f, 1.0f,
				x2, y2, 0.0f, 1.0f,

				x2, y2, 0.0f, 1.0f,
				x2, y1, 0.0f, 1.0f,
				x1, y1, 0.0f, 1.0f
			};

			const glw::GLubyte colors[] =
			{
				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,
				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,
				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,

				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,
				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,
				coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255,
			};

			m_gl.useProgram(m_glProgram.getProgram());
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");

			m_gl.enableVertexAttribArray(m_coordLoc);
			m_gl.enableVertexAttribArray(m_colorLoc);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to enable attributes");

			m_gl.vertexAttribPointer(m_coordLoc, 4, GL_FLOAT, GL_FALSE, 0, coords);
			m_gl.vertexAttribPointer(m_colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to set attribute pointers");

			m_gl.drawArrays(GL_TRIANGLES, 0, DE_LENGTH_OF_ARRAY(coords)/4);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays(), failed");

			m_gl.disableVertexAttribArray(m_coordLoc);
			m_gl.disableVertexAttribArray(m_colorLoc);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to disable attributes");

			m_gl.useProgram(0);
			GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
		}
		else if (frame.draws[drawNdx].drawType == BufferAgeTest::DRAWTYPE_GLES2_CLEAR)
		{
			m_gl.enable(GL_SCISSOR_TEST);
			m_gl.scissor(coloredRect.bottomLeft.x(), coloredRect.bottomLeft.y(),
						 coloredRect.topRight.x()-coloredRect.bottomLeft.x(), coloredRect.topRight.y()-coloredRect.bottomLeft.y());
			m_gl.clearColor(coloredRect.color.x()/255.0f, coloredRect.color.y()/255.0f, coloredRect.color.z()/255.0f, 1.0f);
			m_gl.clear(GL_COLOR_BUFFER_BIT);
			m_gl.disable(GL_SCISSOR_TEST);
		}
		else
			DE_ASSERT(false);
	}
}

class ReferenceRenderer
{
public:
						ReferenceRenderer	(void);
	void				render				(tcu::Surface* target, const Frame& frame) const;
private:
						ReferenceRenderer	(const ReferenceRenderer&);
	ReferenceRenderer&	operator=			(const ReferenceRenderer&);
};

ReferenceRenderer::ReferenceRenderer(void)
{
}

void ReferenceRenderer::render (tcu::Surface* target, const Frame& frame) const
{
	for (size_t drawNdx = 0; drawNdx < frame.draws.size(); drawNdx++)
	{
		const ColoredRect& coloredRect = frame.draws[drawNdx].rect;
		if (frame.draws[drawNdx].drawType == BufferAgeTest::DRAWTYPE_GLES2_RENDER || frame.draws[drawNdx].drawType == BufferAgeTest::DRAWTYPE_GLES2_CLEAR)
		{
			// tcu does not support degenerate subregions. Since they correspond to no-op rendering, just skip them.
			if (coloredRect.bottomLeft.x() == coloredRect.topRight.x() || coloredRect.bottomLeft.y() == coloredRect.topRight.y())
				continue;

			const tcu::UVec4 color(coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255);
			tcu::clear(tcu::getSubregion(target->getAccess(), coloredRect.bottomLeft.x(), coloredRect.bottomLeft.y(),
										 coloredRect.topRight.x()-coloredRect.bottomLeft.x(), coloredRect.topRight.y()-coloredRect.bottomLeft.y()), color);
		}
		else
			DE_ASSERT(false);
	}
}

BufferAgeTest::BufferAgeTest (EglTestContext&			eglTestCtx,
							  bool						preserveColorBuffer,
							  const vector<DrawType>&	oddFrameDrawType,
							  const vector<DrawType>&	evenFrameDrawType,
							  ResizeType				resizeType,
							  const char*				name,
							  const char*				description)
	: TestCase				(eglTestCtx, name, description)
	, m_seed				(deStringHash(name))
	, m_preserveColorBuffer (preserveColorBuffer)
	, m_oddFrameDrawType	(oddFrameDrawType)
	, m_evenFrameDrawType	(evenFrameDrawType)
	, m_resizeType			(resizeType)
	, m_eglDisplay			(EGL_NO_DISPLAY)
	, m_window				(DE_NULL)
	, m_eglSurface			(EGL_NO_SURFACE)
	, m_eglContext			(EGL_NO_CONTEXT)
	, m_gles2Renderer		(DE_NULL)
	, m_refRenderer			(DE_NULL)
{
}

BufferAgeTest::~BufferAgeTest (void)
{
	deinit();
}

void BufferAgeTest::init (void)
{
	const Library&	egl	= m_eglTestCtx.getLibrary();

	m_eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());

	if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_buffer_age") == false)
	{
		egl.terminate(m_eglDisplay);
		m_eglDisplay = EGL_NO_DISPLAY;
		TCU_THROW(NotSupportedError, "EGL_EXT_buffer_age is not supported");
	}

	m_eglConfig	 = getEGLConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, m_preserveColorBuffer);

	if (m_eglConfig == DE_NULL)
		TCU_THROW(NotSupportedError, "No supported config found");

	//create surface and context and make them current
	initEGLSurface(m_eglConfig);
	initEGLContext(m_eglConfig);

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

	m_gles2Renderer = new GLES2Renderer(m_gl);
	m_refRenderer   = new ReferenceRenderer();
}

void BufferAgeTest::deinit (void)
{
	const Library& egl = m_eglTestCtx.getLibrary();

	delete m_refRenderer;
	m_refRenderer = DE_NULL;

	delete m_gles2Renderer;
	m_gles2Renderer = DE_NULL;

	if (m_eglContext != EGL_NO_CONTEXT)
	{
		egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
		egl.destroyContext(m_eglDisplay, m_eglContext);
		m_eglContext = EGL_NO_CONTEXT;
	}

	if (m_eglSurface != EGL_NO_SURFACE)
	{
		egl.destroySurface(m_eglDisplay, m_eglSurface);
		m_eglSurface = EGL_NO_SURFACE;
	}

	if (m_eglDisplay != EGL_NO_DISPLAY)
	{
		egl.terminate(m_eglDisplay);
		m_eglDisplay = EGL_NO_DISPLAY;
	}

	delete m_window;
	m_window = DE_NULL;
}

void BufferAgeTest::initEGLSurface (EGLConfig config)
{
	const eglu::NativeWindowFactory& factory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
	m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, config, DE_NULL,
									eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
	m_eglSurface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, config, DE_NULL);
}

void BufferAgeTest::initEGLContext (EGLConfig config)
{
	const Library&	egl			 = m_eglTestCtx.getLibrary();
	const EGLint	attribList[] =
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};

	egl.bindAPI(EGL_OPENGL_ES_API);
	m_eglContext = egl.createContext(m_eglDisplay, config, EGL_NO_CONTEXT, attribList);
	EGLU_CHECK_MSG(egl, "eglCreateContext");
	DE_ASSERT(m_eglSurface != EGL_NO_SURFACE);
	egl.makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
	EGLU_CHECK_MSG(egl, "eglMakeCurrent");
}

// return indices of frames that have been written to the given buffer
vector<int> getFramesOnBuffer (const vector<int>& bufferAges, int frameNdx)
{
	DE_ASSERT(frameNdx < (int)bufferAges.size());
	vector<int> frameOnBuffer;
	int			age = bufferAges[frameNdx];
	while (age != 0)
	{
		frameNdx = frameNdx - age;
		DE_ASSERT(frameNdx >= 0);
		frameOnBuffer.push_back(frameNdx);
		age = bufferAges[frameNdx];
	}

	reverse(frameOnBuffer.begin(), frameOnBuffer.end());
	return frameOnBuffer;
}

TestCase::IterateResult BufferAgeTest::iterate (void)
{
	de::Random		rnd					(m_seed);
	const Library&	egl					= m_eglTestCtx.getLibrary();
	tcu::TestLog&	log					= m_testCtx.getLog();
	const int		width				= eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_WIDTH);
	const int		height				= eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_HEIGHT);
	const float		clearRed			= rnd.getFloat();
	const float		clearGreen			= rnd.getFloat();
	const float		clearBlue			= rnd.getFloat();
	const tcu::Vec4	clearColor			(clearRed, clearGreen, clearBlue, 1.0f);
	const int		numFrames			= 20;
	FrameSequence	frameSequence;
	vector<int>		bufferAges;

	if (m_preserveColorBuffer)
		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
	else
		EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED));

	for (int frameNdx = 0; frameNdx < numFrames; frameNdx++)
	{
		tcu::Surface					currentBuffer			(width, height);
		tcu::Surface					refBuffer				(width, height);
		Frame							newFrame				(width, height);
		EGLint							currentBufferAge		= -1;

		if (frameNdx % 2 == 0)
			generateRandomFrame(&newFrame, m_evenFrameDrawType, rnd);
		else
			generateRandomFrame(&newFrame, m_oddFrameDrawType, rnd);

		frameSequence.push_back(newFrame);

		EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_EXT, &currentBufferAge));

		if (currentBufferAge > frameNdx || currentBufferAge < 0) // invalid buffer age
		{
			std::ostringstream stream;
			stream << "Fail, the age is invalid. Age: " << currentBufferAge << ", frameNdx: " << frameNdx;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, stream.str().c_str());
			return STOP;
		}

		if (frameNdx > 0 && m_preserveColorBuffer && currentBufferAge != 1)
		{
			std::ostringstream stream;
			stream << "Fail, EGL_BUFFER_PRESERVED is set to true, but buffer age is: " << currentBufferAge << " (should be 1)";
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, stream.str().c_str());
			return STOP;
		}

		bufferAges.push_back(currentBufferAge);
		DE_ASSERT((int)bufferAges.size() == frameNdx+1);

		// during first half, just keep rendering without reading pixel back to mimic ordinary use case
		if (frameNdx < numFrames/2)
		{
			if (currentBufferAge == 0)
				clearColorScreen(m_gl, clearColor);

			m_gles2Renderer->render(width, height, newFrame);

			if (m_resizeType == RESIZETYPE_BEFORE_SWAP)
			{
				if (frameNdx % 2 == 0)
					m_window->setSurfaceSize(IVec2(width*2, height/2));
				else
					m_window->setSurfaceSize(IVec2(height/2, width*2));
			}

			EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, m_eglSurface));

			if (m_resizeType == RESIZETYPE_AFTER_SWAP)
			{
				if (frameNdx % 2 == 0)
					m_window->setSurfaceSize(IVec2(width*2, height/2));
				else
					m_window->setSurfaceSize(IVec2(height/2, width*2));
			}

			continue;
		}

		// do verification in the second half
		if (currentBufferAge > 0) //buffer contain previous content, need to verify
		{
			const vector<int> framesOnBuffer = getFramesOnBuffer(bufferAges, frameNdx);
			readPixels(m_gl, &currentBuffer);
			clearColorReference(&refBuffer, clearColor);

			for (vector<int>::const_iterator it = framesOnBuffer.begin(); it != framesOnBuffer.end(); it++)
				m_refRenderer->render(&refBuffer, frameSequence[*it]);

			if (compareToReference(log, refBuffer, currentBuffer, frameNdx, frameNdx-currentBufferAge) == false)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, buffer content is not well preserved when age > 0");
				return STOP;
			}
		}
		else // currentBufferAge == 0, content is undefined, clear the buffer, currentBufferAge < 0 is ruled out at the beginning
		{
			clearColorScreen(m_gl, clearColor);
			clearColorReference(&refBuffer, clearColor);
		}

		m_gles2Renderer->render(width, height, newFrame);
		m_refRenderer->render(&refBuffer, newFrame);

		readPixels(m_gl, &currentBuffer);

		if (compareToReference(log, refBuffer, currentBuffer, frameNdx, frameNdx) == false)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail, render result is wrong");
			return STOP;
		}

		if (m_resizeType == RESIZETYPE_BEFORE_SWAP)
		{
			if (frameNdx % 2 == 0)
				m_window->setSurfaceSize(IVec2(width*2, height/2));
			else
				m_window->setSurfaceSize(IVec2(height/2, width*2));
		}

		EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, m_eglSurface));

		if (m_resizeType == RESIZETYPE_AFTER_SWAP)
		{
			if (frameNdx % 2 == 0)
				m_window->setSurfaceSize(IVec2(width*2, height/2));
			else
				m_window->setSurfaceSize(IVec2(height/2, width*2));
		}
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	return STOP;
}

string generateDrawTypeName (const vector<BufferAgeTest::DrawType>& drawTypes)
{
	std::ostringstream stream;
	if (drawTypes.size() == 0)
		return string("_none");

	for (size_t ndx = 0; ndx < drawTypes.size(); ndx++)
	{
		if (drawTypes[ndx] == BufferAgeTest::DRAWTYPE_GLES2_RENDER)
			stream << "_render";
		else if (drawTypes[ndx] == BufferAgeTest::DRAWTYPE_GLES2_CLEAR)
			stream << "_clear";
		else
			DE_ASSERT(false);
	}
	return stream.str();
}

string generateTestName (const vector<BufferAgeTest::DrawType>& oddFrameDrawType, const vector<BufferAgeTest::DrawType>& evenFrameDrawType)
{
	return "odd" + generateDrawTypeName(oddFrameDrawType) + "_even" + generateDrawTypeName(evenFrameDrawType);
}

string generateResizeGroupName (BufferAgeTest::ResizeType resizeType)
{
	switch (resizeType)
	{
		case BufferAgeTest::RESIZETYPE_NONE:
			return "no_resize";

		case BufferAgeTest::RESIZETYPE_AFTER_SWAP:
			return "resize_after_swap";

		case BufferAgeTest::RESIZETYPE_BEFORE_SWAP:
			return "resize_before_swap";

		default:
			DE_FATAL("Unknown resize type");
			return "";
	}
}

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

bool isES2Renderable (const eglu::CandidateConfig& c)
{
	return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT;
}

bool hasPreserveSwap (const eglu::CandidateConfig& c)
{
	return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
}

EGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, bool preserveColorBuffer)
{
	eglu::FilterList filters;
	filters << isWindow << isES2Renderable;
	if (preserveColorBuffer)
		filters << hasPreserveSwap;
	return eglu::chooseSingleConfig(egl, eglDisplay, filters);
}

void clearColorScreen (const glw::Functions& gl, const tcu::Vec4& clearColor)
{
	gl.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
	gl.clear(GL_COLOR_BUFFER_BIT);
}

void clearColorReference (tcu::Surface* ref, const tcu::Vec4& clearColor)
{
	tcu::clear(ref->getAccess(), clearColor);
}

void readPixels (const glw::Functions& gl, tcu::Surface* screen)
{
	gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(),  GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
}

float windowToDeviceCoordinates (int x, int length)
{
	return (2.0f * float(x) / float(length)) - 1.0f;
}

bool compareToReference (tcu::TestLog& log,	 const tcu::Surface& reference, const tcu::Surface& buffer, int frameNdx, int bufferNum)
{
	std::ostringstream stream;
	stream << "FrameNdx = " << frameNdx << ", compare current buffer (numbered: " << bufferNum << ") to reference";
	return tcu::intThresholdPositionDeviationCompare(log, "buffer age test", stream.str().c_str(), reference.getAccess(), buffer.getAccess(),
													 tcu::UVec4(8, 8, 8, 0), tcu::IVec3(2,2,0), true, tcu::COMPARE_LOG_RESULT);
}

} // anonymous

BufferAgeTests::BufferAgeTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "buffer_age", "Color buffer age tests")
{
}

void BufferAgeTests::init (void)
{
	const BufferAgeTest::DrawType clearRender[] =
	{
		BufferAgeTest::DRAWTYPE_GLES2_CLEAR,
		BufferAgeTest::DRAWTYPE_GLES2_RENDER
	};

	const BufferAgeTest::DrawType renderClear[] =
	{
		BufferAgeTest::DRAWTYPE_GLES2_RENDER,
		BufferAgeTest::DRAWTYPE_GLES2_CLEAR
	};

	const BufferAgeTest::ResizeType resizeTypes[] =
	{
		BufferAgeTest::RESIZETYPE_NONE,
		BufferAgeTest::RESIZETYPE_BEFORE_SWAP,
		BufferAgeTest::RESIZETYPE_AFTER_SWAP
	};

	vector< vector<BufferAgeTest::DrawType> > frameDrawTypes;
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> ());
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (1, BufferAgeTest::DRAWTYPE_GLES2_CLEAR));
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (1, BufferAgeTest::DRAWTYPE_GLES2_RENDER));
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (2, BufferAgeTest::DRAWTYPE_GLES2_CLEAR));
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (2, BufferAgeTest::DRAWTYPE_GLES2_RENDER));
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (DE_ARRAY_BEGIN(clearRender), DE_ARRAY_END(clearRender)));
	frameDrawTypes.push_back(vector<BufferAgeTest::DrawType> (DE_ARRAY_BEGIN(renderClear), DE_ARRAY_END(renderClear)));

	for (int preserveNdx = 0; preserveNdx < 2; preserveNdx++)
	{
		const bool				preserve		= (preserveNdx == 0);
		TestCaseGroup* const	preserveGroup	= new TestCaseGroup(m_eglTestCtx, (preserve ? "preserve" : "no_preserve"), "");

		for (size_t resizeTypeNdx = 0; resizeTypeNdx < DE_LENGTH_OF_ARRAY(resizeTypes); resizeTypeNdx++)
		{
			const BufferAgeTest::ResizeType	resizeType	= resizeTypes[resizeTypeNdx];
			TestCaseGroup* const			resizeGroup	= new TestCaseGroup(m_eglTestCtx, generateResizeGroupName(resizeType).c_str(), "");

			for (size_t evenNdx = 0; evenNdx < frameDrawTypes.size(); evenNdx++)
			{
				const vector<BufferAgeTest::DrawType>& evenFrameDrawType = frameDrawTypes[evenNdx];

				for (size_t oddNdx = evenNdx; oddNdx < frameDrawTypes.size(); oddNdx++)
				{
					const vector<BufferAgeTest::DrawType>&	oddFrameDrawType	= frameDrawTypes[oddNdx];
					const std::string						name				= generateTestName(oddFrameDrawType, evenFrameDrawType);
					resizeGroup->addChild(new BufferAgeTest(m_eglTestCtx, preserve, oddFrameDrawType, evenFrameDrawType, BufferAgeTest::RESIZETYPE_NONE, name.c_str(), ""));
				}
			}

			preserveGroup->addChild(resizeGroup);
		}
		addChild(preserveGroup);
	}
}

} // egl
} // deqp
