/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrOpFlushState_DEFINED
#define GrOpFlushState_DEFINED

#include "GrBufferAllocPool.h"
#include "SkArenaAlloc.h"
#include "ops/GrMeshDrawOp.h"

class GrGpu;
class GrGpuCommandBuffer;
class GrResourceProvider;

/** Tracks the state across all the GrOps (really just the GrDrawOps) in a GrOpList flush. */
class GrOpFlushState {
public:
    GrOpFlushState(GrGpu*, GrResourceProvider*);

    ~GrOpFlushState() { this->reset(); }

    /** Inserts an upload to be executed after all ops in the flush prepared their draws but before
        the draws are executed to the backend 3D API. */
    void addASAPUpload(GrDrawOp::DeferredUploadFn&& upload) {
        fAsapUploads.emplace_back(std::move(upload));
    }

    const GrCaps& caps() const;
    GrResourceProvider* resourceProvider() const { return fResourceProvider; }

    /** Has the token been flushed to the backend 3D API. */
    bool hasDrawBeenFlushed(GrDrawOpUploadToken token) const {
        return token.fSequenceNumber <= fLastFlushedToken.fSequenceNumber;
    }

    /** Issue a token to an operation that is being enqueued. */
    GrDrawOpUploadToken issueDrawToken() {
        return GrDrawOpUploadToken(++fLastIssuedToken.fSequenceNumber);
    }

    /** Call every time a draw that was issued a token is flushed */
    void flushToken() { ++fLastFlushedToken.fSequenceNumber; }

    /** Gets the next draw token that will be issued. */
    GrDrawOpUploadToken nextDrawToken() const {
        return GrDrawOpUploadToken(fLastIssuedToken.fSequenceNumber + 1);
    }

    /** The last token flushed to all the way to the backend API. */
    GrDrawOpUploadToken nextTokenToFlush() const {
        return GrDrawOpUploadToken(fLastFlushedToken.fSequenceNumber + 1);
    }

    void* makeVertexSpace(size_t vertexSize, int vertexCount,
                          const GrBuffer** buffer, int* startVertex);
    uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex);

    /** This is called after each op has a chance to prepare its draws and before the draws are
        issued. */
    void preIssueDraws() {
        fVertexPool.unmap();
        fIndexPool.unmap();
        int uploadCount = fAsapUploads.count();

        for (int i = 0; i < uploadCount; i++) {
            this->doUpload(fAsapUploads[i]);
        }
        fAsapUploads.reset();
    }

    void doUpload(GrDrawOp::DeferredUploadFn&);

    void putBackIndices(size_t indices) { fIndexPool.putBack(indices * sizeof(uint16_t)); }

    void putBackVertexSpace(size_t sizeInBytes) { fVertexPool.putBack(sizeInBytes); }

    GrGpuCommandBuffer* commandBuffer() { return fCommandBuffer; }
    void setCommandBuffer(GrGpuCommandBuffer* buffer) { fCommandBuffer = buffer; }

    GrGpu* gpu() { return fGpu; }

    void reset() {
        fVertexPool.reset();
        fIndexPool.reset();
        fPipelines.reset();
    }

    /** Additional data required on a per-op basis when executing GrDrawOps. */
    struct DrawOpArgs {
        GrRenderTarget*           fRenderTarget;
        const GrAppliedClip*      fAppliedClip;
        GrXferProcessor::DstProxy fDstProxy;
    };

    void setDrawOpArgs(DrawOpArgs* opArgs) { fOpArgs = opArgs; }

    const DrawOpArgs& drawOpArgs() const {
        SkASSERT(fOpArgs);
        return *fOpArgs;
    }

    template <typename... Args>
    GrPipeline* allocPipeline(Args... args) {
        return fPipelines.make<GrPipeline>(std::forward<Args>(args)...);
    }

private:
    GrGpu* fGpu;
    GrResourceProvider* fResourceProvider;
    GrGpuCommandBuffer* fCommandBuffer;
    GrVertexBufferAllocPool fVertexPool;
    GrIndexBufferAllocPool fIndexPool;
    SkSTArray<4, GrDrawOp::DeferredUploadFn> fAsapUploads;
    GrDrawOpUploadToken fLastIssuedToken;
    GrDrawOpUploadToken fLastFlushedToken;
    DrawOpArgs* fOpArgs;
    SkArenaAlloc fPipelines{sizeof(GrPipeline) * 100};
};

