/*
 * Copyright (C) 2016 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 "ClipArea.h"
#include "Rect.h"
#include "utils/Macros.h"

#include <vector>
#include <unordered_map>

struct SkRect;

namespace android {
namespace uirenderer {

class BakedOpState;
struct BeginLayerOp;
class BatchBase;
class LinearAllocator;
struct MergedBakedOpList;
class MergingOpBatch;
class OffscreenBuffer;
class OpBatch;
class RenderNode;

typedef int batchid_t;
typedef const void* mergeid_t;

namespace OpBatchType {
    enum {
        Bitmap,
        MergedPatch,
        AlphaVertices,
        Vertices,
        AlphaMaskTexture,
        Text,
        ColorText,
        Shadow,
        TextureLayer,
        Functor,
        CopyToLayer,
        CopyFromLayer,

        Count // must be last
    };
}

typedef void (*BakedOpReceiver)(void*, const BakedOpState&);
typedef void (*MergedOpReceiver)(void*, const MergedBakedOpList& opList);

/**
 * Stores the deferred render operations and state used to compute ordering
 * for a single FBO/layer.
 */
class LayerBuilder {
// Prevent copy/assign because users may stash pointer to offscreenBuffer and viewportClip
PREVENT_COPY_AND_ASSIGN(LayerBuilder);
public:
    // Create LayerBuilder for Fbo0
    LayerBuilder(uint32_t width, uint32_t height, const Rect& repaintRect)
            : LayerBuilder(width, height, repaintRect, nullptr, nullptr) {};

    // Create LayerBuilder for an offscreen layer, where beginLayerOp is present for a
    // saveLayer, renderNode is present for a HW layer.
    LayerBuilder(uint32_t width, uint32_t height,
            const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode);

    // iterate back toward target to see if anything drawn since should overlap the new op
    // if no target, merging ops still iterate to find similar batch to insert after
    void locateInsertIndex(int batchId, const Rect& clippedBounds,
            BatchBase** targetBatch, size_t* insertBatchIndex) const;

    void deferUnmergeableOp(LinearAllocator& allocator, BakedOpState* op, batchid_t batchId);

    // insertion point of a new batch, will hopefully be immediately after similar batch
    // (generally, should be similar shader)
    void deferMergeableOp(LinearAllocator& allocator,
            BakedOpState* op, batchid_t batchId, mergeid_t mergeId);

    void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers, MergedOpReceiver*) const;

    void deferLayerClear(const Rect& dstRect);

    bool empty() const {
        return mBatches.empty();
    }

    void clear() {
        mBatches.clear();
    }

    void dump() const;

    const uint32_t width;
    const uint32_t height;
    const Rect repaintRect;
    const ClipRect repaintClip;
    OffscreenBuffer* offscreenBuffer;
    const BeginLayerOp* beginLayerOp;
    const RenderNode* renderNode;

    // list of deferred CopyFromLayer ops, to be deferred upon encountering EndUnclippedLayerOps
    std::vector<BakedOpState*> activeUnclippedSaveLayers;
private:
    void flushLayerClears(LinearAllocator& allocator);

    std::vector<BatchBase*> mBatches;

    /**
     * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
     * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
     * collide, which avoids the need to resolve mergeid collisions.
     */
    std::unordered_map<mergeid_t, MergingOpBatch*> mMergingBatchLookup[OpBatchType::Count];

    // Maps batch ids to the most recent *non-merging* batch of that id
    OpBatch* mBatchLookup[OpBatchType::Count] = { nullptr };

    std::vector<Rect> mClearRects;
};

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