/*-------------------------------------------------------------------------
 * 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 Multi threaded EGL tests
 *//*--------------------------------------------------------------------*/
#include "teglMultiThreadTests.hpp"

#include "egluNativeWindow.hpp"
#include "egluNativePixmap.hpp"
#include "egluUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuCommandLine.hpp"

#include "deRandom.hpp"

#include "deThread.hpp"
#include "deMutex.hpp"
#include "deSemaphore.hpp"

#include "deAtomic.h"
#include "deClock.h"

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

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

using std::vector;
using std::string;
using std::pair;
using std::set;
using std::ostringstream;

using namespace eglw;

namespace deqp
{
namespace egl
{

class ThreadLog
{
public:
	class BeginMessageToken	{};
	class EndMessageToken	{};

	struct Message
	{
					Message	(deUint64 timeUs_, const char* msg_) : timeUs(timeUs_), msg(msg_) {}

		deUint64	timeUs;
		string		msg;
	};

								ThreadLog	(void)						{ m_messages.reserve(100); }

	ThreadLog&					operator<<	(const BeginMessageToken&)	{ return *this; }
	ThreadLog&					operator<<	(const EndMessageToken&);

	template<class T>
	ThreadLog&					operator<< 	(const T& t)				{ m_message << t; return *this; }
	const vector<Message>&		getMessages (void) const				{ return m_messages; }

	static BeginMessageToken	BeginMessage;
	static EndMessageToken		EndMessage;

private:
	ostringstream		m_message;
	vector<Message>		m_messages;
};

ThreadLog& ThreadLog::operator<< (const EndMessageToken&)
{
	m_messages.push_back(Message(deGetMicroseconds(), m_message.str().c_str()));
	m_message.str("");
	return *this;
}

ThreadLog::BeginMessageToken	ThreadLog::BeginMessage;
ThreadLog::EndMessageToken		ThreadLog::EndMessage;

class MultiThreadedTest;

class TestThread : public de::Thread
{
public:
	enum ThreadStatus
	{
		THREADSTATUS_NOT_STARTED = 0,
		THREADSTATUS_RUNNING,
		THREADSTATUS_READY,

		THREADSTATUS_NOT_SUPPORTED,
		THREADSTATUS_ERROR
	};

					TestThread	(MultiThreadedTest& test, int id);
	void			run			(void);

	ThreadStatus	getStatus	(void) const	{ return m_status; }
	ThreadLog&		getLog		(void)			{ return m_log; }

	int				getId		(void) const	{ return m_id; }

	void			setStatus	(ThreadStatus status)	{ m_status = status; }

	const Library&	getLibrary	(void) const;

	// Test has stopped
	class TestStop {};


private:
	MultiThreadedTest&	m_test;
	const int			m_id;
	ThreadStatus		m_status;
	ThreadLog			m_log;
};

class MultiThreadedTest : public TestCase
{
public:
							MultiThreadedTest	(EglTestContext& eglTestCtx, const char* name, const char* description, int threadCount, deUint64 timeoutUs);
	virtual					~MultiThreadedTest	(void);

	void					init				(void);
	void					deinit				(void);

	virtual bool			runThread			(TestThread& thread) = 0;
	virtual IterateResult	iterate				(void);
	bool					execTest			(TestThread& thread);

	const Library&			getLibrary			(void) const { return m_eglTestCtx.getLibrary(); }

protected:
	void					barrier				(TestThread& thread);

private:
	int						m_threadCount;
	bool					m_initialized;
	deUint64				m_startTimeUs;
	const deUint64			m_timeoutUs;
	vector<TestThread*>		m_threads;

	volatile deInt32		m_barrierWaiters;
	de::Semaphore			m_barrierSemaphore1;
	de::Semaphore			m_barrierSemaphore2;

protected:
	EGLDisplay				m_display;
};

inline const Library& TestThread::getLibrary (void) const
{
	return m_test.getLibrary();
}

TestThread::TestThread (MultiThreadedTest& test, int id)
	: m_test	(test)
	, m_id		(id)
	, m_status	(THREADSTATUS_NOT_STARTED)
{
}

void TestThread::run (void)
{
	m_status = THREADSTATUS_RUNNING;

	try
	{
		if (m_test.execTest(*this))
			m_status = THREADSTATUS_READY;
		else
			m_status = THREADSTATUS_ERROR;
	}
	catch (const TestThread::TestStop&)
	{
		getLog() << ThreadLog::BeginMessage << "Thread stopped" << ThreadLog::EndMessage;
	}
	catch (const tcu::NotSupportedError& e)
	{
		getLog() << ThreadLog::BeginMessage << "Not supported: '" << e.what() << "'" << ThreadLog::EndMessage;
	}
	catch (const std::exception& e)
	{
		getLog() << ThreadLog::BeginMessage << "Got exception: '" << e.what() << "'" << ThreadLog::EndMessage;
	}
	catch (...)
	{
		getLog() << ThreadLog::BeginMessage << "Unknown exception" << ThreadLog::EndMessage;
	}
}

bool MultiThreadedTest::execTest (TestThread& thread)
{
	bool isOk = false;

	try
	{
		isOk = runThread(thread);
	}
	catch (const TestThread::TestStop&)
	{
		// Thread exited due to error in other thread
		throw;
	}
	catch (const tcu::NotSupportedError&)
	{
		// Set status of each thread
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
			m_threads[threadNdx]->setStatus(TestThread::THREADSTATUS_NOT_SUPPORTED);

		// Release barriers
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
		{
			m_barrierSemaphore1.increment();
			m_barrierSemaphore2.increment();
		}

		throw;
	}
	catch(...)
	{
		// Set status of each thread
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
			m_threads[threadNdx]->setStatus(TestThread::THREADSTATUS_ERROR);

		// Release barriers
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
		{
			m_barrierSemaphore1.increment();
			m_barrierSemaphore2.increment();
		}

		throw;
	}

	return isOk;
}

MultiThreadedTest::MultiThreadedTest (EglTestContext& eglTestCtx, const char* name, const char* description, int threadCount, deUint64 timeoutUs)
	: TestCase				(eglTestCtx, name, description)
	, m_threadCount			(threadCount)
	, m_initialized			(false)
	, m_startTimeUs			(0)
	, m_timeoutUs			(timeoutUs)

	, m_barrierWaiters		(0)
	, m_barrierSemaphore1	(0, 0)
	, m_barrierSemaphore2	(1, 0)

