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