/*
 * Copyright 2023 Rive
 */

#include "rive/renderer/gl/gl_state.hpp"

#include "shaders/constants.glsl"

namespace rive::gpu
{
void GLState::invalidate()
{
    // Invalidate all cached state.
    memset(&m_validState, 0, sizeof(m_validState));

    // PLS only ever culls the CCW face when culling is enabled.
    glFrontFace(GL_CW);
    glDepthRangef(0, 1);
    glDepthFunc(GL_LESS);
    glClearDepthf(1);
    glClearStencil(0);

    // We always blend with premultiplied src-over when glBlendFunc is relevant.
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    // ANGLE_shader_pixel_local_storage doesn't allow dither.
    glDisable(GL_DITHER);

#ifndef RIVE_ANDROID
    // D3D and Metal both have a provoking vertex convention of "first" for flat
    // varyings, and it's very costly for ANGLE to implement the OpenGL
    // convention of "last" on these backends. To workaround this, ANGLE
    // provides the ANGLE_provoking_vertex extension. When this extension is
    // present, we can just set the provoking vertex to "first" and trust that
    // it will be fast.
    if (m_capabilities.ANGLE_provoking_vertex)
    {
        glProvokingVertexANGLE(GL_FIRST_VERTEX_CONVENTION_ANGLE);
    }
#endif

    // Low-effort attempt to reset core state we don't use to default values.
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_POLYGON_OFFSET_FILL);
#ifndef RIVE_WEBGL
    // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.18
    // WebGL 2.0 behaves as though PRIMITIVE_RESTART_FIXED_INDEX were always
    // enabled.
    glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
#endif
    glDisable(GL_RASTERIZER_DISCARD);
    glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
    glDisable(GL_SAMPLE_COVERAGE);
    glDisable(GL_SCISSOR_TEST);
    glDisable(GL_STENCIL_TEST);
    // glDisable(GL_COLOR_LOGIC_OP);
    // glDisable(GL_INDEX_LOGIC_OP);
    // glDisable(GL_ALPHA_TEST);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
    glPixelStorei(GL_PACK_ALIGNMENT, 4);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}

constexpr static GLenum blend_mode_to_gl_equation(BlendMode blendMode)
{
    switch (blendMode)
    {
        case BlendMode::srcOver:
            return GL_FUNC_ADD;
        case BlendMode::screen:
            return GL_SCREEN_KHR;
        case BlendMode::overlay:
            return GL_OVERLAY_KHR;
        case BlendMode::darken:
            return GL_DARKEN_KHR;
        case BlendMode::lighten:
            return GL_LIGHTEN_KHR;
        case BlendMode::colorDodge:
            return GL_COLORDODGE_KHR;
        case BlendMode::colorBurn:
            return GL_COLORBURN_KHR;
        case BlendMode::hardLight:
            return GL_HARDLIGHT_KHR;
        case BlendMode::softLight:
            return GL_SOFTLIGHT_KHR;
        case BlendMode::difference:
            return GL_DIFFERENCE_KHR;
        case BlendMode::exclusion:
            return GL_EXCLUSION_KHR;
        case BlendMode::multiply:
            return GL_MULTIPLY_KHR;
        case BlendMode::hue:
            return GL_HSL_HUE_KHR;
        case BlendMode::saturation:
            return GL_HSL_SATURATION_KHR;
        case BlendMode::color:
            return GL_HSL_COLOR_KHR;
        case BlendMode::luminosity:
            return GL_HSL_LUMINOSITY_KHR;
    }
    RIVE_UNREACHABLE();
}

void GLState::setBlendEquation(BlendMode blendMode)
{
    GLenum blendEquation = blend_mode_to_gl_equation(blendMode);
    if (!m_validState.blendEquation || blendEquation != m_blendEquation)
    {
        if (!m_validState.blendEquation || m_blendEquation == GL_NONE)
        {
            glEnable(GL_BLEND);
        }
        glBlendEquation(blendEquation);
        m_blendEquation = blendEquation;
        m_validState.blendEquation = true;
    }
}

