/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) 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 State change performance tests.
 *//*--------------------------------------------------------------------*/

#include "glsStateChangePerfTestCases.hpp"

#include "tcuTestLog.hpp"

#include "gluDefs.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"

#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "deStringUtil.hpp"

#include "deClock.h"

#include <vector>
#include <algorithm>

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

namespace deqp
{
namespace gls
{

namespace
{

struct ResultStats
{
	double		median;
	double 		mean;
	double		variance;

	deUint64	min;
	deUint64	max;
};

ResultStats calculateStats (const vector<deUint64>& values)
{
	ResultStats result = { 0.0, 0.0, 0.0, 0xFFFFFFFFFFFFFFFFu, 0 };

	deUint64 sum = 0;

	for (int i = 0; i < (int)values.size(); i++)
		sum += values[i];

	result.mean = ((double)sum) / values.size();

	for (int i = 0; i < (int)values.size(); i++)
	{
		const double val = (double)values[i];
		result.variance += (val - result.mean) * (val - result.mean);
	}

	result.variance /= values.size();

	{
		const int n = (int)(values.size()/2);

		vector<deUint64> sortedValues = values;

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

		result.median = (double)sortedValues[n];
	}

	for (int i = 0; i < (int)values.size(); i++)
	{
		result.min = std::min(result.min, values[i]);
		result.max = std::max(result.max, values[i]);
	}

	return result;
}


void genIndices (vector<GLushort>& indices, int triangleCount)
{
	indices.reserve(triangleCount*3);

	for (int triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++)
	{
		indices.push_back((GLushort)triangleNdx*3);
		indices.push_back((GLushort)triangleNdx*3+1);
		indices.push_back((GLushort)triangleNdx*3+2);
	}
}

void genCoords (vector<GLfloat>& coords, int triangleCount)
{
	coords.reserve(triangleCount * 3 * 2);

	for (int triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++)
	{
		if ((triangleNdx % 2) == 0)
		{
			// CW
			coords.push_back(-1.0f);
			coords.push_back(-1.0f);

			coords.push_back( 1.0f);
			coords.push_back(-1.0f);

			coords.push_back( 1.0f);
			coords.push_back( 1.0f);
		}
		else
		{
			// CCW
			coords.push_back(-1.0f);
			coords.push_back(-1.0f);

			coords.push_back(-1.0f);
			coords.push_back( 1.0f);

			coords.push_back( 1.0f);
			coords.push_back( 1.0f);
		}
	}
}

void genTextureData (vector<deUint8>& data, int width, int height)
{
	data.clear();
	data.reserve(width*height*4);

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			data.push_back((deUint8)((255*x)/width));
			data.push_back((deUint8)((255*y)/width));
			data.push_back((deUint8)((255*x*y)/(width*height)));
			data.push_back(255);
		}
	}
}

double calculateVariance (const vector<deUint64>& values, double avg)
{
	double sum = 0.0;

	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
	{
		double value = (double)values[valueNdx];
		sum += (value - avg) * (value - avg);
	}

	return sum / values.size();
}

deUint64 findMin (const vector<deUint64>& values)
{
	deUint64 min = ~0ull;

	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
		min = std::min(values[valueNdx], min);

	return min;
}

deUint64 findMax (const vector<deUint64>& values)
{
	deUint64 max = 0;

	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
		max = std::max(values[valueNdx], max);

	return max;
}

deUint64 findMedian (const vector<deUint64>& v)
{
	vector<deUint64> values = v;
	size_t n = values.size() / 2;

	std::nth_element(values.begin(), values.begin() + n, values.end());

	return values[n];
}

} // anonymous

