/*-------------------------------------------------------------------------
 * drawElements Quality Program EGL 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 Color clear case.
 *//*--------------------------------------------------------------------*/

#include "teglColorClearCase.hpp"
#include "tcuTestLog.hpp"
#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"
#include "egluUtil.hpp"
#include "deRandom.hpp"
#include "deString.h"
#include "tcuImageCompare.hpp"
#include "tcuVector.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuPixelFormat.hpp"
#include "glwFunctions.hpp"
#include "deThread.hpp"
#include "deSemaphore.hpp"
#include "deSharedPtr.hpp"
#include "teglGLES1RenderUtil.hpp"
#include "teglGLES2RenderUtil.hpp"
#include "teglVGRenderUtil.hpp"

#include <memory>
#include <iterator>

namespace deqp
{
namespace egl
{

using tcu::TestLog;
using tcu::RGBA;
using std::vector;
using namespace eglw;

// Utilities.

struct ClearOp
{
	ClearOp (int x_, int y_, int width_, int height_, const tcu::RGBA& color_)
		: x			(x_)
		, y			(y_)
		, width		(width_)
		, height	(height_)
		, color		(color_)
	{
	}

	ClearOp (void)
		: x			(0)
		, y			(0)
		, width		(0)
		, height	(0)
		, color		(0)
	{
	}

	int			x;
	int			y;
	int			width;
	int			height;
	tcu::RGBA	color;
};

struct ApiFunctions
{
	glw::Functions	gl;
};

static ClearOp computeRandomClear (de::Random& rnd, int width, int height)
{
	int			w		= rnd.getInt(1, width);
	int			h		= rnd.getInt(1, height);
	int			x		= rnd.getInt(0, width-w);
	int			y		= rnd.getInt(0, height-h);
	tcu::RGBA	col		(rnd.getUint32());

	return ClearOp(x, y, w, h, col);
}

static void renderReference (tcu::Surface& dst, const vector<ClearOp>& clears, const tcu::PixelFormat& pixelFormat)
{
	for (vector<ClearOp>::const_iterator clearIter = clears.begin(); clearIter != clears.end(); clearIter++)
	{
		tcu::PixelBufferAccess access = tcu::getSubregion(dst.getAccess(), clearIter->x, clearIter->y, 0, clearIter->width, clearIter->height, 1);
		tcu::clear(access, pixelFormat.convertColor(clearIter->color).toIVec());
	}
}

static void renderClear (EGLint api, const ApiFunctions& func, const ClearOp& clear)
{
	switch (api)
	{
		case EGL_OPENGL_ES_BIT:			gles1::clear(clear.x, clear.y, clear.width, clear.height, clear.color.toVec());				break;
		case EGL_OPENGL_ES2_BIT:		gles2::clear(func.gl, clear.x, clear.y, clear.width, clear.height, clear.color.toVec());	break;
		case EGL_OPENGL_ES3_BIT_KHR:	gles2::clear(func.gl, clear.x, clear.y, clear.width, clear.height, clear.color.toVec());	break;
		case EGL_OPENVG_BIT:			vg::clear	(clear.x, clear.y, clear.width, clear.height, clear.color.toVec());				break;
		default:
			DE_ASSERT(DE_FALSE);
	}
}

static void readPixels (EGLint api, const ApiFunctions& func, tcu::Surface& dst)
{
	switch (api)
	{
		case EGL_OPENGL_ES_BIT:			gles1::readPixels	(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
		case EGL_OPENGL_ES2_BIT:		gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
		case EGL_OPENGL_ES3_BIT_KHR:	gles2::readPixels	(func.gl, dst, 0, 0, dst.getWidth(), dst.getHeight());	break;
		case EGL_OPENVG_BIT:			vg::readPixels		(dst, 0, 0, dst.getWidth(), dst.getHeight());			break;
		default:
			DE_ASSERT(DE_FALSE);
	}
}

static tcu::PixelFormat getPixelFormat (const Library& egl, EGLDisplay display, EGLConfig config)
{
	tcu::PixelFormat pixelFmt;

	egl.getConfigAttrib(display, config, EGL_RED_SIZE,		&pixelFmt.redBits);
	egl.getConfigAttrib(display, config, EGL_GREEN_SIZE,	&pixelFmt.greenBits);
	egl.getConfigAttrib(display, config, EGL_BLUE_SIZE,		&pixelFmt.blueBits);
	egl.getConfigAttrib(display, config, EGL_ALPHA_SIZE,	&pixelFmt.alphaBits);

	return pixelFmt;
}

// SingleThreadColorClearCase

SingleThreadColorClearCase::SingleThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
{
}

void SingleThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
{
	const Library&		egl			= m_eglTestCtx.getLibrary();

	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
	const int			width		= surfaceSize.x();
	const int			height		= surfaceSize.y();

	TestLog&			log			= m_testCtx.getLog();

	tcu::Surface		refFrame	(width, height);
	tcu::Surface		frame		(width, height);
	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);

	de::Random			rnd			(deStringHash(getName()));
	vector<ClearOp>		clears;
	const int			ctxClears	= 2;
	const int			numIters	= 3;

	ApiFunctions		funcs;

	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));

