/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTime.h"
#include "include/gpu/gl/GrGLAssembleInterface.h"
#include "include/gpu/gl/GrGLInterface.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/gl/GrGLDefines.h"
#include "src/gpu/gl/GrGLUtil.h"
#include "src/ports/SkOSLibrary.h"
#include "tools/gpu/gl/angle/GLTestContext_angle.h"
#include "third_party/externals/angle2/include/platform/Platform.h"

#define EGL_EGL_PROTOTYPES 1
#include <EGL/egl.h>
#include <EGL/eglext.h>

#define EGL_PLATFORM_ANGLE_ANGLE                0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE           0x3203
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE      0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE     0x3208
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE    0x320D

#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483

using sk_gpu_test::ANGLEBackend;
using sk_gpu_test::ANGLEContextVersion;

namespace {
struct Libs {
    void* fGLLib;
    void* fEGLLib;
};

std::function<void()> context_restorer() {
    auto display = eglGetCurrentDisplay();
    auto dsurface = eglGetCurrentSurface(EGL_DRAW);
    auto rsurface = eglGetCurrentSurface(EGL_READ);
    auto context = eglGetCurrentContext();
    return [display, dsurface, rsurface, context] {
        eglMakeCurrent(display, dsurface, rsurface, context);
    };
}

static GrGLFuncPtr angle_get_gl_proc(void* ctx, const char name[]) {
    const Libs* libs = reinterpret_cast<const Libs*>(ctx);
    GrGLFuncPtr proc = (GrGLFuncPtr) SkGetProcedureAddress(libs->fGLLib, name);
    if (proc) {
        return proc;
    }
    proc = (GrGLFuncPtr) SkGetProcedureAddress(libs->fEGLLib, name);
    if (proc) {
        return proc;
    }
    return eglGetProcAddress(name);
}

void* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) {
    PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
    eglGetPlatformDisplayEXT =
        (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");

    // We expect ANGLE to support this extension
    if (!eglGetPlatformDisplayEXT) {
        return EGL_NO_DISPLAY;
    }

    EGLint typeNum = 0;
    switch (type) {
        case ANGLEBackend::kD3D9:
            typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
            break;
        case ANGLEBackend::kD3D11:
            typeNum = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
            break;
        case ANGLEBackend::kOpenGL:
            typeNum = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
            break;
    }
    const EGLint attribs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, typeNum, EGL_NONE };
    return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs);
}

class ANGLEGLContext : public sk_gpu_test::GLTestContext {
public:
    ANGLEGLContext(ANGLEBackend, ANGLEContextVersion, ANGLEGLContext* shareContext, void* display);
    ~ANGLEGLContext() override;

    GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
    void destroyEGLImage(GrEGLImage) const override;
    GrGLuint eglImageToExternalTexture(GrEGLImage) const override;
    std::unique_ptr<sk_gpu_test::GLTestContext> makeNew() const override;

private:
    void destroyGLContext();

    void onPlatformMakeNotCurrent() const override;
    void onPlatformMakeCurrent() const override;
    std::function<void()> onPlatformGetAutoContextRestore() const override;
    GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;

    void*                       fContext;
    void*                       fDisplay;
    void*                       fSurface;
    ANGLEBackend                fType;
    ANGLEContextVersion         fVersion;

    angle::ResetDisplayPlatformFunc fResetPlatform = nullptr;

    PFNEGLCREATEIMAGEKHRPROC    fCreateImage = nullptr;
    PFNEGLDESTROYIMAGEKHRPROC   fDestroyImage = nullptr;

#ifdef SK_BUILD_FOR_WIN
    HWND                        fWindow;
    HDC                         fDeviceContext;
    static ATOM                 gWC;
#endif
};

#ifdef SK_BUILD_FOR_WIN
ATOM ANGLEGLContext::gWC = 0;

enum class IsWine { kUnknown, kNo, kYes };

static IsWine is_wine() {
    HMODULE ntdll = GetModuleHandle("ntdll.dll");
    if (!ntdll) {
        SkDebugf("No ntdll.dll on Windows?!\n");
        return IsWine::kUnknown;
    }
    return GetProcAddress(ntdll, "wine_get_version") == nullptr ? IsWine::kNo : IsWine::kYes;
}

#endif

