//
// Copyright 2015 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.
//

#include "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"

#include <d3d11.h>
#include <cstdint>

#include "common/com_utils.h"
#include "util/OSWindow.h"

using namespace angle;

class EGLPresentPathD3D11 : public ANGLETest<>
{
  protected:
    EGLPresentPathD3D11()
        : mDisplay(EGL_NO_DISPLAY),
          mContext(EGL_NO_CONTEXT),
          mSurface(EGL_NO_SURFACE),
          mConfig(0),
          mOSWindow(nullptr),
          mWindowWidth(0)
    {}

    void testSetUp() override
    {
        mOSWindow    = OSWindow::New();
        mWindowWidth = 64;
        mOSWindow->initialize("EGLPresentPathD3D11", mWindowWidth, mWindowWidth);
    }

    void initializeEGL(bool usePresentPathFast)
    {
        int clientVersion = GetParam().majorVersion;

        // Set up EGL Display
        EGLAttrib displayAttribs[] = {
            EGL_PLATFORM_ANGLE_TYPE_ANGLE,
            GetParam().getRenderer(),
            EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
            static_cast<EGLAttrib>(mOSWindow->getNativeDisplayPlatformType()),
            EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
            GetParam().eglParameters.majorVersion,
            EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
            GetParam().eglParameters.majorVersion,
            EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE,
            usePresentPathFast ? EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE
                               : EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE,
            EGL_NONE};
        mDisplay = eglGetPlatformDisplay(GetEglPlatform(), EGL_DEFAULT_DISPLAY, displayAttribs);
        ASSERT_TRUE(EGL_NO_DISPLAY != mDisplay);
        ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

        // Choose the EGL config
        EGLint numConfigs;
        EGLint configAttribs[] = {EGL_RED_SIZE,
                                  8,
                                  EGL_GREEN_SIZE,
                                  8,
                                  EGL_BLUE_SIZE,
                                  8,
                                  EGL_ALPHA_SIZE,
                                  8,
                                  EGL_RENDERABLE_TYPE,
                                  clientVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT,
                                  EGL_SURFACE_TYPE,
                                  EGL_PBUFFER_BIT,
                                  EGL_NONE};
        ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &mConfig, 1, &numConfigs));
        ASSERT_EQ(1, numConfigs);

        // Set up the EGL context
        EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL_NONE};
        mContext                = eglCreateContext(mDisplay, mConfig, nullptr, contextAttribs);
        ASSERT_TRUE(EGL_NO_CONTEXT != mContext);
    }

    void createWindowSurface()
    {
        mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), nullptr);
    }

    void createPbufferFromClientBufferSurface()
    {
        EGLAttrib device      = 0;
        EGLAttrib angleDevice = 0;

        EXPECT_TRUE(IsEGLClientExtensionEnabled("EGL_EXT_device_query"));

        ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &angleDevice));
        ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
                                                EGL_D3D11_DEVICE_ANGLE, &device));
        ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);

        D3D11_TEXTURE2D_DESC textureDesc = {0};
        textureDesc.Width                = mWindowWidth;
        textureDesc.Height               = mWindowWidth;
        textureDesc.Format               = DXGI_FORMAT_B8G8R8A8_UNORM;
        textureDesc.MipLevels            = 1;
        textureDesc.ArraySize            = 1;
        textureDesc.SampleDesc.Count     = 1;
        textureDesc.SampleDesc.Quality   = 0;
        textureDesc.Usage                = D3D11_USAGE_DEFAULT;
        textureDesc.BindFlags            = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
        textureDesc.CPUAccessFlags       = 0;
        textureDesc.MiscFlags            = D3D11_RESOURCE_MISC_SHARED;

        ASSERT_TRUE(SUCCEEDED(
            d3d11Device->CreateTexture2D(&textureDesc, nullptr, &mOffscreenSurfaceD3D11Texture)));

        auto dxgiResource =
            angle::DynamicCastComObject<IDXGIResource>(mOffscreenSurfaceD3D11Texture.Get());
        ASSERT_NE(nullptr, dxgiResource);

        HANDLE sharedHandle = 0;
        ASSERT_TRUE(SUCCEEDED(dxgiResource->GetSharedHandle(&sharedHandle)));
        EGLint pBufferAttributes[] = {EGL_WIDTH,          mWindowWidth,       EGL_HEIGHT,
                                      mWindowWidth,       EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
                                      EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,   EGL_NONE};

        mSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
                                                    sharedHandle, mConfig, pBufferAttributes);
        ASSERT_TRUE(EGL_NO_SURFACE != mSurface);
    }

    void makeCurrent() { ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContext)); }

    void testTearDown() override
    {
        mOffscreenSurfaceD3D11Texture.Reset();

        if (mDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

            if (mSurface != EGL_NO_SURFACE)
            {
                eglDestroySurface(mDisplay, mSurface);
                mSurface = EGL_NO_SURFACE;
            }

            if (mContext != EGL_NO_CONTEXT)
            {
                ASSERT_EGL_TRUE(
                    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
                eglDestroyContext(mDisplay, mContext);
                mContext = EGL_NO_CONTEXT;
            }

            eglTerminate(mDisplay);
            mDisplay = EGL_NO_DISPLAY;
        }

        mOSWindow->destroy();
        OSWindow::Delete(&mOSWindow);
    }

    void drawQuadUsingGL()
    {
        GLuint m2DProgram;
        GLint mTexture2DUniformLocation;

        constexpr char kVS[] =
            R"(precision highp float;
            attribute vec4 position;
            varying vec2 texcoord;

            void main()
            {
                gl_Position = vec4(position.xy, 0.0, 1.0);
                texcoord = (position.xy * 0.5) + 0.5;
            })";

        constexpr char kFS[] =
            R"(precision highp float;
            uniform sampler2D tex;
            varying vec2 texcoord;

            void main()
            {
                gl_FragColor = texture2D(tex, texcoord);
            })";

        m2DProgram                = CompileProgram(kVS, kFS);
        mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex");

        uint8_t textureInitData[16] = {
            255, 0,   0,   255,  // Red
            0,   255, 0,   255,  // Green
            0,   0,   255, 255,  // Blue
            255, 255, 0,   255   // Red + Green
        };

        // Create a simple RGBA texture
        GLuint tex = 0;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureInitData);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        // Draw a quad using the texture
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(m2DProgram);
        glUniform1i(mTexture2DUniformLocation, 0);

        GLint positionLocation = glGetAttribLocation(m2DProgram, "position");
        glUseProgram(m2DProgram);
        const GLfloat vertices[] = {
            -1.0f, 1.0f, 0.5f, -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
            -1.0f, 1.0f, 0.5f, 1.0f,  -1.0f, 0.5f, 1.0f, 1.0f,  0.5f,
        };

        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(positionLocation);

        glDrawArrays(GL_TRIANGLES, 0, 6);
        ASSERT_GL_NO_ERROR();

        glDeleteProgram(m2DProgram);
    }

    void checkPixelsUsingGL()
    {
        // Note that the texture is in BGRA format
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);                                  // Red
        EXPECT_PIXEL_EQ(mWindowWidth - 1, 0, 0, 255, 0, 255);                   // Green
        EXPECT_PIXEL_EQ(0, mWindowWidth - 1, 0, 0, 255, 255);                   // Blue
        EXPECT_PIXEL_EQ(mWindowWidth - 1, mWindowWidth - 1, 255, 255, 0, 255);  // Red + green
    }

    void checkPixelsUsingD3D(bool usingPresentPathFast)
    {
        ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture);

        D3D11_TEXTURE2D_DESC textureDesc = {0};
        angle::ComPtr<ID3D11Device> device;
        angle::ComPtr<ID3D11DeviceContext> context;
        mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc);
        mOffscreenSurfaceD3D11Texture->GetDevice(&device);
        device->GetImmediateContext(&context);
        ASSERT_NE(nullptr, device);
        ASSERT_NE(nullptr, context);

        textureDesc.CPUAccessFlags  = D3D11_CPU_ACCESS_READ;
        textureDesc.Usage           = D3D11_USAGE_STAGING;
        textureDesc.BindFlags       = 0;
        textureDesc.MiscFlags       = 0;
        angle::ComPtr<ID3D11Texture2D> cpuTexture;
        ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture)));

        context->CopyResource(cpuTexture.Get(), mOffscreenSurfaceD3D11Texture.Get());

        D3D11_MAPPED_SUBRESOURCE mappedSubresource;
        context->Map(cpuTexture.Get(), 0, D3D11_MAP_READ, 0, &mappedSubresource);
        ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch);
        ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch);

        angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData);

        // Note that the texture is in BGRA format, although the GLColor struct is RGBA
        GLColor expectedTopLeftPixel     = GLColor(0, 0, 255, 255);    // Red
        GLColor expectedTopRightPixel    = GLColor(0, 255, 0, 255);    // Green
        GLColor expectedBottomLeftPixel  = GLColor(255, 0, 0, 255);    // Blue
        GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255);  // Red + Green

        if (usingPresentPathFast)
        {
            // Invert the expected values
            GLColor tempTopLeft      = expectedTopLeftPixel;
            GLColor tempTopRight     = expectedTopRightPixel;
            expectedTopLeftPixel     = expectedBottomLeftPixel;
            expectedTopRightPixel    = expectedBottomRightPixel;
            expectedBottomLeftPixel  = tempTopLeft;
            expectedBottomRightPixel = tempTopRight;
        }

        EXPECT_EQ(expectedTopLeftPixel, byteData[0]);
        EXPECT_EQ(expectedTopRightPixel, ANGLE_UNSAFE_TODO(byteData[(mWindowWidth - 1)]));
        EXPECT_EQ(expectedBottomLeftPixel,
                  ANGLE_UNSAFE_TODO(byteData[(mWindowWidth - 1) * mWindowWidth]));
        EXPECT_EQ(
            expectedBottomRightPixel,
            ANGLE_UNSAFE_TODO(byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]));

        context->Unmap(cpuTexture.Get(), 0);
    }

    EGLDisplay mDisplay;
    EGLContext mContext;
    EGLSurface mSurface;
    angle::ComPtr<ID3D11Texture2D> mOffscreenSurfaceD3D11Texture;
    EGLConfig mConfig;
    OSWindow *mOSWindow;
    GLint mWindowWidth;
};

