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

// WebGLFramebufferTest.cpp : Framebuffer tests for GL_ANGLE_webgl_compatibility.
// Based on WebGL 1 test renderbuffers/framebuffer-object-attachment.

#include "test_utils/ANGLETest.h"

#include "test_utils/gl_raii.h"

namespace angle
{

class WebGLFramebufferTest : public ANGLETest
{
  protected:
    WebGLFramebufferTest()
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setWebGLCompatibilityEnabled(true);
    }

    void drawUByteColorQuad(GLuint program, GLint uniformLoc, const GLColor &color);
    void testDepthStencilDepthStencil(GLint width, GLint height);
    void testDepthStencilRenderbuffer(GLint width,
                                      GLint height,
                                      GLRenderbuffer *colorBuffer,
                                      GLbitfield allowedStatuses);
    void testRenderingAndReading(GLuint program);
    void testUsingIncompleteFramebuffer(GLenum depthFormat, GLenum depthAttachment);
    void testDrawingMissingAttachment();
};

constexpr GLint ALLOW_COMPLETE              = 0x1;
constexpr GLint ALLOW_UNSUPPORTED           = 0x2;
constexpr GLint ALLOW_INCOMPLETE_ATTACHMENT = 0x4;

void checkFramebufferForAllowedStatuses(GLbitfield allowedStatuses)
{
    // If the framebuffer is in an error state for multiple reasons,
    // we can't guarantee which one will be reported.
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    bool statusAllowed =
        ((allowedStatuses & ALLOW_COMPLETE) && (status == GL_FRAMEBUFFER_COMPLETE)) ||
        ((allowedStatuses & ALLOW_UNSUPPORTED) && (status == GL_FRAMEBUFFER_UNSUPPORTED)) ||
        ((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) &&
         (status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
    EXPECT_TRUE(statusAllowed);
}

void checkBufferBits(GLenum attachment0, GLenum attachment1)
{
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        return;

    bool haveDepthBuffer =
        attachment0 == GL_DEPTH_ATTACHMENT || attachment0 == GL_DEPTH_STENCIL_ATTACHMENT ||
        attachment1 == GL_DEPTH_ATTACHMENT || attachment1 == GL_DEPTH_STENCIL_ATTACHMENT;
    bool haveStencilBuffer =
        attachment0 == GL_STENCIL_ATTACHMENT || attachment0 == GL_DEPTH_STENCIL_ATTACHMENT ||
        attachment1 == GL_STENCIL_ATTACHMENT || attachment1 == GL_DEPTH_STENCIL_ATTACHMENT;

    GLint redBits     = 0;
    GLint greenBits   = 0;
    GLint blueBits    = 0;
    GLint alphaBits   = 0;
    GLint depthBits   = 0;
    GLint stencilBits = 0;
    glGetIntegerv(GL_RED_BITS, &redBits);
    glGetIntegerv(GL_GREEN_BITS, &greenBits);
    glGetIntegerv(GL_BLUE_BITS, &blueBits);
    glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
    glGetIntegerv(GL_DEPTH_BITS, &depthBits);
    glGetIntegerv(GL_STENCIL_BITS, &stencilBits);

    EXPECT_GE(redBits + greenBits + blueBits + alphaBits, 16);

    if (haveDepthBuffer)
        EXPECT_GE(depthBits, 16);
    else
        EXPECT_EQ(0, depthBits);

    if (haveStencilBuffer)
        EXPECT_GE(stencilBits, 8);
    else
        EXPECT_EQ(0, stencilBits);
}

// Tests that certain required combinations work in WebGL compatiblity.
TEST_P(WebGLFramebufferTest, TestFramebufferRequiredCombinations)
{
    // Per discussion with the OpenGL ES working group, the following framebuffer attachment
    // combinations are required to work in all WebGL implementations:
    // 1. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
    // 2. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16
    // renderbuffer
    // 3. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL
    // renderbuffer

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    constexpr int width  = 64;
    constexpr int height = 64;

    // 1. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_NO_ERROR();
    checkFramebufferForAllowedStatuses(ALLOW_COMPLETE);
    checkBufferBits(GL_NONE, GL_NONE);

    // 2. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16
    // renderbuffer
    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
    EXPECT_GL_NO_ERROR();
    checkFramebufferForAllowedStatuses(ALLOW_COMPLETE);
    checkBufferBits(GL_DEPTH_ATTACHMENT, GL_NONE);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);

    if (getClientMajorVersion() == 2)
    {
        // 3. COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT =
        // DEPTH_STENCIL renderbuffer
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                  renderbuffer);
        EXPECT_GL_NO_ERROR();
        checkFramebufferForAllowedStatuses(ALLOW_COMPLETE);
        checkBufferBits(GL_DEPTH_STENCIL_ATTACHMENT, GL_NONE);
    }
}