	, m_display				(EGL_NO_DISPLAY)
{
}

MultiThreadedTest::~MultiThreadedTest (void)
{
	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
		delete m_threads[threadNdx];
	m_threads.clear();
}

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

void MultiThreadedTest::deinit (void)
{
	if (m_display != EGL_NO_DISPLAY)
	{
		m_eglTestCtx.getLibrary().terminate(m_display);
		m_display = EGL_NO_DISPLAY;
	}
}

void MultiThreadedTest::barrier (TestThread& thread)
{
	{
		const deInt32 waiters = deAtomicIncrement32(&m_barrierWaiters);

		if (waiters == m_threadCount)
		{
			m_barrierSemaphore2.decrement();
			m_barrierSemaphore1.increment();
		}
		else
		{
			m_barrierSemaphore1.decrement();
			m_barrierSemaphore1.increment();
		}
	}

	{
		const deInt32 waiters = deAtomicDecrement32(&m_barrierWaiters);

		if (waiters == 0)
		{
			m_barrierSemaphore1.decrement();
			m_barrierSemaphore2.increment();
		}
		else
		{
			m_barrierSemaphore2.decrement();
			m_barrierSemaphore2.increment();
		}
	}

	// Barrier was released due an error in other thread
	if (thread.getStatus() != TestThread::THREADSTATUS_RUNNING)
		throw TestThread::TestStop();
}

TestCase::IterateResult MultiThreadedTest::iterate (void)
{
	if (!m_initialized)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Thread timeout limit: " << m_timeoutUs << "us" << tcu::TestLog::EndMessage;

		// Create threads
		m_threads.reserve(m_threadCount);

		for (int threadNdx = 0; threadNdx < m_threadCount; threadNdx++)
			m_threads.push_back(new TestThread(*this, threadNdx));

		m_startTimeUs = deGetMicroseconds();

		// Run threads
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
			m_threads[threadNdx]->start();

		m_initialized = true;
	}

	int readyCount = 0;
	for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
	{
		if (m_threads[threadNdx]->getStatus() != TestThread::THREADSTATUS_RUNNING)
			readyCount++;
	}

