/*-------------------------------------------------------------------------
 * 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;

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(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(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
