/*-------------------------------------------------------------------------
 * 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 eglMakeCurrent performance tests.
 *//*--------------------------------------------------------------------*/

#include "teglMakeCurrentPerfTests.hpp"

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

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

#include "tcuTestLog.hpp"

#include "deRandom.hpp"
#include "deStringUtil.hpp"

#include "deClock.h"
#include "deString.h"

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

using std::ostringstream;
using std::string;
using std::vector;

using tcu::TestLog;

using namespace eglw;

namespace deqp
{
namespace egl
{

class MakeCurrentPerfCase : public TestCase
{
public:
	enum SurfaceType
	{
		SURFACETYPE_PBUFFER	= (1<<0),
		SURFACETYPE_WINDOW	= (1<<1),
		SURFACETYPE_PIXMAP	= (1<<2)
	};

	struct Spec
	{
		SurfaceType	surfaceTypes;
		int			contextCount;
		int			surfaceCount;

		bool		release;

		int			iterationCount;
		int			sampleCount;

		string		toName			(void) const;
		string		toDescription	(void) const;
	};
					MakeCurrentPerfCase		(EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description);
					~MakeCurrentPerfCase	(void);

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

private:
	Spec						m_spec;
	de::Random					m_rnd;

	EGLDisplay					m_display;
	EGLConfig					m_config;
	vector<EGLContext>			m_contexts;
	vector<EGLSurface>			m_surfaces;

	vector<eglu::NativeWindow*>	m_windows;
	vector<eglu::NativePixmap*>	m_pixmaps;

	vector<deUint64>			m_samples;

	void					chooseConfig	(void);
	void					createSurfaces	(void);
	void					createContexts	(void);

	void					destroySurfaces	(void);
	void					destroyContexts	(void);

	void					createPBuffer	(void);
	void					createWindow	(void);
	void					createPixmap	(void);

	void					logTestInfo		(void);
	void					logResults		(void);
	// Disabled
							MakeCurrentPerfCase	(const MakeCurrentPerfCase&);
	MakeCurrentPerfCase&	operator=			(const MakeCurrentPerfCase&);
};

string MakeCurrentPerfCase::Spec::toName (void) const
{
	ostringstream name;

	name << "context";

	if (contextCount > 1)
		name << "s_" << contextCount;

	if ((surfaceTypes & SURFACETYPE_WINDOW) != 0)
		name << "_window" << (surfaceCount > 1 ? "s" : "");

	if ((surfaceTypes & SURFACETYPE_PIXMAP) != 0)
		name << "_pixmap" << (surfaceCount > 1 ? "s" : "");

	if ((surfaceTypes & SURFACETYPE_PBUFFER) != 0)
		name << "_pbuffer" << (surfaceCount > 1 ? "s" : "");

	if (surfaceCount > 1)
		name << "_" << surfaceCount;

	if (release)
		name << "_release";

	return name.str();
}

string MakeCurrentPerfCase::Spec::toDescription (void) const
{
	// \todo [mika] Generate descrpition
	return toName();
}

MakeCurrentPerfCase::MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description)
	: TestCase		(eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_spec		(spec)
	, m_rnd			(deStringHash(name))
	, m_display		(EGL_NO_DISPLAY)
	, m_config		(DE_NULL)
{
}

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

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

	chooseConfig();
	createContexts();
	createSurfaces();
}

void MakeCurrentPerfCase::deinit (void)
{
	destroyContexts();
	destroySurfaces();

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

void MakeCurrentPerfCase::chooseConfig (void)
{
	const EGLint	surfaceBits	= ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0 ? EGL_WINDOW_BIT : 0)
									| ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0 ? EGL_PIXMAP_BIT : 0)
									| ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0 ? EGL_PBUFFER_BIT : 0);

	const EGLint	attribList[] = {
		EGL_SURFACE_TYPE,		surfaceBits,
		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
		EGL_NONE
	};

	const Library&	egl			= m_eglTestCtx.getLibrary();
	EGLint			configCount = 0;

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

	if (configCount <= 0)
		throw tcu::NotSupportedError("No compatible configs found");
}

