/*-------------------------------------------------------------------------
 * 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 Object lifetime tests.
 *//*--------------------------------------------------------------------*/

#include "es3fLifetimeTests.hpp"

#include "deRandom.hpp"
#include "deUniquePtr.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "gluDrawUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "glsLifetimeTests.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include <vector>

namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace
{

using std::vector;
using de::MovePtr;
using de::Random;
using tcu::RenderTarget;
using tcu::Surface;
using tcu::TestContext;
using tcu::TestLog;
using glu::CallLogWrapper;
using glu::RenderContext;
using glu::ProgramSources;
using glu::VertexArray;
using glu::Buffer;
namespace lt = gls::LifetimeTests;
using namespace lt;
using namespace glw;
typedef TestCase::IterateResult IterateResult;

enum { VIEWPORT_SIZE = 128 };

class ScaleProgram : public glu::ShaderProgram
{
public:
							ScaleProgram	(lt::Context& ctx);
	void					draw			(GLuint vao, GLfloat scale, bool tf, Surface* dst);
	void					setPos			(GLuint buffer, GLuint vao);

private:
	ProgramSources			getSources		(void);

	const RenderContext&	m_renderCtx;
	GLint					m_scaleLoc;
	GLint					m_posLoc;
};

enum { NUM_COMPONENTS = 4, NUM_VERTICES = 3 };

ScaleProgram::ScaleProgram (lt::Context& ctx)
	: glu::ShaderProgram	(ctx.getRenderContext(), getSources())
	, m_renderCtx			(ctx.getRenderContext())
{
	const Functions& gl = m_renderCtx.getFunctions();
	TCU_CHECK(isOk());
	m_scaleLoc = gl.getUniformLocation(getProgram(), "scale");
	m_posLoc = gl.getAttribLocation(getProgram(), "pos");
}

#define GLSL(VERSION, BODY) ("#version " #VERSION "\n" #BODY "\n")

static const char* const s_vertexShaderSrc = GLSL(
	100,
	attribute vec4 pos;
	uniform float scale;
	void main ()
	{
		gl_Position = vec4(scale * pos.xy, pos.zw);
	}
	);

static const char* const s_fragmentShaderSrc = GLSL(
	100,
	void main ()
	{
		gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
	}
	);

ProgramSources ScaleProgram::getSources (void)
{
	using namespace glu;
	ProgramSources sources;
	sources << VertexSource(s_vertexShaderSrc)
			<< FragmentSource(s_fragmentShaderSrc)
			<< TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS)
			<< TransformFeedbackVarying("gl_Position");
	return sources;
}

void ScaleProgram::draw (GLuint vao, GLfloat scale, bool tf, Surface* dst)
{
	const Functions&	gl			= m_renderCtx.getFunctions();
	de::Random			rnd			(vao);
	Rectangle			viewport	= randomViewport(m_renderCtx,
													 VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);
	setViewport(m_renderCtx, viewport);
	gl.clearColor(0, 0, 0, 1);
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	gl.bindVertexArray(vao);
	gl.enableVertexAttribArray(m_posLoc);
	GLU_CHECK_CALL_ERROR(gl.useProgram(getProgram()),
						 gl.getError());

	gl.uniform1f(m_scaleLoc, scale);

	if (tf)
		gl.beginTransformFeedback(GL_TRIANGLES);
	GLU_CHECK_CALL_ERROR(gl.drawArrays(GL_TRIANGLES, 0, 3), gl.getError());
	if (tf)
		gl.endTransformFeedback();

	if (dst != DE_NULL)
		readRectangle(m_renderCtx, viewport, *dst);

	gl.bindVertexArray(0);
}

void ScaleProgram::setPos (GLuint buffer, GLuint vao)
{
	const Functions& gl = m_renderCtx.getFunctions();

	gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
	gl.bindVertexArray(vao);
	GLU_CHECK_CALL_ERROR(
		gl.vertexAttribPointer(m_posLoc, NUM_COMPONENTS, GL_FLOAT, false, 0, DE_NULL),
		gl.getError());
	gl.bindVertexArray(0);
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
	GLU_CHECK_ERROR(gl.getError());
}

class VertexArrayBinder : public SimpleBinder
{
public:
						VertexArrayBinder	(lt::Context& ctx)
							: SimpleBinder	(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true) {}
	void				bind			(GLuint name) { glBindVertexArray(name); }
};

class SamplerBinder : public Binder
{
public:
						SamplerBinder	(lt::Context& ctx) : Binder(ctx) {}
	void				bind			(GLuint name) { glBindSampler(0, name); }
	GLuint				getBinding		(void)
	{
		GLint arr[32] = {};
		glGetIntegerv(GL_SAMPLER_BINDING, arr);
		log() << TestLog::Message << "// First output integer: " << arr[0]
			  << TestLog::EndMessage;
		return arr[0];
	}
	bool				genRequired		(void) const { return true; }
};

