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

#include "es2pTextureCases.hpp"
#include "glsShaderPerformanceCase.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"

#include "deStringUtil.hpp"

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

namespace deqp
{
namespace gles2
{
namespace Performance
{

using namespace gls;
using namespace glw; // GL types
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec4;
using std::string;
using std::vector;
using tcu::TestLog;

Texture2DRenderCase::Texture2DRenderCase (Context&			context,
										  const char*		name,
										  const char*		description,
										  deUint32			format,
										  deUint32			dataType,
										  deUint32			wrapS,
										  deUint32			wrapT,
										  deUint32			minFilter,
										  deUint32			magFilter,
										  const tcu::Mat3&	coordTransform,
										  int				numTextures,
										  bool				powerOfTwo)
	: ShaderPerformanceCase	(context.getTestContext(), context.getRenderContext(), name, description, CASETYPE_FRAGMENT)
	, m_format				(format)
	, m_dataType			(dataType)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_coordTransform		(coordTransform)
	, m_numTextures			(numTextures)
	, m_powerOfTwo			(powerOfTwo)
{
}

Texture2DRenderCase::~Texture2DRenderCase (void)
{
	for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
		delete *i;
	m_textures.clear();
}

static inline int roundDownToPowerOfTwo (int val)
{
	DE_ASSERT(val >= 0);
	int l0 = deClz32(val);
	return val & ~((1<<(31-l0))-1);
}

void Texture2DRenderCase::init (void)
{
	TestLog& log = m_testCtx.getLog();

	int width	= m_renderCtx.getRenderTarget().getWidth();
	int height	= m_renderCtx.getRenderTarget().getHeight();

	if (m_powerOfTwo)
	{
		width	= roundDownToPowerOfTwo(width);
		height	= roundDownToPowerOfTwo(height);
	}

	bool mipmaps = m_minFilter == GL_NEAREST_MIPMAP_NEAREST ||
				   m_minFilter == GL_NEAREST_MIPMAP_LINEAR	||
				   m_minFilter == GL_LINEAR_MIPMAP_NEAREST	||
				   m_minFilter == GL_LINEAR_MIPMAP_LINEAR;

	DE_ASSERT(m_powerOfTwo || (!mipmaps && m_wrapS == GL_CLAMP_TO_EDGE && m_wrapT == GL_CLAMP_TO_EDGE));

	Vec2 p00 = (m_coordTransform * Vec3(0.0f, 0.0f, 1.0f)).swizzle(0,1);
	Vec2 p10 = (m_coordTransform * Vec3(1.0f, 0.0f, 1.0f)).swizzle(0,1);
	Vec2 p01 = (m_coordTransform * Vec3(0.0f, 1.0f, 1.0f)).swizzle(0,1);
	Vec2 p11 = (m_coordTransform * Vec3(1.0f, 1.0f, 1.0f)).swizzle(0,1);

	m_attributes.push_back(AttribSpec("a_coords", Vec4(p00.x(), p00.y(), 0.0f, 0.0f),
												  Vec4(p10.x(), p10.y(), 0.0f, 0.0f),
												  Vec4(p01.x(), p01.y(), 0.0f, 0.0f),
												  Vec4(p11.x(), p11.y(), 0.0f, 0.0f)));

	log << TestLog::Message << "Size: " << width << "x" << height << TestLog::EndMessage;
	log << TestLog::Message << "Format: " <<glu::getTextureFormatName(m_format) << " " << glu::getTypeName(m_dataType) << TestLog::EndMessage;
	log << TestLog::Message << "Coords: " << p00 << ", " << p10 << ", " << p01 << ", " << p11 << TestLog::EndMessage;
	log << TestLog::Message << "Wrap: " << glu::getTextureWrapModeStr(m_wrapS) << " / " << glu::getTextureWrapModeStr(m_wrapT) << TestLog::EndMessage;
	log << TestLog::Message << "Filter: " << glu::getTextureFilterStr(m_minFilter) << " / " << glu::getTextureFilterStr(m_magFilter) << TestLog::EndMessage;
	log << TestLog::Message << "Mipmaps: " << (mipmaps ? "true" : "false") << TestLog::EndMessage;
	log << TestLog::Message << "Using additive blending." << TestLog::EndMessage;

	// Use same viewport size as texture size.
	setViewportSize(width, height);

	m_vertShaderSource =
		"attribute highp vec4 a_position;\n"
		"attribute mediump vec2 a_coords;\n"
		"varying mediump vec2 v_coords;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = a_position;\n"
		"	v_coords = a_coords;\n"
		"}\n";

	std::ostringstream fragSrc;
	fragSrc << "varying mediump vec2 v_coords;\n";

	for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
		fragSrc << "uniform sampler2D u_sampler" << texNdx << ";\n";

	fragSrc << "void main (void)\n"
			<< "{\n";

	for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
		fragSrc << "\t" << (texNdx == 0 ? "lowp vec4 r = " : "r += ") << "texture2D(u_sampler" << texNdx << ", v_coords);\n";

	fragSrc << "	gl_FragColor = r;\n"
			<< "}\n";

	m_fragShaderSource = fragSrc.str();

	m_textures.reserve(m_numTextures);
	for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
	{
		static const IVec4 swizzles[] = { IVec4(0,1,2,3), IVec4(1,2,3,0), IVec4(2,3,0,1), IVec4(3,0,1,2),
										  IVec4(3,2,1,0), IVec4(2,1,0,3), IVec4(1,0,3,2), IVec4(0,3,2,1) };
		const IVec4& sw = swizzles[texNdx % DE_LENGTH_OF_ARRAY(swizzles)];

		glu::Texture2D* texture = new glu::Texture2D(m_renderCtx, m_format, m_dataType, width, height);
		m_textures.push_back(texture);

		// Fill levels.
		int numLevels = mipmaps ? texture->getRefTexture().getNumLevels() : 1;
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			texture->getRefTexture().allocLevel(levelNdx);
			tcu::fillWithComponentGradients(texture->getRefTexture().getLevel(levelNdx),
											Vec4(0.0f, 0.0f, 0.0f, 0.0f).swizzle(sw[0], sw[1], sw[2], sw[3]),
											Vec4(1.0f, 1.0f, 1.0f, 1.0f).swizzle(sw[0], sw[1], sw[2], sw[3]));
		}

		texture->upload();
	}

	ShaderPerformanceCase::init();
}

void Texture2DRenderCase::deinit (void)
{
	for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
		delete *i;
	m_textures.clear();

	ShaderPerformanceCase::deinit();
}

void Texture2DRenderCase::setupProgram (deUint32 program)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();
	for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
	{
		int samplerLoc = gl.getUniformLocation(program, (string("u_sampler") + de::toString(texNdx)).c_str());
		gl.uniform1i(samplerLoc, texNdx);
	}
}

void Texture2DRenderCase::setupRenderState (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	// Setup additive blending.
	gl.enable(GL_BLEND);
	gl.blendFunc(GL_ONE, GL_ONE);
	gl.blendEquation(GL_FUNC_ADD);

	// Setup textures.
	for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
	{
		gl.activeTexture(GL_TEXTURE0 + texNdx);
		gl.bindTexture(GL_TEXTURE_2D, m_textures[texNdx]->getGLTexture());
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	}
}


} // Performance
} // gles2
} // deqp
