// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/opengl/EGLFunctions.h"

#include <string>
#include <tuple>

#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_split.h"
#include "src/dawn/native/opengl/UtilsEGL.h"

namespace dawn::native::opengl {

namespace {

using VersionPromoted = std::tuple<uint32_t, uint32_t>;
constexpr VersionPromoted EGL1_5 = {1, 5};
constexpr VersionPromoted NeverPromoted = {100000, 0};

// EGL_EXT_client_extensions which was promoted to 1.5 adds the concept of client extensions that
// can be queried with eglGetString(EGL_NO_DISPLAY, EGL_EXTENSIONS). These can be loaded during
// LoadClientProcs instead of LoadDisplayProcs.
enum class ExtType {
    Display,
    Client,
};

struct ExtensionInfo {
    EGLExt index;
    const char* name;
    VersionPromoted versionPromoted;
    ExtType type;
};

static constexpr size_t kExtensionCount = static_cast<size_t>(EGLExt::EnumCount);
static constexpr std::array<ExtensionInfo, kExtensionCount> kExtensionInfos{{
    //
    {EGLExt::ClientExtensions, "EGL_EXT_client_extensions", EGL1_5, ExtType::Client},
    {EGLExt::PlatformBase, "EGL_EXT_platform_base", EGL1_5, ExtType::Client},
    // EGL_KHR_fence_sync cannot be marked as promoted to core due to different function prototypes.
    {EGLExt::FenceSync, "EGL_KHR_fence_sync", NeverPromoted, ExtType::Display},
    {EGLExt::CLEvent2, "EGL_KHR_cl_event2", EGL1_5, ExtType::Display},
    {EGLExt::WaitSync, "EGL_KHR_wait_sync", EGL1_5, ExtType::Display},
    {EGLExt::ImageBase, "EGL_KHR_image_base", EGL1_5, ExtType::Display},
    {EGLExt::GLTexture2DImage, "EGL_KHR_gl_texture_2D_image", EGL1_5, ExtType::Display},
    {EGLExt::GLTexture3DImage, "EGL_KHR_gl_texture_3D_image", EGL1_5, ExtType::Display},
    {EGLExt::GLTextureCubemapImage, "EGL_KHR_gl_texture_cubemap_image", EGL1_5, ExtType::Display},
    {EGLExt::GLRenderBufferImage, "EGL_KHR_gl_renderbuffer_image", EGL1_5, ExtType::Display},
    {EGLExt::CreateContext, "EGL_KHR_create_context", EGL1_5, ExtType::Display},
    {EGLExt::CreateContextRobustness, "EGL_EXT_create_context_robustness", EGL1_5,
     ExtType::Display},
    {EGLExt::GetAllProcAddresses, "EGL_KHR_get_all_proc_addresses", EGL1_5, ExtType::Display},
    {EGLExt::ClientGetAllProcAddresses, "EGL_KHR_client_get_all_proc_addresses", EGL1_5,
     ExtType::Client},
    {EGLExt::GLColorSpace, "EGL_KHR_gl_colorspace", EGL1_5, ExtType::Display},
    {EGLExt::SurfacelessContext, "EGL_KHR_surfaceless_context", EGL1_5, ExtType::Display},
    {EGLExt::NativeFenceSync, "EGL_ANDROID_native_fence_sync", NeverPromoted, ExtType::Display},

    {EGLExt::DisplayTextureShareGroup, "EGL_ANGLE_display_texture_share_group", NeverPromoted,
     ExtType::Display},
    {EGLExt::ReusableSync, "EGL_KHR_reusable_sync", NeverPromoted, ExtType::Display},
    {EGLExt::NoConfigContext, "EGL_KHR_no_config_context", NeverPromoted, ExtType::Display},
    {EGLExt::PixelFormatFloat, "EGL_EXT_pixel_format_float", NeverPromoted, ExtType::Display},
    {EGLExt::GLColorspace, "EGL_KHR_gl_colorspace", NeverPromoted, ExtType::Display},
    {EGLExt::ImageNativeBuffer, "EGL_ANDROID_image_native_buffer", NeverPromoted, ExtType::Display},
    {EGLExt::GetNativeClientBuffer, "EGL_ANDROID_get_native_client_buffer", NeverPromoted,
     ExtType::Display},

    {EGLExt::ANGLECreateContextBackwardsCompatible, "EGL_ANGLE_create_context_backwards_compatible",
     NeverPromoted, ExtType::Display},
    {EGLExt::ANGLECreateContextExtensionsEnabled, "EGL_ANGLE_create_context_extensions_enabled",
     NeverPromoted, ExtType::Display},
    {EGLExt::ANGLEContextVirtualization, "EGL_ANGLE_context_virtualization", NeverPromoted,
     ExtType::Display},
    {EGLExt::ANGLECreateContextWebGLCompatibility, "EGL_ANGLE_create_context_webgl_compatibility",
     NeverPromoted, ExtType::Display},
    //
}};

}  // anonymous namespace

#define GET_PROC_WITH_NAME(member, name)                                          \
    do {                                                                          \
        member = reinterpret_cast<decltype(member)>(GetProcAddress(name));        \
        if (member == nullptr) {                                                  \
            return DAWN_INTERNAL_ERROR(std::string("Couldn't get proc ") + name); \
        }                                                                         \
    } while (0)

#define GET_PROC(name) GET_PROC_WITH_NAME(name, "egl" #name)

MaybeError EGLFunctions::LoadClientProcs(EGLGetProcProc getProc) {
    // Load EGL 1.0
    GetProcAddress = getProc;

    GET_PROC(ChooseConfig);
    GET_PROC(CopyBuffers);
    GET_PROC(CreateContext);
    GET_PROC(CreatePbufferSurface);
    GET_PROC(CreatePixmapSurface);
    GET_PROC(CreateWindowSurface);
    GET_PROC(DestroyContext);
    GET_PROC(DestroySurface);
    GET_PROC(GetConfigAttrib);
    GET_PROC(GetConfigs);
    GET_PROC(GetCurrentDisplay);
    GET_PROC(GetCurrentSurface);
    GET_PROC(GetDisplay);
    GET_PROC(GetError);
    GET_PROC(Initialize);
    GET_PROC(MakeCurrent);
    GET_PROC(QueryContext);
    GET_PROC(QueryString);
    GET_PROC(QuerySurface);
    GET_PROC(SwapBuffers);
    GET_PROC(Terminate);
    GET_PROC(WaitGL);
    GET_PROC(WaitNative);

    // Get the EGL client extensions, if they are supported.
    const char* rawExtensions = QueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
    if (rawExtensions == nullptr) {
        return {};
    }
    absl::flat_hash_set<std::string_view> extensions = absl::StrSplit(rawExtensions, " ");

    for (const ExtensionInfo& ext : kExtensionInfos) {
        if (extensions.contains(ext.name) && ext.type == ExtType::Client) {
            mExtensions.set(ext.index);
        }
    }

    return LoadClientExtensions();
}

MaybeError EGLFunctions::LoadDisplayProcs(EGLDisplay display) {
    DAWN_ASSERT(GetProcAddress != nullptr);

    // Get the EGL version and extensions.
    {
        EGLint major, minor;
        DAWN_TRY(CheckEGL(*this, Initialize(display, &major, &minor), "eglInitialize"));
        DAWN_INVALID_IF(major != 1, "EGL version (%u) is not 1.", major);
        mMajorVersion = major;
        mMinorVersion = minor;
    }
    {
        const char* rawExtensions = QueryString(display, EGL_EXTENSIONS);
        absl::flat_hash_set<std::string_view> extensions = absl::StrSplit(rawExtensions, " ");

        for (const ExtensionInfo& ext : kExtensionInfos) {
            if (std::tie(mMajorVersion, mMinorVersion) >= ext.versionPromoted ||
                extensions.contains(ext.name)) {
                mExtensions.set(ext.index);
            }
        }
    }

    // EGL 1.1
    if (mMinorVersion >= 1) {
        GET_PROC(BindTexImage);
        GET_PROC(ReleaseTexImage);
        GET_PROC(SurfaceAttrib);
        GET_PROC(SwapInterval);
    }

    // EGL 1.2
    if (mMinorVersion >= 2) {
        GET_PROC(BindAPI);
        GET_PROC(QueryAPI);
        GET_PROC(CreatePbufferFromClientBuffer);
        GET_PROC(ReleaseThread);
        GET_PROC(WaitClient);
    }

    // EGL 1.3 (no new procs)

    // EGL 1.4
    if (mMinorVersion >= 4) {
        GET_PROC(GetCurrentContext);
    }

    // EGL 1.5
    if (mMinorVersion >= 5) {
        GET_PROC(CreateSync);
        GET_PROC(DestroySync);
        GET_PROC(ClientWaitSync);
        GET_PROC(GetSyncAttrib);
        GET_PROC(CreateImage);
        GET_PROC(DestroyImage);
        GET_PROC(GetPlatformDisplay);
        GET_PROC(CreatePlatformWindowSurface);
        GET_PROC(CreatePlatformPixmapSurface);
        GET_PROC(WaitSync);
    } else {
        // Load display extensions that would otherwise be promoted to EGL 1.5.

        if (HasExt(EGLExt::ImageBase)) {
            GET_PROC_WITH_NAME(CreateImage, "eglCreateImageKHR");
            GET_PROC_WITH_NAME(DestroyImage, "eglDestroyImageKHR");
        }

        if (HasExt(EGLExt::WaitSync)) {
            GET_PROC_WITH_NAME(WaitSync, "eglWaitSyncKHR");
        }
    }

    // Load client extensions if they haven't been already.
    if (!HasExt(EGLExt::ClientExtensions)) {
        DAWN_TRY(LoadClientExtensions());
    }

    // Other extensions

    if (HasExt(EGLExt::FenceSync)) {
        GET_PROC_WITH_NAME(ClientWaitSyncKHR, "eglClientWaitSyncKHR");
        GET_PROC_WITH_NAME(CreateSyncKHR, "eglCreateSyncKHR");
        GET_PROC_WITH_NAME(DestroySyncKHR, "eglDestroySyncKHR");
        GET_PROC_WITH_NAME(GetSyncAttribKHR, "eglGetSyncAttribKHR");
    }

    if (HasExt(EGLExt::ReusableSync)) {
        GET_PROC_WITH_NAME(SignalSync, "eglSignalSyncKHR");
    }

    if (HasExt(EGLExt::GetNativeClientBuffer)) {
        GET_PROC_WITH_NAME(GetNativeClientBuffer, "eglGetNativeClientBufferANDROID");
    }

    if (HasExt(EGLExt::NativeFenceSync)) {
        GET_PROC_WITH_NAME(DupNativeFenceFD, "eglDupNativeFenceFDANDROID");
    }

    return {};
}

uint32_t EGLFunctions::GetMajorVersion() const {
    return mMajorVersion;
}

uint32_t EGLFunctions::GetMinorVersion() const {
    return mMinorVersion;
}

bool EGLFunctions::IsAtLeastVersion(uint32_t major, uint32_t minor) const {
    return std::tie(major, minor) >= std::tie(mMajorVersion, mMinorVersion);
}

bool EGLFunctions::HasExt(EGLExt extension) const {
    return mExtensions[extension];
}

MaybeError EGLFunctions::LoadClientExtensions() {
    if (HasExt(EGLExt::PlatformBase) && mMinorVersion < 5) {
        GET_PROC_WITH_NAME(GetPlatformDisplay, "eglGetPlatformDisplayEXT");
        GET_PROC_WITH_NAME(CreatePlatformWindowSurface, "eglCreatePlatformWindowSurfaceEXT");
        GET_PROC_WITH_NAME(CreatePlatformPixmapSurface, "eglCreatePlatformPixmapSurfaceEXT");
    }

    return {};
}

}  // namespace dawn::native::opengl
