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

// DebugTest.cpp : Tests of the GL_KHR_debug extension

#include "common/debug.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

namespace angle
{
constexpr char kBufferObjLabel[]          = "buffer";
constexpr char kShaderObjLabel[]          = "shader";
constexpr char kProgramObjLabel[]         = "program";
constexpr char kVertexArrayObjLabel[]     = "vertexarray";
constexpr char kQueryObjLabel[]           = "query";
constexpr char kProgramPipelineObjLabel[] = "programpipeline";
constexpr GLenum kObjectTypes[]           = {GL_BUFFER_OBJECT_EXT,           GL_SHADER_OBJECT_EXT,
                                   GL_PROGRAM_OBJECT_EXT,          GL_QUERY_OBJECT_EXT,
                                   GL_PROGRAM_PIPELINE_OBJECT_EXT, GL_VERTEX_ARRAY_OBJECT_EXT};

class DebugTest : public ANGLETest
{
  protected:
    DebugTest() : mDebugExtensionAvailable(false)
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
        setDebugEnabled(true);
    }

    void testSetUp() override
    {
        mDebugExtensionAvailable = IsGLExtensionEnabled("GL_KHR_debug");
        if (mDebugExtensionAvailable)
        {
            glEnable(GL_DEBUG_OUTPUT);
        }
    }

    bool mDebugExtensionAvailable;
};

