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

#ifndef AtlasRenderTask_DEFINED
#define AtlasRenderTask_DEFINED

#include "include/core/SkPath.h"
#include "src/core/SkTBlockList.h"
#include "src/gpu/GrDynamicAtlas.h"
#include "src/gpu/ops/OpsTask.h"
#include "src/gpu/tessellate/PathTessellator.h"

struct SkIPoint16;

namespace skgpu::v1 {

// Represents a GrRenderTask that draws paths into an atlas. This task gets added the DAG and left
// open, lays out its atlas while future tasks call addPath(), and finally adds its internal draw
// ops during onMakeClosed().
//
// The atlas texture does not get instantiated automatically. It is the creator's responsibility to
// call instantiate() at flush time.
class AtlasRenderTask : public OpsTask {
public:
    AtlasRenderTask(GrRecordingContext*,
                    sk_sp<GrArenas>,
                    std::unique_ptr<GrDynamicAtlas>);

    const GrTextureProxy* atlasProxy() const { return fDynamicAtlas->textureProxy(); }
    GrSurfaceProxyView readView(const GrCaps& caps) const { return fDynamicAtlas->readView(caps); }

    // Allocates a rectangle for, and stages the given path to be rendered into the atlas. Returns
    // false if there was not room in the atlas. On success, writes out the location of the path's
    // upper-left corner to 'locationInAtlas'.
    bool addPath(const SkMatrix&, const SkPath&, SkIPoint pathDevTopLeft, int widthInAtlas,
                 int heightInAtlas, bool transposedInAtlas, SkIPoint16* locationInAtlas);

    // Must be called at flush time. The texture proxy is instantiated with 'backingTexture', if
    // provided. See GrDynamicAtlas.
    void instantiate(GrOnFlushResourceProvider* onFlushRP,
                     sk_sp<GrTexture> backingTexture = nullptr) {
        SkASSERT(this->isClosed());
        fDynamicAtlas->instantiate(onFlushRP, std::move(backingTexture));
    }

private:
    // Adds internal ops to render the atlas before deferring to OpsTask::onMakeClosed.
    ExpectedOutcome onMakeClosed(GrRecordingContext*, SkIRect* targetUpdateBounds) override;

    void stencilAtlasRect(GrRecordingContext*, const SkRect&, const SkPMColor4f&,
                          const GrUserStencilSettings*);
    void addAtlasDrawOp(GrOp::Owner, const GrCaps&);

    // Executes the OpsTask and resolves msaa if needed.
    bool onExecute(GrOpFlushState* flushState) override;

    const std::unique_ptr<GrDynamicAtlas> fDynamicAtlas;

    // Allocate enough inline entries for 16 atlas path draws, then spill to the heap.
    using PathDrawList = PathTessellator::PathDrawList;
    using PathDrawAllocator = SkTBlockList<PathDrawList, 16>;
    PathDrawAllocator fPathDrawAllocator{64, SkBlockAllocator::GrowthPolicy::kFibonacci};

    class AtlasPathList : SkNoncopyable {
    public:
        void add(PathDrawAllocator* alloc, const SkMatrix& pathMatrix, const SkPath& path) {
            fPathDrawList = &alloc->emplace_back(pathMatrix, path, SK_PMColor4fTRANSPARENT,
                                                 fPathDrawList);
            if (path.isInverseFillType()) {
                // The atlas never has inverse paths. The inversion happens later.
                fPathDrawList->fPath.toggleInverseFillType();
            }
            fTotalCombinedPathVerbCnt += path.countVerbs();
            ++fPathCount;
        }
        const PathDrawList* pathDrawList() const { return fPathDrawList; }
        int totalCombinedPathVerbCnt() const { return fTotalCombinedPathVerbCnt; }
        int pathCount() const { return fPathCount; }

    private:
        PathDrawList* fPathDrawList = nullptr;
        int fTotalCombinedPathVerbCnt = 0;
        int fPathCount = 0;
    };

    AtlasPathList fWindingPathList;
    AtlasPathList fEvenOddPathList;
};

} // namespace skgpu::v1

#endif // AtlasRenderTask_DEFINED
