1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/effects/gradients/SkBitmapCache.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,153 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2010 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkBitmapCache.h" 1.14 + 1.15 +struct SkBitmapCache::Entry { 1.16 + Entry* fPrev; 1.17 + Entry* fNext; 1.18 + 1.19 + void* fBuffer; 1.20 + size_t fSize; 1.21 + SkBitmap fBitmap; 1.22 + 1.23 + Entry(const void* buffer, size_t size, const SkBitmap& bm) 1.24 + : fPrev(NULL), 1.25 + fNext(NULL), 1.26 + fBitmap(bm) { 1.27 + fBuffer = sk_malloc_throw(size); 1.28 + fSize = size; 1.29 + memcpy(fBuffer, buffer, size); 1.30 + } 1.31 + 1.32 + ~Entry() { sk_free(fBuffer); } 1.33 + 1.34 + bool equals(const void* buffer, size_t size) const { 1.35 + return (fSize == size) && !memcmp(fBuffer, buffer, size); 1.36 + } 1.37 +}; 1.38 + 1.39 +SkBitmapCache::SkBitmapCache(int max) : fMaxEntries(max) { 1.40 + fEntryCount = 0; 1.41 + fHead = fTail = NULL; 1.42 + 1.43 + this->validate(); 1.44 +} 1.45 + 1.46 +SkBitmapCache::~SkBitmapCache() { 1.47 + this->validate(); 1.48 + 1.49 + Entry* entry = fHead; 1.50 + while (entry) { 1.51 + Entry* next = entry->fNext; 1.52 + delete entry; 1.53 + entry = next; 1.54 + } 1.55 +} 1.56 + 1.57 +SkBitmapCache::Entry* SkBitmapCache::detach(Entry* entry) const { 1.58 + if (entry->fPrev) { 1.59 + SkASSERT(fHead != entry); 1.60 + entry->fPrev->fNext = entry->fNext; 1.61 + } else { 1.62 + SkASSERT(fHead == entry); 1.63 + fHead = entry->fNext; 1.64 + } 1.65 + if (entry->fNext) { 1.66 + SkASSERT(fTail != entry); 1.67 + entry->fNext->fPrev = entry->fPrev; 1.68 + } else { 1.69 + SkASSERT(fTail == entry); 1.70 + fTail = entry->fPrev; 1.71 + } 1.72 + return entry; 1.73 +} 1.74 + 1.75 +void SkBitmapCache::attachToHead(Entry* entry) const { 1.76 + entry->fPrev = NULL; 1.77 + entry->fNext = fHead; 1.78 + if (fHead) { 1.79 + fHead->fPrev = entry; 1.80 + } else { 1.81 + fTail = entry; 1.82 + } 1.83 + fHead = entry; 1.84 +} 1.85 + 1.86 +bool SkBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const { 1.87 + AutoValidate av(this); 1.88 + 1.89 + Entry* entry = fHead; 1.90 + while (entry) { 1.91 + if (entry->equals(buffer, size)) { 1.92 + if (bm) { 1.93 + *bm = entry->fBitmap; 1.94 + } 1.95 + // move to the head of our list, so we purge it last 1.96 + this->detach(entry); 1.97 + this->attachToHead(entry); 1.98 + return true; 1.99 + } 1.100 + entry = entry->fNext; 1.101 + } 1.102 + return false; 1.103 +} 1.104 + 1.105 +void SkBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) { 1.106 + AutoValidate av(this); 1.107 + 1.108 + if (fEntryCount == fMaxEntries) { 1.109 + SkASSERT(fTail); 1.110 + delete this->detach(fTail); 1.111 + fEntryCount -= 1; 1.112 + } 1.113 + 1.114 + Entry* entry = SkNEW_ARGS(Entry, (buffer, len, bm)); 1.115 + this->attachToHead(entry); 1.116 + fEntryCount += 1; 1.117 +} 1.118 + 1.119 +/////////////////////////////////////////////////////////////////////////////// 1.120 + 1.121 +#ifdef SK_DEBUG 1.122 + 1.123 +void SkBitmapCache::validate() const { 1.124 + SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries); 1.125 + 1.126 + if (fEntryCount > 0) { 1.127 + SkASSERT(NULL == fHead->fPrev); 1.128 + SkASSERT(NULL == fTail->fNext); 1.129 + 1.130 + if (fEntryCount == 1) { 1.131 + SkASSERT(fHead == fTail); 1.132 + } else { 1.133 + SkASSERT(fHead != fTail); 1.134 + } 1.135 + 1.136 + Entry* entry = fHead; 1.137 + int count = 0; 1.138 + while (entry) { 1.139 + count += 1; 1.140 + entry = entry->fNext; 1.141 + } 1.142 + SkASSERT(count == fEntryCount); 1.143 + 1.144 + entry = fTail; 1.145 + while (entry) { 1.146 + count -= 1; 1.147 + entry = entry->fPrev; 1.148 + } 1.149 + SkASSERT(0 == count); 1.150 + } else { 1.151 + SkASSERT(NULL == fHead); 1.152 + SkASSERT(NULL == fTail); 1.153 + } 1.154 +} 1.155 + 1.156 +#endif