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

// EGLSurfacelessContextTest.cpp:
//   Tests for the EGL_KHR_surfaceless_context and GL_OES_surfaceless_context

#include <gtest/gtest.h>

#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_configs.h"
#include "test_utils/gl_raii.h"

using namespace angle;

namespace
{

class EGLSurfacelessContextTest : public ANGLETest
{
  public:
    EGLSurfacelessContextTest() : mDisplay(0) {}

    void testSetUp() override
    {
        EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
        mDisplay           = eglGetPlatformDisplayEXT(
            EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);

        ASSERT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

        int nConfigs = 0;
        ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs));
        ASSERT_TRUE(nConfigs != 0);

        int nReturnedConfigs = 0;
        std::vector<EGLConfig> configs(nConfigs);
        ASSERT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), nConfigs, &nReturnedConfigs));
        ASSERT_TRUE(nConfigs == nReturnedConfigs);

        for (auto config : configs)
        {
            EGLint surfaceType;
            eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
            if (surfaceType & EGL_PBUFFER_BIT)
            {
                mConfig = config;
                break;
            }
        }
        ASSERT_NE(nullptr, mConfig);
    }

    void testTearDown() override
    {
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

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

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

        eglTerminate(mDisplay);
    }

  protected:
    EGLContext createContext()
    {
        const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};

        mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, contextAttribs);
        EXPECT_TRUE(mContext != EGL_NO_CONTEXT);
        return mContext;
    }

    EGLSurface createPbuffer(int width, int height)
    {
        const EGLint pbufferAttribs[] = {
            EGL_WIDTH, 500, EGL_HEIGHT, 500, EGL_NONE,
        };
        mPbuffer = eglCreatePbufferSurface(mDisplay, mConfig, pbufferAttribs);
        EXPECT_TRUE(mPbuffer != EGL_NO_SURFACE);
        return mPbuffer;
    }

    void createFramebuffer(GLFramebuffer *fbo, GLTexture *tex) const
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo->get());

        glBindTexture(GL_TEXTURE_2D, tex->get());
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 500, 500, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->get(), 0);
        EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }

    bool checkExtension(bool verbose = true) const
    {
        if (!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_KHR_surfaceless_context"))
        {
            if (verbose)
            {
                std::cout << "Test skipped because EGL_KHR_surfaceless_context is not available."
                          << std::endl;
            }
            return false;
        }
        return true;
    }

    EGLContext mContext = EGL_NO_CONTEXT;
    EGLSurface mPbuffer = EGL_NO_SURFACE;
    EGLConfig mConfig   = 0;
    EGLDisplay mDisplay = EGL_NO_DISPLAY;
};

// Test surfaceless MakeCurrent returns the correct value.
TEST_P(EGLSurfacelessContextTest, MakeCurrentSurfaceless)
{
    EGLContext context = createContext();

    if (eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context))
    {
        ASSERT_TRUE(checkExtension(false));
    }
    else
    {
        // The extension allows EGL_BAD_MATCH with the extension too, but ANGLE
        // shouldn't do that.
        ASSERT_FALSE(checkExtension(false));
    }
}

// Test that the scissor and viewport are set correctly
TEST_P(EGLSurfacelessContextTest, DefaultScissorAndViewport)
{
    if (!checkExtension())
    {
        return;
    }

    EGLContext context = createContext();
    ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));

    GLint scissor[4] = {1, 2, 3, 4};
    glGetIntegerv(GL_SCISSOR_BOX, scissor);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(0, scissor[0]);
    ASSERT_EQ(0, scissor[1]);
    ASSERT_EQ(0, scissor[2]);
    ASSERT_EQ(0, scissor[3]);

    GLint viewport[4] = {1, 2, 3, 4};
    glGetIntegerv(GL_VIEWPORT, viewport);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(0, viewport[0]);
    ASSERT_EQ(0, viewport[1]);
    ASSERT_EQ(0, viewport[2]);
    ASSERT_EQ(0, viewport[3]);
}

// Test the CheckFramebufferStatus returns the correct value.
TEST_P(EGLSurfacelessContextTest, CheckFramebufferStatus)
{
    if (!checkExtension())
    {
        return;
    }

    EGLContext context = createContext();
    ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));

    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_UNDEFINED_OES, glCheckFramebufferStatus(GL_FRAMEBUFFER));

    GLFramebuffer fbo;
    GLTexture tex;
    createFramebuffer(&fbo, &tex);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
}

// Test that clearing and readpixels work when done in an FBO.
TEST_P(EGLSurfacelessContextTest, ClearReadPixelsInFBO)
{
    if (!checkExtension())
    {
        return;
    }

    EGLContext context = createContext();
    ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));

    GLFramebuffer fbo;
    GLTexture tex;
    createFramebuffer(&fbo, &tex);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());

    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::red);
    ASSERT_GL_NO_ERROR();
}

// Test clear+readpixels in an FBO in surfaceless and in the default FBO in a pbuffer
TEST_P(EGLSurfacelessContextTest, Switcheroo)
{
    if (!checkExtension())
    {
        return;
    }

    EGLContext context = createContext();
    EGLSurface pbuffer = createPbuffer(500, 500);

    // We need to make the context current to do the one time setup of the FBO
    ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
    GLFramebuffer fbo;
    GLTexture tex;
    createFramebuffer(&fbo, &tex);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());

    for (int i = 0; i < 4; ++i)
    {
        // Clear to red in the FBO in surfaceless mode
        ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));

        glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::red);
        ASSERT_GL_NO_ERROR();

        // Clear to green in the pbuffer
        ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, pbuffer, pbuffer, context));

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_EQ(250, 250, GLColor::green);
        ASSERT_GL_NO_ERROR();
    }
}

}  // anonymous namespace

ANGLE_INSTANTIATE_TEST(EGLSurfacelessContextTest,
                       WithNoFixture(ES2_D3D9()),
                       WithNoFixture(ES2_D3D11()),
                       WithNoFixture(ES2_OPENGL()),
                       WithNoFixture(ES2_VULKAN()));
