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

#include "es3fDitheringTests.hpp"
#include "gluRenderContext.hpp"
#include "gluDefs.hpp"
#include "glsFragmentOpUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuRGBA.hpp"
#include "tcuVector.hpp"
#include "tcuPixelFormat.hpp"
#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuCommandLine.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deString.h"
#include "deMath.h"

#include <string>
#include <algorithm>

#include "glw.h"

namespace deqp
{

using tcu::Vec4;
using tcu::IVec4;
using tcu::TestLog;
using gls::FragmentOpUtil::QuadRenderer;
using gls::FragmentOpUtil::Quad;
using tcu::PixelFormat;
using tcu::Surface;
using de::Random;
using std::vector;
using std::string;

namespace gles3
{
namespace Functional
{

static const char* const s_channelNames[4] = { "red", "green", "blue", "alpha" };

static inline IVec4 pixelFormatToIVec4 (const PixelFormat& format)
{
	return IVec4(format.redBits, format.greenBits, format.blueBits, format.alphaBits);
}

template<typename T>
static inline string choiceListStr (const vector<T>& choices)
{
	string result;
	for (int i = 0; i < (int)choices.size(); i++)
	{
		if (i == (int)choices.size()-1)
			result += " or ";
		else if (i > 0)
			result += ", ";
		result += de::toString(choices[i]);
	}
	return result;
}

class DitheringCase : public tcu::TestCase
{
public:
	enum PatternType
	{
		PATTERNTYPE_GRADIENT = 0,
		PATTERNTYPE_UNICOLORED_QUAD,

		PATTERNTYPE_LAST
	};

											DitheringCase				(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, bool isEnabled, PatternType patternType, const tcu::Vec4& color);
											~DitheringCase				(void);

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

	static const char*						getPatternTypeName			(PatternType type);

private:
	bool									checkColor					(const tcu::Vec4& inputClr, const tcu::RGBA& renderedClr, bool logErrors, const bool incTol) const;

	bool									drawAndCheckGradient		(bool isVerticallyIncreasing, const tcu::Vec4& highColor) const;
	bool									drawAndCheckUnicoloredQuad	(const tcu::Vec4& color) const;

	const glu::RenderContext&				m_renderCtx;

	const bool								m_ditheringEnabled;
	const PatternType						m_patternType;
	const tcu::Vec4							m_color;

	const tcu::PixelFormat					m_renderFormat;

