diff options
author | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 23:59:01 +0000 |
---|---|---|
committer | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 23:59:01 +0000 |
commit | 77a60b9b04457ab552e05751a0b863d6be875cc5 (patch) | |
tree | d5fbb5d77182954c12b81ae820637a34301f35e2 /cc | |
parent | 3196e42a57b359527039fff8873c5f6674d0d9a9 (diff) | |
download | chromium_src-77a60b9b04457ab552e05751a0b863d6be875cc5.zip chromium_src-77a60b9b04457ab552e05751a0b863d6be875cc5.tar.gz chromium_src-77a60b9b04457ab552e05751a0b863d6be875cc5.tar.bz2 |
Allow deletion of some (as opposed to all) textures on the impl thread.
Enable removing uploads to evicted textures from texture upload queues. Track whether not a CCPrioritizedTexture::Backing has been evicted in the structure itself. Purge texture upload queues of evicted backings instead of clearing the entire queue.
Added CCTextureUpdateControllerTest.ClearUploadsToEvictedResources to test the new eviction logic.
BUG=134750
Review URL: https://chromiumcodereview.appspot.com/10947017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157662 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/CCLayerTreeHost.cpp | 7 | ||||
-rw-r--r-- | cc/CCLayerTreeHost.h | 2 | ||||
-rw-r--r-- | cc/CCPrioritizedTexture.cpp | 31 | ||||
-rw-r--r-- | cc/CCPrioritizedTexture.h | 11 | ||||
-rw-r--r-- | cc/CCPrioritizedTextureManager.cpp | 14 | ||||
-rw-r--r-- | cc/CCPrioritizedTextureManager.h | 3 | ||||
-rw-r--r-- | cc/CCTextureUpdateController.cpp | 5 | ||||
-rw-r--r-- | cc/CCTextureUpdateController.h | 3 | ||||
-rw-r--r-- | cc/CCTextureUpdateControllerTest.cpp | 64 | ||||
-rw-r--r-- | cc/CCTextureUpdateQueue.cpp | 17 | ||||
-rw-r--r-- | cc/CCTextureUpdateQueue.h | 3 | ||||
-rw-r--r-- | cc/CCThreadProxy.cpp | 16 | ||||
-rw-r--r-- | cc/LayerTextureUpdater.h | 1 |
13 files changed, 150 insertions, 27 deletions
diff --git a/cc/CCLayerTreeHost.cpp b/cc/CCLayerTreeHost.cpp index eacda97..4122dcf 100644 --- a/cc/CCLayerTreeHost.cpp +++ b/cc/CCLayerTreeHost.cpp @@ -446,6 +446,13 @@ void CCLayerTreeHost::reduceContentsTexturesMemoryOnImplThread(size_t limitBytes 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()); diff --git a/cc/CCLayerTreeHost.h b/cc/CCLayerTreeHost.h index f89f251..65c2bc4 100644 --- a/cc/CCLayerTreeHost.h +++ b/cc/CCLayerTreeHost.h @@ -170,6 +170,8 @@ public: // 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&); diff --git a/cc/CCPrioritizedTexture.cpp b/cc/CCPrioritizedTexture.cpp index 270ceba..2940e92 100644 --- a/cc/CCPrioritizedTexture.cpp +++ b/cc/CCPrioritizedTexture.cpp @@ -69,6 +69,11 @@ bool CCPrioritizedTexture::requestLate() return m_manager->requestLate(this); } +bool CCPrioritizedTexture::backingResourceWasEvicted() const +{ + return m_backing ? m_backing->resourceHasBeenDeleted() : false; +} + void CCPrioritizedTexture::acquireBackingTexture(CCResourceProvider* resourceProvider) { ASSERT(m_isAbovePriorityCutoff); @@ -120,18 +125,42 @@ void CCPrioritizedTexture::setToSelfManagedMemoryPlaceholder(size_t bytes) m_bytes = bytes; } -CCPrioritizedTexture::Backing::Backing(unsigned id, IntSize size, GC3Denum format) +CCPrioritizedTexture::Backing::Backing(unsigned id, CCResourceProvider* resourceProvider, IntSize size, GC3Denum format) : CCTexture(id, size, format) , m_owner(0) , m_priorityAtLastPriorityUpdate(CCPriorityCalculator::lowestPriority()) , m_ownerExistedAtLastPriorityUpdate(false) , m_wasAbovePriorityCutoffAtLastPriorityUpdate(false) + , m_resourceHasBeenDeleted(false) +#ifndef NDEBUG + , m_resourceProvider(resourceProvider) +#endif { } CCPrioritizedTexture::Backing::~Backing() { ASSERT(!m_owner); + ASSERT(m_resourceHasBeenDeleted); +} + +void CCPrioritizedTexture::Backing::deleteResource(CCResourceProvider* resourceProvider) +{ + ASSERT(CCProxy::isImplThread()); + ASSERT(!m_resourceHasBeenDeleted); +#ifndef NDEBUG + ASSERT(resourceProvider == m_resourceProvider); +#endif + + resourceProvider->deleteResource(id()); + setId(0); + m_resourceHasBeenDeleted = true; +} + +bool CCPrioritizedTexture::Backing::resourceHasBeenDeleted() const +{ + ASSERT(CCProxy::isImplThread()); + return m_resourceHasBeenDeleted; } void CCPrioritizedTexture::Backing::updatePriority() diff --git a/cc/CCPrioritizedTexture.h b/cc/CCPrioritizedTexture.h index a65a782..cd33d11 100644 --- a/cc/CCPrioritizedTexture.h +++ b/cc/CCPrioritizedTexture.h @@ -52,6 +52,8 @@ public: // taken away "soon". bool haveBackingTexture() const { return !!backing(); } + bool backingResourceWasEvicted() const; + // If canAcquireBackingTexture() is true acquireBackingTexture() will acquire // a backing texture for use. Call this whenever the texture is actually needed. void acquireBackingTexture(CCResourceProvider*); @@ -85,7 +87,7 @@ private: class Backing : public CCTexture { WTF_MAKE_NONCOPYABLE(Backing); public: - Backing(unsigned id, IntSize, GC3Denum format); + Backing(unsigned id, CCResourceProvider*, IntSize, GC3Denum format); ~Backing(); void updatePriority(); @@ -94,12 +96,19 @@ private: bool requestPriorityAtLastPriorityUpdate() const { return m_priorityAtLastPriorityUpdate; } bool wasAbovePriorityCutoffAtLastPriorityUpdate() const { return m_wasAbovePriorityCutoffAtLastPriorityUpdate; } + void deleteResource(CCResourceProvider*); + bool resourceHasBeenDeleted() const; + private: friend class CCPrioritizedTexture; CCPrioritizedTexture* m_owner; int m_priorityAtLastPriorityUpdate; bool m_ownerExistedAtLastPriorityUpdate; bool m_wasAbovePriorityCutoffAtLastPriorityUpdate; + bool m_resourceHasBeenDeleted; +#ifndef NDEBUG + CCResourceProvider* m_resourceProvider; +#endif }; CCPrioritizedTexture(CCPrioritizedTextureManager*, IntSize, GC3Denum format); diff --git a/cc/CCPrioritizedTextureManager.cpp b/cc/CCPrioritizedTextureManager.cpp index d571e5f..9a5481d 100644 --- a/cc/CCPrioritizedTextureManager.cpp +++ b/cc/CCPrioritizedTextureManager.cpp @@ -265,11 +265,6 @@ void CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CC 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::getEvictedBackings(BackingVector& evictedBackings) @@ -344,7 +339,7 @@ CCPrioritizedTexture::Backing* CCPrioritizedTextureManager::createBacking(IntSiz ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()); ASSERT(resourceProvider); CCResourceProvider::ResourceId resourceId = resourceProvider->createResource(m_pool, size, format, CCResourceProvider::TextureUsageAny); - CCPrioritizedTexture::Backing* backing = new CCPrioritizedTexture::Backing(resourceId, size, format); + CCPrioritizedTexture::Backing* backing = new CCPrioritizedTexture::Backing(resourceId, resourceProvider, size, format); m_memoryUseBytes += backing->bytes(); // Put backing texture at the front for eviction, since it isn't in use yet. m_backings.insertBefore(m_backings.begin(), backing); @@ -358,8 +353,11 @@ void CCPrioritizedTextureManager::evictBackingResource(CCPrioritizedTexture::Bac ASSERT(resourceProvider); ASSERT(m_backings.find(backing) != m_backings.end()); - resourceProvider->deleteResource(backing->id()); - backing->setId(0); + // Note that we create a backing and its resource at the same time, but we + // delete the backing structure and its resource in two steps. This is because + // we can delete the resource while the main thread is running, but we cannot + // unlink backings while the main thread is running. + backing->deleteResource(resourceProvider); m_memoryUseBytes -= backing->bytes(); m_backings.remove(backing); m_evictedBackings.append(backing); diff --git a/cc/CCPrioritizedTextureManager.h b/cc/CCPrioritizedTextureManager.h index 52b35d6..4bb8a3a 100644 --- a/cc/CCPrioritizedTextureManager.h +++ b/cc/CCPrioritizedTextureManager.h @@ -57,10 +57,11 @@ public: void clearPriorities(); void reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider*); + bool evictedBackingsExist() const { return !m_evictedBackings.isEmpty(); } void getEvictedBackings(BackingVector& evictedBackings); void unlinkEvictedBackings(const BackingVector& evictedBackings); // Deletes all evicted backings, unlinking them from their owning textures if needed. - // Returns true if this function to unlinked any backings from their owning texture while + // Returns true if this function unlinked any backings from their owning texture while // destroying them. bool deleteEvictedBackings(); diff --git a/cc/CCTextureUpdateController.cpp b/cc/CCTextureUpdateController.cpp index 8b27385..c1e8f31 100644 --- a/cc/CCTextureUpdateController.cpp +++ b/cc/CCTextureUpdateController.cpp @@ -120,6 +120,11 @@ void CCTextureUpdateController::performMoreUpdates( updateMoreTexturesNow(); } +void CCTextureUpdateController::discardUploadsToEvictedResources() +{ + m_queue->clearUploadsToEvictedResources(); +} + void CCTextureUpdateController::finalize() { updateTextures(m_resourceProvider, m_uploader, m_queue.get()); diff --git a/cc/CCTextureUpdateController.h b/cc/CCTextureUpdateController.h index 6cf726e..ba3fb4b 100644 --- a/cc/CCTextureUpdateController.h +++ b/cc/CCTextureUpdateController.h @@ -34,6 +34,9 @@ public: virtual ~CCTextureUpdateController(); + // Discard uploads to textures that were evicted on the impl thread. + void discardUploadsToEvictedResources(); + void performMoreUpdates(double monotonicTimeLimit); void finalize(); diff --git a/cc/CCTextureUpdateControllerTest.cpp b/cc/CCTextureUpdateControllerTest.cpp index 2eeaa9d..eb6792e 100644 --- a/cc/CCTextureUpdateControllerTest.cpp +++ b/cc/CCTextureUpdateControllerTest.cpp @@ -67,8 +67,16 @@ private: class TextureForUploadTest : public LayerTextureUpdater::Texture { public: - TextureForUploadTest() : LayerTextureUpdater::Texture(adoptPtr<CCPrioritizedTexture>(0)) { } + TextureForUploadTest() + : LayerTextureUpdater::Texture(nullptr) + , m_evicted(false) + { + } virtual void updateRect(CCResourceProvider*, const IntRect& sourceRect, const IntSize& destOffset) { } + virtual bool backingResourceWasEvicted() const { return m_evicted; } + void evictBackingResource() { m_evicted = true; } +private: + bool m_evicted; }; @@ -157,28 +165,39 @@ protected: m_resourceProvider = CCResourceProvider::create(m_context.get(), UnthrottledUploader); } - void appendFullUploadsToUpdateQueue(int count) + + void appendFullUploadsOfIndexedTextureToUpdateQueue(int count, int textureIndex) { m_fullUploadCountExpected += count; m_totalUploadCountExpected += count; const IntRect rect(0, 0, 300, 150); - const TextureUploader::Parameters upload = { &m_texture, rect, IntSize() }; + const TextureUploader::Parameters upload = { &m_textures[textureIndex], rect, IntSize() }; for (int i = 0; i < count; i++) m_queue->appendFullUpload(upload); } - void appendPartialUploadsToUpdateQueue(int count) + void appendFullUploadsToUpdateQueue(int count) + { + appendFullUploadsOfIndexedTextureToUpdateQueue(count, 0); + } + + void appendPartialUploadsOfIndexedTextureToUpdateQueue(int count, int textureIndex) { m_partialCountExpected += count; m_totalUploadCountExpected += count; const IntRect rect(0, 0, 100, 100); - const TextureUploader::Parameters upload = { &m_texture, rect, IntSize() }; + const TextureUploader::Parameters upload = { &m_textures[textureIndex], rect, IntSize() }; for (int i = 0; i < count; i++) m_queue->appendPartialUpload(upload); } + void appendPartialUploadsToUpdateQueue(int count) + { + appendPartialUploadsOfIndexedTextureToUpdateQueue(count, 0); + } + void setMaxUploadCountPerUpdate(int count) { m_maxUploadCountPerUpdate = count; @@ -189,7 +208,7 @@ protected: OwnPtr<CCGraphicsContext> m_context; OwnPtr<CCResourceProvider> m_resourceProvider; OwnPtr<CCTextureUpdateQueue> m_queue; - TextureForUploadTest m_texture; + TextureForUploadTest m_textures[4]; TextureUploaderForUploadTest m_uploader; OwnPtr<WebThread> m_thread; WebCompositorInitializer m_compositorInitializer; @@ -496,4 +515,37 @@ TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime) EXPECT_EQ(2, m_numTotalUploads); } +TEST_F(CCTextureUpdateControllerTest, ClearUploadsToEvictedResources) +{ + appendFullUploadsOfIndexedTextureToUpdateQueue(1, 0); + appendPartialUploadsOfIndexedTextureToUpdateQueue(1, 1); + appendFullUploadsOfIndexedTextureToUpdateQueue(1, 2); + appendPartialUploadsOfIndexedTextureToUpdateQueue(1, 3); + DebugScopedSetImplThread implThread; + + m_queue->clearUploadsToEvictedResources(); + EXPECT_EQ(2u, m_queue->fullUploadSize()); + EXPECT_EQ(2u, m_queue->partialUploadSize()); + + m_textures[0].evictBackingResource(); + m_queue->clearUploadsToEvictedResources(); + EXPECT_EQ(1u, m_queue->fullUploadSize()); + EXPECT_EQ(2u, m_queue->partialUploadSize()); + + m_textures[3].evictBackingResource(); + m_queue->clearUploadsToEvictedResources(); + EXPECT_EQ(1u, m_queue->fullUploadSize()); + EXPECT_EQ(1u, m_queue->partialUploadSize()); + + m_textures[2].evictBackingResource(); + m_queue->clearUploadsToEvictedResources(); + EXPECT_EQ(0u, m_queue->fullUploadSize()); + EXPECT_EQ(1u, m_queue->partialUploadSize()); + + m_textures[1].evictBackingResource(); + m_queue->clearUploadsToEvictedResources(); + EXPECT_EQ(0u, m_queue->fullUploadSize()); + EXPECT_EQ(0u, m_queue->partialUploadSize()); +} + } // namespace diff --git a/cc/CCTextureUpdateQueue.cpp b/cc/CCTextureUpdateQueue.cpp index 1619ab2..b5ebdf5 100644 --- a/cc/CCTextureUpdateQueue.cpp +++ b/cc/CCTextureUpdateQueue.cpp @@ -33,10 +33,21 @@ void CCTextureUpdateQueue::appendCopy(TextureCopier::Parameters copy) m_copyEntries.append(copy); } -void CCTextureUpdateQueue::clearUploads() +void CCTextureUpdateQueue::clearUploadsToEvictedResources() { - m_fullEntries.clear(); - m_partialEntries.clear(); + clearUploadsToEvictedResources(m_fullEntries); + clearUploadsToEvictedResources(m_partialEntries); +} + +void CCTextureUpdateQueue::clearUploadsToEvictedResources(Deque<TextureUploader::Parameters>& entryQueue) +{ + Deque<TextureUploader::Parameters> temp; + entryQueue.swap(temp); + while (temp.size()) { + TextureUploader::Parameters upload = temp.takeFirst(); + if (!upload.texture->backingResourceWasEvicted()) + entryQueue.append(upload); + } } TextureUploader::Parameters CCTextureUpdateQueue::takeFirstFullUpload() diff --git a/cc/CCTextureUpdateQueue.h b/cc/CCTextureUpdateQueue.h index 5549b55..e656489 100644 --- a/cc/CCTextureUpdateQueue.h +++ b/cc/CCTextureUpdateQueue.h @@ -22,7 +22,7 @@ public: void appendPartialUpload(TextureUploader::Parameters); void appendCopy(TextureCopier::Parameters); - void clearUploads(); + void clearUploadsToEvictedResources(); TextureUploader::Parameters takeFirstFullUpload(); TextureUploader::Parameters takeFirstPartialUpload(); @@ -35,6 +35,7 @@ public: bool hasMoreUpdates() const; private: + void clearUploadsToEvictedResources(Deque<TextureUploader::Parameters>& entryQueue); Deque<TextureUploader::Parameters> m_fullEntries; Deque<TextureUploader::Parameters> m_partialEntries; Deque<TextureCopier::Parameters> m_copyEntries; diff --git a/cc/CCThreadProxy.cpp b/cc/CCThreadProxy.cpp index 86d6a04..c36a561 100644 --- a/cc/CCThreadProxy.cpp +++ b/cc/CCThreadProxy.cpp @@ -357,8 +357,10 @@ void CCThreadProxy::releaseContentsTexturesOnImplThread() m_layerTreeHost->reduceContentsTexturesMemoryOnImplThread(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, so clear it. - m_currentTextureUpdateControllerOnImplThread.clear(); + // The texture upload queue may reference textures that were just purged, clear + // them from the queue. + if (m_currentTextureUpdateControllerOnImplThread.get() && m_layerTreeHost->evictedContentsTexturesBackingsExist()) + m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedResources(); } void CCThreadProxy::setNeedsRedraw() @@ -587,14 +589,16 @@ void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion return; } + // Clear any uploads we were making to textures linked to evicted + // resources + if (m_layerTreeHost->evictedContentsTexturesBackingsExist()) + 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). The upload queue - // may contain references to these textures, so clear the queue and kick off + // layer tree being invalidated (unliked from their backings). Kick off // another commit to fill them again. - queue->clearUploads(); setNeedsCommitOnImplThread(); } else { // The layer tree does not reference evicted textures, so mark that we diff --git a/cc/LayerTextureUpdater.h b/cc/LayerTextureUpdater.h index a8e649d..7670fde 100644 --- a/cc/LayerTextureUpdater.h +++ b/cc/LayerTextureUpdater.h @@ -30,6 +30,7 @@ public: void swapTextureWith(OwnPtr<CCPrioritizedTexture>& texture) { m_texture.swap(texture); } virtual void prepareRect(const IntRect& /* sourceRect */, CCRenderingStats&) { } virtual void updateRect(CCResourceProvider*, const IntRect& sourceRect, const IntSize& destOffset) = 0; + virtual bool backingResourceWasEvicted() const { return m_texture->backingResourceWasEvicted(); } protected: explicit Texture(PassOwnPtr<CCPrioritizedTexture> texture) : m_texture(texture) { } |