/**
 * A word about uploads and tokens: Ops should usually schedule their uploads to occur at the
 * begining of a frame whenever possible. These are called ASAP uploads. Of course, this requires
 * that there are no draws that have yet to be flushed that rely on the old texture contents. In
 * that case the ASAP upload would happen prior to the previous draw causing the draw to read the
 * new (wrong) texture data. In that case they should schedule an inline upload.
 *
 * Ops, in conjunction with helpers such as GrDrawOpAtlas, can use the token system to know
 * what the most recent draw was that referenced a resource (or portion of a resource). Each draw
 * is assigned a token. A resource (or portion) can be tagged with the most recent draw's
 * token. The target provides a facility for testing whether the draw corresponding to the token
 * has been flushed. If it has not been flushed then the op must perform an inline upload instead.
 * When scheduling an inline upload the op provides the token of the draw that the upload must occur
 * before. The upload will then occur between the draw that requires the new data but after the
 * token that requires the old data.
 *
 * TODO: Currently the token/upload interface is spread over GrDrawOp, GrMeshDrawOp,
 * GrDrawOp::Target, and GrMeshDrawOp::Target. However, the interface at the GrDrawOp level is not
 * complete and isn't useful. We should push it down to GrMeshDrawOp until it is required at the
 * GrDrawOp level.
 */

/**
 * GrDrawOp instances use this object to allocate space for their geometry and to issue the draws
 * that render their op.
 */
class GrDrawOp::Target {
public:
    Target(GrOpFlushState* state, GrDrawOp* op) : fState(state), fOp(op) {}

    /** Returns the token of the draw that this upload will occur before. */
    GrDrawOpUploadToken addInlineUpload(DeferredUploadFn&& upload) {
        fOp->fInlineUploads.emplace_back(std::move(upload), fState->nextDrawToken());
        return fOp->fInlineUploads.back().fUploadBeforeToken;
    }

    /** Returns the token of the draw that this upload will occur before. Since ASAP uploads
        are done first during a flush, this will be the first token since the most recent
        flush. */
    GrDrawOpUploadToken addAsapUpload(DeferredUploadFn&& upload) {
        fState->addASAPUpload(std::move(upload));
        return fState->nextTokenToFlush();
    }

    bool hasDrawBeenFlushed(GrDrawOpUploadToken token) const {
        return fState->hasDrawBeenFlushed(token);
    }

    /** Gets the next draw token that will be issued by this target. This can be used by an op
        to record that the next draw it issues will use a resource (e.g. texture) while preparing
        that draw. */
    GrDrawOpUploadToken nextDrawToken() const { return fState->nextDrawToken(); }

    const GrCaps& caps() const { return fState->caps(); }

    GrResourceProvider* resourceProvider() const { return fState->resourceProvider(); }

protected:
    GrDrawOp* op() { return fOp; }
    GrOpFlushState* state() { return fState; }
    const GrOpFlushState* state() const { return fState; }

private:
    GrOpFlushState* fState;
    GrDrawOp* fOp;
};

/** Extension of GrDrawOp::Target for use by GrMeshDrawOp. Adds the ability to create vertex
    draws. */
class GrMeshDrawOp::Target : public GrDrawOp::Target {
public:
    Target(GrOpFlushState* state, GrMeshDrawOp* op) : INHERITED(state, op) {}

    void draw(const GrGeometryProcessor* gp, const GrPipeline* pipeline, const GrMesh& mesh);

    void* makeVertexSpace(size_t vertexSize, int vertexCount,
                          const GrBuffer** buffer, int* startVertex) {
        return this->state()->makeVertexSpace(vertexSize, vertexCount, buffer, startVertex);
    }

    uint16_t* makeIndexSpace(int indexCount, const GrBuffer** buffer, int* startIndex) {
        return this->state()->makeIndexSpace(indexCount, buffer, startIndex);
    }

    /** Helpers for ops which over-allocate and then return data to the pool. */
    void putBackIndices(int indices) { this->state()->putBackIndices(indices); }
    void putBackVertices(int vertices, size_t vertexStride) {
        this->state()->putBackVertexSpace(vertices * vertexStride);
    }

    GrRenderTarget* renderTarget() const { return this->state()->drawOpArgs().fRenderTarget; }

    const GrAppliedClip* clip() const { return this->state()->drawOpArgs().fAppliedClip; }

    const GrXferProcessor::DstProxy& dstProxy() const {
        return this->state()->drawOpArgs().fDstProxy;
    }

    template <typename... Args>
    GrPipeline* allocPipeline(Args... args) {
        return this->state()->allocPipeline(std::forward<Args>(args)...);
    }

private:
    GrMeshDrawOp* meshDrawOp() { return static_cast<GrMeshDrawOp*>(this->op()); }
    typedef GrDrawOp::Target INHERITED;
};

#endif