	const QuadRenderer*						m_renderer;
	int										m_iteration;
};

const char* DitheringCase::getPatternTypeName (const PatternType type)
{
	switch (type)
	{
		case PATTERNTYPE_GRADIENT:			return "gradient";
		case PATTERNTYPE_UNICOLORED_QUAD:	return "unicolored_quad";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}


DitheringCase::DitheringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* const name, const char* const description, const bool ditheringEnabled, const PatternType patternType, const Vec4& color)
	: TestCase				(testCtx, name, description)
	, m_renderCtx			(renderCtx)
	, m_ditheringEnabled	(ditheringEnabled)
	, m_patternType			(patternType)
	, m_color				(color)
	, m_renderFormat		(renderCtx.getRenderTarget().getPixelFormat())
	, m_renderer			(DE_NULL)
	, m_iteration			(0)
{
}

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

void DitheringCase::init (void)
{
	DE_ASSERT(!m_renderer);
	m_renderer = new QuadRenderer(m_renderCtx, glu::GLSL_VERSION_300_ES);
	m_iteration = 0;
}

void DitheringCase::deinit (void)
{
	delete m_renderer;
	m_renderer = DE_NULL;
}

bool DitheringCase::checkColor (const Vec4& inputClr, const tcu::RGBA& renderedClr, const bool logErrors, const bool incTol) const
{
	const IVec4		channelBits		= pixelFormatToIVec4(m_renderFormat);
	bool			allChannelsOk	= true;

	for (int chanNdx = 0; chanNdx < 4; chanNdx++)
	{
		if (channelBits[chanNdx] == 0)
			continue;

		const int		channelMax			= (1 << channelBits[chanNdx]) - 1;
		const float		scaledInput			= inputClr[chanNdx] * (float)channelMax;
		const bool		useRoundingMargin	= deFloatAbs(scaledInput - deFloatRound(scaledInput)) < 0.0001f;
		vector<int>		channelChoices;

		channelChoices.push_back(de::min(channelMax,	(int)deFloatCeil(scaledInput)));
		channelChoices.push_back(de::max(0,				(int)deFloatCeil(scaledInput) - 1));
		// Allow for more tolerance for small dimension render targets
		if (incTol)
		{
			channelChoices.push_back(de::max(0,(int)deFloatCeil(scaledInput) - 2));
			channelChoices.push_back(de::max(0,(int)deFloatCeil(scaledInput) + 1));
		}

		// If the input color results in a scaled value that is very close to an integer, account for a little bit of possible inaccuracy.
		if (useRoundingMargin)
		{
			if (scaledInput > deFloatRound(scaledInput))
				channelChoices.push_back((int)deFloatCeil(scaledInput) - 2);
			else
				channelChoices.push_back((int)deFloatCeil(scaledInput) + 1);
		}

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

		{
			const int		renderedClrInFormat	= (int)deFloatRound((float)(renderedClr.toIVec()[chanNdx] * channelMax) / 255.0f);
			bool			goodChannel			= false;

			for (int i = 0; i < (int)channelChoices.size(); i++)
			{
				if (renderedClrInFormat == channelChoices[i])
				{
					goodChannel = true;
					break;
				}
			}

			if (!goodChannel)
			{
				if (logErrors)
				{
					m_testCtx.getLog() << TestLog::Message
									   << "Failure: " << channelBits[chanNdx] << "-bit " << s_channelNames[chanNdx] << " channel is " << renderedClrInFormat
									   << ", should be " << choiceListStr(channelChoices)
									   << " (corresponding fragment color channel is " << inputClr[chanNdx] << ")"
									   << TestLog::EndMessage
									   << TestLog::Message
									   << "Note: " << inputClr[chanNdx] << " * (" << channelMax + 1 << "-1) = " << scaledInput
									   << TestLog::EndMessage;

					if (useRoundingMargin)
					{
						m_testCtx.getLog() << TestLog::Message
										   << "Note: one extra color candidate was allowed because fragmentColorChannel * (2^bits-1) is close to an integer"
										   << TestLog::EndMessage;
					}
				}

				allChannelsOk = false;
			}
		}
	}

	return allChannelsOk;
}

bool DitheringCase::drawAndCheckGradient (const bool isVerticallyIncreasing, const Vec4& highColor) const
{
	TestLog&					log					= m_testCtx.getLog();
	Random						rnd					(deStringHash(getName()));
	const int					maxViewportWid		= 256;
	const int					maxViewportHei		= 256;
	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
	const Vec4					quadClr0			(0.0f, 0.0f, 0.0f, 0.0f);
	const Vec4&					quadClr1			= highColor;
	Quad						quad;
	Surface						renderedImg			(viewportWid, viewportHei);

	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));

	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;

	if (m_ditheringEnabled)
		GLU_CHECK_CALL(glEnable(GL_DITHER));
	else
		GLU_CHECK_CALL(glDisable(GL_DITHER));

	log << TestLog::Message << "Drawing a " << (isVerticallyIncreasing ? "vertically" : "horizontally") << " increasing gradient" << TestLog::EndMessage;

	quad.color[0] = quadClr0;
	quad.color[1] = isVerticallyIncreasing ? quadClr1 : quadClr0;
	quad.color[2] = isVerticallyIncreasing ? quadClr0 : quadClr1;
	quad.color[3] = quadClr1;

	m_renderer->render(quad);

	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
	GLU_CHECK_MSG("glReadPixels()");

	log << TestLog::Image(isVerticallyIncreasing ? "VerGradient"		: "HorGradient",
						  isVerticallyIncreasing ? "Vertical gradient"	: "Horizontal gradient",
						  renderedImg);

