OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrBatchFontCache_DEFINED | 8 #ifndef GrBatchFontCache_DEFINED |
9 #define GrBatchFontCache_DEFINED | 9 #define GrBatchFontCache_DEFINED |
10 | 10 |
11 #include "GrBatchAtlas.h" | 11 #include "GrBatchAtlas.h" |
12 #include "GrDrawTarget.h" | 12 #include "GrDrawTarget.h" |
13 #include "GrFontScaler.h" | 13 #include "GrFontScaler.h" |
14 #include "GrGlyph.h" | 14 #include "GrGlyph.h" |
15 #include "SkTDynamicHash.h" | 15 #include "SkTDynamicHash.h" |
16 #include "SkVarAlloc.h" | 16 #include "SkVarAlloc.h" |
17 | 17 |
18 class GrBatchFontCache; | 18 class GrBatchFontCache; |
19 class GrBatchTarget; | 19 class GrBatchTarget; |
20 class GrGpu; | 20 class GrGpu; |
21 | 21 |
22 /** | 22 /** |
23 * The GrBatchTextStrike manages a pool of CPU backing memory for Glyph Masks.
This backing memory | 23 * The GrBatchTextStrike manages a pool of CPU backing memory for Glyph Masks.
This backing memory |
24 * is abstracted by GrGlyph, and indexed by a PackedID and GrFontScaler. The G
rFontScaler is what | 24 * is abstracted by GrGlyph, and indexed by a PackedID and GrFontScaler. The G
rFontScaler is what |
25 * actually creates the mask. | 25 * actually creates the mask. |
26 */ | 26 */ |
27 class GrBatchTextStrike { | 27 class GrBatchTextStrike : public SkNVRefCnt<GrBatchTextStrike> { |
28 public: | 28 public: |
29 GrBatchTextStrike(GrBatchFontCache*, const GrFontDescKey* fontScalerKey); | 29 GrBatchTextStrike(GrBatchFontCache*, const GrFontDescKey* fontScalerKey); |
30 ~GrBatchTextStrike(); | 30 ~GrBatchTextStrike(); |
31 | 31 |
32 const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; } | 32 const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; } |
33 GrBatchFontCache* getBatchFontCache() const { return fBatchFontCache; } | 33 GrBatchFontCache* getBatchFontCache() const { return fBatchFontCache; } |
34 | 34 |
35 inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) { | 35 inline GrGlyph* getGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler) { |
36 GrGlyph* glyph = fCache.find(packed); | 36 GrGlyph* glyph = fCache.find(packed); |
37 if (NULL == glyph) { | 37 if (NULL == glyph) { |
38 glyph = this->generateGlyph(packed, scaler); | 38 glyph = this->generateGlyph(packed, scaler); |
39 } | 39 } |
40 return glyph; | 40 return glyph; |
41 } | 41 } |
42 | 42 |
43 // returns true if glyph (or glyph+padding for distance field) | 43 // returns true if glyph (or glyph+padding for distance field) |
44 // is too large to ever fit in texture atlas subregions (GrPlots) | 44 // is too large to ever fit in texture atlas subregions (GrPlots) |
45 bool glyphTooLargeForAtlas(GrGlyph*); | 45 bool glyphTooLargeForAtlas(GrGlyph*); |
46 // returns true if glyph successfully added to texture atlas, false otherwis
e | 46 // returns true if glyph successfully added to texture atlas, false otherwis
e |
47 bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*); | 47 bool addGlyphToAtlas(GrBatchTarget*, GrGlyph*, GrFontScaler*); |
48 | 48 |
49 // testing | 49 // testing |
50 int countGlyphs() const { return fCache.count(); } | 50 int countGlyphs() const { return fCache.count(); } |
51 | 51 |
52 // remove any references to this plot | 52 // remove any references to this plot |
53 void removeID(GrBatchAtlas::AtlasID); | 53 void removeID(GrBatchAtlas::AtlasID); |
54 | 54 |
| 55 // If a TextStrike is abandoned by the cache, then the caller must get a new
strike |
| 56 bool isAbandoned() const { return fIsAbandoned; } |
| 57 |
55 static const GrFontDescKey& GetKey(const GrBatchTextStrike& ts) { | 58 static const GrFontDescKey& GetKey(const GrBatchTextStrike& ts) { |
56 return *(ts.fFontScalerKey); | 59 return *(ts.fFontScalerKey); |
57 } | 60 } |
58 static uint32_t Hash(const GrFontDescKey& key) { | 61 static uint32_t Hash(const GrFontDescKey& key) { |
59 return key.getHash(); | 62 return key.getHash(); |
60 } | 63 } |
61 | 64 |
62 private: | 65 private: |
63 SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache; | 66 SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache; |
64 SkAutoTUnref<const GrFontDescKey> fFontScalerKey; | 67 SkAutoTUnref<const GrFontDescKey> fFontScalerKey; |
65 SkVarAlloc fPool; | 68 SkVarAlloc fPool; |
66 | 69 |
67 GrBatchFontCache* fBatchFontCache; | 70 GrBatchFontCache* fBatchFontCache; |
68 int fAtlasedGlyphs; | 71 int fAtlasedGlyphs; |
| 72 bool fIsAbandoned; |
69 | 73 |
70 GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler); | 74 GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler); |
71 | 75 |
72 friend class GrBatchFontCache; | 76 friend class GrBatchFontCache; |
73 }; | 77 }; |
74 | 78 |
75 /* | 79 /* |
76 * GrBatchFontCache manages strikes which are indexed by a GrFontScaler. These
strikes can then be | 80 * GrBatchFontCache manages strikes which are indexed by a GrFontScaler. These
strikes can then be |
77 * used to individual Glyph Masks. The GrBatchFontCache also manages GrBatchAtl
ases, though this is | 81 * used to individual Glyph Masks. The GrBatchFontCache also manages GrBatchAtl
ases, though this is |
78 * more or less transparent to the client(aside from atlasGeneration, described
below). | 82 * more or less transparent to the client(aside from atlasGeneration, described
below). |
79 * Note - we used to initialize the backing atlas for the GrBatchFontCache at in
itialization time. | 83 * Note - we used to initialize the backing atlas for the GrBatchFontCache at in
itialization time. |
80 * However, this caused a regression, even when the GrBatchFontCache was unused.
We now initialize | 84 * However, this caused a regression, even when the GrBatchFontCache was unused.
We now initialize |
81 * the backing atlases lazily. Its not immediately clear why this improves the
situation. | 85 * the backing atlases lazily. Its not immediately clear why this improves the
situation. |
82 */ | 86 */ |
83 class GrBatchFontCache { | 87 class GrBatchFontCache { |
84 public: | 88 public: |
85 GrBatchFontCache(GrContext*); | 89 GrBatchFontCache(GrContext*); |
86 ~GrBatchFontCache(); | 90 ~GrBatchFontCache(); |
87 | 91 // The user of the cache may hold a long-lived ref to the returned strike. H
owever, actions by |
| 92 // another client of the cache may cause the strike to be purged while it is
still reffed. |
| 93 // Therefore, the caller must check GrBatchTextStrike::isAbandoned() if ther
e are other |
| 94 // interactions with the cache since the strike was received. |
88 inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) { | 95 inline GrBatchTextStrike* getStrike(GrFontScaler* scaler) { |
89 GrBatchTextStrike* strike = fCache.find(*(scaler->getKey())); | 96 GrBatchTextStrike* strike = fCache.find(*(scaler->getKey())); |
90 if (NULL == strike) { | 97 if (NULL == strike) { |
91 strike = this->generateStrike(scaler); | 98 strike = this->generateStrike(scaler); |
92 } | 99 } |
93 return strike; | 100 return strike; |
94 } | 101 } |
95 | 102 |
96 void freeAll(); | 103 void freeAll(); |
97 | 104 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 185 |
179 static void HandleEviction(GrBatchAtlas::AtlasID, void*); | 186 static void HandleEviction(GrBatchAtlas::AtlasID, void*); |
180 | 187 |
181 GrContext* fContext; | 188 GrContext* fContext; |
182 SkTDynamicHash<GrBatchTextStrike, GrFontDescKey> fCache; | 189 SkTDynamicHash<GrBatchTextStrike, GrFontDescKey> fCache; |
183 GrBatchAtlas* fAtlases[kMaskFormatCount]; | 190 GrBatchAtlas* fAtlases[kMaskFormatCount]; |
184 GrBatchTextStrike* fPreserveStrike; | 191 GrBatchTextStrike* fPreserveStrike; |
185 }; | 192 }; |
186 | 193 |
187 #endif | 194 #endif |
OLD | NEW |