| 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" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 , m_memoryVisibleLastPushedBytes(0) | 30 , m_memoryVisibleLastPushedBytes(0) |
| 31 , m_memoryVisibleAndNearbyLastPushedBytes(0) | 31 , m_memoryVisibleAndNearbyLastPushedBytes(0) |
| 32 { | 32 { |
| 33 } | 33 } |
| 34 | 34 |
| 35 PrioritizedTextureManager::~PrioritizedTextureManager() | 35 PrioritizedTextureManager::~PrioritizedTextureManager() |
| 36 { | 36 { |
| 37 while (m_textures.size() > 0) | 37 while (m_textures.size() > 0) |
| 38 unregisterTexture(*m_textures.begin()); | 38 unregisterTexture(*m_textures.begin()); |
| 39 | 39 |
| 40 deleteUnlinkedEvictedBackings(); | 40 unlinkAndClearEvictedBackings(); |
| 41 DCHECK(m_evictedBackings.empty()); | 41 DCHECK(m_evictedBackings.empty()); |
| 42 | 42 |
| 43 // Each remaining backing is a leaked opengl texture. There should be none. | 43 // Each remaining backing is a leaked opengl texture. There should be none. |
| 44 DCHECK(m_backings.empty()); | 44 DCHECK(m_backings.empty()); |
| 45 } | 45 } |
| 46 | 46 |
| 47 size_t PrioritizedTextureManager::memoryVisibleBytes() const | 47 size_t PrioritizedTextureManager::memoryVisibleBytes() const |
| 48 { | 48 { |
| 49 DCHECK(Proxy::isImplThread()); | 49 DCHECK(Proxy::isImplThread()); |
| 50 return m_memoryVisibleLastPushedBytes; | 50 return m_memoryVisibleLastPushedBytes; |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 break; | 301 break; |
| 302 wastedMemory += (*it)->bytes(); | 302 wastedMemory += (*it)->bytes(); |
| 303 } | 303 } |
| 304 size_t tenPercentOfMemory = m_memoryAvailableBytes / 10; | 304 size_t tenPercentOfMemory = m_memoryAvailableBytes / 10; |
| 305 if (wastedMemory > tenPercentOfMemory) | 305 if (wastedMemory > tenPercentOfMemory) |
| 306 evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercen
tOfMemory), | 306 evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercen
tOfMemory), |
| 307 PriorityCalculator::allowEverythingCutoff(), | 307 PriorityCalculator::allowEverythingCutoff(), |
| 308 EvictOnlyRecyclable, | 308 EvictOnlyRecyclable, |
| 309 UnlinkBackings, | 309 UnlinkBackings, |
| 310 resourceProvider); | 310 resourceProvider); |
| 311 | |
| 312 // Unlink all evicted backings | |
| 313 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | |
| 314 if ((*it)->owner()) | |
| 315 (*it)->owner()->unlink(); | |
| 316 } | |
| 317 | |
| 318 // And clear the list of evicted backings | |
| 319 deleteUnlinkedEvictedBackings(); | |
| 320 } | 311 } |
| 321 | 312 |
| 322 void PrioritizedTextureManager::clearAllMemory(ResourceProvider* resourceProvide
r) | 313 void PrioritizedTextureManager::clearAllMemory(ResourceProvider* resourceProvide
r) |
| 323 { | 314 { |
| 324 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 315 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); |
| 325 DCHECK(resourceProvider); | 316 DCHECK(resourceProvider); |
| 326 evictBackingsToReduceMemory(0, | 317 evictBackingsToReduceMemory(0, |
| 327 PriorityCalculator::allowEverythingCutoff(), | 318 PriorityCalculator::allowEverythingCutoff(), |
| 328 EvictAnything, | 319 EvictAnything, |
| 329 DoNotUnlinkBackings, | 320 DoNotUnlinkBackings, |
| 330 resourceProvider); | 321 resourceProvider); |
| 331 } | 322 } |
| 332 | 323 |
| 333 bool PrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) | 324 bool PrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) |
| 334 { | 325 { |
| 335 DCHECK(Proxy::isImplThread()); | 326 DCHECK(Proxy::isImplThread()); |
| 336 DCHECK(resourceProvider); | 327 DCHECK(resourceProvider); |
| 337 // If we are in the process of uploading a new frame then the backings at th
e very end of | 328 // If we are in the process of uploading a new frame then the backings at th
e very end of |
| 338 // the list are not sorted by priority. Sort them before doing the eviction. | 329 // the list are not sorted by priority. Sort them before doing the eviction. |
| 339 if (m_backingsTailNotSorted) | 330 if (m_backingsTailNotSorted) |
| 340 sortBackings(); | 331 sortBackings(); |
| 341 return evictBackingsToReduceMemory(limitBytes, | 332 return evictBackingsToReduceMemory(limitBytes, |
| 342 priorityCutoff, | 333 priorityCutoff, |
| 343 EvictAnything, | 334 EvictAnything, |
| 344 DoNotUnlinkBackings, | 335 DoNotUnlinkBackings, |
| 345 resourceProvider); | 336 resourceProvider); |
| 346 } | 337 } |
| 347 | 338 |
| 348 void PrioritizedTextureManager::getEvictedBackings(BackingList& evictedBackings) | 339 void PrioritizedTextureManager::unlinkAndClearEvictedBackings() |
| 349 { | |
| 350 DCHECK(Proxy::isImplThread()); | |
| 351 evictedBackings.clear(); | |
| 352 evictedBackings.insert(evictedBackings.begin(), m_evictedBackings.begin(), m
_evictedBackings.end()); | |
| 353 } | |
| 354 | |
| 355 void PrioritizedTextureManager::unlinkEvictedBackings(const BackingList& evicted
Backings) | |
| 356 { | 340 { |
| 357 DCHECK(Proxy::isMainThread()); | 341 DCHECK(Proxy::isMainThread()); |
| 358 for (BackingList::const_iterator it = evictedBackings.begin(); it != evicted
Backings.end(); ++it) { | 342 base::AutoLock scoped_lock(m_evictedBackingsLock); |
| 343 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
| 359 PrioritizedTexture::Backing* backing = (*it); | 344 PrioritizedTexture::Backing* backing = (*it); |
| 360 if (backing->owner()) | 345 if (backing->owner()) |
| 361 backing->owner()->unlink(); | 346 backing->owner()->unlink(); |
| 347 delete backing; |
| 362 } | 348 } |
| 363 } | 349 m_evictedBackings.clear(); |
| 364 | |
| 365 void PrioritizedTextureManager::deleteUnlinkedEvictedBackings() | |
| 366 { | |
| 367 DCHECK(Proxy::isMainThread() || (Proxy::isImplThread() && Proxy::isMainThrea
dBlocked())); | |
| 368 BackingList newEvictedBackings; | |
| 369 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | |
| 370 PrioritizedTexture::Backing* backing = (*it); | |
| 371 if (backing->owner()) | |
| 372 newEvictedBackings.push_back(backing); | |
| 373 else | |
| 374 delete backing; | |
| 375 } | |
| 376 m_evictedBackings.swap(newEvictedBackings); | |
| 377 } | 350 } |
| 378 | 351 |
| 379 bool PrioritizedTextureManager::linkedEvictedBackingsExist() const | 352 bool PrioritizedTextureManager::linkedEvictedBackingsExist() const |
| 380 { | 353 { |
| 354 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); |
| 355 base::AutoLock scoped_lock(m_evictedBackingsLock); |
| 381 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | 356 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
| 382 if ((*it)->owner()) | 357 if ((*it)->owner()) |
| 383 return true; | 358 return true; |
| 384 } | 359 } |
| 385 return false; | 360 return false; |
| 386 } | 361 } |
| 387 | 362 |
| 388 void PrioritizedTextureManager::registerTexture(PrioritizedTexture* texture) | 363 void PrioritizedTextureManager::registerTexture(PrioritizedTexture* texture) |
| 389 { | 364 { |
| 390 DCHECK(Proxy::isMainThread()); | 365 DCHECK(Proxy::isMainThread()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 DCHECK(!m_backings.empty()); | 409 DCHECK(!m_backings.empty()); |
| 435 PrioritizedTexture::Backing* backing = m_backings.front(); | 410 PrioritizedTexture::Backing* backing = m_backings.front(); |
| 436 | 411 |
| 437 // Note that we create a backing and its resource at the same time, but we | 412 // Note that we create a backing and its resource at the same time, but we |
| 438 // delete the backing structure and its resource in two steps. This is becau
se | 413 // delete the backing structure and its resource in two steps. This is becau
se |
| 439 // we can delete the resource while the main thread is running, but we canno
t | 414 // we can delete the resource while the main thread is running, but we canno
t |
| 440 // unlink backings while the main thread is running. | 415 // unlink backings while the main thread is running. |
| 441 backing->deleteResource(resourceProvider); | 416 backing->deleteResource(resourceProvider); |
| 442 m_memoryUseBytes -= backing->bytes(); | 417 m_memoryUseBytes -= backing->bytes(); |
| 443 m_backings.pop_front(); | 418 m_backings.pop_front(); |
| 419 base::AutoLock scoped_lock(m_evictedBackingsLock); |
| 444 m_evictedBackings.push_back(backing); | 420 m_evictedBackings.push_back(backing); |
| 445 } | 421 } |
| 446 | 422 |
| 447 void PrioritizedTextureManager::assertInvariants() | 423 void PrioritizedTextureManager::assertInvariants() |
| 448 { | 424 { |
| 449 #ifndef NDEBUG | 425 #ifndef NDEBUG |
| 450 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); | 426 DCHECK(Proxy::isImplThread() && Proxy::isMainThreadBlocked()); |
| 451 | 427 |
| 452 // If we hit any of these asserts, there is a bug in this class. To see | 428 // If we hit any of these asserts, there is a bug in this class. To see |
| 453 // where the bug is, call this function at the beginning and end of | 429 // where the bug is, call this function at the beginning and end of |
| 454 // every public function. | 430 // every public function. |
| 455 | 431 |
| 456 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. | 432 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. |
| 457 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { | 433 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { |
| 458 if ((*it)->owner()) { | 434 if ((*it)->owner()) { |
| 459 DCHECK(ContainsKey(m_textures, (*it)->owner())); | 435 DCHECK(ContainsKey(m_textures, (*it)->owner())); |
| 460 DCHECK((*it)->owner()->backing() == (*it)); | 436 DCHECK((*it)->owner()->backing() == (*it)); |
| 461 } | 437 } |
| 462 } | 438 } |
| 463 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { | 439 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { |
| 464 PrioritizedTexture* texture = (*it); | 440 PrioritizedTexture* texture = (*it); |
| 465 PrioritizedTexture::Backing* backing = texture->backing(); | 441 PrioritizedTexture::Backing* backing = texture->backing(); |
| 442 base::AutoLock scoped_lock(m_evictedBackingsLock); |
| 466 if (backing) { | 443 if (backing) { |
| 467 if (backing->resourceHasBeenDeleted()) { | 444 if (backing->resourceHasBeenDeleted()) { |
| 468 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
== m_backings.end()); | 445 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
== m_backings.end()); |
| 469 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) != m_evictedBackings.end()); | 446 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) != m_evictedBackings.end()); |
| 470 } else { | 447 } else { |
| 471 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
!= m_backings.end()); | 448 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
!= m_backings.end()); |
| 472 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) == m_evictedBackings.end()); | 449 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) == m_evictedBackings.end()); |
| 473 } | 450 } |
| 474 DCHECK(backing->owner() == texture); | 451 DCHECK(backing->owner() == texture); |
| 475 } | 452 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 489 if (reachedUnrecyclable) | 466 if (reachedUnrecyclable) |
| 490 DCHECK(!backing->canBeRecycled()); | 467 DCHECK(!backing->canBeRecycled()); |
| 491 else | 468 else |
| 492 DCHECK(backing->canBeRecycled()); | 469 DCHECK(backing->canBeRecycled()); |
| 493 previous_backing = backing; | 470 previous_backing = backing; |
| 494 } | 471 } |
| 495 #endif | 472 #endif |
| 496 } | 473 } |
| 497 | 474 |
| 498 } // namespace cc | 475 } // namespace cc |
| OLD | NEW |