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

#include "es2fTextureSizeTests.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;

class Texture2DSizeCase : public tcu::TestCase
{
public:
							Texture2DSizeCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, bool mipmaps);
							~Texture2DSizeCase		(void);

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

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

	glu::RenderContext&		m_renderCtx;

	deUint32				m_format;
	deUint32				m_dataType;
	int						m_width;
	int						m_height;
	bool					m_useMipmaps;

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

Texture2DSizeCase::Texture2DSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, bool mipmaps)
	: TestCase		(testCtx, name, description)
	, m_renderCtx	(renderCtx)
	, m_format		(format)
	, m_dataType	(dataType)
	, m_width		(width)
	, m_height		(height)
	, m_useMipmaps	(mipmaps)
	, m_texture		(DE_NULL)
	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
{
}

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

void Texture2DSizeCase::init (void)
{
	DE_ASSERT(!m_texture);
	m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);

	int numLevels = m_useMipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;

	// Fill levels.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		m_texture->getRefTexture().allocLevel(levelNdx);
		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(levelNdx), tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
	}
}

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

	m_renderer.clear();
}

Texture2DSizeCase::IterateResult Texture2DSizeCase::iterate (void)
{
	const glw::Functions&	gl				= m_renderCtx.getFunctions();
	TestLog&				log				= m_testCtx.getLog();
	RandomViewport			viewport		(m_renderCtx.getRenderTarget(), 128, 128, deStringHash(getName()));
	tcu::Surface			renderedFrame	(viewport.width, viewport.height);
	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
	tcu::RGBA				threshold		= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
	deUint32				wrapT			= GL_CLAMP_TO_EDGE;
	deUint32				minFilter		= m_useMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
	deUint32				magFilter		= GL_NEAREST;
	vector<float>			texCoord;

	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Upload texture data to GL.
	m_texture->upload();

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

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		wrapT);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

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

	// Compute reference.
	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_2D, mapGLSampler(wrapS, wrapT, minFilter, magFilter)));

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

class TextureCubeSizeCase : public tcu::TestCase
{
public:
							TextureCubeSizeCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, bool mipmaps);
							~TextureCubeSizeCase	(void);

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

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

	bool					testFace				(tcu::CubeFace face);

	glu::RenderContext&		m_renderCtx;

	deUint32				m_format;
	deUint32				m_dataType;
	int						m_width;
	int						m_height;
	bool					m_useMipmaps;

	glu::TextureCube*		m_texture;
	TextureRenderer			m_renderer;

	int						m_curFace;
	bool					m_isOk;
};

TextureCubeSizeCase::TextureCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, bool mipmaps)
	: TestCase		(testCtx, name, description)
	, m_renderCtx	(renderCtx)
	, m_format		(format)
	, m_dataType	(dataType)
	, m_width		(width)
	, m_height		(height)
	, m_useMipmaps	(mipmaps)
	, m_texture		(DE_NULL)
	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_curFace		(0)
	, m_isOk		(false)
{
}

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

