/*-------------------------------------------------------------------------
 * 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 Simple surface construction test.
 *//*--------------------------------------------------------------------*/

#include "teglCreateSurfaceTests.hpp"

#include "egluNativeDisplay.hpp"
#include "egluNativeWindow.hpp"
#include "egluNativePixmap.hpp"
#include "egluUtil.hpp"
#include "egluUnique.hpp"

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

#include "teglSimpleConfigCase.hpp"
#include "tcuTestContext.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"

#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"
#include "deUniquePtr.hpp"

#include <memory>

namespace deqp
{
namespace egl
{

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

namespace
{

#define EGL_MAKE_VERSION(major, minor) (((major) << 12) | (minor))

enum ApiType
{
	LEGACY,
	EXTENSION,
	EGL15
};

void checkEGLPlatformSupport (const Library& egl)
{
	const vector<std::string>	extensions	= eglu::getClientExtensions(egl);
	if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_platform_base"))
		throw tcu::NotSupportedError("Platform extension 'EGL_EXT_platform_base' not supported", "", __FILE__, __LINE__);
}

void checkEGL15Support (const Library& egl, EGLDisplay display)
{
	// The EGL_VERSION string is laid out as follows:
	// major_version.minor_version space vendor_specific_info
	// Split version from vendor_specific_info
	std::vector<std::string> tokens = de::splitString(egl.queryString(display, EGL_VERSION), ' ');
	// split version into major & minor
	std::vector<std::string> values = de::splitString(tokens[0], '.');
	EGLint eglVersion = EGL_MAKE_VERSION(atoi(values[0].c_str()), atoi(values[1].c_str()));
	if (eglVersion < EGL_MAKE_VERSION(1, 5))
		throw tcu::NotSupportedError("EGL 1.5 not supported", "", __FILE__, __LINE__);
}

EGLSurface createWindowSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativeWindow& window, ApiType createType)
{
	const Library&	egl		= nativeDisplay.getLibrary();
	EGLSurface		surface	= EGL_NO_SURFACE;

	switch (createType)
	{
		case LEGACY:
		{
			surface = egl.createWindowSurface(display, config, window.getLegacyNative(), DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreateWindowSurface() failed");
		}
		break;
		case EXTENSION:
		{
			checkEGLPlatformSupport(egl);
			void *nativeWindow = window.getPlatformExtension();
			surface = egl.createPlatformWindowSurfaceEXT(display, config, nativeWindow, DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurfaceEXT() failed");
		}
		break;
		case EGL15:
		{
			checkEGL15Support(egl, display);
			surface = egl.createPlatformWindowSurface(display, config, window.getPlatformNative(), DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreatePlatformWindowSurface() failed");
		}
	}

	return surface;
}

EGLSurface createPixmapSurface (EGLDisplay display, EGLConfig config, eglu::NativeDisplay& nativeDisplay, eglu::NativePixmap& pixmap, ApiType createType)
{
	const Library&	egl		= nativeDisplay.getLibrary();
	EGLSurface		surface	= EGL_NO_SURFACE;

	switch (createType)
	{
		case LEGACY:
			surface = egl.createPixmapSurface(display, config, pixmap.getLegacyNative(), DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface() failed");
		break;
		case EXTENSION:
			checkEGLPlatformSupport(egl);
			surface = egl.createPlatformPixmapSurfaceEXT(display, config, pixmap.getPlatformExtension(), DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurfaceEXT() failed");
		break;
		case EGL15:
			checkEGL15Support(egl, display);
			surface = egl.createPlatformPixmapSurface(display, config, pixmap.getPlatformNative(), DE_NULL);
			EGLU_CHECK_MSG(egl, "eglCreatePlatformPixmapSurface() failed");
		break;
	}

	return surface;
}

class CreateWindowSurfaceCase : public SimpleConfigCase
{
public:
	CreateWindowSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
		: SimpleConfigCase	(eglTestCtx, name, description, filters)
		, m_createType	(createType)
	{
	}

	void executeForConfig (EGLDisplay display, EGLConfig config)
	{
		const Library&						egl				= m_eglTestCtx.getLibrary();
		TestLog&							log				= m_testCtx.getLog();
		EGLint								id				= eglu::getConfigID(egl, display, config);
		const eglu::NativeWindowFactory&	windowFactory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());

		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT

		switch (m_createType)
		{
			case LEGACY:
			{
				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
					TCU_THROW(NotSupportedError, "Native window doesn't support legacy eglCreateWindowSurface()");
			}
			break;
			case EXTENSION:
			{
				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
					TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurfaceEXT()");
			}
			break;
			case EGL15:
			{
				if ((windowFactory.getCapabilities() & eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
					TCU_THROW(NotSupportedError, "Native window doesn't support eglCreatePlatformWindowSurface()");
			}
			break;
		}

		log << TestLog::Message << "Creating window surface with config ID " << id << TestLog::EndMessage;
		EGLU_CHECK_MSG(egl, "init");

		{
			const int							width			= 64;
			const int							height			= 64;
			de::UniquePtr<eglu::NativeWindow>	window			(windowFactory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(width, height, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
			eglu::UniqueSurface					surface			(egl, display, createWindowSurface(display, config, m_eglTestCtx.getNativeDisplay(), *window, m_createType));

			EGLint								windowWidth		= 0;
			EGLint								windowHeight	= 0;

			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&windowWidth));
			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&windowHeight));

			if (windowWidth <= 0 || windowHeight <= 0)
			{
				log << TestLog::Message << "  Fail, invalid surface size " << windowWidth << "x" << windowHeight << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
			}
			else
				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
		}
	}

private:
	ApiType		m_createType;
};

class CreatePixmapSurfaceCase : public SimpleConfigCase
{
public:
	CreatePixmapSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, ApiType createType, const eglu::FilterList& filters)
		: SimpleConfigCase(eglTestCtx, name, description, filters)
		, m_createType	(createType)
	{
	}

	void executeForConfig (EGLDisplay display, EGLConfig config)
	{
		const Library&						egl				= m_eglTestCtx.getLibrary();
		TestLog&							log				= m_testCtx.getLog();
		EGLint								id				= eglu::getConfigID(egl, display, config);
		const eglu::NativePixmapFactory&	pixmapFactory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());

		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT

		switch (m_createType)
		{
			case LEGACY:
			{
				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_LEGACY) == 0)
					TCU_THROW(NotSupportedError, "Native pixmap doesn't support legacy eglCreatePixmapSurface()");
			}
			break;
			case EXTENSION:
			{
				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION) == 0)
					TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurfaceEXT()");
			}
			break;
			case EGL15:
			{
				if ((pixmapFactory.getCapabilities() & eglu::NativePixmap::CAPABILITY_CREATE_SURFACE_PLATFORM) == 0)
					TCU_THROW(NotSupportedError, "Native pixmap doesn't support eglCreatePlatformPixmapSurface()");
			}
			break;
		}

