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

#ifndef SmallPathAtlasMgr_DEFINED
#define SmallPathAtlasMgr_DEFINED

#include "src/core/SkTDynamicHash.h"
#include "src/core/SkTInternalLList.h"
#include "src/gpu/ganesh/GrDrawOpAtlas.h"
#include "src/gpu/ganesh/GrOnFlushResourceProvider.h"

class GrStyledShape;

namespace skgpu::v1 {

class SmallPathShapeData;
class SmallPathShapeDataKey;

/**
 * This class manages the small path renderer's atlas. It solely operates at flush time. Thus
 * the small path renderer will generate ops at record time but the location of the ops' source
 * data and even the number of proxies to be used will not be determined until the recorded
 * DAGs/DDLs are (re)played.
 *
 * TODO: investigate fusing this class and the GrAtlasManager.
 */
class SmallPathAtlasMgr final : public GrOnFlushCallbackObject,
                                public skgpu::PlotEvictionCallback,
                                public skgpu::AtlasGenerationCounter {
public:
    SmallPathAtlasMgr();
    ~SmallPathAtlasMgr() override;

    void reset();

    bool initAtlas(GrProxyProvider*, const GrCaps*);

    SmallPathShapeData* findOrCreate(const GrStyledShape&, int desiredDimension);
    SmallPathShapeData* findOrCreate(const GrStyledShape&, const SkMatrix& ctm);

    GrDrawOpAtlas::ErrorCode addToAtlas(GrResourceProvider*,
                                        GrDeferredUploadTarget*,
                                        int width, int height, const void* image,
                                        skgpu::AtlasLocator*);

    void setUseToken(SmallPathShapeData*, GrDeferredUploadToken);

    // GrOnFlushCallbackObject overrides
    bool preFlush(GrOnFlushResourceProvider* onFlushRP) override {
#if GR_TEST_UTILS
        if (onFlushRP->failFlushTimeCallbacks()) {
            return false;
        }
#endif

        if (fAtlas) {
            fAtlas->instantiate(onFlushRP);
        }
        return true;
    }

    void postFlush(GrDeferredUploadToken startTokenForNextFlush) override {
        if (fAtlas) {
            fAtlas->compact(startTokenForNextFlush);
        }
    }

    // This object has the same lifetime as the GrContext so we want it to survive freeGpuResources
    // calls
    bool retainOnFreeGpuResources() override { return true; }

    const GrSurfaceProxyView* getViews(int* numActiveProxies) {
        *numActiveProxies = fAtlas->numActivePages();
        return fAtlas->getViews();
    }

    void deleteCacheEntry(SmallPathShapeData*);

private:
    SmallPathShapeData* findOrCreate(const SmallPathShapeDataKey&);

    void evict(skgpu::PlotLocator) override;

    using ShapeCache = SkTDynamicHash<SmallPathShapeData, SmallPathShapeDataKey>;
    typedef SkTInternalLList<SmallPathShapeData> ShapeDataList;

    std::unique_ptr<GrDrawOpAtlas> fAtlas;
    ShapeCache                     fShapeCache;
    ShapeDataList                  fShapeList;
};

} // namespace skgpu::v1

#endif // SmallPathAtlasMgr_DEFINED
