diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:36 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:36 -0800 |
commit | 6eb364108744656fcd23a96a478aa772cd4e85bc (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/gl/SkTextureCache.cpp | |
parent | a23c4e24d873b11674987f97f1946e1c4d97e782 (diff) | |
download | external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.zip external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.gz external_skia-6eb364108744656fcd23a96a478aa772cd4e85bc.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'src/gl/SkTextureCache.cpp')
-rw-r--r-- | src/gl/SkTextureCache.cpp | 363 |
1 files changed, 0 insertions, 363 deletions
diff --git a/src/gl/SkTextureCache.cpp b/src/gl/SkTextureCache.cpp deleted file mode 100644 index 17b37ca..0000000 --- a/src/gl/SkTextureCache.cpp +++ /dev/null @@ -1,363 +0,0 @@ -#include "SkTextureCache.h" - -//#define TRACE_HASH_HITS -//#define TRACE_TEXTURE_CACHE_PURGE - -SkTextureCache::Entry::Entry(const SkBitmap& bitmap) - : fName(0), fKey(bitmap), fPrev(NULL), fNext(NULL) { - - fMemSize = SkGL::ComputeTextureMemorySize(bitmap); - fLockCount = 0; -} - -SkTextureCache::Entry::~Entry() { - if (fName != 0) { - glDeleteTextures(1, &fName); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -SkTextureCache::SkTextureCache(size_t countMax, size_t sizeMax) - : fHead(NULL), fTail(NULL), - fTexCountMax(countMax), fTexSizeMax(sizeMax), - fTexCount(0), fTexSize(0) { - - bzero(fHash, sizeof(fHash)); - this->validate(); -} - -SkTextureCache::~SkTextureCache() { -#ifdef SK_DEBUG - Entry* entry = fHead; - while (entry) { - SkASSERT(entry->lockCount() == 0); - entry = entry->fNext; - } -#endif - this->validate(); -} - -void SkTextureCache::deleteAllCaches(bool texturesAreValid) { - this->validate(); - - Entry* entry = fHead; - while (entry) { - Entry* next = entry->fNext; - if (!texturesAreValid) { - entry->abandonTexture(); - } - SkDELETE(entry); - entry = next; - } - - fSorted.reset(); - bzero(fHash, sizeof(fHash)); - - fTexCount = 0; - fTexSize = 0; - - fTail = fHead = NULL; - - this->validate(); -} - -/////////////////////////////////////////////////////////////////////////////// - -int SkTextureCache::findInSorted(const Key& key) const { - int count = fSorted.count(); - if (count == 0) { - return ~0; - } - - Entry** sorted = fSorted.begin(); - int lo = 0; - int hi = count - 1; - while (lo < hi) { - int mid = (hi + lo) >> 1; - if (sorted[mid]->getKey() < key) { - lo = mid + 1; - } else { - hi = mid; - } - } - - // hi is now our best guess - const Entry* entry = sorted[hi]; - if (entry->getKey() == key) { - return hi; - } - - // return where to insert it - if (entry->getKey() < key) { - hi += 1; - } - return ~hi; // we twiddle to indicate not-found -} - -#ifdef TRACE_HASH_HITS -static int gHashHits; -static int gSortedHits; -#endif - -SkTextureCache::Entry* SkTextureCache::find(const Key& key, int* insert) const { - int count = fSorted.count(); - if (count == 0) { - *insert = 0; - return NULL; - } - - // check the hash first - int hashIndex = key.getHashIndex(); - Entry* entry = fHash[hashIndex]; - if (NULL != entry && entry->getKey() == key) { -#ifdef TRACE_HASH_HITS - gHashHits += 1; -#endif - return entry; - } - - int index = this->findInSorted(key); - if (index >= 0) { -#ifdef TRACE_HASH_HITS - gSortedHits += 1; -#endif - entry = fSorted[index]; - fHash[hashIndex] = entry; - return entry; - } - - // ~index is where to insert the entry - *insert = ~index; - return NULL; -} - -SkTextureCache::Entry* SkTextureCache::lock(const SkBitmap& bitmap) { - this->validate(); - - // call this before we call find(), so we don't reorder after find() and - // invalidate our index - this->purgeIfNecessary(SkGL::ComputeTextureMemorySize(bitmap)); - - Key key(bitmap); - int index; - Entry* entry = this->find(key, &index); - - if (NULL == entry) { - entry = SkNEW_ARGS(Entry, (bitmap)); - - entry->fName = SkGL::BindNewTexture(bitmap, &entry->fTexSize); - if (0 == entry->fName) { - SkDELETE(entry); - return NULL; - } - fHash[key.getHashIndex()] = entry; - *fSorted.insert(index) = entry; - - fTexCount += 1; - fTexSize += entry->memSize(); - } else { - // detach from our llist - Entry* prev = entry->fPrev; - Entry* next = entry->fNext; - if (prev) { - prev->fNext = next; - } else { - SkASSERT(fHead == entry); - fHead = next; - } - if (next) { - next->fPrev = prev; - } else { - SkASSERT(fTail == entry); - fTail = prev; - } - // now bind the texture - glBindTexture(GL_TEXTURE_2D, entry->fName); - } - - // add to head of llist for LRU - entry->fPrev = NULL; - entry->fNext = fHead; - if (NULL != fHead) { - SkASSERT(NULL == fHead->fPrev); - fHead->fPrev = entry; - } - fHead = entry; - if (NULL == fTail) { - fTail = entry; - } - - this->validate(); - entry->lock(); - -#ifdef TRACE_HASH_HITS - SkDebugf("---- texture cache hash=%d sorted=%d\n", gHashHits, gSortedHits); -#endif - return entry; -} - -void SkTextureCache::unlock(Entry* entry) { - this->validate(); - -#ifdef SK_DEBUG - SkASSERT(entry); - int index = this->findInSorted(entry->getKey()); - SkASSERT(fSorted[index] == entry); -#endif - - SkASSERT(entry->fLockCount > 0); - entry->unlock(); -} - -void SkTextureCache::purgeIfNecessary(size_t extraSize) { - this->validate(); - - size_t countMax = fTexCountMax; - size_t sizeMax = fTexSizeMax; - - // take extraSize into account, but watch for underflow of size_t - if (extraSize > sizeMax) { - sizeMax = 0; - } else { - sizeMax -= extraSize; - } - - Entry* entry = fTail; - while (entry) { - if (fTexCount <= countMax && fTexSize <= sizeMax) { - break; - } - - Entry* prev = entry->fPrev; - // don't purge an entry that is locked - if (entry->isLocked()) { - entry = prev; - continue; - } - - fTexCount -= 1; - fTexSize -= entry->memSize(); - - // remove from our sorted and hash arrays - int index = this->findInSorted(entry->getKey()); - SkASSERT(index >= 0); - fSorted.remove(index); - index = entry->getKey().getHashIndex(); - if (entry == fHash[index]) { - fHash[index] = NULL; - } - - // now detach it from our llist - Entry* next = entry->fNext; - if (prev) { - prev->fNext = next; - } else { - fHead = next; - } - if (next) { - next->fPrev = prev; - } else { - fTail = prev; - } - - // now delete it -#ifdef TRACE_TEXTURE_CACHE_PURGE - SkDebugf("---- purge texture cache %d size=%d\n", - entry->name(), entry->memSize()); -#endif - SkDELETE(entry); - - // keep going - entry = prev; - } - - this->validate(); -} - -void SkTextureCache::setMaxCount(size_t count) { - if (fTexCountMax != count) { - fTexCountMax = count; - this->purgeIfNecessary(0); - } -} - -void SkTextureCache::setMaxSize(size_t size) { - if (fTexSizeMax != size) { - fTexSizeMax = size; - this->purgeIfNecessary(0); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_DEBUG -void SkTextureCache::validate() const { - if (0 == fTexCount) { - SkASSERT(0 == fTexSize); - SkASSERT(NULL == fHead); - SkASSERT(NULL == fTail); - return; - } - - SkASSERT(fTexSize); // do we allow a zero-sized texture? - SkASSERT(fHead); - SkASSERT(fTail); - - SkASSERT(NULL == fHead->fPrev); - SkASSERT(NULL == fTail->fNext); - if (1 == fTexCount) { - SkASSERT(fHead == fTail); - } - - const Entry* entry = fHead; - size_t count = 0; - size_t size = 0; - size_t i; - - while (entry != NULL) { - SkASSERT(count < fTexCount); - SkASSERT(size < fTexSize); - size += entry->memSize(); - count += 1; - if (NULL == entry->fNext) { - SkASSERT(fTail == entry); - } - entry = entry->fNext; - } - SkASSERT(count == fTexCount); - SkASSERT(size == fTexSize); - - count = 0; - size = 0; - entry = fTail; - while (entry != NULL) { - SkASSERT(count < fTexCount); - SkASSERT(size < fTexSize); - size += entry->memSize(); - count += 1; - if (NULL == entry->fPrev) { - SkASSERT(fHead == entry); - } - entry = entry->fPrev; - } - SkASSERT(count == fTexCount); - SkASSERT(size == fTexSize); - - SkASSERT(count == (size_t)fSorted.count()); - for (i = 1; i < count; i++) { - SkASSERT(fSorted[i-1]->getKey() < fSorted[i]->getKey()); - } - - for (i = 0; i < kHashCount; i++) { - if (fHash[i]) { - size_t index = fHash[i]->getKey().getHashIndex(); - SkASSERT(index == i); - index = fSorted.find(fHash[i]); - SkASSERT((size_t)index < count); - } - } -} -#endif - - |