		log << TestLog::Message << "Creating pixmap surface with config ID " << id << TestLog::EndMessage;
		EGLU_CHECK_MSG(egl, "init");

		{
			const int							width			= 64;
			const int							height			= 64;
			de::UniquePtr<eglu::NativePixmap>	pixmap			(pixmapFactory.createPixmap(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, width, height));
			eglu::UniqueSurface					surface			(egl, display, createPixmapSurface(display, config, m_eglTestCtx.getNativeDisplay(), *pixmap, m_createType));
			EGLint								pixmapWidth		= 0;
			EGLint								pixmapHeight	= 0;

			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_WIDTH,		&pixmapWidth));
			EGLU_CHECK_CALL(egl, querySurface(display, *surface, EGL_HEIGHT,	&pixmapHeight));

			if (pixmapWidth <= 0 || pixmapHeight <= 0)
			{
				log << TestLog::Message << "  Fail, invalid surface size " << pixmapWidth << "x" << pixmapHeight << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid surface size");
			}
			else
				log << TestLog::Message << "  Pass" << TestLog::EndMessage;
		}
	}

private:
	ApiType		m_createType;
};

class CreatePbufferSurfaceCase : public SimpleConfigCase
{
public:
	CreatePbufferSurfaceCase (EglTestContext& eglTestCtx, const char* name, const char* description, const eglu::FilterList& filters)
		: SimpleConfigCase(eglTestCtx, name, description, filters)
	{
	}

