/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL Module
 * ---------------------------------------
 *
 * Copyright 2014 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 GLES2 resource sharing performnace tests.
 *//*--------------------------------------------------------------------*/

#include "teglGLES2SharedRenderingPerfTests.hpp"

#include "tcuTestLog.hpp"

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

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

#include "deThread.hpp"
#include "deClock.h"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"

#include <vector>
#include <string>
#include <algorithm>
#include <cmath>

namespace deqp
{
namespace egl
{

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

using namespace glw;
using namespace eglw;

namespace
{

struct TestConfig
{
	enum TextureType
	{
		TEXTURETYPE_TEXTURE = 0,
		TEXTURETYPE_SHARED_TEXTURE,
		TEXTURETYPE_IMAGE,
		TEXTURETYPE_SHARED_IMAGE,
		TEXTURETYPE_SHARED_IMAGE_TEXTURE
	};

	int			threadCount;
	int			perThreadContextCount;

	int			frameCount;
	int			drawCallCount;
	int			triangleCount;

	bool		sharedContexts;

	bool		useCoordBuffer;
	bool		sharedCoordBuffer;

	bool		useIndices;
	bool		useIndexBuffer;
	bool		sharedIndexBuffer;

	bool		useTexture;
	TextureType	textureType;

	bool		sharedProgram;

	int			textureWidth;
	int			textureHeight;

	int			surfaceWidth;
	int			surfaceHeight;
};

class TestContext
{
public:
						TestContext		(EglTestContext& eglTestCtx, EGLDisplay display, EGLConfig eglConfig, const TestConfig& config, bool share, TestContext* parent);
						~TestContext	(void);

	void				render			(void);

	EGLContext			getEGLContext	(void) { return m_eglContext; }

	GLuint				getCoordBuffer	(void) const { return m_coordBuffer;	}
	GLuint				getIndexBuffer	(void) const { return m_indexBuffer;	}
	GLuint				getTexture		(void) const { return m_texture;		}
	GLuint				getProgram		(void) const { return m_program;		}
	EGLImageKHR			getEGLImage		(void) const { return m_eglImage;		}

private:
	TestContext*		m_parent;
	EglTestContext&		m_testCtx;
	TestConfig			m_config;

	EGLDisplay			m_eglDisplay;
	EGLContext			m_eglContext;
	EGLSurface			m_eglSurface;

	glw::Functions		m_gl;

	GLuint				m_coordBuffer;
	GLuint				m_indexBuffer;
	GLuint				m_texture;
	GLuint				m_program;

	EGLImageKHR			m_eglImage;

	GLuint				m_coordLoc;
	GLuint				m_textureLoc;

	vector<float>		m_coordData;
	vector<deUint16>	m_indexData;

	EGLImageKHR			createEGLImage			(void);
	GLuint				createTextureFromImage	(EGLImageKHR image);

