#ifndef _GLSFBOUTIL_HPP
#define _GLSFBOUTIL_HPP

/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) 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 Utilities for framebuffer objects.
 *//*--------------------------------------------------------------------*/

#include "gluRenderContext.hpp"
#include "gluContextInfo.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "gluTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuDefs.hpp"

#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <iterator>

namespace deqp
{
namespace gls
{

//! A pair of iterators to present a range.
//! \note This must be POD to allow static initialization.
//! \todo [2013-12-03 lauri] Move this to decpp?
template <typename T>
struct Range
{
	typedef const T*	const_iterator;

	const T*	m_begin;
	const T*	m_end;

	const T*	begin		(void) const { return m_begin; }
	const T*	end			(void) const { return m_end; }
};

#define GLS_ARRAY_RANGE(ARR) { DE_ARRAY_BEGIN(ARR), DE_ARRAY_END(ARR) }

#define GLS_NULL_RANGE { DE_NULL, DE_NULL }


//! A pair type that, unlike stl::pair, is POD so it can be statically initialized.
template <typename T1, typename T2>
struct Pair
{
	typedef	T1	first_type;
	typedef T2	second_type;
	T1			first;
	T2			second;
};

namespace FboUtil
{

//! Configurations for framebuffer objects and their attachments.

class FboVerifier;
class FboBuilder;

typedef deUint32		FormatKey;

#define GLS_UNSIZED_FORMATKEY(FORMAT, TYPE) \
	(deUint32(TYPE) << 16 | deUint32(FORMAT))

typedef Range<FormatKey>	FormatKeys;

struct ImageFormat
{
	glw::GLenum				format;

	//! Type if format is unsized, GL_NONE if sized.
	glw::GLenum				unsizedType;

	bool					operator<		(const ImageFormat& other) const
	{
		return (format < other.format ||
				(format == other.format && unsizedType < other.unsizedType));
	}

	static ImageFormat		none			(void)
	{
		ImageFormat fmt = { GL_NONE, GL_NONE };
		return fmt;
	}
};

std::ostream& operator<< (std::ostream& stream, const ImageFormat& format);

static inline ImageFormat formatKeyInfo(FormatKey key)
{
	ImageFormat fmt = { key & 0xffff, key >> 16 };
	return fmt;
}

enum FormatFlags
{
	ANY_FORMAT			= 0,
	COLOR_RENDERABLE	= 1 << 0,
	DEPTH_RENDERABLE	= 1 << 1,
	STENCIL_RENDERABLE	= 1 << 2,
	RENDERBUFFER_VALID	= 1 << 3,
	TEXTURE_VALID		= 1 << 4,
	REQUIRED_RENDERABLE	= 1 << 5, //< Without this, renderability is allowed, not required.
};

static inline FormatFlags operator|(FormatFlags f1, FormatFlags f2)
{
	return FormatFlags(deUint32(f1) | deUint32(f2));
}

FormatFlags formatFlag(glw::GLenum context);

typedef std::set<ImageFormat> Formats;

class FormatDB
{
public:
	void								addCoreFormat				(ImageFormat format, FormatFlags flags);
	void								addExtensionFormat			(ImageFormat format, FormatFlags flags, const std::set<std::string>& requiredExtensions);

	Formats								getFormats					(FormatFlags requirements) const;
	bool								isKnownFormat				(ImageFormat format) const;
	FormatFlags							getFormatInfo				(ImageFormat format) const;
	std::set<std::set<std::string> >	getFormatFeatureExtensions	(ImageFormat format, FormatFlags requirements) const;

private:
	struct ExtensionInfo
	{
		FormatFlags					flags;
		std::set<std::string>		requiredExtensions;

		bool						operator<			(const ExtensionInfo& other) const;
	};

	typedef std::map<ImageFormat, FormatFlags>					FormatMap;
	typedef std::map<ImageFormat, std::set<ExtensionInfo> >		FormatExtensionMap;

