diff options
author | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-15 20:43:25 +0000 |
---|---|---|
committer | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-15 20:43:25 +0000 |
commit | 2c7d23f639f3d6aa1c0c840d230c9a5e1cb0ca63 (patch) | |
tree | 26e43a2eba88f008a1f53bef9c59b7dcc2fbe423 /cc | |
parent | eb63da71b9cc5a06f6de8b59ce50630e094c3c2c (diff) | |
download | chromium_src-2c7d23f639f3d6aa1c0c840d230c9a5e1cb0ca63.zip chromium_src-2c7d23f639f3d6aa1c0c840d230c9a5e1cb0ca63.tar.gz chromium_src-2c7d23f639f3d6aa1c0c840d230c9a5e1cb0ca63.tar.bz2 |
Fix issue where textures currently being drawn by the impl thread can be recycled or evicted by the main thread.
Explicitly push priorities to their backings when a commit begins, and then update the presence of backings' resources in the impl tree when the trees are synchronized.
Note that in the worst case we can momentarily overshoot the texture budget by a factor of two because we keep around both the currently-drawing and the next frame.
Make the CCProxy implementations call the PTM directly instead of maintaining a bunch of wrapper functions in CCLayerTreeHost.
Make reduceMemory (called when synchronizing trees at the end of a commit) be the one true place where backings structures are deleted (they are just evicted in all other places).
Also, we can cut the PTM into a CCPrioritizedTextureManager and CCPrioritizedBackingManager where the former is a main-thread structure and the latter is an impl-thread structure. This change make the PTM follow parts of the commit flow, which will be more explicit with the separate structures.
BUG=152496
Review URL: https://chromiumcodereview.appspot.com/11079007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161949 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layer_tree_host.cc | 41 | ||||
-rw-r--r-- | cc/layer_tree_host.h | 16 | ||||
-rw-r--r-- | cc/prioritized_texture.cc | 18 | ||||
-rw-r--r-- | cc/prioritized_texture.h | 9 | ||||
-rw-r--r-- | cc/prioritized_texture_manager.cc | 125 | ||||
-rw-r--r-- | cc/prioritized_texture_manager.h | 51 | ||||
-rw-r--r-- | cc/prioritized_texture_unittest.cc | 2 | ||||
-rw-r--r-- | cc/single_thread_proxy.cc | 12 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 45 | ||||
-rw-r--r-- | cc/thread_proxy.h | 4 | ||||
-rw-r--r-- | cc/tiled_layer_unittest.cc | 1 |
11 files changed, 155 insertions, 169 deletions
diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index d75a3d3..a157136 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -241,8 +241,6 @@ void CCLayerTreeHost::beginCommitOnImplThread(CCLayerTreeHostImpl* hostImpl) { ASSERT(CCProxy::isImplThread()); TRACE_EVENT0("cc", "CCLayerTreeHost::commitTo"); - - m_contentsTextureManager->reduceMemory(hostImpl->resourceProvider()); } // This function commits the CCLayerTreeHost to an impl tree. When modifying @@ -254,6 +252,9 @@ void CCLayerTreeHost::finishCommitOnImplThread(CCLayerTreeHostImpl* hostImpl) { ASSERT(CCProxy::isImplThread()); + m_contentsTextureManager->updateBackingsInDrawingImplTree(); + m_contentsTextureManager->reduceMemory(hostImpl->resourceProvider()); + hostImpl->setRootLayer(TreeSynchronizer::synchronizeTrees(rootLayer(), hostImpl->detachLayerTree(), hostImpl)); if (m_rootLayer && m_hudLayer) @@ -435,42 +436,6 @@ void CCLayerTreeHost::setVisible(bool visible) m_proxy->setVisible(visible); } -void CCLayerTreeHost::reduceContentsTexturesMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider) -{ - ASSERT(CCProxy::isImplThread()); - ASSERT(m_contentsTextureManager.get()); - m_contentsTextureManager->reduceMemoryOnImplThread(limitBytes, resourceProvider); -} - -bool CCLayerTreeHost::evictedContentsTexturesBackingsExist() const -{ - ASSERT(CCProxy::isImplThread()); - ASSERT(m_contentsTextureManager.get()); - return m_contentsTextureManager->evictedBackingsExist(); -} - -void CCLayerTreeHost::getEvictedContentTexturesBackings(CCPrioritizedTextureManager::BackingVector& evictedBackings) -{ - ASSERT(CCProxy::isImplThread()); - evictedBackings.clear(); - if (m_rendererInitialized) - m_contentsTextureManager->getEvictedBackings(evictedBackings); -} - -void CCLayerTreeHost::unlinkEvictedContentTexturesBackings(const CCPrioritizedTextureManager::BackingVector& evictedBackings) -{ - ASSERT(CCProxy::isMainThread()); - ASSERT(m_contentsTextureManager.get()); - m_contentsTextureManager->unlinkEvictedBackings(evictedBackings); -} - -bool CCLayerTreeHost::deleteEvictedContentTexturesBackings() -{ - ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); - ASSERT(m_contentsTextureManager.get()); - return m_contentsTextureManager->deleteEvictedBackings(); -} - void CCLayerTreeHost::startPageScaleAnimation(const IntSize& targetPosition, bool useAnchor, float scale, double durationSec) { m_proxy->startPageScaleAnimation(targetPosition, useAnchor, scale, durationSec); diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h index 277b1f0..f9a6343 100644 --- a/cc/layer_tree_host.h +++ b/cc/layer_tree_host.h @@ -178,22 +178,6 @@ public: CCPrioritizedTextureManager* contentsTextureManager() const; - // Delete contents textures' backing resources until they use only bytesLimit bytes. This may - // be called on the impl thread while the main thread is running. - void reduceContentsTexturesMemoryOnImplThread(size_t bytesLimit, CCResourceProvider*); - // Returns true if there any evicted backing textures that have not been deleted. - bool evictedContentsTexturesBackingsExist() const; - // Retrieve the list of all contents textures' backings that have been evicted, to pass to the - // main thread to unlink them from their owning textures. - void getEvictedContentTexturesBackings(CCPrioritizedTextureManager::BackingVector&); - // Unlink the list of contents textures' backings from their owning textures on the main thread - // before updating layers. - void unlinkEvictedContentTexturesBackings(const CCPrioritizedTextureManager::BackingVector&); - // Deletes all evicted backings, unlinking them from their owning textures if needed. - // Returns true if this function had to unlink any backings from their owning texture when - // destroying them. If this was the case, the impl layer tree may contain invalid resources. - bool deleteEvictedContentTexturesBackings(); - bool visible() const { return m_visible; } void setVisible(bool); diff --git a/cc/prioritized_texture.cc b/cc/prioritized_texture.cc index 2940e92..f1a7cf4 100644 --- a/cc/prioritized_texture.cc +++ b/cc/prioritized_texture.cc @@ -129,8 +129,8 @@ CCPrioritizedTexture::Backing::Backing(unsigned id, CCResourceProvider* resource : CCTexture(id, size, format) , m_owner(0) , m_priorityAtLastPriorityUpdate(CCPriorityCalculator::lowestPriority()) - , m_ownerExistedAtLastPriorityUpdate(false) , m_wasAbovePriorityCutoffAtLastPriorityUpdate(false) + , m_inDrawingImplTree(false) , m_resourceHasBeenDeleted(false) #ifndef NDEBUG , m_resourceProvider(resourceProvider) @@ -163,18 +163,30 @@ bool CCPrioritizedTexture::Backing::resourceHasBeenDeleted() const return m_resourceHasBeenDeleted; } +bool CCPrioritizedTexture::Backing::canBeRecycled() const +{ + ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); + return !m_wasAbovePriorityCutoffAtLastPriorityUpdate && !m_inDrawingImplTree; +} + void CCPrioritizedTexture::Backing::updatePriority() { ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); if (m_owner) { - m_ownerExistedAtLastPriorityUpdate = true; m_priorityAtLastPriorityUpdate = m_owner->requestPriority(); m_wasAbovePriorityCutoffAtLastPriorityUpdate = m_owner->isAbovePriorityCutoff(); } else { - m_ownerExistedAtLastPriorityUpdate = false; m_priorityAtLastPriorityUpdate = CCPriorityCalculator::lowestPriority(); m_wasAbovePriorityCutoffAtLastPriorityUpdate = false; } } +void CCPrioritizedTexture::Backing::updateInDrawingImplTree() +{ + ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); + m_inDrawingImplTree = !!owner(); + if (!m_inDrawingImplTree) + ASSERT(m_priorityAtLastPriorityUpdate == CCPriorityCalculator::lowestPriority()); +} + } // namespace cc diff --git a/cc/prioritized_texture.h b/cc/prioritized_texture.h index 3196867..242147c 100644 --- a/cc/prioritized_texture.h +++ b/cc/prioritized_texture.h @@ -90,11 +90,13 @@ private: Backing(unsigned id, CCResourceProvider*, IntSize, GC3Denum format); ~Backing(); void updatePriority(); + void updateInDrawingImplTree(); CCPrioritizedTexture* owner() { return m_owner; } - bool hadOwnerAtLastPriorityUpdate() const { return m_ownerExistedAtLastPriorityUpdate; } + bool canBeRecycled() const; int requestPriorityAtLastPriorityUpdate() const { return m_priorityAtLastPriorityUpdate; } bool wasAbovePriorityCutoffAtLastPriorityUpdate() const { return m_wasAbovePriorityCutoffAtLastPriorityUpdate; } + bool inDrawingImplTree() const { return m_inDrawingImplTree; } void deleteResource(CCResourceProvider*); bool resourceHasBeenDeleted() const; @@ -103,8 +105,11 @@ private: friend class CCPrioritizedTexture; CCPrioritizedTexture* m_owner; int m_priorityAtLastPriorityUpdate; - bool m_ownerExistedAtLastPriorityUpdate; bool m_wasAbovePriorityCutoffAtLastPriorityUpdate; + + // Set if this is currently-drawing impl tree. + bool m_inDrawingImplTree; + bool m_resourceHasBeenDeleted; #ifndef NDEBUG CCResourceProvider* m_resourceProvider; diff --git a/cc/prioritized_texture_manager.cc b/cc/prioritized_texture_manager.cc index a609548..06d6c8e 100644 --- a/cc/prioritized_texture_manager.cc +++ b/cc/prioritized_texture_manager.cc @@ -23,7 +23,6 @@ CCPrioritizedTextureManager::CCPrioritizedTextureManager(size_t maxMemoryLimitBy , m_memoryAboveCutoffBytes(0) , m_memoryAvailableBytes(0) , m_pool(pool) - , m_needsUpdateBackingsPrioritites(false) { } @@ -32,7 +31,8 @@ CCPrioritizedTextureManager::~CCPrioritizedTextureManager() while (m_textures.size() > 0) unregisterTexture(*m_textures.begin()); - deleteEvictedBackings(); + deleteUnlinkedEvictedBackings(); + ASSERT(m_evictedBackings.isEmpty()); // Each remaining backing is a leaked opengl texture. There should be none. ASSERT(m_backings.isEmpty()); @@ -94,31 +94,44 @@ void CCPrioritizedTextureManager::prioritizeTextures() } sortedTextures.clear(); - m_needsUpdateBackingsPrioritites = true; - ASSERT(m_memoryAboveCutoffBytes <= m_memoryAvailableBytes); ASSERT(memoryAboveCutoffBytes() <= maxMemoryLimitBytes()); } -void CCPrioritizedTextureManager::updateBackingsPriorities() +void CCPrioritizedTextureManager::pushTexturePrioritiesToBackings() { - TRACE_EVENT0("cc", "CCPrioritizedTextureManager::updateBackingsPriorities"); + TRACE_EVENT0("cc", "CCPrioritizedTextureManager::pushTexturePrioritiesToBackings"); ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); - if (!m_needsUpdateBackingsPrioritites) - return; + for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) + (*it)->updatePriority(); -#if !ASSERT_DISABLED - assertInvariants(); -#endif + sortBackings(); +} + +void CCPrioritizedTextureManager::updateBackingsInDrawingImplTree() +{ + TRACE_EVENT0("cc", "CCPrioritizedTextureManager::updateBackingsInDrawingImplTree"); + ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); + + for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) { + CCPrioritizedTexture::Backing* backing = (*it); + backing->updateInDrawingImplTree(); + } + + sortBackings(); +} + +void CCPrioritizedTextureManager::sortBackings() +{ + TRACE_EVENT0("cc", "CCPrioritizedTextureManager::updateBackingsPriorities"); + ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); // 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(); + for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) sortedBackings.append(*it); - } std::sort(sortedBackings.begin(), sortedBackings.end(), compareBackings); for (BackingVector::iterator it = sortedBackings.begin(); it != sortedBackings.end(); ++it) { @@ -126,7 +139,6 @@ void CCPrioritizedTextureManager::updateBackingsPriorities() m_backings.add(*it); } sortedBackings.clear(); - m_needsUpdateBackingsPrioritites = false; #if !ASSERT_DISABLED assertInvariants(); @@ -162,7 +174,6 @@ bool CCPrioritizedTextureManager::requestLate(CCPrioritizedTexture* texture) m_memoryAboveCutoffBytes = newMemoryBytes; texture->setAbovePriorityCutoff(true); - m_needsUpdateBackingsPrioritites = true; return true; } @@ -174,15 +185,12 @@ 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)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate()) + if (!(*it)->canBeRecycled()) break; if ((*it)->size() == texture->size() && (*it)->format() == texture->format()) { backing = (*it); @@ -218,7 +226,7 @@ void CCPrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, while (memoryUseBytes() > limitBytes && m_backings.size() > 0) { CCPrioritizedTexture::Backing* backing = *m_backings.begin(); if (evictionPolicy == RespectManagerPriorityCutoff) - if (backing->hadOwnerAtLastPriorityUpdate() && backing->wasAbovePriorityCutoffAtLastPriorityUpdate()) + if (backing->wasAbovePriorityCutoffAtLastPriorityUpdate()) break; evictBackingResource(backing, resourceProvider); } @@ -228,9 +236,6 @@ void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvi { ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); - // Make sure that the backings list is up to date and sorted before traversing it. - updateBackingsPriorities(); - evictBackingsToReduceMemory(m_memoryAvailableBytes, RespectManagerPriorityCutoff, resourceProvider); ASSERT(memoryUseBytes() <= maxMemoryLimitBytes()); @@ -249,7 +254,14 @@ void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvi if (wastedMemory > tenPercentOfMemory) evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercentOfMemory), RespectManagerPriorityCutoff, resourceProvider); - deleteEvictedBackings(); + // Unlink all evicted backings + for (BackingVector::const_iterator it = m_evictedBackings.begin(); it != m_evictedBackings.end(); ++it) { + if ((*it)->owner()) + (*it)->owner()->unlink(); + } + + // And clear the list of evicted backings + deleteUnlinkedEvictedBackings(); } void CCPrioritizedTextureManager::clearAllMemory(CCResourceProvider* resourceProvider) @@ -257,7 +269,6 @@ void CCPrioritizedTextureManager::clearAllMemory(CCResourceProvider* resourcePro ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); ASSERT(resourceProvider); evictBackingsToReduceMemory(0, DoNotRespectManagerPriorityCutoff, resourceProvider); - deleteEvictedBackings(); } void CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider) @@ -284,20 +295,27 @@ void CCPrioritizedTextureManager::unlinkEvictedBackings(const BackingVector& evi } } -bool CCPrioritizedTextureManager::deleteEvictedBackings() +void CCPrioritizedTextureManager::deleteUnlinkedEvictedBackings() { ASSERT(CCProxy::isMainThread() || (CCProxy::isImplThread() && CCProxy::isMainThreadBlocked())); - bool linkedEvictedBackingsExisted = false; + BackingVector newEvictedBackings; 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; + if (backing->owner()) + newEvictedBackings.append(backing); + else + delete backing; + } + m_evictedBackings.swap(newEvictedBackings); +} + +bool CCPrioritizedTextureManager::linkedEvictedBackingsExist() const +{ + for (BackingVector::const_iterator it = m_evictedBackings.begin(); it != m_evictedBackings.end(); ++it) { + if ((*it)->owner()) + return true; } - m_evictedBackings.clear(); - return linkedEvictedBackingsExisted; + return false; } void CCPrioritizedTextureManager::registerTexture(CCPrioritizedTexture* texture) @@ -328,10 +346,8 @@ void CCPrioritizedTextureManager::unregisterTexture(CCPrioritizedTexture* textur void CCPrioritizedTextureManager::returnBackingTexture(CCPrioritizedTexture* texture) { ASSERT(CCProxy::isMainThread() || (CCProxy::isImplThread() && CCProxy::isMainThreadBlocked())); - if (texture->backing()) { + if (texture->backing()) texture->unlink(); - m_needsUpdateBackingsPrioritites = true; - } } CCPrioritizedTexture::Backing* CCPrioritizedTextureManager::createBacking(IntSize size, GC3Denum format, CCResourceProvider* resourceProvider) @@ -380,28 +396,31 @@ void CCPrioritizedTextureManager::assertInvariants() } } for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); ++it) { - if ((*it)->backing()) { - ASSERT(m_backings.find((*it)->backing()) != m_backings.end()); - ASSERT((*it)->backing()->owner() == (*it)); + CCPrioritizedTexture* texture = (*it); + CCPrioritizedTexture::Backing* backing = texture->backing(); + if (backing) { + if (backing->resourceHasBeenDeleted()) { + ASSERT(m_backings.find(backing) == m_backings.end()); + ASSERT(m_evictedBackings.contains(backing)); + } else { + ASSERT(m_backings.find(backing) != m_backings.end()); + ASSERT(!m_evictedBackings.contains(backing)); + } + ASSERT(backing->owner() == texture); } } // 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 reachedOwned = false; - bool reachedAboveCutoff = false; + bool reachedUnrecyclable = false; for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) { - if ((*it)->hadOwnerAtLastPriorityUpdate()) - reachedOwned = true; - if ((*it)->wasAbovePriorityCutoffAtLastPriorityUpdate()) - reachedAboveCutoff = true; - if (reachedOwned) - ASSERT((*it)->hadOwnerAtLastPriorityUpdate()); - if (reachedAboveCutoff) { - ASSERT((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate()); - ASSERT(reachedOwned); - } + if (!(*it)->canBeRecycled()) + reachedUnrecyclable = true; + if (reachedUnrecyclable) + ASSERT(!(*it)->canBeRecycled()); + else + ASSERT((*it)->canBeRecycled()); } } #endif diff --git a/cc/prioritized_texture_manager.h b/cc/prioritized_texture_manager.h index 1b3b1ed..e8998b0 100644 --- a/cc/prioritized_texture_manager.h +++ b/cc/prioritized_texture_manager.h @@ -67,14 +67,19 @@ public: void prioritizeTextures(); void clearPriorities(); + // Delete contents textures' backing resources until they use only bytesLimit bytes. This may + // be called on the impl thread while the main thread is running. void reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider*); - bool evictedBackingsExist() const { return !m_evictedBackings.isEmpty(); } + // Returns true if there exist any textures that are linked to backings that have had their + // resources evicted. Only when we commit a tree that has no textures linked to evicted backings + // may we allow drawing. + bool linkedEvictedBackingsExist() const; + // Retrieve the list of all contents textures' backings that have been evicted, to pass to the + // main thread to unlink them from their owning textures. void getEvictedBackings(BackingVector& evictedBackings); + // Unlink the list of contents textures' backings from their owning textures on the main thread + // before updating layers. void unlinkEvictedBackings(const BackingVector& evictedBackings); - // Deletes all evicted backings, unlinking them from their owning textures if needed. - // Returns true if this function unlinked any backings from their owning texture while - // destroying them. - bool deleteEvictedBackings(); bool requestLate(CCPrioritizedTexture*); @@ -87,6 +92,12 @@ public: void unregisterTexture(CCPrioritizedTexture*); void returnBackingTexture(CCPrioritizedTexture*); + // Update all backings' priorities from their owning texture. + void pushTexturePrioritiesToBackings(); + + // Mark all textures' backings as being in the drawing impl tree. + void updateBackingsInDrawingImplTree(); + private: friend class CCPrioritizedTextureTest; @@ -105,25 +116,29 @@ private: // Compare backings. Lowest priority first. static inline bool compareBackings(CCPrioritizedTexture::Backing* a, CCPrioritizedTexture::Backing* b) { - int priorityA = a->requestPriorityAtLastPriorityUpdate(); - int priorityB = b->requestPriorityAtLastPriorityUpdate(); - if (priorityA != priorityB) - return CCPriorityCalculator::priorityIsLower(priorityA, priorityB); - bool aboveCutoffA = a->wasAbovePriorityCutoffAtLastPriorityUpdate(); - bool aboveCutoffB = b->wasAbovePriorityCutoffAtLastPriorityUpdate(); - if (!aboveCutoffA && aboveCutoffB) - return true; - if (aboveCutoffA && !aboveCutoffB) - return false; + // Make textures that can be recycled appear first + if (a->canBeRecycled() != b->canBeRecycled()) + return (a->canBeRecycled() > b->canBeRecycled()); + // Then sort by being above or below the priority cutoff. + if (a->wasAbovePriorityCutoffAtLastPriorityUpdate() != b->wasAbovePriorityCutoffAtLastPriorityUpdate()) + return (a->wasAbovePriorityCutoffAtLastPriorityUpdate() < b->wasAbovePriorityCutoffAtLastPriorityUpdate()); + // Then sort by priority (note that backings that no longer have owners will + // always have the lowest priority) + if (a->requestPriorityAtLastPriorityUpdate() != b->requestPriorityAtLastPriorityUpdate()) + return CCPriorityCalculator::priorityIsLower(a->requestPriorityAtLastPriorityUpdate(), b->requestPriorityAtLastPriorityUpdate()); + // Finally sort by being in the impl tree versus being completely unreferenced + if (a->inDrawingImplTree() != b->inDrawingImplTree()) + return (a->inDrawingImplTree() < b->inDrawingImplTree()); return a < b; } CCPrioritizedTextureManager(size_t maxMemoryLimitBytes, int maxTextureSize, int pool); - void updateBackingsPriorities(); void evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy, CCResourceProvider*); CCPrioritizedTexture::Backing* createBacking(IntSize, GC3Denum format, CCResourceProvider*); void evictBackingResource(CCPrioritizedTexture::Backing*, CCResourceProvider*); + void deleteUnlinkedEvictedBackings(); + void sortBackings(); #if !ASSERT_DISABLED void assertInvariants(); @@ -147,10 +162,6 @@ private: TextureVector m_tempTextureVector; BackingVector m_tempBackingVector; - // Set by the main thread when it adjust priorities in such a way that - // the m_backings array's view of priorities is now out of date. - bool m_needsUpdateBackingsPrioritites; - DISALLOW_COPY_AND_ASSIGN(CCPrioritizedTextureManager); }; diff --git a/cc/prioritized_texture_unittest.cc b/cc/prioritized_texture_unittest.cc index 76e166b..b055b35 100644 --- a/cc/prioritized_texture_unittest.cc +++ b/cc/prioritized_texture_unittest.cc @@ -70,7 +70,7 @@ public: void textureManagerUpdateBackingsPriorities(CCPrioritizedTextureManager* textureManager) { DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; - textureManager->updateBackingsPriorities(); + textureManager->pushTexturePrioritiesToBackings(); } CCResourceProvider* resourceProvider() diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc index 7f89cf5..400fde8 100644 --- a/cc/single_thread_proxy.cc +++ b/cc/single_thread_proxy.cc @@ -189,6 +189,7 @@ void CCSingleThreadProxy::doCommit(PassOwnPtr<CCTextureUpdateQueue> queue) base::TimeTicks startTime = base::TimeTicks::HighResNow(); m_layerTreeHostImpl->beginCommit(); + m_layerTreeHost->contentsTextureManager()->pushTexturePrioritiesToBackings(); m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get()); OwnPtr<CCTextureUpdateController> updateController = @@ -282,7 +283,8 @@ void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr void CCSingleThreadProxy::releaseContentsTexturesOnImplThread() { ASSERT(isImplThread()); - m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); + if (m_layerTreeHost->contentsTextureManager()) + m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); } // Called by the legacy scheduling path (e.g. where render_widget does the scheduling) @@ -319,13 +321,9 @@ bool CCSingleThreadProxy::commitAndComposite() CCPrioritizedTextureManager::BackingVector evictedContentsTexturesBackings; { DebugScopedSetImplThread implThread; - m_layerTreeHost->getEvictedContentTexturesBackings(evictedContentsTexturesBackings); - } - m_layerTreeHost->unlinkEvictedContentTexturesBackings(evictedContentsTexturesBackings); - { - DebugScopedSetImplThreadAndMainThreadBlocked implAndMainBlocked; - m_layerTreeHost->deleteEvictedContentTexturesBackings(); + m_layerTreeHost->contentsTextureManager()->getEvictedBackings(evictedContentsTexturesBackings); } + m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(evictedContentsTexturesBackings); OwnPtr<CCTextureUpdateQueue> queue = adoptPtr(new CCTextureUpdateQueue); m_layerTreeHost->updateLayers(*(queue.get()), m_layerTreeHostImpl->memoryAllocationLimitBytes()); diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index 1d3f2d3..8ff3d93 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -51,7 +51,6 @@ CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost) , m_readbackRequestOnImplThread(0) , m_commitCompletionEventOnImplThread(0) , m_textureAcquisitionCompletionEventOnImplThread(0) - , m_resetContentsTexturesPurgedAfterCommitOnImplThread(false) , m_nextFrameIsNewlyCommittedFrameOnImplThread(false) , m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled) , m_totalCommitCount(0) @@ -354,13 +353,12 @@ void CCThreadProxy::releaseContentsTexturesOnImplThread() { ASSERT(isImplThread()); - m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); + if (m_layerTreeHost->contentsTextureManager()) + m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); - // Make sure that we get a new commit before drawing again. - m_resetContentsTexturesPurgedAfterCommitOnImplThread = false; // The texture upload queue may reference textures that were just purged, clear // them from the queue. - if (m_currentTextureUpdateControllerOnImplThread.get() && m_layerTreeHost->evictedContentsTexturesBackingsExist()) + if (m_currentTextureUpdateControllerOnImplThread.get()) m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedResources(); } @@ -468,7 +466,8 @@ void CCThreadProxy::scheduledActionBeginFrame() m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas(); m_pendingBeginFrameRequest->implTransform = m_layerTreeHostImpl->implTransform(); m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAllocationLimitBytes(); - m_layerTreeHost->getEvictedContentTexturesBackings(m_pendingBeginFrameRequest->evictedContentsTexturesBackings); + if (m_layerTreeHost->contentsTextureManager()) + m_layerTreeHost->contentsTextureManager()->getEvictedBackings(m_pendingBeginFrameRequest->evictedContentsTexturesBackings); m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame)); @@ -540,7 +539,7 @@ void CCThreadProxy::beginFrame() return; } - m_layerTreeHost->unlinkEvictedContentTexturesBackings(request->evictedContentsTexturesBackings); + m_layerTreeHost->contentsTextureManager()->unlinkEvictedBackings(request->evictedContentsTexturesBackings); OwnPtr<CCTextureUpdateQueue> queue = adoptPtr(new CCTextureUpdateQueue); m_layerTreeHost->updateLayers(*(queue.get()), request->memoryAllocationLimitBytes); @@ -598,24 +597,17 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion return; } - // Clear any uploads we were making to textures linked to evicted - // resources - if (m_layerTreeHost->evictedContentsTexturesBackingsExist()) + if (m_layerTreeHost->contentsTextureManager()->linkedEvictedBackingsExist()) { + // Clear any uploads we were making to textures linked to evicted + // resources queue->clearUploadsToEvictedResources(); - - // If we unlinked evicted textures on the main thread, delete them now. - if (m_layerTreeHost->deleteEvictedContentTexturesBackings()) { - // Deleting the evicted textures' backings resulted in some textures in the - // layer tree being invalidated (unliked from their backings). Kick off - // another commit to fill them again. + // Some textures in the layer tree are invalid. Kick off another commit + // to fill them again. setNeedsCommitOnImplThread(); - } else { - // The layer tree does not reference evicted textures, so mark that we - // can draw this tree once this commit is complete. - if (m_layerTreeHostImpl->contentsTexturesPurged()) - m_resetContentsTexturesPurgedAfterCommitOnImplThread = true; } + m_layerTreeHost->contentsTextureManager()->pushTexturePrioritiesToBackings(); + m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(this, CCProxy::implThread(), queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->resourceProvider()->textureUploader()); m_currentTextureUpdateControllerOnImplThread->performMoreUpdates( m_schedulerOnImplThread->anticipatedDrawTime()); @@ -644,14 +636,17 @@ void CCThreadProxy::scheduledActionCommit() m_currentTextureUpdateControllerOnImplThread->finalize(); m_currentTextureUpdateControllerOnImplThread.clear(); - m_layerTreeHostImpl->beginCommit(); + // If there are linked evicted backings, these backings' resources may be put into the + // impl tree, so we can't draw yet. Determine this before clearing all evicted backings. + bool newImplTreeHasNoEvictedResources = !m_layerTreeHost->contentsTextureManager()->linkedEvictedBackingsExist(); + m_layerTreeHostImpl->beginCommit(); m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get()); m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get()); - if (m_resetContentsTexturesPurgedAfterCommitOnImplThread) { - m_resetContentsTexturesPurgedAfterCommitOnImplThread = false; - m_layerTreeHostImpl->resetContentsTexturesPurged(); + if (newImplTreeHasNoEvictedResources) { + if (m_layerTreeHostImpl->contentsTexturesPurged()) + m_layerTreeHostImpl->resetContentsTexturesPurged(); } m_layerTreeHostImpl->commitComplete(); diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index a6ea6ac..48da56d 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -167,10 +167,6 @@ private: OwnPtr<CCTextureUpdateController> m_currentTextureUpdateControllerOnImplThread; - // Set when we need to reset the contentsTexturesPurged flag after the - // commit. - bool m_resetContentsTexturesPurgedAfterCommitOnImplThread; - // Set when the next draw should post didCommitAndDrawFrame to the main thread. bool m_nextFrameIsNewlyCommittedFrameOnImplThread; diff --git a/cc/tiled_layer_unittest.cc b/cc/tiled_layer_unittest.cc index 83e4e0f..a1b28c0 100644 --- a/cc/tiled_layer_unittest.cc +++ b/cc/tiled_layer_unittest.cc @@ -96,6 +96,7 @@ public: { DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; textureManager->clearAllMemory(resourceProvider); + textureManager->reduceMemory(resourceProvider); } void updateTextures() { |