	// Not supported
	TestContext&		operator=				(const TestContext&);
						TestContext				(const TestContext&);
};

namespace
{

void createCoordData (vector<float>& data, const TestConfig& config)
{
	if (config.useIndices)
	{
		for (int triangleNdx = 0; triangleNdx < 2; triangleNdx++)
		{
			const float x1 = -1.0f;
			const float y1 = -1.0f;

			const float x2 = 1.0f;
			const float y2 = 1.0f;

			const float side = ((triangleNdx % 2) == 0 ? 1.0f : -1.0f);

			data.push_back(side * x1);
			data.push_back(side * y1);

			data.push_back(side * x2);
			data.push_back(side * y1);

			data.push_back(side * x2);
			data.push_back(side * y2);
		}
	}
	else
	{
		data.reserve(config.triangleCount * 3 * 2);

		for (int triangleNdx = 0; triangleNdx < config.triangleCount; triangleNdx++)
		{
			const float x1 = -1.0f;
			const float y1 = -1.0f;

			const float x2 = 1.0f;
			const float y2 = 1.0f;

			const float side = ((triangleNdx % 2) == 0 ? 1.0f : -1.0f);

			data.push_back(side * x1);
			data.push_back(side * y1);

			data.push_back(side * x2);
			data.push_back(side * y1);

			data.push_back(side * x2);
			data.push_back(side * y2);
		}
	}
}

GLuint createCoordBuffer (const glw::Functions& gl, const TestConfig& config)
{
	GLuint			buffer;
	vector<float>	data;

	createCoordData(data, config);

	gl.genBuffers(1, &buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers()");
	gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
	gl.bufferData(GL_ARRAY_BUFFER, (GLsizei)(data.size() * sizeof(float)), &(data[0]), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData()");
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");

	return buffer;
}

void createIndexData (vector<deUint16>& data, const TestConfig& config)
{
	for (int triangleNdx = 0; triangleNdx < config.triangleCount; triangleNdx++)
	{
		if ((triangleNdx % 2) == 0)
		{
			data.push_back(0);
			data.push_back(1);
			data.push_back(2);
		}
		else
		{
			data.push_back(2);
			data.push_back(3);
			data.push_back(0);
		}
	}
}

GLuint createIndexBuffer (const glw::Functions& gl, const TestConfig& config)
{
	GLuint				buffer;
	vector<deUint16>	data;

	createIndexData(data, config);

	gl.genBuffers(1, &buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers()");
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizei)(data.size() * sizeof(deUint16)), &(data[0]), GL_STATIC_DRAW);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData()");
	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");

	return buffer;
}

void createTextureData (vector<deUint8>& data, const TestConfig& config)
{
	for (int x = 0; x < config.textureWidth; x++)
	{
		for (int y = 0; y < config.textureHeight; y++)
		{
			data.push_back((deUint8)((255*x)/255));
			data.push_back((deUint8)((255*y)/255));
			data.push_back((deUint8)((255*x*y)/(255*255)));
			data.push_back(255);
		}
	}
}

GLuint createTexture (const glw::Functions& gl, const TestConfig& config)
{
	GLuint			texture;
	vector<deUint8>	data;

	createTextureData(data, config);

	gl.genTextures(1, &texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures()");
	gl.bindTexture(GL_TEXTURE_2D, texture);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, config.textureWidth, config.textureWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(data[0]));
	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D()");
	gl.bindTexture(GL_TEXTURE_2D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");

	return texture;
}

GLuint createProgram (const glw::Functions& gl, const TestConfig& config)
{
	GLuint	vertexShader	= gl.createShader(GL_VERTEX_SHADER);
	GLuint	fragmentShader	= gl.createShader(GL_FRAGMENT_SHADER);

	if (config.useTexture)
	{
		const char* vertexShaderSource =
		"attribute mediump vec2 a_coord;\n"
		"varying mediump vec2 v_texCoord;\n"
		"void main(void)\n"
		"{\n"
		"\tv_texCoord = 0.5 * a_coord + vec2(0.5);\n"
		"\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
		"}\n";

		const char* fragmentShaderSource =
		"uniform sampler2D u_sampler;\n"
		"varying mediump vec2 v_texCoord;\n"
		"void main(void)\n"
		"{\n"
		"\tgl_FragColor = texture2D(u_sampler, v_texCoord);\n"
		"}\n";

		gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()");
		gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()");
	}
	else
	{
		const char* vertexShaderSource =
		"attribute mediump vec2 a_coord;\n"
		"varying mediump vec4 v_color;\n"
		"void main(void)\n"
		"{\n"
		"\tv_color = vec4(0.5 * a_coord + vec2(0.5), 0.5, 1.0);\n"
		"\tgl_Position = vec4(a_coord, 0.0, 1.0);\n"
		"}\n";

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

		gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()");
		gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource()");
	}

	gl.compileShader(vertexShader);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader()");
	gl.compileShader(fragmentShader);
	GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader()");

	{
		GLint status;

		gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");

		if (!status)
		{
			string	log;
			GLint length;

			gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &length);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");
			log.resize(length, 0);

			gl.getShaderInfoLog(vertexShader, (GLsizei)log.size(), &length, &(log[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog()");

			throw std::runtime_error(log.c_str());
		}
	}

	{
		GLint status;

		gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");

		if (!status)
		{
			string	log;
			GLint length;

			gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &length);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv()");
			log.resize(length, 0);

			gl.getShaderInfoLog(fragmentShader, (GLsizei)log.size(), &length, &(log[0]));
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog()");

			throw std::runtime_error(log.c_str());
		}
	}

	{
		GLuint program = gl.createProgram();

		gl.attachShader(program, vertexShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader()");
		gl.attachShader(program, fragmentShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader()");

		gl.linkProgram(program);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()");

		{
			GLint status;

			gl.getProgramiv(program, GL_LINK_STATUS, &status);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv()");

			if (!status)
			{
				string	log;
				GLsizei	length;

				gl.getProgramInfoLog(program, 0, &length, DE_NULL);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog()");
				log.resize(length, 0);

				gl.getProgramInfoLog(program, (GLsizei)log.size(), &length, &(log[0]));
				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog()");

				throw std::runtime_error(log.c_str());
			}
		}

		gl.deleteShader(vertexShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader()");
		gl.deleteShader(fragmentShader);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteShader()");

		return program;
	}
}

EGLContext createEGLContext (EglTestContext& testCtx, EGLDisplay eglDisplay, EGLConfig eglConfig, EGLContext share)
{
	const Library&	egl				= testCtx.getLibrary();
	const EGLint	attribList[]	=
	{
		EGL_CONTEXT_CLIENT_VERSION, 2,
		EGL_NONE
	};

	EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));

	EGLContext context = egl.createContext(eglDisplay, eglConfig, share, attribList);
	EGLU_CHECK_MSG(egl, "eglCreateContext()");

	return context;
}

EGLSurface createEGLSurface (EglTestContext& testCtx, EGLDisplay display, EGLConfig eglConfig, const TestConfig& config)
{
	const Library&	egl				= testCtx.getLibrary();
	const EGLint	attribList[]	=
	{
		EGL_WIDTH,	config.surfaceWidth,
		EGL_HEIGHT, config.surfaceHeight,
		EGL_NONE
	};

	EGLSurface surface = egl.createPbufferSurface(display, eglConfig, attribList);
	EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");

	return surface;
}

} // anonymous

TestContext::TestContext (EglTestContext& testCtx, EGLDisplay eglDisplay, EGLConfig eglConfig, const TestConfig& config, bool share, TestContext* parent)
	: m_parent				(parent)
	, m_testCtx				(testCtx)
	, m_config				(config)
	, m_eglDisplay			(eglDisplay)
	, m_eglContext			(EGL_NO_CONTEXT)
	, m_eglSurface			(EGL_NO_SURFACE)
	, m_coordBuffer			(0)
	, m_indexBuffer			(0)
	, m_texture				(0)
	, m_program				(0)
	, m_eglImage			(EGL_NO_IMAGE_KHR)
{
	const Library&	egl	= m_testCtx.getLibrary();

	if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE
		|| m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE
		|| m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE)
	{
		const vector<string> extensions = eglu::getClientExtensions(egl, m_eglDisplay);

		if (!de::contains(extensions.begin(), extensions.end(), "EGL_KHR_image_base") ||
			!de::contains(extensions.begin(), extensions.end(), "EGL_KHR_gl_texture_2D_image"))
			TCU_THROW(NotSupportedError, "EGL_KHR_image_base extensions not supported");
	}

	m_eglContext = createEGLContext(m_testCtx, m_eglDisplay, eglConfig, (share && parent ? parent->getEGLContext() : EGL_NO_CONTEXT));
	m_eglSurface = createEGLSurface(m_testCtx, m_eglDisplay, eglConfig, config);

	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));

	{
		const char* reqExts[] = { "GL_OES_EGL_image" };
		m_testCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0), DE_LENGTH_OF_ARRAY(reqExts), reqExts);
	}