void createGLObjectAndLabel(GLenum identifier, GLuint &object, const char **label)
{
    switch (identifier)
    {
        case GL_BUFFER_OBJECT_EXT:
            glGenBuffers(1, &object);
            glBindBuffer(GL_ARRAY_BUFFER, object);
            *label = kBufferObjLabel;
            break;
        case GL_SHADER_OBJECT_EXT:
            object = glCreateShader(GL_VERTEX_SHADER);
            *label = kShaderObjLabel;
            break;
        case GL_PROGRAM_OBJECT_EXT:
            object = glCreateProgram();
            *label = kProgramObjLabel;
            break;
        case GL_VERTEX_ARRAY_OBJECT_EXT:
            glGenVertexArrays(1, &object);
            glBindVertexArray(object);
            *label = kVertexArrayObjLabel;
            break;
        case GL_QUERY_OBJECT_EXT:
            glGenQueries(1, &object);
            glBeginQuery(GL_ANY_SAMPLES_PASSED, object);
            *label = kQueryObjLabel;
            break;
        case GL_PROGRAM_PIPELINE_OBJECT_EXT:
            glGenProgramPipelines(1, &object);
            glBindProgramPipeline(object);
            *label = kProgramPipelineObjLabel;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void deleteGLObject(GLenum identifier, GLuint &object)
{
    switch (identifier)
    {
        case GL_BUFFER_OBJECT_EXT:
            glDeleteBuffers(1, &object);
            break;
        case GL_SHADER_OBJECT_EXT:
            glDeleteShader(object);
            break;
        case GL_PROGRAM_OBJECT_EXT:
            glDeleteProgram(object);
            break;
        case GL_VERTEX_ARRAY_OBJECT_EXT:
            glDeleteVertexArrays(1, &object);
            break;
        case GL_QUERY_OBJECT_EXT:
            glEndQuery(GL_ANY_SAMPLES_PASSED);
            glDeleteQueries(1, &object);
            break;
        case GL_PROGRAM_PIPELINE_OBJECT_EXT:
            glDeleteProgramPipelines(1, &object);
            break;
        default:
            UNREACHABLE();
            break;
    }
}

// Test basic usage of setting and getting labels using GL_EXT_debug_label
TEST_P(DebugTest, ObjectLabelsEXT)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_debug_label"));

    for (const GLenum identifier : kObjectTypes)
    {
        bool skip = false;
        switch (identifier)
        {
            case GL_PROGRAM_PIPELINE_OBJECT_EXT:
                if (!(getClientMajorVersion() >= 3 && getClientMinorVersion() >= 1) ||
                    !IsGLExtensionEnabled("GL_EXT_separate_shader_objects"))
                {
                    skip = true;
                }
                break;
            case GL_QUERY_OBJECT_EXT:
                // GLES3 context is required for glGenQueries()
                if (getClientMajorVersion() < 3 ||
                    !IsGLExtensionEnabled("GL_EXT_occlusion_query_boolean"))
                {
                    skip = true;
                }
                break;
            case GL_VERTEX_ARRAY_OBJECT_EXT:
                if (getClientMajorVersion() < 3)
                {
                    skip = true;
                }
                break;
            default:
                break;
        }

        // if object enum is not supported, move on to the next object type
        if (skip)
        {
            continue;
        }

        GLuint object;
        const char *label;
        createGLObjectAndLabel(identifier, object, &label);

        glLabelObjectEXT(identifier, object, 0, label);
        ASSERT_GL_NO_ERROR();

        std::vector<char> labelBuf(strlen(label) + 1);
        GLsizei labelLengthBuf = 0;
        glGetObjectLabelEXT(identifier, object, static_cast<GLsizei>(labelBuf.size()),
                            &labelLengthBuf, labelBuf.data());
        ASSERT_GL_NO_ERROR();

        EXPECT_EQ(static_cast<GLsizei>(strlen(label)), labelLengthBuf);
        EXPECT_STREQ(label, labelBuf.data());

        ASSERT_GL_NO_ERROR();

        deleteGLObject(identifier, object);

        glLabelObjectEXT(identifier, object, 0, label);
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);

        glGetObjectLabelEXT(identifier, object, static_cast<GLsizei>(labelBuf.size()),
                            &labelLengthBuf, labelBuf.data());
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
}

class DebugTestES3 : public DebugTest
{};

struct Message
{
    GLenum source;
    GLenum type;
    GLuint id;
    GLenum severity;
    std::string message;
    const void *userParam;
};

static void GL_APIENTRY Callback(GLenum source,
                                 GLenum type,
                                 GLuint id,
                                 GLenum severity,
                                 GLsizei length,
                                 const GLchar *message,
                                 const void *userParam)
{
    Message m{source, type, id, severity, std::string(message, length), userParam};
    std::vector<Message> *messages =
        static_cast<std::vector<Message> *>(const_cast<void *>(userParam));
    messages->push_back(m);
}

// Test that all ANGLE back-ends have GL_KHR_debug enabled
TEST_P(DebugTestES3, Enabled)
{
    ASSERT_TRUE(mDebugExtensionAvailable);
}

// Test that when debug output is disabled, no message are outputted
TEST_P(DebugTestES3, DisabledOutput)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    glDisable(GL_DEBUG_OUTPUT);

    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 1,
                            GL_DEBUG_SEVERITY_NOTIFICATION, -1, "discarded");

    GLint numMessages = 0;
    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    ASSERT_EQ(0, numMessages);

    std::vector<Message> messages;
    glDebugMessageCallbackKHR(Callback, &messages);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

    ASSERT_EQ(0u, messages.size());
}

// Test a basic flow of inserting a message and reading it back
TEST_P(DebugTestES3, InsertMessage)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    const GLenum source       = GL_DEBUG_SOURCE_APPLICATION;
    const GLenum type         = GL_DEBUG_TYPE_OTHER;
    const GLuint id           = 1;
    const GLenum severity     = GL_DEBUG_SEVERITY_NOTIFICATION;
    const std::string message = "Message";

    glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str());

    GLint numMessages = 0;
    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    ASSERT_EQ(1, numMessages);

    GLint messageLength = 0;
    glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength);
    EXPECT_EQ(static_cast<GLint>(message.length()) + 1, messageLength);

    GLenum sourceBuf   = 0;
    GLenum typeBuf     = 0;
    GLenum idBuf       = 0;
    GLenum severityBuf = 0;
    GLsizei lengthBuf  = 0;
    std::vector<char> messageBuf(messageLength);
    GLuint ret =
        glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf, &typeBuf,
                                &idBuf, &severityBuf, &lengthBuf, messageBuf.data());
    EXPECT_EQ(1u, ret);
    EXPECT_EQ(source, sourceBuf);
    EXPECT_EQ(type, typeBuf);
    EXPECT_EQ(id, idBuf);
    EXPECT_EQ(severity, severityBuf);
    EXPECT_EQ(lengthBuf, messageLength);
    EXPECT_STREQ(message.c_str(), messageBuf.data());

    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    EXPECT_EQ(0, numMessages);

    ASSERT_GL_NO_ERROR();
}

