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

#include "SkTypes.h"

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

#include "GrAHardwareBufferUtils.h"

#include <algorithm>
#include <array>
#include <cstdio>
#include <cstring>
#include <string>

#include <android/hardware_buffer.h>

#include "GrContext.h"
#include "GrContextPriv.h"
#include "gl/GrGLDefines.h"
#include "gl/GrGLTypes.h"

#ifdef SK_VULKAN
#include "vk/GrVkCaps.h"
#include "vk/GrVkGpu.h"
#endif

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

#include <cutils/properties.h>

// Direct access to private framework and HAL data to workaround Adreno 330 driver bugs.
// DO NOT actually call anything from these headers; they are included only to access private
// structs.
#include "../../../../frameworks/native/libs/nativebase/include/nativebase/nativebase.h"
#include "../../../../hardware/qcom/display/libgralloc/gralloc_priv.h"

#define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content"
#define EGL_PROTECTED_CONTENT_EXT 0x32C0

#define VK_CALL(X) gpu->vkInterface()->fFunctions.f##X;

namespace GrAHardwareBufferUtils {

SkColorType GetSkColorTypeFromBufferFormat(uint32_t bufferFormat) {
    switch (bufferFormat) {
        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
            return kRGBA_8888_SkColorType;
        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
            return kRGB_888x_SkColorType;
        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
            return kRGBA_F16_SkColorType;
        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
            return kRGB_565_SkColorType;
        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
            return kRGB_888x_SkColorType;
        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
            return kRGBA_1010102_SkColorType;
        default:
            // Given that we only use this texture as a source, colorType will not impact how Skia
            // uses the texture.  The only potential affect this is anticipated to have is that for
            // some format types if we are not bound as an OES texture we may get invalid results
            // for SKP capture if we read back the texture.
            return kRGBA_8888_SkColorType;
    }
}

GrBackendFormat GetBackendFormat(GrContext* context, AHardwareBuffer* hardwareBuffer,
                                 uint32_t bufferFormat, bool requireKnownFormat) {
    GrBackendApi backend = context->backend();

    if (backend == GrBackendApi::kOpenGL) {
        switch (bufferFormat) {
            //TODO: find out if we can detect, which graphic buffers support GR_GL_TEXTURE_2D
            case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
            case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
                return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
            case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
                return GrBackendFormat::MakeGL(GR_GL_RGBA16F, GR_GL_TEXTURE_EXTERNAL);
            case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
                return GrBackendFormat::MakeGL(GR_GL_RGB565, GR_GL_TEXTURE_EXTERNAL);
            case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
                return GrBackendFormat::MakeGL(GR_GL_RGB10_A2, GR_GL_TEXTURE_EXTERNAL);
            case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
                return GrBackendFormat::MakeGL(GR_GL_RGB8, GR_GL_TEXTURE_EXTERNAL);
            default:
                if (requireKnownFormat) {
                    return GrBackendFormat();
                } else {
                    return GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_EXTERNAL);
                }
        }
    } else if (backend == GrBackendApi::kVulkan) {
#ifdef SK_VULKAN
        switch (bufferFormat) {
            case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
                return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
            case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
                return GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT);
            case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
                return GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16);
            case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
                return GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32);
            case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
                return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM);
            case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
                return GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM);
            default: {
                if (requireKnownFormat) {
                    return GrBackendFormat();
                } else {
                    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->priv().getGpu());
                    SkASSERT(gpu);
                    VkDevice device = gpu->device();

                    if (!gpu->vkCaps().supportsAndroidHWBExternalMemory()) {
                        return GrBackendFormat();
                    }
                    VkAndroidHardwareBufferFormatPropertiesANDROID hwbFormatProps;
                    hwbFormatProps.sType =
                            VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
                    hwbFormatProps.pNext = nullptr;

                    VkAndroidHardwareBufferPropertiesANDROID hwbProps;
                    hwbProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
                    hwbProps.pNext = &hwbFormatProps;

                    VkResult err = VK_CALL(GetAndroidHardwareBufferProperties(device,
                                                                              hardwareBuffer,
                                                                              &hwbProps));
                    if (VK_SUCCESS != err) {
                        return GrBackendFormat();
                    }

                    if (hwbFormatProps.format != VK_FORMAT_UNDEFINED) {
                        return GrBackendFormat();
                    }

                    GrVkYcbcrConversionInfo ycbcrConversion;
                    ycbcrConversion.fYcbcrModel = hwbFormatProps.suggestedYcbcrModel;
                    ycbcrConversion.fYcbcrRange = hwbFormatProps.suggestedYcbcrRange;
                    ycbcrConversion.fXChromaOffset = hwbFormatProps.suggestedXChromaOffset;
                    ycbcrConversion.fYChromaOffset = hwbFormatProps.suggestedYChromaOffset;
                    ycbcrConversion.fForceExplicitReconstruction = VK_FALSE;
                    ycbcrConversion.fExternalFormat = hwbFormatProps.externalFormat;
                    ycbcrConversion.fExternalFormatFeatures = hwbFormatProps.formatFeatures;
                    if (VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT &
                        hwbFormatProps.formatFeatures) {
                        ycbcrConversion.fChromaFilter = VK_FILTER_LINEAR;
                    } else {
                        ycbcrConversion.fChromaFilter = VK_FILTER_NEAREST;
                    }

                    return GrBackendFormat::MakeVk(ycbcrConversion);
                }
            }
        }
