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

#ifndef sktext_gpu_TextBlobRedrawCoordinator_DEFINED
#define sktext_gpu_TextBlobRedrawCoordinator_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkThreadAnnotations.h"
#include "src/base/SkSpinlock.h"
#include "src/base/SkTInternalLList.h"
#include "src/core/SkMessageBus.h"
#include "src/core/SkTHash.h"
#include "src/text/gpu/SubRunContainer.h"
#include "src/text/gpu/TextBlob.h"

#include <cstddef>
#include <cstdint>

class GrTextBlobTestingPeer;
class SkCanvas;
class SkMatrix;
class SkPaint;
struct SkStrikeDeviceInfo;

namespace sktext { class GlyphRunList; }

namespace sktext::gpu {

// TextBlobRedrawCoordinator reuses data from previous drawing operations using multiple criteria
// to pick the best data for the draw. In addition, it provides a central service for managing
// resource usage through a messageBus.
// The draw data is stored in a three-tiered system. The first tier is keyed by the SkTextBlob's
// uniqueID. The second tier uses the sktext::gpu::TextBlob's key to get a general match for the
// draw. The last tier queries each sub run using canReuse to determine if each sub run can handle
// the drawing parameters.
class TextBlobRedrawCoordinator {
public:
    TextBlobRedrawCoordinator(uint32_t messageBusID);

    void drawGlyphRunList(SkCanvas* canvas,
                          const SkMatrix& viewMatrix,
                          const GlyphRunList& glyphRunList,
                          const SkPaint& paint,
                          SkStrikeDeviceInfo strikeDeviceInfo,
                          const AtlasDrawDelegate&);

    void freeAll() SK_EXCLUDES(fSpinLock);

    struct PurgeBlobMessage {
        PurgeBlobMessage(uint32_t blobID, uint32_t contextUniqueID)
                : fBlobID(blobID), fContextID(contextUniqueID) {}

        uint32_t fBlobID;
        uint32_t fContextID;
    };

    void purgeStaleBlobs() SK_EXCLUDES(fSpinLock);

    size_t usedBytes() const SK_EXCLUDES(fSpinLock);

    bool isOverBudget() const SK_EXCLUDES(fSpinLock);

private:
    friend class ::GrTextBlobTestingPeer;
    using TextBlobList = SkTInternalLList<TextBlob>;

    struct BlobIDCacheEntry {
        BlobIDCacheEntry();
        explicit BlobIDCacheEntry(uint32_t id);

        static uint32_t GetKey(const BlobIDCacheEntry& entry);

        void addBlob(sk_sp<TextBlob> blob);

        void removeBlob(TextBlob* blob);

        sk_sp<TextBlob> find(const TextBlob::Key& key) const;

        int findBlobIndex(const TextBlob::Key& key) const;

        uint32_t fID;
        // Current clients don't generate multiple GrAtlasTextBlobs per SkTextBlob, so an array w/
        // linear search is acceptable.  If usage changes, we should re-evaluate this structure.
        skia_private::STArray<1, sk_sp<TextBlob>> fBlobs;
    };

    sk_sp<TextBlob> findOrCreateBlob(const SkMatrix& positionMatrix,
                                     const GlyphRunList& glyphRunList,
                                     const SkPaint& paint,
                                     SkStrikeDeviceInfo strikeDeviceInfo);

    // If not already in the cache, then add it else, return the text blob from the cache.
    sk_sp<TextBlob> addOrReturnExisting(
            const GlyphRunList& glyphRunList,
            sk_sp<TextBlob> blob) SK_EXCLUDES(fSpinLock);

    sk_sp<TextBlob> find(const TextBlob::Key& key) SK_EXCLUDES(fSpinLock);

    void remove(TextBlob* blob) SK_EXCLUDES(fSpinLock);

    void internalPurgeStaleBlobs() SK_REQUIRES(fSpinLock);

    sk_sp<TextBlob>
            internalAdd(sk_sp<TextBlob> blob) SK_REQUIRES(fSpinLock);
    void internalRemove(TextBlob* blob) SK_REQUIRES(fSpinLock);

    void internalCheckPurge(TextBlob* blob = nullptr) SK_REQUIRES(fSpinLock);

    static const int kDefaultBudget = 1 << 22;

    mutable SkSpinlock fSpinLock;
    TextBlobList fBlobList SK_GUARDED_BY(fSpinLock);
    skia_private::THashMap<uint32_t, BlobIDCacheEntry> fBlobIDCache SK_GUARDED_BY(fSpinLock);
    size_t fSizeBudget SK_GUARDED_BY(fSpinLock);
    size_t fCurrentSize SK_GUARDED_BY(fSpinLock) {0};

    // In practice 'messageBusID' is always the unique ID of the owning GrContext
    const uint32_t fMessageBusID;
    SkMessageBus<PurgeBlobMessage, uint32_t>::Inbox fPurgeBlobInbox SK_GUARDED_BY(fSpinLock);
};

}  // namespace sktext::gpu

#endif  // sktext_gpu_TextBlobRedrawCoordinator_DEFINED