StateChangePerformanceCase::StateChangePerformanceCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, DrawType drawType, int drawCallCount, int triangleCount)
	: tcu::TestCase		(testCtx, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_renderCtx		(renderCtx)
	, m_drawType		(drawType)
	, m_iterationCount	(100)
	, m_callCount		(drawCallCount)
	, m_triangleCount	(triangleCount)
{
}

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

void StateChangePerformanceCase::init (void)
{
	if (m_drawType == DRAWTYPE_INDEXED_USER_PTR)
		genIndices(m_indices, m_triangleCount);
}

void StateChangePerformanceCase::requireIndexBuffers (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_indexBuffers.size() >= count)
		return;

	m_indexBuffers.reserve(count);

	vector<GLushort> indices;
	genIndices(indices, m_triangleCount);

	while ((int)m_indexBuffers.size() < count)
	{
		GLuint buffer;

		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, (GLsizeiptr)(indices.size() * sizeof(GLushort)), &(indices[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()");

		m_indexBuffers.push_back(buffer);
	}
}

void StateChangePerformanceCase::requireCoordBuffers (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_coordBuffers.size() >= count)
		return;

	m_coordBuffers.reserve(count);

	vector<GLfloat> coords;
	genCoords(coords, m_triangleCount);

	while ((int)m_coordBuffers.size() < count)
	{
		GLuint buffer;

		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, (GLsizeiptr)(coords.size() * sizeof(GLfloat)), &(coords[0]), GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData()");
		gl.bindBuffer(GL_ARRAY_BUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");

		m_coordBuffers.push_back(buffer);
	}
}

void StateChangePerformanceCase::requirePrograms (int count)
{
	if ((int)m_programs.size() >= count)
		return;

	m_programs.reserve(count);

	while ((int)m_programs.size() < count)
	{
		string vertexShaderSource =
			"attribute mediump vec2 a_coord;\n"
			"varying mediump vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tv_texCoord = vec2(0.5) + 0.5" + de::toString(m_programs.size()) + " * a_coord.xy;\n"
			"\tgl_Position = vec4(a_coord, 0.5, 1.0);\n"
			"}";

		string fragmentShaderSource =
			"uniform sampler2D u_sampler;\n"
			"varying mediump vec2 v_texCoord;\n"
			"void main (void)\n"
			"{\n"
			"\tgl_FragColor = vec4(1.0" + de::toString(m_programs.size()) + " * texture2D(u_sampler, v_texCoord).xyz, 1.0);\n"
			"}";

		glu::ShaderProgram* program = new glu::ShaderProgram(m_renderCtx, glu::ProgramSources() << glu::VertexSource(vertexShaderSource) << glu::FragmentSource(fragmentShaderSource));

		if (!program->isOk())
		{
			m_testCtx.getLog() << *program;
			delete program;
			TCU_FAIL("Compile failed");
		}

		m_programs.push_back(program);
	}
}

void StateChangePerformanceCase::requireTextures (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	const int textureWidth	= 64;
	const int textureHeight	= 64;

	if ((int)m_textures.size() >= count)
		return;

	m_textures.reserve(count);

	vector<deUint8> textureData;
	genTextureData(textureData, textureWidth, textureHeight);

	DE_ASSERT(textureData.size() == textureWidth * textureHeight * 4);

	while ((int)m_textures.size() < count)
	{
		GLuint texture;

		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.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(textureData[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D()");

		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri()");
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri()");
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri()");
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri()");

		gl.bindTexture(GL_TEXTURE_2D, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");

		m_textures.push_back(texture);
	}
}

void StateChangePerformanceCase::requireFramebuffers (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_framebuffers.size() >= count)
		return;

	m_framebuffers.reserve(count);

	requireRenderbuffers(count);

	while ((int)m_framebuffers.size() < count)
	{
		GLuint framebuffer;

		gl.genFramebuffers(1, &framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers()");

		gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");

		gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers[m_framebuffers.size()]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer()");

		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffers[m_framebuffers.size()]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer()");

		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer()");

		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");

		m_framebuffers.push_back(framebuffer);
	}
}

void StateChangePerformanceCase::requireRenderbuffers (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_renderbuffers.size() >= count)
		return;

	m_renderbuffers.reserve(count);

	while ((int)m_renderbuffers.size() < count)
	{
		GLuint renderbuffer;

		gl.genRenderbuffers(1, &renderbuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers()");

		gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer()");

		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 24, 24);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage()");

		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer()");

		m_renderbuffers.push_back(renderbuffer);
	}
}

void StateChangePerformanceCase::requireSamplers (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_samplers.size() >= count)
		return;

	m_samplers.reserve(count);

	while ((int)m_samplers.size() < count)
	{
		GLuint sampler;
		gl.genSamplers(1, &sampler);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers()");
		m_samplers.push_back(sampler);
	}
}

void StateChangePerformanceCase::requireVertexArrays (int count)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if ((int)m_vertexArrays.size() >= count)
		return;

	m_vertexArrays.reserve(count);

	while ((int)m_vertexArrays.size() < count)
	{
		GLuint vertexArray;
		gl.genVertexArrays(1, &vertexArray);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays()");
		m_vertexArrays.push_back(vertexArray);
	}
}

void StateChangePerformanceCase::deinit (void)
{
	m_indices.clear();
	m_interleavedResults.clear();
	m_batchedResults.clear();

	{
		const glw::Functions& gl = m_renderCtx.getFunctions();

		if (!m_indexBuffers.empty())
		{
			gl.deleteBuffers((GLsizei)m_indexBuffers.size(), &(m_indexBuffers[0]));
			m_indexBuffers.clear();
		}

		if (!m_coordBuffers.empty())
		{
			gl.deleteBuffers((GLsizei)m_coordBuffers.size(), &(m_coordBuffers[0]));
			m_coordBuffers.clear();
		}

		if (!m_textures.empty())
		{
			gl.deleteTextures((GLsizei)m_textures.size(), &(m_textures[0]));
			m_textures.clear();
		}

		if (!m_framebuffers.empty())
		{
			gl.deleteFramebuffers((GLsizei)m_framebuffers.size(), &(m_framebuffers[0]));
			m_framebuffers.clear();
		}

		if (!m_renderbuffers.empty())
		{
			gl.deleteRenderbuffers((GLsizei)m_renderbuffers.size(), &(m_renderbuffers[0]));
			m_renderbuffers.clear();
		}

		if (!m_samplers.empty())
		{
			gl.deleteSamplers((GLsizei)m_samplers.size(), &m_samplers[0]);
			m_samplers.clear();
		}

		if (!m_vertexArrays.empty())
		{
			gl.deleteVertexArrays((GLsizei)m_vertexArrays.size(), &m_vertexArrays[0]);
			m_vertexArrays.clear();
		}

		for (int programNdx = 0; programNdx < (int)m_programs.size(); programNdx++)
		{
			delete m_programs[programNdx];
			m_programs[programNdx] = NULL;
		}
		m_programs.clear();
	}
}

void StateChangePerformanceCase::logAndSetTestResult (void)
{
	TestLog&	log			= m_testCtx.getLog();

	ResultStats interleaved	= calculateStats(m_interleavedResults);
	ResultStats batched		= calculateStats(m_batchedResults);

	log << TestLog::Message << "Interleaved mean: "					<< interleaved.mean						<< TestLog::EndMessage;
	log << TestLog::Message << "Interleaved median: "				<< interleaved.median					<< TestLog::EndMessage;
	log << TestLog::Message << "Interleaved variance: "				<< interleaved.variance					<< TestLog::EndMessage;
	log << TestLog::Message << "Interleaved min: "					<< interleaved.min						<< TestLog::EndMessage;
	log << TestLog::Message << "Interleaved max: "					<< interleaved.max						<< TestLog::EndMessage;

	log << TestLog::Message << "Batched mean: "						<< batched.mean							<< TestLog::EndMessage;
	log << TestLog::Message << "Batched median: "					<< batched.median						<< TestLog::EndMessage;
	log << TestLog::Message << "Batched variance: "					<< batched.variance						<< TestLog::EndMessage;
	log << TestLog::Message << "Batched min: "						<< batched.min							<< TestLog::EndMessage;
	log << TestLog::Message << "Batched max: "						<< batched.max							<< TestLog::EndMessage;

	log << TestLog::Message << "Batched/Interleaved mean ratio: "	<< (interleaved.mean/batched.mean)		<< TestLog::EndMessage;
	log << TestLog::Message << "Batched/Interleaved median ratio: "	<< (interleaved.median/batched.median)	<< TestLog::EndMessage;

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)(((double)interleaved.median) / batched.median), 2).c_str());
}

