/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 GL context factory using EGL.
 *//*--------------------------------------------------------------------*/

#include "egluGLContextFactory.hpp"

#include "tcuRenderTarget.hpp"
#include "tcuPlatform.hpp"
#include "tcuCommandLine.hpp"

#include "gluDefs.hpp"

#include "egluDefs.hpp"
#include "egluUtil.hpp"
#include "egluGLUtil.hpp"
#include "egluNativeWindow.hpp"
#include "egluNativePixmap.hpp"
#include "egluStrUtil.hpp"

#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"

#include "glwInitFunctions.hpp"
#include "glwInitES20Direct.hpp"
#include "glwInitES30Direct.hpp"

#include "deDynamicLibrary.hpp"
#include "deSTLUtil.hpp"

#include <string>
#include <string>
#include <sstream>

using std::string;
using std::vector;

// \todo [2014-03-12 pyry] Use command line arguments for libraries?

// Default library names
#if !defined(DEQP_GLES2_LIBRARY_PATH)
#	if (DE_OS == DE_OS_WIN32)
#		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.dll"
#	else
#		define DEQP_GLES2_LIBRARY_PATH "libGLESv2.so"
#	endif
#endif

#if !defined(DEQP_GLES3_LIBRARY_PATH)
#	define DEQP_GLES3_LIBRARY_PATH DEQP_GLES2_LIBRARY_PATH
#endif

#if !defined(DEQP_OPENGL_LIBRARY_PATH)
#	if (DE_OS == DE_OS_WIN32)
#		define DEQP_OPENGL_LIBRARY_PATH "opengl32.dll"
#	else
#		define DEQP_OPENGL_LIBRARY_PATH "libGL.so"
#	endif
#endif

namespace eglu
{

using namespace eglw;

namespace
{

enum
{
	DEFAULT_OFFSCREEN_WIDTH		= 512,
	DEFAULT_OFFSCREEN_HEIGHT	= 512
};

class GetProcFuncLoader : public glw::FunctionLoader
{
public:
	GetProcFuncLoader (const Library& egl)
		: m_egl(egl)
	{
	}

	glw::GenericFuncType get (const char* name) const
	{
		return (glw::GenericFuncType)m_egl.getProcAddress(name);
	}

protected:
	const Library& m_egl;
};

class DynamicFuncLoader : public glw::FunctionLoader
{
public:
	DynamicFuncLoader	(de::DynamicLibrary* library)
		: m_library(library)
	{
	}

