//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ExternalBufferTest:
//   Tests the correctness of external buffer ext extension.
//

#include "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"

#include "common/android_util.h"

#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
#    define ANGLE_AHARDWARE_BUFFER_SUPPORT
// NDK header file for access to Android Hardware Buffers
#    include <android/hardware_buffer.h>
#endif

namespace angle
{

class ExternalBufferTestES31 : public ANGLETest<>
{
  protected:
    ExternalBufferTestES31()
    {
        setWindowWidth(16);
        setWindowHeight(16);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
    }

    AHardwareBuffer *createAndroidHardwareBuffer(size_t size, const GLubyte *data)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        // The height and width are number of pixels of size format
        AHardwareBuffer_Desc aHardwareBufferDescription = {};
        aHardwareBufferDescription.width                = size;
        aHardwareBufferDescription.height               = 1;
        aHardwareBufferDescription.layers               = 1;
        aHardwareBufferDescription.format               = AHARDWAREBUFFER_FORMAT_BLOB;
        aHardwareBufferDescription.usage =
            AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
        aHardwareBufferDescription.stride = 0;

        // Allocate memory from Android Hardware Buffer
        AHardwareBuffer *aHardwareBuffer = nullptr;
        EXPECT_EQ(0, AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer));

        void *mappedMemory = nullptr;
        EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY,
                                          -1, nullptr, &mappedMemory));

        // Need to grab the stride the implementation might have enforced
        AHardwareBuffer_describe(aHardwareBuffer, &aHardwareBufferDescription);

        if (data)
        {
            ANGLE_UNSAFE_TODO(memcpy(mappedMemory, data, size));
        }

        EXPECT_EQ(0, AHardwareBuffer_unlock(aHardwareBuffer, nullptr));
        return aHardwareBuffer;
#else
        return nullptr;
#endif  // ANGLE_PLATFORM_ANDROID
    }

    void destroyAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        AHardwareBuffer_release(aHardwareBuffer);
#endif
    }

    void *lockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
    {
        void *data = nullptr;
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        EXPECT_EQ(0, AHardwareBuffer_lock(aHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
                                          -1, nullptr, &data));
#endif
        return data;
    }

    void unlockAndroidHardwareBuffer(AHardwareBuffer *aHardwareBuffer)
    {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
        AHardwareBuffer_unlock(aHardwareBuffer, nullptr);
#endif
    }
};

// Testing subdata update with external buffer from AHB
TEST_P(ExternalBufferTestES31, BufferSubData)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
    constexpr uint8_t kBufferSize = 16;
    std::vector<GLubyte> initData(kBufferSize, 0xA);

    // Create the Image
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;
    aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());

    GLBuffer buffer;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
    ASSERT_GL_NO_ERROR();

    std::vector<GLubyte> expectedData(kBufferSize, 0xFF);

    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
    glFinish();

    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the buffer using CPU access.
    uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));

    for (uint32_t i = 0; i < kBufferSize; ++i)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(data[i], 0xFF));
    }

    unlockAndroidHardwareBuffer(aHardwareBuffer);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    buffer.reset();
    // Delete the source AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Verify that subdata updates to an external buffer backed by an AHB doesn't orphan the AHB
