/*-------------------------------------------------------------------------
 * 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(void) : m_library("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(uint64_t)) ? 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(void) const
{
    return new VulkanLibrary();
}

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;
    const double safeUsageRatio = 0.25;

    limits.totalSystemMemory =
        de::max((size_t)(double(int64_t(m_totalSystemMemory) - int64_t(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;
}

} // namespace Android
} // namespace tcu
