Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1597)

Unified Diff: cc/CCPrioritizedTextureManager.cpp

Issue 10919320: Integrate r128344 and r128253 from WebKit (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/CCPrioritizedTextureManager.cpp
diff --git a/cc/CCPrioritizedTextureManager.cpp b/cc/CCPrioritizedTextureManager.cpp
index b6bb38dbb6a33c7ee5b93e2bd20d7a10797b79e4..d571e5f08532ddc8881a418940bd6144e62f90b1 100644
--- a/cc/CCPrioritizedTextureManager.cpp
+++ b/cc/CCPrioritizedTextureManager.cpp
@@ -22,6 +22,7 @@ CCPrioritizedTextureManager::CCPrioritizedTextureManager(size_t maxMemoryLimitBy
, m_memoryAboveCutoffBytes(0)
, m_memoryAvailableBytes(0)
, m_pool(pool)
+ , m_needsUpdateBackingsPrioritites(false)
{
}
@@ -30,10 +31,10 @@ CCPrioritizedTextureManager::~CCPrioritizedTextureManager()
while (m_textures.size() > 0)
unregisterTexture(*m_textures.begin());
- // Each remaining backing is a leaked opengl texture. We don't have the resourceProvider
- // to delete the textures at this time so clearMemory() needs to be called before this.
- while (m_backings.size() > 0)
- destroyBacking(*m_backings.begin(), 0);
+ deleteEvictedBackings();
+
+ // Each remaining backing is a leaked opengl texture. There should be none.
+ ASSERT(m_backings.isEmpty());
}
void CCPrioritizedTextureManager::prioritizeTextures()
@@ -41,18 +42,12 @@ void CCPrioritizedTextureManager::prioritizeTextures()
TRACE_EVENT0("cc", "CCPrioritizedTextureManager::prioritizeTextures");
ASSERT(CCProxy::isMainThread());
-#if !ASSERT_DISABLED
- assertInvariants();
-#endif
-
// Sorting textures in this function could be replaced by a slightly
// modified O(n) quick-select to partition textures rather than
// sort them (if performance of the sort becomes an issue).
TextureVector& sortedTextures = m_tempTextureVector;
- BackingVector& sortedBackings = m_tempBackingVector;
sortedTextures.clear();
- sortedBackings.clear();
// Copy all textures into a vector and sort them.
for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); ++it)
@@ -96,24 +91,44 @@ void CCPrioritizedTextureManager::prioritizeTextures()
if (isAbovePriorityCutoff && !(*it)->isSelfManaged())
m_memoryAboveCutoffBytes += (*it)->bytes();
}
+ sortedTextures.clear();
+
+ m_needsUpdateBackingsPrioritites = true;
+
ASSERT(m_memoryAboveCutoffBytes <= m_memoryAvailableBytes);
+ ASSERT(memoryAboveCutoffBytes() <= maxMemoryLimitBytes());
+}
+
+void CCPrioritizedTextureManager::updateBackingsPriorities()
+{
+ TRACE_EVENT0("cc", "CCPrioritizedTextureManager::updateBackingsPriorities");
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
+
+ if (!m_needsUpdateBackingsPrioritites)
+ return;
- // Put backings in eviction/recycling order.
- for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it)
+#if !ASSERT_DISABLED
+ assertInvariants();
+#endif
+
+ // Update backings' priorities and put backings in eviction/recycling order.
+ BackingVector& sortedBackings = m_tempBackingVector;
+ sortedBackings.clear();
+ for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
+ (*it)->updatePriority();
sortedBackings.append(*it);
+ }
std::sort(sortedBackings.begin(), sortedBackings.end(), compareBackings);
for (BackingVector::iterator it = sortedBackings.begin(); it != sortedBackings.end(); ++it) {
m_backings.remove(*it);
m_backings.add(*it);
}
-
- sortedTextures.clear();
sortedBackings.clear();
+ m_needsUpdateBackingsPrioritites = false;
#if !ASSERT_DISABLED
assertInvariants();
- ASSERT(memoryAboveCutoffBytes() <= maxMemoryLimitBytes());
#endif
}
@@ -146,10 +161,7 @@ bool CCPrioritizedTextureManager::requestLate(CCPrioritizedTexture* texture)
m_memoryAboveCutoffBytes = newMemoryBytes;
texture->setAbovePriorityCutoff(true);
- if (texture->backing()) {
- m_backings.remove(texture->backing());
- m_backings.add(texture->backing());
- }
+ m_needsUpdateBackingsPrioritites = true;
return true;
}
@@ -161,12 +173,15 @@ void CCPrioritizedTextureManager::acquireBackingTextureIfNeeded(CCPrioritizedTex
if (texture->backing() || !texture->isAbovePriorityCutoff())
return;
+ // Make sure that the backings list is up to date and sorted before traversing it.
+ updateBackingsPriorities();
+
// Find a backing below, by either recycling or allocating.
CCPrioritizedTexture::Backing* backing = 0;
// First try to recycle
for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
+ if ((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate())
break;
if ((*it)->size() == texture->size() && (*it)->format() == texture->format()) {
backing = (*it);
@@ -176,7 +191,7 @@ void CCPrioritizedTextureManager::acquireBackingTextureIfNeeded(CCPrioritizedTex
// Otherwise reduce memory and just allocate a new backing texures.
if (!backing) {
- reduceMemory(m_memoryAvailableBytes - texture->bytes(), resourceProvider);
+ evictBackingsToReduceMemory(m_memoryAvailableBytes - texture->bytes(), RespectManagerPriorityCutoff, resourceProvider);
backing = createBacking(texture->size(), texture->format(), resourceProvider);
}
@@ -186,27 +201,36 @@ void CCPrioritizedTextureManager::acquireBackingTextureIfNeeded(CCPrioritizedTex
texture->link(backing);
m_backings.remove(backing);
m_backings.add(backing);
+
+ // Update the backing's priority from its new owner.
+ backing->updatePriority();
}
-void CCPrioritizedTextureManager::reduceMemory(size_t limitBytes, CCResourceProvider* resourceProvider)
+void CCPrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy evictionPolicy, CCResourceProvider* resourceProvider)
{
- ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
+ ASSERT(CCProxy::isImplThread());
if (memoryUseBytes() <= limitBytes)
return;
+
// Destroy backings until we are below the limit,
// or until all backings remaining are above the cutoff.
while (memoryUseBytes() > limitBytes && m_backings.size() > 0) {
- BackingSet::iterator it = m_backings.begin();
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
- break;
- destroyBacking((*it), resourceProvider);
+ CCPrioritizedTexture::Backing* backing = *m_backings.begin();
+ if (evictionPolicy == RespectManagerPriorityCutoff)
+ if (backing->hadOwnerAtLastPriorityUpdate() && backing->wasAbovePriorityCutoffAtLastPriorityUpdate())
+ break;
+ evictBackingResource(backing, resourceProvider);
}
}
void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvider)
{
ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
- reduceMemory(m_memoryAvailableBytes, resourceProvider);
+
+ // Make sure that the backings list is up to date and sorted before traversing it.
+ updateBackingsPriorities();
+
+ evictBackingsToReduceMemory(m_memoryAvailableBytes, RespectManagerPriorityCutoff, resourceProvider);
ASSERT(memoryUseBytes() <= maxMemoryLimitBytes());
// We currently collect backings from deleted textures for later recycling.
@@ -221,42 +245,64 @@ void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvi
wastedMemory += (*it)->bytes();
}
size_t tenPercentOfMemory = m_memoryAvailableBytes / 10;
- if (wastedMemory <= tenPercentOfMemory)
- return;
- reduceMemory(memoryUseBytes() - (wastedMemory - tenPercentOfMemory), resourceProvider);
+ if (wastedMemory > tenPercentOfMemory)
+ evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercentOfMemory), RespectManagerPriorityCutoff, resourceProvider);
+
+ deleteEvictedBackings();
}
void CCPrioritizedTextureManager::clearAllMemory(CCResourceProvider* resourceProvider)
{
ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
ASSERT(resourceProvider);
- // Unlink and destroy all backing textures.
- while (m_backings.size() > 0) {
- BackingSet::iterator it = m_backings.begin();
- if ((*it)->owner())
- (*it)->owner()->unlink();
- destroyBacking((*it), resourceProvider);
- }
+ evictBackingsToReduceMemory(0, DoNotRespectManagerPriorityCutoff, resourceProvider);
+ deleteEvictedBackings();
}
-void CCPrioritizedTextureManager::unlinkAllBackings()
+void CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider)
{
- ASSERT(CCProxy::isMainThread());
- for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it)
- if ((*it)->owner())
- (*it)->owner()->unlink();
+ ASSERT(CCProxy::isImplThread());
+ ASSERT(resourceProvider);
+
+ evictBackingsToReduceMemory(limitBytes, DoNotRespectManagerPriorityCutoff, resourceProvider);
+
+ // Deleting just some (not all) resources is not supported yet because we do not clear
+ // only the deleted resources from the texture upload queues (rather, we clear all uploads).
+ // Make sure that if we evict all resources.
+ ASSERT(m_backings.isEmpty());
}
-void CCPrioritizedTextureManager::deleteAllUnlinkedBackings()
+void CCPrioritizedTextureManager::getEvictedBackings(BackingVector& evictedBackings)
{
- ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
- BackingVector backingsToDelete;
- for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it)
- if (!(*it)->owner())
- backingsToDelete.append((*it));
+ ASSERT(CCProxy::isImplThread());
+ evictedBackings.clear();
+ evictedBackings.append(m_evictedBackings);
+}
- for (BackingVector::iterator it = backingsToDelete.begin(); it != backingsToDelete.end(); ++it)
- destroyBacking((*it), 0);
+void CCPrioritizedTextureManager::unlinkEvictedBackings(const BackingVector& evictedBackings)
+{
+ ASSERT(CCProxy::isMainThread());
+ for (BackingVector::const_iterator it = evictedBackings.begin(); it != evictedBackings.end(); ++it) {
+ CCPrioritizedTexture::Backing* backing = (*it);
+ if (backing->owner())
+ backing->owner()->unlink();
+ }
+}
+
+bool CCPrioritizedTextureManager::deleteEvictedBackings()
+{
+ ASSERT(CCProxy::isMainThread() || (CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()));
+ bool linkedEvictedBackingsExisted = false;
+ for (BackingVector::const_iterator it = m_evictedBackings.begin(); it != m_evictedBackings.end(); ++it) {
+ CCPrioritizedTexture::Backing* backing = (*it);
+ if (backing->owner()) {
+ linkedEvictedBackingsExisted = true;
+ backing->owner()->unlink();
+ }
+ delete backing;
+ }
+ m_evictedBackings.clear();
+ return linkedEvictedBackingsExisted;
}
void CCPrioritizedTextureManager::registerTexture(CCPrioritizedTexture* texture)
@@ -288,10 +334,8 @@ void CCPrioritizedTextureManager::returnBackingTexture(CCPrioritizedTexture* tex
{
ASSERT(CCProxy::isMainThread() || (CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()));
if (texture->backing()) {
- // Move the backing texture to the front for eviction/recycling and unlink it.
- m_backings.remove(texture->backing());
- m_backings.insertBefore(m_backings.begin(), texture->backing());
texture->unlink();
+ m_needsUpdateBackingsPrioritites = true;
}
}
@@ -307,28 +351,24 @@ CCPrioritizedTexture::Backing* CCPrioritizedTextureManager::createBacking(IntSiz
return backing;
}
-void CCPrioritizedTextureManager::destroyBacking(CCPrioritizedTexture::Backing* backing, CCResourceProvider* resourceProvider)
+void CCPrioritizedTextureManager::evictBackingResource(CCPrioritizedTexture::Backing* backing, CCResourceProvider* resourceProvider)
{
+ ASSERT(CCProxy::isImplThread());
ASSERT(backing);
- ASSERT(!backing->owner() || !backing->owner()->isAbovePriorityCutoff());
- ASSERT(!backing->owner() || !backing->owner()->isSelfManaged());
+ ASSERT(resourceProvider);
ASSERT(m_backings.find(backing) != m_backings.end());
- if (resourceProvider)
- resourceProvider->deleteResource(backing->id());
- if (backing->owner())
- backing->owner()->unlink();
+ resourceProvider->deleteResource(backing->id());
+ backing->setId(0);
m_memoryUseBytes -= backing->bytes();
m_backings.remove(backing);
-
- delete backing;
+ m_evictedBackings.append(backing);
}
-
#if !ASSERT_DISABLED
void CCPrioritizedTextureManager::assertInvariants()
{
- ASSERT(CCProxy::isMainThread());
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
// If we hit any of these asserts, there is a bug in this class. To see
// where the bug is, call this function at the beginning and end of
@@ -351,12 +391,19 @@ void CCPrioritizedTextureManager::assertInvariants()
// At all times, backings that can be evicted must always come before
// backings that can't be evicted in the backing texture list (otherwise
// reduceMemory will not find all textures available for eviction/recycling).
- bool reachedProtected = false;
+ bool reachedOwned = false;
+ bool reachedAboveCutoff = false;
for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
- reachedProtected = true;
- if (reachedProtected)
- ASSERT((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff());
+ if ((*it)->hadOwnerAtLastPriorityUpdate())
+ reachedOwned = true;
+ if ((*it)->wasAbovePriorityCutoffAtLastPriorityUpdate())
+ reachedAboveCutoff = true;
+ if (reachedOwned)
+ ASSERT((*it)->hadOwnerAtLastPriorityUpdate());
+ if (reachedAboveCutoff) {
+ ASSERT((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate());
+ ASSERT(reachedOwned);
+ }
}
}
#endif

Powered by Google App Engine
This is Rietveld 408576698