/*-------------------------------------------------------------------------
 * 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 Texture wrap mode tests.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureWrapTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"

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

namespace deqp
{
namespace gles2
{
namespace Functional
{

using tcu::TestLog;
using std::vector;
using std::string;
using tcu::Sampler;
using namespace glu;
using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

enum
{
	VIEWPORT_WIDTH		= 256,
	VIEWPORT_HEIGHT		= 256
};

class TextureWrapCase : public tcu::TestCase
{
public:
								TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
								TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames);
								~TextureWrapCase		(void);

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

private:
								TextureWrapCase			(const TextureWrapCase& other);
	TextureWrapCase&			operator=				(const TextureWrapCase& other);

	glu::RenderContext&			m_renderCtx;
	const glu::ContextInfo&		m_renderCtxInfo;

	deUint32					m_format;
	deUint32					m_dataType;
	deUint32					m_wrapS;
	deUint32					m_wrapT;
	deUint32					m_minFilter;
	deUint32					m_magFilter;

	int							m_width;
	int							m_height;
	std::vector<std::string>	m_filenames;

	glu::Texture2D*				m_texture;
	TextureRenderer				m_renderer;
};

TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(ctxInfo)
	, m_format			(format)
	, m_dataType		(dataType)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
{
}

TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(ctxInfo)
	, m_format			(GL_NONE)
	, m_dataType		(GL_NONE)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_width			(0)
	, m_height			(0)
	, m_filenames		(filenames)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
{
}

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

void TextureWrapCase::init (void)
{
	if (!m_filenames.empty())
	{
		DE_ASSERT(m_width == 0 && m_height == 0 && m_format == GL_NONE && m_dataType == GL_NONE);

		m_texture	= glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
		m_width		= m_texture->getRefTexture().getWidth();
		m_height	= m_texture->getRefTexture().getHeight();
	}
	else
	{
		m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);

		// Fill level 0.
		m_texture->getRefTexture().allocLevel(0);
		if (m_wrapS == GL_REPEAT ||
			m_wrapT == GL_REPEAT)
		{
			// If run in repeat mode, use conical style texture to avoid edge sample result have a huge difference when coordinate offset in allow range.
			tcu::fillWithComponentGradients3(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 1.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
		}
		else
		{
			tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 1.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
		}

		m_texture->upload();
	}
}

void TextureWrapCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

TextureWrapCase::IterateResult TextureWrapCase::iterate (void)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	bool					isCompressedTex		= !m_filenames.empty();
	ReferenceParams			refParams			(TEXTURETYPE_2D);
	int						leftWidth			= viewport.width / 2;
	int						rightWidth			= viewport.width - leftWidth;
	vector<float>			texCoord;

	tcu::RGBA				threshold;
	if (m_texture->getRefTexture().getFormat().type == tcu::TextureFormat::UNORM_SHORT_4444 ||
		m_texture->getRefTexture().getFormat().type == tcu::TextureFormat::UNSIGNED_SHORT_4444)
	{
		threshold = tcu::PixelFormat(4, 4, 4, 4).getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
	}
	else
	{
		threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() +
					(isCompressedTex ? tcu::RGBA(7, 7, 7, 7) : tcu::RGBA(3, 3, 3, 3));
	}

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup filtering and wrap modes.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Parameters for reference images.
	refParams.sampler	= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
	refParams.lodMode	= LODMODE_EXACT;

	// Left: minification
	{
		gl.viewport(viewport.x, viewport.y, leftWidth, viewport.height);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(-1.5f, -3.0f), tcu::Vec2(1.5f, 2.5f));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, viewport.height),
					  m_texture->getRefTexture(), &texCoord[0], refParams);
	}

	// Right: magnification
	{
		gl.viewport(viewport.x+leftWidth, viewport.y, rightWidth, viewport.height);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, viewport.height),
					  m_texture->getRefTexture(), &texCoord[0], refParams);
	}

	// Compare and log.
	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);

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

	return STOP;
}

TextureWrapTests::TextureWrapTests (Context& context)
	: TestCaseGroup(context, "wrap", "Wrap Mode Tests")
{
}

TextureWrapTests::~TextureWrapTests (void)
{
}

void TextureWrapTests::init (void)
{
	static const struct
	{
		const char*		name;
		deUint32		mode;
	} wrapModes[] =
	{
		{ "clamp",		GL_CLAMP_TO_EDGE },
		{ "repeat",		GL_REPEAT },
		{ "mirror",		GL_MIRRORED_REPEAT }
	};

	static const struct
	{
		const char*		name;
		deUint32		mode;
	} filteringModes[] =
	{
		{ "nearest",	GL_NEAREST },
		{ "linear",		GL_LINEAR }
	};

	static const struct
	{
		const char*		name;
		int				width;
		int				height;
	} sizes[] =
	{
		{ "pot",		64, 128 },
		{ "npot",		63, 112 }
	};

	static const struct
	{
		const char*		name;
		deUint32		format;
		deUint32		dataType;
	} formats[] =
	{
		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE },
		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
	};

#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
		BODY

	FOR_EACH(wrapS,		wrapModes,
	FOR_EACH(wrapT,		wrapModes,
	FOR_EACH(filter,	filteringModes,
	FOR_EACH(size,		sizes,
	FOR_EACH(format,	formats,
		{
			bool is_clamp_clamp		= (wrapModes[wrapS].mode == GL_CLAMP_TO_EDGE	&& wrapModes[wrapT].mode == GL_CLAMP_TO_EDGE);
			bool is_repeat_mirror	= (wrapModes[wrapS].mode == GL_REPEAT			&& wrapModes[wrapT].mode == GL_MIRRORED_REPEAT);

			if (!is_clamp_clamp && !is_repeat_mirror && format != 0)
				continue; // Use other format varants with clamp_clamp & repeat_mirror pair only.

			if (!is_clamp_clamp && (!deIsPowerOfTwo32(sizes[size].width) || !deIsPowerOfTwo32(sizes[size].height)))
				continue; // Not supported as described in Spec section 3.8.2.

			string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + sizes[size].name + "_" + formats[format].name;
			addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
										 formats[format].format, formats[format].dataType,
										 wrapModes[wrapS].mode,
										 wrapModes[wrapT].mode,
										 filteringModes[filter].mode, filteringModes[filter].mode,
										 sizes[size].width, sizes[size].height));

		})))));

	// Power-of-two ETC1 texture
	std::vector<std::string> potFilenames;
	potFilenames.push_back("data/etc1/photo_helsinki_mip_0.pkm");

	FOR_EACH(wrapS,		wrapModes,
	FOR_EACH(wrapT,		wrapModes,
	FOR_EACH(filter,	filteringModes,
		{
			string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_pot_etc1";
			addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
										 wrapModes[wrapS].mode,
										 wrapModes[wrapT].mode,
										 filteringModes[filter].mode, filteringModes[filter].mode,
										 potFilenames));

		})));

	std::vector<std::string> npotFilenames;
	npotFilenames.push_back("data/etc1/photo_helsinki_113x89.pkm");

	// NPOT ETC1 texture
	for (int filter = 0; filter < DE_LENGTH_OF_ARRAY(filteringModes); filter++)
	{
		string name = string("clamp_clamp_") + filteringModes[filter].name + "_npot_etc1";
		addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
									 GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
									 filteringModes[filter].mode, filteringModes[filter].mode,
									 npotFilenames));
	}
}

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