Diff
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp 2012-08-15 19:54:29 UTC (rev 125699)
@@ -122,7 +122,7 @@
, m_settings(settings)
, m_deviceScaleFactor(1)
, m_visible(true)
- , m_contentsTexturesWerePurgedSinceLastCommit(false)
+ , m_contentsTexturesPurged(false)
, m_memoryAllocationLimitBytes(CCPrioritizedTextureManager::defaultMemoryAllocationLimit())
, m_pageScale(1)
, m_pageScaleDelta(1)
@@ -159,7 +159,6 @@
// Recompute max scroll position; must be after layer content bounds are
// updated.
updateMaxScrollPosition();
- m_contentsTexturesWerePurgedSinceLastCommit = false;
}
bool CCLayerTreeHostImpl::canDraw()
@@ -176,7 +175,7 @@
TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw no layerRenderer");
return false;
}
- if (m_contentsTexturesWerePurgedSinceLastCommit) {
+ if (m_contentsTexturesPurged) {
TRACE_EVENT_INSTANT0("cc", "CCLayerTreeHostImpl::canDraw contents textures purged");
return false;
}
@@ -519,8 +518,10 @@
void CCLayerTreeHostImpl::releaseContentsTextures()
{
+ if (m_contentsTexturesPurged)
+ return;
m_resourceProvider->deleteOwnedResources(CCRenderer::ContentPool);
- m_contentsTexturesWerePurgedSinceLastCommit = true;
+ m_contentsTexturesPurged = true;
m_client->setNeedsCommitOnImplThread();
}
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h 2012-08-15 19:54:29 UTC (rev 125699)
@@ -145,7 +145,8 @@
int sourceFrameNumber() const { return m_sourceFrameNumber; }
void setSourceFrameNumber(int frameNumber) { m_sourceFrameNumber = frameNumber; }
- bool contentsTexturesWerePurgedSinceLastCommit() const { return m_contentsTexturesWerePurgedSinceLastCommit; }
+ bool contentsTexturesPurged() const { return m_contentsTexturesPurged; }
+ void resetContentsTexturesPurged() { m_contentsTexturesPurged = false; }
size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBytes; }
void setViewportSize(const IntSize& layoutViewportSize, const IntSize& deviceViewportSize);
@@ -265,7 +266,7 @@
IntSize m_deviceViewportSize;
float m_deviceScaleFactor;
bool m_visible;
- bool m_contentsTexturesWerePurgedSinceLastCommit;
+ bool m_contentsTexturesPurged;
size_t m_memoryAllocationLimitBytes;
float m_pageScale;
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp 2012-08-15 19:54:29 UTC (rev 125699)
@@ -260,7 +260,7 @@
DebugScopedSetMainThreadBlocked mainThreadBlocked;
DebugScopedSetImplThread impl;
- if (!m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+ if (!m_layerTreeHostImpl->contentsTexturesPurged())
m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
m_layerTreeHostImpl.clear();
}
@@ -300,11 +300,12 @@
if (!m_layerTreeHost->initializeLayerRendererIfNeeded())
return false;
- if (m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+ if (m_layerTreeHostImpl->contentsTexturesPurged())
m_layerTreeHost->evictAllContentTextures();
CCTextureUpdateQueue queue;
m_layerTreeHost->updateLayers(queue, m_layerTreeHostImpl->memoryAllocationLimitBytes());
+ m_layerTreeHostImpl->resetContentsTexturesPurged();
m_layerTreeHost->willCommit();
doCommit(queue);
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateController.h (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateController.h 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateController.h 2012-08-15 19:54:29 UTC (rev 125699)
@@ -57,6 +57,7 @@
CCTextureUpdateController(PassOwnPtr<CCTextureUpdateQueue>, CCResourceProvider*, TextureCopier*, TextureUploader*);
OwnPtr<CCTextureUpdateQueue> m_queue;
+ bool m_contentsTexturesPurged;
CCResourceProvider* m_resourceProvider;
TextureCopier* m_copier;
TextureUploader* m_uploader;
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.cpp (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.cpp 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.cpp 2012-08-15 19:54:29 UTC (rev 125699)
@@ -54,6 +54,12 @@
m_copyEntries.append(copy);
}
+void CCTextureUpdateQueue::clearUploads()
+{
+ m_fullEntries.clear();
+ m_partialEntries.clear();
+}
+
TextureUploader::Parameters CCTextureUpdateQueue::takeFirstFullUpload()
{
return m_fullEntries.takeFirst();
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.h (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.h 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCTextureUpdateQueue.h 2012-08-15 19:54:29 UTC (rev 125699)
@@ -43,6 +43,8 @@
void appendPartialUpload(TextureUploader::Parameters);
void appendCopy(TextureCopier::Parameters);
+ void clearUploads();
+
TextureUploader::Parameters takeFirstFullUpload();
TextureUploader::Parameters takeFirstPartialUpload();
TextureCopier::Parameters takeFirstCopy();
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-08-15 19:54:29 UTC (rev 125699)
@@ -80,6 +80,7 @@
, m_readbackRequestOnImplThread(0)
, m_commitCompletionEventOnImplThread(0)
, m_textureAcquisitionCompletionEventOnImplThread(0)
+ , m_resetContentsTexturesPurgedAfterCommitOnImplThread(false)
, m_nextFrameIsNewlyCommittedFrameOnImplThread(false)
, m_renderVSyncEnabled(layerTreeHost->settings().renderVSyncEnabled)
{
@@ -445,7 +446,7 @@
m_pendingBeginFrameRequest = adoptPtr(new BeginFrameAndCommitState());
m_pendingBeginFrameRequest->monotonicFrameBeginTime = monotonicallyIncreasingTime();
m_pendingBeginFrameRequest->scrollInfo = m_layerTreeHostImpl->processScrollDeltas();
- m_pendingBeginFrameRequest->contentsTexturesWereDeleted = m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit();
+ m_pendingBeginFrameRequest->contentsTexturesWereDeleted = m_layerTreeHostImpl->contentsTexturesPurged();
m_pendingBeginFrameRequest->memoryAllocationLimitBytes = m_layerTreeHostImpl->memoryAllocationLimitBytes();
m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrame));
@@ -538,7 +539,7 @@
DebugScopedSetMainThreadBlocked mainThreadBlocked;
CCCompletionEvent completion;
- CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, &completion, queue.release()));
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::beginFrameCompleteOnImplThread, &completion, queue.release(), request->contentsTexturesWereDeleted));
completion.wait();
}
@@ -546,7 +547,7 @@
m_layerTreeHost->didBeginFrame();
}
-void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion, PassOwnPtr<CCTextureUpdateQueue> queue)
+void CCThreadProxy::beginFrameCompleteOnImplThread(CCCompletionEvent* completion, PassOwnPtr<CCTextureUpdateQueue> queue, bool contentsTexturesWereDeleted)
{
TRACE_EVENT0("cc", "CCThreadProxy::beginFrameCompleteOnImplThread");
ASSERT(!m_commitCompletionEventOnImplThread);
@@ -559,6 +560,16 @@
return;
}
+ if (!contentsTexturesWereDeleted && m_layerTreeHostImpl->contentsTexturesPurged()) {
+ // We purged the content textures on the impl thread between the time we
+ // posted the beginFrame task and now, meaning we have a bunch of
+ // uploads that are now invalid. Clear the uploads (they all go to
+ // content textures), and kick another commit to fill them again.
+ queue->clearUploads();
+ setNeedsCommitOnImplThread();
+ } else
+ m_resetContentsTexturesPurgedAfterCommitOnImplThread = true;
+
m_currentTextureUpdateControllerOnImplThread = CCTextureUpdateController::create(queue, m_layerTreeHostImpl->resourceProvider(), m_layerTreeHostImpl->layerRenderer()->textureCopier(), m_layerTreeHostImpl->layerRenderer()->textureUploader());
m_commitCompletionEventOnImplThread = completion;
@@ -612,6 +623,11 @@
m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
+ if (m_resetContentsTexturesPurgedAfterCommitOnImplThread) {
+ m_resetContentsTexturesPurgedAfterCommitOnImplThread = false;
+ m_layerTreeHostImpl->resetContentsTexturesPurged();
+ }
+
m_layerTreeHostImpl->commitComplete();
m_nextFrameIsNewlyCommittedFrameOnImplThread = true;
@@ -846,7 +862,7 @@
{
TRACE_EVENT0("cc", "CCThreadProxy::layerTreeHostClosedOnImplThread");
ASSERT(isImplThread());
- if (!m_layerTreeHostImpl->contentsTexturesWerePurgedSinceLastCommit())
+ if (!m_layerTreeHostImpl->contentsTexturesPurged())
m_layerTreeHost->deleteContentsTexturesOnImplThread(m_layerTreeHostImpl->resourceProvider());
m_inputHandlerOnImplThread.clear();
m_layerTreeHostImpl.clear();
Modified: branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h (125698 => 125699)
--- branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-08-15 19:54:29 UTC (rev 125699)
@@ -126,7 +126,7 @@
IntRect rect;
};
void forceBeginFrameOnImplThread(CCCompletionEvent*);
- void beginFrameCompleteOnImplThread(CCCompletionEvent*, PassOwnPtr<CCTextureUpdateQueue>);
+ void beginFrameCompleteOnImplThread(CCCompletionEvent*, PassOwnPtr<CCTextureUpdateQueue>, bool contentsTexturesWereDeleted);
void beginFrameAbortedOnImplThread();
void requestReadbackOnImplThread(ReadbackRequest*);
void requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double durationSec);
@@ -184,6 +184,10 @@
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;
Modified: branches/chromium/1229/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (125698 => 125699)
--- branches/chromium/1229/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp 2012-08-15 19:54:29 UTC (rev 125699)
@@ -2349,4 +2349,251 @@
SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit)
+
+class EvictionTrackingTexture : public LayerTextureUpdater::Texture {
+public:
+ static PassOwnPtr<EvictionTrackingTexture> create(PassOwnPtr<CCPrioritizedTexture> texture) { return adoptPtr(new EvictionTrackingTexture(texture)); }
+ virtual ~EvictionTrackingTexture() { }
+
+ virtual void updateRect(CCResourceProvider* resourceProvider, const IntRect&, const IntRect&) OVERRIDE
+ {
+ ASSERT_TRUE(!texture()->haveBackingTexture() || resourceProvider->numResources() > 0);
+ texture()->acquireBackingTexture(resourceProvider);
+ m_updated = true;
+ }
+ void resetUpdated() { m_updated = false; }
+ bool updated() const { return m_updated; }
+
+private:
+ explicit EvictionTrackingTexture(PassOwnPtr<CCPrioritizedTexture> texture)
+ : LayerTextureUpdater::Texture(texture)
+ , m_updated(false)
+ { }
+ bool m_updated;
+};
+
+class EvictionTestLayer : public LayerChromium {
+public:
+ static PassRefPtr<EvictionTestLayer> create() { return adoptRef(new EvictionTestLayer()); }
+
+ virtual void update(CCTextureUpdateQueue&, const CCOcclusionTracker*, CCRenderingStats&) OVERRIDE;
+ virtual bool drawsContent() const OVERRIDE { return true; }
+
+ virtual PassOwnPtr<CCLayerImpl> createCCLayerImpl() OVERRIDE;
+ virtual void pushPropertiesTo(CCLayerImpl*) OVERRIDE;
+ virtual void setTexturePriorities(const CCPriorityCalculator&) OVERRIDE;
+
+ void resetUpdated()
+ {
+ if (m_texture.get())
+ m_texture->resetUpdated();
+ }
+ bool updated() const { return m_texture.get() ? m_texture->updated() : false; }
+
+private:
+ EvictionTestLayer() : LayerChromium() { }
+
+ void createTextureIfNeeded()
+ {
+ if (m_texture.get())
+ return;
+ m_texture = EvictionTrackingTexture::create(CCPrioritizedTexture::create(layerTreeHost()->contentsTextureManager()));
+ m_texture->texture()->setDimensions(WebCore::IntSize(10, 10), WebCore::GraphicsContext3D::RGBA);
+ }
+
+ OwnPtr<EvictionTrackingTexture> m_texture;
+};
+
+class EvictionTestLayerImpl : public CCLayerImpl {
+public:
+ static PassOwnPtr<EvictionTestLayerImpl> create(int id)
+ {
+ return adoptPtr(new EvictionTestLayerImpl(id));
+ }
+ virtual ~EvictionTestLayerImpl() { }
+ virtual void appendQuads(CCQuadSink&, const CCSharedQuadState*, bool& hadMissingTiles)
+ {
+ ASSERT_TRUE(m_hasTexture);
+ ASSERT_NE(0u, layerTreeHostImpl()->resourceProvider()->numResources());
+ }
+ void setHasTexture(bool hasTexture) { m_hasTexture = hasTexture; }
+
+private:
+ explicit EvictionTestLayerImpl(int id)
+ : CCLayerImpl(id)
+ , m_hasTexture(false) { }
+
+ bool m_hasTexture;
+};
+
+void EvictionTestLayer::setTexturePriorities(const CCPriorityCalculator&)
+{
+ createTextureIfNeeded();
+ if (!m_texture.get())
+ return;
+ m_texture->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(true));
+}
+
+void EvictionTestLayer::update(CCTextureUpdateQueue& queue, const CCOcclusionTracker*, CCRenderingStats&)
+{
+ createTextureIfNeeded();
+ if (!m_texture.get())
+ return;
+ IntRect fullRect(0, 0, 10, 10);
+ TextureUploader::Parameters parameters = { m_texture.get(), fullRect, fullRect };
+ queue.appendFullUpload(parameters);
+}
+
+PassOwnPtr<CCLayerImpl> EvictionTestLayer::createCCLayerImpl()
+{
+ return EvictionTestLayerImpl::create(m_layerId);
+}
+
+void EvictionTestLayer::pushPropertiesTo(CCLayerImpl* layerImpl)
+{
+ LayerChromium::pushPropertiesTo(layerImpl);
+
+ EvictionTestLayerImpl* testLayerImpl = static_cast<EvictionTestLayerImpl*>(layerImpl);
+ testLayerImpl->setHasTexture(m_texture->texture()->haveBackingTexture());
+}
+
+class CCLayerTreeHostTestEvictTextures : public CCLayerTreeHostTest {
+public:
+ CCLayerTreeHostTestEvictTextures()
+ : m_layer(EvictionTestLayer::create())
+ , m_implForEvictTextures(0)
+ , m_numCommits(0)
+ {
+ }
+
+ virtual void beginTest()
+ {
+ m_layerTreeHost->setRootLayer(m_layer);
+ m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20));
+
+ WebTransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(m_layer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 20), true);
+ }
+
+ class EvictTexturesTask : public WebKit::WebThread::Task {
+ public:
+ EvictTexturesTask(CCLayerTreeHostTestEvictTextures* test) : m_test(test) { }
+ virtual ~EvictTexturesTask() { }
+ virtual void run()
+ {
+ ASSERT(m_test->m_implForEvictTextures);
+ m_test->m_implForEvictTextures->releaseContentsTextures();
+ }
+
+ private:
+ CCLayerTreeHostTestEvictTextures* m_test;
+ };
+
+ void postEvictTextures()
+ {
+ ASSERT(webThread());
+ webThread()->postTask(new EvictTexturesTask(this));
+ }
+
+ // Commit 1: Just commit and draw normally, then post an eviction at the end
+ // that will trigger a commit.
+ // Commit 2: Triggered by the eviction, let it go through and then set
+ // needsCommit.
+ // Commit 3: Triggered by the setNeedsCommit. In layout(), post an eviction
+ // task, which will be handled before the commit. Don't set needsCommit, it
+ // should have been posted. A frame should not be drawn (note,
+ // didCommitAndDrawFrame may be called anyway).
+ // Commit 4: Triggered by the eviction, let it go through and then set
+ // needsCommit.
+ // Commit 5: Triggered by the setNeedsCommit, post an eviction task in
+ // layout(), a frame should not be drawn but a commit will be posted.
+ // Commit 6: Triggered by the eviction, post an eviction task in
+ // layout(), which will be a noop, letting the commit (which recreates the
+ // textures) go through and draw a frame, then end the test.
+ //
+ // Commits 1+2 test the eviction recovery path where eviction happens outside
+ // of the beginFrame/commit pair.
+ // Commits 3+4 test the eviction recovery path where eviction happens inside
+ // the beginFrame/commit pair.
+ // Commits 5+6 test the path where an eviction happens during the eviction
+ // recovery path.
+ virtual void didCommitAndDrawFrame()
+ {
+ switch (m_numCommits) {
+ case 1:
+ EXPECT_TRUE(m_layer->updated());
+ postEvictTextures();
+ break;
+ case 2:
+ EXPECT_TRUE(m_layer->updated());
+ m_layerTreeHost->setNeedsCommit();
+ break;
+ case 3:
+ break;
+ case 4:
+ EXPECT_TRUE(m_layer->updated());
+ m_layerTreeHost->setNeedsCommit();
+ break;
+ case 5:
+ break;
+ case 6:
+ EXPECT_TRUE(m_layer->updated());
+ endTest();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ m_implForEvictTextures = impl;
+ }
+
+ virtual void layout()
+ {
+ ++m_numCommits;
+ switch (m_numCommits) {
+ case 1:
+ case 2:
+ break;
+ case 3:
+ postEvictTextures();
+ break;
+ case 4:
+ // We couldn't check in didCommitAndDrawFrame on commit 3, so check here.
+ EXPECT_FALSE(m_layer->updated());
+ break;
+ case 5:
+ postEvictTextures();
+ break;
+ case 6:
+ // We couldn't check in didCommitAndDrawFrame on commit 5, so check here.
+ EXPECT_FALSE(m_layer->updated());
+ postEvictTextures();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ m_layer->resetUpdated();
+ }
+
+ virtual void afterTest()
+ {
+ }
+
+private:
+ MockContentLayerDelegate m_delegate;
+ RefPtr<EvictionTestLayer> m_layer;
+ CCLayerTreeHostImpl* m_implForEvictTextures;
+ int m_numCommits;
+};
+
+TEST_F(CCLayerTreeHostTestEvictTextures, runMultiThread)
+{
+ runTest(true);
+}
+
} // namespace
Modified: branches/chromium/1229/Source/WebKit/chromium/tests/CCThreadedTest.h (125698 => 125699)
--- branches/chromium/1229/Source/WebKit/chromium/tests/CCThreadedTest.h 2012-08-15 19:39:41 UTC (rev 125698)
+++ branches/chromium/1229/Source/WebKit/chromium/tests/CCThreadedTest.h 2012-08-15 19:54:29 UTC (rev 125699)
@@ -134,6 +134,7 @@
static void dispatchDidAddAnimation(void* self);
virtual void runTest(bool threaded);
+ WebKit::WebThread* webThread() const { return m_webThread.get(); }
WebCore::CCLayerTreeSettings m_settings;
OwnPtr<MockCCLayerTreeHostClient> m_client;