/*-------------------------------------------------------------------------
 * 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 "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;

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;

	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_config		(DE_NULL)
{
}

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

void MakeCurrentPerfCase::init (void)
{
	chooseConfig();
	createContexts();
	createSurfaces();
}

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

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
	};

	EGLint		configCount = 0;
	EGLDisplay	display	= m_eglTestCtx.getDisplay().getEGLDisplay();

	TCU_CHECK_EGL_CALL(eglChooseConfig(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 EGLint	width	= 256;
	const EGLint	height	= 256;

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

	EGLDisplay	display	= m_eglTestCtx.getDisplay().getEGLDisplay();
	EGLSurface	surface = eglCreatePbufferSurface(display, m_config, attribList);

	TCU_CHECK_EGL_MSG("eglCreatePbufferSurface()");

	m_surfaces.push_back(surface);
}

void MakeCurrentPerfCase::createWindow (void)
{
	const EGLint	width	= 256;
	const EGLint	height	= 256;

	eglu::NativeWindow* window	= DE_NULL;
	EGLSurface			surface	= EGL_NO_SURFACE;

	try
	{
		window	= m_eglTestCtx.createNativeWindow(m_eglTestCtx.getDisplay().getEGLDisplay(), m_config, DE_NULL, width, height, eglu::parseWindowVisibility(m_eglTestCtx.getTestContext().getCommandLine()));
		surface	= eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_eglTestCtx.getDisplay().getEGLDisplay(), m_config, DE_NULL);
	}
	catch (const std::exception&)
	{
		if (surface != EGL_NO_SURFACE)
			TCU_CHECK_EGL_CALL(eglDestroySurface(m_eglTestCtx.getDisplay().getEGLDisplay(), surface));

		delete window;
		throw;
	}

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

void MakeCurrentPerfCase::createPixmap (void)
{
	const EGLint	width	= 256;
	const EGLint	height	= 256;

	eglu::NativePixmap*	pixmap	= DE_NULL;
	EGLSurface			surface	= EGL_NO_SURFACE;

	try
	{
		pixmap	= m_eglTestCtx.createNativePixmap(m_eglTestCtx.getDisplay().getEGLDisplay(), m_config, DE_NULL, width, height);
		surface	= eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_eglTestCtx.getDisplay().getEGLDisplay(), m_config, DE_NULL);
	}
	catch (const std::exception&)
	{
		if (surface != EGL_NO_SURFACE)
			TCU_CHECK_EGL_CALL(eglDestroySurface(m_eglTestCtx.getDisplay().getEGLDisplay(), surface));

		delete pixmap;
		throw;
	}

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

void MakeCurrentPerfCase::destroySurfaces (void)
{
	if (m_surfaces.size() > 0)
	{
		EGLDisplay display = m_eglTestCtx.getDisplay().getEGLDisplay();

		// Destroy surfaces
		for (vector<EGLSurface>::iterator iter = m_surfaces.begin(); iter != m_surfaces.end(); ++iter)
		{
			if (*iter != EGL_NO_SURFACE)
				TCU_CHECK_EGL_CALL(eglDestroySurface(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)
{
	EGLDisplay display = m_eglTestCtx.getDisplay().getEGLDisplay();

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

		TCU_CHECK_EGL_CALL(eglBindAPI(EGL_OPENGL_ES_API));
		EGLContext context = eglCreateContext(display, m_config, EGL_NO_CONTEXT, attribList);
		TCU_CHECK_EGL_MSG("eglCreateContext()");

		m_contexts.push_back(context);
	}
}

void MakeCurrentPerfCase::destroyContexts (void)
{
	if (m_contexts.size() > 0)
	{
		EGLDisplay display = m_eglTestCtx.getDisplay().getEGLDisplay();

		for (vector<EGLContext>::iterator iter = m_contexts.begin(); iter != m_contexts.end(); ++iter)
		{
			if (*iter != EGL_NO_CONTEXT)
				TCU_CHECK_EGL_CALL(eglDestroyContext(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)
{
	if (m_samples.size() == 0)
		logTestInfo();

	{
		EGLDisplay	display		= m_eglTestCtx.getDisplay().getEGLDisplay();
		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()];

			TCU_CHECK_EGL_CALL(eglMakeCurrent(display, surface, surface, context));

			if (m_spec.release)
				TCU_CHECK_EGL_CALL(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
		}

		m_samples.push_back(deGetMicroseconds() - beginTimeUs);
	}

	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