	if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE
		|| m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE
		|| m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE)
	{
		vector<string> glExts = de::splitString((const char*)m_gl.getString(GL_EXTENSIONS), ' ');

		if (!de::contains(glExts.begin(), glExts.end(), "GL_OES_EGL_image"))
			TCU_THROW(NotSupportedError, "GL_OES_EGL_image extensions not supported");

		TCU_CHECK(m_gl.eglImageTargetTexture2DOES);
	}

	if (m_config.useCoordBuffer && (!m_config.sharedCoordBuffer || !parent))
		m_coordBuffer = createCoordBuffer(m_gl, m_config);
	else if (m_config.useCoordBuffer && m_config.sharedCoordBuffer)
		m_coordBuffer = parent->getCoordBuffer();
	else
		createCoordData(m_coordData, m_config);

	if (m_config.useIndexBuffer && (!m_config.sharedIndexBuffer || !parent))
		m_indexBuffer = createIndexBuffer(m_gl, m_config);
	else if (m_config.useIndexBuffer && m_config.sharedIndexBuffer)
		m_indexBuffer = parent->getIndexBuffer();
	else if (m_config.useIndices)
		createIndexData(m_indexData, m_config);

	if (m_config.useTexture)
	{
		if (m_config.textureType == TestConfig::TEXTURETYPE_TEXTURE)
			m_texture = createTexture(m_gl, m_config);
		else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_TEXTURE)
		{
			if (parent)
				m_texture = parent->getTexture();
			else
				m_texture = createTexture(m_gl, m_config);
		}
		else if (m_config.textureType == TestConfig::TEXTURETYPE_IMAGE)
		{
			m_eglImage	= createEGLImage();
			m_texture	= createTextureFromImage(m_eglImage);
		}
		else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE)
		{
			if (parent)
				m_eglImage = parent->getEGLImage();
			else
				m_eglImage = createEGLImage();

			m_texture = createTextureFromImage(m_eglImage);
		}
		else if (m_config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE)
		{
			if (parent)
				m_texture = parent->getTexture();
			else
			{
				m_eglImage	= createEGLImage();
				m_texture	= createTextureFromImage(m_eglImage);
			}
		}
	}

	if (!m_config.sharedProgram || !parent)
		m_program = createProgram(m_gl, m_config);
	else if (m_config.sharedProgram)
		m_program = parent->getProgram();

	m_coordLoc = m_gl.getAttribLocation(m_program, "a_coord");

	if (m_config.useTexture)
		m_textureLoc = m_gl.getUniformLocation(m_program, "u_sampler");

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