static const unsigned char* ANGLE_getTraceCategoryEnabledFlag(angle::PlatformMethods* platform,
                                                              const char* category_group) {
    return SkEventTracer::GetInstance()->getCategoryGroupEnabled(category_group);
}

static angle::TraceEventHandle ANGLE_addTraceEvent(angle::PlatformMethods* platform,
                                                   char phase,
                                                   const unsigned char* category_group_enabled,
                                                   const char* name,
                                                   unsigned long long id,
                                                   double timestamp,
                                                   int num_args,
                                                   const char** arg_names,
                                                   const unsigned char* arg_types,
                                                   const unsigned long long* arg_values,
                                                   unsigned char flags) {
    static_assert(sizeof(unsigned long long) == sizeof(uint64_t), "Non-64-bit trace event args!");
    return SkEventTracer::GetInstance()->addTraceEvent(
            phase, category_group_enabled, name, id, num_args, arg_names, arg_types,
            reinterpret_cast<const uint64_t*>(arg_values), flags);
}

static void ANGLE_updateTraceEventDuration(angle::PlatformMethods* platform,
                                           const unsigned char* category_group_enabled,
                                           const char* name,
                                           angle::TraceEventHandle handle) {
    SkEventTracer::GetInstance()->updateTraceEventDuration(category_group_enabled, name, handle);
}

static double ANGLE_monotonicallyIncreasingTime(angle::PlatformMethods* platform) {
    return SkTime::GetSecs();
}

ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
                               ANGLEGLContext* shareContext, void* display)
    : fContext(EGL_NO_CONTEXT)
    , fDisplay(display)
    , fSurface(EGL_NO_SURFACE)
    , fType(type)
    , fVersion(version) {
#ifdef SK_BUILD_FOR_WIN
    fWindow = nullptr;
    fDeviceContext = nullptr;

    static IsWine gIsWine = is_wine();
    if (gIsWine == IsWine::kYes && type != ANGLEBackend::kOpenGL) {
        // D3D backends of ANGLE don't really work well under Wine with our tests and are likely to
        // crash. This makes it easier to test using the GL ANGLE backend under Wine on Linux
        // without lots of spurious Wine debug spew and crashes.
        return;
    }

    if (EGL_NO_DISPLAY == fDisplay) {
        HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);

        if (!gWC) {
            WNDCLASS wc;
            wc.cbClsExtra = 0;
            wc.cbWndExtra = 0;
            wc.hbrBackground = nullptr;
            wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
            wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
            wc.hInstance = hInstance;
            wc.lpfnWndProc = (WNDPROC) DefWindowProc;
            wc.lpszClassName = TEXT("ANGLE-win");
            wc.lpszMenuName = nullptr;
            wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

            gWC = RegisterClass(&wc);
            if (!gWC) {
                SkDebugf("Could not register window class.\n");
                return;
            }
        }
        if (!(fWindow = CreateWindow(TEXT("ANGLE-win"),
                                        TEXT("The Invisible Man"),
                                        WS_OVERLAPPEDWINDOW,
                                        0, 0, 1, 1,
                                        nullptr, nullptr,
                                        hInstance, nullptr))) {
            SkDebugf("Could not create window.\n");
            return;
        }

        if (!(fDeviceContext = GetDC(fWindow))) {
            SkDebugf("Could not get device context.\n");
            this->destroyGLContext();
            return;
        }

        fDisplay = get_angle_egl_display(fDeviceContext, type);
    }
#else
    SkASSERT(EGL_NO_DISPLAY == fDisplay);
    fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type);
