157c3a863fce929a96463ab24318006f8b2afcc7areed@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com */ 8dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 10a6cac4ce3896669e1b5935def0a84b4456ec9777reed#include "SkGradientBitmapCache.h" 11dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 12a6cac4ce3896669e1b5935def0a84b4456ec9777reedstruct SkGradientBitmapCache::Entry { 13dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* fPrev; 14dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* fNext; 15dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 16dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com void* fBuffer; 17dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com size_t fSize; 18dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkBitmap fBitmap; 19dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 203c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org Entry(const void* buffer, size_t size, const SkBitmap& bm) 212880df2609eba09b555ca37be04b6ad89290c765Tom Hudson : fPrev(nullptr), 222880df2609eba09b555ca37be04b6ad89290c765Tom Hudson fNext(nullptr), 233c898186c9082c535e589807752a0a9dc5d28aa0vandebo@chromium.org fBitmap(bm) { 24dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fBuffer = sk_malloc_throw(size); 25dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fSize = size; 26dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com memcpy(fBuffer, buffer, size); 27dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 28dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 29dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com ~Entry() { sk_free(fBuffer); } 30dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 31dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com bool equals(const void* buffer, size_t size) const { 32dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com return (fSize == size) && !memcmp(fBuffer, buffer, size); 33dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 34dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com}; 35dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 36a6cac4ce3896669e1b5935def0a84b4456ec9777reedSkGradientBitmapCache::SkGradientBitmapCache(int max) : fMaxEntries(max) { 37dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fEntryCount = 0; 382880df2609eba09b555ca37be04b6ad89290c765Tom Hudson fHead = fTail = nullptr; 39dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 40dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com this->validate(); 41dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 42dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 43a6cac4ce3896669e1b5935def0a84b4456ec9777reedSkGradientBitmapCache::~SkGradientBitmapCache() { 44dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com this->validate(); 45dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 46dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* entry = fHead; 47dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com while (entry) { 48dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* next = entry->fNext; 49dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com delete entry; 50dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry = next; 51dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 52dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 53dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 54a6cac4ce3896669e1b5935def0a84b4456ec9777reedSkGradientBitmapCache::Entry* SkGradientBitmapCache::detach(Entry* entry) const { 55dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (entry->fPrev) { 56dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fHead != entry); 57dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry->fPrev->fNext = entry->fNext; 58dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } else { 59dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fHead == entry); 60dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fHead = entry->fNext; 61dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 62dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (entry->fNext) { 63dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fTail != entry); 64dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry->fNext->fPrev = entry->fPrev; 65dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } else { 66dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fTail == entry); 67dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fTail = entry->fPrev; 68dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 69dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com return entry; 70dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 71dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 72a6cac4ce3896669e1b5935def0a84b4456ec9777reedvoid SkGradientBitmapCache::attachToHead(Entry* entry) const { 732880df2609eba09b555ca37be04b6ad89290c765Tom Hudson entry->fPrev = nullptr; 74dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry->fNext = fHead; 75dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (fHead) { 76dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fHead->fPrev = entry; 77dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } else { 78dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fTail = entry; 79dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 80dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fHead = entry; 81dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 82dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 83a6cac4ce3896669e1b5935def0a84b4456ec9777reedbool SkGradientBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const { 84dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com AutoValidate av(this); 85dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 86dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* entry = fHead; 87dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com while (entry) { 88dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (entry->equals(buffer, size)) { 89dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (bm) { 90dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com *bm = entry->fBitmap; 91dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 92dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com // move to the head of our list, so we purge it last 93dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com this->detach(entry); 94dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com this->attachToHead(entry); 95dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com return true; 96dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 97dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry = entry->fNext; 98dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 99dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com return false; 100dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 101dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 102a6cac4ce3896669e1b5935def0a84b4456ec9777reedvoid SkGradientBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) { 103dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com AutoValidate av(this); 104e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com 105dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (fEntryCount == fMaxEntries) { 106e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com SkASSERT(fTail); 107e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com delete this->detach(fTail); 108e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com fEntryCount -= 1; 109dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 110dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 1112880df2609eba09b555ca37be04b6ad89290c765Tom Hudson Entry* entry = new Entry(buffer, len, bm); 112dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com this->attachToHead(entry); 113dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com fEntryCount += 1; 114dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 115dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 116dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com/////////////////////////////////////////////////////////////////////////////// 117dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 118dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com#ifdef SK_DEBUG 119dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 120a6cac4ce3896669e1b5935def0a84b4456ec9777reedvoid SkGradientBitmapCache::validate() const { 121dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries); 122e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com 123dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (fEntryCount > 0) { 1242880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkASSERT(nullptr == fHead->fPrev); 1252880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkASSERT(nullptr == fTail->fNext); 126dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 127dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com if (fEntryCount == 1) { 128dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fHead == fTail); 129dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } else { 130dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(fHead != fTail); 131dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 132dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 133dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com Entry* entry = fHead; 134dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com int count = 0; 135dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com while (entry) { 136dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com count += 1; 137dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry = entry->fNext; 138dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 139dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(count == fEntryCount); 140e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com 141dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry = fTail; 142dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com while (entry) { 143dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com count -= 1; 144dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com entry = entry->fPrev; 145dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } 146dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com SkASSERT(0 == count); 147dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com } else { 1482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkASSERT(nullptr == fHead); 1492880df2609eba09b555ca37be04b6ad89290c765Tom Hudson SkASSERT(nullptr == fTail); 150e49d57117507903a7d912218b4e1ebd2f15bbbd7reed@google.com } 151dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com} 152dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com 153dc731fd4830380a01664b99f7a23df4bfca71facreed@google.com#endif 154