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

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

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

#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

    // WebGL doesn't support glMaxShaderCompilerThreadsKHR.
#ifndef RIVE_WEBGL
    if (m_capabilities.KHR_parallel_shader_compile)
    {
        // Allow GL's shader compilation to use 2 background threads.
        //
        // Parallel compilation is documented to be enabled by default, but on
        // some drivers the parallel compilation does not actually activate
        // without explicitly setting this.
        //
        // NOTE: the spec states that apps may use "0xffffffff" to mean "use the
        // maximum number of threads", but that seems like an easy invitation
        // for a driver bug, so we are explicit about the number of threads.
        //
        // FIXME: When AsyncPipelineManager starts using >1 thread, we should
        // incorporate its same logic here.
        glMaxShaderCompilerThreadsKHR(2);
    }
#endif
}

static void gl_enable_disable(GLenum state, bool enabled)
{
    if (enabled)
        glEnable(state);
    else
        glDisable(state);
}

void GLState::setDepthStencilEnabled(bool depthEnabled, bool stencilEnabled)
{
    if (!m_validState.depthStencilEnabled || m_depthTestEnabled != depthEnabled)
    {
        gl_enable_disable(GL_DEPTH_TEST, depthEnabled);
        m_depthTestEnabled = depthEnabled;
    }

    if (!m_validState.depthStencilEnabled ||
        m_stencilTestEnabled != stencilEnabled)
    {
        gl_enable_disable(GL_STENCIL_TEST, stencilEnabled);
        m_stencilTestEnabled = stencilEnabled;
    }

    m_validState.depthStencilEnabled = true;
}

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

static GLenum gl_stencil_op(StencilOp op)
{
    switch (op)
    {
        case StencilOp::keep:
            return GL_KEEP;
        case StencilOp::replace:
            return GL_REPLACE;
        case StencilOp::zero:
            return GL_ZERO;
        case StencilOp::decrClamp:
            return GL_DECR;
        case StencilOp::incrWrap:
            return GL_INCR_WRAP;
        case StencilOp::decrWrap:
            return GL_DECR_WRAP;
    }
    RIVE_UNREACHABLE();
}

static GLenum gl_stencil_func(gpu::StencilCompareOp compareOp)
{
    switch (compareOp)
    {
        case gpu::StencilCompareOp::less:
            return GL_LESS;
        case gpu::StencilCompareOp::equal:
            return GL_EQUAL;
        case gpu::StencilCompareOp::lessOrEqual:
            return GL_LEQUAL;
        case gpu::StencilCompareOp::notEqual:
            return GL_NOTEQUAL;
        case gpu::StencilCompareOp::always:
            return GL_ALWAYS;
    }
    RIVE_UNREACHABLE();
}

static GLenum gl_cull_face(CullFace riveCullFace)
{
    switch (riveCullFace)
    {
        case CullFace::none:
            return GL_NONE;
        case CullFace::clockwise:
            return GL_FRONT;
        case CullFace::counterclockwise:
            return GL_BACK;
    }
    RIVE_UNREACHABLE();
}

