/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 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 Default vertex attribute test
 *//*--------------------------------------------------------------------*/

#include "es2fDefaultVertexAttributeTests.hpp"
#include "tcuVector.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTextureUtil.hpp"
#include "gluRenderContext.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluShaderProgram.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deString.h"

#include <limits>

namespace deqp
{
namespace gles2
{
namespace Functional
{
namespace
{

static const int s_valueRange = 10;

static const char* const s_passThroughFragmentShaderSource =	"varying mediump vec4 v_color;\n"
																"void main (void)\n"
																"{\n"
																"	gl_FragColor = v_color;\n"
																"}\n";

template <typename T1, int S1, typename T2, int S2>
tcu::Vector<T1, S1> convertToTypeVec (const tcu::Vector<T2, S2>& v)
{
	tcu::Vector<T1, S1> retVal;

	for (int ndx = 0; ndx < S1; ++ndx)
		retVal[ndx] = T1(0);

	if (S1 == 4)
		retVal[3] = T1(1);

	for (int ndx = 0; ndx < de::min(S1, S2); ++ndx)
		retVal[ndx] = T1(v[ndx]);

	return retVal;
}

class FloatLoader
{
public:
	virtual				~FloatLoader	(void) {};

	// returns the value loaded
	virtual tcu::Vec4	load			(glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const = 0;
};

#define GEN_DIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME, VALUES)				\
	class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader						\
	{																					\
	public:																				\
		enum																			\
		{																				\
			NORMALIZING = 0,															\
		};																				\
		enum																			\
		{																				\
			COMPONENTS = (COMPS)														\
		};																				\
		typedef TYPE Type;																\
																						\
		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
		{																				\
			tcu::Vector<TYPE, COMPONENTS> value;										\
			value = convertToTypeVec<Type, COMPONENTS>(v);								\
																						\
			gl.glVertexAttrib ##COMPS ##TYPECODE VALUES;								\
			return convertToTypeVec<float, 4>(value);									\
		}																				\
																						\
		static const char* getCaseName (void)											\
		{																				\
			return CASENAME;															\
		}																				\
																						\
		static const char* getName (void)												\
		{																				\
			return "VertexAttrib" #COMPS #TYPECODE;										\
		}																				\
	}

#define GEN_INDIRECT_FLOAT_LOADER(TYPE, COMPS, TYPECODE, CASENAME)						\
	class LoaderVertexAttrib##COMPS##TYPECODE : public FloatLoader						\
	{																					\
	public:																				\
		enum																			\
		{																				\
			NORMALIZING = 0,															\
		};																				\
		enum																			\
		{																				\
			COMPONENTS = (COMPS)														\
		};																				\
		typedef TYPE Type;																\
																						\
		tcu::Vec4 load (glu::CallLogWrapper& gl, int index, const tcu::Vec4& v) const	\
		{																				\
			tcu::Vector<TYPE, COMPONENTS> value;										\
			value = convertToTypeVec<Type, COMPONENTS>(v);								\
																						\
			gl.glVertexAttrib ##COMPS ##TYPECODE (index, value.getPtr());				\
			return convertToTypeVec<float, 4>(value);									\
		}																				\
																						\
		static const char* getCaseName (void)											\
		{																				\
			return CASENAME;															\
		}																				\
																						\
		static const char* getName (void)												\
		{																				\
			return "VertexAttrib" #COMPS #TYPECODE;										\
		}																				\
	}

GEN_DIRECT_FLOAT_LOADER(float, 1, f, "vertex_attrib_1f", (index, value.x()));
GEN_DIRECT_FLOAT_LOADER(float, 2, f, "vertex_attrib_2f", (index, value.x(), value.y()));
GEN_DIRECT_FLOAT_LOADER(float, 3, f, "vertex_attrib_3f", (index, value.x(), value.y(), value.z()));
GEN_DIRECT_FLOAT_LOADER(float, 4, f, "vertex_attrib_4f", (index, value.x(), value.y(), value.z(), value.w()));

GEN_INDIRECT_FLOAT_LOADER(float, 1, fv, "vertex_attrib_1fv");
GEN_INDIRECT_FLOAT_LOADER(float, 2, fv, "vertex_attrib_2fv");
GEN_INDIRECT_FLOAT_LOADER(float, 3, fv, "vertex_attrib_3fv");
GEN_INDIRECT_FLOAT_LOADER(float, 4, fv, "vertex_attrib_4fv");

class AttributeCase : public TestCase
{
									AttributeCase			(Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType);
public:
	template<typename LoaderType>
	static AttributeCase*			create					(Context& ctx, glu::DataType dataType);
									~AttributeCase			(void);

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

