1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrStrikeCache_DEFINED
9#define GrStrikeCache_DEFINED
10
11#include "include/private/SkTHash.h"
12#include "src/core/SkArenaAlloc.h"
13#include "src/core/SkDescriptor.h"
14#include "src/gpu/GrGlyph.h"
15
16class GrAtlasManager;
17class GrGpu;
18class GrStrikeCache;
19class SkBulkGlyphMetricsAndImages;
20
21/**
22 * The GrTextStrike manages a pool of CPU backing memory for GrGlyphs. This backing memory
23 * is indexed by a PackedID and SkStrike. The SkStrike is what actually creates the mask.
24 * The GrTextStrike may outlive the generating SkStrike. However, it retains a copy
25 * of it's SkDescriptor as a key to access (or regenerate) the SkStrike. GrTextStrikes are
26 * created by and owned by a GrStrikeCache.
27 */
28class GrTextStrike : public SkNVRefCnt<GrTextStrike> {
29public:
30 GrTextStrike(const SkDescriptor& fontScalerKey);
31
32 GrGlyph* getGlyph(SkPackedGlyphID);
33
34private:
35 struct HashTraits {
36 // GetKey and Hash for the the hash table.
37 static const SkPackedGlyphID& GetKey(const GrGlyph* glyph) {
38 return glyph->fPackedID;
39 }
40
41 static uint32_t Hash(SkPackedGlyphID key) {
42 return SkChecksum::Mix(key.hash());
43 }
44 };
45 SkTHashTable<GrGlyph*, SkPackedGlyphID, HashTraits> fCache;
46 SkAutoDescriptor fFontScalerKey;
47 SkArenaAlloc fAlloc{512};
48
49 friend class GrStrikeCache;
50};
51
52/**
53 * GrStrikeCache manages strikes which are indexed by a SkStrike. These strikes can then be
54 * used to generate individual Glyph Masks.
55 */
56class GrStrikeCache {
57public:
58 ~GrStrikeCache();
59
60 // The user of the cache may hold a long-lived ref to the returned strike. However, actions by
61 // another client of the cache may cause the strike to be purged while it is still reffed.
62 // Therefore, the caller must check GrTextStrike::isAbandoned() if there are other
63 // interactions with the cache since the strike was received.
64 sk_sp<GrTextStrike> findOrCreateStrike(const SkDescriptor& desc) {
65 if (sk_sp<GrTextStrike>* cached = fCache.find(desc)) {
66 return *cached;
67 }
68 return this->generateStrike(desc);
69 }
70
71 void freeAll();
72
73private:
74 sk_sp<GrTextStrike> generateStrike(const SkDescriptor& desc) {
75 sk_sp<GrTextStrike> strike = sk_make_sp<GrTextStrike>(desc);
76 fCache.set(strike);
77 return strike;
78 }
79
80 struct DescriptorHashTraits {
81 static const SkDescriptor& GetKey(const sk_sp<GrTextStrike>& strike) {
82 return *strike->fFontScalerKey.getDesc();
83 }
84 static uint32_t Hash(const SkDescriptor& desc) { return desc.getChecksum(); }
85 };
86
87 using StrikeHash = SkTHashTable<sk_sp<GrTextStrike>, SkDescriptor, DescriptorHashTraits>;
88
89 StrikeHash fCache;
90};
91
92#endif // GrStrikeCache_DEFINED
93