EGLImageKHR TestContext::createEGLImage (void)
{
	GLuint sourceTexture = createTexture(m_gl, m_config);

	try
	{
		const Library&	egl				= m_testCtx.getLibrary();
		const EGLint	attribList[]	=
		{
			EGL_GL_TEXTURE_LEVEL_KHR, 0,
			EGL_NONE
		};

		EGLImageKHR image = egl.createImageKHR(m_eglDisplay, m_eglContext, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)sourceTexture, attribList);
		EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");

		m_gl.deleteTextures(1, &sourceTexture);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "eglCreateImageKHR()");

		return image;
	}
	catch (...)
	{
		m_gl.deleteTextures(1, &sourceTexture);
		throw;
	}
}

GLuint TestContext::createTextureFromImage (EGLImageKHR image)
{
	GLuint texture = 0;

	try
	{
		m_gl.genTextures(1, &texture);
		m_gl.bindTexture(GL_TEXTURE_2D, texture);
		m_gl.eglImageTargetTexture2DOES(GL_TEXTURE_2D, image);
		m_gl.bindTexture(GL_TEXTURE_2D, 0);
		GLU_EXPECT_NO_ERROR(m_gl.getError(), "Creating texture from image");

		return texture;
	}
	catch (...)
	{
		m_gl.deleteTextures(1, &texture);
		throw;
	}
}


TestContext::~TestContext (void)
{
	const Library&	egl	= m_testCtx.getLibrary();

	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));

	if (m_parent == DE_NULL && m_eglImage)
		EGLU_CHECK_CALL(egl, destroyImageKHR(m_eglDisplay, m_eglImage));

	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
	EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));
	EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
}

void TestContext::render (void)
{
	const Library&	egl	= m_testCtx.getLibrary();

	egl.makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);

	for (int frameNdx = 0; frameNdx < m_config.frameCount; frameNdx++)
	{
		m_gl.clearColor(0.75f, 0.6f, 0.5f, 1.0f);
		m_gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

		for (int callNdx = 0; callNdx < m_config.drawCallCount; callNdx++)
		{
			m_gl.useProgram(m_program);
			m_gl.enableVertexAttribArray(m_coordLoc);

			if (m_config.useCoordBuffer)
			{
				m_gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffer);
				m_gl.vertexAttribPointer(m_coordLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
				m_gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			}
			else
				m_gl.vertexAttribPointer(m_coordLoc, 2, GL_FLOAT, GL_FALSE, 0, &(m_coordData[0]));

			if (m_config.useTexture)
			{
				m_gl.bindTexture(GL_TEXTURE_2D, m_texture);
				m_gl.uniform1i(m_textureLoc, 0);
			}

			if (m_config.useIndices)
			{
				if (m_config.useIndexBuffer)
				{
					m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
					m_gl.drawElements(GL_TRIANGLES, m_config.triangleCount, GL_UNSIGNED_SHORT, 0);
				}
				else
					m_gl.drawElements(GL_TRIANGLES, m_config.triangleCount, GL_UNSIGNED_SHORT, &(m_indexData[0]));
			}
			else
				m_gl.drawArrays(GL_TRIANGLES, 0, m_config.triangleCount);


			if (m_config.useTexture)
				m_gl.bindTexture(GL_TEXTURE_2D, 0);

			m_gl.disableVertexAttribArray(m_coordLoc);

			m_gl.useProgram(0);
		}


		egl.swapBuffers(m_eglDisplay, m_eglSurface);
	}

	m_gl.finish();
	GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFinish()");
	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
}