	glu::DataType					getTargetType			(void) const;
	std::string						genVertexSource			(void) const;
	bool							renderWithValue			(const tcu::Vec4& v);
	tcu::Vec4						computeColor			(const tcu::Vec4& value);
	bool							verifyUnicoloredBuffer	(const tcu::Surface& scene, const tcu::Vec4& refValue);

	const bool						m_normalizing;
	const bool						m_useNegativeValues;
	const char* const				m_funcName;
	const glu::DataType				m_dataType;
	const FloatLoader*				m_loader;
	glu::ShaderProgram*				m_program;
	deUint32						m_bufID;
	bool							m_allIterationsPassed;
	int								m_iteration;

	enum
	{
		RENDER_SIZE = 32
	};
};

AttributeCase::AttributeCase (Context& ctx, const char* name, const char* desc, const char* funcName, bool normalizing, bool useNegative, glu::DataType dataType)
	: TestCase				(ctx, name, desc)
	, m_normalizing			(normalizing)
	, m_useNegativeValues	(useNegative)
	, m_funcName			(funcName)
	, m_dataType			(dataType)
	, m_loader				(DE_NULL)
	, m_program				(DE_NULL)
	, m_bufID				(0)
	, m_allIterationsPassed	(true)
	, m_iteration			(0)
{
}

template<typename LoaderType>
AttributeCase* AttributeCase::create (Context& ctx, glu::DataType dataType)
{
	AttributeCase* retVal = new AttributeCase(ctx,
											  LoaderType::getCaseName(),
											  (std::string("Test ") + LoaderType::getName()).c_str(),
											  LoaderType::getName(),
											  LoaderType::NORMALIZING != 0,
											  std::numeric_limits<typename LoaderType::Type>::is_signed,
											  dataType);
	retVal->m_loader = new LoaderType();
	return retVal;
}

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

void AttributeCase::init (void)
{
	if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || m_context.getRenderTarget().getHeight() < RENDER_SIZE)
		throw tcu::NotSupportedError("Render target must be at least " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE));

	// log test info

	{
		const float			maxRange		= (m_normalizing) ? (1.0f) : (s_valueRange);
		const float			minRange		= (m_useNegativeValues) ? (-maxRange) : (0.0f);

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "Loading attribute values using " << m_funcName << "\n"
			<< "Attribute type: " << glu::getDataTypeName(m_dataType) << "\n"
			<< "Attribute value range: [" << minRange << ", " << maxRange << "]"
			<< tcu::TestLog::EndMessage;
	}

	// gen shader and base quad

	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource()) << glu::FragmentSource(s_passThroughFragmentShaderSource));
	m_testCtx.getLog() << *m_program;
	if (!m_program->isOk())
		throw tcu::TestError("could not build program");

	{
		const tcu::Vec4 fullscreenQuad[] =
		{
			tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
			tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
			tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
			tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
		};

		const glw::Functions& gl = m_context.getRenderContext().getFunctions();

		gl.genBuffers(1, &m_bufID);
		gl.bindBuffer(GL_ARRAY_BUFFER, m_bufID);
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(fullscreenQuad), fullscreenQuad, GL_STATIC_DRAW);
		GLU_EXPECT_NO_ERROR(gl.getError(), "fill buffer");
	}
}

void AttributeCase::deinit (void)
{
	delete m_loader;
	m_loader = DE_NULL;

	delete m_program;
	m_program = DE_NULL;

	if (m_bufID)
	{
		m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_bufID);
		m_bufID = 0;
	}
}

AttributeCase::IterateResult AttributeCase::iterate (void)
{
	static const tcu::Vec4 testValues[] =
	{
		tcu::Vec4(0.0f, 0.5f, 0.2f, 1.0f),
		tcu::Vec4(0.1f, 0.7f, 1.0f, 0.6f),
		tcu::Vec4(0.4f, 0.2f, 0.0f, 0.5f),
		tcu::Vec4(0.5f, 0.0f, 0.9f, 0.1f),
		tcu::Vec4(0.6f, 0.2f, 0.2f, 0.9f),
		tcu::Vec4(0.9f, 1.0f, 0.0f, 0.0f),
		tcu::Vec4(1.0f, 0.5f, 0.3f, 0.8f),
	};

	const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", "Iteration " + de::toString(m_iteration+1) + "/" + de::toString(DE_LENGTH_OF_ARRAY(testValues)));

	// Test normalizing transfers with whole range, non-normalizing with up to s_valueRange
	const tcu::Vec4 testValue = ((m_useNegativeValues) ? (testValues[m_iteration] * 2.0f - tcu::Vec4(1.0f)) : (testValues[m_iteration])) * ((m_normalizing) ? (1.0f) : ((float)s_valueRange));

	if (!renderWithValue(testValue))
		m_allIterationsPassed = false;

	// continue

	if (++m_iteration < DE_LENGTH_OF_ARRAY(testValues))
		return CONTINUE;

	if (m_allIterationsPassed)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected values");

	return STOP;
}