class QueryBinder : public Binder
{
public:
						QueryBinder		(lt::Context& ctx) : Binder(ctx) {}
	void				bind			(GLuint name)
	{
		if (name != 0)
			glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
		else
			glEndQuery(GL_ANY_SAMPLES_PASSED);
	}
	GLuint				getBinding		(void) { return 0; }
};

class BufferVAOAttacher : public Attacher
{
public:
						BufferVAOAttacher	(lt::Context& ctx, Type& elementType,
											 Type& varrType, ScaleProgram& program)
							: Attacher		(ctx, elementType, varrType)
							, m_program		(program) {}
	void				initAttachment		(GLuint seed, GLuint element);
	void				attach				(GLuint element, GLuint container);
	void				detach				(GLuint element, GLuint container);
	bool				canAttachDeleted	(void) const { return false; }
	ScaleProgram&		getProgram			(void) { return m_program; }
	GLuint				getAttachment		(GLuint container);

private:
	ScaleProgram&		m_program;
};

static const GLfloat s_varrData[NUM_VERTICES * NUM_COMPONENTS] =
{
	-1.0,  0.0, 0.0, 1.0,
	 1.0,  1.0, 0.0, 1.0,
	 0.0, -1.0, 0.0, 1.0
};

void initBuffer (const Functions& gl, GLuint seed, GLenum usage, GLuint buffer)
{
	gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
	if (seed == 0)
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(s_varrData), s_varrData, usage);
	else
	{
		Random	rnd	(seed);
		GLfloat data[DE_LENGTH_OF_ARRAY(s_varrData)];

		for (int ndx = 0; ndx < NUM_VERTICES; ndx++)
		{
			GLfloat* vertex = &data[ndx * NUM_COMPONENTS];
			vertex[0] = 2.0f * (rnd.getFloat() - 0.5f);
			vertex[1] = 2.0f * (rnd.getFloat() - 0.5f);
			DE_STATIC_ASSERT(NUM_COMPONENTS == 4);
			vertex[2] = 0.0f;
			vertex[3] = 1.0f;
		}
		gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, usage);
	}
	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
	GLU_CHECK_ERROR(gl.getError());
}

void BufferVAOAttacher::initAttachment (GLuint seed, GLuint buffer)
{
	initBuffer(gl(), seed, GL_STATIC_DRAW, buffer);
	log() << TestLog::Message << "// Initialized buffer " << buffer << " from seed " << seed
		  << TestLog::EndMessage;
}

void BufferVAOAttacher::attach (GLuint buffer, GLuint vao)
{
	m_program.setPos(buffer, vao);
	log() << TestLog::Message
		  << "// Set the `pos` attribute in VAO " << vao << " to buffer " << buffer
		  << TestLog::EndMessage;
}

void BufferVAOAttacher::detach (GLuint buffer, GLuint varr)
{
	DE_UNREF(buffer);
	attach(0, varr);
}

GLuint BufferVAOAttacher::getAttachment (GLuint varr)
{
	GLint name = 0;
	gl().bindVertexArray(varr);
	gl().getVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &name);
	gl().bindVertexArray(0);
	GLU_CHECK_ERROR(gl().getError());
	return GLuint(name);
}

class BufferVAOInputAttacher : public InputAttacher
{
public:
						BufferVAOInputAttacher	(BufferVAOAttacher& attacher)
							: InputAttacher		(attacher)
							, m_program			(attacher.getProgram()) {}
	void				drawContainer			(GLuint container, Surface& dst);

private:
	ScaleProgram&		m_program;
};

void BufferVAOInputAttacher::drawContainer (GLuint vao, Surface& dst)
{
	m_program.draw(vao, 1.0, false, &dst);
	log() << TestLog::Message << "// Drew an output image with VAO " << vao
		  << TestLog::EndMessage;
}

class BufferTfAttacher : public Attacher
{
public:
				BufferTfAttacher	(lt::Context& ctx, Type& bufferType, Type& tfType)
					: Attacher		(ctx, bufferType, tfType) {}
	void		initAttachment		(GLuint seed, GLuint element);
	void		attach				(GLuint buffer, GLuint tf);
	void		detach				(GLuint buffer, GLuint tf);
	bool		canAttachDeleted	(void) const { return false; }
	GLuint		getAttachment		(GLuint tf);
};

void BufferTfAttacher::initAttachment (GLuint seed, GLuint buffer)
{
	initBuffer(gl(), seed, GL_DYNAMIC_READ, buffer);
	log() << TestLog::Message << "// Initialized buffer " << buffer << " from seed " << seed
		  << TestLog::EndMessage;
}

