/*-------------------------------------------------------------------------
 * 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;
using namespace glu::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(tcu::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(tcu::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