	if (readyCount == m_threadCount)
	{
		// Join threads
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
			m_threads[threadNdx]->join();

		bool isOk			= true;
		bool notSupported	= false;

		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
		{
			if (m_threads[threadNdx]->getStatus() == TestThread::THREADSTATUS_ERROR)
				isOk = false;

			if (m_threads[threadNdx]->getStatus() == TestThread::THREADSTATUS_NOT_SUPPORTED)
				notSupported = true;
		}

		// Get logs
		{
			vector<int> messageNdx;

			messageNdx.resize(m_threads.size(), 0);

			while (true)
			{
				int			nextThreadNdx		= -1;
				deUint64	nextThreadTimeUs	= 0;

				for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
				{
					if (messageNdx[threadNdx] >= (int)m_threads[threadNdx]->getLog().getMessages().size())
						continue;

					if (nextThreadNdx == -1 || nextThreadTimeUs > m_threads[threadNdx]->getLog().getMessages()[messageNdx[threadNdx]].timeUs)
					{
						nextThreadNdx		= threadNdx;
						nextThreadTimeUs	= m_threads[threadNdx]->getLog().getMessages()[messageNdx[threadNdx]].timeUs;
					}
				}

				if (nextThreadNdx == -1)
					break;

				m_testCtx.getLog() << tcu::TestLog::Message << "[" << (nextThreadTimeUs - m_startTimeUs) << "] (" << nextThreadNdx << ") " << m_threads[nextThreadNdx]->getLog().getMessages()[messageNdx[nextThreadNdx]].msg << tcu::TestLog::EndMessage;

				messageNdx[nextThreadNdx]++;
			}
		}

		// Destroy threads
		for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
			delete m_threads[threadNdx];

		m_threads.clear();

		// Set result
		if (isOk)
		{
			if (notSupported)
				m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
			else
				m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
		}
		else
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");

		return STOP;
	}
	else
	{
		// Check for timeout
		const deUint64 currentTimeUs = deGetMicroseconds();

		if (currentTimeUs - m_startTimeUs > m_timeoutUs)
		{
			// Get logs
			{
				vector<int> messageNdx;

				messageNdx.resize(m_threads.size(), 0);

				while (true)
				{
					int			nextThreadNdx		= -1;
					deUint64	nextThreadTimeUs	= 0;

					for (int threadNdx = 0; threadNdx < (int)m_threads.size(); threadNdx++)
					{
						if (messageNdx[threadNdx] >= (int)m_threads[threadNdx]->getLog().getMessages().size())
							continue;

						if (nextThreadNdx == -1 || nextThreadTimeUs > m_threads[threadNdx]->getLog().getMessages()[messageNdx[threadNdx]].timeUs)
						{
							nextThreadNdx		= threadNdx;
							nextThreadTimeUs	= m_threads[threadNdx]->getLog().getMessages()[messageNdx[threadNdx]].timeUs;
						}
					}

					if (nextThreadNdx == -1)
						break;

					m_testCtx.getLog() << tcu::TestLog::Message << "[" << (nextThreadTimeUs - m_startTimeUs) << "] (" << nextThreadNdx << ") " << m_threads[nextThreadNdx]->getLog().getMessages()[messageNdx[nextThreadNdx]].msg << tcu::TestLog::EndMessage;

					messageNdx[nextThreadNdx]++;
				}
			}

			m_testCtx.getLog() << tcu::TestLog::Message << "[" << (currentTimeUs - m_startTimeUs) << "] (-) Timeout, Limit: " << m_timeoutUs << "us" << tcu::TestLog::EndMessage;
			m_testCtx.getLog() << tcu::TestLog::Message << "[" << (currentTimeUs - m_startTimeUs) << "] (-) Trying to perform resource cleanup..." << tcu::TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		// Sleep
		deSleep(10);
	}

	return CONTINUE;
}

namespace
{

const char* configAttributeToString (EGLint e)
{
	switch (e)
	{
		case EGL_BUFFER_SIZE:				return "EGL_BUFFER_SIZE";
		case EGL_RED_SIZE:					return "EGL_RED_SIZE";
		case EGL_GREEN_SIZE:				return "EGL_GREEN_SIZE";
		case EGL_BLUE_SIZE:					return "EGL_BLUE_SIZE";
		case EGL_LUMINANCE_SIZE:			return "EGL_LUMINANCE_SIZE";
		case EGL_ALPHA_SIZE:				return "EGL_ALPHA_SIZE";
		case EGL_ALPHA_MASK_SIZE:			return "EGL_ALPHA_MASK_SIZE";
		case EGL_BIND_TO_TEXTURE_RGB:		return "EGL_BIND_TO_TEXTURE_RGB";
		case EGL_BIND_TO_TEXTURE_RGBA:		return "EGL_BIND_TO_TEXTURE_RGBA";
		case EGL_COLOR_BUFFER_TYPE:			return "EGL_COLOR_BUFFER_TYPE";
		case EGL_CONFIG_CAVEAT:				return "EGL_CONFIG_CAVEAT";
		case EGL_CONFIG_ID:					return "EGL_CONFIG_ID";
		case EGL_CONFORMANT:				return "EGL_CONFORMANT";
		case EGL_DEPTH_SIZE:				return "EGL_DEPTH_SIZE";
		case EGL_LEVEL:						return "EGL_LEVEL";
		case EGL_MAX_PBUFFER_WIDTH:			return "EGL_MAX_PBUFFER_WIDTH";
		case EGL_MAX_PBUFFER_HEIGHT:		return "EGL_MAX_PBUFFER_HEIGHT";
		case EGL_MAX_PBUFFER_PIXELS:		return "EGL_MAX_PBUFFER_PIXELS";
		case EGL_MAX_SWAP_INTERVAL:			return "EGL_MAX_SWAP_INTERVAL";
		case EGL_MIN_SWAP_INTERVAL:			return "EGL_MIN_SWAP_INTERVAL";
		case EGL_NATIVE_RENDERABLE:			return "EGL_NATIVE_RENDERABLE";
		case EGL_NATIVE_VISUAL_ID:			return "EGL_NATIVE_VISUAL_ID";
		case EGL_NATIVE_VISUAL_TYPE:		return "EGL_NATIVE_VISUAL_TYPE";
		case EGL_RENDERABLE_TYPE:			return "EGL_RENDERABLE_TYPE";
		case EGL_SAMPLE_BUFFERS:			return "EGL_SAMPLE_BUFFERS";
		case EGL_SAMPLES:					return "EGL_SAMPLES";
		case EGL_STENCIL_SIZE:				return "EGL_STENCIL_SIZE";
		case EGL_SURFACE_TYPE:				return "EGL_SURFACE_TYPE";
		case EGL_TRANSPARENT_TYPE:			return "EGL_TRANSPARENT_TYPE";
		case EGL_TRANSPARENT_RED_VALUE:		return "EGL_TRANSPARENT_RED_VALUE";
		case EGL_TRANSPARENT_GREEN_VALUE:	return "EGL_TRANSPARENT_GREEN_VALUE";
		case EGL_TRANSPARENT_BLUE_VALUE:	return "EGL_TRANSPARENT_BLUE_VALUE";
		default:							return "<Unknown>";
	}
}

} // anonymous

class MultiThreadedConfigTest : public MultiThreadedTest
{
public:
				MultiThreadedConfigTest		(EglTestContext& context, const char* name, const char* description, int getConfigs, int chooseConfigs, int query);
	bool		runThread					(TestThread& thread);

private:
	const int	m_getConfigs;
	const int	m_chooseConfigs;
	const int	m_query;
};

MultiThreadedConfigTest::MultiThreadedConfigTest (EglTestContext& context, const char* name, const char* description, int getConfigs, int chooseConfigs, int query)
	: MultiThreadedTest (context, name, description, 2, 20000000/*us = 20s*/) // \todo [mika] Set timeout to something relevant to frameworks timeout?
	, m_getConfigs		(getConfigs)
	, m_chooseConfigs	(chooseConfigs)
	, m_query			(query)
{
}

bool MultiThreadedConfigTest::runThread (TestThread& thread)
{
	const Library&		egl		= getLibrary();
	de::Random			rnd		(deInt32Hash(thread.getId() + 10435));
	vector<EGLConfig>	configs;

	barrier(thread);

	for (int getConfigsNdx = 0; getConfigsNdx < m_getConfigs; getConfigsNdx++)
	{
		EGLint configCount;

		// Get number of configs
		{
			EGLBoolean result;

			result = egl.getConfigs(m_display, NULL, 0, &configCount);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglGetConfigs(" << m_display << ", NULL, 0, " << configCount << ")" <<  ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglGetConfigs()");

			if (!result)
				return false;
		}

		configs.resize(configs.size() + configCount);

		// Get configs
		if (configCount != 0)
		{
			EGLBoolean result;

			result = egl.getConfigs(m_display, &(configs[configs.size() - configCount]), configCount, &configCount);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglGetConfigs(" << m_display << ", &configs' " << configCount << ", " << configCount << ")" <<  ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglGetConfigs()");

			if (!result)
				return false;
		}

		// Pop configs to stop config list growing
		if (configs.size() > 40)
		{
			configs.erase(configs.begin() + 40, configs.end());
		}
		else
		{
			const int popCount = rnd.getInt(0, (int)(configs.size()-2));

			configs.erase(configs.begin() + (configs.size() - popCount), configs.end());
		}
	}

	for (int chooseConfigsNdx = 0; chooseConfigsNdx < m_chooseConfigs; chooseConfigsNdx++)
	{
		EGLint configCount;

		static const EGLint attribList[] = {
			EGL_NONE
		};

		// Get number of configs
		{
			EGLBoolean result;

			result = egl.chooseConfig(m_display, attribList, NULL, 0, &configCount);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglChooseConfig(" << m_display << ", { EGL_NONE }, NULL, 0, " << configCount << ")" <<  ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglChooseConfig()");

			if (!result)
				return false;
		}

		configs.resize(configs.size() + configCount);

		// Get configs
		if (configCount != 0)
		{
			EGLBoolean result;

			result = egl.chooseConfig(m_display, attribList, &(configs[configs.size() - configCount]), configCount, &configCount);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglChooseConfig(" << m_display << ", { EGL_NONE }, &configs, " << configCount << ", " << configCount << ")" <<  ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglChooseConfig()");

			if (!result)
				return false;
		}

		// Pop configs to stop config list growing
		if (configs.size() > 40)
		{
			configs.erase(configs.begin() + 40, configs.end());
		}
		else
		{
			const int popCount = rnd.getInt(0, (int)(configs.size()-2));

			configs.erase(configs.begin() + (configs.size() - popCount), configs.end());
		}
	}

	{
		// Perform queries on configs
		static const EGLint attributes[] =
		{
			EGL_BUFFER_SIZE,
			EGL_RED_SIZE,
			EGL_GREEN_SIZE,
			EGL_BLUE_SIZE,
			EGL_LUMINANCE_SIZE,
			EGL_ALPHA_SIZE,
			EGL_ALPHA_MASK_SIZE,
			EGL_BIND_TO_TEXTURE_RGB,
			EGL_BIND_TO_TEXTURE_RGBA,
			EGL_COLOR_BUFFER_TYPE,
			EGL_CONFIG_CAVEAT,
			EGL_CONFIG_ID,
			EGL_CONFORMANT,
			EGL_DEPTH_SIZE,
			EGL_LEVEL,
			EGL_MAX_PBUFFER_WIDTH,
			EGL_MAX_PBUFFER_HEIGHT,
			EGL_MAX_PBUFFER_PIXELS,
			EGL_MAX_SWAP_INTERVAL,
			EGL_MIN_SWAP_INTERVAL,
			EGL_NATIVE_RENDERABLE,
			EGL_NATIVE_VISUAL_ID,
			EGL_NATIVE_VISUAL_TYPE,
			EGL_RENDERABLE_TYPE,
			EGL_SAMPLE_BUFFERS,
			EGL_SAMPLES,
			EGL_STENCIL_SIZE,
			EGL_SURFACE_TYPE,
			EGL_TRANSPARENT_TYPE,
			EGL_TRANSPARENT_RED_VALUE,
			EGL_TRANSPARENT_GREEN_VALUE,
			EGL_TRANSPARENT_BLUE_VALUE
		};

		for (int queryNdx = 0; queryNdx < m_query; queryNdx++)
		{
			const EGLint	attribute	= attributes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(attributes)-1)];
			EGLConfig		config		= configs[rnd.getInt(0, (int)(configs.size()-1))];
			EGLint			value;
			EGLBoolean		result;