std::string AttributeCase::genVertexSource (void) const
{
	const int			vectorSize	= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeScalarSize(m_dataType)) : (-1);
	const char* const	vectorType	= glu::getDataTypeName((glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::isDataTypeVector(m_dataType)) ? (glu::getDataTypeVector(glu::TYPE_FLOAT, vectorSize)) : (glu::TYPE_FLOAT));
	const int			components	= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));
	std::ostringstream	buf;

	buf <<	"attribute highp vec4 a_position;\n"
			"attribute highp " << glu::getDataTypeName(m_dataType) << " a_value;\n"
			"varying highp vec4 v_color;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"\n";

	if (m_normalizing)
		buf << "	highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ");\n";
	else
		buf << "	highp " << vectorType << " normalizedValue = " << ((glu::getDataTypeScalarType(m_dataType) == glu::TYPE_FLOAT) ? ("") : (vectorType)) << "(a_value" << ((glu::isDataTypeMatrix(m_dataType)) ? ("[1]") : ("")) << ") / float(" << s_valueRange << ");\n";

	if (m_useNegativeValues)
		buf << "	highp " << vectorType << " positiveNormalizedValue = (normalizedValue + " << vectorType << "(1.0)) / 2.0;\n";
	else
		buf << "	highp " << vectorType << " positiveNormalizedValue = normalizedValue;\n";

	if (components == 1)
		buf << "	v_color = vec4(positiveNormalizedValue, 0.0, 0.0, 1.0);\n";
	else if (components == 2)
		buf << "	v_color = vec4(positiveNormalizedValue.xy, 0.0, 1.0);\n";
	else if (components == 3)
		buf << "	v_color = vec4(positiveNormalizedValue.xyz, 1.0);\n";
	else if (components == 4)
		buf << "	v_color = vec4((positiveNormalizedValue.xy + positiveNormalizedValue.zz) / 2.0, positiveNormalizedValue.w, 1.0);\n";
	else
		DE_ASSERT(DE_FALSE);

	buf << "}\n";

	return buf.str();
}

bool AttributeCase::renderWithValue (const tcu::Vec4& v)
{
	glu::CallLogWrapper	gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	gl.enableLogging(true);

	const int			positionIndex	= gl.glGetAttribLocation(m_program->getProgram(), "a_position");
	const int			valueIndex		= gl.glGetAttribLocation(m_program->getProgram(), "a_value");
	tcu::Surface		dest			(RENDER_SIZE, RENDER_SIZE);
	tcu::Vec4			loadedValue;

	gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	gl.glClear(GL_COLOR_BUFFER_BIT);
	gl.glViewport(0, 0, RENDER_SIZE, RENDER_SIZE);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup");

	gl.glBindBuffer(GL_ARRAY_BUFFER, m_bufID);
	gl.glVertexAttribPointer(positionIndex, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.glEnableVertexAttribArray(positionIndex);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "position va");

	// transfer test value. Load to the second column in the matrix case
	loadedValue = m_loader->load(gl, (glu::isDataTypeMatrix(m_dataType)) ? (valueIndex + 1) : (valueIndex), v);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "default va");

	gl.glUseProgram(m_program->getProgram());
	gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	gl.glUseProgram(0);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "draw");

	glu::readPixels(m_context.getRenderContext(), 0, 0, dest.getAccess());

	// check whole result is colored correctly
	return verifyUnicoloredBuffer(dest, computeColor(loadedValue));
}

tcu::Vec4 AttributeCase::computeColor (const tcu::Vec4& value)
{
	const tcu::Vec4 normalizedValue			= value / ((m_normalizing) ? (1.0f) : ((float)s_valueRange));
	const tcu::Vec4 positiveNormalizedValue = ((m_useNegativeValues) ? ((normalizedValue + tcu::Vec4(1.0f)) / 2.0f) : (normalizedValue));
	const int		components				= (glu::isDataTypeMatrix(m_dataType)) ? (glu::getDataTypeMatrixNumRows(m_dataType)) : (glu::getDataTypeScalarSize(m_dataType));

	if (components == 1)
		return tcu::Vec4(positiveNormalizedValue.x(), 0.0f, 0.0f, 1.0f);
	else if (components == 2)
		return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), 0.0f, 1.0f);
	else if (components == 3)
		return tcu::Vec4(positiveNormalizedValue.x(), positiveNormalizedValue.y(), positiveNormalizedValue.z(), 1.0f);
	else if (components == 4)
		return tcu::Vec4((positiveNormalizedValue.x() + positiveNormalizedValue.z()) / 2.0f, (positiveNormalizedValue.y() + positiveNormalizedValue.z()) / 2.0f, positiveNormalizedValue.w(), 1.0f);
	else
		DE_ASSERT(DE_FALSE);

	return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
}

