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

#ifndef GrOpsTask_DEFINED
#define GrOpsTask_DEFINED

#include "include/core/SkMatrix.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkClipStack.h"
#include "src/core/SkSpan.h"
#include "src/core/SkStringUtils.h"
#include "src/core/SkTLazy.h"
#include "src/gpu/GrAppliedClip.h"
#include "src/gpu/GrPathRendering.h"
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrRenderTask.h"
#include "src/gpu/ops/GrDrawOp.h"
#include "src/gpu/ops/GrOp.h"

class GrAuditTrail;
class GrCaps;
class GrClearOp;
class GrGpuBuffer;
class GrRenderTargetProxy;

class GrOpsTask : public GrRenderTask {
private:
    using DstProxyView = GrXferProcessor::DstProxyView;

public:
    // The Arenas must outlive the GrOpsTask, either by preserving the context that owns
    // the pool, or by moving the pool to the DDL that takes over the GrOpsTask.
    GrOpsTask(GrDrawingManager*, GrRecordingContext::Arenas, GrSurfaceProxyView, GrAuditTrail*);
    ~GrOpsTask() override;

    GrOpsTask* asOpsTask() override { return this; }

    bool isEmpty() const { return fOpChains.empty(); }

    /**
     * Empties the draw buffer of any queued up draws.
     */
    void endFlush(GrDrawingManager*) override;

    void onPrePrepare(GrRecordingContext*) override;
    /**
     * Together these two functions flush all queued up draws to GrCommandBuffer. The return value
     * of onExecute() indicates whether any commands were actually issued to the GPU.
     */
    void onPrepare(GrOpFlushState* flushState) override;
    bool onExecute(GrOpFlushState* flushState) override;

    void addSampledTexture(GrSurfaceProxy* proxy) {
        // This function takes a GrSurfaceProxy because all subsequent uses of the proxy do not
        // require the specifics of GrTextureProxy, so this avoids a number of unnecessary virtual
        // asTextureProxy() calls. However, sampling the proxy implicitly requires that the proxy
        // be a texture. Eventually, when proxies are a unified type with flags, this can just
        // assert that capability.
        SkASSERT(proxy->asTextureProxy());
        fSampledProxies.push_back(proxy);
    }

    void addOp(GrDrawingManager*, GrOp::Owner, GrTextureResolveManager, const GrCaps&);

    void addDrawOp(GrDrawingManager*, GrOp::Owner, const GrProcessorSet::Analysis&,
                   GrAppliedClip&&, const DstProxyView&, GrTextureResolveManager, const GrCaps&);

    void discard();

    enum class CanDiscardPreviousOps : bool {
        kYes = true,
        kNo = false
    };

    // Perform book-keeping for a fullscreen clear, regardless of how the clear is implemented later
    // (i.e. setColorLoadOp(), adding a ClearOp, or adding a GrFillRectOp that covers the device).
    // Returns true if the clear can be converted into a load op (barring device caps).
    bool resetForFullscreenClear(CanDiscardPreviousOps);

    // Must only be called if native color buffer clearing is enabled.
    void setColorLoadOp(GrLoadOp op, std::array<float, 4> color = {0, 0, 0, 0});

    // Merge as many opsTasks as possible from the head of 'tasks'. They should all be
    // renderPass compatible. Return the number of tasks merged into 'this'.
    int mergeFrom(SkSpan<const sk_sp<GrRenderTask>> tasks);

#ifdef SK_DEBUG
    int numClips() const override { return fNumClips; }
    void visitProxies_debugOnly(const GrOp::VisitProxyFunc&) const override;
#endif

#if GR_TEST_UTILS
    void dump(const SkString& label,
              SkString indent,
              bool printDependencies,
              bool close) const override;
    const char* name() const final { return "Ops"; }
    int numOpChains() const { return fOpChains.count(); }
    const GrOp* getChain(int index) const { return fOpChains[index].head(); }
#endif

private:
    bool isNoOp() const {
        // TODO: GrLoadOp::kDiscard (i.e., storing a discard) should also be grounds for skipping
        // execution. We currently don't because of Vulkan. See http://skbug.com/9373.
        //
        // TODO: We should also consider stencil load/store here. We get away with it for now
        // because we never discard stencil buffers.
        return fOpChains.empty() && GrLoadOp::kLoad == fColorLoadOp;
    }

    void deleteOps();

    enum class StencilContent {
        kDontCare,
        kUserBitsCleared,  // User bits: cleared
                           // Clip bit: don't care (Ganesh always pre-clears the clip bit.)
        kPreserved
    };

    // Lets the caller specify what the content of the stencil buffer should be at the beginning
    // of the render pass.
    //
    // When requesting kClear: Tilers will load the stencil buffer with a "clear" op; non-tilers
    // will clear the stencil on first load, and then preserve it on subsequent loads. (Preserving
    // works because renderTargetContexts are required to leave the user bits in a cleared state
    // once finished.)
    //
    // NOTE: initialContent must not be kClear if caps.performStencilClearsAsDraws() is true.
    void setInitialStencilContent(StencilContent initialContent) {
        fInitialStencilContent = initialContent;
    }

    // If a surfaceDrawContext splits its opsTask, it uses this method to guarantee stencil values
    // get preserved across its split tasks.
    void setMustPreserveStencil() { fMustPreserveStencil = true; }

    class OpChain {
    public:
        OpChain(GrOp::Owner, GrProcessorSet::Analysis, GrAppliedClip*, const DstProxyView*);
        ~OpChain() {
            // The ops are stored in a GrMemoryPool and must be explicitly deleted via the pool.
            SkASSERT(fList.empty());
        }