void MakeCurrentPerfCase::createSurfaces (void)
{
	vector<SurfaceType> types;

	if ((m_spec.surfaceTypes & SURFACETYPE_WINDOW) != 0)
		types.push_back(SURFACETYPE_WINDOW);

	if ((m_spec.surfaceTypes & SURFACETYPE_PIXMAP) != 0)
		types.push_back(SURFACETYPE_PIXMAP);

	if ((m_spec.surfaceTypes & SURFACETYPE_PBUFFER) != 0)
		types.push_back(SURFACETYPE_PBUFFER);

	DE_ASSERT((int)types.size() <= m_spec.surfaceCount);

	// Create surfaces
	for (int surfaceNdx = 0; surfaceNdx < m_spec.surfaceCount; surfaceNdx++)
	{
		SurfaceType type = types[surfaceNdx % types.size()];

		switch (type)
		{
			case SURFACETYPE_PBUFFER:
				createPBuffer();
				break;

			case SURFACETYPE_WINDOW:
				createWindow();
				break;

			case SURFACETYPE_PIXMAP:
				createPixmap();
				break;

			default:
				DE_ASSERT(false);
		};
	}
}

void MakeCurrentPerfCase::createPBuffer (void)
{
	const Library&	egl		= m_eglTestCtx.getLibrary();
	const EGLint	width	= 256;
	const EGLint	height	= 256;

	const EGLint attribList[] = {
		EGL_WIDTH,	width,
		EGL_HEIGHT, height,
		EGL_NONE
	};

	EGLSurface	surface = egl.createPbufferSurface(m_display, m_config, attribList);

	EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");

	m_surfaces.push_back(surface);
}

void MakeCurrentPerfCase::createWindow (void)
{
	const Library&						egl				= m_eglTestCtx.getLibrary();
	const EGLint						width			= 256;
	const EGLint						height			= 256;

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

	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(width, height, eglu::parseWindowVisibility(m_eglTestCtx.getTestContext().getCommandLine())));
		surface	= eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, m_config, DE_NULL);
	}
	catch (...)
	{
		if (surface != EGL_NO_SURFACE)
			egl.destroySurface(m_display, surface);

		delete window;
		throw;
	}

	m_windows.push_back(window);
	m_surfaces.push_back(surface);
}

void MakeCurrentPerfCase::createPixmap (void)
{
	const Library&						egl				= m_eglTestCtx.getLibrary();
	const EGLint						width			= 256;
	const EGLint						height			= 256;

	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, width, height);
		surface	= eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, m_config, DE_NULL);
	}
	catch (...)
	{
		if (surface != EGL_NO_SURFACE)
			egl.destroySurface(m_display, surface);

		delete pixmap;
		throw;
	}

	m_pixmaps.push_back(pixmap);
	m_surfaces.push_back(surface);
}

void MakeCurrentPerfCase::destroySurfaces (void)
{
	const Library&	egl	= m_eglTestCtx.getLibrary();

	if (m_surfaces.size() > 0)
	{
		EGLDisplay display = m_display;

		// Destroy surfaces
		for (vector<EGLSurface>::iterator iter = m_surfaces.begin(); iter != m_surfaces.end(); ++iter)
		{
			if (*iter != EGL_NO_SURFACE)
				EGLU_CHECK_CALL(egl, destroySurface(display, *iter));
			*iter = EGL_NO_SURFACE;
		}

		m_surfaces.clear();

		// Destroy pixmaps
		for (vector<eglu::NativePixmap*>::iterator iter = m_pixmaps.begin(); iter != m_pixmaps.end(); ++iter)
		{
			delete *iter;
			*iter = NULL;
		}

		m_pixmaps.clear();

		// Destroy windows
		for (vector<eglu::NativeWindow*>::iterator iter = m_windows.begin(); iter != m_windows.end(); ++iter)
		{
			delete *iter;
			*iter = NULL;
		}

		m_windows.clear();

		// Clear all surface handles
		m_surfaces.clear();
	}
}