	// Clear to black using first context.
	{
		EGLint		api			= contexts[0].first;
		EGLContext	context		= contexts[0].second;
		ClearOp		clear		(0, 0, width, height, RGBA::black);

		egl.makeCurrent(display, surface, surface, context);
		EGLU_CHECK_MSG(egl, "eglMakeCurrent");

		renderClear(api, funcs, clear);
		clears.push_back(clear);
	}

	// Render.
	for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
	{
		for (vector<std::pair<EGLint, EGLContext> >::const_iterator ctxIter = contexts.begin(); ctxIter != contexts.end(); ctxIter++)
		{
			EGLint		api			= ctxIter->first;
			EGLContext	context		= ctxIter->second;

			egl.makeCurrent(display, surface, surface, context);
			EGLU_CHECK_MSG(egl, "eglMakeCurrent");

			for (int clearNdx = 0; clearNdx < ctxClears; clearNdx++)
			{
				ClearOp clear = computeRandomClear(rnd, width, height);

				renderClear(api, funcs, clear);
				clears.push_back(clear);
			}
		}
	}

	// Read pixels using first context. \todo [pyry] Randomize?
	{
		EGLint		api		= contexts[0].first;
		EGLContext	context	= contexts[0].second;

		egl.makeCurrent(display, surface, surface, context);
		EGLU_CHECK_MSG(egl, "eglMakeCurrent");

		readPixels(api, funcs, frame);
	}

	egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
	EGLU_CHECK_MSG(egl, "eglMakeCurrent");

	// Render reference.
	renderReference(refFrame, clears, pixelFmt);

	// Compare images
	{
		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, RGBA(1,1,1,1) + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);

		if (!imagesOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
	}
}

// MultiThreadColorClearCase

enum
{
	NUM_CLEARS_PER_PACKET	= 2 //!< Number of clears performed in one context activation in one thread.
};

class ColorClearThread;

typedef de::SharedPtr<ColorClearThread>	ColorClearThreadSp;
typedef de::SharedPtr<de::Semaphore>	SemaphoreSp;

struct ClearPacket
{
	ClearPacket (void)
	{
	}

	ClearOp			clears[NUM_CLEARS_PER_PACKET];
	SemaphoreSp		wait;
	SemaphoreSp		signal;
};

class ColorClearThread : public de::Thread
{
public:
	ColorClearThread (const Library& egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLint api, const ApiFunctions& funcs, const std::vector<ClearPacket>& packets)
		: m_egl		(egl)
		, m_display	(display)
		, m_surface	(surface)
		, m_context	(context)
		, m_api		(api)
		, m_funcs	(funcs)
		, m_packets	(packets)
	{
	}

	void run (void)
	{
		for (std::vector<ClearPacket>::const_iterator packetIter = m_packets.begin(); packetIter != m_packets.end(); packetIter++)
		{
			// Wait until it is our turn.
			packetIter->wait->decrement();

			// Acquire context.
			m_egl.makeCurrent(m_display, m_surface, m_surface, m_context);

			// Execute clears.
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(packetIter->clears); ndx++)
				renderClear(m_api, m_funcs, packetIter->clears[ndx]);

			// Release context.
			m_egl.makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

			// Signal completion.
			packetIter->signal->increment();
		}
	}

private:
	const Library&					m_egl;
	EGLDisplay						m_display;
	EGLSurface						m_surface;
	EGLContext						m_context;
	EGLint							m_api;
	const ApiFunctions&				m_funcs;
	const std::vector<ClearPacket>&	m_packets;
};

