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

#include "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"
#include "util/random_utils.h"
#include "util/test_utils.h"

using namespace angle;

class OcclusionQueriesTest : public ANGLETest<>
{
  protected:
    OcclusionQueriesTest() : mProgram(0), mRNG(1)
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
    }

    void testSetUp() override
    {
        mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        ASSERT_NE(0u, mProgram);
    }

    void testTearDown() override { glDeleteProgram(mProgram); }

    GLuint mProgram;
    RNG mRNG;
};

class OcclusionQueriesTestES3 : public OcclusionQueriesTest
{};

TEST_P(OcclusionQueriesTest, IsOccluded)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // draw a quad at depth 0.3
    glEnable(GL_DEPTH_TEST);
    glUseProgram(mProgram);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.3f);
    glUseProgram(0);

    EXPECT_GL_NO_ERROR();

    GLQueryEXT query;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(),
             0.8f);  // this quad should be occluded by first quad
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint ready = GL_FALSE;
    while (ready == GL_FALSE)
    {
        angle::Sleep(0);
        glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
    }

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);

    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

TEST_P(OcclusionQueriesTest, IsNotOccluded)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    EXPECT_GL_NO_ERROR();

    GLQueryEXT query;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);  // will block waiting for result

    EXPECT_GL_NO_ERROR();

    EXPECT_GL_TRUE(result);
}

// Test that glClear should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest, ClearNotCounted)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsD3D11());

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    EXPECT_GL_NO_ERROR();

    GLQueryEXT query[2];

    // First query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[0]);
    // Full screen clear
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // View port clear
    glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
    glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
    glEnable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    EXPECT_GL_NO_ERROR();

    // Second query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[1]);

    // View port clear
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // View port clear
    glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
    glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
    glEnable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // this quad should not be occluded
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);

    // Clear again
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // this quad should not be occluded
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 1.0);

    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result[2] = {GL_TRUE, GL_TRUE};
    glGetQueryObjectuivEXT(query[0], GL_QUERY_RESULT_EXT,
                           &result[0]);  // will block waiting for result
    glGetQueryObjectuivEXT(query[1], GL_QUERY_RESULT_EXT,
                           &result[1]);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result[0]);
    EXPECT_GL_TRUE(result[1]);
}

// Test that masked glClear should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest, MaskedClearNotCounted)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsD3D());

    GLQueryEXT query;

    // Masked clear
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

// Test that copies should not be counted by occlusion query.
TEST_P(OcclusionQueriesTest, CopyNotCounted)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsD3D());

    GLQueryEXT query;

    // Unrelated draw before the query starts.
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);

    // Copy to a texture with a different format from backbuffer
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, getWindowWidth(), getWindowHeight(), 0);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

// Test that blit should not be counted by occlusion query.
TEST_P(OcclusionQueriesTestES3, BlitNotCounted)
{
    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsD3D11());

    // http://anglebug.com/42263669
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());

    constexpr GLuint kSize = 64;

    GLFramebuffer srcFbo;
    glBindFramebuffer(GL_FRAMEBUFFER, srcFbo);

    GLTexture srcTex;
    glBindTexture(GL_TEXTURE_2D, srcTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcTex, 0);

    GLFramebuffer dstFbo;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);

    GLTexture dstTex;
    glBindTexture(GL_TEXTURE_2D, dstTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSize, kSize, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTex, 0);

    GLQueryEXT query;

    // Unrelated draw before the query starts.
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);

    // Blit flipped and with different formats.
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glBlitFramebuffer(0, 0, 64, 64, 64, 64, 0, 0, GL_COLOR_BUFFER_BIT, GL_LINEAR);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

// Test that multisampled-render-to-texture unresolve should not be counted by occlusion query.
TEST_P(OcclusionQueriesTestES3, UnresolveNotCounted)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    constexpr GLuint kSize = 64;

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);

    // Create multisampled framebuffer to draw into
    GLTexture textureMS;
    glBindTexture(GL_TEXTURE_2D, textureMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         textureMS, 0, 4);

    GLRenderbuffer depthMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, kSize, kSize);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);

    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw red into the multisampled color buffer.
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Create a texture and copy into it, forcing a resolve of the color buffer.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);

    GLQueryEXT query;

    // Make a draw call that will fail the depth test, and therefore shouldn't contribute to
    // occlusion query.
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_NEVER);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