#endif
    if (EGL_NO_DISPLAY == fDisplay) {
        SkDebugf("Could not create EGL display!");
        return;
    }

    // Add ANGLE platform hooks to connect to Skia's tracing implementation
    angle::GetDisplayPlatformFunc getPlatform = reinterpret_cast<angle::GetDisplayPlatformFunc>(
            eglGetProcAddress("ANGLEGetDisplayPlatform"));
    if (getPlatform) {
        fResetPlatform = reinterpret_cast<angle::ResetDisplayPlatformFunc>(
                eglGetProcAddress("ANGLEResetDisplayPlatform"));
        SkASSERT(fResetPlatform);

        angle::PlatformMethods* platformMethods = nullptr;
        if (getPlatform(fDisplay, angle::g_PlatformMethodNames, angle::g_NumPlatformMethods,
                        nullptr, &platformMethods)) {
            platformMethods->addTraceEvent               = ANGLE_addTraceEvent;
            platformMethods->getTraceCategoryEnabledFlag = ANGLE_getTraceCategoryEnabledFlag;
            platformMethods->updateTraceEventDuration    = ANGLE_updateTraceEventDuration;
            platformMethods->monotonicallyIncreasingTime = ANGLE_monotonicallyIncreasingTime;
        }
    }

    EGLint majorVersion;
    EGLint minorVersion;
    if (!eglInitialize(fDisplay, &majorVersion, &minorVersion)) {
        SkDebugf("Could not initialize display!");
        this->destroyGLContext();
        return;
    }

    EGLint numConfigs;
    static const EGLint configAttribs[] = {
        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_NONE
    };

    EGLConfig surfaceConfig;
    if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
        SkDebugf("Could not create choose config!");
        this->destroyGLContext();
        return;
    }

    int versionNum = ANGLEContextVersion::kES2 == version ? 2 : 3;
    std::vector<EGLint> contextAttribs = {
        EGL_CONTEXT_CLIENT_VERSION, versionNum,
    };

    const char* extensions = eglQueryString(fDisplay, EGL_EXTENSIONS);
    if (strstr(extensions, "EGL_ANGLE_create_context_backwards_compatible")) {
        contextAttribs.push_back(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE);
        contextAttribs.push_back(EGL_FALSE);
    }

    contextAttribs.push_back(EGL_NONE);

    EGLContext eglShareContext = shareContext ? shareContext->fContext : nullptr;
    fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs.data());
    if (EGL_NO_CONTEXT == fContext) {
        SkDebugf("Could not create context!");
        this->destroyGLContext();
        return;
    }

    static const EGLint surfaceAttribs[] = {
        EGL_WIDTH, 1,
        EGL_HEIGHT, 1,
        EGL_NONE
    };

    fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);

    SkScopeExit restorer(context_restorer());
    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
        SkDebugf("Could not set the context.");
        this->destroyGLContext();
        return;
    }

    sk_sp<const GrGLInterface> gl = sk_gpu_test::CreateANGLEGLInterface();
    if (nullptr == gl.get()) {
        SkDebugf("Could not create ANGLE GL interface!\n");
        this->destroyGLContext();
        return;
    }
    if (!gl->validate()) {
        SkDebugf("Could not validate ANGLE GL interface!\n");
        this->destroyGLContext();
        return;
    }

#ifdef SK_DEBUG
    // Verify that the interface we requested was actually returned to us
    const GrGLubyte* rendererUByte;
    GR_GL_CALL_RET(gl.get(), rendererUByte, GetString(GR_GL_RENDERER));
    const char* renderer = reinterpret_cast<const char*>(rendererUByte);
    switch (type) {
    case ANGLEBackend::kD3D9:
        SkASSERT(strstr(renderer, "Direct3D9"));
        break;
    case ANGLEBackend::kD3D11:
        SkASSERT(strstr(renderer, "Direct3D11"));
        break;
    case ANGLEBackend::kOpenGL:
        SkASSERT(strstr(renderer, "OpenGL"));
        break;
    }
#endif
    if (strstr(extensions, "EGL_KHR_image")) {
        fCreateImage = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR");
        fDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR");
    }

    this->init(std::move(gl));
}

ANGLEGLContext::~ANGLEGLContext() {
    this->teardown();
    this->destroyGLContext();
}

GrEGLImage ANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const {
    if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) {
        return GR_EGL_NO_IMAGE;
    }
    EGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0,
                         GR_EGL_IMAGE_PRESERVED, GR_EGL_TRUE,
                         GR_EGL_NONE };
    // 64 bit cast is to shut Visual C++ up about casting 32 bit value to a pointer.
    GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>((uint64_t)texID);
    return fCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer, attribs);
}

void ANGLEGLContext::destroyEGLImage(GrEGLImage image) const { fDestroyImage(fDisplay, image); }