class TestThread : de::Thread
{
public:
					TestThread		(const vector<TestContext*> contexts);
					~TestThread		(void);

	void			start			(void);
	void			join			(void);
	void			log				(TestLog& log);

	bool			resultOk		(void) { return m_isOk; }

private:
	vector<TestContext*>	m_contexts;
	bool					m_isOk;
	string					m_errorString;

	deUint64				m_beginTimeUs;
	deUint64				m_endTimeUs;

	deUint64				m_joinBeginUs;
	deUint64				m_joinEndUs;

	deUint64				m_startBeginUs;
	deUint64				m_startEndUs;


	virtual void	run			(void);

	TestThread&		operator=	(const TestThread&);
					TestThread	(const TestThread&);
};

TestThread::TestThread (const vector<TestContext*> contexts)
	: m_contexts		(contexts)
	, m_isOk			(false)
	, m_errorString		("")
	, m_beginTimeUs		(0)
	, m_endTimeUs		(0)
	, m_joinBeginUs		(0)
	, m_joinEndUs		(0)
	, m_startBeginUs	(0)
	, m_startEndUs		(0)
{
}

TestThread::~TestThread (void)
{
	m_contexts.clear();
}

void TestThread::log (TestLog& testLog)
{
	if (!m_isOk)
		testLog << TestLog::Message << "Thread failed: " << m_errorString << TestLog::EndMessage;
}

void TestThread::start (void)
{
	m_startBeginUs = deGetMicroseconds();
	de::Thread::start();
	m_startEndUs = deGetMicroseconds();
}

void TestThread::join (void)
{
	m_joinBeginUs = deGetMicroseconds();
	de::Thread::join();
	m_joinEndUs = deGetMicroseconds();
}

void TestThread::run (void)
{
	try
	{
		m_beginTimeUs = deGetMicroseconds();

		for (int contextNdx = 0; contextNdx < (int)m_contexts.size(); contextNdx++)
			m_contexts[contextNdx]->render();

		m_isOk		= true;
		m_endTimeUs = deGetMicroseconds();
	}
	catch (const std::runtime_error& error)
	{
		m_isOk			= false;
		m_errorString	= error.what();
	}
	catch (...)
	{
		m_isOk			= false;
		m_errorString	= "Got unknown exception";
	}
}

class SharedRenderingPerfCase : public TestCase
{
public:
								SharedRenderingPerfCase		(EglTestContext& eglTestCtx, const TestConfig& config, const char* name, const char* description);
								~SharedRenderingPerfCase	(void);

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

private:
	TestConfig					m_config;
	const int					m_iterationCount;

	EGLDisplay					m_display;
	vector<TestContext*>		m_contexts;
	vector<deUint64>			m_results;

	SharedRenderingPerfCase&	operator=					(const SharedRenderingPerfCase&);
								SharedRenderingPerfCase		(const SharedRenderingPerfCase&);
};

SharedRenderingPerfCase::SharedRenderingPerfCase (EglTestContext& eglTestCtx, const TestConfig& config, const char* name, const char* description)
	: TestCase			(eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_config			(config)
	, m_iterationCount	(30)
	, m_display			(EGL_NO_DISPLAY)
{
}

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

void SharedRenderingPerfCase::init (void)
{
	m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());

	{
		const Library&	egl				= m_eglTestCtx.getLibrary();
		const EGLint	attribList[]	=
		{
			EGL_SURFACE_TYPE,		EGL_PBUFFER_BIT,
			EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
			EGL_NONE
		};
		EGLConfig		eglConfig		= eglu::chooseSingleConfig(egl, m_display, attribList);

		// Create contexts and resources
		for (int threadNdx = 0; threadNdx < m_config.threadCount * m_config.perThreadContextCount; threadNdx++)
			m_contexts.push_back(new TestContext(m_eglTestCtx, m_display, eglConfig, m_config, m_config.sharedContexts, (threadNdx == 0 ? DE_NULL : m_contexts[threadNdx-1])));
	}
}

