OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkGlyphCache.h" | 8 #include "SkGlyphCache.h" |
9 #include "SkGlyphCache_Globals.h" | 9 #include "SkGlyphCache_Globals.h" |
10 #include "SkGraphics.h" | 10 #include "SkGraphics.h" |
11 #include "SkLazyPtr.h" | 11 #include "SkLazyPtr.h" |
12 #include "SkPath.h" | 12 #include "SkPath.h" |
13 #include "SkTemplates.h" | 13 #include "SkTemplates.h" |
14 #include "SkTypeface.h" | 14 #include "SkTypeface.h" |
15 | 15 |
16 //#define SPEW_PURGE_STATUS | 16 //#define SPEW_PURGE_STATUS |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 SkGlyphCache_Globals* create_globals() { | 20 SkGlyphCache_Globals* create_globals() { return new SkGlyphCache_Globals; } |
21 return SkNEW(SkGlyphCache_Globals); | |
22 } | |
23 | 21 |
24 } // namespace | 22 } // namespace |
25 | 23 |
26 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals); | 24 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals); |
27 | 25 |
28 // Returns the shared globals | 26 // Returns the shared globals |
29 static SkGlyphCache_Globals& get_globals() { | 27 static SkGlyphCache_Globals& get_globals() { |
30 return *globals.get(); | 28 return *globals.get(); |
31 } | 29 } |
32 | 30 |
(...skipping 15 matching lines...) Expand all Loading... |
48 fPrev = fNext = NULL; | 46 fPrev = fNext = NULL; |
49 | 47 |
50 fScalerContext->getFontMetrics(&fFontMetrics); | 48 fScalerContext->getFontMetrics(&fFontMetrics); |
51 | 49 |
52 fMemoryUsed = sizeof(*this); | 50 fMemoryUsed = sizeof(*this); |
53 | 51 |
54 fAuxProcList = NULL; | 52 fAuxProcList = NULL; |
55 } | 53 } |
56 | 54 |
57 SkGlyphCache::~SkGlyphCache() { | 55 SkGlyphCache::~SkGlyphCache() { |
58 fGlyphMap.foreach( | 56 fGlyphMap.foreach ([](SkGlyph* g) { delete g->fPath; }); |
59 [](SkGlyph* g) { | |
60 SkDELETE(g->fPath); | |
61 } | |
62 ); | |
63 SkDescriptor::Free(fDesc); | 57 SkDescriptor::Free(fDesc); |
64 SkDELETE(fScalerContext); | 58 delete fScalerContext; |
65 this->invokeAndRemoveAuxProcs(); | 59 this->invokeAndRemoveAuxProcs(); |
66 } | 60 } |
67 | 61 |
68 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packed
UnicharID) { | 62 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packed
UnicharID) { |
69 if (NULL == fPackedUnicharIDToPackedGlyphID.get()) { | 63 if (NULL == fPackedUnicharIDToPackedGlyphID.get()) { |
70 // Allocate the array. | 64 // Allocate the array. |
71 fPackedUnicharIDToPackedGlyphID.reset(kHashCount); | 65 fPackedUnicharIDToPackedGlyphID.reset(kHashCount); |
72 // Initialize array to map character and position with the impossible gl
yph ID. This | 66 // Initialize array to map character and position with the impossible gl
yph ID. This |
73 // represents no mapping. | 67 // represents no mapping. |
74 for (int i = 0; i <kHashCount; ++i) { | 68 for (int i = 0; i <kHashCount; ++i) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 fMemoryUsed += size; | 208 fMemoryUsed += size; |
215 } | 209 } |
216 } | 210 } |
217 } | 211 } |
218 return glyph.fImage; | 212 return glyph.fImage; |
219 } | 213 } |
220 | 214 |
221 const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) { | 215 const SkPath* SkGlyphCache::findPath(const SkGlyph& glyph) { |
222 if (glyph.fWidth) { | 216 if (glyph.fWidth) { |
223 if (glyph.fPath == NULL) { | 217 if (glyph.fPath == NULL) { |
224 const_cast<SkGlyph&>(glyph).fPath = SkNEW(SkPath); | 218 const_cast<SkGlyph&>(glyph).fPath = new SkPath; |
225 fScalerContext->getPath(glyph, glyph.fPath); | 219 fScalerContext->getPath(glyph, glyph.fPath); |
226 fMemoryUsed += sizeof(SkPath) + | 220 fMemoryUsed += sizeof(SkPath) + |
227 glyph.fPath->countPoints() * sizeof(SkPoint); | 221 glyph.fPath->countPoints() * sizeof(SkPoint); |
228 } | 222 } |
229 } | 223 } |
230 return glyph.fPath; | 224 return glyph.fPath; |
231 } | 225 } |
232 | 226 |
233 void SkGlyphCache::dump() const { | 227 void SkGlyphCache::dump() const { |
234 const SkTypeface* face = fScalerContext->getTypeface(); | 228 const SkTypeface* face = fScalerContext->getTypeface(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 | 266 |
273 AuxProcRec* rec = fAuxProcList; | 267 AuxProcRec* rec = fAuxProcList; |
274 while (rec) { | 268 while (rec) { |
275 if (rec->fProc == proc) { | 269 if (rec->fProc == proc) { |
276 rec->fData = data; | 270 rec->fData = data; |
277 return; | 271 return; |
278 } | 272 } |
279 rec = rec->fNext; | 273 rec = rec->fNext; |
280 } | 274 } |
281 // not found, create a new rec | 275 // not found, create a new rec |
282 rec = SkNEW(AuxProcRec); | 276 rec = new AuxProcRec; |
283 rec->fProc = proc; | 277 rec->fProc = proc; |
284 rec->fData = data; | 278 rec->fData = data; |
285 rec->fNext = fAuxProcList; | 279 rec->fNext = fAuxProcList; |
286 fAuxProcList = rec; | 280 fAuxProcList = rec; |
287 } | 281 } |
288 | 282 |
289 void SkGlyphCache::invokeAndRemoveAuxProcs() { | 283 void SkGlyphCache::invokeAndRemoveAuxProcs() { |
290 AuxProcRec* rec = fAuxProcList; | 284 AuxProcRec* rec = fAuxProcList; |
291 while (rec) { | 285 while (rec) { |
292 rec->fProc(rec->fData); | 286 rec->fProc(rec->fData); |
293 AuxProcRec* next = rec->fNext; | 287 AuxProcRec* next = rec->fNext; |
294 SkDELETE(rec); | 288 delete rec; |
295 rec = next; | 289 rec = next; |
296 } | 290 } |
297 } | 291 } |
298 | 292 |
299 /////////////////////////////////////////////////////////////////////////////// | 293 /////////////////////////////////////////////////////////////////////////////// |
300 /////////////////////////////////////////////////////////////////////////////// | 294 /////////////////////////////////////////////////////////////////////////////// |
301 | 295 |
302 | 296 |
303 class AutoAcquire { | 297 class AutoAcquire { |
304 public: | 298 public: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 // cache once and try again. | 374 // cache once and try again. |
381 { | 375 { |
382 // pass true the first time, to notice if the scalercontext failed, | 376 // pass true the first time, to notice if the scalercontext failed, |
383 // so we can try the purge. | 377 // so we can try the purge. |
384 SkScalerContext* ctx = typeface->createScalerContext(desc, true); | 378 SkScalerContext* ctx = typeface->createScalerContext(desc, true); |
385 if (!ctx) { | 379 if (!ctx) { |
386 get_globals().purgeAll(); | 380 get_globals().purgeAll(); |
387 ctx = typeface->createScalerContext(desc, false); | 381 ctx = typeface->createScalerContext(desc, false); |
388 SkASSERT(ctx); | 382 SkASSERT(ctx); |
389 } | 383 } |
390 cache = SkNEW_ARGS(SkGlyphCache, (typeface, desc, ctx)); | 384 cache = new SkGlyphCache(typeface, desc, ctx); |
391 } | 385 } |
392 | 386 |
393 AutoValidate av(cache); | 387 AutoValidate av(cache); |
394 | 388 |
395 if (!proc(cache, context)) { // need to reattach | 389 if (!proc(cache, context)) { // need to reattach |
396 globals.attachCacheToHead(cache); | 390 globals.attachCacheToHead(cache); |
397 cache = NULL; | 391 cache = NULL; |
398 } | 392 } |
399 return cache; | 393 return cache; |
400 } | 394 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // we start at the tail and proceed backwards, as the linklist is in LRU | 489 // we start at the tail and proceed backwards, as the linklist is in LRU |
496 // order, with unimportant entries at the tail. | 490 // order, with unimportant entries at the tail. |
497 SkGlyphCache* cache = this->internalGetTail(); | 491 SkGlyphCache* cache = this->internalGetTail(); |
498 while (cache != NULL && | 492 while (cache != NULL && |
499 (bytesFreed < bytesNeeded || countFreed < countNeeded)) { | 493 (bytesFreed < bytesNeeded || countFreed < countNeeded)) { |
500 SkGlyphCache* prev = cache->fPrev; | 494 SkGlyphCache* prev = cache->fPrev; |
501 bytesFreed += cache->fMemoryUsed; | 495 bytesFreed += cache->fMemoryUsed; |
502 countFreed += 1; | 496 countFreed += 1; |
503 | 497 |
504 this->internalDetachCache(cache); | 498 this->internalDetachCache(cache); |
505 SkDELETE(cache); | 499 delete cache; |
506 cache = prev; | 500 cache = prev; |
507 } | 501 } |
508 | 502 |
509 this->validate(); | 503 this->validate(); |
510 | 504 |
511 #ifdef SPEW_PURGE_STATUS | 505 #ifdef SPEW_PURGE_STATUS |
512 if (countFreed) { | 506 if (countFreed) { |
513 SkDebugf("purging %dK from font cache [%d entries]\n", | 507 SkDebugf("purging %dK from font cache [%d entries]\n", |
514 (int)(bytesFreed >> 10), countFreed); | 508 (int)(bytesFreed >> 10), countFreed); |
515 } | 509 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 } | 606 } |
613 | 607 |
614 void SkGraphics::PurgeFontCache() { | 608 void SkGraphics::PurgeFontCache() { |
615 get_globals().purgeAll(); | 609 get_globals().purgeAll(); |
616 SkTypefaceCache::PurgeAll(); | 610 SkTypefaceCache::PurgeAll(); |
617 } | 611 } |
618 | 612 |
619 // TODO(herb): clean up TLS apis. | 613 // TODO(herb): clean up TLS apis. |
620 size_t SkGraphics::GetTLSFontCacheLimit() { return 0; } | 614 size_t SkGraphics::GetTLSFontCacheLimit() { return 0; } |
621 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { } | 615 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { } |
OLD | NEW |