			result = egl.getConfigAttrib(m_display, config, attribute, &value);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglGetConfigAttrib(" << m_display << ", " << config << ", " << configAttributeToString(attribute) << ", " << value << ")" <<  ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglGetConfigAttrib()");

			if (!result)
				return false;
		}
	}

	return true;
}

class MultiThreadedObjectTest : public MultiThreadedTest
{
public:
	enum Type
	{
		TYPE_PBUFFER			= (1<<0),
		TYPE_PIXMAP				= (1<<1),
		TYPE_WINDOW				= (1<<2),
		TYPE_SINGLE_WINDOW		= (1<<3),
		TYPE_CONTEXT			= (1<<4)
	};

					MultiThreadedObjectTest			(EglTestContext& context, const char* name, const char* description, deUint32 types);
					~MultiThreadedObjectTest		(void);

	virtual void	deinit							(void);

	bool			runThread						(TestThread& thread);

	void			createDestroyObjects			(TestThread& thread, int count);
	void			pushObjectsToShared				(TestThread& thread);
	void			pullObjectsFromShared			(TestThread& thread, int pbufferCount, int pixmapCount, int windowCount, int contextCount);
	void			querySetSharedObjects			(TestThread& thread, int count);
	void			destroyObjects					(TestThread& thread);

private:
	EGLConfig			m_config;
	de::Random			m_rnd0;
	de::Random			m_rnd1;
	Type				m_types;

	volatile deUint32	m_hasWindow;

	vector<pair<eglu::NativePixmap*, EGLSurface> >	m_sharedNativePixmaps;
	vector<pair<eglu::NativePixmap*, EGLSurface> >	m_nativePixmaps0;
	vector<pair<eglu::NativePixmap*, EGLSurface> >	m_nativePixmaps1;

	vector<pair<eglu::NativeWindow*, EGLSurface> >	m_sharedNativeWindows;
	vector<pair<eglu::NativeWindow*, EGLSurface> >	m_nativeWindows0;
	vector<pair<eglu::NativeWindow*, EGLSurface> >	m_nativeWindows1;

	vector<EGLSurface>								m_sharedPbuffers;
	vector<EGLSurface>								m_pbuffers0;
	vector<EGLSurface>								m_pbuffers1;

	vector<EGLContext>								m_sharedContexts;
	vector<EGLContext>								m_contexts0;
	vector<EGLContext>								m_contexts1;
};

MultiThreadedObjectTest::MultiThreadedObjectTest (EglTestContext& context, const char* name, const char* description, deUint32 type)
	: MultiThreadedTest (context, name, description, 2, 20000000/*us = 20s*/) // \todo [mika] Set timeout to something relevant to frameworks timeout?
	, m_config			(DE_NULL)
	, m_rnd0			(58204327)
	, m_rnd1			(230983)
	, m_types			((Type)type)
	, m_hasWindow		(0)
{
}

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

