OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkGlyphCache.h" | 10 #include "SkGlyphCache.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #endif | 46 #endif |
47 #define RecordHashCollision() RecordHashCollisionIf(true) | 47 #define RecordHashCollision() RecordHashCollisionIf(true) |
48 | 48 |
49 /////////////////////////////////////////////////////////////////////////////// | 49 /////////////////////////////////////////////////////////////////////////////// |
50 | 50 |
51 // so we don't grow our arrays a lot | 51 // so we don't grow our arrays a lot |
52 #define kMinGlyphCount 16 | 52 #define kMinGlyphCount 16 |
53 #define kMinGlyphImageSize (16*2) | 53 #define kMinGlyphImageSize (16*2) |
54 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC
ount) | 54 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC
ount) |
55 | 55 |
56 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc) | 56 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
lerContext* ctx) |
57 : fGlyphAlloc(kMinAllocAmount) { | 57 : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) { |
58 SkASSERT(typeface); | 58 SkASSERT(typeface); |
| 59 SkASSERT(desc); |
| 60 SkASSERT(ctx); |
59 | 61 |
60 fPrev = fNext = NULL; | 62 fPrev = fNext = NULL; |
61 | 63 |
62 fDesc = desc->copy(); | 64 fDesc = desc->copy(); |
63 fScalerContext = typeface->createScalerContext(desc); | |
64 fScalerContext->getFontMetrics(&fFontMetrics); | 65 fScalerContext->getFontMetrics(&fFontMetrics); |
65 | 66 |
66 // init to 0 so that all of the pointers will be null | 67 // init to 0 so that all of the pointers will be null |
67 memset(fGlyphHash, 0, sizeof(fGlyphHash)); | 68 memset(fGlyphHash, 0, sizeof(fGlyphHash)); |
68 // init with 0xFF so that the charCode field will be -1, which is invalid | 69 // init with 0xFF so that the charCode field will be -1, which is invalid |
69 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); | 70 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); |
70 | 71 |
71 fMemoryUsed = sizeof(*this); | 72 fMemoryUsed = sizeof(*this); |
72 | 73 |
73 fGlyphArray.setReserve(kMinGlyphCount); | 74 fGlyphArray.setReserve(kMinGlyphCount); |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 goto FOUND_IT; | 583 goto FOUND_IT; |
583 } | 584 } |
584 } | 585 } |
585 | 586 |
586 /* Release the mutex now, before we create a new entry (which might have | 587 /* Release the mutex now, before we create a new entry (which might have |
587 side-effects like trying to access the cache/mutex (yikes!) | 588 side-effects like trying to access the cache/mutex (yikes!) |
588 */ | 589 */ |
589 ac.release(); // release the mutex now | 590 ac.release(); // release the mutex now |
590 insideMutex = false; // can't use globals anymore | 591 insideMutex = false; // can't use globals anymore |
591 | 592 |
592 cache = SkNEW_ARGS(SkGlyphCache, (typeface, desc)); | 593 // Check if we can create a scaler-context before creating the glyphcache. |
| 594 // If not, we may have exhausted OS/font resources, so try purging the |
| 595 // cache once and try again. |
| 596 { |
| 597 SkScalerContext* ctx = typeface->createScalerContext(desc); |
| 598 if (!ctx) { |
| 599 getSharedGlobals().purgeAll(); |
| 600 ctx = typeface->createScalerContext(desc); |
| 601 if (!ctx) { |
| 602 sk_throw(); |
| 603 } |
| 604 } |
| 605 cache = SkNEW_ARGS(SkGlyphCache, (typeface, desc, ctx)); |
| 606 } |
593 | 607 |
594 FOUND_IT: | 608 FOUND_IT: |
595 | 609 |
596 AutoValidate av(cache); | 610 AutoValidate av(cache); |
597 | 611 |
598 if (proc(cache, context)) { // stay detached | 612 if (proc(cache, context)) { // stay detached |
599 if (insideMutex) { | 613 if (insideMutex) { |
600 SkASSERT(globals.fTotalMemoryUsed >= cache->fMemoryUsed); | 614 SkASSERT(globals.fTotalMemoryUsed >= cache->fMemoryUsed); |
601 globals.fTotalMemoryUsed -= cache->fMemoryUsed; | 615 globals.fTotalMemoryUsed -= cache->fMemoryUsed; |
602 #ifdef USE_CACHE_HASH | 616 #ifdef USE_CACHE_HASH |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 return tls ? tls->getFontCacheLimit() : 0; | 779 return tls ? tls->getFontCacheLimit() : 0; |
766 } | 780 } |
767 | 781 |
768 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { | 782 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { |
769 if (0 == bytes) { | 783 if (0 == bytes) { |
770 SkGlyphCache_Globals::DeleteTLS(); | 784 SkGlyphCache_Globals::DeleteTLS(); |
771 } else { | 785 } else { |
772 SkGlyphCache_Globals::GetTLS().setFontCacheLimit(bytes); | 786 SkGlyphCache_Globals::GetTLS().setFontCacheLimit(bytes); |
773 } | 787 } |
774 } | 788 } |
OLD | NEW |