void MakeCurrentPerfCase::createContexts (void)
{
	const Library&	egl	= m_eglTestCtx.getLibrary();

	for (int contextNdx = 0; contextNdx < m_spec.contextCount; contextNdx++)
	{
		const EGLint attribList[] = {
			EGL_CONTEXT_CLIENT_VERSION, 2,
			EGL_NONE
		};

		EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
		EGLContext context = egl.createContext(m_display, m_config, EGL_NO_CONTEXT, attribList);
		EGLU_CHECK_MSG(egl, "eglCreateContext()");

		m_contexts.push_back(context);
	}
}

void MakeCurrentPerfCase::destroyContexts (void)
{
	const Library&	egl	= m_eglTestCtx.getLibrary();
	if (m_contexts.size() > 0)
	{
		EGLDisplay display = m_display;

		for (vector<EGLContext>::iterator iter = m_contexts.begin(); iter != m_contexts.end(); ++iter)
		{
			if (*iter != EGL_NO_CONTEXT)
				EGLU_CHECK_CALL(egl, destroyContext(display, *iter));
			*iter = EGL_NO_CONTEXT;
		}

		m_contexts.clear();
	}
}

void MakeCurrentPerfCase::logTestInfo (void)
{
	TestLog& log = m_testCtx.getLog();

	{
		tcu::ScopedLogSection	section(log, "Test Info", "Test case information.");

		log << TestLog::Message << "Context count: "	<< m_contexts.size()											<< TestLog::EndMessage;
		log << TestLog::Message << "Surfaces count: "	<< m_surfaces.size()											<< TestLog::EndMessage;
		log << TestLog::Message << "Sample count: "	<< m_spec.sampleCount												<< TestLog::EndMessage;
		log << TestLog::Message << "Iteration count: "	<< m_spec.iterationCount										<< TestLog::EndMessage;
		log << TestLog::Message << "Window count: "	<< m_windows.size()													<< TestLog::EndMessage;
		log << TestLog::Message << "Pixmap count: "	<< m_pixmaps.size()													<< TestLog::EndMessage;
		log << TestLog::Message << "PBuffer count: "	<< (m_surfaces.size() - m_windows.size() - m_pixmaps.size())	<< TestLog::EndMessage;

		if (m_spec.release)
			log << TestLog::Message << "Context is released after each use. Both binding and releasing context are included in result time." << TestLog::EndMessage;
	}
}

void MakeCurrentPerfCase::logResults (void)
{
	TestLog& log = m_testCtx.getLog();

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

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

	log << TestLog::EndSampleList;

	// Log stats
	{
		deUint64	totalTimeUs				= 0;
		deUint64	totalIterationCount		= 0;

		float		iterationTimeMeanUs		= 0.0f;
		float		iterationTimeMedianUs	= 0.0f;
		float		iterationTimeVarianceUs	= 0.0f;
		float		iterationTimeSkewnessUs	= 0.0f;
		float		iterationTimeMinUs		= std::numeric_limits<float>::max();
		float		iterationTimeMaxUs		= 0.0f;

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

		// Calculate totals
		for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++)
		{
			totalTimeUs			+= m_samples[sampleNdx];
			totalIterationCount	+= m_spec.iterationCount;
		}

		// Calculate mean and median
		iterationTimeMeanUs		= ((float)(((double)totalTimeUs) / totalIterationCount));
		iterationTimeMedianUs	= ((float)(((double)m_samples[m_samples.size() / 2]) / m_spec.iterationCount));

		// Calculate variance
		for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++)
		{
			float iterationTimeUs	= (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount);
			iterationTimeVarianceUs	+= std::pow(iterationTimeUs - iterationTimeMedianUs, 2.0f);
		}

		// Calculate min and max
		for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++)
		{
			float iterationTimeUs	= (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount);
			iterationTimeMinUs		= std::min<float>(iterationTimeMinUs, iterationTimeUs);
			iterationTimeMaxUs		= std::max<float>(iterationTimeMaxUs, iterationTimeUs);
		}

		iterationTimeVarianceUs /= m_samples.size();

		// Calculate skewness
		for (int sampleNdx = 0; sampleNdx < (int)m_samples.size(); sampleNdx++)
		{
			float iterationTimeUs	= (float)(((double)m_samples[sampleNdx]) / m_spec.iterationCount);
			iterationTimeSkewnessUs	= std::pow((iterationTimeUs - iterationTimeMedianUs) / iterationTimeVarianceUs, 2.0f);
		}

		iterationTimeSkewnessUs /= (float)m_samples.size();

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

			log << TestLog::Message << "Total time: "	<< totalTimeUs				<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Mean: "			<< iterationTimeMeanUs		<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Median: "		<< iterationTimeMedianUs	<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Variance: "		<< iterationTimeVarianceUs	<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Skewness: "		<< iterationTimeSkewnessUs	<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Min: "			<< iterationTimeMinUs		<< "us" << TestLog::EndMessage;
			log << TestLog::Message << "Max: "			<< iterationTimeMaxUs		<< "us" << TestLog::EndMessage;
		}

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)(((double)totalTimeUs)/totalIterationCount), 2).c_str());
	}
}