void MultiThreadedObjectTest::deinit (void)
{
	const Library&		egl		= getLibrary();

	// Clear pbuffers
	for (int pbufferNdx = 0; pbufferNdx < (int)m_pbuffers0.size(); pbufferNdx++)
	{
		if (m_pbuffers0[pbufferNdx] != EGL_NO_SURFACE)
		{
			egl.destroySurface(m_display, m_pbuffers0[pbufferNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroySurface()");
			m_pbuffers0[pbufferNdx] = EGL_NO_SURFACE;
		}
	}
	m_pbuffers0.clear();

	for (int pbufferNdx = 0; pbufferNdx < (int)m_pbuffers1.size(); pbufferNdx++)
	{
		if (m_pbuffers1[pbufferNdx] != EGL_NO_SURFACE)
		{
			egl.destroySurface(m_display, m_pbuffers1[pbufferNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroySurface()");
			m_pbuffers1[pbufferNdx] = EGL_NO_SURFACE;
		}
	}
	m_pbuffers1.clear();

	for (int pbufferNdx = 0; pbufferNdx < (int)m_sharedPbuffers.size(); pbufferNdx++)
	{
		if (m_sharedPbuffers[pbufferNdx] != EGL_NO_SURFACE)
		{
			egl.destroySurface(m_display, m_sharedPbuffers[pbufferNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroySurface()");
			m_sharedPbuffers[pbufferNdx] = EGL_NO_SURFACE;
		}
	}
	m_sharedPbuffers.clear();

	for (int contextNdx = 0; contextNdx < (int)m_sharedContexts.size(); contextNdx++)
	{
		if (m_sharedContexts[contextNdx] != EGL_NO_CONTEXT)
		{
			egl.destroyContext(m_display, m_sharedContexts[contextNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroyContext()");
			m_sharedContexts[contextNdx] =  EGL_NO_CONTEXT;
		}
	}
	m_sharedContexts.clear();

	for (int contextNdx = 0; contextNdx < (int)m_contexts0.size(); contextNdx++)
	{
		if (m_contexts0[contextNdx] != EGL_NO_CONTEXT)
		{
			egl.destroyContext(m_display, m_contexts0[contextNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroyContext()");
			m_contexts0[contextNdx] =  EGL_NO_CONTEXT;
		}
	}
	m_contexts0.clear();

	for (int contextNdx = 0; contextNdx < (int)m_contexts1.size(); contextNdx++)
	{
		if (m_contexts1[contextNdx] != EGL_NO_CONTEXT)
		{
			egl.destroyContext(m_display, m_contexts1[contextNdx]);
			EGLU_CHECK_MSG(egl, "eglDestroyContext()");
			m_contexts1[contextNdx] =  EGL_NO_CONTEXT;
		}
	}
	m_contexts1.clear();

	// Clear pixmaps
	for (int pixmapNdx = 0; pixmapNdx < (int)m_nativePixmaps0.size(); pixmapNdx++)
	{
		if (m_nativePixmaps0[pixmapNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_nativePixmaps0[pixmapNdx].second));

		m_nativePixmaps0[pixmapNdx].second = EGL_NO_SURFACE;
		delete m_nativePixmaps0[pixmapNdx].first;
		m_nativePixmaps0[pixmapNdx].first = NULL;
	}
	m_nativePixmaps0.clear();

	for (int pixmapNdx = 0; pixmapNdx < (int)m_nativePixmaps1.size(); pixmapNdx++)
	{
		if (m_nativePixmaps1[pixmapNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_nativePixmaps1[pixmapNdx].second));

		m_nativePixmaps1[pixmapNdx].second = EGL_NO_SURFACE;
		delete m_nativePixmaps1[pixmapNdx].first;
		m_nativePixmaps1[pixmapNdx].first = NULL;
	}
	m_nativePixmaps1.clear();

	for (int pixmapNdx = 0; pixmapNdx < (int)m_sharedNativePixmaps.size(); pixmapNdx++)
	{
		if (m_sharedNativePixmaps[pixmapNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_sharedNativePixmaps[pixmapNdx].second));

		m_sharedNativePixmaps[pixmapNdx].second = EGL_NO_SURFACE;
		delete m_sharedNativePixmaps[pixmapNdx].first;
		m_sharedNativePixmaps[pixmapNdx].first = NULL;
	}
	m_sharedNativePixmaps.clear();

	// Clear windows
	for (int windowNdx = 0; windowNdx < (int)m_nativeWindows1.size(); windowNdx++)
	{
		if (m_nativeWindows1[windowNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_nativeWindows1[windowNdx].second));

		m_nativeWindows1[windowNdx].second = EGL_NO_SURFACE;
		delete m_nativeWindows1[windowNdx].first;
		m_nativeWindows1[windowNdx].first = NULL;
	}
	m_nativeWindows1.clear();

	for (int windowNdx = 0; windowNdx < (int)m_nativeWindows0.size(); windowNdx++)
	{
		if (m_nativeWindows0[windowNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_nativeWindows0[windowNdx].second));

		m_nativeWindows0[windowNdx].second = EGL_NO_SURFACE;
		delete m_nativeWindows0[windowNdx].first;
		m_nativeWindows0[windowNdx].first = NULL;
	}
	m_nativeWindows0.clear();

	for (int windowNdx = 0; windowNdx < (int)m_sharedNativeWindows.size(); windowNdx++)
	{
		if (m_sharedNativeWindows[windowNdx].second != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_display, m_sharedNativeWindows[windowNdx].second));

		m_sharedNativeWindows[windowNdx].second = EGL_NO_SURFACE;
		delete m_sharedNativeWindows[windowNdx].first;
		m_sharedNativeWindows[windowNdx].first = NULL;
	}
	m_sharedNativeWindows.clear();

	MultiThreadedTest::deinit();
}

bool MultiThreadedObjectTest::runThread (TestThread& thread)
{
	const Library&		egl		= getLibrary();

	if (thread.getId() == 0)
	{
		EGLint surfaceTypes = 0;

		if ((m_types & TYPE_WINDOW) != 0)
			surfaceTypes |= EGL_WINDOW_BIT;

		if ((m_types & TYPE_PBUFFER) != 0)
			surfaceTypes |= EGL_PBUFFER_BIT;

		if ((m_types & TYPE_PIXMAP) != 0)
			surfaceTypes |= EGL_PIXMAP_BIT;

		EGLint configCount;
		EGLint attribList[] =
		{
			EGL_SURFACE_TYPE, surfaceTypes,
			EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
			EGL_NONE
		};

		EGLU_CHECK_CALL(egl, chooseConfig(m_display, attribList, &m_config, 1, &configCount));

		if (configCount == 0)
			TCU_THROW(NotSupportedError, "No usable config found");
	}

	barrier(thread);

	// Create / Destroy Objects
	if ((m_types & TYPE_SINGLE_WINDOW) != 0 && (m_types & TYPE_PBUFFER) == 0 && (m_types & TYPE_PIXMAP) == 0 && (m_types & TYPE_CONTEXT) == 0)
	{
		if (thread.getId() == 0)
			createDestroyObjects(thread, 1);
	}
	else
		createDestroyObjects(thread, 100);

	// Push first threads objects to shared
	if (thread.getId() == 0)
		pushObjectsToShared(thread);

	barrier(thread);

	// Push second threads objects to shared
	if (thread.getId() == 1)
		pushObjectsToShared(thread);

	barrier(thread);

	// Make queries from shared surfaces
	querySetSharedObjects(thread, 100);

	barrier(thread);

	// Pull surfaces for first thread from shared surfaces
	if (thread.getId() == 0)
		pullObjectsFromShared(thread, (int)(m_sharedPbuffers.size()/2), (int)(m_sharedNativePixmaps.size()/2), (int)(m_sharedNativeWindows.size()/2), (int)(m_sharedContexts.size()/2));

	barrier(thread);

	// Pull surfaces for second thread from shared surfaces
	if (thread.getId() == 1)
		pullObjectsFromShared(thread, (int)m_sharedPbuffers.size(), (int)m_sharedNativePixmaps.size(), (int)m_sharedNativeWindows.size(), (int)m_sharedContexts.size());

	barrier(thread);

	// Create / Destroy Objects
	if ((m_types & TYPE_SINGLE_WINDOW) == 0)
		createDestroyObjects(thread, 100);

	// Destroy surfaces
	destroyObjects(thread);

	return true;
}

void MultiThreadedObjectTest::createDestroyObjects (TestThread& thread, int count)
{
	const Library&									egl			= getLibrary();
	de::Random&										rnd			= (thread.getId() == 0 ? m_rnd0 : m_rnd1);
	vector<EGLSurface>&								pbuffers	= (thread.getId() == 0 ? m_pbuffers0 : m_pbuffers1);
	vector<pair<eglu::NativeWindow*, EGLSurface> >&	windows		= (thread.getId() == 0 ? m_nativeWindows0 : m_nativeWindows1);
	vector<pair<eglu::NativePixmap*, EGLSurface> >&	pixmaps		= (thread.getId() == 0 ? m_nativePixmaps0 : m_nativePixmaps1);
	vector<EGLContext>&								contexts	= (thread.getId() == 0 ? m_contexts0 : m_contexts1);
	set<Type>										objectTypes;

	if ((m_types & TYPE_PBUFFER) != 0)
		objectTypes.insert(TYPE_PBUFFER);

	if ((m_types & TYPE_PIXMAP) != 0)
		objectTypes.insert(TYPE_PIXMAP);

	if ((m_types & TYPE_WINDOW) != 0)
		objectTypes.insert(TYPE_WINDOW);

	if ((m_types & TYPE_CONTEXT) != 0)
		objectTypes.insert(TYPE_CONTEXT);

	for (int createDestroyNdx = 0; createDestroyNdx < count; createDestroyNdx++)
	{
		bool create;
		Type type;

		if (pbuffers.size() > 5 && ((m_types & TYPE_PBUFFER) != 0))
		{
			create	= false;
			type	= TYPE_PBUFFER;
		}
		else if (windows.size() > 5 && ((m_types & TYPE_WINDOW) != 0))
		{
			create	= false;
			type	= TYPE_WINDOW;
		}
		else if (pixmaps.size() > 5 && ((m_types & TYPE_PIXMAP) != 0))
		{
			create	= false;
			type	= TYPE_PIXMAP;
		}
		else if (contexts.size() > 5 && ((m_types & TYPE_CONTEXT) != 0))
		{
			create	= false;
			type	= TYPE_CONTEXT;
		}
		else if (pbuffers.size() < 3 && ((m_types & TYPE_PBUFFER) != 0))
		{
			create	= true;
			type	= TYPE_PBUFFER;
		}
		else if (pixmaps.size() < 3 && ((m_types & TYPE_PIXMAP) != 0))
		{
			create	= true;
			type	= TYPE_PIXMAP;
		}
		else if (contexts.size() < 3 && ((m_types & TYPE_CONTEXT) != 0))
		{
			create	= true;
			type	= TYPE_CONTEXT;
		}
		else if (windows.size() < 3 && ((m_types & TYPE_WINDOW) != 0) && ((m_types & TYPE_SINGLE_WINDOW) == 0))
		{
			create	= true;
			type	= TYPE_WINDOW;
		}
		else if (windows.empty() && (m_hasWindow == 0) && ((m_types & TYPE_WINDOW) != 0) && ((m_types & TYPE_SINGLE_WINDOW) != 0))
		{
			create	= true;
			type	= TYPE_WINDOW;
		}
		else
		{
			create = rnd.getBool();

			if (!create && windows.empty())
				objectTypes.erase(TYPE_WINDOW);

			type = rnd.choose<Type>(objectTypes.begin(), objectTypes.end());
		}

		if (create)
		{
			switch (type)
			{
				case TYPE_PBUFFER:
				{
					EGLSurface surface;

					const EGLint attributes[] =
					{
						EGL_WIDTH,	64,
						EGL_HEIGHT,	64,

						EGL_NONE
					};

					surface = egl.createPbufferSurface(m_display, m_config, attributes);
					thread.getLog() << ThreadLog::BeginMessage << surface << " = eglCreatePbufferSurface(" << m_display << ", " << m_config << ", { EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE })" << ThreadLog::EndMessage;
					EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");

					pbuffers.push_back(surface);

					break;
				}

				case TYPE_WINDOW:
				{
					const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());

					if ((m_types & TYPE_SINGLE_WINDOW) != 0)
					{
						if (deAtomicCompareExchange32(&m_hasWindow, 0, 1) == 0)
						{
							eglu::NativeWindow* window	= DE_NULL;
							EGLSurface			surface = EGL_NO_SURFACE;

							try
							{
								window = windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(64, 64, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
								surface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, m_config, DE_NULL);

								thread.getLog() << ThreadLog::BeginMessage << surface << " = eglCreateWindowSurface()" << ThreadLog::EndMessage;
								windows.push_back(std::make_pair(window, surface));
							}
							catch (const std::exception&)
							{
								if (surface != EGL_NO_SURFACE)
									EGLU_CHECK_CALL(egl, destroySurface(m_display, surface));
								delete window;
								m_hasWindow = 0;
								throw;
							}
						}
						else
						{
							createDestroyNdx--;
						}
					}
					else
					{
						eglu::NativeWindow* window	= DE_NULL;
						EGLSurface			surface = EGL_NO_SURFACE;

						try
						{
							window	= windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, eglu::WindowParams(64, 64, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
							surface	= eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, m_config, DE_NULL);

							thread.getLog() << ThreadLog::BeginMessage << surface << " = eglCreateWindowSurface()" << ThreadLog::EndMessage;
							windows.push_back(std::make_pair(window, surface));
						}
						catch (const std::exception&)
						{
							if (surface != EGL_NO_SURFACE)
								EGLU_CHECK_CALL(egl, destroySurface(m_display, surface));
							delete window;
							throw;
						}
					}
					break;
				}

				case TYPE_PIXMAP:
				{
					const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
					eglu::NativePixmap* 				pixmap			= DE_NULL;
					EGLSurface							surface			= EGL_NO_SURFACE;

					try
					{
						pixmap	= pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), m_display, m_config, DE_NULL, 64, 64);
						surface	= eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, m_config, DE_NULL);

						thread.getLog() << ThreadLog::BeginMessage << surface << " = eglCreatePixmapSurface()" << ThreadLog::EndMessage;
						pixmaps.push_back(std::make_pair(pixmap, surface));
					}
					catch (const std::exception&)
					{
						if (surface != EGL_NO_SURFACE)
							EGLU_CHECK_CALL(egl, destroySurface(m_display, surface));
						delete pixmap;
						throw;
					}
					break;
				}

				case TYPE_CONTEXT:
				{
					EGLContext context;

					EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
					thread.getLog() << ThreadLog::BeginMessage << "eglBindAPI(EGL_OPENGL_ES_API)" << ThreadLog::EndMessage;

					const EGLint attributes[] =
					{
						EGL_CONTEXT_CLIENT_VERSION, 2,
						EGL_NONE
					};

					context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attributes);
					thread.getLog() << ThreadLog::BeginMessage << context << " = eglCreateContext(" << m_display << ", " << m_config << ", EGL_NO_CONTEXT, { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE })" << ThreadLog::EndMessage;
					EGLU_CHECK_MSG(egl, "eglCreateContext()");
					contexts.push_back(context);
					break;
				}

				default:
					DE_ASSERT(false);
			};
		}
		else
		{
			switch (type)
			{
				case TYPE_PBUFFER:
				{
					const int pbufferNdx = rnd.getInt(0, (int)(pbuffers.size()-1));
					EGLBoolean result;

					result = egl.destroySurface(m_display, pbuffers[pbufferNdx]);
					thread.getLog() << ThreadLog::BeginMessage << result << " = eglDestroySurface(" << m_display << ", " << pbuffers[pbufferNdx] << ")" << ThreadLog::EndMessage;
					EGLU_CHECK_MSG(egl, "eglDestroySurface()");

					pbuffers.erase(pbuffers.begin() + pbufferNdx);

					break;
				}

				case TYPE_WINDOW:
				{
					const int windowNdx = rnd.getInt(0, (int)(windows.size()-1));

					thread.getLog() << ThreadLog::BeginMessage << "eglDestroySurface(" << m_display << ", " << windows[windowNdx].second << ")" << ThreadLog::EndMessage;

					EGLU_CHECK_CALL(egl, destroySurface(m_display, windows[windowNdx].second));
					windows[windowNdx].second = EGL_NO_SURFACE;
					delete windows[windowNdx].first;
					windows[windowNdx].first = DE_NULL;
					windows.erase(windows.begin() + windowNdx);

					if ((m_types & TYPE_SINGLE_WINDOW) != 0)
						m_hasWindow = 0;

					break;
				}

				case TYPE_PIXMAP:
				{
					const int pixmapNdx = rnd.getInt(0, (int)(pixmaps.size()-1));

					thread.getLog() << ThreadLog::BeginMessage << "eglDestroySurface(" << m_display << ", " << pixmaps[pixmapNdx].second << ")" << ThreadLog::EndMessage;
					EGLU_CHECK_CALL(egl, destroySurface(m_display, pixmaps[pixmapNdx].second));
					pixmaps[pixmapNdx].second = EGL_NO_SURFACE;
					delete pixmaps[pixmapNdx].first;
					pixmaps[pixmapNdx].first = DE_NULL;
					pixmaps.erase(pixmaps.begin() + pixmapNdx);

					break;
				}

				case TYPE_CONTEXT:
				{
					const int contextNdx = rnd.getInt(0, (int)(contexts.size()-1));

					EGLU_CHECK_CALL(egl, destroyContext(m_display, contexts[contextNdx]));
					thread.getLog() << ThreadLog::BeginMessage << "eglDestroyContext(" << m_display << ", " << contexts[contextNdx]  << ")" << ThreadLog::EndMessage;
					contexts.erase(contexts.begin() + contextNdx);

					break;
				}

				default:
					DE_ASSERT(false);
			}

		}
	}
}

void MultiThreadedObjectTest::pushObjectsToShared (TestThread& thread)
{
	vector<EGLSurface>&									pbuffers	= (thread.getId() == 0 ? m_pbuffers0 : m_pbuffers1);
	vector<pair<eglu::NativeWindow*, EGLSurface> >&		windows		= (thread.getId() == 0 ? m_nativeWindows0 : m_nativeWindows1);
	vector<pair<eglu::NativePixmap*, EGLSurface> >&		pixmaps		= (thread.getId() == 0 ? m_nativePixmaps0 : m_nativePixmaps1);
	vector<EGLContext>&									contexts	= (thread.getId() == 0 ? m_contexts0 : m_contexts1);

	for (int pbufferNdx = 0; pbufferNdx < (int)pbuffers.size(); pbufferNdx++)
		m_sharedPbuffers.push_back(pbuffers[pbufferNdx]);

	pbuffers.clear();

	for (int windowNdx = 0; windowNdx < (int)windows.size(); windowNdx++)
		m_sharedNativeWindows.push_back(windows[windowNdx]);

	windows.clear();

	for (int pixmapNdx = 0; pixmapNdx < (int)pixmaps.size(); pixmapNdx++)
		m_sharedNativePixmaps.push_back(pixmaps[pixmapNdx]);

	pixmaps.clear();

	for (int contextNdx = 0; contextNdx < (int)contexts.size(); contextNdx++)
		m_sharedContexts.push_back(contexts[contextNdx]);

	contexts.clear();
}

void MultiThreadedObjectTest::pullObjectsFromShared (TestThread& thread, int pbufferCount, int pixmapCount, int windowCount, int contextCount)
{
	de::Random&											rnd			= (thread.getId() == 0 ? m_rnd0 : m_rnd1);
	vector<EGLSurface>&									pbuffers	= (thread.getId() == 0 ? m_pbuffers0 : m_pbuffers1);
	vector<pair<eglu::NativeWindow*, EGLSurface> >&		windows		= (thread.getId() == 0 ? m_nativeWindows0 : m_nativeWindows1);
	vector<pair<eglu::NativePixmap*, EGLSurface> >&		pixmaps		= (thread.getId() == 0 ? m_nativePixmaps0 : m_nativePixmaps1);
	vector<EGLContext>&									contexts	= (thread.getId() == 0 ? m_contexts0 : m_contexts1);

	for (int pbufferNdx = 0; pbufferNdx < pbufferCount; pbufferNdx++)
	{
		const int ndx = rnd.getInt(0, (int)(m_sharedPbuffers.size()-1));

		pbuffers.push_back(m_sharedPbuffers[ndx]);
		m_sharedPbuffers.erase(m_sharedPbuffers.begin() + ndx);
	}

	for (int pixmapNdx = 0; pixmapNdx < pixmapCount; pixmapNdx++)
	{
		const int ndx = rnd.getInt(0, (int)(m_sharedNativePixmaps.size()-1));

		pixmaps.push_back(m_sharedNativePixmaps[ndx]);
		m_sharedNativePixmaps.erase(m_sharedNativePixmaps.begin() + ndx);
	}

	for (int windowNdx = 0; windowNdx < windowCount; windowNdx++)
	{
		const int ndx = rnd.getInt(0, (int)(m_sharedNativeWindows.size()-1));

		windows.push_back(m_sharedNativeWindows[ndx]);
		m_sharedNativeWindows.erase(m_sharedNativeWindows.begin() + ndx);
	}

	for (int contextNdx = 0; contextNdx < contextCount; contextNdx++)
	{
		const int ndx = rnd.getInt(0, (int)(m_sharedContexts.size()-1));

		contexts.push_back(m_sharedContexts[ndx]);
		m_sharedContexts.erase(m_sharedContexts.begin() + ndx);
	}
}

void MultiThreadedObjectTest::querySetSharedObjects (TestThread& thread, int count)
{
	const Library&		egl		= getLibrary();
	de::Random&			rnd		= (thread.getId() == 0 ? m_rnd0 : m_rnd1);
	vector<Type>		objectTypes;

	if ((m_types & TYPE_PBUFFER) != 0)
		objectTypes.push_back(TYPE_PBUFFER);

	if ((m_types & TYPE_PIXMAP) != 0)
		objectTypes.push_back(TYPE_PIXMAP);

	if (!m_sharedNativeWindows.empty() && (m_types & TYPE_WINDOW) != 0)
		objectTypes.push_back(TYPE_WINDOW);

	if ((m_types & TYPE_CONTEXT) != 0)
		objectTypes.push_back(TYPE_CONTEXT);

	for (int queryNdx = 0; queryNdx < count; queryNdx++)
	{
		const Type	type		= rnd.choose<Type>(objectTypes.begin(), objectTypes.end());
		EGLSurface	surface		= EGL_NO_SURFACE;
		EGLContext	context		= EGL_NO_CONTEXT;

		switch (type)
		{
			case TYPE_PBUFFER:
				surface = m_sharedPbuffers[rnd.getInt(0, (int)(m_sharedPbuffers.size()-1))];
				break;

			case TYPE_PIXMAP:
				surface = m_sharedNativePixmaps[rnd.getInt(0, (int)(m_sharedNativePixmaps.size()-1))].second;
				break;

			case TYPE_WINDOW:
				surface = m_sharedNativeWindows[rnd.getInt(0, (int)(m_sharedNativeWindows.size()-1))].second;
				break;

			case TYPE_CONTEXT:
				context = m_sharedContexts[rnd.getInt(0, (int)(m_sharedContexts.size()-1))];
				break;

			default:
				DE_ASSERT(false);
		}

		if (surface != EGL_NO_SURFACE)
		{
			static const EGLint queryAttributes[] =
			{
				EGL_LARGEST_PBUFFER,
				EGL_HEIGHT,
				EGL_WIDTH
			};

			const EGLint	attribute	= queryAttributes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(queryAttributes) - 1)];
			EGLBoolean		result;
			EGLint			value;

			result = egl.querySurface(m_display, surface, attribute, &value);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglQuerySurface(" << m_display << ", " << surface << ", " << attribute << ", " << value << ")" << ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglQuerySurface()");

		}
		else if (context != EGL_NO_CONTEXT)
		{
			static const EGLint attributes[] =
			{
				EGL_CONFIG_ID,
				EGL_CONTEXT_CLIENT_TYPE,
				EGL_CONTEXT_CLIENT_VERSION,
				EGL_RENDER_BUFFER
			};

			const EGLint	attribute = attributes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(attributes)-1)];
			EGLint			value;
			EGLBoolean		result;

			result = egl.queryContext(m_display, context, attribute, &value);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglQueryContext(" << m_display << ", " << context << ", " << attribute << ", " << value << ")" << ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglQueryContext()");

		}
		else
			DE_ASSERT(false);
	}
}

