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

#include "es3fStencilTests.hpp"

#include "tcuSurface.hpp"
#include "tcuVector.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"

#include "sglrContextUtil.hpp"
#include "sglrGLContext.hpp"
#include "sglrReferenceContext.hpp"

#include "deRandom.hpp"
#include "deMath.h"
#include "deString.h"

#include <vector>

#include "glwEnums.hpp"
#include "glwDefs.hpp"

using tcu::Vec3;
using tcu::IVec2;
using tcu::IVec4;
using std::vector;
using namespace glw;

namespace deqp
{
namespace gles3
{
namespace Functional
{

class StencilShader : public sglr::ShaderProgram
{
public:
	StencilShader (void)
		: sglr::ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
									<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
									<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
									<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
									<< sglr::pdec::Uniform("u_color", glu::TYPE_FLOAT_VEC4)
									<< sglr::pdec::VertexSource("#version 300 es\n"
																"in highp vec4 a_position;\n"
																"void main (void)\n"
																"{\n"
																"	gl_Position = a_position;\n"
																"}\n")
									<< sglr::pdec::FragmentSource("#version 300 es\n"
																  "uniform highp vec4 u_color;\n"
																  "layout(location = 0) out mediump vec4 o_color;\n"
																  "void main (void)\n"
																  "{\n"
																  "	o_color = u_color;\n"
																  "}\n"))
		, u_color	(getUniformByName("u_color"))
	{
	}

	void setColor (sglr::Context& ctx, deUint32 program, const tcu::Vec4& color)
	{
		ctx.useProgram(program);
		ctx.uniform4fv(ctx.getUniformLocation(program, "u_color"), 1, color.getPtr());
	}

private:
	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			rr::VertexPacket& packet = *packets[packetNdx];

			packet.position = rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
		}
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		const tcu::Vec4 color(u_color.value.f4);

		DE_UNREF(packets);

		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
	}

	const sglr::UniformSlot& u_color;
};

class StencilOp
{
public:
	enum Type
	{
		TYPE_CLEAR_STENCIL = 0,
		TYPE_CLEAR_DEPTH,
		TYPE_QUAD,

		TYPE_LAST
	};

	Type		type;
	GLenum		stencilTest;
	int			stencil;	//!< Ref for quad op, clear value for clears
	deUint32	stencilMask;
	GLenum		depthTest;
	float		depth;		//!< Quad depth or clear value
	GLenum		sFail;
	GLenum		dFail;
	GLenum		dPass;

	StencilOp (Type type_, GLenum stencilTest_ = GL_ALWAYS, int stencil_ = 0, GLenum depthTest_ = GL_ALWAYS, float depth_ = 1.0f, GLenum sFail_ = GL_KEEP, GLenum dFail_ = GL_KEEP, GLenum dPass_ = GL_KEEP)
		: type			(type_)
		, stencilTest	(stencilTest_)
		, stencil		(stencil_)
		, stencilMask	(0xffffffffu)
		, depthTest		(depthTest_)
		, depth			(depth_)
		, sFail			(sFail_)
		, dFail			(dFail_)
		, dPass			(dPass_)
	{
	}

	static StencilOp clearStencil (int stencil)
	{
		StencilOp op(TYPE_CLEAR_STENCIL);
		op.stencil = stencil;
		return op;
	}

	static StencilOp clearDepth (float depth)
	{
		StencilOp op(TYPE_CLEAR_DEPTH);
		op.depth = depth;
		return op;
	}

	static StencilOp quad (GLenum stencilTest, int stencil, GLenum depthTest, float depth, GLenum sFail, GLenum dFail, GLenum dPass)
	{
		return StencilOp(TYPE_QUAD, stencilTest, stencil, depthTest, depth, sFail, dFail, dPass);
	}
};

class StencilCase : public TestCase
{
public:
						StencilCase			(Context& context, const char* name, const char* description);
	virtual				~StencilCase		(void);

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

	virtual void		genOps				(vector<StencilOp>& dst, int stencilBits, int depthBits, int targetStencil) = DE_NULL;

private:
	void				executeOps			(sglr::Context& context, const IVec4& cell, const vector<StencilOp>& ops);
	void				visualizeStencil	(sglr::Context& context, int stencilBits, int stencilStep);

	StencilShader		m_shader;
	deUint32			m_shaderID;
};

StencilCase::StencilCase (Context& context, const char* name, const char* description)
	: TestCase		(context, name, description)
	, m_shaderID	(0)
{
}

StencilCase::~StencilCase (void)
{
}

void StencilCase::init (void)
{
}

void StencilCase::deinit (void)
{
}