#else
        return GrBackendFormat();
#endif
    }
    return GrBackendFormat();
}

class NativeGLCleanupHelper {
public:
    NativeGLCleanupHelper(GrGLuint texID)
        : fTexID(texID) { }
    ~NativeGLCleanupHelper() {
        // Compared to GLCleanupHelper, we don't have an EGLImageKHR, but a
        // regular GL texture with its own storage. Thus, there's also no
        // reference to the AHardwareBuffer anymore.
        glDeleteTextures(1, &fTexID);
    }
private:
    GrGLuint fTexID;
};

void delete_native_gl_texture(void* context) {
    auto cleanupHelper = static_cast<NativeGLCleanupHelper*>(context);
    delete cleanupHelper;
}

static const auto EGLImageWorkaroundAllowlist = std::array{
    "android.uirendering.cts",
    "com.android.launcher3",
};

static bool isProcessOnEGLWorkaroundAllowlist() {
    static bool checked = false;
    static bool isOnAllowlist = false;
    if (checked) {
        return isOnAllowlist;
    }

    const char* processName = getprogname();
    if (!processName) {
        // Cannot read, so need to assume false.
        isOnAllowlist = false;
        checked = true;
        return isOnAllowlist;
    }

    const auto& l = EGLImageWorkaroundAllowlist;
    isOnAllowlist = std::find(l.begin(), l.end(), std::string(processName)) != l.end();
    checked = true;

    if (isOnAllowlist) {
        SkDebugf("createGLTextureFromPrivateHandle: process is listed for EGLImage "
            "workaround");
    }

    return isOnAllowlist;
}