TEST_P(ExternalBufferTestES31, SubDataDoesNotCauseOrphaning)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
    constexpr uint8_t kBufferSize = 16;
    std::vector<GLubyte> initData(kBufferSize, 0xA);

    // Create the AHB
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;
    aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());

    // Create externalBuffer
    GLBuffer externalBuffer;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, externalBuffer);
    glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
    ASSERT_GL_NO_ERROR();

    // Create a copy read buffer
    std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);
    GLBuffer copyReadBuffer;
    glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);
    glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);
    ASSERT_GL_NO_ERROR();

    // Copy from copyReadBuffer to externalBuffer
    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);
    ASSERT_GL_NO_ERROR();

    // Update externalBuffer
    std::vector<GLubyte> expectedData(kBufferSize, 0xFF);
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
    glFinish();
    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the AHB, through externalBuffer, using CPU access.
    uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));

    for (uint32_t i = 0; i < kBufferSize; ++i)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(data[i], 0xFF));
    }

    unlockAndroidHardwareBuffer(aHardwareBuffer);

    glBindBuffer(GL_COPY_READ_BUFFER, 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    copyReadBuffer.reset();
    externalBuffer.reset();
    // Delete the source AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Testing dispatch compute shader external from source AHB
TEST_P(ExternalBufferTestES31, DispatchCompute)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage"));
    constexpr char kCS[] = R"(#version 310 es
    layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
    layout(std430, binding=0) buffer Output {
        uint data[];
    } bOutput;
    void main() {
        bOutput.data[gl_GlobalInvocationID.x] =
            gl_GlobalInvocationID.x * 3u;
    }
)";

    constexpr uint8_t kBufferSize = 16 * 4;
    std::vector<GLubyte> initData(kBufferSize, 0xA);

    // Create the Image
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags = GL_MAP_READ_BIT;
    aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());

    GLBuffer buffer;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);

    ASSERT_GL_NO_ERROR();

    GLProgram program;
    program.makeCompute(kCS);
    ASSERT_NE(program, 0U);
    ASSERT_GL_NO_ERROR();

    glUseProgram(program);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
    glDispatchCompute(kBufferSize, 1, 1);
    glFinish();
    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the buffer using CPU access.
    uint32_t *data = static_cast<uint32_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));

    for (uint32_t i = 0; i < (kBufferSize / sizeof(uint32_t)); ++i)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(data[i], static_cast<uint32_t>(i * 3)));
    }

    unlockAndroidHardwareBuffer(aHardwareBuffer);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    buffer.reset();
    // Delete the source AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Test interaction between GL_OES_mapbuffer and GL_EXT_external_buffer extensions.
TEST_P(ExternalBufferTestES31, MapBuffer)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage") ||
                       !IsGLExtensionEnabled("GL_EXT_map_buffer_range"));
    constexpr uint8_t kBufferSize = 16;
    std::vector<GLubyte> initData(kBufferSize, 0xFF);

    // Create the AHB
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags = (GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT);
    aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());

    GLBuffer buffer;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);

    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the buffer using CPU access.
    uint8_t *data = static_cast<uint8_t *>(
        glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT_EXT));
    ASSERT_GL_NO_ERROR();

    for (uint32_t i = 0; i < kBufferSize; ++i)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(data[i], 0xFF));
    }

    glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    buffer.reset();
    // Delete the source AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Verify that mapping an external buffer backed by an AHB doesn't orphan the AHB
TEST_P(ExternalBufferTestES31, MapBufferDoesNotCauseOrphaning)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage") ||
                       !IsGLExtensionEnabled("GL_EXT_map_buffer_range"));
    constexpr uint8_t kBufferSize = 16;
    std::vector<GLubyte> initData(kBufferSize, 0xA);

    // Create the AHB
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags =
        (GL_MAP_READ_BIT_EXT | GL_MAP_WRITE_BIT_EXT | GL_DYNAMIC_STORAGE_BIT_EXT);
    aHardwareBuffer = createAndroidHardwareBuffer(kBufferSize, initData.data());

    GLBuffer buffer;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
    ASSERT_GL_NO_ERROR();

    // Create a copy read buffer
    std::vector<GLubyte> copyReadBufferData(kBufferSize, 0xB);
    GLBuffer copyReadBuffer;
    glBindBuffer(GL_COPY_READ_BUFFER, copyReadBuffer);
    glBufferData(GL_COPY_READ_BUFFER, kBufferSize, copyReadBufferData.data(), GL_STATIC_READ);
    ASSERT_GL_NO_ERROR();

    // Copy from copyReadBuffer to externalBuffer
    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, kBufferSize);
    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the buffer using map buffer API.
    constexpr GLbitfield kMapFlags = (GL_MAP_WRITE_BIT_EXT | GL_MAP_INVALIDATE_BUFFER_BIT);
    uint8_t *mapData               = static_cast<uint8_t *>(
        glMapBufferRangeEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, kMapFlags));
    ASSERT_GL_NO_ERROR();
    EXPECT_NE(mapData, nullptr);
    glUnmapBufferOES(GL_SHADER_STORAGE_BUFFER);

    // Update externalBuffer
    std::vector<GLubyte> expectedData(kBufferSize, 0xFF);
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, expectedData.data());
    glFinish();
    ASSERT_GL_NO_ERROR();

    // Inspect the data written into the AHB, through externalBuffer, using CPU access.
    uint8_t *data = static_cast<uint8_t *>(lockAndroidHardwareBuffer(aHardwareBuffer));

    for (uint32_t i = 0; i < kBufferSize; ++i)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(data[i], 0xFF));
    }

    unlockAndroidHardwareBuffer(aHardwareBuffer);

    glBindBuffer(GL_COPY_READ_BUFFER, 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
    copyReadBuffer.reset();
    buffer.reset();
    // Delete the source AHB
    destroyAndroidHardwareBuffer(aHardwareBuffer);
}