void SharedRenderingPerfCase::deinit (void)
{
	// Destroy resources and contexts
	for (int threadNdx = 0; threadNdx < (int)m_contexts.size(); threadNdx++)
	{
		delete m_contexts[threadNdx];
		m_contexts[threadNdx] = DE_NULL;
	}

	m_contexts.clear();
	m_results.clear();

	if (m_display != EGL_NO_DISPLAY)
	{
		m_eglTestCtx.getLibrary().terminate(m_display);
		m_display = EGL_NO_DISPLAY;
	}
}

namespace
{

void createThreads (vector<TestThread*>& threads, int threadCount, int perThreadContextCount, vector<TestContext*>& contexts)
{
	DE_ASSERT(threadCount * perThreadContextCount == (int)contexts.size());
	DE_ASSERT(threads.empty());

	vector<TestContext*> threadContexts;

	for (int threadNdx = 0; threadNdx < threadCount; threadNdx++)
	{
		for (int contextNdx = 0; contextNdx < perThreadContextCount; contextNdx++)
			threadContexts.push_back(contexts[threadNdx * perThreadContextCount + contextNdx]);

		threads.push_back(new TestThread(threadContexts));

		threadContexts.clear();
	}
}

void destroyThreads (vector<TestThread*>& threads)
{
	for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++)
	{
		delete threads[threadNdx];
		threads[threadNdx] = DE_NULL;
	}

	threads.clear();
}

void startThreads (vector<TestThread*>& threads)
{
	for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++)
		threads[threadNdx]->start();
}

void joinThreads (vector<TestThread*>& threads)
{
	for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++)
		threads[threadNdx]->join();
}

bool threadResultsOk (const vector<TestThread*>& threads)
{
	for (int threadNdx = 0; threadNdx < (int)threads.size(); threadNdx++)
	{
		if (!threads[threadNdx]->resultOk())
			return false;
	}

	return true;
}

void logAndSetResults (tcu::TestContext& testCtx, const vector<deUint64>& r)
{
	TestLog& log		= testCtx.getLog();
	vector<deUint64>	resultsUs = r;
	deUint64			sum = 0;
	deUint64			average;
	deUint64			median;
	double				deviation;

	log << TestLog::SampleList("Result", "Result")
		<< TestLog::SampleInfo << TestLog::ValueInfo("Time", "Time", "us", QP_SAMPLE_VALUE_TAG_RESPONSE)
		<< TestLog::EndSampleInfo;

	for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++)
		log << TestLog::Sample << deInt64(resultsUs[resultNdx]) << TestLog::EndSample;

	log << TestLog::EndSampleList;

	std::sort(resultsUs.begin(), resultsUs.end());

	for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++)
		sum += resultsUs[resultNdx];

	average	= sum / resultsUs.size();
	median	= resultsUs[resultsUs.size() / 2];

	deviation = 0.0;
	for (int resultNdx = 0; resultNdx < (int)resultsUs.size(); resultNdx++)
		deviation += (double)((resultsUs[resultNdx] - average) * (resultsUs[resultNdx] - average));

	deviation = std::sqrt(deviation/(double)resultsUs.size());

	{
		tcu::ScopedLogSection	section(log, "Statistics from results", "Statistics from results");

		log << TestLog::Message
		<< "Average: "					<< ((double)average/1000.0)											<< "ms\n"
		<< "Standard deviation: "		<< ((double)deviation/1000.0)										<< "ms\n"
		<< "Standard error of mean: "	<< (((double)deviation/std::sqrt((double)resultsUs.size()))/1000.0)	<< "ms\n"
		<< "Median: "					<< ((double)median/1000.0)											<< "ms\n"
		<< TestLog::EndMessage;
	}

	testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)((double)average/1000.0), 2).c_str());
}