// Test that reusing a query should reset its value to zero if no draw calls are emitted in the
// second pass.
TEST_P(OcclusionQueriesTest, RewriteDrawNoDrawToZero)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    GLQueryEXT query;
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // draw a quad at depth 0.3
    glEnable(GL_DEPTH_TEST);
    glUseProgram(mProgram);
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.3f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    glUseProgram(0);

    EXPECT_GL_NO_ERROR();

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    EXPECT_GL_NO_ERROR();

    swapBuffers();

    GLuint ready = GL_FALSE;
    while (ready == GL_FALSE)
    {
        angle::Sleep(0);
        glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
    }

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);

    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(result);
}

// Test that changing framebuffers work
TEST_P(OcclusionQueriesTest, FramebufferBindingChange)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    constexpr GLsizei kSize = 4;

    // Create two framebuffers, and make sure they are synced.
    std::array<GLFramebuffer, 2> fbo;
    std::array<GLTexture, 2> color;

    for (size_t index = 0; index < 2; ++index)
    {
        glBindTexture(GL_TEXTURE_2D, color[index]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);

        glBindFramebuffer(GL_FRAMEBUFFER, fbo[index]);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color[index],
                               0);

        glClearColor(0, index, 1 - index, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        EXPECT_PIXEL_COLOR_EQ(0, 0, index ? GLColor::green : GLColor::blue);
    }
    EXPECT_GL_NO_ERROR();

    glViewport(0, 0, kSize, kSize);

    // Start an occlusion query and issue a draw call to each framebuffer.
    GLQueryEXT query;

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);

    for (size_t index = 0; index < 2; ++index)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo[index]);
        drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    }

    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    GLuint result = GL_FALSE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_TRUE(result);
}

// Test that switching framebuffers without actually drawing, then issuing a masked clear while a
// query is active works.
TEST_P(OcclusionQueriesTestES3, SwitchFramebuffersThenMaskedClear)
{
    constexpr GLint kSize = 10;

    GLFramebuffer fbo1, fbo2;
    GLRenderbuffer rbo1, rbo2;

    // Set up two framebuffers
    glBindRenderbuffer(GL_RENDERBUFFER, rbo1);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kSize, kSize);

    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo1);

    glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kSize, kSize);

    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo2);

    // Start render pass on fbo1
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0);

    // Begin a query
    GLQuery query;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);

    // Switch to another render pass and clear.  In the Vulkan backend, this clear is deferred, so
    // while the framebuffer binding is synced, the previous render pass is not necessarily closed.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glClear(GL_STENCIL_BUFFER_BIT);

    // Switch back to the original render pass and issue a masked stencil clear.  In the Vulkan
    // backend, this is done with a draw call.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glStencilMask(0xAA);
    glClearStencil(0xF4);
    glClear(GL_STENCIL_BUFFER_BIT);

    // Verify the clear worked.
    GLRenderbuffer color;
    glBindRenderbuffer(GL_RENDERBUFFER, color);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 0xA4, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0);

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

// Test that an empty query after a positive query returns false
TEST_P(OcclusionQueriesTest, EmptyQueryAfterCompletedQuery)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    GLQueryEXT query;

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    ASSERT_GL_NO_ERROR();

    GLuint result = GL_FALSE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    ASSERT_GL_NO_ERROR();
    EXPECT_TRUE(result);

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    ASSERT_GL_NO_ERROR();

    result = GL_FALSE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    ASSERT_GL_NO_ERROR();
    EXPECT_FALSE(result);
}