	FormatMap							m_formatFlags;
	FormatExtensionMap					m_formatExtensions;
};

typedef Pair<FormatFlags, FormatKeys>				FormatEntry;
typedef Range<FormatEntry>							FormatEntries;

// \todo [2013-12-20 lauri] It turns out that format properties in extensions
// are actually far too fine-grained for this bundling to be reasonable,
// especially given the syntactic cumbersomeness of static arrays. It's better
// to list each entry separately.

struct FormatExtEntry
{
	const char*									extensions;
	deUint32									flags;
	Range<FormatKey>							formats;
};

typedef Range<FormatExtEntry>						FormatExtEntries;

// Check support for GL_* and DEQP_* extensions
bool				checkExtensionSupport		(const glu::RenderContext& ctx, const std::string& extension);

// Accepts GL_* and DEQP_* extension strings and converts DEQP_* strings to a human readable string
std::string			getExtensionDescription		(const std::string& extensionName);

void				addFormats					(FormatDB& db, FormatEntries stdFmts);
void				addExtFormats				(FormatDB& db, FormatExtEntries extFmts, const glu::RenderContext* ctx);
glu::TransferFormat	transferImageFormat			(const ImageFormat& imgFormat);

namespace config
{

struct Config
{
	virtual						~Config			(void) {};
};

struct Image : public Config
{
	ImageFormat					internalFormat;
	glw::GLsizei				width;
	glw::GLsizei				height;

protected:
								Image			(void)
									: internalFormat	(ImageFormat::none())
									, width				(0)
									, height			(0) {}
};

struct Renderbuffer : public Image
{
						Renderbuffer	(void) : numSamples(0) {}

	glw::GLsizei		numSamples;
};

struct Texture : public Image
{
							Texture			(void) : numLevels(1) {}

	glw::GLint				numLevels;
};

struct TextureFlat : public Texture
{
};

struct Texture2D : public TextureFlat
{
};

struct TextureCubeMap : public TextureFlat
{
};

struct TextureLayered : public Texture
{
							TextureLayered	(void) : numLayers(1) {}
	glw::GLsizei			numLayers;
};

struct Texture3D : public TextureLayered
{
};

struct Texture2DArray : public TextureLayered
{
};

struct Attachment : public Config
{
							Attachment		(void) : target(GL_FRAMEBUFFER), imageName(0) {}

	glw::GLenum				target;
	glw::GLuint				imageName;

	//! Returns `true` iff this attachment is "framebuffer attachment
	//! complete" when bound to attachment point `attPoint`, and the current
	//! image with name `imageName` is `image`, using `vfr` to check format
	//! renderability.
	bool					isComplete		(glw::GLenum attPoint, const Image* image,
											 const FboVerifier& vfr) const;
};

struct RenderbufferAttachment : public Attachment
{
				RenderbufferAttachment	(void)
				: renderbufferTarget(GL_RENDERBUFFER) {}

	glw::GLenum renderbufferTarget;
};

struct TextureAttachment : public Attachment
{
							TextureAttachment	(void) : level(0) {}

	glw::GLint				level;
};

struct TextureFlatAttachment : public TextureAttachment
{
							TextureFlatAttachment (void) : texTarget(GL_NONE) {}

	glw::GLenum				texTarget;
};

struct TextureLayerAttachment : public TextureAttachment
{
							TextureLayerAttachment (void) : layer(0) {}

	glw::GLsizei			layer;
};

glw::GLenum		attachmentType	(const Attachment& att);
glw::GLsizei	imageNumSamples	(const Image& img);

//! Mapping from attachment points to attachment configurations.
typedef std::map<glw::GLenum, const Attachment*> AttachmentMap;

//! Mapping from object names to texture configurations.
typedef std::map<glw::GLuint, const Texture*> TextureMap;

//! Mapping from object names to renderbuffer configurations.
typedef std::map<glw::GLuint, const Renderbuffer*> RboMap;

//! A framebuffer configuration.
struct Framebuffer
{
	AttachmentMap			attachments;
	TextureMap				textures;
	RboMap					rbos;