bool AttributeCase::verifyUnicoloredBuffer (const tcu::Surface& scene, const tcu::Vec4& refValue)
{
	tcu::Surface	errorMask		(RENDER_SIZE, RENDER_SIZE);
	const tcu::RGBA	refColor		(refValue);
	const int		resultThreshold	= 2;
	const tcu::RGBA	colorThreshold	= m_context.getRenderTarget().getPixelFormat().getColorThreshold() * resultThreshold;
	bool			error			= false;

	tcu::RGBA		exampleColor;
	tcu::IVec2		examplePos;

	tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toIVec());

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying rendered image. Expecting color " << refColor << ", threshold " << colorThreshold << tcu::TestLog::EndMessage;

	for (int y = 0; y < RENDER_SIZE; ++y)
	for (int x = 0; x < RENDER_SIZE; ++x)
	{
		const tcu::RGBA color = scene.getPixel(x, y);

		if (de::abs(color.getRed()   - refColor.getRed())   > colorThreshold.getRed()   ||
			de::abs(color.getGreen() - refColor.getGreen()) > colorThreshold.getGreen() ||
			de::abs(color.getBlue()  - refColor.getBlue())  > colorThreshold.getBlue())
		{
			// first error
			if (!error)
			{
				exampleColor = color;
				examplePos = tcu::IVec2(x, y);
			}

			error = true;
			errorMask.setPixel(x, y, tcu::RGBA::red());
		}
	}

	if (!error)
		m_testCtx.getLog() << tcu::TestLog::Message << "Rendered image is valid." << tcu::TestLog::EndMessage;
	else
	{
		m_testCtx.getLog()	<< tcu::TestLog::Message
							<< "Found invalid pixel(s).\n"
							<< "Pixel at (" << examplePos.x() << ", " << examplePos.y() << ") color: " << exampleColor
							<< tcu::TestLog::EndMessage
							<< tcu::TestLog::ImageSet("Result", "Render result")
							<< tcu::TestLog::Image("Result", "Result", scene)
							<< tcu::TestLog::Image("ErrorMask", "Error Mask", errorMask)
							<< tcu::TestLog::EndImageSet;
	}

	return !error;
}

} // anonymous

DefaultVertexAttributeTests::DefaultVertexAttributeTests (Context& context)
	: TestCaseGroup(context, "default_vertex_attrib", "Test default vertex attributes")
{
}

DefaultVertexAttributeTests::~DefaultVertexAttributeTests (void)
{
}

void DefaultVertexAttributeTests::init (void)
{
	struct Target
	{
		const char*		name;
		glu::DataType	dataType;
		bool			reducedTestSets;	// !< use reduced coverage
	};

	static const Target floatTargets[] =
	{
		{ "float",	glu::TYPE_FLOAT,		false	},
		{ "vec2",	glu::TYPE_FLOAT_VEC2,	true	},
		{ "vec3",	glu::TYPE_FLOAT_VEC3,	true	},
		{ "vec4",	glu::TYPE_FLOAT_VEC4,	false	},
		{ "mat2",	glu::TYPE_FLOAT_MAT2,	true	},
		{ "mat3",	glu::TYPE_FLOAT_MAT3,	true	},
		{ "mat4",	glu::TYPE_FLOAT_MAT4,	false	},
	};

	// float targets

	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(floatTargets); ++targetNdx)
	{
		tcu::TestCaseGroup* const	group	= new tcu::TestCaseGroup(m_testCtx, floatTargets[targetNdx].name, (std::string("test with ") + floatTargets[targetNdx].name).c_str());
		const bool					fullSet	= !floatTargets[targetNdx].reducedTestSets;

#define ADD_CASE(X) group->addChild(AttributeCase::create<X>(m_context, floatTargets[targetNdx].dataType))
#define ADD_REDUCED_CASE(X)	if (fullSet) ADD_CASE(X)

		ADD_CASE		(LoaderVertexAttrib1f);
		ADD_REDUCED_CASE(LoaderVertexAttrib2f);
		ADD_REDUCED_CASE(LoaderVertexAttrib3f);
		ADD_CASE		(LoaderVertexAttrib4f);

		ADD_CASE		(LoaderVertexAttrib1fv);
		ADD_REDUCED_CASE(LoaderVertexAttrib2fv);
		ADD_REDUCED_CASE(LoaderVertexAttrib3fv);
		ADD_CASE		(LoaderVertexAttrib4fv);

#undef ADD_CASE
#undef ADD_REDUCED_CASE

		addChild(group);
	}
}

} // Functional
} // gles2
} // deqp
