| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "cc/prioritized_texture_manager.h" | 7 #include "cc/prioritized_texture_manager.h" |
| 8 | 8 |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "cc/prioritized_texture.h" | 11 #include "cc/prioritized_texture.h" |
| 12 #include "cc/priority_calculator.h" | 12 #include "cc/priority_calculator.h" |
| 13 #include "cc/proxy.h" | 13 #include "cc/proxy.h" |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 | 15 |
| 16 using namespace std; | 16 using namespace std; |
| 17 | 17 |
| 18 namespace cc { | 18 namespace cc { |
| 19 | 19 |
| 20 PrioritizedTextureManager::PrioritizedTextureManager(size_t maxMemoryLimitBytes,
int, int pool) | 20 PrioritizedTextureManager::PrioritizedTextureManager(size_t maxMemoryLimitBytes,
int, int pool, const Proxy* proxy) |
| 21 : m_maxMemoryLimitBytes(maxMemoryLimitBytes) | 21 : m_proxy(proxy) |
| 22 , m_maxMemoryLimitBytes(maxMemoryLimitBytes) |
| 22 , m_externalPriorityCutoff(PriorityCalculator::allowEverythingCutoff()) | 23 , m_externalPriorityCutoff(PriorityCalculator::allowEverythingCutoff()) |
| 23 , m_memoryUseBytes(0) | 24 , m_memoryUseBytes(0) |
| 24 , m_memoryAboveCutoffBytes(0) | 25 , m_memoryAboveCutoffBytes(0) |
| 25 , m_memoryAvailableBytes(0) | 26 , m_memoryAvailableBytes(0) |
| 26 , m_pool(pool) | 27 , m_pool(pool) |
| 27 , m_backingsTailNotSorted(false) | 28 , m_backingsTailNotSorted(false) |
| 28 { | 29 { |
| 29 } | 30 } |
| 30 | 31 |
| 31 PrioritizedTextureManager::~PrioritizedTextureManager() | 32 PrioritizedTextureManager::~PrioritizedTextureManager() |
| 32 { | 33 { |
| 33 while (m_textures.size() > 0) | 34 while (m_textures.size() > 0) |
| 34 unregisterTexture(*m_textures.begin()); | 35 unregisterTexture(*m_textures.begin()); |
| 35 | 36 |
| 36 deleteUnlinkedEvictedBackings(); | 37 deleteUnlinkedEvictedBackings(); |
| 37 DCHECK(m_evictedBackings.empty()); | 38 DCHECK(m_evictedBackings.empty()); |
| 38 | 39 |
| 39 // Each remaining backing is a leaked opengl texture. There should be none. | 40 // Each remaining backing is a leaked opengl texture. There should be none. |
| 40 DCHECK(m_backings.empty()); | 41 DCHECK(m_backings.empty()); |
| 41 } | 42 } |
| 42 | 43 |
| 43 void PrioritizedTextureManager::prioritizeTextures() | 44 void PrioritizedTextureManager::prioritizeTextures() |
| 44 { | 45 { |
| 45 TRACE_EVENT0("cc", "PrioritizedTextureManager::prioritizeTextures"); | 46 TRACE_EVENT0("cc", "PrioritizedTextureManager::prioritizeTextures"); |
| 46 DCHECK(Proxy::isMainThread()); | 47 DCHECK(m_proxy->isMainThread()); |
| 47 | 48 |
| 48 // Sorting textures in this function could be replaced by a slightly | 49 // Sorting textures in this function could be replaced by a slightly |
| 49 // modified O(n) quick-select to partition textures rather than | 50 // modified O(n) quick-select to partition textures rather than |
| 50 // sort them (if performance of the sort becomes an issue). | 51 // sort them (if performance of the sort becomes an issue). |
| 51 | 52 |
| 52 TextureVector& sortedTextures = m_tempTextureVector; | 53 TextureVector& sortedTextures = m_tempTextureVector; |
| 53 sortedTextures.clear(); | 54 sortedTextures.clear(); |
| 54 | 55 |
| 55 // Copy all textures into a vector and sort them. | 56 // Copy all textures into a vector and sort them. |
| 56 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) | 57 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 } | 105 } |
| 105 sortedTextures.clear(); | 106 sortedTextures.clear(); |
| 106 | 107 |
| 107 DCHECK(m_memoryAboveCutoffBytes <= m_memoryAvailableBytes); | 108 DCHECK(m_memoryAboveCutoffBytes <= m_memoryAvailableBytes); |
| 108 DCHECK(memoryAboveCutoffBytes() <= maxMemoryLimitBytes()); | 109 DCHECK(memoryAboveCutoffBytes() <= maxMemoryLimitBytes()); |
| 109 } | 110 } |
| 110 | 111 |
| 111 void PrioritizedTextureManager::pushTexturePrioritiesToBackings() | 112 void PrioritizedTextureManager::pushTexturePrioritiesToBackings() |
| 112 { | 113 { |
| 113 TRACE_EVENT0("cc", "PrioritizedTextureManager::pushTexturePrioritiesToBackin
gs"); | 114 TRACE_EVENT0("cc", "PrioritizedTextureManager::pushTexturePrioritiesToBackin
gs"); |
| 114 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 115 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 115 | 116 |
| 116 assertInvariants(); | 117 assertInvariants(); |
| 117 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) | 118 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) |
| 118 (*it)->updatePriority(); | 119 (*it)->updatePriority(); |
| 119 sortBackings(); | 120 sortBackings(); |
| 120 assertInvariants(); | 121 assertInvariants(); |
| 121 } | 122 } |
| 122 | 123 |
| 123 void PrioritizedTextureManager::updateBackingsInDrawingImplTree() | 124 void PrioritizedTextureManager::updateBackingsInDrawingImplTree() |
| 124 { | 125 { |
| 125 TRACE_EVENT0("cc", "PrioritizedTextureManager::updateBackingsInDrawingImplTr
ee"); | 126 TRACE_EVENT0("cc", "PrioritizedTextureManager::updateBackingsInDrawingImplTr
ee"); |
| 126 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 127 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 127 | 128 |
| 128 assertInvariants(); | 129 assertInvariants(); |
| 129 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { | 130 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { |
| 130 PrioritizedTexture::Backing* backing = (*it); | 131 PrioritizedTexture::Backing* backing = (*it); |
| 131 backing->updateInDrawingImplTree(); | 132 backing->updateInDrawingImplTree(); |
| 132 } | 133 } |
| 133 sortBackings(); | 134 sortBackings(); |
| 134 assertInvariants(); | 135 assertInvariants(); |
| 135 } | 136 } |
| 136 | 137 |
| 137 void PrioritizedTextureManager::sortBackings() | 138 void PrioritizedTextureManager::sortBackings() |
| 138 { | 139 { |
| 139 TRACE_EVENT0("cc", "PrioritizedTextureManager::sortBackings"); | 140 TRACE_EVENT0("cc", "PrioritizedTextureManager::sortBackings"); |
| 140 DCHECK(Proxy::isImplThread()); | 141 DCHECK(m_proxy->isImplThread()); |
| 141 | 142 |
| 142 // Put backings in eviction/recycling order. | 143 // Put backings in eviction/recycling order. |
| 143 m_backings.sort(compareBackings); | 144 m_backings.sort(compareBackings); |
| 144 m_backingsTailNotSorted = false; | 145 m_backingsTailNotSorted = false; |
| 145 } | 146 } |
| 146 | 147 |
| 147 void PrioritizedTextureManager::clearPriorities() | 148 void PrioritizedTextureManager::clearPriorities() |
| 148 { | 149 { |
| 149 DCHECK(Proxy::isMainThread()); | 150 DCHECK(m_proxy->isMainThread()); |
| 150 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { | 151 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { |
| 151 // FIXME: We should remove this and just set all priorities to | 152 // FIXME: We should remove this and just set all priorities to |
| 152 // PriorityCalculator::lowestPriority() once we have priorities | 153 // PriorityCalculator::lowestPriority() once we have priorities |
| 153 // for all textures (we can't currently calculate distances for | 154 // for all textures (we can't currently calculate distances for |
| 154 // off-screen textures). | 155 // off-screen textures). |
| 155 (*it)->setRequestPriority(PriorityCalculator::lingeringPriority((*it)->r
equestPriority())); | 156 (*it)->setRequestPriority(PriorityCalculator::lingeringPriority((*it)->r
equestPriority())); |
| 156 } | 157 } |
| 157 } | 158 } |
| 158 | 159 |
| 159 bool PrioritizedTextureManager::requestLate(PrioritizedTexture* texture) | 160 bool PrioritizedTextureManager::requestLate(PrioritizedTexture* texture) |
| 160 { | 161 { |
| 161 DCHECK(Proxy::isMainThread()); | 162 DCHECK(m_proxy->isMainThread()); |
| 162 | 163 |
| 163 // This is already above cutoff, so don't double count it's memory below. | 164 // This is already above cutoff, so don't double count it's memory below. |
| 164 if (texture->isAbovePriorityCutoff()) | 165 if (texture->isAbovePriorityCutoff()) |
| 165 return true; | 166 return true; |
| 166 | 167 |
| 167 // Allow textures that have priority equal to the cutoff, but not strictly l
ower. | 168 // Allow textures that have priority equal to the cutoff, but not strictly l
ower. |
| 168 if (PriorityCalculator::priorityIsLower(texture->requestPriority(), m_priori
tyCutoff)) | 169 if (PriorityCalculator::priorityIsLower(texture->requestPriority(), m_priori
tyCutoff)) |
| 169 return false; | 170 return false; |
| 170 | 171 |
| 171 // Disallow textures that do not have a priority strictly higher than the ex
ternal cutoff. | 172 // Disallow textures that do not have a priority strictly higher than the ex
ternal cutoff. |
| 172 if (!PriorityCalculator::priorityIsHigher(texture->requestPriority(), m_exte
rnalPriorityCutoff)) | 173 if (!PriorityCalculator::priorityIsHigher(texture->requestPriority(), m_exte
rnalPriorityCutoff)) |
| 173 return false; | 174 return false; |
| 174 | 175 |
| 175 size_t newMemoryBytes = m_memoryAboveCutoffBytes + texture->bytes(); | 176 size_t newMemoryBytes = m_memoryAboveCutoffBytes + texture->bytes(); |
| 176 if (newMemoryBytes > m_memoryAvailableBytes) | 177 if (newMemoryBytes > m_memoryAvailableBytes) |
| 177 return false; | 178 return false; |
| 178 | 179 |
| 179 m_memoryAboveCutoffBytes = newMemoryBytes; | 180 m_memoryAboveCutoffBytes = newMemoryBytes; |
| 180 texture->setAbovePriorityCutoff(true); | 181 texture->setAbovePriorityCutoff(true); |
| 181 return true; | 182 return true; |
| 182 } | 183 } |
| 183 | 184 |
| 184 void PrioritizedTextureManager::acquireBackingTextureIfNeeded(PrioritizedTexture
* texture, ResourceProvider* resourceProvider) | 185 void PrioritizedTextureManager::acquireBackingTextureIfNeeded(PrioritizedTexture
* texture, ResourceProvider* resourceProvider) |
| 185 { | 186 { |
| 186 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 187 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 187 DCHECK(!texture->isSelfManaged()); | 188 DCHECK(!texture->isSelfManaged()); |
| 188 DCHECK(texture->isAbovePriorityCutoff()); | 189 DCHECK(texture->isAbovePriorityCutoff()); |
| 189 if (texture->backing() || !texture->isAbovePriorityCutoff()) | 190 if (texture->backing() || !texture->isAbovePriorityCutoff()) |
| 190 return; | 191 return; |
| 191 | 192 |
| 192 // Find a backing below, by either recycling or allocating. | 193 // Find a backing below, by either recycling or allocating. |
| 193 PrioritizedTexture::Backing* backing = 0; | 194 PrioritizedTexture::Backing* backing = 0; |
| 194 | 195 |
| 195 // First try to recycle | 196 // First try to recycle |
| 196 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { | 197 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 216 texture->link(backing); | 217 texture->link(backing); |
| 217 m_backings.push_back(backing); | 218 m_backings.push_back(backing); |
| 218 m_backingsTailNotSorted = true; | 219 m_backingsTailNotSorted = true; |
| 219 | 220 |
| 220 // Update the backing's priority from its new owner. | 221 // Update the backing's priority from its new owner. |
| 221 backing->updatePriority(); | 222 backing->updatePriority(); |
| 222 } | 223 } |
| 223 | 224 |
| 224 bool PrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, i
nt priorityCutoff, EvictionPolicy evictionPolicy, ResourceProvider* resourceProv
ider) | 225 bool PrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, i
nt priorityCutoff, EvictionPolicy evictionPolicy, ResourceProvider* resourceProv
ider) |
| 225 { | 226 { |
| 226 DCHECK(Proxy::isImplThread()); | 227 DCHECK(m_proxy->isImplThread()); |
| 227 if (memoryUseBytes() <= limitBytes && PriorityCalculator::allowEverythingCut
off() == priorityCutoff) | 228 if (memoryUseBytes() <= limitBytes && PriorityCalculator::allowEverythingCut
off() == priorityCutoff) |
| 228 return false; | 229 return false; |
| 229 | 230 |
| 230 // Destroy backings until we are below the limit, | 231 // Destroy backings until we are below the limit, |
| 231 // or until all backings remaining are above the cutoff. | 232 // or until all backings remaining are above the cutoff. |
| 232 while (m_backings.size() > 0) { | 233 while (m_backings.size() > 0) { |
| 233 PrioritizedTexture::Backing* backing = m_backings.front(); | 234 PrioritizedTexture::Backing* backing = m_backings.front(); |
| 234 if (memoryUseBytes() <= limitBytes && | 235 if (memoryUseBytes() <= limitBytes && |
| 235 PriorityCalculator::priorityIsHigher(backing->requestPriorityAtLastP
riorityUpdate(), priorityCutoff)) | 236 PriorityCalculator::priorityIsHigher(backing->requestPriorityAtLastP
riorityUpdate(), priorityCutoff)) |
| 236 break; | 237 break; |
| 237 if (evictionPolicy == EvictOnlyRecyclable && !backing->canBeRecycled()) | 238 if (evictionPolicy == EvictOnlyRecyclable && !backing->canBeRecycled()) |
| 238 break; | 239 break; |
| 239 evictFirstBackingResource(resourceProvider); | 240 evictFirstBackingResource(resourceProvider); |
| 240 } | 241 } |
| 241 return true; | 242 return true; |
| 242 } | 243 } |
| 243 | 244 |
| 244 void PrioritizedTextureManager::reduceMemory(ResourceProvider* resourceProvider) | 245 void PrioritizedTextureManager::reduceMemory(ResourceProvider* resourceProvider) |
| 245 { | 246 { |
| 246 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 247 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 247 | 248 |
| 248 evictBackingsToReduceMemory(m_memoryAvailableBytes, PriorityCalculator::allo
wEverythingCutoff(), EvictOnlyRecyclable, resourceProvider); | 249 evictBackingsToReduceMemory(m_memoryAvailableBytes, PriorityCalculator::allo
wEverythingCutoff(), EvictOnlyRecyclable, resourceProvider); |
| 249 DCHECK(memoryUseBytes() <= maxMemoryLimitBytes()); | 250 DCHECK(memoryUseBytes() <= maxMemoryLimitBytes()); |
| 250 | 251 |
| 251 // We currently collect backings from deleted textures for later recycling. | 252 // We currently collect backings from deleted textures for later recycling. |
| 252 // However, if we do that forever we will always use the max limit even if | 253 // However, if we do that forever we will always use the max limit even if |
| 253 // we really need very little memory. This should probably be solved by redu
cing the | 254 // we really need very little memory. This should probably be solved by redu
cing the |
| 254 // limit externally, but until then this just does some "clean up" of unused | 255 // limit externally, but until then this just does some "clean up" of unused |
| 255 // backing textures (any more than 10%). | 256 // backing textures (any more than 10%). |
| 256 size_t wastedMemory = 0; | 257 size_t wastedMemory = 0; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 268 if ((*it)->owner()) | 269 if ((*it)->owner()) |
| 269 (*it)->owner()->unlink(); | 270 (*it)->owner()->unlink(); |
| 270 } | 271 } |
| 271 | 272 |
| 272 // And clear the list of evicted backings | 273 // And clear the list of evicted backings |
| 273 deleteUnlinkedEvictedBackings(); | 274 deleteUnlinkedEvictedBackings(); |
| 274 } | 275 } |
| 275 | 276 |
| 276 void PrioritizedTextureManager::clearAllMemory(ResourceProvider* resourceProvide
r) | 277 void PrioritizedTextureManager::clearAllMemory(ResourceProvider* resourceProvide
r) |
| 277 { | 278 { |
| 278 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 279 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 279 DCHECK(resourceProvider); | 280 DCHECK(resourceProvider); |
| 280 evictBackingsToReduceMemory(0, PriorityCalculator::allowEverythingCutoff(),
EvictAnything, resourceProvider); | 281 evictBackingsToReduceMemory(0, PriorityCalculator::allowEverythingCutoff(),
EvictAnything, resourceProvider); |
| 281 } | 282 } |
| 282 | 283 |
| 283 bool PrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) | 284 bool PrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) |
| 284 { | 285 { |
| 285 DCHECK(Proxy::isImplThread()); | 286 DCHECK(m_proxy->isImplThread()); |
| 286 DCHECK(resourceProvider); | 287 DCHECK(resourceProvider); |
| 287 // If we are in the process of uploading a new frame then the backings at th
e very end of | 288 // If we are in the process of uploading a new frame then the backings at th
e very end of |
| 288 // the list are not sorted by priority. Sort them before doing the eviction. | 289 // the list are not sorted by priority. Sort them before doing the eviction. |
| 289 if (m_backingsTailNotSorted) | 290 if (m_backingsTailNotSorted) |
| 290 sortBackings(); | 291 sortBackings(); |
| 291 return evictBackingsToReduceMemory(limitBytes, priorityCutoff, EvictAnything
, resourceProvider); | 292 return evictBackingsToReduceMemory(limitBytes, priorityCutoff, EvictAnything
, resourceProvider); |
| 292 } | 293 } |
| 293 | 294 |
| 294 void PrioritizedTextureManager::getEvictedBackings(BackingList& evictedBackings) | 295 void PrioritizedTextureManager::getEvictedBackings(BackingList& evictedBackings) |
| 295 { | 296 { |
| 296 DCHECK(Proxy::isImplThread()); | 297 DCHECK(m_proxy->isImplThread()); |
| 297 evictedBackings.clear(); | 298 evictedBackings.clear(); |
| 298 evictedBackings.insert(evictedBackings.begin(), m_evictedBackings.begin(), m
_evictedBackings.end()); | 299 evictedBackings.insert(evictedBackings.begin(), m_evictedBackings.begin(), m
_evictedBackings.end()); |
| 299 } | 300 } |
| 300 | 301 |
| 301 void PrioritizedTextureManager::unlinkEvictedBackings(const BackingList& evicted
Backings) | 302 void PrioritizedTextureManager::unlinkEvictedBackings(const BackingList& evicted
Backings) |
| 302 { | 303 { |
| 303 DCHECK(Proxy::isMainThread()); | 304 DCHECK(m_proxy->isMainThread()); |
| 304 for (BackingList::const_iterator it = evictedBackings.begin(); it != evicted
Backings.end(); ++it) { | 305 for (BackingList::const_iterator it = evictedBackings.begin(); it != evicted
Backings.end(); ++it) { |
| 305 PrioritizedTexture::Backing* backing = (*it); | 306 PrioritizedTexture::Backing* backing = (*it); |
| 306 if (backing->owner()) | 307 if (backing->owner()) |
| 307 backing->owner()->unlink(); | 308 backing->owner()->unlink(); |
| 308 } | 309 } |
| 309 } | 310 } |
| 310 | 311 |
| 311 void PrioritizedTextureManager::deleteUnlinkedEvictedBackings() | 312 void PrioritizedTextureManager::deleteUnlinkedEvictedBackings() |
| 312 { | 313 { |
| 313 DCHECK(Proxy::isMainThread() || (Proxy::isImplThread() && Proxy::isMainThrea
dBlocked())); | 314 DCHECK(m_proxy->isMainThread() || (m_proxy->isImplThread() && m_proxy->isMai
nThreadBlocked())); |
| 314 BackingList newEvictedBackings; | 315 BackingList newEvictedBackings; |
| 315 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | 316 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
| 316 PrioritizedTexture::Backing* backing = (*it); | 317 PrioritizedTexture::Backing* backing = (*it); |
| 317 if (backing->owner()) | 318 if (backing->owner()) |
| 318 newEvictedBackings.push_back(backing); | 319 newEvictedBackings.push_back(backing); |
| 319 else | 320 else |
| 320 delete backing; | 321 delete backing; |
| 321 } | 322 } |
| 322 m_evictedBackings.swap(newEvictedBackings); | 323 m_evictedBackings.swap(newEvictedBackings); |
| 323 } | 324 } |
| 324 | 325 |
| 325 bool PrioritizedTextureManager::linkedEvictedBackingsExist() const | 326 bool PrioritizedTextureManager::linkedEvictedBackingsExist() const |
| 326 { | 327 { |
| 327 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | 328 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
| 328 if ((*it)->owner()) | 329 if ((*it)->owner()) |
| 329 return true; | 330 return true; |
| 330 } | 331 } |
| 331 return false; | 332 return false; |
| 332 } | 333 } |
| 333 | 334 |
| 334 void PrioritizedTextureManager::registerTexture(PrioritizedTexture* texture) | 335 void PrioritizedTextureManager::registerTexture(PrioritizedTexture* texture) |
| 335 { | 336 { |
| 336 DCHECK(Proxy::isMainThread()); | 337 DCHECK(m_proxy->isMainThread()); |
| 337 DCHECK(texture); | 338 DCHECK(texture); |
| 338 DCHECK(!texture->textureManager()); | 339 DCHECK(!texture->textureManager()); |
| 339 DCHECK(!texture->backing()); | 340 DCHECK(!texture->backing()); |
| 340 DCHECK(!ContainsKey(m_textures, texture)); | 341 DCHECK(!ContainsKey(m_textures, texture)); |
| 341 | 342 |
| 342 texture->setManagerInternal(this); | 343 texture->setManagerInternal(this); |
| 343 m_textures.insert(texture); | 344 m_textures.insert(texture); |
| 344 | 345 |
| 345 } | 346 } |
| 346 | 347 |
| 347 void PrioritizedTextureManager::unregisterTexture(PrioritizedTexture* texture) | 348 void PrioritizedTextureManager::unregisterTexture(PrioritizedTexture* texture) |
| 348 { | 349 { |
| 349 DCHECK(Proxy::isMainThread() || (Proxy::isImplThread() && Proxy::isMainThrea
dBlocked())); | 350 DCHECK(m_proxy->isMainThread() || (m_proxy->isImplThread() && m_proxy->isMai
nThreadBlocked())); |
| 350 DCHECK(texture); | 351 DCHECK(texture); |
| 351 DCHECK(ContainsKey(m_textures, texture)); | 352 DCHECK(ContainsKey(m_textures, texture)); |
| 352 | 353 |
| 353 returnBackingTexture(texture); | 354 returnBackingTexture(texture); |
| 354 texture->setManagerInternal(0); | 355 texture->setManagerInternal(0); |
| 355 m_textures.erase(texture); | 356 m_textures.erase(texture); |
| 356 texture->setAbovePriorityCutoff(false); | 357 texture->setAbovePriorityCutoff(false); |
| 357 } | 358 } |
| 358 | 359 |
| 359 void PrioritizedTextureManager::returnBackingTexture(PrioritizedTexture* texture
) | 360 void PrioritizedTextureManager::returnBackingTexture(PrioritizedTexture* texture
) |
| 360 { | 361 { |
| 361 DCHECK(Proxy::isMainThread() || (Proxy::isImplThread() && Proxy::isMainThrea
dBlocked())); | 362 DCHECK(m_proxy->isMainThread() || (m_proxy->isImplThread() && m_proxy->isMai
nThreadBlocked())); |
| 362 if (texture->backing()) | 363 if (texture->backing()) |
| 363 texture->unlink(); | 364 texture->unlink(); |
| 364 } | 365 } |
| 365 | 366 |
| 366 PrioritizedTexture::Backing* PrioritizedTextureManager::createBacking(IntSize si
ze, GLenum format, ResourceProvider* resourceProvider) | 367 PrioritizedTexture::Backing* PrioritizedTextureManager::createBacking(IntSize si
ze, GLenum format, ResourceProvider* resourceProvider) |
| 367 { | 368 { |
| 368 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 369 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 369 DCHECK(resourceProvider); | 370 DCHECK(resourceProvider); |
| 370 ResourceProvider::ResourceId resourceId = resourceProvider->createResource(m
_pool, size, format, ResourceProvider::TextureUsageAny); | 371 ResourceProvider::ResourceId resourceId = resourceProvider->createResource(m
_pool, size, format, ResourceProvider::TextureUsageAny); |
| 371 PrioritizedTexture::Backing* backing = new PrioritizedTexture::Backing(resou
rceId, resourceProvider, size, format); | 372 PrioritizedTexture::Backing* backing = new PrioritizedTexture::Backing(resou
rceId, resourceProvider, size, format); |
| 372 m_memoryUseBytes += backing->bytes(); | 373 m_memoryUseBytes += backing->bytes(); |
| 373 return backing; | 374 return backing; |
| 374 } | 375 } |
| 375 | 376 |
| 376 void PrioritizedTextureManager::evictFirstBackingResource(ResourceProvider* reso
urceProvider) | 377 void PrioritizedTextureManager::evictFirstBackingResource(ResourceProvider* reso
urceProvider) |
| 377 { | 378 { |
| 378 DCHECK(Proxy::isImplThread()); | 379 DCHECK(m_proxy->isImplThread()); |
| 379 DCHECK(resourceProvider); | 380 DCHECK(resourceProvider); |
| 380 DCHECK(!m_backings.empty()); | 381 DCHECK(!m_backings.empty()); |
| 381 PrioritizedTexture::Backing* backing = m_backings.front(); | 382 PrioritizedTexture::Backing* backing = m_backings.front(); |
| 382 | 383 |
| 383 // Note that we create a backing and its resource at the same time, but we | 384 // Note that we create a backing and its resource at the same time, but we |
| 384 // delete the backing structure and its resource in two steps. This is becau
se | 385 // delete the backing structure and its resource in two steps. This is becau
se |
| 385 // we can delete the resource while the main thread is running, but we canno
t | 386 // we can delete the resource while the main thread is running, but we canno
t |
| 386 // unlink backings while the main thread is running. | 387 // unlink backings while the main thread is running. |
| 387 backing->deleteResource(resourceProvider); | 388 backing->deleteResource(resourceProvider); |
| 388 m_memoryUseBytes -= backing->bytes(); | 389 m_memoryUseBytes -= backing->bytes(); |
| 389 m_backings.pop_front(); | 390 m_backings.pop_front(); |
| 390 m_evictedBackings.push_back(backing); | 391 m_evictedBackings.push_back(backing); |
| 391 } | 392 } |
| 392 | 393 |
| 393 void PrioritizedTextureManager::assertInvariants() | 394 void PrioritizedTextureManager::assertInvariants() |
| 394 { | 395 { |
| 395 #ifndef NDEBUG | 396 #ifndef NDEBUG |
| 396 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 397 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 397 | 398 |
| 398 // If we hit any of these asserts, there is a bug in this class. To see | 399 // If we hit any of these asserts, there is a bug in this class. To see |
| 399 // where the bug is, call this function at the beginning and end of | 400 // where the bug is, call this function at the beginning and end of |
| 400 // every public function. | 401 // every public function. |
| 401 | 402 |
| 402 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. | 403 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. |
| 403 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { | 404 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { |
| 404 if ((*it)->owner()) { | 405 if ((*it)->owner()) { |
| 405 DCHECK(ContainsKey(m_textures, (*it)->owner())); | 406 DCHECK(ContainsKey(m_textures, (*it)->owner())); |
| 406 DCHECK((*it)->owner()->backing() == (*it)); | 407 DCHECK((*it)->owner()->backing() == (*it)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 435 if (reachedUnrecyclable) | 436 if (reachedUnrecyclable) |
| 436 DCHECK(!backing->canBeRecycled()); | 437 DCHECK(!backing->canBeRecycled()); |
| 437 else | 438 else |
| 438 DCHECK(backing->canBeRecycled()); | 439 DCHECK(backing->canBeRecycled()); |
| 439 previous_backing = backing; | 440 previous_backing = backing; |
| 440 } | 441 } |
| 441 #endif | 442 #endif |
| 442 } | 443 } |
| 443 | 444 |
| 444 } // namespace cc | 445 } // namespace cc |
| OLD | NEW |