void testAttachment(GLint width,
                    GLint height,
                    GLRenderbuffer *colorBuffer,
                    GLenum attachment,
                    GLRenderbuffer *buffer,
                    GLbitfield allowedStatuses)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, *buffer);
    EXPECT_GL_NO_ERROR();
    checkFramebufferForAllowedStatuses(allowedStatuses);
    if ((allowedStatuses & ALLOW_COMPLETE) == 0)
    {
        std::vector<uint8_t> tempBuffer(width * height * 4);

        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
        glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tempBuffer.data());
        EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
    }
    checkBufferBits(attachment, GL_NONE);
}

void testAttachments(GLRenderbuffer &colorBuffer,
                     GLenum attachment0,
                     GLRenderbuffer &buffer0,
                     GLenum attachment1,
                     GLRenderbuffer &buffer1,
                     GLbitfield allowedStatuses)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment0, GL_RENDERBUFFER, buffer0);
    EXPECT_GL_NO_ERROR();
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment1, GL_RENDERBUFFER, buffer1);
    EXPECT_GL_NO_ERROR();
    checkFramebufferForAllowedStatuses(allowedStatuses);
    checkBufferBits(attachment0, attachment1);
}

void testColorRenderbuffer(GLint width,
                           GLint height,
                           GLenum internalformat,
                           GLbitfield allowedStatuses)
{
    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, internalformat, width, height);
    EXPECT_GL_NO_ERROR();
    testAttachment(width, height, &colorBuffer, GL_COLOR_ATTACHMENT0, &colorBuffer,
                   allowedStatuses);
}

GLint getRenderbufferParameter(GLenum paramName)
{
    GLint paramValue = 0;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, paramName, &paramValue);
    return paramValue;
}

void WebGLFramebufferTest::drawUByteColorQuad(GLuint program,
                                              GLint uniformLoc,
                                              const GLColor &color)
{
    Vector4 vecColor = color.toNormalizedVector();
    glUseProgram(program);
    glUniform4fv(uniformLoc, 1, vecColor.data());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
}

void WebGLFramebufferTest::testDepthStencilDepthStencil(GLint width, GLint height)
{
    if (width == 0 || height == 0)
    {
        return;
    }

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    GLint uniformLoc = glGetUniformLocation(program.get(), essl1_shaders::ColorUniform());
    ASSERT_NE(-1, uniformLoc);

    struct TestInfo
    {
        GLenum firstFormat;
        GLenum firstAttach;
        GLenum secondFormat;
        GLenum secondAttach;
    };

    TestInfo tests[2] = {
        {GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT},
        {GL_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT}};

    for (const TestInfo &test : tests)
    {
        for (GLint opIndex = 0; opIndex < 2; ++opIndex)
        {
            GLFramebuffer fbo;
            GLTexture tex;
            GLRenderbuffer firstRb;

            // test: firstFormat vs secondFormat with unbind or delete.

            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            // attach texture as color
            glBindTexture(GL_TEXTURE_2D, tex);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                         nullptr);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

            // attach first
            glBindRenderbuffer(GL_RENDERBUFFER, firstRb);
            glRenderbufferStorage(GL_RENDERBUFFER, test.firstFormat, width, height);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, test.firstAttach, GL_RENDERBUFFER, firstRb);

            EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));

            // TODO(jmadill): Remove clear - this should be implicit in WebGL_
            glClear(GL_DEPTH_BUFFER_BIT);

            glEnable(GL_DEPTH_TEST);
            // Test it works
            drawUByteColorQuad(program.get(), uniformLoc, GLColor::green);
            // should not draw since DEPTH_FUNC == LESS
            drawUByteColorQuad(program.get(), uniformLoc, GLColor::red);
            // should be green
            EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

            GLuint secondRb = 0;
            glGenRenderbuffers(1, &secondRb);

            // attach second
            glBindRenderbuffer(GL_RENDERBUFFER, secondRb);
            glRenderbufferStorage(GL_RENDERBUFFER, test.secondFormat, width, height);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, test.secondAttach, GL_RENDERBUFFER, secondRb);

            if (opIndex == 0)
            {
                // now delete it
                glDeleteRenderbuffers(1, &secondRb);
                secondRb = 0;
            }
            else
            {
                // unbind it
                glFramebufferRenderbuffer(GL_FRAMEBUFFER, test.secondAttach, GL_RENDERBUFFER, 0);
            }

            // If the first attachment is not restored this may fail
            EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
            EXPECT_GL_NO_ERROR();

            // If the first attachment is not restored this may fail.
            glClear(GL_DEPTH_BUFFER_BIT);
            drawUByteColorQuad(program.get(), uniformLoc, GLColor::green);
            // should not draw since DEPTH_FUNC == LESS
            drawUByteColorQuad(program.get(), uniformLoc, GLColor::red);
            // should be green
            EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
            glDisable(GL_DEPTH_TEST);

            if (opIndex == 1)
            {
                glDeleteRenderbuffers(1, &secondRb);
                secondRb = 0;
            }
        }
    }
    EXPECT_GL_NO_ERROR();
}

