Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Side by Side Diff: src/gpu/GrTextStrike.cpp

Issue 177463003: New approach for GPU font atlas (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove unnecessary reference to GrAtlasMgr Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrTextStrike.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2010 Google Inc. 2 * Copyright 2010 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 #include "GrAtlas.h" 8 #include "GrAtlas.h"
9 #include "GrGpu.h" 9 #include "GrGpu.h"
10 #include "GrRectanizer.h" 10 #include "GrRectanizer.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 fTail = NULL; 103 fTail = NULL;
104 } 104 }
105 105
106 void GrFontCache::purgeStrike(GrTextStrike* strike) { 106 void GrFontCache::purgeStrike(GrTextStrike* strike) {
107 const GrFontCache::Key key(strike->fFontScalerKey); 107 const GrFontCache::Key key(strike->fFontScalerKey);
108 fCache.remove(key, strike); 108 fCache.remove(key, strike);
109 this->detachStrikeFromList(strike); 109 this->detachStrikeFromList(strike);
110 delete strike; 110 delete strike;
111 } 111 }
112 112
113 void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) { 113 bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
114 SkASSERT(NULL != preserveStrike); 114 SkASSERT(NULL != preserveStrike);
115 GrTextStrike* strike = fTail; 115
116 bool purge = true; 116 GrAtlasMgr* atlasMgr = preserveStrike->fAtlasMgr;
117 GrPlot* plot = atlasMgr->getUnusedPlot();
118 if (NULL == plot) {
119 return false;
120 }
121 plot->resetRects();
122
123 GrTextStrike* strike = fHead;
117 GrMaskFormat maskFormat = preserveStrike->fMaskFormat; 124 GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
118 while (strike) { 125 while (strike) {
119 if (strike == preserveStrike || maskFormat != strike->fMaskFormat) { 126 if (maskFormat != strike->fMaskFormat) {
120 strike = strike->fPrev; 127 strike = strike->fNext;
121 continue; 128 continue;
122 } 129 }
130
123 GrTextStrike* strikeToPurge = strike; 131 GrTextStrike* strikeToPurge = strike;
124 strike = strikeToPurge->fPrev; 132 strike = strikeToPurge->fNext;
125 if (purge) { 133 strikeToPurge->removePlot(plot);
126 // keep purging if we won't free up any atlases with this strike. 134
127 purge = strikeToPurge->fAtlas.isEmpty(); 135 // clear out any empty strikes (except this one)
136 if (strikeToPurge != preserveStrike && strikeToPurge->fAtlas.isEmpty()) {
128 this->purgeStrike(strikeToPurge); 137 this->purgeStrike(strikeToPurge);
129 } 138 }
130 } 139 }
140
131 #if FONT_CACHE_STATS 141 #if FONT_CACHE_STATS
132 ++g_PurgeCount; 142 ++g_PurgeCount;
133 #endif 143 #endif
134 }
135 144
136 void GrFontCache::freePlotExceptFor(GrTextStrike* preserveStrike) { 145 return true;
137 SkASSERT(NULL != preserveStrike);
138 GrTextStrike* strike = fTail;
139 GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
140 while (strike) {
141 if (strike == preserveStrike || maskFormat != strike->fMaskFormat) {
142 strike = strike->fPrev;
143 continue;
144 }
145 GrTextStrike* strikeToPurge = strike;
146 strike = strikeToPurge->fPrev;
147 if (strikeToPurge->removeUnusedPlots()) {
148 if (strikeToPurge->fAtlas.isEmpty()) {
149 this->purgeStrike(strikeToPurge);
150 }
151 break;
152 }
153 }
154 } 146 }
155 147
156 #ifdef SK_DEBUG 148 #ifdef SK_DEBUG
157 void GrFontCache::validate() const { 149 void GrFontCache::validate() const {
158 int count = fCache.count(); 150 int count = fCache.count();
159 if (0 == count) { 151 if (0 == count) {
160 SkASSERT(!fHead); 152 SkASSERT(!fHead);
161 SkASSERT(!fTail); 153 SkASSERT(!fTail);
162 } else if (1 == count) { 154 } else if (1 == count) {
163 SkASSERT(fHead == fTail); 155 SkASSERT(fHead == fTail);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 /* 206 /*
215 The text strike is specific to a given font/style/matrix setup, which is 207 The text strike is specific to a given font/style/matrix setup, which is
216 represented by the GrHostFontScaler object we are given in getGlyph(). 208 represented by the GrHostFontScaler object we are given in getGlyph().
217 209
218 We map a 32bit glyphID to a GrGlyph record, which in turn points to a 210 We map a 32bit glyphID to a GrGlyph record, which in turn points to a
219 atlas and a position within that texture. 211 atlas and a position within that texture.
220 */ 212 */
221 213
222 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 214 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
223 GrMaskFormat format, 215 GrMaskFormat format,
224 GrAtlasMgr* atlasMgr) : fPool(64), fAtlas(atlasMgr) { 216 GrAtlasMgr* atlasMgr) : fPool(64) {
225 fFontScalerKey = key; 217 fFontScalerKey = key;
226 fFontScalerKey->ref(); 218 fFontScalerKey->ref();
227 219
228 fFontCache = cache; // no need to ref, it won't go away before we do 220 fFontCache = cache; // no need to ref, it won't go away before we do
229 fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do 221 fAtlasMgr = atlasMgr; // no need to ref, it won't go away before we do
230 222
231 fMaskFormat = format; 223 fMaskFormat = format;
232 224
233 #ifdef SK_DEBUG 225 #ifdef SK_DEBUG
234 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); 226 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
235 gCounter += 1; 227 gCounter += 1;
236 #endif 228 #endif
237 } 229 }
238 230
239 // these signatures are needed because they're used with 231 // this signature is needed because it's used with
240 // SkTDArray::visitAll() (see destructor & removeUnusedAtlases()) 232 // SkTDArray::visitAll() (see destructor)
241 static void free_glyph(GrGlyph*& glyph) { glyph->free(); } 233 static void free_glyph(GrGlyph*& glyph) { glyph->free(); }
242 234
243 static void invalidate_glyph(GrGlyph*& glyph) {
244 if (glyph->fPlot && glyph->fPlot->drawToken().isIssued()) {
245 glyph->fPlot = NULL;
246 }
247 }
248
249 GrTextStrike::~GrTextStrike() { 235 GrTextStrike::~GrTextStrike() {
250 fFontScalerKey->unref(); 236 fFontScalerKey->unref();
251 fCache.getArray().visitAll(free_glyph); 237 fCache.getArray().visitAll(free_glyph);
252 238
253 #ifdef SK_DEBUG 239 #ifdef SK_DEBUG
254 gCounter -= 1; 240 gCounter -= 1;
255 // GrPrintf("~GrTextStrike %p %d\n", this, gCounter); 241 // GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
256 #endif 242 #endif
257 } 243 }
258 244
(...skipping 12 matching lines...) Expand all
271 bounds.fRight += DISTANCE_FIELD_PAD; 257 bounds.fRight += DISTANCE_FIELD_PAD;
272 bounds.fTop -= DISTANCE_FIELD_PAD; 258 bounds.fTop -= DISTANCE_FIELD_PAD;
273 bounds.fBottom += DISTANCE_FIELD_PAD; 259 bounds.fBottom += DISTANCE_FIELD_PAD;
274 } 260 }
275 #endif 261 #endif
276 glyph->init(packed, bounds); 262 glyph->init(packed, bounds);
277 fCache.insert(packed, glyph); 263 fCache.insert(packed, glyph);
278 return glyph; 264 return glyph;
279 } 265 }
280 266
281 bool GrTextStrike::removeUnusedPlots() { 267 void GrTextStrike::removePlot(const GrPlot* plot) {
282 fCache.getArray().visitAll(invalidate_glyph); 268 SkTDArray<GrGlyph*>& glyphArray = fCache.getArray();
283 return fAtlasMgr->removeUnusedPlots(&fAtlas); 269 for (int i = 0; i < glyphArray.count(); ++i) {
270 if (plot == glyphArray[i]->fPlot) {
271 glyphArray[i]->fPlot = NULL;
272 }
273 }
274
275 fAtlasMgr->removePlot(&fAtlas, plot);
284 } 276 }
285 277
286 278
287 bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { 279 bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
288 #if 0 // testing hack to force us to flush our cache often 280 #if 0 // testing hack to force us to flush our cache often
289 static int gCounter; 281 static int gCounter;
290 if ((++gCounter % 10) == 0) return false; 282 if ((++gCounter % 10) == 0) return false;
291 #endif 283 #endif
292 284
293 SkASSERT(glyph); 285 SkASSERT(glyph);
294 SkASSERT(scaler); 286 SkASSERT(scaler);
295 SkASSERT(fCache.contains(glyph)); 287 SkASSERT(fCache.contains(glyph));
296 SkASSERT(NULL == glyph->fPlot); 288 SkASSERT(NULL == glyph->fPlot);
297 289
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 } 402 }
411 #endif 403 #endif
412 404
413 if (NULL == plot) { 405 if (NULL == plot) {
414 return false; 406 return false;
415 } 407 }
416 408
417 glyph->fPlot = plot; 409 glyph->fPlot = plot;
418 return true; 410 return true;
419 } 411 }
OLDNEW
« no previous file with comments | « src/gpu/GrTextStrike.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698