// Some Metal drivers do not automatically clear visibility buffer
// at the beginning of a render pass. This test makes two queries
// that would use the same internal visibility buffer at the same
// offset and checks the query results.
TEST_P(OcclusionQueriesTest, EmptyQueryAfterCompletedQueryInterleaved)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    GLQueryEXT query;

    // Make a draw call to start a new render pass
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);

    // Begin a query and make another draw call
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    // Check the query result to end command encoding
    GLuint result = GL_FALSE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    EXPECT_TRUE(result);
    ASSERT_GL_NO_ERROR();

    // Make a draw call to start a new render pass
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.0f);

    // Begin and immediately resolve a new query; it must return false
    result = GL_FALSE;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    EXPECT_FALSE(result);
    ASSERT_GL_NO_ERROR();
}

// Test multiple occlusion queries.
TEST_P(OcclusionQueriesTest, MultiQueries)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsOpenGL() || IsD3D11());

    GLQueryEXT query[5];

    // First query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[0]);

    EXPECT_GL_NO_ERROR();

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    EXPECT_GL_NO_ERROR();

    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded

    EXPECT_GL_NO_ERROR();

    // Due to implementation might skip in-renderpass flush, we are using glFinish here to force a
    // flush. A flush shound't clear the query result.
    glFinish();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), -2, 0.25f);  // this quad should be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    // First query ends

    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f,
             0.25f);  // this quad should not be occluded

    // Second query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[1]);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
             0.25f);  // this quad should be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    // Third query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[2]);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
             0.5f);  // this quad should not be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    // ------------
    glFinish();

    glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
    glScissor(0, 0, getWindowWidth() / 2, getWindowHeight());
    glEnable(GL_SCISSOR_TEST);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
             0.5f);  // this quad should not be occluded

    // Fourth query: begin query then end then begin again
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[3]);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
             1);  // this quad should not be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[3]);
    EXPECT_GL_NO_ERROR();
    // glClear should not be counted toward query);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    // Fifth query spans across frames
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query[4]);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f,
             0.25f);  // this quad should not be occluded

    swapBuffers();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.9f,
             0.5f);  // this quad should not be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query[0], GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_TRUE(result);

    glGetQueryObjectuivEXT(query[1], GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_FALSE(result);

    glGetQueryObjectuivEXT(query[2], GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_TRUE(result);

    glGetQueryObjectuivEXT(query[3], GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_FALSE(result);

    glGetQueryObjectuivEXT(query[4], GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_TRUE(result);
}

TEST_P(OcclusionQueriesTest, Errors)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    EXPECT_GL_NO_ERROR();

    GLuint query  = 0;
    GLuint query2 = 0;
    glGenQueriesEXT(1, &query);

    EXPECT_GL_FALSE(glIsQueryEXT(query));
    EXPECT_GL_FALSE(glIsQueryEXT(query2));

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);  // can't pass 0 as query id
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
                    query2);  // can't initiate a query while one's already active
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    EXPECT_GL_TRUE(glIsQueryEXT(query));
    EXPECT_GL_FALSE(glIsQueryEXT(query2));  // have not called begin

    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);  // this quad should not be occluded
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);      // no active query for this target
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
                    query);  // can't begin a query as a different type than previously used
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
                    query2);  // have to call genqueries first
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glGenQueriesEXT(1, &query2);
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2);  // should be ok now
    EXPECT_GL_TRUE(glIsQueryEXT(query2));

    drawQuad(mProgram, essl1_shaders::PositionAttrib(),
             0.3f);                  // this should draw in front of other quad
    glDeleteQueriesEXT(1, &query2);  // should delete when query becomes inactive
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);  // should not incur error; should delete
                                                            // query + 1 at end of execution.
    EXPECT_GL_NO_ERROR();

    swapBuffers();

    EXPECT_GL_NO_ERROR();

    GLuint ready = GL_FALSE;
    glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT,
                           &ready);  // this query is now deleted
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    EXPECT_GL_NO_ERROR();
}

