// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tests/DawnTest.h"

#include "common/DynamicLib.h"
#include "dawn_native/OpenGLBackend.h"
#include "dawn_native/opengl/DeviceGL.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

#include <EGL/egl.h>

namespace {

    class EGLFunctions {
      public:
        EGLFunctions() {
#ifdef DAWN_PLATFORM_WINDOWS
            const char* eglLib = "libEGL.dll";
#else
            const char* eglLib = "libEGL.so";
#endif
            EXPECT_TRUE(mlibEGL.Open(eglLib));
            CreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(LoadProc("eglCreateImage"));
            DestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(LoadProc("eglDestroyImage"));
            GetCurrentContext =
                reinterpret_cast<PFNEGLGETCURRENTCONTEXTPROC>(LoadProc("eglGetCurrentContext"));
            GetCurrentDisplay =
                reinterpret_cast<PFNEGLGETCURRENTDISPLAYPROC>(LoadProc("eglGetCurrentDisplay"));
        }

      private:
        void* LoadProc(const char* name) {
            void* proc = mlibEGL.GetProc(name);
            EXPECT_NE(proc, nullptr);
            return proc;
        }

      public:
        PFNEGLCREATEIMAGEPROC CreateImage;
        PFNEGLDESTROYIMAGEPROC DestroyImage;
        PFNEGLGETCURRENTCONTEXTPROC GetCurrentContext;
        PFNEGLGETCURRENTDISPLAYPROC GetCurrentDisplay;

      private:
        DynamicLib mlibEGL;
    };

    class ScopedEGLImage {
      public:
        ScopedEGLImage(PFNEGLDESTROYIMAGEPROC destroyImage,
                       PFNGLDELETETEXTURESPROC deleteTextures,
                       EGLDisplay display,
                       EGLImage image,
                       GLuint texture)
            : mDestroyImage(destroyImage),
              mDeleteTextures(deleteTextures),
              mDisplay(display),
              mImage(image),
              mTexture(texture) {
        }

        ScopedEGLImage(ScopedEGLImage&& other) {
            if (mImage != nullptr) {
                mDestroyImage(mDisplay, mImage);
            }
            if (mTexture != 0) {
                mDeleteTextures(1, &mTexture);
            }
            mDestroyImage = std::move(other.mDestroyImage);
            mDeleteTextures = std::move(other.mDeleteTextures);
            mDisplay = std::move(other.mDisplay);
            mImage = std::move(other.mImage);
            mTexture = std::move(other.mTexture);
        }

        ~ScopedEGLImage() {
            if (mTexture != 0) {
                mDeleteTextures(1, &mTexture);
            }
            if (mImage != nullptr) {
                mDestroyImage(mDisplay, mImage);
            }
        }

        EGLImage getImage() const {
            return mImage;
        }

        GLuint getTexture() const {
            return mTexture;
        }

      private:
        PFNEGLDESTROYIMAGEPROC mDestroyImage = nullptr;
        PFNGLDELETETEXTURESPROC mDeleteTextures = nullptr;
        EGLDisplay mDisplay = nullptr;
        EGLImage mImage = nullptr;
        GLuint mTexture = 0;
    };

}  // anonymous namespace

class EGLImageTestBase : public DawnTest {
  public:
    ScopedEGLImage CreateEGLImage(uint32_t width,
                                  uint32_t height,
                                  GLenum internalFormat,
                                  GLenum format,
                                  GLenum type,
                                  void* data,
                                  size_t size) {
        dawn_native::opengl::Device* openglDevice =
            reinterpret_cast<dawn_native::opengl::Device*>(device.Get());
        const dawn_native::opengl::OpenGLFunctions& gl = openglDevice->gl;
        GLuint tex;
        gl.GenTextures(1, &tex);
        gl.BindTexture(GL_TEXTURE_2D, tex);
        gl.TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, data);
        EGLAttrib attribs[1] = {EGL_NONE};
        EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
        EGLDisplay dpy = egl.GetCurrentDisplay();
        EGLContext ctx = egl.GetCurrentContext();
        EGLImage eglImage = egl.CreateImage(dpy, ctx, EGL_GL_TEXTURE_2D, buffer, attribs);
        EXPECT_NE(nullptr, eglImage);

        return ScopedEGLImage(egl.DestroyImage, gl.DeleteTextures, dpy, eglImage, tex);
    }
    wgpu::Texture WrapEGLImage(const wgpu::TextureDescriptor* descriptor, EGLImage eglImage) {
        dawn_native::opengl::ExternalImageDescriptorEGLImage externDesc;
        externDesc.cTextureDescriptor = reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
        externDesc.image = eglImage;
        WGPUTexture texture = dawn_native::opengl::WrapExternalEGLImage(device.Get(), &externDesc);
        return wgpu::Texture::Acquire(texture);
    }
    EGLFunctions egl;
};

// A small fixture used to initialize default data for the EGLImage validation tests.
// These tests are skipped if the harness is using the wire.
class EGLImageValidationTests : public EGLImageTestBase {
  public:
    EGLImageValidationTests() {
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.size = {10, 10, 1};
        descriptor.sampleCount = 1;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;
    }