tcu::TestCase::IterateResult StateChangePerformanceCase::iterate (void)
{
	if (m_interleavedResults.empty() && m_batchedResults.empty())
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Message << "Draw call count: " << m_callCount << TestLog::EndMessage;
		log << TestLog::Message << "Per call triangle count: " << m_triangleCount << TestLog::EndMessage;
	}

	// \note [mika] Interleave sampling to balance effects of powerstate etc.
	if ((int)m_interleavedResults.size() < m_iterationCount && m_batchedResults.size() >= m_interleavedResults.size())
	{
		const glw::Functions&	gl			= m_renderCtx.getFunctions();
		deUint64				resBeginUs	= 0;
		deUint64				resEndUs	= 0;

		setupInitialState(gl);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");

		// Render result
		resBeginUs = deGetMicroseconds();

		renderTest(gl);

		gl.finish();
		resEndUs = deGetMicroseconds();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");

		m_interleavedResults.push_back(resEndUs - resBeginUs);

		return CONTINUE;
	}
	else if ((int)m_batchedResults.size() < m_iterationCount)
	{
		const glw::Functions&	gl			= m_renderCtx.getFunctions();
		deUint64				refBeginUs	= 0;
		deUint64				refEndUs	= 0;

		setupInitialState(gl);
		gl.finish();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");

		// Render reference
		refBeginUs = deGetMicroseconds();

		renderReference(gl);

		gl.finish();
		refEndUs = deGetMicroseconds();
		GLU_EXPECT_NO_ERROR(gl.getError(), "glFinish()");

		m_batchedResults.push_back(refEndUs - refBeginUs);

		return CONTINUE;
	}
	else
	{
		logAndSetTestResult();
		return STOP;
	}
}