// Test inserting multiple messages
TEST_P(DebugTestES3, InsertMessageMultiple)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    const GLenum source          = GL_DEBUG_SOURCE_APPLICATION;
    const GLenum type            = GL_DEBUG_TYPE_OTHER;
    const GLuint startID         = 1;
    const GLenum severity        = GL_DEBUG_SEVERITY_NOTIFICATION;
    const char messageRepeatChar = 'm';
    const size_t messageCount    = 32;

    for (size_t i = 0; i < messageCount; i++)
    {
        std::string message(i + 1, messageRepeatChar);
        glDebugMessageInsertKHR(source, type, startID + static_cast<GLuint>(i), severity, -1,
                                message.c_str());
    }

    GLint numMessages = 0;
    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    ASSERT_EQ(static_cast<GLint>(messageCount), numMessages);

    for (size_t i = 0; i < messageCount; i++)
    {
        glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
        EXPECT_EQ(static_cast<GLint>(messageCount - i), numMessages);

        std::string expectedMessage(i + 1, messageRepeatChar);

        GLint messageLength = 0;
        glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength);
        EXPECT_EQ(static_cast<GLint>(expectedMessage.length()) + 1, messageLength);

        GLenum sourceBuf   = 0;
        GLenum typeBuf     = 0;
        GLenum idBuf       = 0;
        GLenum severityBuf = 0;
        GLsizei lengthBuf  = 0;
        std::vector<char> messageBuf(messageLength);
        GLuint ret =
            glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf,
                                    &typeBuf, &idBuf, &severityBuf, &lengthBuf, messageBuf.data());
        EXPECT_EQ(1u, ret);
        EXPECT_EQ(source, sourceBuf);
        EXPECT_EQ(type, typeBuf);
        EXPECT_EQ(startID + i, idBuf);
        EXPECT_EQ(severity, severityBuf);
        EXPECT_EQ(lengthBuf, messageLength);
        EXPECT_STREQ(expectedMessage.c_str(), messageBuf.data());
    }

    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    EXPECT_EQ(0, numMessages);

    ASSERT_GL_NO_ERROR();
}

// Test using a debug callback
TEST_P(DebugTestES3, DebugCallback)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    std::vector<Message> messages;

    glDebugMessageCallbackKHR(Callback, &messages);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

    const GLenum source       = GL_DEBUG_SOURCE_APPLICATION;
    const GLenum type         = GL_DEBUG_TYPE_OTHER;
    const GLuint id           = 1;
    const GLenum severity     = GL_DEBUG_SEVERITY_NOTIFICATION;
    const std::string message = "Message";

    glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str());

    GLint numMessages = 0;
    glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages);
    EXPECT_EQ(0, numMessages);

    ASSERT_EQ(1u, messages.size());

    const Message &m = messages.front();
    EXPECT_EQ(source, m.source);
    EXPECT_EQ(type, m.type);
    EXPECT_EQ(id, m.id);
    EXPECT_EQ(severity, m.severity);
    EXPECT_EQ(message, m.message);

    ASSERT_GL_NO_ERROR();
}

// Test the glGetPointervKHR entry point
TEST_P(DebugTestES3, GetPointer)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    std::vector<Message> messages;

    glDebugMessageCallbackKHR(Callback, &messages);

    void *callback = nullptr;
    glGetPointervKHR(GL_DEBUG_CALLBACK_FUNCTION, &callback);
    EXPECT_EQ(reinterpret_cast<void *>(Callback), callback);

    void *userData = nullptr;
    glGetPointervKHR(GL_DEBUG_CALLBACK_USER_PARAM, &userData);
    EXPECT_EQ(static_cast<void *>(&messages), userData);
}