void TextureCubeSizeCase::init (void)
{
	DE_ASSERT(!m_texture);
	DE_ASSERT(m_width == m_height);
	m_texture = new TextureCube(m_renderCtx, m_format, m_dataType, m_width);

	static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
	{
		{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
		{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
		{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
		{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
		{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
		{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
	};

	int numLevels = m_useMipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;

	// Fill levels.
	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
		{
			m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
			fillWithComponentGradients(m_texture->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0], gradients[face][1]);
		}
	}

	// Upload texture data to GL.
	m_texture->upload();

	// Initialize iteration state.
	m_curFace	= 0;
	m_isOk		= true;
}

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

	m_renderer.clear();
}

bool TextureCubeSizeCase::testFace (tcu::CubeFace face)
{
	const glw::Functions&	gl				= m_renderCtx.getFunctions();
	TestLog&				log				= m_testCtx.getLog();
	RandomViewport			viewport		(m_renderCtx.getRenderTarget(), 128, 128, deStringHash(getName())+(deUint32)face);
	tcu::Surface			renderedFrame	(viewport.width, viewport.height);
	tcu::Surface			referenceFrame	(viewport.width, viewport.height);
	tcu::RGBA				threshold		= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
	deUint32				wrapS			= GL_CLAMP_TO_EDGE;
	deUint32				wrapT			= GL_CLAMP_TO_EDGE;
	deUint32				minFilter		= m_useMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST;
	deUint32				magFilter		= GL_NEAREST;
	vector<float>			texCoord;

	computeQuadTexCoordCube(texCoord, face);

	// \todo [2011-10-28 pyry] Image set name / section?
	log << TestLog::Message << face << TestLog::EndMessage;

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

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

	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrapS);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrapT);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, minFilter);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, magFilter);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

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

	// Compute reference.
	Sampler sampler = mapGLSampler(wrapS, wrapT, minFilter, magFilter);
	sampler.seamlessCubeMap = false;
	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_CUBE, sampler));

	// Compare and log.
	return compareImages(log, referenceFrame, renderedFrame, threshold);
}

TextureCubeSizeCase::IterateResult TextureCubeSizeCase::iterate (void)
{
	// Execute test for all faces.
	if (!testFace((tcu::CubeFace)m_curFace))
		m_isOk = false;

	m_curFace += 1;

	if (m_curFace == tcu::CUBEFACE_LAST)
	{
		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								m_isOk ? "Pass"					: "Image comparison failed");
		return STOP;
	}
	else
		return CONTINUE;
}

TextureSizeTests::TextureSizeTests (Context& context)
	: TestCaseGroup(context, "size", "Texture Size Tests")
{
}

TextureSizeTests::~TextureSizeTests (void)
{
}

void TextureSizeTests::init (void)
{
	struct
	{
		int	width;
		int	height;
	} sizes2D[] =
	{
		{   64,   64 }, // Spec-mandated minimum.
		{   65,   63 },
		{  512,  512 },
		{ 1024, 1024 },
		{ 2048, 2048 }
	};

	struct
	{
		int	width;
		int	height;
	} sizesCube[] =
	{
		{  15,  15 },
		{  16,  16 }, // Spec-mandated minimum
		{  64,  64 },
		{ 128, 128 },
		{ 256, 256 },
		{ 512, 512 }
	};

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

	// 2D cases.
	tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Size Tests");
	addChild(group2D);
	for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
	{
		int		width	= sizes2D[sizeNdx].width;
		int		height	= sizes2D[sizeNdx].height;
		bool	isPOT	= deIsPowerOfTwo32(width) && deIsPowerOfTwo32(height);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
		{
			for (int mipmap = 0; mipmap < (isPOT ? 2 : 1); mipmap++)
			{
				std::ostringstream name;
				name << width << "x" << height << "_" << formats[formatNdx].name << (mipmap ? "_mipmap" : "");

				group2D->addChild(new Texture2DSizeCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "",
														formats[formatNdx].format, formats[formatNdx].dataType,
														width, height, mipmap != 0));
			}
		}
	}

	// Cubemap cases.
	tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cubemap Texture Size Tests");
	addChild(groupCube);
	for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizesCube); sizeNdx++)
	{
		int		width	= sizesCube[sizeNdx].width;
		int		height	= sizesCube[sizeNdx].height;
		bool	isPOT	= deIsPowerOfTwo32(width) && deIsPowerOfTwo32(height);

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
		{
			for (int mipmap = 0; mipmap < (isPOT ? 2 : 1); mipmap++)
			{
				std::ostringstream name;
				name << width << "x" << height << "_" << formats[formatNdx].name << (mipmap ? "_mipmap" : "");

				groupCube->addChild(new TextureCubeSizeCase(m_testCtx, m_context.getRenderContext(), name.str().c_str(), "",
															formats[formatNdx].format, formats[formatNdx].dataType,
															width, height, mipmap != 0));
			}
		}
	}
}

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