/*
 * Copyright 2020 Google LLC
 *
 * 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 "include/core/SkTypes.h"

#if !defined(SK_ENABLE_OPTIMIZE_SIZE)

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

#include <memory>

class GrCaps;
class GrDeferredUploadTarget;
class GrProxyProvider;
class GrResourceProvider;
class GrStyledShape;
class GrSurfaceProxyView;
class SkMatrix;

namespace skgpu::ganesh {

/**
 * 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 GrPlotEvictionCallback,
                                public GrAtlasGenerationCounter {
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,
                                        GrAtlasLocator*);

    void setUseToken(SmallPathShapeData*, skgpu::Token);

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

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

    void postFlush(skgpu::Token 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(GrPlotLocator) override;

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

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

}  // namespace skgpu::ganesh

#endif // SK_ENABLE_OPTIMIZE_SIZE

#endif // SmallPathAtlasMgr_DEFINED