// Test that running multiple simultaneous queries from multiple EGL contexts returns the correct
// result for each query.  Helps expose bugs in ANGLE's virtual contexts.
TEST_P(OcclusionQueriesTest, MultiContext)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // TODO(cwallez@chromium.org): Suppression for http://anglebug.com/42261759
    ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());

    // Test skipped because the D3D backends cannot support simultaneous queries on multiple
    // contexts yet.
    ANGLE_SKIP_TEST_IF(IsD3D());

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // draw a quad at depth 0.5
    glEnable(GL_DEPTH_TEST);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);

    EGLWindow *window = getEGLWindow();

    EGLDisplay display = window->getDisplay();
    EGLConfig config   = window->getConfig();
    EGLSurface surface = window->getSurface();

    EGLint contextAttributes[] = {
        EGL_CONTEXT_MAJOR_VERSION_KHR,
        getClientMajorVersion(),
        EGL_CONTEXT_MINOR_VERSION_KHR,
        getClientMinorVersion(),
        EGL_NONE,
    };

    const size_t passCount = 5;
    struct ContextInfo
    {
        EGLContext context;
        GLuint program;
        GLuint query;
        std::array<bool, passCount> visiblePasses;
        bool shouldPass;
    };

    ContextInfo contexts[] = {
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, true, false, true, false},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {true, true, false, true, true},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, true, true, true, true},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {true, false, false, true, false},
            true,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
        {
            EGL_NO_CONTEXT,
            0,
            0,
            {false, false, false, false, false},
            false,
        },
    };

    for (auto &context : contexts)
    {
        context.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
        ASSERT_NE(context.context, EGL_NO_CONTEXT);

        eglMakeCurrent(display, surface, surface, context.context);

        context.program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        ASSERT_NE(context.program, 0u);

        glDepthMask(GL_FALSE);
        glEnable(GL_DEPTH_TEST);

        glGenQueriesEXT(1, &context.query);
        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, context.query);

        ASSERT_GL_NO_ERROR();
    }

    for (size_t pass = 0; pass < passCount; pass++)
    {
        for (const auto &context : contexts)
        {
            eglMakeCurrent(display, surface, surface, context.context);

            float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f)
                                                      : mRNG.randomFloatBetween(0.6f, 1.0f);
            drawQuad(context.program, essl1_shaders::PositionAttrib(), depth);

            EXPECT_GL_NO_ERROR();
        }
    }

    for (const auto &context : contexts)
    {
        eglMakeCurrent(display, surface, surface, context.context);
        glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

        GLuint result = GL_TRUE;
        glGetQueryObjectuivEXT(context.query, GL_QUERY_RESULT_EXT, &result);

        EXPECT_GL_NO_ERROR();

        GLuint expectation = context.shouldPass ? GL_TRUE : GL_FALSE;
        EXPECT_EQ(expectation, result);
    }

    eglMakeCurrent(display, surface, surface, window->getContext());

    for (auto &context : contexts)
    {
        eglDestroyContext(display, context.context);
        context.context = EGL_NO_CONTEXT;
    }
}

// Test multiple occlusion queries in flight. This test provoked a bug in the Metal backend that
// resulted in an infinite loop when trying to flush the command buffer when the maximum number of
// inflight render passes was reached.
TEST_P(OcclusionQueriesTest, ManyQueriesInFlight)
{
    constexpr int kManyQueryCount = 100;

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // http://anglebug.com/42263499
    ANGLE_SKIP_TEST_IF(IsOpenGL() || IsD3D11());

    GLQueryEXT query;

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    GLRenderbuffer rbo[2];
    glBindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 32, 32);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 32, 32);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    EXPECT_GL_NO_ERROR();

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    for (int i = 0; i < kManyQueryCount; i++)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);
        drawQuad(mProgram, essl1_shaders::PositionAttrib(), 1.0f - 2.0f * i / kManyQueryCount);
        glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);
    }

    glFinish();

    EXPECT_GL_NO_ERROR();
}

// Test two occlusion queries in sequence and there are some glBindFramebuffer in between.
// This test provoked a bug that the second query been skipped.
TEST_P(OcclusionQueriesTest, WrongSkippedQuery)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    GLRenderbuffer rbo;
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 32, 32);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
    EXPECT_GL_NO_ERROR();

    GLQueryEXT query1;
    // Draw square in 1st FBO, clear main framebuffer - main framebuffer is active after
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query1);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    GLQueryEXT query2;
    // Draw square in FBO, clear main framebuffer - FBO is active after
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query2);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    GLuint results[2]  = {0};
    GLuint expectation = GL_TRUE;
    glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_EXT, &results[0]);
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectation, results[0]);

    glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_EXT, &results[1]);
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(expectation, results[1]);
}

