/*-------------------------------------------------------------------------
 * 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 Occlusion query stress tests
 *//*--------------------------------------------------------------------*/

#include "es3sOcclusionQueryTests.hpp"

#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deString.h"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuSurface.hpp"
#include "gluShaderProgram.hpp"
#include "deClock.h"

#include "glw.h"

#include <vector>

using std::vector;
using tcu::TestLog;

namespace deqp
{
namespace gles3
{
namespace Stress
{

static const tcu::Vec4	OCCLUDER_COLOR			= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
static const tcu::Vec4	TARGET_COLOR			= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
static const int		NUM_CASE_ITERATIONS		= 3;
static const int		NUM_GENERATED_VERTICES	= 100;
static const int		WATCHDOG_INTERVAL		= 50; // Touch watchdog every N iterations.

class OcclusionQueryStressCase : public TestCase
{
public:
								OcclusionQueryStressCase		(Context& ctx, const char* name, const char* desc, int m_numOccluderDraws, int m_numOccludersPerDraw, int m_numTargetDraws, int m_numTargetsPerDraw, int m_numQueries, deUint32 m_queryMode);
								~OcclusionQueryStressCase		(void);

	void						init							(void);
	void						deinit							(void);
	IterateResult				iterate							(void);

private:
								OcclusionQueryStressCase		(const OcclusionQueryStressCase&);
	OcclusionQueryStressCase&	operator=						(const OcclusionQueryStressCase&);

	int							m_numOccluderDraws;
	int							m_numOccludersPerDraw;
	int							m_numTargetDraws;
	int							m_numTargetsPerDraw;
	int							m_numQueries;
	deUint32					m_queryMode;

	glu::RenderContext&			m_renderCtx;
	glu::ShaderProgram*			m_program;
	int							m_iterNdx;
	de::Random					m_rnd;

};

OcclusionQueryStressCase::OcclusionQueryStressCase (Context& ctx, const char* name, const char* desc, int numOccluderDraws, int numOccludersPerDraw, int numTargetDraws, int numTargetsPerDraw, int numQueries, deUint32 queryMode)
	: TestCase				(ctx, name, desc)
	, m_numOccluderDraws	(numOccluderDraws)
	, m_numOccludersPerDraw	(numOccludersPerDraw)
	, m_numTargetDraws		(numTargetDraws)
	, m_numTargetsPerDraw	(numTargetsPerDraw)
	, m_numQueries			(numQueries)
	, m_queryMode			(queryMode)
	, m_renderCtx			(ctx.getRenderContext())
	, m_program				(DE_NULL)
	, m_iterNdx				(0)
	, m_rnd					(deStringHash(name))
{
}

OcclusionQueryStressCase::~OcclusionQueryStressCase (void)
{
	OcclusionQueryStressCase::deinit();
}

void OcclusionQueryStressCase::init (void)
{
	const char*	vertShaderSource =
				"#version 300 es\n"
				"layout(location = 0) in mediump vec4 a_position;\n"
				"\n"
				"void main (void)\n"
				"{\n"
				"	gl_Position = a_position;\n"
				"}\n";

	const char* fragShaderSource =
				"#version 300 es\n"
				"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
				"uniform mediump vec4 u_color;\n"
				"\n"
				"void main (void)\n"
				"{\n"
				"	mediump float depth_gradient = gl_FragCoord.z;\n"
				"	mediump float bias = 0.1;\n"
				"	dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n"
				"}\n";

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertShaderSource, fragShaderSource));

	if (!m_program->isOk())
	{
		m_testCtx.getLog() << *m_program;
		TCU_FAIL("Failed to compile shader program");
	}

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); // Initialize test result to pass.
	GLU_CHECK_MSG ("Case initialization finished");
}

void OcclusionQueryStressCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}


