/*
 * Copyright 2022 Rive
 */

#include "testing_gl_renderer.hpp"

#ifndef RIVE_TOOLS_NO_GL

#include "rive/renderer/render_context.hpp"
#include "rive/renderer/rive_renderer.hpp"
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"

TestingGLRenderer::~TestingGLRenderer() {}

std::unique_ptr<TestingGLRenderer> TestingGLRenderer::Make(
    const TestingWindow::BackendParams& backendParams)
{
    class RiveRenderer : public TestingGLRenderer
    {
    public:
        RiveRenderer(const TestingWindow::BackendParams& backendParams) :
            m_backendParams(backendParams)
        {
            m_contextOptions.shaderCompilationMode =
                backendParams.shaderCompilationMode;
            if (m_backendParams.msaa)
            {
                m_contextOptions.disablePixelLocalStorage = true;
            }
            if (m_backendParams.atomic)
            {
                m_contextOptions.disableFragmentShaderInterlock = true;
            }
        }

        void init(void* getGLProcAddress) override
        {
            m_renderContext =
                rive::gpu::RenderContextGLImpl::MakeContext(m_contextOptions);
        }

        rive::Factory* factory() override { return m_renderContext.get(); }

        std::unique_ptr<rive::Renderer> reset(int width,
                                              int height,
                                              uint32_t targetTextureID) override
        {
            if (targetTextureID == 0)
            {
                // Render directly to the default framebuffer.
                GLint sampleCount;
                glBindFramebuffer(GL_FRAMEBUFFER, 0);
                glGetIntegerv(GL_SAMPLES, &sampleCount);
                m_renderTarget =
                    rive::make_rcp<rive::gpu::FramebufferRenderTargetGL>(
                        width,
                        height,
                        0,
                        sampleCount);
            }
            else
            {
                // Render to targetTextureID.
                auto renderTarget =
                    rive::make_rcp<rive::gpu::TextureRenderTargetGL>(width,
                                                                     height);
                renderTarget->setTargetTexture(targetTextureID);
                m_renderTarget = std::move(renderTarget);
            }
            return std::make_unique<rive::RiveRenderer>(m_renderContext.get());
        }

        void beginFrame(const TestingWindow::FrameOptions& options) override
        {
            // For testing, reset GPU resources to their initial sizes every
            // frame. This will stress intermediate flushes more, as well as
            // creating more consistency when rendering in multiple threads and
            // a nondeterministic order.
            m_renderContext->releaseResources();

            rive::gpu::RenderContext::FrameDescriptor frameDescriptor = {
                .renderTargetWidth = m_renderTarget->width(),
                .renderTargetHeight = m_renderTarget->height(),
                .loadAction = options.doClear
                                  ? rive::gpu::LoadAction::clear
                                  : rive::gpu::LoadAction::preserveRenderTarget,
                .clearColor = options.clearColor,
                .msaaSampleCount =
                    (m_backendParams.msaa || options.forceMSAA) ? 4u : 0u,
                .disableRasterOrdering =
                    m_backendParams.atomic || options.disableRasterOrdering,
                .triangulationThresholds = options.triangulationThresholds,
                .wireframe = options.wireframe,
                .fillsDisabled = options.fillsDisabled,
                .strokesDisabled = options.strokesDisabled,
                .clockwiseFillOverride =
                    m_backendParams.clockwise || options.clockwiseFillOverride,
                .synthesizedFailureType = options.synthesizedFailureType,
            };
            m_renderContext->beginFrame(frameDescriptor);
        }

        void flush(int dpiScale) override { flushPLSContext(nullptr); }

        rive::gpu::RenderContext* renderContext() const override
        {
            return m_renderContext.get();
        }
        rive::gpu::RenderTarget* renderTarget() const override
        {
            return m_renderTarget.get();
        }

        void flushPLSContext(
            rive::gpu::RenderTarget* offscreenRenderTarget) override
        {
            m_renderContext->flush({
                .renderTarget = offscreenRenderTarget != nullptr
                                    ? offscreenRenderTarget
                                    : m_renderTarget.get(),
            });
        }

    private:
        const TestingWindow::BackendParams m_backendParams;
        rive::gpu::RenderContextGLImpl::ContextOptions m_contextOptions;
        std::unique_ptr<rive::gpu::RenderContext> m_renderContext;
        rive::rcp<rive::gpu::RenderTargetGL> m_renderTarget;
    };
    return std::make_unique<RiveRenderer>(backendParams);
}

#endif