void StencilCase::executeOps (sglr::Context& context, const IVec4& cell, const vector<StencilOp>& ops)
{
	// For quadOps
	float x0 = 2.0f*((float)cell.x() / (float)context.getWidth())-1.0f;
	float y0 = 2.0f*((float)cell.y() / (float)context.getHeight())-1.0f;
	float x1 = x0 + 2.0f*((float)cell.z() / (float)context.getWidth());
	float y1 = y0 + 2.0f*((float)cell.w() / (float)context.getHeight());

	m_shader.setColor(context, m_shaderID, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	for (vector<StencilOp>::const_iterator i = ops.begin(); i != ops.end(); i++)
	{
		const StencilOp& op = *i;

		switch (op.type)
		{
			case StencilOp::TYPE_CLEAR_DEPTH:
				context.enable(GL_SCISSOR_TEST);
				context.scissor(cell.x(), cell.y(), cell.z(), cell.w());
				context.clearDepthf(op.depth);
				context.clear(GL_DEPTH_BUFFER_BIT);
				context.disable(GL_SCISSOR_TEST);
				break;

			case StencilOp::TYPE_CLEAR_STENCIL:
				context.enable(GL_SCISSOR_TEST);
				context.scissor(cell.x(), cell.y(), cell.z(), cell.w());
				context.clearStencil(op.stencil);
				context.clear(GL_STENCIL_BUFFER_BIT);
				context.disable(GL_SCISSOR_TEST);
				break;

			case StencilOp::TYPE_QUAD:
				context.enable(GL_DEPTH_TEST);
				context.enable(GL_STENCIL_TEST);
				context.depthFunc(op.depthTest);
				context.stencilFunc(op.stencilTest, op.stencil, op.stencilMask);
				context.stencilOp(op.sFail, op.dFail, op.dPass);
				sglr::drawQuad(context, m_shaderID, Vec3(x0, y0, op.depth), Vec3(x1, y1, op.depth));
				context.disable(GL_STENCIL_TEST);
				context.disable(GL_DEPTH_TEST);
				break;

			default:
				DE_ASSERT(DE_FALSE);
		}
	}
}

void StencilCase::visualizeStencil (sglr::Context& context, int stencilBits, int stencilStep)
{
	int endVal				= 1<<stencilBits;
	int numStencilValues	= endVal/stencilStep + 1;

	context.enable(GL_STENCIL_TEST);
	context.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	for (int ndx = 0; ndx < numStencilValues; ndx++)
	{
		int			value		= deMin32(ndx*stencilStep, endVal-1);
		float		colorMix	= (float)value/(float)de::max(1, endVal-1);
		tcu::Vec4	color		(0.0f, 1.0f-colorMix, colorMix, 1.0f);

		m_shader.setColor(context, m_shaderID, color);
		context.stencilFunc(GL_EQUAL, value, 0xffffffffu);
		sglr::drawQuad(context, m_shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
	}
}

TestCase::IterateResult StencilCase::iterate (void)
{
	const tcu::RenderTarget&	renderTarget		= m_context.getRenderContext().getRenderTarget();
	int							depthBits			= renderTarget.getDepthBits();
	int							stencilBits			= renderTarget.getStencilBits();

	int							stencilStep			= stencilBits == 8 ? 8 : 1;
	int							numStencilValues	= (1<<stencilBits)/stencilStep + 1;

	int							gridSize			= (int)deFloatCeil(deFloatSqrt((float)(numStencilValues+2)));

	int							width				= deMin32(128, renderTarget.getWidth());
	int							height				= deMin32(128, renderTarget.getHeight());

	tcu::TestLog&				log					= m_testCtx.getLog();
	de::Random					rnd					(deStringHash(m_name.c_str()));
	int							viewportX			= rnd.getInt(0, renderTarget.getWidth()-width);
	int							viewportY			= rnd.getInt(0, renderTarget.getHeight()-height);
	IVec4						viewport			= IVec4(viewportX, viewportY, width, height);

	tcu::Surface				gles2Frame			(width, height);
	tcu::Surface				refFrame			(width, height);
	GLenum						gles2Error;

	const char*					failReason			= DE_NULL;

	// Get ops for stencil values
	vector<vector<StencilOp> >	ops(numStencilValues+2);
	{
		// Values from 0 to max
		for (int ndx = 0; ndx < numStencilValues; ndx++)
			genOps(ops[ndx], stencilBits, depthBits, deMin32(ndx*stencilStep, (1<<stencilBits)-1));

		// -1 and max+1
		genOps(ops[numStencilValues+0], stencilBits, depthBits, 1<<stencilBits);
		genOps(ops[numStencilValues+1], stencilBits, depthBits, -1);
	}

	// Compute cells: (x, y, w, h)
	vector<IVec4>				cells;
	int							cellWidth			= width/gridSize;
	int							cellHeight			= height/gridSize;
	for (int y = 0; y < gridSize; y++)
	for (int x = 0; x < gridSize; x++)
		cells.push_back(IVec4(x*cellWidth, y*cellHeight, cellWidth, cellHeight));

	DE_ASSERT(ops.size() <= cells.size());

	// Execute for gles3 context
	{
		sglr::GLContext context(m_context.getRenderContext(), log, 0 /* don't log calls or program */, viewport);

		m_shaderID = context.createProgram(&m_shader);

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

		for (int ndx = 0; ndx < (int)ops.size(); ndx++)
			executeOps(context, cells[ndx], ops[ndx]);

		visualizeStencil(context, stencilBits, stencilStep);

		gles2Error = context.getError();
		context.readPixels(gles2Frame, 0, 0, width, height);
	}

	// Execute for reference context
	{
		sglr::ReferenceContextBuffers	buffers	(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
		sglr::ReferenceContext			context	(sglr::ReferenceContextLimits(m_context.getRenderContext()), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());

		m_shaderID = context.createProgram(&m_shader);

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

		for (int ndx = 0; ndx < (int)ops.size(); ndx++)
			executeOps(context, cells[ndx], ops[ndx]);

		visualizeStencil(context, stencilBits, stencilStep);

		context.readPixels(refFrame, 0, 0, width, height);
	}

	// Check error
	bool errorCodeOk = (gles2Error == GL_NO_ERROR);
	if (!errorCodeOk && !failReason)
		failReason = "Got unexpected error";

	// Compare images
	const float		threshold	= 0.02f;
	bool			imagesOk	= tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, gles2Frame, threshold, tcu::COMPARE_LOG_RESULT);

	if (!imagesOk && !failReason)
		failReason = "Image comparison failed";

	// Store test result
	bool isOk = errorCodeOk && imagesOk;
	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: failReason);

	return STOP;
}

StencilTests::StencilTests (Context& context)
	: TestCaseGroup(context, "stencil", "Stencil Tests")
{
}

StencilTests::~StencilTests (void)
{
}

typedef void (*GenStencilOpsFunc) (vector<StencilOp>& dst, int stencilBits, int depthBits, int targetStencil);

class SimpleStencilCase : public StencilCase
{
public:
	SimpleStencilCase (Context& context, const char* name, const char* description, GenStencilOpsFunc genOpsFunc)
		: StencilCase	(context, name, description)
		, m_genOps		(genOpsFunc)
	{
	}

	void genOps (vector<StencilOp>& dst, int stencilBits, int depthBits, int targetStencil)
	{
		m_genOps(dst, stencilBits, depthBits, targetStencil);
	}

private:
	GenStencilOpsFunc	m_genOps;
};

void StencilTests::init (void)
{
#define STENCIL_CASE(NAME, DESCRIPTION, GEN_OPS_BODY)														\
	do {																									\
		struct Gen_##NAME {																					\
			static void genOps (vector<StencilOp>& dst, int stencilBits, int depthBits, int targetStencil)	\
			{																								\
				DE_UNREF(stencilBits && depthBits);															\
				GEN_OPS_BODY																				\
			}																								\
		};																									\
		addChild(new SimpleStencilCase(m_context, #NAME, DESCRIPTION, Gen_##NAME::genOps));					\
	} while (deGetFalse());

	STENCIL_CASE(clear, "Stencil clear",
		{
			// \note Unused bits are set to 1, clear should mask them out
			int mask = (1<<stencilBits)-1;
			dst.push_back(StencilOp::clearStencil(targetStencil | ~mask));
		});

	// Replace in different points
	STENCIL_CASE(stencil_fail_replace, "Set stencil on stencil fail",
		{
			dst.push_back(StencilOp::quad(GL_NEVER, targetStencil, GL_ALWAYS, 0.0f, GL_REPLACE, GL_KEEP, GL_KEEP));
		});
	STENCIL_CASE(depth_fail_replace, "Set stencil on depth fail",
		{
			dst.push_back(StencilOp::clearDepth(0.0f));
			dst.push_back(StencilOp::quad(GL_ALWAYS, targetStencil, GL_LESS, 0.5f, GL_KEEP, GL_REPLACE, GL_KEEP));
		});
	STENCIL_CASE(depth_pass_replace, "Set stencil on depth pass",
		{
			dst.push_back(StencilOp::quad(GL_ALWAYS, targetStencil, GL_LESS, 0.0f, GL_KEEP, GL_KEEP, GL_REPLACE));
		});

	// Increment, decrement
	STENCIL_CASE(incr_stencil_fail, "Increment on stencil fail",
		{
			if (targetStencil > 0)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil-1));
				dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_INCR, GL_KEEP, GL_KEEP));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(decr_stencil_fail, "Decrement on stencil fail",
		{
			int maxStencil = (1<<stencilBits)-1;
			if (targetStencil < maxStencil)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil+1));
				dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_DECR, GL_KEEP, GL_KEEP));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(incr_wrap_stencil_fail, "Increment (wrap) on stencil fail",
		{
			int maxStencil = (1<<stencilBits)-1;
			dst.push_back(StencilOp::clearStencil((targetStencil-1)&maxStencil));
			dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_INCR_WRAP, GL_KEEP, GL_KEEP));
		});
	STENCIL_CASE(decr_wrap_stencil_fail, "Decrement (wrap) on stencil fail",
		{
			int maxStencil = (1<<stencilBits)-1;
			dst.push_back(StencilOp::clearStencil((targetStencil+1)&maxStencil));
			dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_DECR_WRAP, GL_KEEP, GL_KEEP));
		});

	// Zero, Invert
	STENCIL_CASE(zero_stencil_fail, "Zero on stencil fail",
		{
			dst.push_back(StencilOp::clearStencil(targetStencil));
			dst.push_back(StencilOp::quad(GL_NOTEQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_ZERO, GL_KEEP, GL_KEEP));
			dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_REPLACE, GL_KEEP, GL_KEEP));
		});
	STENCIL_CASE(invert_stencil_fail, "Invert on stencil fail",
		{
			int mask = (1<<stencilBits)-1;
			dst.push_back(StencilOp::clearStencil((~targetStencil)&mask));
			dst.push_back(StencilOp::quad(GL_EQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_INVERT, GL_KEEP, GL_KEEP));
		});

	// Comparison modes
	STENCIL_CASE(cmp_equal, "Equality comparison",
		{
			int mask = (1<<stencilBits)-1;
			int inv  = (~targetStencil)&mask;
			dst.push_back(StencilOp::clearStencil(inv));
			dst.push_back(StencilOp::quad(GL_EQUAL, inv, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INVERT));
			dst.push_back(StencilOp::quad(GL_EQUAL, inv, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INVERT));
		});
	STENCIL_CASE(cmp_not_equal, "Equality comparison",
		{
			int mask = (1<<stencilBits)-1;
			int inv  = (~targetStencil)&mask;
			dst.push_back(StencilOp::clearStencil(inv));
			dst.push_back(StencilOp::quad(GL_NOTEQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INVERT));
			dst.push_back(StencilOp::quad(GL_NOTEQUAL, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INVERT));
		});
	STENCIL_CASE(cmp_less_than, "Less than comparison",
		{
			int maxStencil = (1<<stencilBits)-1;
			if (targetStencil < maxStencil)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil+1));
				dst.push_back(StencilOp::quad(GL_LESS, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_DECR));
				dst.push_back(StencilOp::quad(GL_LESS, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_DECR));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(cmp_less_or_equal, "Less or equal comparison",
		{
			int maxStencil = (1<<stencilBits)-1;
			if (targetStencil < maxStencil)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil+1));
				dst.push_back(StencilOp::quad(GL_LEQUAL, targetStencil+1, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_DECR));
				dst.push_back(StencilOp::quad(GL_LEQUAL, targetStencil+1, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_DECR));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(cmp_greater_than, "Greater than comparison",
		{
			if (targetStencil > 0)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil-1));
				dst.push_back(StencilOp::quad(GL_GREATER, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INCR));
				dst.push_back(StencilOp::quad(GL_GREATER, targetStencil, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INCR));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(cmp_greater_or_equal, "Greater or equal comparison",
		{
			if (targetStencil > 0)
			{
				dst.push_back(StencilOp::clearStencil(targetStencil-1));
				dst.push_back(StencilOp::quad(GL_GEQUAL, targetStencil-1, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INCR));
				dst.push_back(StencilOp::quad(GL_GEQUAL, targetStencil-1, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INCR));
			}
			else
				dst.push_back(StencilOp::clearStencil(targetStencil));
		});
	STENCIL_CASE(cmp_mask_equal, "Equality comparison with mask",
		{
			int valMask = (1<<stencilBits)-1;
			int mask	= (1<<7)|(1<<5)|(1<<3)|(1<<1);
			dst.push_back(StencilOp::clearStencil(~targetStencil));
			StencilOp op = StencilOp::quad(GL_EQUAL, (~targetStencil | ~mask) & valMask, GL_ALWAYS, 0.0f, GL_KEEP, GL_KEEP, GL_INVERT);
			op.stencilMask = mask;
			dst.push_back(op);
		});
}

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