void GLState::setBlendEquation(gpu::BlendEquation blendEquation)
{
    if (m_validState.blendEquation && blendEquation == m_blendEquation)
    {
        return;
    }
    if (!m_validState.blendEquation ||
        m_blendEquation == gpu::BlendEquation::none)
    {
        glEnable(GL_BLEND);
    }
    switch (blendEquation)
    {
        case gpu::BlendEquation::none:
            glDisable(GL_BLEND);
            break;
        case gpu::BlendEquation::srcOver:
            glBlendEquation(GL_FUNC_ADD);
            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
            break;
        case gpu::BlendEquation::screen:
            glBlendEquation(GL_SCREEN_KHR);
            break;
        case gpu::BlendEquation::overlay:
            glBlendEquation(GL_OVERLAY_KHR);
            break;
        case gpu::BlendEquation::darken:
            glBlendEquation(GL_DARKEN_KHR);
            break;
        case gpu::BlendEquation::lighten:
            glBlendEquation(GL_LIGHTEN_KHR);
            break;
        case gpu::BlendEquation::colorDodge:
            glBlendEquation(GL_COLORDODGE_KHR);
            break;
        case gpu::BlendEquation::colorBurn:
            glBlendEquation(GL_COLORBURN_KHR);
            break;
        case gpu::BlendEquation::hardLight:
            glBlendEquation(GL_HARDLIGHT_KHR);
            break;
        case gpu::BlendEquation::softLight:
            glBlendEquation(GL_SOFTLIGHT_KHR);
            break;
        case gpu::BlendEquation::difference:
            glBlendEquation(GL_DIFFERENCE_KHR);
            break;
        case gpu::BlendEquation::exclusion:
            glBlendEquation(GL_EXCLUSION_KHR);
            break;
        case gpu::BlendEquation::multiply:
            glBlendEquation(GL_MULTIPLY_KHR);
            break;
        case gpu::BlendEquation::hue:
            glBlendEquation(GL_HSL_HUE_KHR);
            break;
        case gpu::BlendEquation::saturation:
            glBlendEquation(GL_HSL_SATURATION_KHR);
            break;
        case gpu::BlendEquation::color:
            glBlendEquation(GL_HSL_COLOR_KHR);
            break;
        case gpu::BlendEquation::luminosity:
            glBlendEquation(GL_HSL_LUMINOSITY_KHR);
            break;
        case gpu::BlendEquation::plus:
            glBlendEquation(GL_FUNC_ADD);
            glBlendFunc(GL_ONE, GL_ONE);
            break;
        case gpu::BlendEquation::max:
            glBlendEquation(GL_MAX);
            glBlendFunc(GL_ONE, GL_ONE);
            break;
    }
    m_blendEquation = blendEquation;
    m_validState.blendEquation = true;
}

void GLState::setWriteMasks(bool colorWriteMask,
                            bool depthWriteMask,
                            uint8_t 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::setPipelineState(const gpu::PipelineState& pipelineState)
{
    setDepthStencilEnabled(pipelineState.depthTestEnabled,
                           pipelineState.stencilTestEnabled);
    if (pipelineState.stencilTestEnabled)
    {
        if (!pipelineState.stencilDoubleSided)
        {
            glStencilFunc(
                gl_stencil_func(pipelineState.stencilFrontOps.compareOp),
                pipelineState.stencilReference,
                pipelineState.stencilCompareMask);
            glStencilOp(
                gl_stencil_op(pipelineState.stencilFrontOps.failOp),
                gl_stencil_op(pipelineState.stencilFrontOps.depthFailOp),
                gl_stencil_op(pipelineState.stencilFrontOps.passOp));
        }
        else
        {
            glStencilFuncSeparate(
                GL_FRONT,
                gl_stencil_func(pipelineState.stencilFrontOps.compareOp),
                pipelineState.stencilReference,
                pipelineState.stencilCompareMask);
            glStencilOpSeparate(
                GL_FRONT,
                gl_stencil_op(pipelineState.stencilFrontOps.failOp),
                gl_stencil_op(pipelineState.stencilFrontOps.depthFailOp),
                gl_stencil_op(pipelineState.stencilFrontOps.passOp));
            glStencilFuncSeparate(
                GL_BACK,
                gl_stencil_func(pipelineState.stencilBackOps.compareOp),
                pipelineState.stencilReference,
                pipelineState.stencilCompareMask);
            glStencilOpSeparate(
                GL_BACK,
                gl_stencil_op(pipelineState.stencilBackOps.failOp),
                gl_stencil_op(pipelineState.stencilBackOps.depthFailOp),
                gl_stencil_op(pipelineState.stencilBackOps.passOp));
        }
    }
    setCullFace(gl_cull_face(pipelineState.cullFace));
    setBlendEquation(pipelineState.blendEquation);
    setWriteMasks(pipelineState.colorWriteEnabled,
                  pipelineState.depthWriteEnabled,
                  pipelineState.stencilWriteMask);
}

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