void WebGLFramebufferTest::testDepthStencilRenderbuffer(GLint width,
                                                        GLint height,
                                                        GLRenderbuffer *colorBuffer,
                                                        GLbitfield allowedStatuses)
{
    GLRenderbuffer depthStencilBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
    EXPECT_GL_NO_ERROR();

    // OpenGL itself doesn't seem to guarantee that e.g. a 2 x 0
    // renderbuffer will report 2 for its width when queried.
    if (!(height == 0 && width > 0))
    {
        EXPECT_EQ(width, getRenderbufferParameter(GL_RENDERBUFFER_WIDTH));
    }
    if (!(width == 0 && height > 0))
    {
        EXPECT_EQ(height, getRenderbufferParameter(GL_RENDERBUFFER_HEIGHT));
    }
    EXPECT_EQ(GL_DEPTH_STENCIL, getRenderbufferParameter(GL_RENDERBUFFER_INTERNAL_FORMAT));
    EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_RED_SIZE));
    EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_GREEN_SIZE));
    EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_BLUE_SIZE));
    EXPECT_EQ(0, getRenderbufferParameter(GL_RENDERBUFFER_ALPHA_SIZE));

    // Avoid verifying these for zero-sized renderbuffers for the time
    // being since it appears that even OpenGL doesn't guarantee them.
    if (width > 0 && height > 0)
    {
        EXPECT_GT(getRenderbufferParameter(GL_RENDERBUFFER_DEPTH_SIZE), 0);
        EXPECT_GT(getRenderbufferParameter(GL_RENDERBUFFER_STENCIL_SIZE), 0);
    }
    EXPECT_GL_NO_ERROR();
    testAttachment(width, height, colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT, &depthStencilBuffer,
                   allowedStatuses);
    testDepthStencilDepthStencil(width, height);
}

