/*
 * 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 GrBatchFontCache_DEFINED
#define GrBatchFontCache_DEFINED

#include "GrBatchAtlas.h"
#include "GrFontScaler.h"
#include "GrGlyph.h"
#include "SkGlyph.h"
#include "SkTDynamicHash.h"
#include "SkVarAlloc.h"

class GrBatchFontCache;
class GrGpu;

/**
 *  The GrBatchTextStrike manages a pool of CPU backing memory for GrGlyphs.  This backing memory
 *  is indexed by a PackedID and GrFontScaler.  The GrFontScaler is what actually creates the mask.
 */
class GrBatchTextStrike : public SkNVRefCnt<GrBatchTextStrike> {
public:
    GrBatchTextStrike(GrBatchFontCache*, const GrFontDescKey* fontScalerKey);
    ~GrBatchTextStrike();

    const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
    GrBatchFontCache* getBatchFontCache() const { return fBatchFontCache; }

    inline GrGlyph* getGlyph(const SkGlyph& skGlyph, GrGlyph::PackedID packed,
                             GrFontScaler* scaler) {
        GrGlyph* glyph = fCache.find(packed);
        if (nullptr == glyph) {
            glyph = this->generateGlyph(skGlyph, packed, scaler);
        }
        return glyph;
    }

    // This variant of the above function is called by TextBatch.  At this point, it is possible
    // that the maskformat of the glyph differs from what we expect.  In these cases we will just
    // draw a clear square.
    // skbug:4143 crbug:510931
    inline GrGlyph* getGlyph(GrGlyph::PackedID packed,
                             GrMaskFormat expectedMaskFormat,
                             GrFontScaler* scaler) {
        GrGlyph* glyph = fCache.find(packed);
        if (nullptr == glyph) {
            // We could return this to the caller, but in practice it adds code complexity for
            // potentially little benefit(ie, if the glyph is not in our font cache, then its not
            // in the atlas and we're going to be doing a texture upload anyways).
            const SkGlyph& skGlyph = scaler->grToSkGlyph(packed);
            glyph = this->generateGlyph(skGlyph, packed, scaler);
            glyph->fMaskFormat = expectedMaskFormat;
        }
        return glyph;
    }

    // returns true if glyph successfully added to texture atlas, false otherwise.  If the glyph's
    // mask format has changed, then addGlyphToAtlas will draw a clear box.  This will almost never
    // happen.
    // TODO we can handle some of these cases if we really want to, but the long term solution is to
    // get the actual glyph image itself when we get the glyph metrics.
    bool addGlyphToAtlas(GrDrawBatch::Target*, GrGlyph*, GrFontScaler*,
                         GrMaskFormat expectedMaskFormat);

    // testing
    int countGlyphs() const { return fCache.count(); }

    // remove any references to this plot
    void removeID(GrBatchAtlas::AtlasID);

    // If a TextStrike is abandoned by the cache, then the caller must get a new strike
    bool isAbandoned() const { return fIsAbandoned; }

    static const GrFontDescKey& GetKey(const GrBatchTextStrike& ts) {
        return *(ts.fFontScalerKey);
    }
    static uint32_t Hash(const GrFontDescKey& key) {
        return key.getHash();
    }

private:
    SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
    SkAutoTUnref<const GrFontDescKey> fFontScalerKey;
    SkVarAlloc fPool;

    GrBatchFontCache* fBatchFontCache;
    int fAtlasedGlyphs;
    bool fIsAbandoned;

    GrGlyph* generateGlyph(const SkGlyph&, GrGlyph::PackedID, GrFontScaler*);

    friend class GrBatchFontCache;
};

/*
 * GrBatchFontCache manages strikes which are indexed by a GrFontScaler.  These strikes can then be
 * used to individual Glyph Masks.  The GrBatchFontCache also manages GrBatchAtlases, though this is
 * more or less transparent to the client(aside from atlasGeneration, described below).
 * Note - we used to initialize the backing atlas for the GrBatchFontCache at initialization time.
 * However, this caused a regression, even when the GrBatchFontCache was unused.  We now initialize
 * the backing atlases lazily.  Its not immediately clear why this improves the situation.
 */