void MultiThreadedObjectTest::destroyObjects (TestThread& thread)
{
	const Library&										egl			= getLibrary();
	vector<EGLSurface>&									pbuffers	= (thread.getId() == 0 ? m_pbuffers0 : m_pbuffers1);
	vector<pair<eglu::NativeWindow*, EGLSurface> >&		windows		= (thread.getId() == 0 ? m_nativeWindows0 : m_nativeWindows1);
	vector<pair<eglu::NativePixmap*, EGLSurface> >&		pixmaps		= (thread.getId() == 0 ? m_nativePixmaps0 : m_nativePixmaps1);
	vector<EGLContext>&									contexts	= (thread.getId() == 0 ? m_contexts0 : m_contexts1);

	for (int pbufferNdx = 0; pbufferNdx < (int)pbuffers.size(); pbufferNdx++)
	{
		if (pbuffers[pbufferNdx] != EGL_NO_SURFACE)
		{
			// Destroy EGLSurface
			EGLBoolean result;

			result = egl.destroySurface(m_display, pbuffers[pbufferNdx]);
			thread.getLog() << ThreadLog::BeginMessage << result << " = eglDestroySurface(" << m_display << ", " << pbuffers[pbufferNdx] << ")" << ThreadLog::EndMessage;
			EGLU_CHECK_MSG(egl, "eglDestroySurface()");
			pbuffers[pbufferNdx] = EGL_NO_SURFACE;
		}
	}
	pbuffers.clear();

	for (int windowNdx = 0; windowNdx < (int)windows.size(); windowNdx++)
	{
		if (windows[windowNdx].second != EGL_NO_SURFACE)
		{
			thread.getLog() << ThreadLog::BeginMessage << "eglDestroySurface(" << m_display << ", " << windows[windowNdx].second << ")" << ThreadLog::EndMessage;
			EGLU_CHECK_CALL(egl, destroySurface(m_display, windows[windowNdx].second));
			windows[windowNdx].second = EGL_NO_SURFACE;
		}

		if (windows[windowNdx].first)
		{
			delete windows[windowNdx].first;
			windows[windowNdx].first = NULL;
		}
	}
	windows.clear();

	for (int pixmapNdx = 0; pixmapNdx < (int)pixmaps.size(); pixmapNdx++)
	{
		if (pixmaps[pixmapNdx].first != EGL_NO_SURFACE)
		{
			thread.getLog() << ThreadLog::BeginMessage << "eglDestroySurface(" << m_display << ", " << pixmaps[pixmapNdx].second << ")" << ThreadLog::EndMessage;
			EGLU_CHECK_CALL(egl, destroySurface(m_display, pixmaps[pixmapNdx].second));
			pixmaps[pixmapNdx].second = EGL_NO_SURFACE;
		}

		if (pixmaps[pixmapNdx].first)
		{
			delete pixmaps[pixmapNdx].first;
			pixmaps[pixmapNdx].first = NULL;
		}
	}
	pixmaps.clear();

	for (int contextNdx = 0; contextNdx < (int)contexts.size(); contextNdx++)
	{
		if (contexts[contextNdx] != EGL_NO_CONTEXT)
		{
			EGLU_CHECK_CALL(egl, destroyContext(m_display, contexts[contextNdx]));
			thread.getLog() << ThreadLog::BeginMessage << "eglDestroyContext(" << m_display << ", " << contexts[contextNdx]  << ")" << ThreadLog::EndMessage;
			contexts[contextNdx] = EGL_NO_CONTEXT;
		}
	}
	contexts.clear();
}