class OcclusionQueriesNoSurfaceTestES3 : public ANGLETest<>
{
  protected:
    OcclusionQueriesNoSurfaceTestES3() : mUnusedConfig(0), mUnusedDisplay(nullptr)
    {
        setWindowWidth(kWidth);
        setWindowHeight(kHeight);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setDeferContextInit(true);
    }

    static constexpr int kWidth  = 300;
    static constexpr int kHeight = 300;

    void swapBuffers() override {}

    EGLConfig mUnusedConfig;
    EGLDisplay mUnusedDisplay;
};

// This test provked a bug in the Metal backend that only happened
// when there was no surfaces on the EGLContext and a query had
// just ended after a draw and then switching to a different
// context.
TEST_P(OcclusionQueriesNoSurfaceTestES3, SwitchingContextsWithQuery)
{
    EGLWindow *window = getEGLWindow();

    EGLDisplay display = window->getDisplay();
    EGLConfig config   = window->getConfig();

    EGLint contextAttributes[] = {
        EGL_CONTEXT_MAJOR_VERSION_KHR,
        getClientMajorVersion(),
        EGL_CONTEXT_MINOR_VERSION_KHR,
        getClientMinorVersion(),
        EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE,
        EGL_TRUE,
        EGL_NONE,
    };

    // The following GL objects are implicitly deleted in
    // ContextInfo's destructor before the EGLContext is manually destroyed
    struct ContextInfo
    {
        EGLContext context;
        GLBuffer buf;
        GLProgram program;
        GLFramebuffer fb;
        GLTexture tex;
        GLQuery query;
    };

    // ContextInfo contains objects that clean themselves on destruction.
    // We want these objects to stick around until the test ends.
    std::vector<ContextInfo *> pairs;

    for (size_t i = 0; i < 2; ++i)
    {
        ContextInfo *infos[] = {
            new ContextInfo(),
            new ContextInfo(),
        };

        for (ContextInfo *pinfo : infos)
        {
            pairs.push_back(pinfo);
            ContextInfo &info = *pinfo;

            info.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
            ASSERT_NE(info.context, EGL_NO_CONTEXT);

            // Make context current context with no draw and read surface.
            ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info.context));

            // Create something to draw to.
            glBindFramebuffer(GL_FRAMEBUFFER, info.fb);
            glBindTexture(GL_TEXTURE_2D, info.tex);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, info.tex,
                                   0);
            EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            EXPECT_GL_NO_ERROR();
            glFlush();
        }

        // Setup an shader and quad buffer
        for (ContextInfo *pinfo : infos)
        {
            ContextInfo &info = *pinfo;
            ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info.context));

            constexpr char kVS[] = R"(
            attribute vec4 position;
            void main() {
              gl_Position = position;
            }
          )";

            constexpr char kFS[] = R"(
          precision mediump float;
          void main() {
            gl_FragColor = vec4(1, 0, 0, 1);
          }
          )";

            info.program.makeRaster(kVS, kFS);
            glUseProgram(info.program);

            constexpr float vertices[] = {
                -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
            };
            glBindBuffer(GL_ARRAY_BUFFER, info.buf);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
            EXPECT_GL_NO_ERROR();
        }

        ContextInfo &info1 = *infos[0];
        ContextInfo &info2 = *infos[1];

        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));

        glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, info1.query);
        glFlush();

        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        glEndQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE);
        EXPECT_GL_NO_ERROR();

        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info2.context));
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, info1.context));
    }

    // destroy GL objects on the correct context.
    for (ContextInfo *pinfo : pairs)
    {
        EGLContext context = pinfo->context;
        ASSERT_EGL_TRUE(eglMakeCurrent(display, nullptr, nullptr, context));
        EXPECT_GL_NO_ERROR();
        delete pinfo;
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        ASSERT_EGL_TRUE(eglDestroyContext(display, context));
        EXPECT_EGL_SUCCESS();
    }
}

