/*-------------------------------------------------------------------------
 * 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);
		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), 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			= 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