MultiThreadedTests::MultiThreadedTests (EglTestContext& context)
	: TestCaseGroup(context, "multithread", "Multithreaded EGL tests")
{
}

void MultiThreadedTests::init (void)
{
	// Config tests
	addChild(new MultiThreadedConfigTest(m_eglTestCtx,	"config",	"",	30,	30,	30));

	// Object tests
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer",								"", MultiThreadedObjectTest::TYPE_PBUFFER));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap",								"", MultiThreadedObjectTest::TYPE_PIXMAP));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"window",								"", MultiThreadedObjectTest::TYPE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"single_window",						"", MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"context",								"", MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap",						"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_window",						"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_single_window",				"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_context",						"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap_window",						"", MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap_single_window",					"", MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap_context",						"", MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"window_context",						"", MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"single_window_context",				"", MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap_window",				"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap_single_window",			"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap_context",				"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_window_context",				"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_single_window_context",		"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap_window_context",				"", MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pixmap_single_window_context",			"", MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));

	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap_window_context",		"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));
	addChild(new MultiThreadedObjectTest(m_eglTestCtx,	"pbuffer_pixmap_single_window_context",	"", MultiThreadedObjectTest::TYPE_PBUFFER|MultiThreadedObjectTest::TYPE_PIXMAP|MultiThreadedObjectTest::TYPE_WINDOW|MultiThreadedObjectTest::TYPE_SINGLE_WINDOW|MultiThreadedObjectTest::TYPE_CONTEXT));
}

} // egl
} // deqp