// Test various attachment combinations with WebGL framebuffers.
TEST_P(WebGLFramebufferTest, TestAttachments)
{
    // GL_DEPTH_STENCIL renderbuffer format is only valid for WebGL1
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() != 2);

    for (GLint width = 2; width <= 2; width += 2)
    {
        for (GLint height = 2; height <= 2; height += 2)
        {
            // Dimensions width x height.
            GLRenderbuffer colorBuffer;
            glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, width, height);
            EXPECT_GL_NO_ERROR();

            GLRenderbuffer depthBuffer;
            glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
            EXPECT_GL_NO_ERROR();

            GLRenderbuffer stencilBuffer;
            glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height);
            EXPECT_GL_NO_ERROR();

            GLRenderbuffer depthStencilBuffer;
            glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
            EXPECT_GL_NO_ERROR();

            GLbitfield allowedStatusForGoodCase =
                (width == 0 || height == 0) ? ALLOW_INCOMPLETE_ATTACHMENT : ALLOW_COMPLETE;

            // some cases involving stencil seem to be implementation-dependent
            GLbitfield allowedStatusForImplDependentCase =
                allowedStatusForGoodCase | ALLOW_UNSUPPORTED;

            // Attach depth using DEPTH_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_ATTACHMENT, &depthBuffer,
                           allowedStatusForGoodCase);

            // Attach depth using STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_STENCIL_ATTACHMENT, &depthBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            // Attach depth using DEPTH_STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT, &depthBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            // Attach stencil using STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_STENCIL_ATTACHMENT, &stencilBuffer,
                           allowedStatusForImplDependentCase);

            // Attach stencil using DEPTH_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_ATTACHMENT, &stencilBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            // Attach stencil using DEPTH_STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT, &stencilBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            // Attach depthStencil using DEPTH_STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT,
                           &depthStencilBuffer, allowedStatusForGoodCase);

            // Attach depthStencil using DEPTH_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_DEPTH_ATTACHMENT, &depthStencilBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            // Attach depthStencil using STENCIL_ATTACHMENT.
            testAttachment(width, height, &colorBuffer, GL_STENCIL_ATTACHMENT, &depthStencilBuffer,
                           ALLOW_INCOMPLETE_ATTACHMENT);

            GLbitfield allowedStatusForConflictedAttachment =
                (width == 0 || height == 0) ? ALLOW_UNSUPPORTED | ALLOW_INCOMPLETE_ATTACHMENT
                                            : ALLOW_UNSUPPORTED;

            // Attach depth, then stencil, causing conflict.
            testAttachments(colorBuffer, GL_DEPTH_ATTACHMENT, depthBuffer, GL_STENCIL_ATTACHMENT,
                            stencilBuffer, allowedStatusForConflictedAttachment);

            // Attach stencil, then depth, causing conflict.
            testAttachments(colorBuffer, GL_STENCIL_ATTACHMENT, stencilBuffer, GL_DEPTH_ATTACHMENT,
                            depthBuffer, allowedStatusForConflictedAttachment);

            // Attach depth, then depthStencil, causing conflict.
            testAttachments(colorBuffer, GL_DEPTH_ATTACHMENT, depthBuffer,
                            GL_DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer,
                            allowedStatusForConflictedAttachment);

            // Attach depthStencil, then depth, causing conflict.
            testAttachments(colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer,
                            GL_DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment);

            // Attach stencil, then depthStencil, causing conflict.
            testAttachments(colorBuffer, GL_DEPTH_ATTACHMENT, depthBuffer,
                            GL_DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer,
                            allowedStatusForConflictedAttachment);

            // Attach depthStencil, then stencil, causing conflict.
            testAttachments(colorBuffer, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer,
                            GL_STENCIL_ATTACHMENT, stencilBuffer,
                            allowedStatusForConflictedAttachment);

            // Attach color renderbuffer with internalformat == RGBA4.
            testColorRenderbuffer(width, height, GL_RGBA4, allowedStatusForGoodCase);

            // Attach color renderbuffer with internalformat == RGB5_A1.
            // This particular format seems to be bugged on NVIDIA Retina. http://crbug.com/635081
            // TODO(jmadill): Figure out if we can add a format workaround.
            if (!(IsNVIDIA() && IsOSX() && IsOpenGL()))
            {
                testColorRenderbuffer(width, height, GL_RGB5_A1, allowedStatusForGoodCase);
            }

            // Attach color renderbuffer with internalformat == RGB565.
            testColorRenderbuffer(width, height, GL_RGB565, allowedStatusForGoodCase);

            // Create and attach depthStencil renderbuffer.
            testDepthStencilRenderbuffer(width, height, &colorBuffer, allowedStatusForGoodCase);
        }
    }
}

bool tryDepth(GLRenderbuffer *depthBuffer,
              GLenum *depthFormat,
              GLenum *depthAttachment,
              GLenum try_format,
              GLenum try_attachment)
{
    if (*depthAttachment != GL_NONE)
    {
        // If we've tried once unattach the old one.
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, *depthAttachment, GL_RENDERBUFFER, 0);
    }
    *depthFormat     = try_format;
    *depthAttachment = try_attachment;
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, *depthAttachment, GL_RENDERBUFFER, *depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, *depthFormat, 16, 16);
    EXPECT_GL_NO_ERROR();
    return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
}

bool checkValidColorDepthCombination(GLenum *depthFormat, GLenum *depthAttachment)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);

    GLRenderbuffer depthBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);

    return tryDepth(&depthBuffer, depthFormat, depthAttachment, GL_DEPTH_COMPONENT16,
                    GL_DEPTH_ATTACHMENT) ||
           tryDepth(&depthBuffer, depthFormat, depthAttachment, GL_DEPTH_STENCIL,
                    GL_DEPTH_STENCIL_ATTACHMENT);
}

