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

#include "include/android/GrAHardwareBufferUtils.h"

#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES

#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/ganesh/gl/GrGLTypes.h"
#include "include/private/SkLog.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/gl/GrGLDefines.h"
#include "src/gpu/ganesh/gl/GrGLUtil.h"

#include <android/hardware_buffer.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content"
#define EGL_PROTECTED_CONTENT_EXT 0x32C0

namespace GrAHardwareBufferUtils {

GrBackendFormat GetGLBackendFormat(GrDirectContext* dContext,
                                   uint32_t bufferFormat, bool requireKnownFormat) {
    GrBackendApi backend = dContext->backend();
    if (backend != GrBackendApi::kOpenGL) {
        return GrBackendFormat();
    }
    switch (bufferFormat) {
        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
            return GrBackendFormats::MakeGL(GR_GL_RGBA8);
        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
            // According to  https://developer.android.com/ndk/reference/group/a-hardware-buffer,
            // the GL format equivalent is GL_RGB8 but that is considered to be 24bpp throughout
            // Ganesh. For now keep it as an external format until we figure out the RGB vs RGBA
            // compatibility.
            return GrBackendFormats::MakeGLExternal();
        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
            return GrBackendFormats::MakeGL(GR_GL_RGBA16F);
        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
            return GrBackendFormats::MakeGL(GR_GL_RGB565);
        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
            return GrBackendFormats::MakeGL(GR_GL_RGB10_A2);
        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
            return GrBackendFormats::MakeGL(GR_GL_RGB8);
#if __ANDROID_API__ >= 33
        case AHARDWAREBUFFER_FORMAT_R8_UNORM:
            return GrBackendFormats::MakeGL(GR_GL_R8);
#endif
#if __ANDROID_API__ >= 34
        case AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM:
            // There is no GLFormat enum that corresponds to this texture format, but it is known
            // (GrColorType and SkColorType can describe it).
            return GrBackendFormats::MakeGLExternal();
#endif
        default:
            if (requireKnownFormat) {
                return GrBackendFormat();
            } else {
                return GrBackendFormats::MakeGLExternal();
            }
    }
    SkUNREACHABLE;
}

class GLTextureHelper {
public:
    GLTextureHelper(GrGLuint texID, EGLImageKHR image, EGLDisplay display, GrGLuint texTarget)
        : fTexID(texID)
        , fImage(image)
        , fDisplay(display)
        , fTexTarget(texTarget) { }
    ~GLTextureHelper() {
        glDeleteTextures(1, &fTexID);
        // eglDestroyImageKHR will remove a ref from the AHardwareBuffer
        eglDestroyImageKHR(fDisplay, fImage);
    }
    void rebind(GrDirectContext*);

private:
    GrGLuint    fTexID;
    EGLImageKHR fImage;
    EGLDisplay  fDisplay;
    GrGLuint    fTexTarget;
};

void GLTextureHelper::rebind(GrDirectContext* dContext) {
    glBindTexture(fTexTarget, fTexID);
    GLenum status = GL_NO_ERROR;
    if ((status = glGetError()) != GL_NO_ERROR) {
        SKIA_LOG_E("glBindTexture(%#x, %d) failed (%#x)", (int) fTexTarget,
            (int) fTexID, (int) status);
        return;
    }
    glEGLImageTargetTexture2DOES(fTexTarget, fImage);
    if ((status = glGetError()) != GL_NO_ERROR) {
        SKIA_LOG_E("glEGLImageTargetTexture2DOES failed (%#x)", (int) status);
        return;
    }
    dContext->resetContext(kTextureBinding_GrGLBackendState);
}

void delete_gl_texture(void* context) {
    GLTextureHelper* cleanupHelper = static_cast<GLTextureHelper*>(context);
    delete cleanupHelper;
}

void update_gl_texture(void* context, GrDirectContext* dContext) {
    GLTextureHelper* cleanupHelper = static_cast<GLTextureHelper*>(context);
    cleanupHelper->rebind(dContext);
}

static GrBackendTexture make_gl_backend_texture(
        GrDirectContext* dContext,
        AHardwareBuffer* hardwareBuffer,
        int width, int height,
        DeleteImageProc* deleteProc,
        UpdateImageProc* updateProc,
        TexImageCtx* imageCtx,
        bool isProtectedContent,
        const GrBackendFormat& backendFormat) {
    while (GL_NO_ERROR != glGetError()) {} //clear GL errors

    auto textureType = backendFormat.textureType();
    if (textureType != GrTextureType::k2D && textureType != GrTextureType::kExternal) {
        SKIA_LOG_E("Unsupported texture target type: %d\n", (int) textureType);
        return GrBackendTexture();
    }

    EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer);
    EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
                         isProtectedContent ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
                         isProtectedContent ? EGL_TRUE : EGL_NONE,
                         EGL_NONE };
    EGLDisplay display = eglGetCurrentDisplay();
    // eglCreateImageKHR will add a ref to the AHardwareBuffer
    EGLImageKHR image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                                          clientBuffer, attribs);
    if (EGL_NO_IMAGE_KHR == image) {
        SKIA_LOG_E("Could not create EGL image, err = (%#x)", (int) eglGetError() );
        return GrBackendTexture();
    }

    GrGLuint texID;
    glGenTextures(1, &texID);
    if (!texID) {
        eglDestroyImageKHR(display, image);
        return GrBackendTexture();
    }

    GrGLuint target = textureType == GrTextureType::kExternal ? GR_GL_TEXTURE_EXTERNAL
                                                              : GR_GL_TEXTURE_2D;

    if (!dContext->priv().caps()->shaderCaps()->fExternalTextureSupport &&
        textureType == GrTextureType::kExternal) {
        // The extension OES_EGL_image_external is mandatory for an
        // Android-compatible device. See
        // https://source.android.com/docs/core/graphics/implement-opengl-es
        //
        // This path exists to support a RenderDoc fork which supports
        // OES_EGL_image but not OES_EGL_image_external.
        target = GR_GL_TEXTURE_2D;
    }

    glBindTexture(target, texID);
    GLenum status = GL_NO_ERROR;
    if ((status = glGetError()) != GL_NO_ERROR) {
        SKIA_LOG_E("glBindTexture failed (%#x)", (int) status);
        glDeleteTextures(1, &texID);
        eglDestroyImageKHR(display, image);
        return GrBackendTexture();
    }
    glEGLImageTargetTexture2DOES(target, image);
    if ((status = glGetError()) != GL_NO_ERROR) {
        SKIA_LOG_E("glEGLImageTargetTexture2DOES failed (%#x)", (int) status);
        glDeleteTextures(1, &texID);
        eglDestroyImageKHR(display, image);
        return GrBackendTexture();
    }
    dContext->resetContext(kTextureBinding_GrGLBackendState);

    GrGLTextureInfo textureInfo;
    textureInfo.fID = texID;
    SkASSERT(backendFormat.isValid());
    textureInfo.fTarget = target;
    textureInfo.fFormat = GrBackendFormats::AsGLFormatEnum(backendFormat);
    textureInfo.fProtected = skgpu::Protected(isProtectedContent);

    *deleteProc = delete_gl_texture;
    *updateProc = update_gl_texture;
    *imageCtx = new GLTextureHelper(texID, image, display, target);

    return GrBackendTextures::MakeGL(width, height, skgpu::Mipmapped::kNo, textureInfo);
}