class GrBatchFontCache {
public:
    GrBatchFontCache(GrContext*);
    ~GrBatchFontCache();
    // The user of the cache may hold a long-lived ref to the returned strike. However, actions by
    // another client of the cache may cause the strike to be purged while it is still reffed.
    // Therefore, the caller must check GrBatchTextStrike::isAbandoned() if there are other
    // interactions with the cache since the strike was received.
    inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) {
        GrBatchTextStrike* strike = fCache.find(*(scaler->getKey()));
        if (nullptr == strike) {
            strike = this->generateStrike(scaler);
        }
        return strike;
    }

    void freeAll();

    // if getTexture returns nullptr, the client must not try to use other functions on the
    // GrBatchFontCache which use the atlas.  This function *must* be called first, before other
    // functions which use the atlas.
    GrTexture* getTexture(GrMaskFormat format) {
        if (this->initAtlas(format)) {
            return this->getAtlas(format)->getTexture();
        }
        return nullptr;
    }

    bool hasGlyph(GrGlyph* glyph) {
        SkASSERT(glyph);
        return this->getAtlas(glyph->fMaskFormat)->hasID(glyph->fID);
    }

    // To ensure the GrBatchAtlas does not evict the Glyph Mask from its texture backing store,
    // the client must pass in the current batch token along with the GrGlyph.
    // A BulkUseTokenUpdater is used to manage bulk last use token updating in the Atlas.
    // For convenience, this function will also set the use token for the current glyph if required
    // NOTE: the bulk uploader is only valid if the subrun has a valid atlasGeneration
    void addGlyphToBulkAndSetUseToken(GrBatchAtlas::BulkUseTokenUpdater* updater,
                                      GrGlyph* glyph, GrBatchToken token) {
        SkASSERT(glyph);
        updater->add(glyph->fID);
        this->getAtlas(glyph->fMaskFormat)->setLastUseToken(glyph->fID, token);
    }

    void setUseTokenBulk(const GrBatchAtlas::BulkUseTokenUpdater& updater,
                         GrBatchToken token,
                         GrMaskFormat format) {
        this->getAtlas(format)->setLastUseTokenBulk(updater, token);
    }

    // add to texture atlas that matches this format
    bool addToAtlas(GrBatchTextStrike* strike, GrBatchAtlas::AtlasID* id,
                    GrDrawBatch::Target* target,
                    GrMaskFormat format, int width, int height, const void* image,
                    SkIPoint16* loc) {
        fPreserveStrike = strike;
        return this->getAtlas(format)->addToAtlas(id, target, width, height, image, loc);
    }

    // Some clients may wish to verify the integrity of the texture backing store of the
    // GrBatchAtlas.  The atlasGeneration returned below is a monitonically increasing number which
    // changes everytime something is removed from the texture backing store.
    uint64_t atlasGeneration(GrMaskFormat format) const {
        return this->getAtlas(format)->atlasGeneration();
    }

    ///////////////////////////////////////////////////////////////////////////
    // Functions intended debug only
    void dump() const;

    void setAtlasSizes_ForTesting(const GrBatchAtlasConfig configs[3]);

private:
    static GrPixelConfig MaskFormatToPixelConfig(GrMaskFormat format) {
        static const GrPixelConfig kPixelConfigs[] = {
            kAlpha_8_GrPixelConfig,
            kRGB_565_GrPixelConfig,
            kSkia8888_GrPixelConfig
        };
        static_assert(SK_ARRAY_COUNT(kPixelConfigs) == kMaskFormatCount, "array_size_mismatch");

        return kPixelConfigs[format];
    }

    // There is a 1:1 mapping between GrMaskFormats and atlas indices
    static int MaskFormatToAtlasIndex(GrMaskFormat format) {
        static const int sAtlasIndices[] = {
            kA8_GrMaskFormat,
            kA565_GrMaskFormat,
            kARGB_GrMaskFormat,
        };
        static_assert(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, "array_size_mismatch");

        SkASSERT(sAtlasIndices[format] < kMaskFormatCount);
        return sAtlasIndices[format];
    }

    bool initAtlas(GrMaskFormat);

    GrBatchTextStrike* generateStrike(GrFontScaler* scaler) {
        GrBatchTextStrike* strike = new GrBatchTextStrike(this, scaler->getKey());
        fCache.add(strike);
        return strike;
    }

    GrBatchAtlas* getAtlas(GrMaskFormat format) const {
        int atlasIndex = MaskFormatToAtlasIndex(format);
        SkASSERT(fAtlases[atlasIndex]);
        return fAtlases[atlasIndex];
    }

    static void HandleEviction(GrBatchAtlas::AtlasID, void*);

    GrContext* fContext;
    SkTDynamicHash<GrBatchTextStrike, GrFontDescKey> fCache;
    GrBatchAtlas* fAtlases[kMaskFormatCount];
    GrBatchTextStrike* fPreserveStrike;
    GrBatchAtlasConfig fAtlasConfigs[kMaskFormatCount];
};

#endif