// glCheckFramebufferStatus(GL_FRAMEBUFFER) should be either complete or (unsupported/expected).
void checkFramebuffer(GLenum expected)
{
    GLenum actual = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    EXPECT_TRUE(actual == expected ||
                (expected != GL_FRAMEBUFFER_COMPLETE && actual == GL_FRAMEBUFFER_UNSUPPORTED));
}

void WebGLFramebufferTest::testRenderingAndReading(GLuint program)
{
    EXPECT_GL_NO_ERROR();

    // drawArrays with incomplete framebuffer
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
    EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);

    // readPixels from incomplete framebuffer
    std::vector<uint8_t> dummyBuffer(4);
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dummyBuffer.data());
    EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);

    // copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because
    // the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments
    // the framebuffer is not of a compatible type.

    // copyTexSubImage2D from incomplete framebuffer
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
    GLenum error = glGetError();
    EXPECT_TRUE(error == GL_INVALID_FRAMEBUFFER_OPERATION || error == GL_INVALID_OPERATION);

    // copyTexImage2D from incomplete framebuffer
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
    error = glGetError();
    EXPECT_TRUE(error == GL_INVALID_FRAMEBUFFER_OPERATION || error == GL_INVALID_OPERATION);

    // clear with incomplete framebuffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
}

// Test drawing or reading from an incomplete framebuffer
void WebGLFramebufferTest::testUsingIncompleteFramebuffer(GLenum depthFormat,
                                                          GLenum depthAttachment)
{
    // Simple draw program.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);

    GLRenderbuffer depthBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, depthAttachment, GL_RENDERBUFFER, depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 16, 16);
    EXPECT_GL_NO_ERROR();
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    // We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES
    // 2.0
    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 32, 16);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);

    // Drawing or reading from an incomplete framebuffer should generate
    // INVALID_FRAMEBUFFER_OPERATION.
    testRenderingAndReading(program.get());

    GLFramebuffer fbo2;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);

    // Drawing or reading from an incomplete framebuffer should generate
    // INVALID_FRAMEBUFFER_OPERATION.
    testRenderingAndReading(program.get());

    GLRenderbuffer colorBuffer2;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer2);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer2);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 0, 0);

    // Drawing or reading from an incomplete framebuffer should generate
    // INVALID_FRAMEBUFFER_OPERATION.
    testRenderingAndReading(program.get());
}

void testFramebufferIncompleteAttachment(GLenum depthFormat)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    // Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0
    // 4.4.5).
    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);

    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    // 0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5).
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 0, 0);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);

    EXPECT_GL_NO_ERROR();
}

// No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5).
void testFramebufferIncompleteMissingAttachment()
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);

    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);

    EXPECT_GL_NO_ERROR();
}

// Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5).
void testFramebufferIncompleteDimensions(GLenum depthFormat, GLenum depthAttachment)
{
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLRenderbuffer colorBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);

    GLRenderbuffer depthBuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, depthAttachment, GL_RENDERBUFFER, depthBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 16, 16);
    EXPECT_GL_NO_ERROR();
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 32, 16);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
    glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 32);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 16, 16);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);
    EXPECT_GL_NO_ERROR();

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    EXPECT_GL_NO_ERROR();
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        return;
    }

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    checkFramebuffer(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    checkFramebuffer(GL_FRAMEBUFFER_COMPLETE);

    EXPECT_GL_NO_ERROR();
}

class NoColorFB final : angle::NonCopyable
{
  public:
    NoColorFB(int size)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, mFBO);

        // The only scenario we can verify is an attempt to read or copy
        // from a missing color attachment while the framebuffer is still
        // complete.
        glBindRenderbuffer(GL_RENDERBUFFER, mDepthBuffer);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                  mDepthBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);

        // After depth renderbuffer setup
        EXPECT_GL_NO_ERROR();

        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        {
            // Unable to allocate a framebuffer with just a depth attachment; this is legal.
            // Try just a depth/stencil renderbuffer.
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);

            glBindRenderbuffer(GL_RENDERBUFFER, mDepthStencilBuffer);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                      mDepthStencilBuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, size, size);

            // After depth+stencil renderbuffer setup
            EXPECT_GL_NO_ERROR();
        }
    }

  private:
    GLRenderbuffer mDepthBuffer;
    GLRenderbuffer mDepthStencilBuffer;
    GLFramebuffer mFBO;
};