void GLState::disableBlending()
{
    if (!m_validState.blendEquation || m_blendEquation != GL_NONE)
    {
        glDisable(GL_BLEND);
        m_blendEquation = GL_NONE;
        m_validState.blendEquation = true;
    }
}

void GLState::setWriteMasks(bool colorWriteMask,
                            bool depthWriteMask,
                            GLuint stencilWriteMask)
{
    if (!m_validState.writeMasks)
    {
        glColorMask(colorWriteMask,
                    colorWriteMask,
                    colorWriteMask,
                    colorWriteMask);
        glDepthMask(depthWriteMask);
        glStencilMask(stencilWriteMask);
        m_colorWriteMask = colorWriteMask;
        m_depthWriteMask = depthWriteMask;
        m_stencilWriteMask = stencilWriteMask;
        m_validState.writeMasks = true;
    }
    else
    {
        if (colorWriteMask != m_colorWriteMask)
        {
            glColorMask(colorWriteMask,
                        colorWriteMask,
                        colorWriteMask,
                        colorWriteMask);
            m_colorWriteMask = colorWriteMask;
        }
        if (depthWriteMask != m_depthWriteMask)
        {
            glDepthMask(depthWriteMask);
            m_depthWriteMask = depthWriteMask;
        }
        if (stencilWriteMask != m_stencilWriteMask)
        {
            glStencilMask(stencilWriteMask);
            m_stencilWriteMask = stencilWriteMask;
        }
    }
}

void GLState::setCullFace(GLenum cullFace)
{
    if (!m_validState.cullFace || cullFace != m_cullFace)
    {
        if (cullFace == GL_NONE)
        {
            glDisable(GL_CULL_FACE);
        }
        else
        {
            if (!m_validState.cullFace || m_cullFace == GL_NONE)
            {
                glEnable(GL_CULL_FACE);
            }
            glCullFace(cullFace);
        }
        m_cullFace = cullFace;
        m_validState.cullFace = true;
    }
}

void GLState::bindProgram(GLuint programID)
{
    if (!m_validState.boundProgramID || programID != m_boundProgramID)
    {
        glUseProgram(programID);
        m_boundProgramID = programID;
        m_validState.boundProgramID = true;
    }
}

void GLState::bindVAO(GLuint vao)
{
    if (!m_validState.boundVAO || vao != m_boundVAO)
    {
        glBindVertexArray(vao);
        m_boundVAO = vao;
        m_validState.boundVAO = true;
    }
}

void GLState::bindBuffer(GLenum target, GLuint bufferID)
{
    switch (target)
    {
        default:
            // Don't track GL_ELEMENT_ARRAY_BUFFER, since it is tied to the VAO
            // state.
            glBindBuffer(target, bufferID);
            return;
        case GL_ARRAY_BUFFER:
            if (!m_validState.boundArrayBufferID ||
                bufferID != m_boundArrayBufferID)
            {
                glBindBuffer(GL_ARRAY_BUFFER, bufferID);
                m_boundArrayBufferID = bufferID;
                m_validState.boundArrayBufferID = true;
            }
            break;
        case GL_UNIFORM_BUFFER:
            if (!m_validState.boundUniformBufferID ||
                bufferID != m_boundUniformBufferID)
            {
                glBindBuffer(GL_UNIFORM_BUFFER, bufferID);
                m_boundUniformBufferID = bufferID;
                m_validState.boundUniformBufferID = true;
            }
            break;
    }
}

void GLState::deleteProgram(GLuint programID)
{
    glDeleteProgram(programID);
    if (m_validState.boundProgramID && m_boundProgramID == programID)
        m_boundProgramID = 0;
}

void GLState::deleteVAO(GLuint vao)
{
    glDeleteVertexArrays(1, &vao);
    if (m_validState.boundVAO && m_boundVAO == vao)
        m_boundVAO = 0;
}

void GLState::deleteBuffer(GLuint bufferID)
{
    glDeleteBuffers(1, &bufferID);
    if (m_validState.boundArrayBufferID && m_boundArrayBufferID == bufferID)
        m_boundArrayBufferID = 0;
    if (m_validState.boundUniformBufferID && m_boundUniformBufferID == bufferID)
        m_boundUniformBufferID = 0;
}
} // namespace rive::gpu
