/*-------------------------------------------------------------------------
 * 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::getDisplayExtensions(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