static GrBackendTexture createGLTextureFromPrivateHandle(
    GrContext* context, const AHardwareBuffer* hardwareBuffer,
    const int imageWidth, const int imageHeight,
    DeleteImageProc* deleteProc, DeleteImageCtx* deleteCtx,
    const GrBackendFormat& backendFormat) {

    if (!isProcessOnEGLWorkaroundAllowlist()) {
        return GrBackendTexture();
    }

    if (!hardwareBuffer) {
        SkDebugf("createGLTextureFromPrivateHandle: Cannot work without AHardwareBuffer");
        return GrBackendTexture();
    }

    const GrGLenum* glFormat = backendFormat.getGLFormat();
    if (!glFormat) {
        SkDebugf("createGLTextureFromPrivateHandle: backend API must be GL.");
        return GrBackendTexture();
    }

    size_t bytesPerPixel = 0;
    GrGLenum type = GL_INVALID_ENUM;
    // In the fall-back OpenGL ES 2.0 context sized formats are not supported,
    // so translate to the unsized format enums.
    GrGLenum format = GL_INVALID_ENUM;
    switch (*glFormat) {
    case GR_GL_RGBA8:
        format = GL_RGBA;
        bytesPerPixel = 4;
        type = GL_UNSIGNED_BYTE;
        break;
    case GR_GL_RGB565:
        format = GL_RGB;
        bytesPerPixel = 2;
        type = GL_UNSIGNED_SHORT_5_6_5;
        break;
    default:
        SkDebugf("createGLTextureFromPrivateHandle: Unsupported GL format %u", *glFormat);
        return GrBackendTexture();
    }

    EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(hardwareBuffer);
    const native_handle_t* nativeHandle =
        reinterpret_cast<const ANativeWindowBuffer*>(clientBuffer)->handle;
    const bool handleIsAsExpected = private_handle_t::validate(nativeHandle) == 0;
    if (!handleIsAsExpected) {
        SkDebugf("createGLTextureFromPrivateHandle: GraphicBuffer doesn't seem to map to gralloc "
            "private handle.");
        return GrBackendTexture();
    }
    const private_handle_t* hnd = static_cast<const private_handle_t*>(nativeHandle);

    if (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER) {
        // The buffer comes from a non-CPU hardware component. Specifically for buffers coming from
        // hardware encoders, access doesn't seem to work reliably in the way it's done here.
        SkDebugf("createGLTextureFromPrivateHandle: Cannot handle non-CPU buffers.");
        return GrBackendTexture();
    }

    if (hnd->flags & private_handle_t::PRIV_FLAGS_HW_COMPOSER) {
        SkDebugf("createGLTextureFromPrivateHandle: Cannot handle hardware composer buffers.");
        return GrBackendTexture();
    }

    const int bufferWidth = hnd->width; // May be aligned and be larger than the actual image.
    const int bufferHeight = hnd->height;
    if (imageWidth > bufferWidth || imageHeight > bufferHeight) {
        SkDebugf("createGLTextureFromPrivateHandle: image is larger than the buffer. This is not "
            "supposed to happen.");
        return GrBackendTexture();
    }
    const size_t bufferRowBytes = bufferWidth * bytesPerPixel;
    // We access as many rows as the image has, aligned to the width of the buffer.
    const size_t minBufferSize = bufferRowBytes * imageHeight;
    if (hnd->size < 0 || static_cast<size_t>(hnd->size) < minBufferSize) {
        SkDebugf("createGLTextureFromPrivateHandle: buffer is smaller than expected or invalid.");
        return GrBackendTexture();
    }

    const char* bufferData = reinterpret_cast<const char*>(hnd->base);

    GrGLuint texID;
    glGenTextures(1, &texID);
    glBindTexture(GL_TEXTURE_2D, texID);

    if (imageWidth == bufferWidth) {
        // Take the quick path if possible
        glTexImage2D(GL_TEXTURE_2D, 0, format, imageWidth, imageHeight, 0, format, type, bufferData);
    } else {
        // The buffer has some extra space for alignment. Copy row by row.
        // First allocate the texture storage without filling it.
        glTexImage2D(GL_TEXTURE_2D, 0, format, imageWidth, imageHeight, 0, format, type, 0);
        for (int y = 0; y < imageHeight; ++y) {
            const void* bufferRowAddr = bufferData + static_cast<size_t>(y) * bufferRowBytes;
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, y, imageWidth, 1, format, type, bufferRowAddr);
        }
    }
    int gl_error;
    bool hasGlError = false;
    while (GL_NO_ERROR != (gl_error = glGetError())) {
        SkDebugf("createGLTextureFromPrivateHandle: glGetError reports %i", gl_error);
        hasGlError = true;
    }
    if (hasGlError) {
        SkDebugf("createGLTextureFromPrivateHandle: discarding results, because we had GL errors.");
        glDeleteTextures(1, &texID);
        return GrBackendTexture();
    }

    GrGLTextureInfo textureInfo;
    textureInfo.fID = texID;
    SkASSERT(backendFormat.isValid());
    textureInfo.fTarget = GL_TEXTURE_2D;
    // Store the original, potentially sized format here, not the more compatible unsized one.
    textureInfo.fFormat = *glFormat;

    GrBackendTexture backendTex(imageWidth, imageHeight, GrMipMapped::kNo, textureInfo);

    *deleteProc = delete_native_gl_texture;
    *deleteCtx = new NativeGLCleanupHelper(texID);

    return backendTex;
}

