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 | |
16 | class GrAtlasManager; |
17 | class GrGpu; |
18 | class GrStrikeCache; |
19 | class 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 | */ |
28 | class GrTextStrike : public SkNVRefCnt<GrTextStrike> { |
29 | public: |
30 | GrTextStrike(const SkDescriptor& fontScalerKey); |
31 | |
32 | GrGlyph* getGlyph(SkPackedGlyphID); |
33 | |
34 | private: |
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 | */ |
56 | class GrStrikeCache { |
57 | public: |
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 | |
73 | private: |
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 |