// Verify that create and destroy external buffer backed by an AHB doesn't leak AHB
TEST_P(ExternalBufferTestES31, BufferDoesNotLeakAHB)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage"));

    // Create and destroy 128M AHB backed buffer in a loop. If we leak AHB, it will fail due to AHB
    // allocation failure before loop ends.
    constexpr size_t kBufferSize = 128 * 1024 * 1024;
    for (int loop = 0; loop < 1000; loop++)
    {
        // Create the AHB
        AHardwareBuffer *aHardwareBuffer;
        constexpr GLbitfield kFlags = GL_DYNAMIC_STORAGE_BIT_EXT;
        aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, nullptr);
        GLBuffer buffer;
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
        glBufferStorageExternalEXT(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
                                   eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
        ASSERT_GL_NO_ERROR();
        buffer.reset();
        // Delete the source AHB
        destroyAndroidHardwareBuffer(aHardwareBuffer);
    }
}

// Test that checks buffer object state after calling glBufferStorageExternalEXT
TEST_P(ExternalBufferTestES31, getBufferParameter)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_external_buffer") ||
                       !IsGLExtensionEnabled("GL_EXT_buffer_storage"));

    GLint64 value = -1;

    constexpr uint8_t kBufferSize = 3;
    std::vector<GLubyte> initData(kBufferSize, 0xA);

    // Create the Image
    AHardwareBuffer *aHardwareBuffer;
    constexpr GLbitfield kFlags = GL_MAP_WRITE_BIT;
    aHardwareBuffer             = createAndroidHardwareBuffer(kBufferSize, initData.data());

    GLBuffer buffer;
    glBindBuffer(GL_COPY_READ_BUFFER, buffer);
    glBufferStorageExternalEXT(GL_COPY_READ_BUFFER, 0, kBufferSize,
                               eglGetNativeClientBufferANDROID(aHardwareBuffer), kFlags);
    ASSERT_GL_NO_ERROR();

    /* Check the value of GL_BUFFER_SIZE. */
    glGetBufferParameteri64v(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &value);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(kBufferSize, static_cast<GLint>(value));

    /* Check the value of GL_BUFFER_USAGE. */
    value = -1;
    glGetBufferParameteri64v(GL_COPY_READ_BUFFER, GL_BUFFER_USAGE, &value);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(GL_DYNAMIC_DRAW, value);

    /* Check the value of GL_BUFFER_IMMUTABLE_STORAGE_EXT. */
    value = -1;
    glGetBufferParameteri64v(GL_COPY_READ_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE_EXT, &value);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(GL_TRUE, value);

    /* Check the value of GL_BUFFER_STORAGE_FLAGS_EXT. */
    value = -1;
    glGetBufferParameteri64v(GL_COPY_READ_BUFFER, GL_BUFFER_STORAGE_FLAGS_EXT, &value);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(kFlags, value);

    /* Clean up. */
    glUnmapBuffer(GL_COPY_READ_BUFFER);
    glBindBuffer(GL_COPY_READ_BUFFER, 0);
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ExternalBufferTestES31);
ANGLE_INSTANTIATE_TEST_ES31(ExternalBufferTestES31);
}  // namespace angle