	glw::GenericFuncType get (const char* name) const
	{
		return (glw::GenericFuncType)m_library->getFunction(name);
	}

private:
	de::DynamicLibrary*	m_library;
};

class RenderContext : public GLRenderContext
{
public:
										RenderContext			(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
	virtual								~RenderContext			(void);

	virtual glu::ContextType			getType					(void) const { return m_renderConfig.type;	}
	virtual const glw::Functions&		getFunctions			(void) const { return m_glFunctions;		}
	virtual const tcu::RenderTarget&	getRenderTarget			(void) const { return m_glRenderTarget;		}
	virtual void						postIterate				(void);

	virtual EGLDisplay					getEGLDisplay			(void) const { return m_eglDisplay;			}
	virtual EGLContext					getEGLContext			(void) const { return m_eglContext;			}

private:
	void								create					(const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config);
	void								destroy					(void);

	const glu::RenderConfig				m_renderConfig;
	const NativeWindowFactory* const	m_nativeWindowFactory;	// Stored in case window must be re-created

	NativeDisplay*						m_display;
	NativeWindow*						m_window;
	NativePixmap*						m_pixmap;

	EGLDisplay							m_eglDisplay;
	EGLConfig							m_eglConfig;
	EGLSurface							m_eglSurface;
	EGLContext							m_eglContext;

	tcu::RenderTarget					m_glRenderTarget;
	de::DynamicLibrary*					m_dynamicGLLibrary;
	glw::Functions						m_glFunctions;
};

RenderContext::RenderContext (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
	: m_renderConfig		(config)
	, m_nativeWindowFactory	(windowFactory)
	, m_display				(DE_NULL)
	, m_window				(DE_NULL)
	, m_pixmap				(DE_NULL)

	, m_eglDisplay			(EGL_NO_DISPLAY)
	, m_eglSurface			(EGL_NO_SURFACE)
	, m_eglContext			(EGL_NO_CONTEXT)

	, m_dynamicGLLibrary	(DE_NULL)
{
	DE_ASSERT(displayFactory);

	try
	{
		create(displayFactory, windowFactory, pixmapFactory, config);
	}
	catch (...)
	{
		destroy();
		throw;
	}
}

RenderContext::~RenderContext(void)
{
	try
	{
		destroy();
	}
	catch (...)
	{
		// destroy() calls EGL functions that are checked and may throw exceptions
	}

	delete m_window;
	delete m_pixmap;
	delete m_display;
	delete m_dynamicGLLibrary;
}

static WindowParams::Visibility getNativeWindowVisibility (glu::RenderConfig::Visibility visibility)
{
	using glu::RenderConfig;

	switch (visibility)
	{
		case RenderConfig::VISIBILITY_HIDDEN:		return WindowParams::VISIBILITY_HIDDEN;
		case RenderConfig::VISIBILITY_VISIBLE:		return WindowParams::VISIBILITY_VISIBLE;
		case RenderConfig::VISIBILITY_FULLSCREEN:	return WindowParams::VISIBILITY_FULLSCREEN;
		default:
			DE_ASSERT((int)visibility == RenderConfig::DONT_CARE);
			return WindowParams::VISIBILITY_DONT_CARE;
	}
}

typedef std::pair<NativeWindow*, EGLSurface> WindowSurfacePair;
typedef std::pair<NativePixmap*, EGLSurface> PixmapSurfacePair;

WindowSurfacePair createWindow (NativeDisplay* nativeDisplay, const NativeWindowFactory* windowFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
{
	const int						width			= (config.width		== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.width);
	const int						height			= (config.height	== glu::RenderConfig::DONT_CARE ? WindowParams::SIZE_DONT_CARE	: config.height);
	const WindowParams::Visibility	visibility		= getNativeWindowVisibility(config.windowVisibility);
	NativeWindow*					nativeWindow	= DE_NULL;
	EGLSurface						surface			= EGL_NO_SURFACE;
	const EGLAttrib					attribList[]	= { EGL_NONE };

	nativeWindow = windowFactory->createWindow(nativeDisplay, eglDisplay, eglConfig, &attribList[0], WindowParams(width, height, visibility));

	try
	{
		surface = eglu::createWindowSurface(*nativeDisplay, *nativeWindow, eglDisplay, eglConfig, attribList);
	}
	catch (...)
	{
		delete nativeWindow;
		throw;
	}

	return WindowSurfacePair(nativeWindow, surface);
}

PixmapSurfacePair createPixmap (NativeDisplay* nativeDisplay, const NativePixmapFactory* pixmapFactory, EGLDisplay eglDisplay, EGLConfig eglConfig, const glu::RenderConfig& config)
{
	const int			width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
	const int			height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
	NativePixmap*		nativePixmap	= DE_NULL;
	EGLSurface			surface			= EGL_NO_SURFACE;
	const EGLAttrib		attribList[]	= { EGL_NONE };

	nativePixmap = pixmapFactory->createPixmap(nativeDisplay, eglDisplay, eglConfig, &attribList[0], width, height);

	try
	{
		surface = eglu::createPixmapSurface(*nativeDisplay, *nativePixmap, eglDisplay, eglConfig, attribList);
	}
	catch (...)
	{
		delete nativePixmap;
		throw;
	}

	return PixmapSurfacePair(nativePixmap, surface);
}

EGLSurface createPBuffer (const Library& egl, EGLDisplay display, EGLConfig eglConfig, const glu::RenderConfig& config)
{
	const int		width			= (config.width		== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_WIDTH	: config.width);
	const int		height			= (config.height	== glu::RenderConfig::DONT_CARE ? DEFAULT_OFFSCREEN_HEIGHT	: config.height);
	EGLSurface		surface;
	const EGLint	attribList[]	=
	{
		EGL_WIDTH,	width,
		EGL_HEIGHT,	height,
		EGL_NONE
	};

	surface = egl.createPbufferSurface(display, eglConfig, &(attribList[0]));
	EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");

	return surface;
}

void RenderContext::create (const NativeDisplayFactory* displayFactory, const NativeWindowFactory* windowFactory, const NativePixmapFactory* pixmapFactory, const glu::RenderConfig& config)
{
	glu::RenderConfig::SurfaceType	surfaceType	= config.surfaceType;

	DE_ASSERT(displayFactory);

	m_display		= displayFactory->createDisplay();
	m_eglDisplay	= eglu::getDisplay(*m_display);

	const Library& egl = m_display->getLibrary();

	{
		EGLint major = 0;
		EGLint minor = 0;
		EGLU_CHECK_CALL(egl, initialize(m_eglDisplay, &major, &minor));
	}

	m_eglConfig	= chooseConfig(egl, m_eglDisplay, config);

	if (surfaceType == glu::RenderConfig::SURFACETYPE_DONT_CARE)
	{
		// Choose based on what selected configuration supports
		const EGLint supportedTypes = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_SURFACE_TYPE);

		if ((supportedTypes & EGL_WINDOW_BIT) != 0)
			surfaceType = glu::RenderConfig::SURFACETYPE_WINDOW;
		else if ((supportedTypes & EGL_PBUFFER_BIT) != 0)
			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC;
		else if ((supportedTypes & EGL_PIXMAP_BIT) != 0)
			surfaceType = glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;
		else
			throw tcu::NotSupportedError("Selected EGL config doesn't support any surface types", DE_NULL, __FILE__, __LINE__);
	}

	switch (surfaceType)
	{
		case glu::RenderConfig::SURFACETYPE_WINDOW:
		{
			if (windowFactory)
			{
				const WindowSurfacePair windowSurface = createWindow(m_display, windowFactory, m_eglDisplay, m_eglConfig, config);
				m_window		= windowSurface.first;
				m_eglSurface	= windowSurface.second;
			}
			else
				throw tcu::NotSupportedError("EGL platform doesn't support windows", DE_NULL, __FILE__, __LINE__);
			break;
		}

		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
		{
			if (pixmapFactory)
			{
				const PixmapSurfacePair pixmapSurface = createPixmap(m_display, pixmapFactory, m_eglDisplay, m_eglConfig, config);
				m_pixmap		= pixmapSurface.first;
				m_eglSurface	= pixmapSurface.second;
			}
			else
				throw tcu::NotSupportedError("EGL platform doesn't support pixmaps", DE_NULL, __FILE__, __LINE__);
			break;
		}

		case glu::RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
			m_eglSurface = createPBuffer(egl, m_eglDisplay, m_eglConfig, config);
			break;

		default:
			throw tcu::InternalError("Invalid surface type");
	}

	m_eglContext = createGLContext(egl, m_eglDisplay, m_eglConfig, config.type);

	EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));