	void					attach			(glw::GLenum attPoint, const Attachment* att);
	void					setTexture		(glw::GLuint texName, const Texture& texCfg);
	void					setRbo			(glw::GLuint rbName, const Renderbuffer& rbCfg);
	const Image*			getImage		(glw::GLenum type, glw::GLuint imgName) const;
};

} // config

class FboBuilder : public config::Framebuffer
{
public:
	void						glAttach		(glw::GLenum attPoint,
												 const config::Attachment* att);
	glw::GLuint					glCreateTexture	(const config::Texture& texCfg);
	glw::GLuint					glCreateRbo		(const config::Renderbuffer& rbCfg);
								FboBuilder		(glw::GLuint fbo, glw::GLenum target,
												 const glw::Functions& gl);
								~FboBuilder		(void);
	glw::GLenum					getError		(void) { return m_error; }

	//! Allocate a new configuration of type `Config` (which must be a
	//! subclass of `config::Config`), and return a referenc to it. The newly
	//! allocated object will be freed when this builder object is destroyed.
	template<typename Config>
	Config&						makeConfig		(void)
	{
		Config* cfg = new Config();
		m_configs.insert(cfg);
		return *cfg;
	}

private:
	typedef std::set<config::Config*> Configs;

	void						checkError		(void);

	glw::GLenum					m_error;		//< The first GL error encountered.
	glw::GLenum					m_target;
	const glw::Functions&		m_gl;
	Configs						m_configs;
};

struct ValidStatusCodes
{
								ValidStatusCodes		(void);

	bool						isFBOStatusValid		(glw::GLenum fboStatus) const;
	bool						isFBOStatusRequired		(glw::GLenum fboStatus) const;
	bool						isErrorCodeValid		(glw::GLenum errorCode) const;
	bool						isErrorCodeRequired		(glw::GLenum errorCode) const;

	void						addErrorCode			(glw::GLenum error, const char* description);
	void						addFBOErrorStatus		(glw::GLenum status, const char* description);
	void						setAllowComplete		(bool);

	void						logLegalResults			(tcu::TestLog& log) const;
	void						logRules				(tcu::TestLog& log) const;

private:
	struct RuleViolation
	{
		glw::GLenum				errorCode;
		std::set<std::string>	rules;
	};

	void						logRule					(tcu::TestLog& log, const std::string& ruleName, const std::set<std::string>& rules) const;
	void						addViolation			(std::vector<RuleViolation>& dst, glw::GLenum code, const char* description) const;

	std::vector<RuleViolation>	m_errorCodes;			//!< Allowed GL errors, GL_NO_ERROR is not allowed
	std::vector<RuleViolation>	m_errorStatuses;		//!< Allowed FBO error statuses, GL_FRAMEBUFFER_COMPLETE is not allowed
	bool						m_allowComplete;		//!< true if (GL_NO_ERROR && GL_FRAMEBUFFER_COMPLETE) is allowed
};

void logFramebufferConfig (const config::Framebuffer& cfg, tcu::TestLog& log);

class Checker
{
public:
								Checker					(const glu::RenderContext&);
	virtual						~Checker				(void) {}

	void						addGLError				(glw::GLenum error, const char* description);
	void						addPotentialGLError		(glw::GLenum error, const char* description);
	void						addFBOStatus			(glw::GLenum status, const char* description);
	void						addPotentialFBOStatus	(glw::GLenum status, const char* description);

	ValidStatusCodes			getStatusCodes			(void) { return m_statusCodes; }

	virtual void				check					(glw::GLenum				attPoint,
														 const config::Attachment&	att,
														 const config::Image*		image) = 0;

protected:
	const glu::RenderContext&	m_renderCtx;

private:
	ValidStatusCodes			m_statusCodes;	//< Allowed return values for glCheckFramebufferStatus.
};

class CheckerFactory
{
public:
	virtual Checker*	createChecker	(const glu::RenderContext&) = 0;
};

typedef std::set<glw::GLenum> AttachmentPoints;
typedef std::set<ImageFormat> Formats;

class FboVerifier
{
public:
								FboVerifier				(const FormatDB&			formats,
														 CheckerFactory&			factory,
														 const glu::RenderContext&	renderCtx);

	ValidStatusCodes			validStatusCodes		(const config::Framebuffer& cfg) const;

private:
	const FormatDB&				m_formats;
	CheckerFactory&				m_factory;
	const glu::RenderContext&	m_renderCtx;
};

} // FboUtil
} // gls
} // deqp

#endif // _GLSFBOUTIL_HPP