	void executeForConfig (EGLDisplay display, EGLConfig config)
	{
		const Library&	egl		= m_eglTestCtx.getLibrary();
		TestLog&		log		= m_testCtx.getLog();
		EGLint			id		= eglu::getConfigID(egl, display, config);
		int				width	= 64;
		int				height	= 64;

		// \todo [2011-03-23 pyry] Iterate thru all possible combinations of EGL_RENDER_BUFFER, EGL_VG_COLORSPACE and EGL_VG_ALPHA_FORMAT

		log << TestLog::Message << "Creating pbuffer surface with config ID " << id << TestLog::EndMessage;
		EGLU_CHECK_MSG(egl, "init");

		// Clamp to maximums reported by implementation
		width	= deMin32(width, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_WIDTH));
		height	= deMin32(height, eglu::getConfigAttribInt(egl, display, config, EGL_MAX_PBUFFER_HEIGHT));

		if (width == 0 || height == 0)
		{
			log << TestLog::Message << "  Fail, maximum pbuffer size of " << width << "x" << height << " reported" << TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid maximum pbuffer size");
			return;
		}

		// \todo [2011-03-23 pyry] Texture-backed variants!

		const EGLint attribs[] =
		{
			EGL_WIDTH,			width,
			EGL_HEIGHT,			height,
			EGL_TEXTURE_FORMAT,	EGL_NO_TEXTURE,
			EGL_NONE
		};

		EGLSurface surface = egl.createPbufferSurface(display, config, attribs);
		EGLU_CHECK_MSG(egl, "Failed to create pbuffer");
		TCU_CHECK(surface != EGL_NO_SURFACE);
		egl.destroySurface(display, surface);

		log << TestLog::Message << "  Pass" << TestLog::EndMessage;
	}
};

} // anonymous

CreateSurfaceTests::CreateSurfaceTests (EglTestContext& eglTestCtx)
	: TestCaseGroup(eglTestCtx, "create_surface", "Basic surface construction tests")
{
}

CreateSurfaceTests::~CreateSurfaceTests (void)
{
}

template <deUint32 Type>
static bool surfaceType (const eglu::CandidateConfig& c)
{
	return (c.surfaceType() & Type) == Type;
}

void CreateSurfaceTests::init (void)
{
	// Window surfaces
	{
		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "window", "Window surfaces");
		addChild(windowGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_WINDOW_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
	}

	// Pixmap surfaces
	{
		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "pixmap", "Pixmap surfaces");
		addChild(pixmapGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_PIXMAP_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), LEGACY, *i));
	}

	// Pbuffer surfaces
	{
		tcu::TestCaseGroup* pbufferGroup = new tcu::TestCaseGroup(m_testCtx, "pbuffer", "Pbuffer surfaces");
		addChild(pbufferGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_PBUFFER_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			pbufferGroup->addChild(new CreatePbufferSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
	}

	// Window surfaces with new platform extension
	{
		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_window", "Window surfaces with platform extension");
		addChild(windowGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_WINDOW_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
	}

	// Pixmap surfaces with new platform extension
	{
		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_ext_pixmap", "Pixmap surfaces with platform extension");
		addChild(pixmapGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_PIXMAP_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EXTENSION, *i));
	}
	//
	// Window surfaces with EGL 1.5 CreateWindowSurface
	{
		tcu::TestCaseGroup* windowGroup = new tcu::TestCaseGroup(m_testCtx, "platform_window", "Window surfaces with EGL 1.5");
		addChild(windowGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_WINDOW_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			windowGroup->addChild(new CreateWindowSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
	}

	// Pixmap surfaces with EGL 1.5 CreateWindowSurface
	{
		tcu::TestCaseGroup* pixmapGroup = new tcu::TestCaseGroup(m_testCtx, "platform_pixmap", "Pixmap surfaces with EGL 1.5");
		addChild(pixmapGroup);

		eglu::FilterList baseFilters;
		baseFilters << surfaceType<EGL_PIXMAP_BIT>;

		vector<NamedFilterList> filterLists;
		getDefaultFilterLists(filterLists, baseFilters);

		for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
			pixmapGroup->addChild(new CreatePixmapSurfaceCase(m_eglTestCtx, i->getName(), i->getDescription(), EGL15, *i));
	}
}

} // egl
} // deqp
