#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
