#ifndef _ES3FFBOTESTUTIL_HPP
#define _ES3FFBOTESTUTIL_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.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 FBO test utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "sglrContext.hpp"
#include "gluShaderUtil.hpp"
#include "tcuTexture.hpp"
#include "tcuMatrix.hpp"
#include "tcuRenderTarget.hpp"

#include <vector>

namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace FboTestUtil
{

// \todo [2012-04-29 pyry] Clean up and name as SglrUtil

// Helper class for constructing DataType vectors.
struct DataTypes
{
	std::vector<glu::DataType> vec;
	DataTypes& operator<< (glu::DataType type) { vec.push_back(type); return *this; }
};

// Shaders.

class FlatColorShader : public sglr::ShaderProgram
{
public:
						FlatColorShader		(glu::DataType outputType);
						~FlatColorShader	(void) {}

	void				setColor			(sglr::Context& context, deUint32 program, const tcu::Vec4& color);

	void				shadeVertices		(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void				shadeFragments		(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	const glu::DataType	m_outputType;
};

class GradientShader : public sglr::ShaderProgram
{
public:
						GradientShader		(glu::DataType outputType);
						~GradientShader		(void) {}

	void				setGradient			(sglr::Context& context, deUint32 program, const tcu::Vec4& gradientMin, const tcu::Vec4& gradientMax);

	void				shadeVertices		(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void				shadeFragments		(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	const glu::DataType	m_outputType;
};

class Texture2DShader : public sglr::ShaderProgram
{
public:
					Texture2DShader			(const DataTypes& samplerTypes, glu::DataType outputType, const tcu::Vec4& outScale = tcu::Vec4(1.0f), const tcu::Vec4& outBias = tcu::Vec4(0.0f));
					~Texture2DShader		(void) {}

	void			setUnit					(int samplerNdx, int unitNdx);
	void			setTexScaleBias			(int samplerNdx, const tcu::Vec4& scale, const tcu::Vec4& bias);
	void			setOutScaleBias			(const tcu::Vec4& scale, const tcu::Vec4& bias);

	void			setUniforms				(sglr::Context& context, deUint32 program) const;

	void			shadeVertices			(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void			shadeFragments			(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	struct Input
	{
		int			unitNdx;
		tcu::Vec4	scale;
		tcu::Vec4	bias;
	};

	std::vector<Input>	m_inputs;
	tcu::Vec4			m_outScale;
	tcu::Vec4			m_outBias;

	const glu::DataType	m_outputType;
};

class TextureCubeShader : public sglr::ShaderProgram
{
public:
						TextureCubeShader		(glu::DataType samplerType, glu::DataType outputType);
						~TextureCubeShader		(void) {}

	void				setFace					(tcu::CubeFace face);
	void				setTexScaleBias			(const tcu::Vec4& scale, const tcu::Vec4& bias);

	void				setUniforms				(sglr::Context& context, deUint32 program) const;

	void				shadeVertices			(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void				shadeFragments			(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	tcu::Mat3			m_coordMat;
	tcu::Vec4			m_texScale;
	tcu::Vec4			m_texBias;

	const glu::DataType	m_outputType;
};

class Texture2DArrayShader : public sglr::ShaderProgram
{
public:
						Texture2DArrayShader	(glu::DataType samplerType, glu::DataType outputType);
						~Texture2DArrayShader	(void) {}

	void				setLayer				(int layer);
	void				setTexScaleBias			(const tcu::Vec4& scale, const tcu::Vec4& bias);

	void				setUniforms				(sglr::Context& context, deUint32 program) const;

	void				shadeVertices			(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void				shadeFragments			(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	tcu::Vec4			m_texScale;
	tcu::Vec4			m_texBias;
	int					m_layer;

	const glu::DataType	m_outputType;
};

class Texture3DShader : public sglr::ShaderProgram
{
public:
						Texture3DShader			(glu::DataType samplerType, glu::DataType outputType);
						~Texture3DShader		(void) {}

	void				setDepth				(float r);
	void				setTexScaleBias			(const tcu::Vec4& scale, const tcu::Vec4& bias);

	void				setUniforms				(sglr::Context& context, deUint32 program) const;

	void				shadeVertices			(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void				shadeFragments			(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	tcu::Vec4			m_texScale;
	tcu::Vec4			m_texBias;
	float				m_depth;

	const glu::DataType	m_outputType;
};

class DepthGradientShader : public sglr::ShaderProgram
{
public:
								DepthGradientShader		(glu::DataType outputType);
								~DepthGradientShader	(void) {}

	void						setUniforms				(sglr::Context& context, deUint32 program, const float gradientMin, const float gradientMax, const tcu::Vec4& color);

	void						shadeVertices			(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void						shadeFragments			(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

private:
	const glu::DataType			m_outputType;
	const sglr::UniformSlot&	u_minGradient;
	const sglr::UniformSlot&	u_maxGradient;
	const sglr::UniformSlot&	u_color;
};

// Framebuffer incomplete exception.
class FboIncompleteException : public tcu::TestError
{
public:
						FboIncompleteException		(deUint32 reason, const char* file, int line);
	virtual				~FboIncompleteException		(void) throw() {}

	deUint32			getReason					(void) const { return m_reason; }

private:
	deUint32			m_reason;
};

// Utility functions.

glu::DataType			getFragmentOutputType				(const tcu::TextureFormat& format);
tcu::TextureFormat		getFramebufferReadFormat			(const tcu::TextureFormat& format);

const char*				getFormatName						(deUint32 format);

void					clearColorBuffer					(sglr::Context& ctx, const tcu::TextureFormat& format, const tcu::Vec4& value);
void					readPixels							(sglr::Context& ctx, tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias);

tcu::RGBA				getFormatThreshold					(const tcu::TextureFormat& format);
tcu::RGBA				getFormatThreshold					(const deUint32 glFormat);

tcu::RGBA				getToSRGBConversionThreshold		(const tcu::TextureFormat& src, const tcu::TextureFormat& dst);

} // FboTestUtil
} // Functional
} // gles3
} // deqp

#endif // _ES3FFBOTESTUTIL_HPP