	// Validate, at each pixel, that each color channel is one of its two allowed values.

	{
		Surface		errorMask		(viewportWid, viewportHei);
		bool		colorChoicesOk	= true;

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				const float		inputF		= ((float)(isVerticallyIncreasing ? y : x) + 0.5f) / (float)(isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth());
				const Vec4		inputClr	= (1.0f-inputF)*quadClr0 + inputF*quadClr1;
				const bool              increaseTol     = ((renderedImg.getWidth() < 300) || (renderedImg.getHeight() < 300)) ? true : false;

				if (!checkColor(inputClr, renderedImg.getPixel(x, y), colorChoicesOk, increaseTol))
				{
					errorMask.setPixel(x, y, tcu::RGBA::red());

					if (colorChoicesOk)
					{
						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
						colorChoicesOk = false;
					}
				}
				else
					errorMask.setPixel(x, y, tcu::RGBA::green());
			}
		}

		if (!colorChoicesOk)
		{
			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
			return false;
		}
	}

	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the colors must be constant in the gradient's constant direction.

	if (!m_ditheringEnabled)
	{
		const int	increasingDirectionSize	= isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth();
		const int	constantDirectionSize	= isVerticallyIncreasing ? renderedImg.getWidth() : renderedImg.getHeight();

		for (int incrPos = 0; incrPos < increasingDirectionSize; incrPos++)
		{
			bool		colorHasChanged			= false;
			tcu::RGBA	prevConstantDirectionPix;

			for (int constPos = 0; constPos < constantDirectionSize; constPos++)
			{
				const int			x		= isVerticallyIncreasing ? constPos : incrPos;
				const int			y		= isVerticallyIncreasing ? incrPos : constPos;
				const tcu::RGBA		clr		= renderedImg.getPixel(x, y);

				if (constPos > 0 && clr != prevConstantDirectionPix)
				{
					if (colorHasChanged)
					{
						log << TestLog::Message
							<< "Failure: colors should be constant per " << (isVerticallyIncreasing ? "row" : "column")
							<< " (since dithering is disabled), but the color at position (" << x << ", " << y << ") is " << clr
							<< " and does not equal the color at (" << (isVerticallyIncreasing ? x-1 : x) << ", " << (isVerticallyIncreasing ? y : y-1) << "), which is " << prevConstantDirectionPix
							<< TestLog::EndMessage;

						return false;
					}
					else
						colorHasChanged = true;
				}

				prevConstantDirectionPix = clr;
			}
		}
	}

	return true;
}

bool DitheringCase::drawAndCheckUnicoloredQuad (const Vec4& quadColor) const
{
	TestLog&					log					= m_testCtx.getLog();
	Random						rnd					(deStringHash(getName()));
	const int					maxViewportWid		= 32;
	const int					maxViewportHei		= 32;
	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
	Quad						quad;
	Surface						renderedImg			(viewportWid, viewportHei);

	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));

	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;

	if (m_ditheringEnabled)
		GLU_CHECK_CALL(glEnable(GL_DITHER));
	else
		GLU_CHECK_CALL(glDisable(GL_DITHER));

	log << TestLog::Message << "Drawing an unicolored quad with color " << quadColor << TestLog::EndMessage;

	quad.color[0] = quadColor;
	quad.color[1] = quadColor;
	quad.color[2] = quadColor;
	quad.color[3] = quadColor;

	m_renderer->render(quad);

	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
	GLU_CHECK_MSG("glReadPixels()");

	log << TestLog::Image(("Quad" + de::toString(m_iteration)).c_str(), ("Quad " + de::toString(m_iteration)).c_str(), renderedImg);

	// Validate, at each pixel, that each color channel is one of its two allowed values.

	{
		Surface		errorMask		(viewportWid, viewportHei);
		bool		colorChoicesOk	= true;

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				if (!checkColor(quadColor, renderedImg.getPixel(x, y), colorChoicesOk, false))
				{
					errorMask.setPixel(x, y, tcu::RGBA::red());

					if (colorChoicesOk)
					{
						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
						colorChoicesOk = false;
					}
				}
				else
					errorMask.setPixel(x, y, tcu::RGBA::green());
			}
		}

		if (!colorChoicesOk)
		{
			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
			return false;
		}
	}

	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the entire rendered image must be unicolored.

	if (!m_ditheringEnabled)
	{
		const tcu::RGBA renderedClr00 = renderedImg.getPixel(0, 0);

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				const tcu::RGBA curClr = renderedImg.getPixel(x, y);

				if (curClr != renderedClr00)
				{
					log << TestLog::Message
						<< "Failure: color at (" << x << ", " << y << ") is " << curClr
						<< " and does not equal the color at (0, 0), which is " << renderedClr00
						<< TestLog::EndMessage;

					return false;
				}
			}
		}
	}

	return true;
}

