• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2010 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 
11 #ifndef GrTextStrike_DEFINED
12 #define GrTextStrike_DEFINED
13 
14 #include "GrAllocPool.h"
15 #include "GrFontScaler.h"
16 #include "SkTDynamicHash.h"
17 #include "GrGlyph.h"
18 #include "GrDrawTarget.h"
19 #include "GrAtlas.h"
20 
21 class GrFontCache;
22 class GrGpu;
23 class GrFontPurgeListener;
24 
25 /**
26  *  The textcache maps a hostfontscaler instance to a dictionary of
27  *  glyphid->strike
28  */
29 class GrTextStrike {
30 public:
31     GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey, GrMaskFormat, GrAtlas*);
32     ~GrTextStrike();
33 
getFontScalerKey()34     const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
getFontCache()35     GrFontCache* getFontCache() const { return fFontCache; }
getMaskFormat()36     GrMaskFormat getMaskFormat() const { return fMaskFormat; }
getTexture()37     GrTexture*   getTexture() const { return fAtlas->getTexture(); }
38 
39     inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
40     // returns true if glyph (or glyph+padding for distance field)
41     // is too large to ever fit in texture atlas subregions (GrPlots)
42     bool glyphTooLargeForAtlas(GrGlyph*);
43     // returns true if glyph successfully added to texture atlas, false otherwise
44     bool addGlyphToAtlas(GrGlyph*, GrFontScaler*);
45 
46     // testing
countGlyphs()47     int countGlyphs() const { return fCache.count(); }
48 
49     // remove any references to this plot
50     void removePlot(const GrPlot* plot);
51 
GetKey(const GrTextStrike & ts)52     static const GrFontDescKey& GetKey(const GrTextStrike& ts) {
53         return *(ts.fFontScalerKey);
54     }
Hash(const GrFontDescKey & key)55     static uint32_t Hash(const GrFontDescKey& key) {
56         return key.getHash();
57     }
58 
59 public:
60     // for easy removal from list
61     GrTextStrike*   fPrev;
62     GrTextStrike*   fNext;
63 
64 private:
65     SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
66     const GrFontDescKey* fFontScalerKey;
67     GrTAllocPool<GrGlyph> fPool;
68 
69     GrFontCache*    fFontCache;
70     GrAtlas*        fAtlas;
71     GrMaskFormat    fMaskFormat;
72     bool            fUseDistanceField;
73 
74     GrAtlas::ClientPlotUsage fPlotUsage;
75 
76     GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
77 
78     friend class GrFontCache;
79 };
80 
81 class GrFontCache {
82 public:
83     GrFontCache(GrGpu*);
84     ~GrFontCache();
85 
86     inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField);
87 
88     void freeAll();
89 
90     // make an unused plot available
91     bool freeUnusedPlot(GrTextStrike* preserveStrike);
92 
93     // testing
countStrikes()94     int countStrikes() const { return fCache.count(); }
getHeadStrike()95     GrTextStrike* getHeadStrike() const { return fHead; }
96 
updateTextures()97     void updateTextures() {
98         for (int i = 0; i < kAtlasCount; ++i) {
99             if (fAtlases[i]) {
100                 fAtlases[i]->uploadPlotsToTexture();
101             }
102         }
103     }
104 
105 #ifdef SK_DEBUG
106     void validate() const;
107 #else
validate()108     void validate() const {}
109 #endif
110 
111     void dump() const;
112 
113     enum AtlasType {
114         kA8_AtlasType,   //!< 1-byte per pixel
115         k565_AtlasType,  //!< 2-bytes per pixel
116         k8888_AtlasType, //!< 4-bytes per pixel
117 
118         kLast_AtlasType = k8888_AtlasType
119     };
120     static const int kAtlasCount = kLast_AtlasType + 1;
121 
122 private:
123     friend class GrFontPurgeListener;
124 
125     SkTDynamicHash<GrTextStrike, GrFontDescKey> fCache;
126     // for LRU
127     GrTextStrike* fHead;
128     GrTextStrike* fTail;
129 
130     GrGpu*      fGpu;
131     GrAtlas*    fAtlases[kAtlasCount];
132 
133     GrTextStrike* generateStrike(GrFontScaler*);
134     inline void detachStrikeFromList(GrTextStrike*);
135     void purgeStrike(GrTextStrike* strike);
136 };
137 
138 #endif
139