static bool can_import_protected_content_eglimpl() {
    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
    size_t cropExtLen = strlen(PROT_CONTENT_EXT_STR);
    size_t extsLen = strlen(exts);
    bool equal = !strcmp(PROT_CONTENT_EXT_STR, exts);
    bool atStart = !strncmp(PROT_CONTENT_EXT_STR " ", exts, cropExtLen+1);
    bool atEnd = (cropExtLen+1) < extsLen
                  && !strcmp(" " PROT_CONTENT_EXT_STR,
                  exts + extsLen - (cropExtLen+1));
    bool inMiddle = strstr(exts, " " PROT_CONTENT_EXT_STR " ");
    return equal || atStart || atEnd || inMiddle;
}

static bool can_import_protected_content(GrDirectContext* dContext) {
    SkASSERT(GrBackendApi::kOpenGL == dContext->backend());
    // Only compute whether the extension is present once the first time this
    // function is called.
    static bool hasIt = can_import_protected_content_eglimpl();
    return hasIt;
}

GrBackendTexture MakeGLBackendTexture(GrDirectContext* dContext,
                                      AHardwareBuffer* hardwareBuffer,
                                      int width, int height,
                                      DeleteImageProc* deleteProc,
                                      UpdateImageProc* updateProc,
                                      TexImageCtx* imageCtx,
                                      bool isProtectedContent,
                                      const GrBackendFormat& backendFormat,
                                      bool isRenderable) {
    SkASSERT(dContext);
    if (!dContext || dContext->abandoned()) {
        return GrBackendTexture();
    }

    if (GrBackendApi::kOpenGL != dContext->backend()) {
        return GrBackendTexture();
    }

    if (isProtectedContent && !can_import_protected_content(dContext)) {
        return GrBackendTexture();
    }

    if (isRenderable &&
        !dContext->priv().caps()->isFormatRenderable(backendFormat, /*sampleCount=*/1)) {
        return GrBackendTexture();
    }

    GrBackendTexture tex =
            make_gl_backend_texture(dContext, hardwareBuffer, width, height, deleteProc,
                                    updateProc, imageCtx, isProtectedContent, backendFormat);
    // Retry if we can still fallback external texture target.
    //
    // Even when the format is known, an AHB can fail to be imported as a regular GL_TEXTURE_2D for
    // reasons hidden from the GL API (e.g. lossy compression is meant for sample-only textures, in
    // which case a driver might fail glEGLImageTargetTexture2DOES for regular texture targets).
    //
    // NOTE: We exclude this fallback when `isRenderable == true` since we never treat external
    // formats as renderable. If we instead called MakeGLBackendTexture, we'd just fail the
    // renderable validation check above.
    if (!tex.isValid() &&
        !isRenderable &&
        backendFormat.textureType() != GrTextureType::kExternal) {
        tex = make_gl_backend_texture(dContext, hardwareBuffer, width, height, deleteProc,
                                      updateProc, imageCtx, isProtectedContent,
                                      GrBackendFormats::MakeGLExternal());
    }

    return tex;
}

}  // namespace GrAHardwareBufferUtils

#endif