DitheringCase::IterateResult DitheringCase::iterate (void)
{
	if (m_patternType == PATTERNTYPE_GRADIENT)
	{
		// Draw horizontal and vertical gradients.

		DE_ASSERT(m_iteration < 2);

		const bool success = drawAndCheckGradient(m_iteration == 1, m_color);

		if (!success)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		if (m_iteration == 1)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
			return STOP;
		}
	}
	else if (m_patternType == PATTERNTYPE_UNICOLORED_QUAD)
	{
		const int numQuads = m_testCtx.getCommandLine().getTestIterationCount() > 0 ? m_testCtx.getCommandLine().getTestIterationCount() : 30;

		DE_ASSERT(m_iteration < numQuads);

		const Vec4 quadColor	= (float)m_iteration / (float)(numQuads-1) * m_color;
		const bool success		=  drawAndCheckUnicoloredQuad(quadColor);

		if (!success)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
			return STOP;
		}

		if (m_iteration == numQuads - 1)
		{
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
			return STOP;
		}
	}
	else
		DE_ASSERT(false);

	m_iteration++;

	return CONTINUE;
}

DitheringTests::DitheringTests (Context& context)
	: TestCaseGroup(context, "dither", "Dithering tests")
{
}

DitheringTests::~DitheringTests (void)
{
}

void DitheringTests::init (void)
{
	static const struct
	{
		const char*		name;
		Vec4			color;
	} caseColors[] =
	{
		{ "white",		Vec4(1.0f, 1.0f, 1.0f, 1.0f) },
		{ "red",		Vec4(1.0f, 0.0f, 0.0f, 1.0f) },
		{ "green",		Vec4(0.0f, 1.0f, 0.0f, 1.0f) },
		{ "blue",		Vec4(0.0f, 0.0f, 1.0f, 1.0f) },
		{ "alpha",		Vec4(0.0f, 0.0f, 0.0f, 1.0f) }
	};

	for (int ditheringEnabledI = 0; ditheringEnabledI <= 1; ditheringEnabledI++)
	{
		const bool				ditheringEnabled	= ditheringEnabledI != 0;
		TestCaseGroup* const	group				= new TestCaseGroup(m_context, ditheringEnabled ? "enabled" : "disabled", "");
		addChild(group);

		for (int patternTypeI = 0; patternTypeI < DitheringCase::PATTERNTYPE_LAST; patternTypeI++)
		{
			for (int caseColorNdx = 0; caseColorNdx < DE_LENGTH_OF_ARRAY(caseColors); caseColorNdx++)
			{
				const DitheringCase::PatternType	patternType		= (DitheringCase::PatternType)patternTypeI;
				const string						caseName		= string("") + DitheringCase::getPatternTypeName(patternType) + "_" + caseColors[caseColorNdx].name;

				group->addChild(new DitheringCase(m_context.getTestContext(), m_context.getRenderContext(), caseName.c_str(), "", ditheringEnabled, patternType, caseColors[caseColorNdx].color));
			}
		}
	}
}

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