/*-------------------------------------------------------------------------
 * 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 Android EGL and Vulkan platforms.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidPlatform.hpp"
#include "tcuAndroidUtil.hpp"
#include "gluRenderContext.hpp"
#include "egluNativeDisplay.hpp"
#include "egluNativeWindow.hpp"
#include "egluGLContextFactory.hpp"
#include "egluUtil.hpp"
#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"
#include "tcuFunctionLibrary.hpp"
#include "vkWsiPlatform.hpp"

// Assume no call translation is needed
#include <android/native_window.h>
struct egl_native_pixmap_t;
DE_STATIC_ASSERT(sizeof(eglw::EGLNativeDisplayType) == sizeof(void*));
DE_STATIC_ASSERT(sizeof(eglw::EGLNativePixmapType) == sizeof(struct egl_native_pixmap_t*));
DE_STATIC_ASSERT(sizeof(eglw::EGLNativeWindowType) == sizeof(ANativeWindow*));

namespace tcu
{
namespace Android
{

using namespace eglw;

static const eglu::NativeDisplay::Capability	DISPLAY_CAPABILITIES	= eglu::NativeDisplay::CAPABILITY_GET_DISPLAY_LEGACY;
static const eglu::NativeWindow::Capability		WINDOW_CAPABILITIES		= (eglu::NativeWindow::Capability)(eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_LEGACY |
																										   eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM |
																										   eglu::NativeWindow::CAPABILITY_CREATE_SURFACE_PLATFORM_EXTENSION |
																										   eglu::NativeWindow::CAPABILITY_SET_SURFACE_SIZE |
																										   eglu::NativeWindow::CAPABILITY_GET_SCREEN_SIZE);

class NativeDisplay : public eglu::NativeDisplay
{
public:
									NativeDisplay			(void) : eglu::NativeDisplay(DISPLAY_CAPABILITIES), m_library("libEGL.so") {}
	virtual							~NativeDisplay			(void) {}

	virtual EGLNativeDisplayType	getLegacyNative			(void)			{ return EGL_DEFAULT_DISPLAY;	}
	virtual const eglw::Library&	getLibrary				(void) const	{ return m_library;				}

private:
	eglw::DefaultLibrary			m_library;
};

class NativeDisplayFactory : public eglu::NativeDisplayFactory
{
public:
									NativeDisplayFactory	(WindowRegistry& windowRegistry);
									~NativeDisplayFactory	(void) {}

	virtual eglu::NativeDisplay*	createDisplay			(const EGLAttrib* attribList) const;
};

class NativeWindow : public eglu::NativeWindow
{
public:
									NativeWindow			(Window* window, int width, int height, int32_t format);
	virtual							~NativeWindow			(void);

	virtual EGLNativeWindowType		getLegacyNative			(void)			{ return m_window->getNativeWindow();	}
	virtual EGLNativeWindowType		getPlatformExtension	(void)			{ return m_window->getNativeWindow();	}
	virtual EGLNativeWindowType		getPlatformNative		(void)			{ return m_window->getNativeWindow();	}
	IVec2							getScreenSize			(void) const	{ return m_window->getSize();			}

	void							setSurfaceSize			(IVec2 size);

	virtual void					processEvents			(void);

private:
	Window*							m_window;
	int32_t							m_format;
};

class NativeWindowFactory : public eglu::NativeWindowFactory
{
public:
									NativeWindowFactory		(WindowRegistry& windowRegistry);
									~NativeWindowFactory	(void);

	virtual eglu::NativeWindow*		createWindow			(eglu::NativeDisplay* nativeDisplay, const eglu::WindowParams& params) const;
	virtual eglu::NativeWindow*		createWindow			(eglu::NativeDisplay* nativeDisplay, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, const eglu::WindowParams& params) const;

private:
	virtual eglu::NativeWindow*		createWindow			(const eglu::WindowParams& params, int32_t format) const;

	WindowRegistry&					m_windowRegistry;
};

// NativeWindow

NativeWindow::NativeWindow (Window* window, int width, int height, int32_t format)
	: eglu::NativeWindow	(WINDOW_CAPABILITIES)
	, m_window				(window)
	, m_format				(format)
{
	// Set up buffers.
	setSurfaceSize(IVec2(width, height));
}

NativeWindow::~NativeWindow (void)
{
	m_window->release();
}

void NativeWindow::processEvents (void)
{
	if (m_window->isPendingDestroy())
		throw eglu::WindowDestroyedError("Window has been destroyed");
}

void NativeWindow::setSurfaceSize (tcu::IVec2 size)
{
	m_window->setBuffersGeometry(size.x() != eglu::WindowParams::SIZE_DONT_CARE ? size.x() : 0,
								 size.y() != eglu::WindowParams::SIZE_DONT_CARE ? size.y() : 0,
								 m_format);
}

// NativeWindowFactory

NativeWindowFactory::NativeWindowFactory (WindowRegistry& windowRegistry)
	: eglu::NativeWindowFactory	("default", "Default display", WINDOW_CAPABILITIES)
	, m_windowRegistry			(windowRegistry)
{
}

NativeWindowFactory::~NativeWindowFactory (void)
{
}

eglu::NativeWindow* NativeWindowFactory::createWindow (eglu::NativeDisplay* nativeDisplay, const eglu::WindowParams& params) const
{
	DE_UNREF(nativeDisplay);
	return createWindow(params, WINDOW_FORMAT_RGBA_8888);
}

eglu::NativeWindow* NativeWindowFactory::createWindow (eglu::NativeDisplay* nativeDisplay, EGLDisplay display, EGLConfig config, const EGLAttrib* attribList, const eglu::WindowParams& params) const
{
	const int32_t format = (int32_t)eglu::getConfigAttribInt(nativeDisplay->getLibrary(), display, config, EGL_NATIVE_VISUAL_ID);
	DE_UNREF(nativeDisplay && attribList);
	return createWindow(params, format);
}

eglu::NativeWindow* NativeWindowFactory::createWindow (const eglu::WindowParams& params, int32_t format) const
{
	Window* window = m_windowRegistry.tryAcquireWindow();

	if (!window)
		throw ResourceError("Native window is not available", DE_NULL, __FILE__, __LINE__);

	return new NativeWindow(window, params.width, params.height, format);
}

// NativeDisplayFactory

NativeDisplayFactory::NativeDisplayFactory (WindowRegistry& windowRegistry)
	: eglu::NativeDisplayFactory("default", "Default display", DISPLAY_CAPABILITIES)
{
	m_nativeWindowRegistry.registerFactory(new NativeWindowFactory(windowRegistry));
}

eglu::NativeDisplay* NativeDisplayFactory::createDisplay (const EGLAttrib* attribList) const
{
	DE_UNREF(attribList);
	return new NativeDisplay();
}

// Vulkan

class VulkanLibrary : public vk::Library
{
public:
	VulkanLibrary (const char* libraryPath)
		: m_library	(libraryPath != DE_NULL ? libraryPath : "libvulkan.so")
		, m_driver	(m_library)
	{
	}

	const vk::PlatformInterface& getPlatformInterface		(void) const
	{
		return m_driver;
	}

	const tcu::FunctionLibrary&		getFunctionLibrary		(void) const
	{
		return m_library;
	}

private:
	const tcu::DynamicFunctionLibrary	m_library;
	const vk::PlatformDriver			m_driver;
};

DE_STATIC_ASSERT(sizeof(vk::pt::AndroidNativeWindowPtr) == sizeof(ANativeWindow*));

class VulkanWindow : public vk::wsi::AndroidWindowInterface
{
public:
	VulkanWindow (tcu::Android::Window& window)
		: vk::wsi::AndroidWindowInterface	(vk::pt::AndroidNativeWindowPtr(window.getNativeWindow()))
		, m_window							(window)
	{
	}

	void setVisible(bool visible)
	{
		DE_UNREF(visible);
	}

	void resize(const UVec2& newSize)
	{
		DE_UNREF(newSize);
	}

	~VulkanWindow (void)
	{
		m_window.release();
	}

private:
	tcu::Android::Window&	m_window;
};

class VulkanDisplay : public vk::wsi::Display
{
public:
	VulkanDisplay (WindowRegistry& windowRegistry)
		: m_windowRegistry(windowRegistry)
	{
	}

	vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
	{
		Window* const	window	= m_windowRegistry.tryAcquireWindow();

		if (window)
		{
			try
			{
				if (initialSize)
					window->setBuffersGeometry((int)initialSize->x(), (int)initialSize->y(), WINDOW_FORMAT_RGBA_8888);

				return new VulkanWindow(*window);
			}
			catch (...)
			{
				window->release();
				throw;
			}
		}
		else
			TCU_THROW(ResourceError, "Native window is not available");
	}

private:
	WindowRegistry&		m_windowRegistry;
};

static size_t getTotalSystemMemory (ANativeActivity* activity)
{
	const size_t	MiB		= (size_t)(1<<20);

	try
	{
		const size_t totalMemory = getTotalAndroidSystemMemory(activity);
		print("Device has %.2f MiB of system memory\n", static_cast<double>(totalMemory) / static_cast<double>(MiB));
		return totalMemory;
	}
	catch (const std::exception& e)
	{
		// Use relatively high fallback size to encourage CDD-compliant behavior
		const size_t	fallbackSize	= (sizeof(void*) == sizeof(deUint64)) ? 2048*MiB : 1024*MiB;

		print("WARNING: Failed to determine system memory size required by CDD: %s\n", e.what());
		print("WARNING: Using fall-back size of %.2f MiB\n", double(fallbackSize) / double(MiB));

		return fallbackSize;
	}
}

// Platform

Platform::Platform (NativeActivity& activity)
	: m_activity			(activity)
	, m_totalSystemMemory	(getTotalSystemMemory(activity.getNativeActivity()))
{
	m_nativeDisplayFactoryRegistry.registerFactory(new NativeDisplayFactory(m_windowRegistry));
	m_contextFactoryRegistry.registerFactory(new eglu::GLContextFactory(m_nativeDisplayFactoryRegistry));
}

Platform::~Platform (void)
{
}

bool Platform::processEvents (void)
{
	m_windowRegistry.garbageCollect();
	return true;
}

vk::Library* Platform::createLibrary (const char* libraryPath) const
{
	return new VulkanLibrary(libraryPath);
}

void Platform::describePlatform (std::ostream& dst) const
{
	tcu::Android::describePlatform(m_activity.getNativeActivity(), dst);
}

void Platform::getMemoryLimits (tcu::PlatformMemoryLimits& limits) const
{
	// Worst-case estimates
	const size_t	MiB				= (size_t)(1<<20);
	const size_t	baseMemUsage	= 400*MiB;

#if (DE_PTR_SIZE == 4)
	// Some tests, such as:
	//
	// dEQP-VK.api.object_management.max_concurrent.*
	// dEQP-VK.memory.allocation.random.*
	//
	// when run in succession, can lead to system memory fragmentation. It depends on the allocator, and on some 32-bit
	// systems can lead to out of memory errors. As a workaround, we use a smaller amount of memory on 32-bit systems,
	// as this typically avoids out of memory errors caused by fragmentation.
	const double	safeUsageRatio	= 0.1;
#else
	const double	safeUsageRatio	= 0.25;
#endif

	limits.totalSystemMemory					= de::max((size_t)(double(deInt64(m_totalSystemMemory)-deInt64(baseMemUsage)) * safeUsageRatio), 16*MiB);

	// Assume UMA architecture
	limits.totalDeviceLocalMemory				= 0;

	// Reasonable worst-case estimates
	limits.deviceMemoryAllocationGranularity	= 64*1024;
	limits.devicePageSize						= 4096;
	limits.devicePageTableEntrySize				= 8;
	limits.devicePageTableHierarchyLevels		= 3;
}

vk::wsi::Display* Platform::createWsiDisplay (vk::wsi::Type wsiType) const
{
	if (wsiType == vk::wsi::TYPE_ANDROID)
		return new VulkanDisplay(const_cast<WindowRegistry&>(m_windowRegistry));
	else
		TCU_THROW(NotSupportedError, "WSI type not supported on Android");
}

bool Platform::hasDisplay (vk::wsi::Type wsiType) const
{
	if (wsiType == vk::wsi::TYPE_ANDROID)
		return true;

	return false;
}

} // Android
} // tcu