class GLCleanupHelper {
public:
    GLCleanupHelper(GrGLuint texID, EGLImageKHR image, EGLDisplay display)
        : fTexID(texID)
        , fImage(image)
        , fDisplay(display) { }
    ~GLCleanupHelper() {
        glDeleteTextures(1, &fTexID);
        // eglDestroyImageKHR will remove a ref from the AHardwareBuffer
        eglDestroyImageKHR(fDisplay, fImage);
    }
private:
    GrGLuint    fTexID;
    EGLImageKHR fImage;
    EGLDisplay  fDisplay;
};

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

static GrBackendTexture make_gl_backend_texture(
        GrContext* context, AHardwareBuffer* hardwareBuffer,
        int width, int height,
        DeleteImageProc* deleteProc,
        DeleteImageCtx* deleteCtx,
        bool isProtectedContent,
        const GrBackendFormat& backendFormat,
        bool isRenderable) {
    while (GL_NO_ERROR != glGetError()) {} //clear GL errors

    // On Adreno 330 drivers sampling from EGLImage bound to GL_TEXTURE_EXTERNAL_OES texture targets
    // leads to artifacts. Copy image data into a regular GL texture instead.
    static const bool gl_tex_workaround_enabled =
        [] () -> bool {
            const int value = property_get_bool("skia.force_gl_texture", 0);
            SkDebugf("make_gl_backend_texture skia.force_gl_texture=%i", value);
            return bool(value);
        }();

    if (gl_tex_workaround_enabled) {
        GrBackendTexture tex = createGLTextureFromPrivateHandle(
            context, hardwareBuffer, width, height, deleteProc, deleteCtx, backendFormat);

        if (tex.isValid()) {
            return tex;
        }
        SkDebugf("make_gl_backend_texture: Private data access workaround failed. Falling back "
            "native buffer access.");
    }

    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) {
        SkDebugf("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 = isRenderable ? GR_GL_TEXTURE_2D : GR_GL_TEXTURE_EXTERNAL;

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

    GrGLTextureInfo textureInfo;
    textureInfo.fID = texID;
    SkASSERT(backendFormat.isValid());
    textureInfo.fTarget = target;
    textureInfo.fFormat = *backendFormat.getGLFormat();

    *deleteProc = delete_gl_texture;
    *deleteCtx = new GLCleanupHelper(texID, image, display);

    return GrBackendTexture(width, height, GrMipMapped::kNo, textureInfo);
}

#ifdef SK_VULKAN
class VulkanCleanupHelper {
public:
    VulkanCleanupHelper(GrVkGpu* gpu, VkImage image, VkDeviceMemory memory)
        : fDevice(gpu->device())
        , fImage(image)
        , fMemory(memory)
        , fDestroyImage(gpu->vkInterface()->fFunctions.fDestroyImage)
        , fFreeMemory(gpu->vkInterface()->fFunctions.fFreeMemory) {}
    ~VulkanCleanupHelper() {
        fDestroyImage(fDevice, fImage, nullptr);
        fFreeMemory(fDevice, fMemory, nullptr);
    }
private:
    VkDevice           fDevice;
    VkImage            fImage;
    VkDeviceMemory     fMemory;
    PFN_vkDestroyImage fDestroyImage;
    PFN_vkFreeMemory   fFreeMemory;
};

void delete_vk_image(void* context) {
    VulkanCleanupHelper* cleanupHelper = static_cast<VulkanCleanupHelper*>(context);
    delete cleanupHelper;
}

static GrBackendTexture make_vk_backend_texture(
        GrContext* context, AHardwareBuffer* hardwareBuffer,
        int width, int height,
        DeleteImageProc* deleteProc,
        DeleteImageCtx* deleteCtx,
        bool isProtectedContent,
        const GrBackendFormat& backendFormat,
        bool isRenderable) {
    SkASSERT(context->backend() == GrBackendApi::kVulkan);
    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->priv().getGpu());

    VkPhysicalDevice physicalDevice = gpu->physicalDevice();
    VkDevice device = gpu->device();

    SkASSERT(gpu);

    if (!gpu->vkCaps().supportsAndroidHWBExternalMemory()) {
        return GrBackendTexture();
    }

    SkASSERT(backendFormat.getVkFormat());
    VkFormat format = *backendFormat.getVkFormat();

    VkResult err;

    VkAndroidHardwareBufferFormatPropertiesANDROID hwbFormatProps;
    hwbFormatProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
    hwbFormatProps.pNext = nullptr;

    VkAndroidHardwareBufferPropertiesANDROID hwbProps;
    hwbProps.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
    hwbProps.pNext = &hwbFormatProps;

    err = VK_CALL(GetAndroidHardwareBufferProperties(device, hardwareBuffer, &hwbProps));
    if (VK_SUCCESS != err) {
        return GrBackendTexture();
    }

    VkExternalFormatANDROID externalFormat;
    externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
    externalFormat.pNext = nullptr;
    externalFormat.externalFormat = 0;  // If this is zero it is as if we aren't using this struct.

    const GrVkYcbcrConversionInfo* ycbcrConversion = backendFormat.getVkYcbcrConversionInfo();
    if (!ycbcrConversion) {
        return GrBackendTexture();
    }

    if (hwbFormatProps.format != VK_FORMAT_UNDEFINED) {
        // TODO: We should not assume the transfer features here and instead should have a way for
        // Ganesh's tracking of intenral images to report whether or not they support transfers.
        SkASSERT(SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & hwbFormatProps.formatFeatures) &&
                 SkToBool(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT & hwbFormatProps.formatFeatures) &&
                 SkToBool(VK_FORMAT_FEATURE_TRANSFER_DST_BIT & hwbFormatProps.formatFeatures));
        SkASSERT(!ycbcrConversion->isValid());
    } else {
        SkASSERT(ycbcrConversion->isValid());
        // We have an external only format
        SkASSERT(SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & hwbFormatProps.formatFeatures));
        SkASSERT(format == VK_FORMAT_UNDEFINED);
        SkASSERT(hwbFormatProps.externalFormat == ycbcrConversion->fExternalFormat);
        externalFormat.externalFormat = hwbFormatProps.externalFormat;
    }
    SkASSERT(format == hwbFormatProps.format);

    const VkExternalMemoryImageCreateInfo externalMemoryImageInfo{
            VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,                 // sType
            &externalFormat,                                                     // pNext
            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,  // handleTypes
    };
    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
    if (format != VK_FORMAT_UNDEFINED) {
        usageFlags = usageFlags |
                VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                VK_IMAGE_USAGE_TRANSFER_DST_BIT;
        if (isRenderable) {
            usageFlags = usageFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
        }
    }

    // TODO: Check the supported tilings vkGetPhysicalDeviceImageFormatProperties2 to see if we have
    // to use linear. Add better linear support throughout Ganesh.
    VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;

    const VkImageCreateInfo imageCreateInfo = {
        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,         // sType
        &externalMemoryImageInfo,                    // pNext
        0,                                           // VkImageCreateFlags
        VK_IMAGE_TYPE_2D,                            // VkImageType
        format,                                      // VkFormat
        { (uint32_t)width, (uint32_t)height, 1 },    // VkExtent3D
        1,                                           // mipLevels
        1,                                           // arrayLayers
        VK_SAMPLE_COUNT_1_BIT,                       // samples
        tiling,                                      // VkImageTiling
        usageFlags,                                  // VkImageUsageFlags
        VK_SHARING_MODE_EXCLUSIVE,                   // VkSharingMode
        0,                                           // queueFamilyCount
        0,                                           // pQueueFamilyIndices
        VK_IMAGE_LAYOUT_UNDEFINED,                   // initialLayout
    };

    VkImage image;
    err = VK_CALL(CreateImage(device, &imageCreateInfo, nullptr, &image));
    if (VK_SUCCESS != err) {
        return GrBackendTexture();
    }

    VkPhysicalDeviceMemoryProperties2 phyDevMemProps;
    phyDevMemProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
    phyDevMemProps.pNext = nullptr;

    uint32_t typeIndex = 0;
    uint32_t heapIndex = 0;
    bool foundHeap = false;
    VK_CALL(GetPhysicalDeviceMemoryProperties2(physicalDevice, &phyDevMemProps));
    uint32_t memTypeCnt = phyDevMemProps.memoryProperties.memoryTypeCount;
    for (uint32_t i = 0; i < memTypeCnt && !foundHeap; ++i) {
        if (hwbProps.memoryTypeBits & (1 << i)) {
            const VkPhysicalDeviceMemoryProperties& pdmp = phyDevMemProps.memoryProperties;
            uint32_t supportedFlags = pdmp.memoryTypes[i].propertyFlags &
                    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
            if (supportedFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
                typeIndex = i;
                heapIndex = pdmp.memoryTypes[i].heapIndex;
                foundHeap = true;
            }
        }
    }
    if (!foundHeap) {
        VK_CALL(DestroyImage(device, image, nullptr));
        return GrBackendTexture();
    }

    VkImportAndroidHardwareBufferInfoANDROID hwbImportInfo;
    hwbImportInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
    hwbImportInfo.pNext = nullptr;
    hwbImportInfo.buffer = hardwareBuffer;

    VkMemoryDedicatedAllocateInfo dedicatedAllocInfo;
    dedicatedAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
    dedicatedAllocInfo.pNext = &hwbImportInfo;
    dedicatedAllocInfo.image = image;
    dedicatedAllocInfo.buffer = VK_NULL_HANDLE;

    VkMemoryAllocateInfo allocInfo = {
        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,      // sType
        &dedicatedAllocInfo,                         // pNext
        hwbProps.allocationSize,                     // allocationSize
        typeIndex,                                   // memoryTypeIndex
    };

    VkDeviceMemory memory;

    err = VK_CALL(AllocateMemory(device, &allocInfo, nullptr, &memory));
    if (VK_SUCCESS != err) {
        VK_CALL(DestroyImage(device, image, nullptr));
        return GrBackendTexture();
    }

    VkBindImageMemoryInfo bindImageInfo;
    bindImageInfo.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
    bindImageInfo.pNext = nullptr;
    bindImageInfo.image = image;
    bindImageInfo.memory = memory;
    bindImageInfo.memoryOffset = 0;

    err = VK_CALL(BindImageMemory2(device, 1, &bindImageInfo));
    if (VK_SUCCESS != err) {
        VK_CALL(DestroyImage(device, image, nullptr));
        VK_CALL(FreeMemory(device, memory, nullptr));
        return GrBackendTexture();
    }

    GrVkImageInfo imageInfo;

    imageInfo.fImage = image;
    imageInfo.fAlloc = GrVkAlloc(memory, 0, hwbProps.allocationSize, 0);
    imageInfo.fImageTiling = tiling;
    imageInfo.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageInfo.fFormat = format;
    imageInfo.fLevelCount = 1;
    // TODO: This should possibly be VK_QUEUE_FAMILY_FOREIGN_EXT but current Adreno devices do not
    // support that extension. Or if we know the source of the AHardwareBuffer is not from a
    // "foreign" device we can leave them as external.
    imageInfo.fCurrentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
    imageInfo.fYcbcrConversionInfo = *ycbcrConversion;

    *deleteProc = delete_vk_image;
    *deleteCtx = new VulkanCleanupHelper(gpu, image, memory);

    return GrBackendTexture(width, height, imageInfo);
}
#endif

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(GrContext* context) {
    if (GrBackendApi::kOpenGL == context->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;
    }
    return false;
}

GrBackendTexture MakeBackendTexture(GrContext* context, AHardwareBuffer* hardwareBuffer,
                                    int width, int height,
                                    DeleteImageProc* deleteProc,
                                    DeleteImageCtx* deleteCtx,
                                    bool isProtectedContent,
                                    const GrBackendFormat& backendFormat,
                                    bool isRenderable) {
    if (context->abandoned()) {
        return GrBackendTexture();
    }
    bool createProtectedImage = isProtectedContent && can_import_protected_content(context);

    if (GrBackendApi::kOpenGL == context->backend()) {
        return make_gl_backend_texture(context, hardwareBuffer, width, height, deleteProc,
                                       deleteCtx, createProtectedImage, backendFormat,
                                       isRenderable);
    } else {
        SkASSERT(GrBackendApi::kVulkan == context->backend());
#ifdef SK_VULKAN
        // Currently we don't support protected images on vulkan
        SkASSERT(!createProtectedImage);
        return make_vk_backend_texture(context, hardwareBuffer, width, height, deleteProc,
                                       deleteCtx, createProtectedImage, backendFormat,
                                       isRenderable);
#else
        return GrBackendTexture();
#endif
    }
}

} // GrAHardwareBufferUtils

#endif