TestCase::IterateResult MakeCurrentPerfCase::iterate (void)
{
	const Library&	egl	= m_eglTestCtx.getLibrary();
	if (m_samples.size() == 0)
		logTestInfo();

	{
		EGLDisplay	display		= m_display;
		deUint64	beginTimeUs	= deGetMicroseconds();

		for (int iteration = 0; iteration < m_spec.iterationCount; iteration++)
		{
			EGLContext	context = m_contexts[m_rnd.getUint32() % m_contexts.size()];
			EGLSurface	surface	= m_surfaces[m_rnd.getUint32() % m_surfaces.size()];

			egl.makeCurrent(display, surface, surface, context);

			if (m_spec.release)
				egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
		}

		m_samples.push_back(deGetMicroseconds() - beginTimeUs);

		egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
		EGLU_CHECK_MSG(egl, "eglMakeCurrent()");
	}

	if ((int)m_samples.size() == m_spec.sampleCount)
	{
		logResults();
		return STOP;
	}
	else
		return CONTINUE;
}

MakeCurrentPerfTests::MakeCurrentPerfTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "make_current", "eglMakeCurrent performance tests")
{
}

void MakeCurrentPerfTests::init (void)
{
	const int iterationCount	= 100;
	const int sampleCount		= 100;

	// Add simple test group
	{
		TestCaseGroup* simple = new TestCaseGroup(m_eglTestCtx, "simple", "Simple eglMakeCurrent performance tests using single context and surface");

		const MakeCurrentPerfCase::SurfaceType types[] = {
			MakeCurrentPerfCase::SURFACETYPE_PBUFFER,
			MakeCurrentPerfCase::SURFACETYPE_PIXMAP,
			MakeCurrentPerfCase::SURFACETYPE_WINDOW
		};

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++)
		{
			for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++)
			{
				MakeCurrentPerfCase::Spec spec;

				spec.surfaceTypes	= types[typeNdx];
				spec.contextCount	= 1;
				spec.surfaceCount	= 1;
				spec.release		= (releaseNdx == 1);
				spec.iterationCount	= iterationCount;
				spec.sampleCount	= sampleCount;

				simple->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str()));
			}
		}

		addChild(simple);
	}

	// Add multi context test group
	{
		TestCaseGroup* multiContext = new TestCaseGroup(m_eglTestCtx, "multi_context", "eglMakeCurrent performance tests using multiple contexts and single surface");

		const MakeCurrentPerfCase::SurfaceType types[] = {
			MakeCurrentPerfCase::SURFACETYPE_PBUFFER,
			MakeCurrentPerfCase::SURFACETYPE_PIXMAP,
			MakeCurrentPerfCase::SURFACETYPE_WINDOW
		};

		const int contextCounts[] = {
			10, 100
		};

		for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++)
		{
			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++)
			{
				for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++)
				{
					MakeCurrentPerfCase::Spec spec;

					spec.surfaceTypes	= types[typeNdx];
					spec.contextCount	= contextCounts[contextCountNdx];
					spec.surfaceCount	= 1;
					spec.release		= (releaseNdx == 1);
					spec.iterationCount	= iterationCount;
					spec.sampleCount	= sampleCount;

					multiContext->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str()));
				}
			}
		}

		addChild(multiContext);
	}

	// Add multi surface test group
	{
		TestCaseGroup* multiSurface = new TestCaseGroup(m_eglTestCtx, "multi_surface", "eglMakeCurrent performance tests using single context and multiple surfaces");

		const MakeCurrentPerfCase::SurfaceType types[] = {
			MakeCurrentPerfCase::SURFACETYPE_PBUFFER,
			MakeCurrentPerfCase::SURFACETYPE_PIXMAP,
			MakeCurrentPerfCase::SURFACETYPE_WINDOW,

			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER	|MakeCurrentPerfCase::SURFACETYPE_PIXMAP),
			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER	|MakeCurrentPerfCase::SURFACETYPE_WINDOW),
			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP	|MakeCurrentPerfCase::SURFACETYPE_WINDOW),

			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW)
		};

		const int surfaceCounts[] = {
			10, 100
		};

		for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++)
		{
			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++)
			{
				for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++)
				{
					MakeCurrentPerfCase::Spec spec;

					spec.surfaceTypes	= types[typeNdx];
					spec.surfaceCount	= surfaceCounts[surfaceCountNdx];
					spec.contextCount	= 1;
					spec.release		= (releaseNdx == 1);
					spec.iterationCount	= iterationCount;
					spec.sampleCount	= sampleCount;

					multiSurface->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str()));
				}
			}
		}

		addChild(multiSurface);
	}

	// Add Complex? test group
	{
		TestCaseGroup* multi = new TestCaseGroup(m_eglTestCtx, "complex", "eglMakeCurrent performance tests using multiple contexts and multiple surfaces");

		const MakeCurrentPerfCase::SurfaceType types[] = {
			MakeCurrentPerfCase::SURFACETYPE_PBUFFER,
			MakeCurrentPerfCase::SURFACETYPE_PIXMAP,
			MakeCurrentPerfCase::SURFACETYPE_WINDOW,

			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER	|MakeCurrentPerfCase::SURFACETYPE_PIXMAP),
			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER	|MakeCurrentPerfCase::SURFACETYPE_WINDOW),
			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PIXMAP	|MakeCurrentPerfCase::SURFACETYPE_WINDOW),

			(MakeCurrentPerfCase::SurfaceType)(MakeCurrentPerfCase::SURFACETYPE_PBUFFER|MakeCurrentPerfCase::SURFACETYPE_PIXMAP|MakeCurrentPerfCase::SURFACETYPE_WINDOW)
		};

		const int surfaceCounts[] = {
			10, 100
		};


		const int contextCounts[] = {
			10, 100
		};

		for (int surfaceCountNdx = 0; surfaceCountNdx < DE_LENGTH_OF_ARRAY(surfaceCounts); surfaceCountNdx++)
		{
			for (int contextCountNdx = 0; contextCountNdx < DE_LENGTH_OF_ARRAY(contextCounts); contextCountNdx++)
			{
				for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); typeNdx++)
				{
					for (int releaseNdx = 0; releaseNdx < 2; releaseNdx++)
					{
						MakeCurrentPerfCase::Spec spec;

						spec.surfaceTypes	= types[typeNdx];
						spec.contextCount	= contextCounts[contextCountNdx];
						spec.surfaceCount	= surfaceCounts[surfaceCountNdx];
						spec.release		= (releaseNdx == 1);
						spec.iterationCount	= iterationCount;
						spec.sampleCount	= sampleCount;

						multi->addChild(new MakeCurrentPerfCase(m_eglTestCtx, spec, spec.toName().c_str(), spec.toDescription().c_str()));
					}
				}
			}
		}

		addChild(multi);
	}
}

} // egl
} // deqp