void logTestConfig (TestLog& log, const TestConfig& config)
{
	tcu::ScopedLogSection threadSection(log, "Test info", "Test information");

	log << TestLog::Message << "Total triangles rendered: : "							<< config.triangleCount * config.drawCallCount * config.frameCount * config.perThreadContextCount * config.threadCount << TestLog::EndMessage;
	log << TestLog::Message << "Number of threads: "									<< config.threadCount << TestLog::EndMessage;
	log << TestLog::Message << "Number of contexts used to render with each thread: "	<< config.perThreadContextCount << TestLog::EndMessage;
	log << TestLog::Message << "Number of frames rendered with each context: "			<< config.frameCount << TestLog::EndMessage;
	log << TestLog::Message << "Number of draw calls performed by each frame: "			<< config.drawCallCount << TestLog::EndMessage;
	log << TestLog::Message << "Number of triangles rendered by each draw call: "		<< config.triangleCount << TestLog::EndMessage;

	if (config.sharedContexts)
		log << TestLog::Message << "Shared contexts." << TestLog::EndMessage;
	else
		log << TestLog::Message << "No shared contexts." << TestLog::EndMessage;

	if (config.useCoordBuffer)
		log << TestLog::Message << (config.sharedCoordBuffer ? "Shared " : "") << "Coordinate buffer" << TestLog::EndMessage;
	else
		log << TestLog::Message << "Coordinates from pointer" << TestLog::EndMessage;

	if (config.useIndices)
		log << TestLog::Message << "Using glDrawElements with indices from " << (config.sharedIndexBuffer ? "shared " : "") << (config.useIndexBuffer ? "buffer." : "pointer.") << TestLog::EndMessage;

	if (config.useTexture)
	{
		if (config.textureType == TestConfig::TEXTURETYPE_TEXTURE)
			log << TestLog::Message << "Use texture." << TestLog::EndMessage;
		else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_TEXTURE)
			log << TestLog::Message << "Use shared texture." << TestLog::EndMessage;
		else if (config.textureType == TestConfig::TEXTURETYPE_IMAGE)
			log << TestLog::Message << "Use texture created from EGLImage." << TestLog::EndMessage;
		else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE)
			log << TestLog::Message << "Use texture created from shared EGLImage." << TestLog::EndMessage;
		else if (config.textureType == TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE)
			log << TestLog::Message << "Use shared texture created from EGLImage." << TestLog::EndMessage;
		else
			DE_ASSERT(false);

		log << TestLog::Message << "Texture size: " << config.textureWidth << "x" << config.textureHeight << TestLog::EndMessage;
	}

	if (config.sharedProgram)
		log << TestLog::Message << "Shared program." << TestLog::EndMessage;

	log << TestLog::Message << "Surface size: " << config.surfaceWidth << "x" << config.surfaceHeight << TestLog::EndMessage;
}

} // anonymous

TestCase::IterateResult SharedRenderingPerfCase::iterate (void)
{
	deUint64			beginTimeUs;
	deUint64			endTimeUs;
	vector<TestThread*>	threads;

	if (m_results.empty())
		logTestConfig(m_testCtx.getLog(), m_config);

	createThreads(threads, m_config.threadCount, m_config.perThreadContextCount, m_contexts);

	beginTimeUs = deGetMicroseconds();

	startThreads(threads);
	joinThreads(threads);

	endTimeUs = deGetMicroseconds();

	if (!threadResultsOk(threads))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
		return STOP;
	}

	destroyThreads(threads);

	m_results.push_back(endTimeUs - beginTimeUs);

	if ((int)m_results.size() == m_iterationCount)
	{
		logAndSetResults(m_testCtx, m_results);
		return STOP;
	}
	else
		return CONTINUE;
}

string createTestName(int threads, int perThreadContextCount)
{
	std::ostringstream stream;

	stream << threads << (threads == 1 ? "_thread_" : "_threads_") << perThreadContextCount << (perThreadContextCount == 1 ? "_context" : "_contexts");

	return stream.str();
}

} // anonymous

GLES2SharedRenderingPerfTests::GLES2SharedRenderingPerfTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "gles2_shared_render", "")
{
}

