/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.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 GLSL ES 1.0 gl_FragData[] tests.
 *//*--------------------------------------------------------------------*/

#include "es3fShaderFragDataTests.hpp"

#include "glsShaderLibrary.hpp"

#include "gluRenderContext.hpp"
#include "gluShaderProgram.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluObjectWrapper.hpp"

#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"

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

namespace deqp
{
namespace gles3
{
namespace Functional
{

using std::string;
using tcu::TestLog;

namespace
{

enum IndexExprType
{
	INDEX_EXPR_STATIC	= 0,
	INDEX_EXPR_UNIFORM,
	INDEX_EXPR_DYNAMIC,

	INDEX_EXPR_TYPE_LAST
};

static bool isExtensionSupported (const glu::RenderContext& renderCtx, const std::string& extension)
{
	const glw::Functions&	gl		= renderCtx.getFunctions();
	int						numExts	= 0;

	gl.getIntegerv(GL_NUM_EXTENSIONS, &numExts);

	for (int ndx = 0; ndx < numExts; ndx++)
	{
		const char* curExt = (const char*)gl.getStringi(GL_EXTENSIONS, ndx);

		if (extension == curExt)
			return true;
	}

	return false;
}

static bool compareSingleColor (tcu::TestLog& log, const tcu::Surface& surface, tcu::RGBA expectedColor, tcu::RGBA threshold)
{
	const int	maxPrints			= 10;
	int			numFailedPixels		= 0;

	log << TestLog::Message << "Expecting " << expectedColor << " with threshold " << threshold << TestLog::EndMessage;

	for (int y = 0; y < surface.getHeight(); y++)
	{
		for (int x = 0; x < surface.getWidth(); x++)
		{
			const tcu::RGBA		resultColor		= surface.getPixel(x, y);
			const bool			isOk			= compareThreshold(resultColor, expectedColor, threshold);

			if (!isOk)
			{
				if (numFailedPixels < maxPrints)
					log << TestLog::Message << "ERROR: Got " << resultColor << " at (" << x << ", " << y << ")!" << TestLog::EndMessage;
				else if (numFailedPixels == maxPrints)
					log << TestLog::Message << "..." << TestLog::EndMessage;

				numFailedPixels += 1;
			}
		}
	}

	if (numFailedPixels > 0)
	{
		log << TestLog::Message << "Found " << numFailedPixels << " invalid pixels, comparison FAILED!" << TestLog::EndMessage;
		log << TestLog::Image("ResultImage", "Result Image", surface);
		return false;
	}
	else
	{
		log << TestLog::Message << "Image comparison passed." << TestLog::EndMessage;
		return true;
	}
}

class FragDataIndexingCase : public TestCase
{
public:
	FragDataIndexingCase (Context& context, const char* name, const char* description, IndexExprType indexExprType)
		: TestCase			(context, name, description)
		, m_indexExprType	(indexExprType)
	{
	}

	static glu::ProgramSources genSources (const IndexExprType indexExprType)
	{
		const char* const	fragIndexExpr	= indexExprType == INDEX_EXPR_STATIC	? "0"				:
											  indexExprType == INDEX_EXPR_UNIFORM	? "u_index"			:
											  indexExprType == INDEX_EXPR_DYNAMIC	? "int(v_index)"	: DE_NULL;
		glu::ProgramSources	sources;

		DE_ASSERT(fragIndexExpr);

		sources << glu::VertexSource(
			"attribute highp vec4 a_position;\n"
			"attribute highp float a_index;\n"
			"attribute highp vec4 a_color;\n"
			"varying mediump float v_index;\n"
			"varying mediump vec4 v_color;\n"
			"void main (void)\n"
			"{\n"
			"	gl_Position = a_position;\n"
			"	v_color = a_color;\n"
			"	v_index = a_index;\n"
			"}\n");

		sources << glu::FragmentSource(string(
			"varying mediump vec4 v_color;\n"
			"varying mediump float v_index;\n"
			"uniform mediump int u_index;\n"
			"void main (void)\n"
			"{\n"
			"	gl_FragData[") + fragIndexExpr + "] = v_color;\n"
			"}\n");

		return sources;
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&		renderCtx		= m_context.getRenderContext();
		const glw::Functions&			gl				= renderCtx.getFunctions();
		const glu::ShaderProgram		program			(renderCtx, genSources(m_indexExprType));
		const int						viewportW		= de::min(renderCtx.getRenderTarget().getWidth(), 128);
		const int						viewportH		= de::min(renderCtx.getRenderTarget().getHeight(), 128);

		const float positions[] =
		{
			-1.0f, -1.0f,
			+1.0f, -1.0f,
			-1.0f, +1.0f,
			+1.0f, +1.0f
		};
		const float colors[] =
		{
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f
		};
		const float		indexValues[]	= { 0.0f, 0.0f, 0.0f, 0.0f };
		const deUint8	indices[]		= { 0, 1, 2, 2, 1, 3 };

		const glu::VertexArrayBinding vertexArrays[] =
		{
			glu::va::Float("a_position",	2, 4, 0, &positions[0]),
			glu::va::Float("a_color",		4, 4, 0, &colors[0]),
			glu::va::Float("a_index",		1, 4, 0, &indexValues[0])
		};

		m_testCtx.getLog() << program;

		if (!program.isOk())
		{
			if (m_indexExprType == INDEX_EXPR_STATIC)
				TCU_FAIL("Compile failed");
			else
				throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");
		}

		gl.clearColor	(1.0f, 0.0f, 0.0f, 1.0f);
		gl.clear		(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

		gl.viewport		(0, 0, viewportW, viewportH);
		gl.useProgram	(program.getProgram());
		gl.uniform1i	(gl.getUniformLocation(program.getProgram(), "u_index"), 0);

		glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");

		{
			tcu::Surface		result		(viewportW, viewportH);
			const tcu::RGBA		threshold	= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
			bool				isOk;

			glu::readPixels(renderCtx, 0, 0, result.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");

			isOk = compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold);

			m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									isOk ? "Pass"				: "Image comparison failed");
		}

		return STOP;
	}

private:
	const IndexExprType m_indexExprType;
};

class FragDataDrawBuffersCase : public TestCase
{
public:
	FragDataDrawBuffersCase (Context& context)
		: TestCase(context, "draw_buffers", "gl_FragData[] and glDrawBuffers() interaction")
	{
	}