MultiThreadColorClearCase::MultiThreadColorClearCase (EglTestContext& eglTestCtx, const char* name, const char* description, EGLint api, EGLint surfaceType, const eglu::FilterList& filters, int numContextsPerApi)
	: MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
{
}

void MultiThreadColorClearCase::executeForContexts (EGLDisplay display, EGLSurface surface, const Config& config, const std::vector<std::pair<EGLint, EGLContext> >& contexts)
{
	const Library&		egl			= m_eglTestCtx.getLibrary();

	const tcu::IVec2	surfaceSize	= eglu::getSurfaceSize(egl, display, surface);
	const int			width		= surfaceSize.x();
	const int			height		= surfaceSize.y();

	TestLog&			log			= m_testCtx.getLog();

	tcu::Surface		refFrame	(width, height);
	tcu::Surface		frame		(width, height);
	tcu::PixelFormat	pixelFmt	= getPixelFormat(egl, display, config.config);

	de::Random			rnd			(deStringHash(getName()));

	ApiFunctions		funcs;

	m_eglTestCtx.initGLFunctions(&funcs.gl, glu::ApiType::es(2,0));

	// Create clear packets.
	const int						numPacketsPerThread		= 2;
	int								numThreads				= (int)contexts.size();
	int								numPackets				= numThreads * numPacketsPerThread;

	vector<SemaphoreSp>				semaphores				(numPackets+1);
	vector<vector<ClearPacket> >	packets					(numThreads);
	vector<ColorClearThreadSp>		threads					(numThreads);

	// Initialize semaphores.
	for (vector<SemaphoreSp>::iterator sem = semaphores.begin(); sem != semaphores.end(); ++sem)
		*sem = SemaphoreSp(new de::Semaphore(0));

	// Create packets.
	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
	{
		packets[threadNdx].resize(numPacketsPerThread);

		for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
		{
			ClearPacket& packet = packets[threadNdx][packetNdx];

			// Threads take turns with packets.
			packet.wait		= semaphores[packetNdx*numThreads + threadNdx];
			packet.signal	= semaphores[packetNdx*numThreads + threadNdx + 1];

			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
			{
				// First clear is always full-screen black.
				if (threadNdx == 0 && packetNdx == 0 && clearNdx == 0)
					packet.clears[clearNdx] = ClearOp(0, 0, width, height, RGBA::black);
				else
					packet.clears[clearNdx] = computeRandomClear(rnd, width, height);
			}
		}
	}

	// Create and launch threads (actual rendering starts once first semaphore is signaled).
	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
	{
		threads[threadNdx] = ColorClearThreadSp(new ColorClearThread(egl, display, surface, contexts[threadNdx].second, contexts[threadNdx].first, funcs, packets[threadNdx]));
		threads[threadNdx]->start();
	}

	// Signal start and wait until complete.
	semaphores.front()->increment();
	semaphores.back()->decrement();

	// Read pixels using first context. \todo [pyry] Randomize?
	{
		EGLint		api		= contexts[0].first;
		EGLContext	context	= contexts[0].second;

		egl.makeCurrent(display, surface, surface, context);
		EGLU_CHECK_MSG(egl, "eglMakeCurrent");

		readPixels(api, funcs, frame);
	}

	egl.makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
	EGLU_CHECK_MSG(egl, "eglMakeCurrent");

	// Join threads.
	for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
		threads[threadNdx]->join();

	// Render reference.
	for (int packetNdx = 0; packetNdx < numPacketsPerThread; packetNdx++)
	{
		for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
		{
			const ClearPacket& packet = packets[threadNdx][packetNdx];
			for (int clearNdx = 0; clearNdx < DE_LENGTH_OF_ARRAY(packet.clears); clearNdx++)
			{
				tcu::PixelBufferAccess access = tcu::getSubregion(refFrame.getAccess(),
																  packet.clears[clearNdx].x, packet.clears[clearNdx].y, 0,
																  packet.clears[clearNdx].width, packet.clears[clearNdx].height, 1);
				tcu::clear(access, pixelFmt.convertColor(packet.clears[clearNdx].color).toIVec());
			}
		}
	}

	// Compare images
	{
		bool imagesOk = tcu::pixelThresholdCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame, RGBA(1,1,1,1) + pixelFmt.getColorThreshold(), tcu::COMPARE_LOG_RESULT);

		if (!imagesOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
	}
}

} // egl
} // deqp