	// Init core functions

	if (hasExtension(egl, m_eglDisplay, "EGL_KHR_get_all_proc_addresses"))
	{
		// Use eglGetProcAddress() for core functions
		GetProcFuncLoader funcLoader(egl);
		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
	}
#if !defined(DEQP_GLES2_RUNTIME_LOAD)
	else if (config.type.getAPI() == glu::ApiType::es(2,0))
	{
		glw::initES20Direct(&m_glFunctions);
	}
#endif
#if !defined(DEQP_GLES3_RUNTIME_LOAD)
	else if (config.type.getAPI() == glu::ApiType::es(3,0))
	{
		glw::initES30Direct(&m_glFunctions);
	}
#endif
	else
	{
		const char* libraryPath = DE_NULL;

		if (glu::isContextTypeES(config.type))
		{
			if (config.type.getMinorVersion() <= 2)
				libraryPath = DEQP_GLES2_LIBRARY_PATH;
			else
				libraryPath = DEQP_GLES3_LIBRARY_PATH;
		}
		else
			libraryPath = DEQP_OPENGL_LIBRARY_PATH;

		m_dynamicGLLibrary = new de::DynamicLibrary(libraryPath);

		DynamicFuncLoader funcLoader(m_dynamicGLLibrary);
		glu::initCoreFunctions(&m_glFunctions, &funcLoader, config.type.getAPI());
	}

	// Init extension functions
	{
		GetProcFuncLoader extLoader(egl);
		glu::initExtensionFunctions(&m_glFunctions, &extLoader, config.type.getAPI());
	}

	{
		EGLint				width, height, depthBits, stencilBits, numSamples;
		tcu::PixelFormat	pixelFmt;

		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&width);
		egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&height);

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

		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_DEPTH_SIZE,		&depthBits);
		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_STENCIL_SIZE,	&stencilBits);
		egl.getConfigAttrib(m_eglDisplay, m_eglConfig, EGL_SAMPLES,			&numSamples);

		EGLU_CHECK_MSG(egl, "Failed to query config attributes");

		m_glRenderTarget = tcu::RenderTarget(width, height, pixelFmt, depthBits, stencilBits, numSamples);
	}
}