// This test provoked a bug in the Metal backend where a command buffer flush during query
// preparation would recursively clear mAllocatedQueries, causing fillBuffer to be called with
// size 0, resulting in a Metal validation error (when run with MTL_DEBUG_LAYER=1).
TEST_P(OcclusionQueriesTestES3, TextureResizeWithQueryReuse)
{
    // The Metal backend flushes command buffers after this many render passes
    // (defined in src/libANGLE/renderer/metal/mtl_common.h)
    constexpr int kMaxRenderPassesPerCommandBuffer = 16;

    GLQueryEXT query;
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_GL_NO_ERROR();

    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    glEndQuery(GL_ANY_SAMPLES_PASSED);
    EXPECT_GL_NO_ERROR();

    // Call texImage2D enough times to accumulate render passes up to the flush limit.
    const int numTexImageCalls = kMaxRenderPassesPerCommandBuffer - 1;
    for (int i = 0; i < numTexImageCalls; i++)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
                     nullptr);
        EXPECT_GL_NO_ERROR();
    }

    // Begin query again with the SAME query object.
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    EXPECT_GL_NO_ERROR();

    // This texImage2D is the 16th render pass, triggering a command buffer flush.
    // Without a fix, prepareRenderPassVisibilityPoolBuffer would call fillBuffer with size 0
    // because mAllocatedQueries gets cleared during the recursive flush.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_GL_NO_ERROR();

    glEndQuery(GL_ANY_SAMPLES_PASSED);
    EXPECT_GL_NO_ERROR();

    GLuint result = GL_TRUE;
    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
    EXPECT_GL_NO_ERROR();

    // Result should be false since no draw calls were made.
    EXPECT_GL_FALSE(result);
}

// Test query reuse with render pass accumulation using draw calls to distinct FBOs.
TEST_P(OcclusionQueriesTestES3, QueryReuseWithMultipleFBOs)
{
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    constexpr int kNumRenderPasses = 16;
    std::vector<GLTexture> textures(kNumRenderPasses);
    std::vector<GLFramebuffer> fbos(kNumRenderPasses);

    for (int i = 0; i < kNumRenderPasses; i++)
    {
        glBindTexture(GL_TEXTURE_2D, textures[i]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    }

    GLQueryEXT query;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    glEndQuery(GL_ANY_SAMPLES_PASSED);

    for (int i = 0; i < kNumRenderPasses - 1; i++)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    }

    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[kNumRenderPasses - 1]);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    glEndQuery(GL_ANY_SAMPLES_PASSED);

    GLuint result = GL_FALSE;
    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
    EXPECT_GL_TRUE(result);
}

// Test that deleting an FBO while a query result on that FBO is pending does not crash the driver
// when calling glGetQueryObjectuiv.
TEST_P(OcclusionQueriesTestES3, DeleteFBOWithPendingQuery)
{
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glViewport(0, 0, 64, 64);
    glClear(GL_COLOR_BUFFER_BIT);

    GLQueryEXT query;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    glEndQuery(GL_ANY_SAMPLES_PASSED);

    // Delete the FBO on which the query was executed, while result is still pending
    fbo.reset();

    // Retrieve query result - flushes pending jobs referencing the deleted FBO
    GLuint result = GL_FALSE;
    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_TRUE(result);
}

// Test that unbinding an FBO while a query result on that FBO is pending does not crash the driver
// when calling glGetQueryObjectuiv.
TEST_P(OcclusionQueriesTestES3, UnbindFBOWithPendingQuery)
{
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glViewport(0, 0, 64, 64);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    GLQueryEXT query;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    glEndQuery(GL_ANY_SAMPLES_PASSED);

    // Unbind user FBO by switching back to default framebuffer (0)
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    // FORCE the driver to commit the unbind and end the previous render pass.
    // Because drivers often optimize glClear, issuing geometry (drawQuad)
    // strictly guarantees a new render pass is initiated in the hardware.
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);

    // Retrieve query result
    GLuint result = GL_FALSE;
    glGetQueryObjectuiv(query, GL_QUERY_RESULT, &result);
    EXPECT_GL_NO_ERROR();
    EXPECT_GL_TRUE(result);
}