// Test usage of message control.  Example taken from GL_KHR_debug spec.
TEST_P(DebugTestES3, MessageControl1)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    std::vector<Message> messages;

    glDebugMessageCallbackKHR(Callback, &messages);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

    // Setup of the default active debug group: Filter everything in
    glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);

    // Generate a debug marker debug output message
    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,
                            GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 1");

    // Push debug group 1
    glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 2");

    // Setup of the debug group 1: Filter everything out
    glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);

    // This message won't appear in the debug output log of
    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,
                            GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 3");

    // Pop debug group 1, restore the volume control of the default debug group.
    glPopDebugGroupKHR();

    // Generate a debug marker debug output message
    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100,
                            GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 5");

    // Expected debug output from the GL implementation
    // Message 1
    // Message 2
    // Message 2
    // Message 5
    EXPECT_EQ(4u, messages.size());
    EXPECT_STREQ(messages[0].message.c_str(), "Message 1");
    EXPECT_STREQ(messages[1].message.c_str(), "Message 2");
    EXPECT_STREQ(messages[2].message.c_str(), "Message 2");
    EXPECT_STREQ(messages[3].message.c_str(), "Message 5");

    ASSERT_GL_NO_ERROR();
}

// Test usage of message control.  Example taken from GL_KHR_debug spec.
TEST_P(DebugTestES3, MessageControl2)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    std::vector<Message> messages;

    glDebugMessageCallbackKHR(Callback, &messages);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

    // Setup the control of de debug output for the default debug group
    glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);
    glDebugMessageControlKHR(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr,
                             GL_FALSE);
    std::vector<GLuint> ids0 = {1234, 2345, 3456, 4567};
    glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                             static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE);
    glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, GL_DONT_CARE,
                             static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE);

    // Push debug group 1
    // Inherit of the default debug group debug output volume control
    // Filtered out by glDebugMessageControl
    glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 1");

    // In this section of the code, we are interested in performances.
    glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE,
                             0, nullptr, GL_TRUE);
    // But we already identify that some messages are not really useful for us.
    std::vector<GLuint> ids1 = {5678, 6789};
    glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE,
                             static_cast<GLuint>(ids1.size()), ids1.data(), GL_FALSE);

    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 1357,
                            GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 2");
    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_THIRD_PARTY,  // We still filter out these messages.
                            GL_DEBUG_TYPE_OTHER, 3579, GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 3");

    glPopDebugGroupKHR();

    // Expected debug output from the GL implementation
    // Message 2
    EXPECT_EQ(1u, messages.size());
    EXPECT_STREQ(messages[0].message.c_str(), "Message 2");

    ASSERT_GL_NO_ERROR();
}

// Test basic usage of setting and getting labels
TEST_P(DebugTestES3, ObjectLabels)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    GLuint renderbuffer = 0;
    glGenRenderbuffers(1, &renderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);

    const std::string &label = "renderbuffer";
    glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str());

    std::vector<char> labelBuf(label.length() + 1);
    GLsizei labelLengthBuf = 0;
    glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()),
                        &labelLengthBuf, labelBuf.data());

    EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
    EXPECT_STREQ(label.c_str(), labelBuf.data());

    ASSERT_GL_NO_ERROR();

    glDeleteRenderbuffers(1, &renderbuffer);

    glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()),
                        &labelLengthBuf, labelBuf.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
}

// Test basic usage of setting and getting labels
TEST_P(DebugTestES3, ObjectPtrLabels)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    const std::string &label = "sync";
    glObjectPtrLabelKHR(sync, -1, label.c_str());

    std::vector<char> labelBuf(label.length() + 1);
    GLsizei labelLengthBuf = 0;
    glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf,
                           labelBuf.data());

    EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf);
    EXPECT_STREQ(label.c_str(), labelBuf.data());

    ASSERT_GL_NO_ERROR();

    glDeleteSync(sync);

    glObjectPtrLabelKHR(sync, -1, label.c_str());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);

    glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf,
                           labelBuf.data());
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
}

