//
// 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 SetUp() override
    {
        ANGLETest::SetUp();
        glRequestExtensionANGLE = reinterpret_cast<PFNGLREQUESTEXTENSIONANGLEPROC>(
            eglGetProcAddress("glRequestExtensionANGLE"));
    }

    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();

    PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE = nullptr;
};

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);

    // 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, "position", 0.5f, 1.0f, true);
}

void WebGLFramebufferTest::testDepthStencilDepthStencil(GLint width, GLint height)
{
    const std::string &vertexShader =
        "attribute vec4 position;\n"
        "void main() {\n"
        "    gl_Position = position;\n"
        "}";
    const std::string &fragmentShader =
        "precision mediump float;\n"
        "uniform vec4 color;\n"
        "void main() {\n"
        "    gl_FragColor = color;\n"
        "}";

    if (width == 0 || height == 0)
    {
        return;
    }

    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
    GLint uniformLoc = glGetUniformLocation(program.get(), "color");
    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)
{
    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, "position", 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.
    const std::string &vertexShader =
        "attribute vec4 position; void main() { gl_Position = position; }";
    const std::string &fragmentShader = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";

    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);

    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.
    const std::string &vertexShader   = "attribute vec4 pos; void main() { gl_Position = pos; }";
    const std::string &fragmentShader = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
    ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    // try glDrawArrays
    drawQuad(program, "pos", 0.5f, 1.0f, true);
    EXPECT_GL_NO_ERROR();

    // try glDrawElements
    drawIndexedQuad(program, "pos", 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)
{
    if (extensionRequestable("GL_ANGLE_depth_texture"))
    {
        glRequestExtensionANGLE("GL_ANGLE_depth_texture");
    }

    ANGLE_SKIP_TEST_IF(!extensionEnabled("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();
}

// Only run against WebGL 1 validation, since much was changed in 2.
ANGLE_INSTANTIATE_TEST(WebGLFramebufferTest,
                       ES2_D3D9(),
                       ES2_D3D11(),
                       ES2_D3D11_FL9_3(),
                       ES2_OPENGL(),
                       ES2_OPENGLES());

}  // namespace
