From 22a0221968bbc7498110f098d7975989d0fbcf6d Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Tue, 1 Mar 2011 21:33:48 +0000 Subject: [PATCH] check that alloc() succeeded before calling the scaler's getImage() git-svn-id: http://skia.googlecode.com/svn/trunk@873 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/core/SkGlyphCache.cpp | 53 +++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index 199ac14..5ed7386 100644 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -2,16 +2,16 @@ ** ** Copyright 2006, The Android Open Source Project ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at ** -** http://www.apache.org/licenses/LICENSE-2.0 +** http://www.apache.org/licenses/LICENSE-2.0 ** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and ** limitations under the License. */ @@ -37,7 +37,7 @@ static void RecordHashCollisionIf(bool pred) { if (pred) { gHashCollision += 1; - + uint32_t total = gHashSuccess + gHashCollision; SkDebugf("Font Cache Hash success rate: %d%%\n", 100 * gHashSuccess / total); @@ -68,9 +68,9 @@ SkGlyphCache::SkGlyphCache(const SkDescriptor* desc) memset(fGlyphHash, 0, sizeof(fGlyphHash)); // init with 0xFF so that the charCode field will be -1, which is invalid memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); - + fMemoryUsed = sizeof(*this) + kMinGlphAlloc + kMinImageAlloc; - + fGlyphArray.setReserve(METRICS_RESERVE_COUNT); fMetricsCount = 0; @@ -105,7 +105,7 @@ uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { VALIDATE(); uint32_t id = SkGlyph::MakeID(charCode); const CharGlyphRec& rec = fCharToGlyphHash[ID2HashIndex(id)]; - + if (rec.fID == id) { return rec.fGlyph->getGlyphID(); } else { @@ -123,7 +123,7 @@ const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { VALIDATE(); uint32_t id = SkGlyph::MakeID(charCode); CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; - + if (rec->fID != id) { // this ID is based on the UniChar rec->fID = id; @@ -153,7 +153,7 @@ const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { VALIDATE(); uint32_t id = SkGlyph::MakeID(charCode); CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; - + if (rec->fID != id) { RecordHashCollisionIf(rec->fGlyph != NULL); // this ID is based on the UniChar @@ -176,7 +176,7 @@ const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, VALIDATE(); uint32_t id = SkGlyph::MakeID(charCode, x, y); CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; - + if (rec->fID != id) { RecordHashCollisionIf(rec->fGlyph != NULL); // this ID is based on the UniChar @@ -199,7 +199,7 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { uint32_t id = SkGlyph::MakeID(glyphID); unsigned index = ID2HashIndex(id); SkGlyph* glyph = fGlyphHash[index]; - + if (NULL == glyph || glyph->fID != id) { RecordHashCollisionIf(glyph != NULL); glyph = this->lookupMetrics(glyphID, kFull_MetricsType); @@ -275,7 +275,7 @@ SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { SkChunkAlloc::kThrow_AllocFailType); glyph->init(id); *fGlyphArray.insert(hi) = glyph; - + if (kJustAdvance_MetricsType == mtype) { fScalerContext->getAdvance(glyph); fAdvanceCount += 1; @@ -294,8 +294,11 @@ const void* SkGlyphCache::findImage(const SkGlyph& glyph) { size_t size = glyph.computeImageSize(); const_cast(glyph).fImage = fImageAlloc.alloc(size, SkChunkAlloc::kReturnNil_AllocFailType); - fScalerContext->getImage(glyph); - fMemoryUsed += size; + // check that alloc() actually succeeded + if (glyph.fImage) { + fScalerContext->getImage(glyph); + fMemoryUsed += size; + } } } return glyph.fImage; @@ -391,7 +394,7 @@ void SkGlyphCache::invokeAndRemoveAuxProcs() { #define HASH_BITCOUNT 6 #define HASH_COUNT (1 << HASH_BITCOUNT) #define HASH_MASK (HASH_COUNT - 1) - + static unsigned desc_to_hashindex(const SkDescriptor* desc) { SkASSERT(HASH_MASK < 256); // since our munging reduces to 8 bits @@ -446,9 +449,9 @@ void SkGlyphCache::VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), SkGlyphCache_Globals& globals = FIND_GC_GLOBALS(); SkAutoMutexAcquire ac(globals.fMutex); SkGlyphCache* cache; - + globals.validate(); - + for (cache = globals.fHead; cache != NULL; cache = cache->fNext) { if (proc(cache, context)) { break; @@ -560,7 +563,7 @@ void SkGlyphCache::AttachCache(SkGlyphCache* cache) { size_t SkGlyphCache::GetCacheUsed() { SkGlyphCache_Globals& globals = FIND_GC_GLOBALS(); SkAutoMutexAcquire ac(globals.fMutex); - + return SkGlyphCache::ComputeMemoryUsed(globals.fHead); } @@ -570,7 +573,7 @@ bool SkGlyphCache::SetCacheUsed(size_t bytesUsed) { if (curr > bytesUsed) { SkGlyphCache_Globals& globals = FIND_GC_GLOBALS(); SkAutoMutexAcquire ac(globals.fMutex); - + return InternalFreeCache(&globals, curr - bytesUsed) > 0; } return false; @@ -589,7 +592,7 @@ SkGlyphCache* SkGlyphCache::FindTail(SkGlyphCache* cache) { size_t SkGlyphCache::ComputeMemoryUsed(const SkGlyphCache* head) { size_t size = 0; - + while (head != NULL) { size += head->fMemoryUsed; head = head->fNext; -- 2.7.4