GrGLuint ANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
    while (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {}
    if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
        return 0;
    }
    typedef GrGLvoid (EGLAPIENTRY *EGLImageTargetTexture2DProc)(GrGLenum, GrGLeglImage);
    EGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
        (EGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES");
    if (!glEGLImageTargetTexture2D) {
        return 0;
    }
    GrGLuint texID;
    GR_GL_CALL(this->gl(), GenTextures(1, &texID));
    if (!texID) {
        return 0;
    }
    GR_GL_CALL(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
    if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
        return 0;
    }
    glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
    if (this->gl()->fFunctions.fGetError() != GR_GL_NO_ERROR) {
        GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
        return 0;
    }
    return texID;
}

std::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew() const {
    // For EGLImage sharing between contexts to work in ANGLE the two contexts
    // need to share the same display
    std::unique_ptr<sk_gpu_test::GLTestContext> ctx =
        sk_gpu_test::MakeANGLETestContext(fType, fVersion, nullptr, fDisplay);
    if (ctx) {
        ctx->makeCurrent();
    }
    return ctx;
}

void ANGLEGLContext::destroyGLContext() {
    if (EGL_NO_DISPLAY != fDisplay) {
        if (eglGetCurrentContext() == fContext) {
            // This will ensure that the context is immediately deleted.
            eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        }

        if (EGL_NO_CONTEXT != fContext) {
            eglDestroyContext(fDisplay, fContext);
            fContext = EGL_NO_CONTEXT;
        }

        if (EGL_NO_SURFACE != fSurface) {
            eglDestroySurface(fDisplay, fSurface);
            fSurface = EGL_NO_SURFACE;
        }

        if (fResetPlatform) {
            fResetPlatform(fDisplay);
        }

        eglTerminate(fDisplay);
        fDisplay = EGL_NO_DISPLAY;
    }

#ifdef SK_BUILD_FOR_WIN
    if (fWindow) {
        if (fDeviceContext) {
            ReleaseDC(fWindow, fDeviceContext);
            fDeviceContext = 0;
        }

        DestroyWindow(fWindow);
        fWindow = 0;
    }
#endif
}

void ANGLEGLContext::onPlatformMakeNotCurrent() const {
    if (!eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
        SkDebugf("Could not reset the context 0x%x.\n", eglGetError());
    }
}

void ANGLEGLContext::onPlatformMakeCurrent() const {
    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
        SkDebugf("Could not set the context 0x%x.\n", eglGetError());
    }
}

std::function<void()> ANGLEGLContext::onPlatformGetAutoContextRestore() const {
    if (eglGetCurrentContext() == fContext) {
        return nullptr;
    }
    return context_restorer();
}

GrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(const char* name) const {
    return eglGetProcAddress(name);
}
}  // anonymous namespace

namespace sk_gpu_test {
sk_sp<const GrGLInterface> CreateANGLEGLInterface() {
    static Libs gLibs = { nullptr, nullptr };

    if (nullptr == gLibs.fGLLib) {
        // We load the ANGLE library and never let it go
#if defined _WIN32
        gLibs.fGLLib = SkLoadDynamicLibrary("libGLESv2.dll");
        gLibs.fEGLLib = SkLoadDynamicLibrary("libEGL.dll");
#elif defined SK_BUILD_FOR_MAC
        gLibs.fGLLib = SkLoadDynamicLibrary("libGLESv2.dylib");
        gLibs.fEGLLib = SkLoadDynamicLibrary("libEGL.dylib");
#else
        gLibs.fGLLib = SkLoadDynamicLibrary("libGLESv2.so");
        gLibs.fEGLLib = SkLoadDynamicLibrary("libEGL.so");
#endif
    }

    if (nullptr == gLibs.fGLLib || nullptr == gLibs.fEGLLib) {
        // We can't setup the interface correctly w/o the so
        return nullptr;
    }

    return GrGLMakeAssembledGLESInterface(&gLibs, angle_get_gl_proc);
}

std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version,
                                                    GLTestContext* shareContext, void* display) {
#if defined(SK_BUILD_FOR_WIN) && defined(_M_ARM64)
    // Windows-on-ARM only has D3D11. This will fail correctly, but it produces huge amounts of
    // debug output for every unit test from both ANGLE and our context factory.
    if (ANGLEBackend::kD3D11 != type) {
        return nullptr;
    }
#endif

    ANGLEGLContext* angleShareContext = reinterpret_cast<ANGLEGLContext*>(shareContext);
    std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version,
                                                          angleShareContext, display));
    if (!ctx->isValid()) {
        return nullptr;
    }
    return ctx;
}
}  // namespace sk_gpu_test