void BufferTfAttacher::attach (GLuint buffer, GLuint tf)
{
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
	GLU_CHECK_ERROR(gl().getError());
}

void BufferTfAttacher::detach (GLuint buffer, GLuint tf)
{
	DE_UNREF(buffer);
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
	glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
	GLU_CHECK_ERROR(gl().getError());
}

GLuint BufferTfAttacher::getAttachment (GLuint tf)
{
	GLint ret = 0;
	gl().bindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
	gl().getIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &ret);
	gl().bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
	GLU_CHECK_ERROR(gl().getError());
	return GLuint(ret);
}

class BufferTfOutputAttacher : public OutputAttacher
{
public:
				BufferTfOutputAttacher	(BufferTfAttacher&	attacher, ScaleProgram& program)
					: OutputAttacher	(attacher)
					, m_program			(program) {}
	void		setupContainer		(GLuint seed, GLuint container);
	void		drawAttachment		(GLuint attachment, Surface& dst);

private:
	ScaleProgram&	m_program;
};

void BufferTfOutputAttacher::drawAttachment (GLuint buffer, Surface& dst)
{
	VertexArray vao(getRenderContext());

	m_program.setPos(buffer, *vao);
	m_program.draw(*vao, 1.0, false, &dst);
	log() << TestLog::Message
		  << "// Drew output image with vertices from buffer " << buffer
		  << TestLog::EndMessage;
	GLU_CHECK_ERROR(gl().getError());
}

void BufferTfOutputAttacher::setupContainer (GLuint seed, GLuint tf)
{
	Buffer		posBuf	(getRenderContext());
	VertexArray	vao		(getRenderContext());

	initBuffer(gl(), seed, GL_STATIC_DRAW, *posBuf);
	m_program.setPos(*posBuf, *vao);

	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf);
	m_program.draw(*vao, -1.0, true, DE_NULL);
	log() << TestLog::Message
		  << "// Drew an image with seed " << seed << " with transform feedback to " << tf
		  << TestLog::EndMessage;
	glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
	GLU_CHECK_ERROR(gl().getError());
}

class ES3Types : public ES2Types
{
public:
							ES3Types		(lt::Context& ctx);
private:
	ScaleProgram			m_program;
	QueryBinder				m_queryBind;
	SimpleType				m_queryType;
	SimpleBinder			m_tfBind;
	SimpleType				m_tfType;
	VertexArrayBinder		m_varrBind;
	SimpleType				m_varrType;
	SamplerBinder			m_samplerBind;
	SimpleType				m_samplerType;
	BufferVAOAttacher		m_bufVarrAtt;
	BufferVAOInputAttacher	m_bufVarrInAtt;
	BufferTfAttacher		m_bufTfAtt;
	BufferTfOutputAttacher	m_bufTfOutAtt;
};

ES3Types::ES3Types (lt::Context& ctx)
	: ES2Types		(ctx)
	, m_program		(ctx)
	, m_queryBind	(ctx)
	, m_queryType	(ctx, "query", &CallLogWrapper::glGenQueries,
					 &CallLogWrapper::glDeleteQueries,
					 &CallLogWrapper::glIsQuery, &m_queryBind)
	, m_tfBind		(ctx, &CallLogWrapper::glBindTransformFeedback, GL_TRANSFORM_FEEDBACK,
					 GL_TRANSFORM_FEEDBACK_BINDING, true)
	, m_tfType		(ctx, "transform_feedback", &CallLogWrapper::glGenTransformFeedbacks,
					 &CallLogWrapper::glDeleteTransformFeedbacks,
					 &CallLogWrapper::glIsTransformFeedback, &m_tfBind)
	, m_varrBind	(ctx)
	, m_varrType	(ctx, "vertex_array", &CallLogWrapper::glGenVertexArrays,
					 &CallLogWrapper::glDeleteVertexArrays,
					 &CallLogWrapper::glIsVertexArray, &m_varrBind)
	, m_samplerBind	(ctx)
	, m_samplerType	(ctx, "sampler", &CallLogWrapper::glGenSamplers,
					 &CallLogWrapper::glDeleteSamplers,
					 &CallLogWrapper::glIsSampler, &m_samplerBind, true)
	, m_bufVarrAtt	(ctx, m_bufferType, m_varrType, m_program)
	, m_bufVarrInAtt(m_bufVarrAtt)
	, m_bufTfAtt	(ctx, m_bufferType, m_tfType)
	, m_bufTfOutAtt	(m_bufTfAtt, m_program)
{
	Type* types[] = { &m_queryType, &m_tfType, &m_varrType, &m_samplerType };
	m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));

	m_attachers.push_back(&m_bufVarrAtt);
	m_attachers.push_back(&m_bufTfAtt);

	m_inAttachers.push_back(&m_bufVarrInAtt);
	m_outAttachers.push_back(&m_bufTfOutAtt);
}

