/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "BakedOpState.h"
#include "Matrix.h"
#include "utils/Macros.h"

namespace android {
namespace uirenderer {

class Caches;
struct Glop;
class Layer;
class RenderState;
struct ClipBase;

/**
 * Main rendering manager for a collection of work - one frame + any contained FBOs.
 *
 * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only
 * place where FBOs are bound, created, and destroyed.
 *
 * All rendering operations will be sent by the Dispatcher, a collection of static methods,
 * which has intentionally limited access to the renderer functionality.
 */
class BakedOpRenderer {
public:
    typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&);
    /**
     * Position agnostic shadow lighting info. Used with all shadow ops in scene.
     */
    struct LightInfo {
        LightInfo() : LightInfo(0, 0) {}
        LightInfo(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha)
                : ambientShadowAlpha(ambientShadowAlpha), spotShadowAlpha(spotShadowAlpha) {}
        uint8_t ambientShadowAlpha;
        uint8_t spotShadowAlpha;
    };

    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
                    const LightInfo& lightInfo)
            : mGlopReceiver(DefaultGlopReceiver)
            , mRenderState(renderState)
            , mCaches(caches)
            , mOpaque(opaque)
            , mWideColorGamut(wideColorGamut)
            , mLightInfo(lightInfo) {}

    RenderState& renderState() { return mRenderState; }
    Caches& caches() { return mCaches; }

    void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
    void endFrame(const Rect& repaintRect);
    WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
    void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer);
    void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
    void endLayer();
    WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);

    Texture* getTexture(Bitmap* bitmap);
    const LightInfo& getLightInfo() const { return mLightInfo; }

    void renderGlop(const BakedOpState& state, const Glop& glop) {
        renderGlop(&state.computedState.clippedBounds, state.computedState.getClipIfNeeded(), glop);
    }
    void renderFunctor(const FunctorOp& op, const BakedOpState& state);

    void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) {
        mGlopReceiver(*this, dirtyBounds, clip, glop);
    }
    bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
    void dirtyRenderTarget(const Rect& dirtyRect);
    bool didDraw() const { return mHasDrawn; }

    uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; }
    uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; }

    // simple draw methods, to be used for end frame decoration
    void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) {
        float ltrb[4] = {left, top, right, bottom};
        drawRects(ltrb, 4, paint);
    }
    void drawRects(const float* rects, int count, const SkPaint* paint);

protected:
    GlopReceiver mGlopReceiver;

private:
    static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
                                    const ClipBase* clip, const Glop& glop) {
        renderer.renderGlopImpl(dirtyBounds, clip, glop);
    }
    void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop);
    void setViewport(uint32_t width, uint32_t height);
    void clearColorBuffer(const Rect& clearRect);
    void prepareRender(const Rect* dirtyBounds, const ClipBase* clip);
    void setupStencilRectList(const ClipBase* clip);
    void setupStencilRegion(const ClipBase* clip);
    void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold);

    RenderState& mRenderState;
    Caches& mCaches;
    bool mOpaque;
    bool mWideColorGamut;
    bool mHasDrawn = false;

    // render target state - setup by start/end layer/frame
    // only valid to use in between start/end pairs.
    struct {
        // If not drawing to a layer: fbo = 0, offscreenBuffer = null,
        // Otherwise these refer to currently painting layer's state
        GLuint frameBufferId = 0;
        OffscreenBuffer* offscreenBuffer = nullptr;

        // Used when drawing to a layer and using stencil clipping. otherwise null.
        RenderBuffer* stencil = nullptr;

        // value representing the ClipRectList* or ClipRegion* currently stored in
        // the stencil of the current render target
        const ClipBase* lastStencilClip = nullptr;

        // Size of renderable region in current render target - for layers, may not match actual
        // bounds of FBO texture. offscreenBuffer->texture has this information.
        uint32_t viewportWidth = 0;
        uint32_t viewportHeight = 0;

        Matrix4 orthoMatrix;
    } mRenderTarget;

    const LightInfo mLightInfo;
};

};  // namespace uirenderer
};  // namespace android
