| 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 |