void RenderContext::destroy (void)
{
	const Library& egl = m_display->getLibrary();

	if (m_eglDisplay != EGL_NO_DISPLAY)
	{
		EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

		if (m_eglSurface != EGL_NO_SURFACE)
			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));

		if (m_eglContext != EGL_NO_CONTEXT)
			EGLU_CHECK_CALL(egl, destroyContext(m_eglDisplay, m_eglContext));

		EGLU_CHECK_CALL(egl, terminate(m_eglDisplay));

		m_eglDisplay	= EGL_NO_DISPLAY;
		m_eglSurface	= EGL_NO_SURFACE;
		m_eglContext	= EGL_NO_CONTEXT;
	}

	delete m_window;
	delete m_pixmap;
	delete m_display;
	delete m_dynamicGLLibrary;

	m_window			= DE_NULL;
	m_pixmap			= DE_NULL;
	m_display			= DE_NULL;
	m_dynamicGLLibrary	= DE_NULL;
}

void RenderContext::postIterate (void)
{
	const Library& egl = m_display->getLibrary();

	if (m_window)
	{
		EGLBoolean	swapOk		= egl.swapBuffers(m_eglDisplay, m_eglSurface);
		EGLint		error		= egl.getError();
		const bool	badWindow	= error == EGL_BAD_SURFACE || error == EGL_BAD_NATIVE_WINDOW;

		if (!swapOk && !badWindow)
			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());

		try
		{
			m_window->processEvents();
		}
		catch (const WindowDestroyedError&)
		{
			tcu::print("Warning: Window destroyed, recreating...\n");

			EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
			EGLU_CHECK_CALL(egl, destroySurface(m_eglDisplay, m_eglSurface));
			m_eglSurface = EGL_NO_SURFACE;

			delete m_window;
			m_window = DE_NULL;

			try
			{
				WindowSurfacePair windowSurface = createWindow(m_display, m_nativeWindowFactory, m_eglDisplay, m_eglConfig, m_renderConfig);
				m_window		= windowSurface.first;
				m_eglSurface	= windowSurface.second;

				EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext));

				swapOk	= EGL_TRUE;
				error	= EGL_SUCCESS;
			}
			catch (const std::exception& e)
			{
				if (m_eglSurface)
				{
					egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
					egl.destroySurface(m_eglDisplay, m_eglSurface);
					m_eglSurface = EGL_NO_SURFACE;
				}

				delete m_window;
				m_window = DE_NULL;

				throw tcu::ResourceError(string("Failed to re-create window: ") + e.what());
			}
		}

		if (!swapOk)
		{
			DE_ASSERT(badWindow);
			throw tcu::ResourceError(string("eglSwapBuffers() failed: ") + getErrorStr(error).toString());
		}

		// Refresh dimensions
		{
			int	newWidth	= 0;
			int	newHeight	= 0;

			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_WIDTH,		&newWidth);
			egl.querySurface(m_eglDisplay, m_eglSurface, EGL_HEIGHT,	&newHeight);
			EGLU_CHECK_MSG(egl, "Failed to query window size");

			if (newWidth	!= m_glRenderTarget.getWidth() ||
				newHeight	!= m_glRenderTarget.getHeight())
			{
				tcu::print("Warning: Window size changed (%dx%d -> %dx%d), test results might be invalid!\n",
						   m_glRenderTarget.getWidth(), m_glRenderTarget.getHeight(), newWidth, newHeight);

				m_glRenderTarget = tcu::RenderTarget(newWidth, newHeight,
													 m_glRenderTarget.getPixelFormat(),
													 m_glRenderTarget.getDepthBits(),
													 m_glRenderTarget.getStencilBits(),
													 m_glRenderTarget.getNumSamples());
			}
		}
	}
	else
		m_glFunctions.flush();
}

} // anonymous

GLContextFactory::GLContextFactory (const NativeDisplayFactoryRegistry& displayFactoryRegistry)
	: glu::ContextFactory		("egl", "EGL OpenGL Context")
	, m_displayFactoryRegistry	(displayFactoryRegistry)
{
}

glu::RenderContext* GLContextFactory::createContext (const glu::RenderConfig& config, const tcu::CommandLine& cmdLine) const
{
	const NativeDisplayFactory& displayFactory = selectNativeDisplayFactory(m_displayFactoryRegistry, cmdLine);

	const NativeWindowFactory*	windowFactory;
	const NativePixmapFactory*	pixmapFactory;

	try
	{
		windowFactory = &selectNativeWindowFactory(displayFactory, cmdLine);
	}
	catch (const tcu::NotSupportedError&)
	{
		windowFactory = DE_NULL;
	}

	try
	{
		pixmapFactory = &selectNativePixmapFactory(displayFactory, cmdLine);
	}
	catch (const tcu::NotSupportedError&)
	{
		pixmapFactory = DE_NULL;
	}

	return new RenderContext(&displayFactory, windowFactory, pixmapFactory, config);
}

} // eglu