    ScopedEGLImage CreateDefaultEGLImage() {
        return CreateEGLImage(10, 10, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, 0);
    }

  protected:
    wgpu::TextureDescriptor descriptor;
};

// Test a successful wrapping of an EGLImage in a texture
TEST_P(EGLImageValidationTests, Success) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage image = CreateDefaultEGLImage();
    wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage());
    ASSERT_NE(texture.Get(), nullptr);
}

// Test an error occurs if the texture descriptor is invalid
TEST_P(EGLImageValidationTests, InvalidTextureDescriptor) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());

    wgpu::ChainedStruct chainedDescriptor;
    descriptor.nextInChain = &chainedDescriptor;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor dimension isn't 2D
TEST_P(EGLImageValidationTests, InvalidTextureDimension) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.dimension = wgpu::TextureDimension::e3D;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the texture usage is not RenderAttachment
TEST_P(EGLImageValidationTests, InvalidTextureUsage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.usage = wgpu::TextureUsage::Sampled;

    ScopedEGLImage image = CreateDefaultEGLImage();
    wgpu::Texture texture;
    ASSERT_DEVICE_ERROR(texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
    descriptor.usage = wgpu::TextureUsage::Storage;

    ASSERT_DEVICE_ERROR(texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor mip level count isn't 1
TEST_P(EGLImageValidationTests, InvalidMipLevelCount) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.mipLevelCount = 2;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor depth isn't 1
TEST_P(EGLImageValidationTests, InvalidDepth) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.depthOrArrayLayers = 2;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor sample count isn't 1
TEST_P(EGLImageValidationTests, InvalidSampleCount) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.sampleCount = 4;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor width doesn't match the surface's
TEST_P(EGLImageValidationTests, InvalidWidth) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.width = 11;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor height doesn't match the surface's
TEST_P(EGLImageValidationTests, InvalidHeight) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.height = 11;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Fixture to test using EGLImages through different usages.
// These tests are skipped if the harness is using the wire.
class EGLImageUsageTests : public EGLImageTestBase {
  public:
    // Test that clearing using BeginRenderPass writes correct data in the eglImage.
    void DoClearTest(EGLImage eglImage,
                     GLuint texture,
                     wgpu::TextureFormat format,
                     GLenum glFormat,
                     GLenum glType,
                     void* data,
                     size_t dataSize) {
        dawn_native::opengl::Device* openglDevice =
            reinterpret_cast<dawn_native::opengl::Device*>(device.Get());
        const dawn_native::opengl::OpenGLFunctions& gl = openglDevice->gl;

        // Get a texture view for the eglImage
        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.dimension = wgpu::TextureDimension::e2D;
        textureDescriptor.format = format;
        textureDescriptor.size = {1, 1, 1};
        textureDescriptor.sampleCount = 1;
        textureDescriptor.mipLevelCount = 1;
        textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
        wgpu::Texture eglImageTexture = WrapEGLImage(&textureDescriptor, eglImage);
        ASSERT_NE(eglImageTexture, nullptr);

        wgpu::TextureView eglImageView = eglImageTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPassDescriptor({eglImageView}, {});
        renderPassDescriptor.cColorAttachments[0].clearColor = {1 / 255.0f, 2 / 255.0f, 3 / 255.0f,
                                                                4 / 255.0f};

        // Execute commands to clear the eglImage
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
        pass.EndPass();

        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        // Check the correct data was written
        std::vector<uint8_t> result(dataSize);
        GLuint fbo;
        gl.GenFramebuffers(1, &fbo);
        gl.BindFramebuffer(GL_FRAMEBUFFER, fbo);
        gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                                0);
        gl.ReadPixels(0, 0, 1, 1, glFormat, glType, result.data());
        gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
        gl.DeleteFramebuffers(1, &fbo);
        ASSERT_EQ(0, memcmp(result.data(), data, dataSize));
    }
};

// Test clearing a R8 EGLImage
TEST_P(EGLImageUsageTests, ClearR8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_R8, GL_RED, GL_UNSIGNED_BYTE, nullptr, 0);

    uint8_t data = 0x01;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::R8Unorm, GL_RED,
                GL_UNSIGNED_BYTE, &data, sizeof(data));
}

// Test clearing a RG8 EGLImage
TEST_P(EGLImageUsageTests, ClearRG8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, nullptr, 0);

    uint16_t data = 0x0201;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::RG8Unorm, GL_RG,
                GL_UNSIGNED_BYTE, &data, sizeof(data));
}

// Test clearing an RGBA8 EGLImage
TEST_P(EGLImageUsageTests, ClearRGBA8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, 0);

    uint32_t data = 0x04030201;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::RGBA8Unorm,
                GL_RGBA, GL_UNSIGNED_BYTE, &data, sizeof(data));
}

DAWN_INSTANTIATE_TEST(EGLImageValidationTests, OpenGLESBackend());
DAWN_INSTANTIATE_TEST(EGLImageUsageTests, OpenGLESBackend());