void StateChangePerformanceCase::callDraw (const glw::Functions& gl)
{
	switch (m_drawType)
	{
		case DRAWTYPE_NOT_INDEXED:		gl.drawArrays(GL_TRIANGLES, 0, m_triangleCount * 3);									break;
		case DRAWTYPE_INDEXED_USER_PTR:	gl.drawElements(GL_TRIANGLES, m_triangleCount * 3, GL_UNSIGNED_SHORT, &m_indices[0]);	break;
		case DRAWTYPE_INDEXED_BUFFER:	gl.drawElements(GL_TRIANGLES, m_triangleCount * 3, GL_UNSIGNED_SHORT, NULL);			break;
		default:
			DE_ASSERT(false);
	}
}

// StateChangeCallPerformanceCase

StateChangeCallPerformanceCase::StateChangeCallPerformanceCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
	: tcu::TestCase 	(testCtx, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_renderCtx		(renderCtx)
	, m_iterationCount	(100)
	, m_callCount		(1000)
{
}

StateChangeCallPerformanceCase::~StateChangeCallPerformanceCase (void)
{
}

void StateChangeCallPerformanceCase::executeTest (void)
{
	const glw::Functions&	gl				= m_renderCtx.getFunctions();
	deUint64				beginTimeUs		= 0;
	deUint64				endTimeUs		= 0;

	beginTimeUs = deGetMicroseconds();

	execCalls(gl, (int)m_results.size(), m_callCount);

	endTimeUs = deGetMicroseconds();

	m_results.push_back(endTimeUs - beginTimeUs);
}

void StateChangeCallPerformanceCase::logTestCase (void)
{
	TestLog& log = m_testCtx.getLog();

	log << TestLog::Message << "Iteration count: " << m_iterationCount << TestLog::EndMessage;
	log << TestLog::Message << "Per iteration call count: " << m_callCount << TestLog::EndMessage;
}

double calculateAverage (const vector<deUint64>& values)
{
	deUint64 sum = 0;

	for (int valueNdx = 0; valueNdx < (int)values.size(); valueNdx++)
		sum += values[valueNdx];

	return ((double)sum) / values.size();
}

void StateChangeCallPerformanceCase::logAndSetTestResult (void)
{
	TestLog&	log				= m_testCtx.getLog();

	deUint64	minUs			= findMin(m_results);
	deUint64	maxUs			= findMax(m_results);
	deUint64	medianUs		= findMedian(m_results);
	double		avgIterationUs	= calculateAverage(m_results);
	double		avgCallUs		= avgIterationUs / m_callCount;
	double		varIteration	= calculateVariance(m_results, avgIterationUs);
	double		avgMedianCallUs	= ((double)medianUs)/m_callCount;

	log << TestLog::Message << "Min iteration time: "						<< minUs << "us" << TestLog::EndMessage;
	log << TestLog::Message << "Max iteration time: "						<< maxUs << "us" << TestLog::EndMessage;
	log << TestLog::Message << "Average iteration time: "					<< avgIterationUs << "us" << TestLog::EndMessage;
	log << TestLog::Message << "Iteration variance time: "					<< varIteration << TestLog::EndMessage;
	log << TestLog::Message << "Median iteration time: "					<< medianUs << "us" << TestLog::EndMessage;
	log << TestLog::Message << "Average call time: "						<< avgCallUs << "us" << TestLog::EndMessage;
	log << TestLog::Message << "Average call time for median iteration: "	<< avgMedianCallUs << "us" << TestLog::EndMessage;

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)avgMedianCallUs, 3).c_str());
}

tcu::TestCase::IterateResult StateChangeCallPerformanceCase::iterate (void)
{
	if (m_results.empty())
		logTestCase();

	if ((int)m_results.size() < m_iterationCount)
	{
		executeTest();
		GLU_EXPECT_NO_ERROR(m_renderCtx.getFunctions().getError(), "Unexpected error");
		return CONTINUE;
	}
	else
	{
		logAndSetTestResult();
		return STOP;
	}
}

} // gls
} // deqp