void GLES2SharedRenderingPerfTests::init (void)
{
	TestConfig basicConfig;

	basicConfig.threadCount					= 1;
	basicConfig.perThreadContextCount		= 1;

	basicConfig.sharedContexts				= true;
	basicConfig.frameCount					= 10;
	basicConfig.drawCallCount				= 10;
	basicConfig.triangleCount				= 100;

	basicConfig.useCoordBuffer				= true;
	basicConfig.sharedCoordBuffer			= false;

	basicConfig.useIndices					= true;
	basicConfig.useIndexBuffer				= true;
	basicConfig.sharedIndexBuffer			= false;

	basicConfig.useTexture					= true;
	basicConfig.textureType					= TestConfig::TEXTURETYPE_TEXTURE;

	basicConfig.sharedProgram				= false;

	basicConfig.textureWidth				= 128;
	basicConfig.textureHeight				= 128;

	basicConfig.surfaceWidth				= 256;
	basicConfig.surfaceHeight				= 256;

	const int	threadCounts[]				= { 1, 2, 4 };
	const int	perThreadContextCounts[]	= { 1, 2, 4 };

	// Add no sharing tests
	{
		TestCaseGroup* sharedNoneGroup = new TestCaseGroup(m_eglTestCtx, "no_shared_context", "Tests without sharing contexts.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config 				= basicConfig;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;
				config.sharedContexts			= false;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedNoneGroup);
	}

	// Add no resource sharing tests
	{
		TestCaseGroup* sharedNoneGroup = new TestCaseGroup(m_eglTestCtx, "no_shared_resource", "Tests without shared resources.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedNoneGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedNoneGroup);
	}

	// Add shared coord buffer tests
	{
		TestCaseGroup* sharedCoordBufferGroup = new TestCaseGroup(m_eglTestCtx, "shared_coord_buffer", "Shared coordinate bufffer");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.sharedCoordBuffer		= true;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedCoordBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedCoordBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedCoordBufferGroup);
	}

	// Add shared index buffer tests
	{
		TestCaseGroup* sharedIndexBufferGroup = new TestCaseGroup(m_eglTestCtx, "shared_index_buffer", "Shared index bufffer");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.sharedIndexBuffer		= true;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedIndexBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedIndexBufferGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedIndexBufferGroup);
	}

	// Add shared texture tests
	{
		TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_texture", "Shared texture tests.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.textureType				= TestConfig::TEXTURETYPE_SHARED_TEXTURE;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedTextureGroup);
	}

	// Add shared program tests
	{
		TestCaseGroup* sharedProgramGroup = new TestCaseGroup(m_eglTestCtx, "shared_program", "Shared program tests.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.sharedProgram			= true;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedProgramGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedProgramGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedProgramGroup);
	}

	// Add shared all tests
	{
		TestCaseGroup* sharedallGroup = new TestCaseGroup(m_eglTestCtx, "shared_all", "Share all possible resources.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.sharedCoordBuffer		= true;
				config.sharedIndexBuffer		= true;
				config.sharedProgram			= true;
				config.textureType				= TestConfig::TEXTURETYPE_SHARED_TEXTURE;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedallGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedallGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedallGroup);
	}

	// Add EGLImage tests
	{
		TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "egl_image", "EGL image tests.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config = basicConfig;

				config.textureType				= TestConfig::TEXTURETYPE_IMAGE;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;
				config.sharedContexts			= false;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedTextureGroup);
	}

	// Add shared EGLImage tests
	{
		TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_egl_image", "Shared EGLImage tests.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;

				config.textureType				= TestConfig::TEXTURETYPE_SHARED_IMAGE;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;
				config.sharedContexts			= false;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedTextureGroup);
	}

	// Shared EGLImage texture test
	{
		TestCaseGroup* sharedTextureGroup = new TestCaseGroup(m_eglTestCtx, "shared_egl_image_texture", "Shared EGLImage texture tests.");

		for (int threadCountNdx = 0; threadCountNdx < DE_LENGTH_OF_ARRAY(threadCounts); threadCountNdx++)
		{
			int threadCount = threadCounts[threadCountNdx];

			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(perThreadContextCounts); contextCountNdx++)
			{
				int contextCount = perThreadContextCounts[contextCountNdx];

				if (threadCount * contextCount != 4 && threadCount * contextCount != 1)
					continue;

				TestConfig config				= basicConfig;
				config.textureType				= TestConfig::TEXTURETYPE_SHARED_IMAGE_TEXTURE;
				config.threadCount				= threadCount;
				config.perThreadContextCount	= contextCount;

				{
					TestConfig smallConfig		= config;
					smallConfig.triangleCount	= 1;
					smallConfig.drawCallCount	= 1000;
					smallConfig.frameCount		= 10;

					if (threadCount * contextCount == 1)
						smallConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, smallConfig, (createTestName(threadCount, contextCount) + "_small_call").c_str(), ""));
				}

				{
					TestConfig bigConfig	= config;
					bigConfig.triangleCount	= 1000;
					bigConfig.drawCallCount	= 1;
					bigConfig.frameCount	= 10;

					if (threadCount * contextCount == 1)
						bigConfig.frameCount *= 4;

					sharedTextureGroup->addChild(new SharedRenderingPerfCase(m_eglTestCtx, bigConfig, (createTestName(threadCount, contextCount) + "_big_call").c_str(), ""));
				}
			}
		}

		addChild(sharedTextureGroup);
	}

}

} // egl
} // deqp