// Test that a very large number of scissored clears while an occlusion query is active still
// yields a correct query result. On backends that emulate scissored clears with draws, each clear
// pauses and resumes the query in the same render pass; the render pass must be split before the
// backend's per-pass visibility offset limit is reached.
TEST_P(OcclusionQueriesTest, ManyScissoredClearsInsideQuery)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    // Metal allows at most 32768 visibility result slots per render pass.
    constexpr int kClearCount = 35000;

    glDepthMask(GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    GLQueryEXT query;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);

    // this quad should not be occluded
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);

    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, 1, 1);
    for (int i = 0; i < kClearCount; ++i)
    {
        glClear(GL_COLOR_BUFFER_BIT);
    }
    glDisable(GL_SCISSOR_TEST);

    // this quad should not be occluded
    drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.8f);

    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();

    GLuint result = GL_FALSE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT,
                           &result);  // will block waiting for result
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_TRUE(result);
}

// Test that a very large number of distinct queries and draw calls in a single render pass
// still works and yields correct query results when exceeding the backend's per-pass
// visibility offset limit.
TEST_P(OcclusionQueriesTest, ExcessiveNumberOfQueries)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                       !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"));

    constexpr int kQueryCount = 35000;

    glDisable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_GL_NO_ERROR();

    constexpr char kVS[] =
        "attribute vec4 a_position;\n"
        "attribute vec4 a_color;\n"
        "varying vec4 v_color;\n"
        "void main() {\n"
        "    gl_Position  = a_position;\n"
        "    gl_PointSize = 4.0;\n"
        "    v_color      = a_color;\n"
        "}\n";

    constexpr char kFS[] =
        "precision mediump float;\n"
        "varying vec4 v_color;\n"
        "void main() {\n"
        "    gl_FragColor = v_color;\n"
        "}\n";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);

    GLint posLoc   = glGetAttribLocation(program, "a_position");
    GLint colorLoc = glGetAttribLocation(program, "a_color");
    ASSERT_NE(-1, posLoc);
    ASSERT_NE(-1, colorLoc);

    glDisableVertexAttribArray(posLoc);
    glDisableVertexAttribArray(colorLoc);

    std::vector<GLQueryEXT> queries(kQueryCount);

    for (int i = 0; i < kQueryCount; ++i)
    {
        glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, queries[i]);
        if (i % 2 != 0)
        {
            int idx   = i / 2;
            GLfloat x = (static_cast<GLfloat>(idx % 30) / 30.0f) * 1.8f - 0.9f;
            GLfloat y = (static_cast<GLfloat>((idx / 30) % 30) / 30.0f) * 1.8f - 0.9f;
            glVertexAttrib3f(posLoc, x, y, 0.0f);

            GLfloat r = static_cast<GLfloat>(i % 256) / 255.0f;
            GLfloat g = static_cast<GLfloat>((i * 7) % 256) / 255.0f;
            GLfloat b = static_cast<GLfloat>((i * 13) % 256) / 255.0f;
            glVertexAttrib4f(colorLoc, r, g, b, 1.0f);
            glDrawArrays(GL_POINTS, 0, 1);
        }
        glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    }
    EXPECT_GL_NO_ERROR();

    for (int i = 0; i < kQueryCount; ++i)
    {
        GLuint result = GL_FALSE;
        glGetQueryObjectuivEXT(queries[i], GL_QUERY_RESULT_EXT, &result);
        EXPECT_GL_NO_ERROR();
        if (i % 2 != 0)
        {
            EXPECT_GL_TRUE(result) << " at query index " << i;
        }
        else
        {
            EXPECT_GL_FALSE(result) << " at query index " << i;
        }
    }
}

ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(OcclusionQueriesTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OcclusionQueriesTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(
    OcclusionQueriesTestES3,
    ES3_VULKAN().enable(Feature::PreferSubmitOnAnySamplesPassedQueryEnd));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OcclusionQueriesNoSurfaceTestES3);
ANGLE_INSTANTIATE_TEST_ES3(OcclusionQueriesNoSurfaceTestES3);