// Test setting labels before, during and after rendering.  The debug markers can be validated by
// capturing this test under a graphics debugger.
TEST_P(DebugTestES3, Rendering)
{
    ANGLE_SKIP_TEST_IF(!mDebugExtensionAvailable);

    // The test produces the following hierarchy:
    //
    // Group: Before Draw
    // Message: Before Draw Marker
    //   Message: In Group 1 Marker
    //   glDrawArrays
    //   Group: After Draw 1
    //      glDrawArrays
    //      Message: In Group 2 Marker
    //
    //      glCopyTexImage <-- this breaks the render pass
    //
    //      glDrawArrays
    //   End Group
    //
    //   glCopyTexImage <-- this breaks the render pass
    //
    //   Group: After Draw 2
    //      glDrawArrays
    //
    //      glCopyTexImage <-- this breaks the render pass
    //
    //      Message: In Group 3 Marker
    //   End Group
    //   Message: After Draw Marker
    // End Group
    const std::string beforeDrawGroup = "Before Draw";
    const std::string drawGroup1      = "Group 1";
    const std::string drawGroup2      = "Group 2";

    const std::string beforeDrawMarker = "Before Draw Marker";
    const std::string inGroup1Marker   = "In Group 1 Marker";
    const std::string inGroup2Marker   = "In Group 2 Marker";
    const std::string inGroup3Marker   = "In Group 3 Marker";
    const std::string afterDrawMarker  = "After Draw Marker";

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    glUseProgram(program);

    glPushDebugGroupKHR(GL_DEBUG_SOURCE_THIRD_PARTY, 0, -1, beforeDrawGroup.c_str());
    glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 0,
                            GL_DEBUG_SEVERITY_NOTIFICATION, -1, beforeDrawMarker.c_str());
    {
        glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0,
                                GL_DEBUG_SEVERITY_LOW, -1, inGroup1Marker.c_str());

        glDrawArrays(GL_TRIANGLES, 0, 6);

        glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 0, -1, drawGroup1.c_str());
        {
            glDrawArrays(GL_TRIANGLES, 0, 6);

            glDebugMessageInsertKHR(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_PORTABILITY, 0,
                                    GL_DEBUG_SEVERITY_MEDIUM, -1, inGroup2Marker.c_str());

            GLTexture texture;
            glBindTexture(GL_TEXTURE_2D, texture);
            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);

            glDrawArrays(GL_TRIANGLES, 0, 6);
        }
        glPopDebugGroupKHR();

        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 2, 2, 0);

        glPushDebugGroupKHR(GL_DEBUG_SOURCE_THIRD_PARTY, 0, -1, drawGroup2.c_str());
        {
            glDrawArrays(GL_TRIANGLES, 0, 6);

            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 3, 3, 0);

            glDebugMessageInsertKHR(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DEBUG_TYPE_OTHER, 0,
                                    GL_DEBUG_SEVERITY_HIGH, -1, inGroup3Marker.c_str());
        }
        glPopGroupMarkerEXT();

        glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0,
                                GL_DEBUG_SEVERITY_HIGH, -1, afterDrawMarker.c_str());
    }
    glPopGroupMarkerEXT();

    ASSERT_GL_NO_ERROR();
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DebugTestES3);
ANGLE_INSTANTIATE_TEST_ES3(DebugTestES3);

ANGLE_INSTANTIATE_TEST(DebugTest,
                       ANGLE_ALL_TEST_PLATFORMS_ES1,
                       ANGLE_ALL_TEST_PLATFORMS_ES2,
                       ANGLE_ALL_TEST_PLATFORMS_ES3,
                       ANGLE_ALL_TEST_PLATFORMS_ES31);
}  // namespace angle