	IterateResult iterate (void)
	{
		const glu::RenderContext&		renderCtx			= m_context.getRenderContext();

		int								num_test_attachment	= 2;
		if(!isExtensionSupported(renderCtx, "GL_EXT_draw_buffers") && !isExtensionSupported(renderCtx, "GL_NV_draw_buffers"))
			num_test_attachment = 1;

		const glu::ShaderProgram		program			(renderCtx, glu::ProgramSources()
															<< glu::VertexSource(
																"attribute highp vec4 a_position;\n"
																"attribute highp vec4 a_color;\n"
																"varying mediump vec4 v_color;\n"
																"void main (void)\n"
																"{\n"
																"	gl_Position = a_position;\n"
																"	v_color = a_color;\n"
																"}\n")
															<< glu::FragmentSource(
																"varying mediump vec4 v_color;\n"
																"uniform mediump int u_index;\n"
																"void main (void)\n"
																"{\n"
																"	gl_FragData[u_index] = v_color;\n"
																"}\n"));
		const glw::Functions&			gl				= renderCtx.getFunctions();
		const int						width			= 128;
		const int						height			= 128;
		const int						indexLoc		= program.isOk() ? gl.getUniformLocation(program.getProgram(), "u_index") : -1;
		const glu::Framebuffer			fbo				(renderCtx);
		const glu::Renderbuffer			colorBuf0		(renderCtx);
		const glu::Renderbuffer			colorBuf1		(renderCtx);

		const float positions[] =
		{
			-1.0f, -1.0f,
			+1.0f, -1.0f,
			-1.0f, +1.0f,
			+1.0f, +1.0f
		};
		const float colors[] =
		{
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f,
			0.0f, 1.0f, 0.0f, 1.0f
		};
		const deUint8	indices[]		= { 0, 1, 2, 2, 1, 3 };

		const glu::VertexArrayBinding vertexArrays[] =
		{
			glu::va::Float("a_position",	2, 4, 0, &positions[0]),
			glu::va::Float("a_color",		4, 4, 0, &colors[0])
		};

		m_testCtx.getLog() << program;

		if (!program.isOk())
			throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");

		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
		for (int ndx = 0; ndx < num_test_attachment; ndx++)
		{
			const deUint32	rbo	= ndx == 0 ? *colorBuf0 : *colorBuf1;

			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
			gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+ndx, GL_RENDERBUFFER, rbo);
		}
		TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);

		{
			const deUint32 drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
			gl.drawBuffers(DE_LENGTH_OF_ARRAY(drawBuffers), &drawBuffers[0]);
		}

		gl.viewport		(0, 0, width, height);
		gl.useProgram	(program.getProgram());

		GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");

		bool			allOk		= true;
		const tcu::RGBA threshold	= renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);

		for (int ndx = 0; ndx < num_test_attachment; ndx++)
		{
			gl.clearBufferfv(GL_COLOR, 0, tcu::RGBA::red().toVec().getPtr());
			gl.clearBufferfv(GL_COLOR, 1, tcu::RGBA::red().toVec().getPtr());

			m_testCtx.getLog() << TestLog::Message << "Drawing to attachments " << ndx << TestLog::EndMessage;

			gl.uniform1i(indexLoc, ndx);
			glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
					  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));

			GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");

			{
				tcu::Surface result(width, height);

				m_testCtx.getLog() << TestLog::Message << "Verifying attachment " << ndx << "..." << TestLog::EndMessage;

				gl.readBuffer(GL_COLOR_ATTACHMENT0+ndx);
				glu::readPixels(renderCtx, 0, 0, result.getAccess());
				GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");

				if (!compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold))
					allOk = false;
			}
		}

		m_testCtx.setTestResult(allOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								allOk ? "Pass"				: "Image comparison failed");

		return STOP;
	}
};

} // anonymous

ShaderFragDataTests::ShaderFragDataTests (Context& context)
	: TestCaseGroup(context, "fragdata", "gl_FragData[] Tests")
{
}

ShaderFragDataTests::~ShaderFragDataTests (void)
{
}

void ShaderFragDataTests::init (void)
{
	addChild(new FragDataIndexingCase		(m_context, "valid_static_index",	"Valid gl_FragData[] assignment using static index",	INDEX_EXPR_STATIC));
	addChild(new FragDataIndexingCase		(m_context, "valid_uniform_index",	"Valid gl_FragData[] assignment using uniform index",	INDEX_EXPR_UNIFORM));
	addChild(new FragDataIndexingCase		(m_context, "valid_dynamic_index",	"Valid gl_FragData[] assignment using dynamic index",	INDEX_EXPR_DYNAMIC));
	addChild(new FragDataDrawBuffersCase	(m_context));

	// Negative cases.
	{
		gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
		std::vector<tcu::TestNode*> negativeCases = library.loadShaderFile("shaders/fragdata.test");

		for (std::vector<tcu::TestNode*>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++)
			addChild(*i);
	}
}

} // Functional
} // gles3
} // deqp
