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

#ifndef AtlasPathRenderer_DEFINED
#define AtlasPathRenderer_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/private/base/SkTArray.h"
#include "src/core/SkChecksum.h"
#include "src/core/SkIPoint16.h"
#include "src/core/SkTHash.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrOnFlushResourceProvider.h"
#include "src/gpu/ganesh/PathRenderer.h"
#include "src/gpu/ganesh/ops/AtlasRenderTask.h"

#include <cstdint>
#include <cstring>
#include <functional>
#include <memory>

class GrDirectContext;
class GrOp;
class GrRecordingContext;
class GrStyledShape;
class GrSurfaceProxy;
class SkMatrix;
class SkPath;
enum class GrAAType : unsigned int;
struct SkIRect;
struct SkRect;

namespace skgpu::ganesh {

class SurfaceDrawContext;

// Draws paths by first rendering their coverage mask into an offscreen atlas.
class AtlasPathRenderer final : public PathRenderer, public GrOnFlushCallbackObject {
public:
    static bool IsSupported(GrRecordingContext*);

    // Returns a GrAtlasPathRenderer if it is supported, otherwise null.
    static sk_sp<AtlasPathRenderer> Make(GrRecordingContext* rContext);

    const char* name() const override { return "GrAtlasPathRenderer"; }

    // Returns a fragment processor that modulates inputFP by the given deviceSpacePath's coverage,
    // implemented using an internal atlas.
    //
    // Returns 'inputFP' wrapped in GrFPFailure() if the path was too large, or if the current atlas
    // is full and already used by either opBeingClipped or inputFP. (Currently, "too large" means
    // larger than fMaxAtlasSize in either dimension, more than 256^2 total pixels, or more than
    // 128^2 total pixels if the surfaceDrawContext supports MSAA or DMSAA.)
    //
    // Also returns GrFPFailure() if the view matrix has perspective.
    GrFPResult makeAtlasClipEffect(const skgpu::ganesh::SurfaceDrawContext*,
                                   const GrOp* opBeingClipped,
                                   std::unique_ptr<GrFragmentProcessor> inputFP,
                                   const SkIRect& drawBounds,
                                   const SkMatrix&,
                                   const SkPath&);

private:
    // The atlas is not compatible with DDL. We can only use it on direct contexts.
    AtlasPathRenderer(GrDirectContext*);

    StencilSupport onGetStencilSupport(const GrStyledShape&) const override {
        return kNoSupport_StencilSupport;
    }

    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;

    bool onDrawPath(const DrawPathArgs&) override;

    // Returns true if the given device-space path bounds are small enough to fit in an atlas and to
    // benefit from atlasing. (Currently, "small enough" means no larger than fMaxAtlasSize in
    // either dimension, no more than 256^2 total pixels, or no more than 128^2 total pixels if the
    // fallbackAAType is kMSAA.)
    bool pathFitsInAtlas(const SkRect& pathDevBounds, GrAAType fallbackAAType) const;

    // Returns true if the draw being set up already uses the given atlasProxy.
    using DrawRefsAtlasCallback = std::function<bool(const GrSurfaceProxy* atlasProxy)>;

    // Adds the filled path to an atlas.
    //
    // pathFitsInAtlas() and is_visible() both must have returned true before making this call.
    //
    // Fails and returns false if the current atlas is full and already in use according to
    // DrawRefsAtlasCallback.
    bool addPathToAtlas(GrRecordingContext*,
                        const SkMatrix&,
                        const SkPath&,
                        const SkRect& pathDevBounds,
                        SkIRect* devIBounds,
                        SkIPoint16* locationInAtlas,
                        bool* transposedInAtlas,
                        const DrawRefsAtlasCallback&);

    // Instantiates texture(s) for all atlases we've created since the last flush. Atlases that are
    // the same size will be instantiated with the same backing texture.
    bool preFlush(GrOnFlushResourceProvider*) override;

    float fAtlasMaxSize = 0;
    float fAtlasMaxPathWidth = 0;
    int fAtlasInitialSize = 0;

    // A collection of all atlases we've created and used since the last flush. We instantiate these
    // at flush time during preFlush().
    skia_private::STArray<4, sk_sp<AtlasRenderTask>> fAtlasRenderTasks;

    // This simple cache remembers the locations of cacheable path masks in the most recent atlas.
    // Its main motivation is for clip paths.
    struct AtlasPathKey {
        void set(const SkMatrix&, const SkPath&);
        bool operator==(const AtlasPathKey& k) const {
            static_assert(sizeof(*this) == sizeof(uint32_t) * 8);
            return !memcmp(this, &k, sizeof(*this));
        }
        uint32_t fPathGenID;
        float fAffineMatrix[6];
        uint32_t fFillRule;

        using Hash = SkForceDirectHash<AtlasPathKey>;
    };

    skia_private::THashMap<AtlasPathKey, SkIPoint16, AtlasPathKey::Hash> fAtlasPathCache;
};

}  // namespace skgpu::ganesh

#endif // GrAtlasPathRenderer_DEFINED
