OLD | NEW |
---|---|
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 "GrGpu.h" | 8 #include "GrGpu.h" |
9 #include "GrRectanizer.h" | 9 #include "GrRectanizer.h" |
10 #include "GrSurfacePriv.h" | 10 #include "GrSurfacePriv.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 GrFontCache::k8888_AtlasType, | 73 GrFontCache::k8888_AtlasType, |
74 GrFontCache::k8888_AtlasType | 74 GrFontCache::k8888_AtlasType |
75 }; | 75 }; |
76 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_s ize_mismatch); | 76 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_s ize_mismatch); |
77 | 77 |
78 SkASSERT(sAtlasIndices[format] < GrFontCache::kAtlasCount); | 78 SkASSERT(sAtlasIndices[format] < GrFontCache::kAtlasCount); |
79 return sAtlasIndices[format]; | 79 return sAtlasIndices[format]; |
80 } | 80 } |
81 | 81 |
82 GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler) { | 82 GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler) { |
83 GrMaskFormat format = scaler->getMaskFormat(); | 83 GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, (this, scaler->getKey())); |
84 GrPixelConfig config = mask_format_to_pixel_config(format); | |
85 int atlasIndex = mask_format_to_atlas_index(format); | |
86 if (NULL == fAtlases[atlasIndex]) { | |
87 SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, | |
88 GR_ATLAS_TEXTURE_HEIGHT); | |
89 fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextur eFlags, | |
90 textureSize, | |
91 GR_NUM_PLOTS_X, | |
92 GR_NUM_PLOTS_Y, | |
93 true)); | |
94 } | |
95 GrTextStrike* strike = SkNEW_ARGS(GrTextStrike, | |
96 (this, scaler->getKey(), format, fAtlases[ atlasIndex])); | |
97 fCache.add(strike); | 84 fCache.add(strike); |
98 | 85 |
99 if (fHead) { | 86 if (fHead) { |
100 fHead->fPrev = strike; | 87 fHead->fPrev = strike; |
101 } else { | 88 } else { |
102 SkASSERT(NULL == fTail); | 89 SkASSERT(NULL == fTail); |
103 fTail = strike; | 90 fTail = strike; |
104 } | 91 } |
105 strike->fPrev = NULL; | 92 strike->fPrev = NULL; |
106 strike->fNext = fHead; | 93 strike->fNext = fHead; |
(...skipping 16 matching lines...) Expand all Loading... | |
123 fHead = NULL; | 110 fHead = NULL; |
124 fTail = NULL; | 111 fTail = NULL; |
125 } | 112 } |
126 | 113 |
127 void GrFontCache::purgeStrike(GrTextStrike* strike) { | 114 void GrFontCache::purgeStrike(GrTextStrike* strike) { |
128 fCache.remove(*(strike->fFontScalerKey)); | 115 fCache.remove(*(strike->fFontScalerKey)); |
129 this->detachStrikeFromList(strike); | 116 this->detachStrikeFromList(strike); |
130 delete strike; | 117 delete strike; |
131 } | 118 } |
132 | 119 |
133 bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) { | 120 |
121 GrPlot* GrFontCache::addToAtlas(GrMaskFormat format, GrAtlas::ClientPlotUsage* u sage, | |
122 int width, int height, const void* image, | |
123 SkIPoint16* loc) { | |
robertphillips
2014/10/09 16:14:53
Do we need both index and atlasIndex ?
jvanverth1
2014/10/09 17:34:35
Done.
| |
124 int index = mask_format_to_atlas_index(format); | |
125 GrPixelConfig config = mask_format_to_pixel_config(format); | |
126 int atlasIndex = mask_format_to_atlas_index(format); | |
127 if (NULL == fAtlases[atlasIndex]) { | |
128 SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, | |
129 GR_ATLAS_TEXTURE_HEIGHT); | |
130 fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextur eFlags, | |
131 textureSize, | |
132 GR_NUM_PLOTS_X, | |
133 GR_NUM_PLOTS_Y, | |
134 true)); | |
135 } | |
136 return fAtlases[index]->addToAtlas(usage, width, height, image, loc); | |
137 } | |
138 | |
139 | |
140 bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* gl yph) { | |
134 SkASSERT(preserveStrike); | 141 SkASSERT(preserveStrike); |
135 | 142 |
136 GrAtlas* atlas = preserveStrike->fAtlas; | 143 int index = mask_format_to_atlas_index(glyph->fMaskFormat); |
144 GrAtlas* atlas = fAtlases[index]; | |
137 GrPlot* plot = atlas->getUnusedPlot(); | 145 GrPlot* plot = atlas->getUnusedPlot(); |
138 if (NULL == plot) { | 146 if (NULL == plot) { |
139 return false; | 147 return false; |
140 } | 148 } |
141 plot->resetRects(); | 149 plot->resetRects(); |
142 | 150 |
143 GrTextStrike* strike = fHead; | 151 GrTextStrike* strike = fHead; |
144 GrMaskFormat maskFormat = preserveStrike->fMaskFormat; | |
145 while (strike) { | 152 while (strike) { |
146 if (maskFormat != strike->fMaskFormat) { | |
147 strike = strike->fNext; | |
148 continue; | |
149 } | |
150 | |
151 GrTextStrike* strikeToPurge = strike; | 153 GrTextStrike* strikeToPurge = strike; |
152 strike = strikeToPurge->fNext; | 154 strike = strikeToPurge->fNext; |
153 strikeToPurge->removePlot(plot); | 155 strikeToPurge->removePlot(plot); |
154 | 156 |
155 // clear out any empty strikes (except this one) | 157 // clear out any empty strikes (except this one) |
156 if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty ()) { | 158 if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty ()) { |
157 this->purgeStrike(strikeToPurge); | 159 this->purgeStrike(strikeToPurge); |
158 } | 160 } |
159 } | 161 } |
160 | 162 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 #endif | 223 #endif |
222 | 224 |
223 /* | 225 /* |
224 The text strike is specific to a given font/style/matrix setup, which is | 226 The text strike is specific to a given font/style/matrix setup, which is |
225 represented by the GrHostFontScaler object we are given in getGlyph(). | 227 represented by the GrHostFontScaler object we are given in getGlyph(). |
226 | 228 |
227 We map a 32bit glyphID to a GrGlyph record, which in turn points to a | 229 We map a 32bit glyphID to a GrGlyph record, which in turn points to a |
228 atlas and a position within that texture. | 230 atlas and a position within that texture. |
229 */ | 231 */ |
230 | 232 |
231 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key, | 233 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key) : fPool (64) { |
232 GrMaskFormat format, | |
233 GrAtlas* atlas) : fPool(64) { | |
234 fFontScalerKey = key; | 234 fFontScalerKey = key; |
235 fFontScalerKey->ref(); | 235 fFontScalerKey->ref(); |
236 | 236 |
237 fFontCache = cache; // no need to ref, it won't go away before we do | 237 fFontCache = cache; // no need to ref, it won't go away before we do |
238 fAtlas = atlas; // no need to ref, it won't go away before we do | |
239 | |
240 fMaskFormat = format; | |
241 | 238 |
242 #ifdef SK_DEBUG | 239 #ifdef SK_DEBUG |
243 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); | 240 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); |
244 gCounter += 1; | 241 gCounter += 1; |
245 #endif | 242 #endif |
246 } | 243 } |
247 | 244 |
248 GrTextStrike::~GrTextStrike() { | 245 GrTextStrike::~GrTextStrike() { |
249 fFontScalerKey->unref(); | 246 fFontScalerKey->unref(); |
250 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); | 247 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); |
(...skipping 13 matching lines...) Expand all Loading... | |
264 SkIRect bounds; | 261 SkIRect bounds; |
265 if (fUseDistanceField) { | 262 if (fUseDistanceField) { |
266 if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { | 263 if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { |
267 return NULL; | 264 return NULL; |
268 } | 265 } |
269 } else { | 266 } else { |
270 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { | 267 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { |
271 return NULL; | 268 return NULL; |
272 } | 269 } |
273 } | 270 } |
274 | 271 GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed); |
272 | |
275 GrGlyph* glyph = fPool.alloc(); | 273 GrGlyph* glyph = fPool.alloc(); |
276 glyph->init(packed, bounds); | 274 glyph->init(packed, bounds, format); |
277 fCache.add(glyph); | 275 fCache.add(glyph); |
278 return glyph; | 276 return glyph; |
279 } | 277 } |
280 | 278 |
281 void GrTextStrike::removePlot(const GrPlot* plot) { | 279 void GrTextStrike::removePlot(const GrPlot* plot) { |
282 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); | 280 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); |
283 while (!iter.done()) { | 281 while (!iter.done()) { |
284 if (plot == (*iter).fPlot) { | 282 if (plot == (*iter).fPlot) { |
285 (*iter).fPlot = NULL; | 283 (*iter).fPlot = NULL; |
286 } | 284 } |
(...skipping 23 matching lines...) Expand all Loading... | |
310 if ((++gCounter % 10) == 0) return false; | 308 if ((++gCounter % 10) == 0) return false; |
311 #endif | 309 #endif |
312 | 310 |
313 SkASSERT(glyph); | 311 SkASSERT(glyph); |
314 SkASSERT(scaler); | 312 SkASSERT(scaler); |
315 SkASSERT(fCache.find(glyph->fPackedID)); | 313 SkASSERT(fCache.find(glyph->fPackedID)); |
316 SkASSERT(NULL == glyph->fPlot); | 314 SkASSERT(NULL == glyph->fPlot); |
317 | 315 |
318 SkAutoUnref ar(SkSafeRef(scaler)); | 316 SkAutoUnref ar(SkSafeRef(scaler)); |
319 | 317 |
320 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); | 318 int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat); |
321 | 319 |
322 size_t size = glyph->fBounds.area() * bytesPerPixel; | 320 size_t size = glyph->fBounds.area() * bytesPerPixel; |
323 GrAutoMalloc<1024> storage(size); | 321 GrAutoMalloc<1024> storage(size); |
324 | 322 |
325 if (fUseDistanceField) { | 323 if (fUseDistanceField) { |
326 if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), | 324 if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), |
327 glyph->height(), | 325 glyph->height(), |
328 storage.get())) { | 326 storage.get())) { |
329 return false; | 327 return false; |
330 } | 328 } |
331 } else { | 329 } else { |
332 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), | 330 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), |
333 glyph->height(), | 331 glyph->height(), |
334 glyph->width() * bytesPerPixel, | 332 glyph->width() * bytesPerPixel, |
335 storage.get())) { | 333 storage.get())) { |
336 return false; | 334 return false; |
337 } | 335 } |
338 } | 336 } |
339 | 337 |
340 GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, glyph->width(), | 338 GrPlot* plot = fFontCache->addToAtlas(glyph->fMaskFormat, &fPlotUsage, |
341 glyph->height(), storage.get(), | 339 glyph->width(), glyph->height(), |
342 &glyph->fAtlasLocation); | 340 storage.get(), &glyph->fAtlasLocation) ; |
343 | 341 |
344 if (NULL == plot) { | 342 if (NULL == plot) { |
345 return false; | 343 return false; |
346 } | 344 } |
347 | 345 |
348 glyph->fPlot = plot; | 346 glyph->fPlot = plot; |
349 return true; | 347 return true; |
350 } | 348 } |
OLD | NEW |