// Test reading from a missing framebuffer attachment.
void TestReadingMissingAttachment(int size)
{
    // The FBO has no color attachment. ReadPixels, CopyTexImage2D,
    // and CopyTexSubImage2D should all generate INVALID_OPERATION.

    // Before ReadPixels from missing attachment
    std::vector<uint8_t> dummyBuffer(4);
    EXPECT_GL_NO_ERROR();
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dummyBuffer.data());
    // After ReadPixels from missing attachment
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    // Before CopyTexImage2D from missing attachment
    EXPECT_GL_NO_ERROR();
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, size, size, 0);
    // After CopyTexImage2D from missing attachment
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    // Before CopyTexSubImage2D from missing attachment
    EXPECT_GL_NO_ERROR();
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size, size);
    // After CopyTexSubImage2D from missing attachment
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Test drawing to a missing framebuffer attachment.
void WebGLFramebufferTest::testDrawingMissingAttachment()
{
    // Simple draw program.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    // try glDrawArrays
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
    EXPECT_GL_NO_ERROR();

    // try glDrawElements
    drawIndexedQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
    EXPECT_GL_NO_ERROR();
}

// Determine if we can attach both color and depth or color and depth_stencil
TEST_P(WebGLFramebufferTest, CheckValidColorDepthCombination)
{
    // In FL9_3, we don't have a good way to handle non-color framebuffer rendering.
    if (IsD3D11_FL93())
    {
        ignoreD3D11SDKLayersWarnings();
    }

    GLenum depthFormat     = GL_NONE;
    GLenum depthAttachment = GL_NONE;

    if (checkValidColorDepthCombination(&depthFormat, &depthAttachment))
    {
        testFramebufferIncompleteDimensions(depthFormat, depthAttachment);
        testFramebufferIncompleteAttachment(depthFormat);
        testFramebufferIncompleteMissingAttachment();
        testUsingIncompleteFramebuffer(depthFormat, depthAttachment);

        constexpr int size = 16;
        NoColorFB fb(size);
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
        {
            // The FBO has no color attachment. ReadPixels, CopyTexImage2D,
            // and CopyTexSubImage2D should all generate INVALID_OPERATION.
            TestReadingMissingAttachment(size);

            // The FBO has no color attachment. Clear, DrawArrays,
            // and DrawElements should not generate an error.
            testDrawingMissingAttachment();
        }
    }
}

// Test to cover a bug in preserving the texture image index for WebGL framebuffer attachments
TEST_P(WebGLFramebufferTest, TextureAttachmentCommitBug)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_depth_texture"));

    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture.get());
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
                 nullptr);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture.get(),
                           0);

    glCheckFramebufferStatus(GL_FRAMEBUFFER);

    EXPECT_GL_NO_ERROR();
}

// Test combinations of ordering in setting the resource format and attaching it to the depth
// stencil attacchment.  Covers http://crbug.com/997702
TEST_P(WebGLFramebufferTest, DepthStencilAttachmentOrdering)
{
    constexpr GLsizei kFramebufferSize = 16;

    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kFramebufferSize, kFramebufferSize, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer depthStencil;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);

    // Attach the renderbuffer to the framebuffer when it has no format
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencil);

    // Framebuffer is incomplete because the depth stencil attachment doesn't a format/size
    EXPECT_GL_NO_ERROR();
    EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
                     GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);

    // Set depth stencil attachment to a color format
    if (EnsureGLExtensionEnabled("GL_OES_rgb8_rgba8"))
    {
        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kFramebufferSize, kFramebufferSize);

        // Non-depth stencil format on the depth stencil attachment
        EXPECT_GL_NO_ERROR();
        EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
                         GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
    }

    {
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kFramebufferSize,
                              kFramebufferSize);

        // Depth-stencil attachment only has a depth format, not complete
        EXPECT_GL_NO_ERROR();
        EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
                         GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
    }

    if (EnsureGLExtensionEnabled("GL_OES_packed_depth_stencil"))
    {
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kFramebufferSize,
                              kFramebufferSize);

        // Framebuffer should be complete now with a depth-stencil format
        EXPECT_GL_NO_ERROR();
        EXPECT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
    }
}

// Only run against WebGL 1 validation, since much was changed in 2.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLFramebufferTest);

}  // namespace angle
