* 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_StrikeCache_DEFINED
#define sktext_gpu_StrikeCache_DEFINED
#include "include/core/SkRefCnt.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTHash.h"
#include "src/gpu/AtlasTypes.h"
#include <cstddef>
#include <cstdint>
struct SkPackedGlyphID;
#ifndef SK_DEFAULT_GPU_FONT_CACHE_COUNT_LIMIT
#define SK_DEFAULT_GPU_FONT_CACHE_COUNT_LIMIT 2048
#endif
#ifndef SK_DEFAULT_GPU_FONT_CACHE_LIMIT
#define SK_DEFAULT_GPU_FONT_CACHE_LIMIT (2 * 1024 * 1024)
#endif
namespace sktext::gpu {
class Glyph;
struct GlyphEntryKey;
class StrikeCache;
class TextStrike : public SkNVRefCnt<TextStrike> {
public:
TextStrike(StrikeCache* strikeCache,
const SkStrikeSpec& strikeSpec);
Glyph* getGlyph(SkPackedGlyphID, skgpu::MaskFormat format);
const SkStrikeSpec& strikeSpec() const { return fStrikeSpec; }
const SkDescriptor& getDescriptor() const { return fStrikeSpec.descriptor(); }
private:
StrikeCache* const fStrikeCache;
const SkStrikeSpec fStrikeSpec;
struct HashTraits {
static const GlyphEntryKey& GetKey(const Glyph* glyph);
static uint32_t Hash(GlyphEntryKey key);
};
skia_private::THashTable<Glyph*, GlyphEntryKey, HashTraits> fCache;
SkArenaAlloc fAlloc{512};
TextStrike* fNext{nullptr};
TextStrike* fPrev{nullptr};
size_t fMemoryUsed{sizeof(TextStrike)};
bool fRemoved{false};
friend class StrikeCache;
};
class StrikeCache {
public:
~StrikeCache();
sk_sp<TextStrike> findOrCreateStrike(const SkStrikeSpec& strikeSpec);
void freeAll();
private:
friend class TextStrike;
sk_sp<TextStrike> internalFindStrikeOrNull(const SkDescriptor& desc);
sk_sp<TextStrike> generateStrike(const SkStrikeSpec& strikeSpec);
void internalRemoveStrike(TextStrike* strike);
void internalAttachToHead(sk_sp<TextStrike> strike);
size_t internalPurge(size_t minBytesNeeded = 0);
void validate() const;
TextStrike* fHead{nullptr};
TextStrike* fTail{nullptr};
struct HashTraits {
static const SkDescriptor& GetKey(const sk_sp<TextStrike>& strike);
static uint32_t Hash(const SkDescriptor& strikeSpec);
};
using StrikeHash = skia_private::THashTable<sk_sp<TextStrike>, const SkDescriptor&, HashTraits>;
StrikeHash fCache;
size_t fCacheSizeLimit{SK_DEFAULT_GPU_FONT_CACHE_LIMIT};
size_t fTotalMemoryUsed{0};
int32_t fCacheCountLimit{SK_DEFAULT_GPU_FONT_CACHE_COUNT_LIMIT};
int32_t fCacheCount{0};
};
}
#endif