OcclusionQueryStressCase::IterateResult OcclusionQueryStressCase::iterate (void)
{
	tcu::TestLog&				log				 = m_testCtx.getLog();
	deUint32					colorUnif		 = glGetUniformLocation(m_program->getProgram(), "u_color");

	std::vector<float>			vertices;
	std::vector<float>			occluderVertices;
	std::vector<float>			targetVertices;
	std::vector<deUint32>		queryIds		 (m_numQueries, 0);
	std::vector<deUint32>		queryResultReady (m_numQueries, 0);
	std::vector<deUint32>		queryResult		 (m_numQueries, 0);

	std::string					sectionName		("Case iteration " + de::toString(m_iterNdx+1) + "/" + de::toString(NUM_CASE_ITERATIONS));
	tcu::ScopedLogSection		section			(log, sectionName.c_str(), sectionName.c_str());

	log << tcu::TestLog::Message << "Parameters:\n"
								 << "- Number of occlusion queries: "		 << m_numQueries		<< ".\n"
								 << "- Number of occluder draws per query: " << m_numOccluderDraws	<< ", primitives per draw: " << m_numOccludersPerDraw << ".\n"
								 << "- Number of target draws per query: "	 << m_numTargetDraws	<< ", primitives per draw: " << m_numTargetsPerDraw	  << ".\n"
		<< tcu::TestLog::EndMessage;

	int numOccluderIndicesPerDraw = 3*m_numOccludersPerDraw;
	int numTargetIndicesPerDraw = 3*m_numTargetsPerDraw;

	// Generate vertex data

	vertices.resize(4*NUM_GENERATED_VERTICES);

	for (int i = 0; i < NUM_GENERATED_VERTICES; i++)
	{
		vertices[4*i    ] = m_rnd.getFloat(-1.0f, 1.0f);
		vertices[4*i + 1] = m_rnd.getFloat(-1.0f, 1.0f);
		vertices[4*i + 2] = m_rnd.getFloat(0.0f, 1.0f);
		vertices[4*i + 3] = 1.0f;
	}

	// Generate primitives

	occluderVertices.resize(4*numOccluderIndicesPerDraw * m_numOccluderDraws);

	for (int i = 0; i < numOccluderIndicesPerDraw * m_numOccluderDraws; i++)
	{
		int vtxNdx = m_rnd.getInt(0, NUM_GENERATED_VERTICES-1);
		occluderVertices[4*i    ] = vertices[4*vtxNdx];
		occluderVertices[4*i + 1] = vertices[4*vtxNdx + 1];
		occluderVertices[4*i + 2] = vertices[4*vtxNdx + 2];
		occluderVertices[4*i + 3] = vertices[4*vtxNdx + 3];
	}

	targetVertices.resize(4*numTargetIndicesPerDraw * m_numTargetDraws);

	for (int i = 0; i < numTargetIndicesPerDraw * m_numTargetDraws; i++)
	{
		int vtxNdx = m_rnd.getInt(0, NUM_GENERATED_VERTICES-1);
		targetVertices[4*i    ] = vertices[4*vtxNdx];
		targetVertices[4*i + 1] = vertices[4*vtxNdx + 1];
		targetVertices[4*i + 2] = vertices[4*vtxNdx + 2];
		targetVertices[4*i + 3] = vertices[4*vtxNdx + 3];
	}

	TCU_CHECK(m_program);

	glClearColor				(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepthf				(1.0f);
	glClear						(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable					(GL_DEPTH_TEST);
	glUseProgram				(m_program->getProgram());
	glEnableVertexAttribArray	(0);

	deUint64 time = deGetMicroseconds();

	for (int queryIter = 0; queryIter < m_numQueries; queryIter++)
	{
		// Draw occluders

		glUniform4f	(colorUnif, OCCLUDER_COLOR.x(), OCCLUDER_COLOR.y(), OCCLUDER_COLOR.z(), OCCLUDER_COLOR.w());

		for (int drawIter = 0; drawIter < m_numOccluderDraws; drawIter++)
		{
			glVertexAttribPointer	(0, 4, GL_FLOAT, GL_FALSE, 0, &occluderVertices[drawIter * numOccluderIndicesPerDraw]);
			glDrawArrays			(GL_TRIANGLES, 0, numOccluderIndicesPerDraw);
		}

		// Begin occlusion query

		glGenQueries	(1, &queryIds[queryIter]);
		glBeginQuery	(m_queryMode, queryIds[queryIter]);

		// Draw targets

		glUniform4f	(colorUnif, TARGET_COLOR.x(), TARGET_COLOR.y(), TARGET_COLOR.z(), TARGET_COLOR.w());

		for (int drawIter = 0; drawIter < m_numTargetDraws; drawIter++)
		{
			glVertexAttribPointer	(0, 4, GL_FLOAT, GL_FALSE, 0, &targetVertices[drawIter * numTargetIndicesPerDraw]);
			glDrawArrays			(GL_TRIANGLES, 0, numTargetIndicesPerDraw);
		}

		// End occlusion query

		glEndQuery		(m_queryMode);

		if ((queryIter % WATCHDOG_INTERVAL) == 0 && m_testCtx.getWatchDog())
			qpWatchDog_touch(m_testCtx.getWatchDog());
	}

	glFinish();
	glDisable(GL_DEPTH_TEST);

	deUint64 dTime = deGetMicroseconds() - time;
	log << tcu::TestLog::Message << "Total duration: " << dTime/1000 << " ms" << tcu::TestLog::EndMessage;

	// Get results

	for (int queryIter = 0; queryIter < m_numQueries; queryIter++)
	{
		glGetQueryObjectuiv(queryIds[queryIter], GL_QUERY_RESULT_AVAILABLE, &queryResultReady[queryIter]);

		if (queryResultReady[queryIter] == GL_TRUE)
		{
			glGetQueryObjectuiv(queryIds[queryIter], GL_QUERY_RESULT, &queryResult[queryIter]);
		}
		else
			TCU_FAIL("Occlusion query failed to return a result after glFinish()");

		if ((queryIter % WATCHDOG_INTERVAL) == 0 && m_testCtx.getWatchDog())
			qpWatchDog_touch(m_testCtx.getWatchDog());
	}

	glDeleteQueries	(m_numQueries, &queryIds[0]);
	GLU_CHECK_MSG	("Occlusion queries finished");

	log << tcu::TestLog::Message << "Case passed!" << tcu::TestLog::EndMessage;

	return (++m_iterNdx < NUM_CASE_ITERATIONS) ? CONTINUE : STOP;
}


OcclusionQueryTests::OcclusionQueryTests (Context& testCtx)
	: TestCaseGroup(testCtx, "occlusion_query", "Occlusion query stress tests")
{
}

OcclusionQueryTests::~OcclusionQueryTests(void)
{
}

void OcclusionQueryTests::init (void)
{
	addChild(new OcclusionQueryStressCase(m_context, "10_queries_2500_triangles_per_query",		"10_queries_2500_triangles_per_query",	  49, 50, 1, 50, 10,	GL_ANY_SAMPLES_PASSED));
	addChild(new OcclusionQueryStressCase(m_context, "100_queries_2500_triangles_per_query",	"100_queries_2500_triangles_per_query",	  49, 50, 1, 50, 100,	GL_ANY_SAMPLES_PASSED));
	addChild(new OcclusionQueryStressCase(m_context, "1000_queries_500_triangles_per_query",	"1000_queries_500_triangles_per_query",	  49, 10, 1, 10, 1000,	GL_ANY_SAMPLES_PASSED));
	addChild(new OcclusionQueryStressCase(m_context, "10000_queries_20_triangles_per_query",	"10000_queries_20_triangles_per_query",   1,  19, 1, 1,  10000,	GL_ANY_SAMPLES_PASSED));
}

} // Stress
} // gles3
} // deqp