        OpChain(const OpChain&) = delete;
        OpChain& operator=(const OpChain&) = delete;
        OpChain(OpChain&&) = default;
        OpChain& operator=(OpChain&&) = default;

        void visitProxies(const GrOp::VisitProxyFunc&) const;

        GrOp* head() const { return fList.head(); }

        GrAppliedClip* appliedClip() const { return fAppliedClip; }
        const DstProxyView& dstProxyView() const { return fDstProxyView; }
        const SkRect& bounds() const { return fBounds; }

        // Deletes all the ops in the chain.
        void deleteOps();

        // Attempts to move the ops from the passed chain to this chain at the head. Also attempts
        // to merge ops between the chains. Upon success the passed chain is empty.
        // Fails when the chains aren't of the same op type, have different clips or dst proxies.
        bool prependChain(OpChain*, const GrCaps&, GrRecordingContext::Arenas*, GrAuditTrail*);

        // Attempts to add 'op' to this chain either by merging or adding to the tail. Returns
        // 'op' to the caller upon failure, otherwise null. Fails when the op and chain aren't of
        // the same op type, have different clips or dst proxies.
        GrOp::Owner appendOp(GrOp::Owner op, GrProcessorSet::Analysis,
                             const DstProxyView*, const GrAppliedClip*, const GrCaps&,
                             GrRecordingContext::Arenas*, GrAuditTrail*);

        void setSkipExecuteFlag() { fSkipExecute = true; }
        bool shouldExecute() const {
            return SkToBool(this->head()) && !fSkipExecute;
        }

    private:
        class List {
        public:
            List() = default;
            List(GrOp::Owner);
            List(List&&);
            List& operator=(List&& that);

            bool empty() const { return !SkToBool(fHead); }
            GrOp* head() const { return fHead.get(); }
            GrOp* tail() const { return fTail; }

            GrOp::Owner popHead();
            GrOp::Owner removeOp(GrOp* op);
            void pushHead(GrOp::Owner op);
            void pushTail(GrOp::Owner);

            void validate() const;

        private:
            GrOp::Owner fHead{nullptr};
            GrOp* fTail{nullptr};
        };

        void validate() const;

        bool tryConcat(List*, GrProcessorSet::Analysis, const DstProxyView&, const GrAppliedClip*,
                       const SkRect& bounds, const GrCaps&, GrRecordingContext::Arenas*,
                       GrAuditTrail*);
        static List DoConcat(List, List, const GrCaps&, GrRecordingContext::Arenas*, GrAuditTrail*);

        List fList;
        GrProcessorSet::Analysis fProcessorAnalysis;
        DstProxyView fDstProxyView;
        GrAppliedClip* fAppliedClip;
        SkRect fBounds;

        // We set this flag to true if any of the ops' proxies fail to instantiate so that we know
        // not to try and draw the op.
        bool fSkipExecute = false;
    };


    bool onIsUsed(GrSurfaceProxy*) const override;

    void handleInternalAllocationFailure() override;

    void gatherProxyIntervals(GrResourceAllocator*) const override;

    void recordOp(GrOp::Owner, GrProcessorSet::Analysis, GrAppliedClip*,
                  const DstProxyView*, const GrCaps&);

    void forwardCombine(const GrCaps&);

    ExpectedOutcome onMakeClosed(const GrCaps& caps, SkIRect* targetUpdateBounds) override;

    // Remove all ops, proxies, etc. Used in the merging algorithm when tasks can be skipped.
    void reset();

    friend class OpsTaskTestingAccess;

    // The RTC and OpsTask have to work together to handle buffer clears. In most cases, buffer
    // clearing can be done natively, in which case the op list's load ops are sufficient. In other
    // cases, draw ops must be used, which makes the RTC the best place for those decisions. This,
    // however, requires that the RTC be able to coordinate with the op list to achieve similar ends
    friend class GrSurfaceDrawContext;

    // This is a backpointer to the Arenas that holds the memory for this GrOpsTask's ops. In the
    // DDL case, the Arenas must have been detached from the original recording context and moved
    // into the owning DDL.
    GrRecordingContext::Arenas fArenas;
    GrAuditTrail*              fAuditTrail;

    GrSwizzle fTargetSwizzle;
    GrSurfaceOrigin fTargetOrigin;

    GrLoadOp fColorLoadOp = GrLoadOp::kLoad;
    std::array<float, 4> fLoadClearColor = {0, 0, 0, 0};
    StencilContent fInitialStencilContent = StencilContent::kDontCare;
    bool fMustPreserveStencil = false;

    uint32_t fLastClipStackGenID = SK_InvalidUniqueID;
    SkIRect fLastDevClipBounds;
    int fLastClipNumAnalyticElements;

    GrXferBarrierFlags fRenderPassXferBarriers = GrXferBarrierFlags::kNone;

    // For ops/opsTask we have mean: 5 stdDev: 28
    SkSTArray<25, OpChain> fOpChains;

    // MDB TODO: 4096 for the first allocation of the clip space will be huge overkill.
    // Gather statistics to determine the correct size.
    // TODO: Move the clips onto the recordTimeAllocator after CCPR is removed.
    SkSTArray<1, std::unique_ptr<SkArenaAlloc>> fClipAllocators;
    SkDEBUGCODE(int fNumClips;)

    // TODO: We could look into this being a set if we find we're adding a lot of duplicates that is
    // causing slow downs.
    SkTArray<GrSurfaceProxy*, true> fSampledProxies;

    SkRect fTotalBounds = SkRect::MakeEmpty();
    SkIRect fClippedContentBounds = SkIRect::MakeEmpty();
};

#endif
