OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkLruImageCache.h" | 8 #include "SkLruImageCache.h" |
9 | 9 |
10 static intptr_t NextGenerationID() { | 10 static intptr_t NextGenerationID() { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 #endif | 67 #endif |
68 SkDELETE(pixels); | 68 SkDELETE(pixels); |
69 pixels = prev; | 69 pixels = prev; |
70 } | 70 } |
71 #ifdef SK_DEBUG | 71 #ifdef SK_DEBUG |
72 SkASSERT(fRamUsed == 0); | 72 SkASSERT(fRamUsed == 0); |
73 #endif | 73 #endif |
74 } | 74 } |
75 | 75 |
76 #ifdef SK_DEBUG | 76 #ifdef SK_DEBUG |
77 SkImageCache::CacheStatus SkLruImageCache::getCacheStatus(intptr_t ID) const { | 77 SkImageCache::MemoryStatus SkLruImageCache::getMemoryStatus(intptr_t ID) const { |
| 78 if (SkImageCache::UNINITIALIZED_ID == ID) { |
| 79 return SkImageCache::kFreed_MemoryStatus; |
| 80 } |
78 SkAutoMutexAcquire ac(&fMutex); | 81 SkAutoMutexAcquire ac(&fMutex); |
79 CachedPixels* pixels = this->findByID(ID); | 82 CachedPixels* pixels = this->findByID(ID); |
80 if (NULL == pixels) { | 83 if (NULL == pixels) { |
81 return SkImageCache::kThrownAway_CacheStatus; | 84 return SkImageCache::kFreed_MemoryStatus; |
82 } | 85 } |
83 if (pixels->isLocked()) { | 86 if (pixels->isLocked()) { |
84 return SkImageCache::kPinned_CacheStatus; | 87 return SkImageCache::kPinned_MemoryStatus; |
85 } | 88 } |
86 return SkImageCache::kUnpinned_CacheStatus; | 89 return SkImageCache::kUnpinned_MemoryStatus; |
| 90 } |
| 91 |
| 92 void SkLruImageCache::purgeAllUnpinnedCaches() { |
| 93 SkAutoMutexAcquire ac(&fMutex); |
| 94 this->purgeTilAtOrBelow(0); |
87 } | 95 } |
88 #endif | 96 #endif |
89 | 97 |
90 size_t SkLruImageCache::setImageCacheLimit(size_t newLimit) { | 98 size_t SkLruImageCache::setImageCacheLimit(size_t newLimit) { |
91 size_t oldLimit = fRamBudget; | 99 size_t oldLimit = fRamBudget; |
92 SkAutoMutexAcquire ac(&fMutex); | 100 SkAutoMutexAcquire ac(&fMutex); |
93 fRamBudget = newLimit; | 101 fRamBudget = newLimit; |
94 this->purgeIfNeeded(); | 102 this->purgeIfNeeded(); |
95 return oldLimit; | 103 return oldLimit; |
96 } | 104 } |
97 | 105 |
98 void* SkLruImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { | 106 void* SkLruImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { |
99 SkAutoMutexAcquire ac(&fMutex); | 107 SkAutoMutexAcquire ac(&fMutex); |
100 CachedPixels* pixels = SkNEW_ARGS(CachedPixels, (bytes)); | 108 CachedPixels* pixels = SkNEW_ARGS(CachedPixels, (bytes)); |
101 if (ID != NULL) { | 109 if (ID != NULL) { |
102 *ID = pixels->getID(); | 110 *ID = pixels->getID(); |
103 } | 111 } |
104 pixels->lock(); | 112 pixels->lock(); |
105 fRamUsed += bytes; | 113 fRamUsed += bytes; |
106 fLRU.addToHead(pixels); | 114 fLRU.addToHead(pixels); |
107 this->purgeIfNeeded(); | 115 this->purgeIfNeeded(); |
108 return pixels->getData(); | 116 return pixels->getData(); |
109 } | 117 } |
110 | 118 |
111 void* SkLruImageCache::pinCache(intptr_t ID) { | 119 void* SkLruImageCache::pinCache(intptr_t ID, SkImageCache::DataStatus* status) { |
112 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); | 120 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
113 SkAutoMutexAcquire ac(&fMutex); | 121 SkAutoMutexAcquire ac(&fMutex); |
114 CachedPixels* pixels = this->findByID(ID); | 122 CachedPixels* pixels = this->findByID(ID); |
115 if (NULL == pixels) { | 123 if (NULL == pixels) { |
116 return NULL; | 124 return NULL; |
117 } | 125 } |
118 if (pixels != fLRU.head()) { | 126 if (pixels != fLRU.head()) { |
119 fLRU.remove(pixels); | 127 fLRU.remove(pixels); |
120 fLRU.addToHead(pixels); | 128 fLRU.addToHead(pixels); |
121 } | 129 } |
| 130 SkASSERT(status != NULL); |
| 131 // This cache will never return pinned memory whose data has been overwritte
n. |
| 132 *status = SkImageCache::kRetained_DataStatus; |
122 pixels->lock(); | 133 pixels->lock(); |
123 return pixels->getData(); | 134 return pixels->getData(); |
124 } | 135 } |
125 | 136 |
126 void SkLruImageCache::releaseCache(intptr_t ID) { | 137 void SkLruImageCache::releaseCache(intptr_t ID) { |
127 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); | 138 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
128 SkAutoMutexAcquire ac(&fMutex); | 139 SkAutoMutexAcquire ac(&fMutex); |
129 CachedPixels* pixels = this->findByID(ID); | 140 CachedPixels* pixels = this->findByID(ID); |
130 SkASSERT(pixels != NULL); | 141 SkASSERT(pixels != NULL); |
131 pixels->unlock(); | 142 pixels->unlock(); |
132 this->purgeIfNeeded(); | 143 this->purgeIfNeeded(); |
133 } | 144 } |
134 | 145 |
135 void SkLruImageCache::throwAwayCache(intptr_t ID) { | 146 void SkLruImageCache::throwAwayCache(intptr_t ID) { |
| 147 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
136 SkAutoMutexAcquire ac(&fMutex); | 148 SkAutoMutexAcquire ac(&fMutex); |
137 CachedPixels* pixels = this->findByID(ID); | 149 CachedPixels* pixels = this->findByID(ID); |
138 if (pixels != NULL) { | 150 if (pixels != NULL) { |
139 if (pixels->isLocked()) { | 151 if (pixels->isLocked()) { |
140 pixels->unlock(); | 152 pixels->unlock(); |
141 } | 153 } |
142 this->removePixels(pixels); | 154 this->removePixels(pixels); |
143 } | 155 } |
144 } | 156 } |
145 | 157 |
146 void SkLruImageCache::removePixels(CachedPixels* pixels) { | 158 void SkLruImageCache::removePixels(CachedPixels* pixels) { |
147 // Mutex is already locked. | 159 // Mutex is already locked. |
148 SkASSERT(!pixels->isLocked()); | 160 SkASSERT(!pixels->isLocked()); |
149 const size_t size = pixels->getLength(); | 161 const size_t size = pixels->getLength(); |
150 SkASSERT(size <= fRamUsed); | 162 SkASSERT(size <= fRamUsed); |
151 fLRU.remove(pixels); | 163 fLRU.remove(pixels); |
152 SkDELETE(pixels); | 164 SkDELETE(pixels); |
153 fRamUsed -= size; | 165 fRamUsed -= size; |
154 } | 166 } |
155 | 167 |
156 CachedPixels* SkLruImageCache::findByID(intptr_t ID) const { | 168 CachedPixels* SkLruImageCache::findByID(intptr_t ID) const { |
157 // Mutex is already locked. | 169 // Mutex is already locked. |
158 if (SkImageCache::UNINITIALIZED_ID == ID) { | |
159 return NULL; | |
160 } | |
161 Iter iter; | 170 Iter iter; |
162 // Start from the head, most recently used. | 171 // Start from the head, most recently used. |
163 CachedPixels* pixels = iter.init(fLRU, Iter::kHead_IterStart); | 172 CachedPixels* pixels = iter.init(fLRU, Iter::kHead_IterStart); |
164 while (pixels != NULL) { | 173 while (pixels != NULL) { |
165 if (pixels->getID() == ID) { | 174 if (pixels->getID() == ID) { |
166 return pixels; | 175 return pixels; |
167 } | 176 } |
168 pixels = iter.next(); | 177 pixels = iter.next(); |
169 } | 178 } |
170 return NULL; | 179 return NULL; |
(...skipping 14 matching lines...) Expand all Loading... |
185 CachedPixels* pixels = iter.init(fLRU, Iter::kTail_IterStart); | 194 CachedPixels* pixels = iter.init(fLRU, Iter::kTail_IterStart); |
186 while (pixels != NULL && fRamUsed > limit) { | 195 while (pixels != NULL && fRamUsed > limit) { |
187 CachedPixels* prev = iter.prev(); | 196 CachedPixels* prev = iter.prev(); |
188 if (!pixels->isLocked()) { | 197 if (!pixels->isLocked()) { |
189 this->removePixels(pixels); | 198 this->removePixels(pixels); |
190 } | 199 } |
191 pixels = prev; | 200 pixels = prev; |
192 } | 201 } |
193 } | 202 } |
194 } | 203 } |
OLD | NEW |