class TfDeleteActiveTest : public TestCase, private CallLogWrapper
{
	public:
						TfDeleteActiveTest	(gles3::Context& context,
											 const char* name, const char* description);
	IterateResult		iterate				(void);
};

TfDeleteActiveTest::TfDeleteActiveTest (gles3::Context& context,
										const char* name, const char* description)
	: TestCase			(context, name, description)
	, CallLogWrapper	(context.getRenderContext().getFunctions(),
						 context.getTestContext().getLog())
{
	enableLogging(true);
}

class ScopedTransformFeedbackFeedback
{
public:
							ScopedTransformFeedbackFeedback		(glu::CallLogWrapper& gl, GLenum type);
							~ScopedTransformFeedbackFeedback	(void);

private:
	glu::CallLogWrapper&	m_gl;
};

ScopedTransformFeedbackFeedback::ScopedTransformFeedbackFeedback (glu::CallLogWrapper& gl, GLenum type)
	: m_gl(gl)
{
	m_gl.glBeginTransformFeedback(type);
	GLU_EXPECT_NO_ERROR(m_gl.glGetError(), "glBeginTransformFeedback");
}

ScopedTransformFeedbackFeedback::~ScopedTransformFeedbackFeedback (void)
{
	m_gl.glEndTransformFeedback();
}

IterateResult TfDeleteActiveTest::iterate (void)
{
	static const char* const s_xfbVertexSource =	"#version 300 es\n"
													"void main ()\n"
													"{\n"
													"	gl_Position = vec4(float(gl_VertexID) / 2.0, float(gl_VertexID % 2) / 2.0, 0.0, 1.0);\n"
													"}\n";
	static const char* const s_xfbFragmentSource =	"#version 300 es\n"
													"layout(location=0) out mediump vec4 dEQP_FragColor;\n"
													"void main ()\n"
													"{\n"
													"	dEQP_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
													"}\n";

	glu::Buffer			buf			(m_context.getRenderContext());
	GLuint				tf			= 0;
	glu::ShaderProgram	program		(m_context.getRenderContext(),
									 glu::ProgramSources()
										<< glu::VertexSource(s_xfbVertexSource)
										<< glu::FragmentSource(s_xfbFragmentSource)
										<< glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS)
										<< glu::TransformFeedbackVarying("gl_Position"));

	if (!program.isOk())
	{
		m_testCtx.getLog() << program;
		throw tcu::TestError("failed to build program");
	}

	try
	{
		GLU_CHECK_CALL(glUseProgram(program.getProgram()));
		GLU_CHECK_CALL(glGenTransformFeedbacks(1, &tf));
		GLU_CHECK_CALL(glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf));
		GLU_CHECK_CALL(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, *buf));
		GLU_CHECK_CALL(glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * sizeof(glw::GLfloat[4]), DE_NULL, GL_DYNAMIC_COPY));

		{
			ScopedTransformFeedbackFeedback xfb(static_cast<glu::CallLogWrapper&>(*this), GL_TRIANGLES);

			glDeleteTransformFeedbacks(1, &tf);
			{
				GLenum err = glGetError();
				if (err != GL_INVALID_OPERATION)
					getTestContext().setTestResult(
						QP_TEST_RESULT_FAIL,
						"Deleting active transform feedback did not produce GL_INVALID_OPERATION");
				else
					getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
			}
		}
		GLU_CHECK(); // ScopedTransformFeedbackFeedback::dtor might modify error state

		GLU_CHECK_CALL(glDeleteTransformFeedbacks(1, &tf));
	}
	catch (const glu::Error&)
	{
		glDeleteTransformFeedbacks(1, &tf);
		throw;
	}

	return STOP;
}

class TestGroup : public TestCaseGroup
{
public:
							TestGroup		(gles3::Context& context)
								: TestCaseGroup	(context, "lifetime", "Object lifetime tests")
							{}
	void					init			(void);
private:
	MovePtr<Types>			m_types;
};

void TestGroup::init (void)
{
	gles3::Context&	ctx		= getContext();
	lt::Context		ltCtx	(ctx.getRenderContext(), ctx.getTestContext());

	m_types	= MovePtr<Types>(new ES3Types(ltCtx));

	addTestCases(*this, *m_types);

	TestCaseGroup* deleteActiveGroup =
		new TestCaseGroup(ctx, "delete_active", "Delete active object");
	addChild(deleteActiveGroup);
	deleteActiveGroup->addChild(
		new TfDeleteActiveTest(ctx, "transform_feedback", "Transform Feedback"));
}

} // anonymous

TestCaseGroup* createLifetimeTests (Context& context)
{
	return new TestGroup(context);
}

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