// Test that rendering basic content onto a window surface when present path fast
// is enabled works as expected
TEST_P(EGLPresentPathD3D11, WindowPresentPathFast)
{
    initializeEGL(true);
    createWindowSurface();
    makeCurrent();

    drawQuadUsingGL();

    checkPixelsUsingGL();
}

// Test that rendering basic content onto a client buffer surface when present path fast
// works as expected, and is also oriented the correct way around
TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathFast)
{
    initializeEGL(true);
    createPbufferFromClientBufferSurface();
    makeCurrent();

    drawQuadUsingGL();

    checkPixelsUsingGL();
    checkPixelsUsingD3D(true);
}

// Test that rendering basic content onto a window surface when present path fast
// is disabled works as expected
TEST_P(EGLPresentPathD3D11, WindowPresentPathCopy)
{
    initializeEGL(false);
    createWindowSurface();
    makeCurrent();

    drawQuadUsingGL();

    checkPixelsUsingGL();
}

// Test that rendering basic content onto a client buffer surface when present path
// fast is disabled works as expected, and is also oriented the correct way around
TEST_P(EGLPresentPathD3D11, ClientBufferPresentPathCopy)
{
    initializeEGL(false);
    createPbufferFromClientBufferSurface();
    makeCurrent();

    drawQuadUsingGL();

    checkPixelsUsingGL();
    checkPixelsUsingD3D(false);
}

ANGLE_INSTANTIATE_TEST(EGLPresentPathD3D11, WithNoFixture(ES2_D3D11()));
