gfx/skia/trunk/src/effects/gradients/SkBitmapCache.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial