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) { |
| 124 GrPixelConfig config = mask_format_to_pixel_config(format); |
| 125 int atlasIndex = mask_format_to_atlas_index(format); |
| 126 if (NULL == fAtlases[atlasIndex]) { |
| 127 SkISize textureSize = SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, |
| 128 GR_ATLAS_TEXTURE_HEIGHT); |
| 129 fAtlases[atlasIndex] = SkNEW_ARGS(GrAtlas, (fGpu, config, kNone_GrTextur
eFlags, |
| 130 textureSize, |
| 131 GR_NUM_PLOTS_X, |
| 132 GR_NUM_PLOTS_Y, |
| 133 true)); |
| 134 } |
| 135 return fAtlases[atlasIndex]->addToAtlas(usage, width, height, image, loc); |
| 136 } |
| 137 |
| 138 |
| 139 bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* gl
yph) { |
134 SkASSERT(preserveStrike); | 140 SkASSERT(preserveStrike); |
135 | 141 |
136 GrAtlas* atlas = preserveStrike->fAtlas; | 142 int index = mask_format_to_atlas_index(glyph->fMaskFormat); |
| 143 GrAtlas* atlas = fAtlases[index]; |
137 GrPlot* plot = atlas->getUnusedPlot(); | 144 GrPlot* plot = atlas->getUnusedPlot(); |
138 if (NULL == plot) { | 145 if (NULL == plot) { |
139 return false; | 146 return false; |
140 } | 147 } |
141 plot->resetRects(); | 148 plot->resetRects(); |
142 | 149 |
143 GrTextStrike* strike = fHead; | 150 GrTextStrike* strike = fHead; |
144 GrMaskFormat maskFormat = preserveStrike->fMaskFormat; | |
145 while (strike) { | 151 while (strike) { |
146 if (maskFormat != strike->fMaskFormat) { | |
147 strike = strike->fNext; | |
148 continue; | |
149 } | |
150 | |
151 GrTextStrike* strikeToPurge = strike; | 152 GrTextStrike* strikeToPurge = strike; |
152 strike = strikeToPurge->fNext; | 153 strike = strikeToPurge->fNext; |
153 strikeToPurge->removePlot(plot); | 154 strikeToPurge->removePlot(plot); |
154 | 155 |
155 // clear out any empty strikes (except this one) | 156 // clear out any empty strikes (except this one) |
156 if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty
()) { | 157 if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty
()) { |
157 this->purgeStrike(strikeToPurge); | 158 this->purgeStrike(strikeToPurge); |
158 } | 159 } |
159 } | 160 } |
160 | 161 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 #endif | 222 #endif |
222 | 223 |
223 /* | 224 /* |
224 The text strike is specific to a given font/style/matrix setup, which is | 225 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(). | 226 represented by the GrHostFontScaler object we are given in getGlyph(). |
226 | 227 |
227 We map a 32bit glyphID to a GrGlyph record, which in turn points to a | 228 We map a 32bit glyphID to a GrGlyph record, which in turn points to a |
228 atlas and a position within that texture. | 229 atlas and a position within that texture. |
229 */ | 230 */ |
230 | 231 |
231 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key, | 232 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrFontDescKey* key) : fPool
(64) { |
232 GrMaskFormat format, | |
233 GrAtlas* atlas) : fPool(64) { | |
234 fFontScalerKey = key; | 233 fFontScalerKey = key; |
235 fFontScalerKey->ref(); | 234 fFontScalerKey->ref(); |
236 | 235 |
237 fFontCache = cache; // no need to ref, it won't go away before we do | 236 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 | 237 |
242 #ifdef SK_DEBUG | 238 #ifdef SK_DEBUG |
243 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); | 239 // GrPrintf(" GrTextStrike %p %d\n", this, gCounter); |
244 gCounter += 1; | 240 gCounter += 1; |
245 #endif | 241 #endif |
246 } | 242 } |
247 | 243 |
248 GrTextStrike::~GrTextStrike() { | 244 GrTextStrike::~GrTextStrike() { |
249 fFontScalerKey->unref(); | 245 fFontScalerKey->unref(); |
250 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); | 246 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); |
(...skipping 13 matching lines...) Expand all Loading... |
264 SkIRect bounds; | 260 SkIRect bounds; |
265 if (fUseDistanceField) { | 261 if (fUseDistanceField) { |
266 if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { | 262 if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { |
267 return NULL; | 263 return NULL; |
268 } | 264 } |
269 } else { | 265 } else { |
270 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { | 266 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { |
271 return NULL; | 267 return NULL; |
272 } | 268 } |
273 } | 269 } |
274 | 270 GrMaskFormat format = scaler->getPackedGlyphMaskFormat(packed); |
| 271 |
275 GrGlyph* glyph = fPool.alloc(); | 272 GrGlyph* glyph = fPool.alloc(); |
276 glyph->init(packed, bounds); | 273 glyph->init(packed, bounds, format); |
277 fCache.add(glyph); | 274 fCache.add(glyph); |
278 return glyph; | 275 return glyph; |
279 } | 276 } |
280 | 277 |
281 void GrTextStrike::removePlot(const GrPlot* plot) { | 278 void GrTextStrike::removePlot(const GrPlot* plot) { |
282 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); | 279 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); |
283 while (!iter.done()) { | 280 while (!iter.done()) { |
284 if (plot == (*iter).fPlot) { | 281 if (plot == (*iter).fPlot) { |
285 (*iter).fPlot = NULL; | 282 (*iter).fPlot = NULL; |
286 } | 283 } |
(...skipping 23 matching lines...) Expand all Loading... |
310 if ((++gCounter % 10) == 0) return false; | 307 if ((++gCounter % 10) == 0) return false; |
311 #endif | 308 #endif |
312 | 309 |
313 SkASSERT(glyph); | 310 SkASSERT(glyph); |
314 SkASSERT(scaler); | 311 SkASSERT(scaler); |
315 SkASSERT(fCache.find(glyph->fPackedID)); | 312 SkASSERT(fCache.find(glyph->fPackedID)); |
316 SkASSERT(NULL == glyph->fPlot); | 313 SkASSERT(NULL == glyph->fPlot); |
317 | 314 |
318 SkAutoUnref ar(SkSafeRef(scaler)); | 315 SkAutoUnref ar(SkSafeRef(scaler)); |
319 | 316 |
320 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); | 317 int bytesPerPixel = GrMaskFormatBytesPerPixel(glyph->fMaskFormat); |
321 | 318 |
322 size_t size = glyph->fBounds.area() * bytesPerPixel; | 319 size_t size = glyph->fBounds.area() * bytesPerPixel; |
323 GrAutoMalloc<1024> storage(size); | 320 GrAutoMalloc<1024> storage(size); |
324 | 321 |
325 if (fUseDistanceField) { | 322 if (fUseDistanceField) { |
326 if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), | 323 if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), |
327 glyph->height(), | 324 glyph->height(), |
328 storage.get())) { | 325 storage.get())) { |
329 return false; | 326 return false; |
330 } | 327 } |
331 } else { | 328 } else { |
332 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), | 329 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), |
333 glyph->height(), | 330 glyph->height(), |
334 glyph->width() * bytesPerPixel, | 331 glyph->width() * bytesPerPixel, |
335 storage.get())) { | 332 storage.get())) { |
336 return false; | 333 return false; |
337 } | 334 } |
338 } | 335 } |
339 | 336 |
340 GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, glyph->width(), | 337 GrPlot* plot = fFontCache->addToAtlas(glyph->fMaskFormat, &fPlotUsage, |
341 glyph->height(), storage.get(), | 338 glyph->width(), glyph->height(), |
342 &glyph->fAtlasLocation); | 339 storage.get(), &glyph->fAtlasLocation)
; |
343 | 340 |
344 if (NULL == plot) { | 341 if (NULL == plot) { |
345 return false; | 342 return false; |
346 } | 343 } |
347 | 344 |
348 glyph->fPlot = plot; | 345 glyph->fPlot = plot; |
349 return true; | 346 return true; |
350 } | 347 } |
OLD | NEW |