diff options
-rw-r--r-- | cc/delegated_renderer_layer_impl_unittest.cc | 2 | ||||
-rw-r--r-- | cc/gl_renderer.cc | 35 | ||||
-rw-r--r-- | cc/gl_renderer.h | 2 | ||||
-rw-r--r-- | cc/gl_renderer_unittest.cc | 1 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 19 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 5 | ||||
-rw-r--r-- | cc/layer_tree_host_impl_unittest.cc | 46 | ||||
-rw-r--r-- | cc/layer_tree_host_unittest.cc | 4 | ||||
-rw-r--r-- | cc/prioritized_texture_manager.cc | 9 | ||||
-rw-r--r-- | cc/prioritized_texture_manager.h | 7 | ||||
-rw-r--r-- | cc/renderer.h | 1 | ||||
-rw-r--r-- | cc/single_thread_proxy.cc | 8 | ||||
-rw-r--r-- | cc/single_thread_proxy.h | 2 | ||||
-rw-r--r-- | cc/software_renderer_unittest.cc | 1 | ||||
-rw-r--r-- | cc/thread_proxy.cc | 10 | ||||
-rw-r--r-- | cc/thread_proxy.h | 2 |
16 files changed, 101 insertions, 53 deletions
diff --git a/cc/delegated_renderer_layer_impl_unittest.cc b/cc/delegated_renderer_layer_impl_unittest.cc index e530377..4073d48c 100644 --- a/cc/delegated_renderer_layer_impl_unittest.cc +++ b/cc/delegated_renderer_layer_impl_unittest.cc @@ -51,7 +51,7 @@ public: virtual void setNeedsRedrawOnImplThread() OVERRIDE { } virtual void setNeedsCommitOnImplThread() OVERRIDE { } virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { } - virtual void releaseContentsTexturesOnImplThread() OVERRIDE { } + virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes) OVERRIDE { return true; } protected: scoped_ptr<CCGraphicsContext> createContext() diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc index f76863e..18c9f4f 100644 --- a/cc/gl_renderer.cc +++ b/cc/gl_renderer.cc @@ -76,6 +76,7 @@ CCRendererGL::CCRendererGL(CCRendererClient* client, , m_context(resourceProvider->graphicsContext3D()) , m_isViewportChanged(false) , m_isFramebufferDiscarded(false) + , m_discardFramebufferWhenNotVisible(false) , m_isUsingBindUniform(false) , m_visible(true) { @@ -174,6 +175,8 @@ void CCRendererGL::setVisible(bool visible) // crbug.com/116049 if (m_capabilities.usingSetVisibility) m_context->setVisibilityCHROMIUM(visible); + + enforceMemoryPolicy(); } void CCRendererGL::releaseRenderPassTextures() @@ -1067,18 +1070,24 @@ void CCRendererGL::onMemoryAllocationChanged(WebGraphicsMemoryAllocation allocat void CCRendererGL::onMemoryAllocationChangedOnImplThread(WebKit::WebGraphicsMemoryAllocation allocation) { - if (m_visible && !allocation.gpuResourceSizeInBytes) - return; - - if (!allocation.suggestHaveBackbuffer && !m_visible) - discardFramebuffer(); + m_discardFramebufferWhenNotVisible = !allocation.suggestHaveBackbuffer; + // Just ignore the memory manager when it says to set the limit to zero + // bytes. This will happen when the memory manager thinks that the renderer + // is not visible (which the renderer knows better). + if (allocation.gpuResourceSizeInBytes) + m_client->setMemoryAllocationLimitBytes(allocation.gpuResourceSizeInBytes); + enforceMemoryPolicy(); +} - if (!allocation.gpuResourceSizeInBytes) { +void CCRendererGL::enforceMemoryPolicy() +{ + if (!m_visible) { + TRACE_EVENT0("cc", "CCRendererGL::enforceMemoryPolicy dropping resources"); releaseRenderPassTextures(); - m_client->releaseContentsTextures(); + if (m_discardFramebufferWhenNotVisible) + discardFramebuffer(); GLC(m_context, m_context->flush()); - } else - m_client->setMemoryAllocationLimitBytes(allocation.gpuResourceSizeInBytes); + } } void CCRendererGL::discardFramebuffer() @@ -1179,13 +1188,7 @@ void CCRendererGL::getFramebufferPixels(void *pixels, const IntRect& rect) GLC(m_context, m_context->deleteTexture(temporaryTexture)); } - if (!m_visible) { - TRACE_EVENT0("cc", "CCRendererGL::getFramebufferPixels dropping resources after readback"); - discardFramebuffer(); - releaseRenderPassTextures(); - m_client->releaseContentsTextures(); - GLC(m_context, m_context->flush()); - } + enforceMemoryPolicy(); } bool CCRendererGL::getFramebufferTexture(CCScopedTexture* texture, const IntRect& deviceRect) diff --git a/cc/gl_renderer.h b/cc/gl_renderer.h index caf7495..07a8461 100644 --- a/cc/gl_renderer.h +++ b/cc/gl_renderer.h @@ -120,6 +120,7 @@ private: void onMemoryAllocationChangedOnImplThread(WebKit::WebGraphicsMemoryAllocation); void discardFramebuffer(); void ensureFramebuffer(); + void enforceMemoryPolicy(); // WebGraphicsContext3D::WebGraphicsContextLostCallback implementation. virtual void onContextLost() OVERRIDE; @@ -209,6 +210,7 @@ private: IntRect m_swapBufferRect; bool m_isViewportChanged; bool m_isFramebufferDiscarded; + bool m_discardFramebufferWhenNotVisible; bool m_isUsingBindUniform; bool m_visible; diff --git a/cc/gl_renderer_unittest.cc b/cc/gl_renderer_unittest.cc index 078c066..0802f36 100644 --- a/cc/gl_renderer_unittest.cc +++ b/cc/gl_renderer_unittest.cc @@ -74,7 +74,6 @@ public: virtual void didLoseContext() OVERRIDE { } virtual void onSwapBuffersComplete() OVERRIDE { } virtual void setFullRootLayerDamage() OVERRIDE { m_setFullRootLayerDamageCount++; } - virtual void releaseContentsTextures() OVERRIDE { } virtual void setMemoryAllocationLimitBytes(size_t bytes) OVERRIDE { m_memoryAllocationLimitBytes = bytes; } // Methods added for test. diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 3da5b45..51cf1e2 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -634,23 +634,23 @@ bool CCLayerTreeHostImpl::prepareToDraw(FrameData& frame) return true; } -void CCLayerTreeHostImpl::releaseContentsTextures() +void CCLayerTreeHostImpl::reduceContentsTextureMemoryOnImplThread(size_t limitBytes) { - if (m_contentsTexturesPurged) - return; - m_client->releaseContentsTexturesOnImplThread(); - setContentsTexturesPurged(); - m_client->setNeedsCommitOnImplThread(); - m_client->onCanDrawStateChanged(canDraw()); + bool evictedResources = m_client->reduceContentsTextureMemoryOnImplThread(limitBytes); + if (evictedResources) { + setContentsTexturesPurged(); + m_client->setNeedsCommitOnImplThread(); + m_client->onCanDrawStateChanged(canDraw()); + } } void CCLayerTreeHostImpl::setMemoryAllocationLimitBytes(size_t bytes) { + ASSERT(bytes); if (m_memoryAllocationLimitBytes == bytes) return; m_memoryAllocationLimitBytes = bytes; - - ASSERT(bytes); + reduceContentsTextureMemoryOnImplThread(m_visible ? m_memoryAllocationLimitBytes : 0); m_client->setNeedsCommitOnImplThread(); } @@ -817,6 +817,7 @@ void CCLayerTreeHostImpl::setVisible(bool visible) return; m_visible = visible; didVisibilityChange(this, m_visible); + reduceContentsTextureMemoryOnImplThread(m_visible ? m_memoryAllocationLimitBytes : 0); if (!m_renderer) return; diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index 1a56c14..b6f57e5 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -43,7 +43,8 @@ public: virtual void setNeedsRedrawOnImplThread() = 0; virtual void setNeedsCommitOnImplThread() = 0; virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector>, double wallClockTime) = 0; - virtual void releaseContentsTexturesOnImplThread() = 0; + // Returns true if resources were deleted by this call. + virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes) = 0; }; // CCPinchZoomViewport models the bounds and offset of the viewport that is used during a pinch-zoom operation. @@ -151,7 +152,6 @@ public: virtual void didLoseContext() OVERRIDE; virtual void onSwapBuffersComplete() OVERRIDE; virtual void setFullRootLayerDamage() OVERRIDE; - virtual void releaseContentsTextures() OVERRIDE; virtual void setMemoryAllocationLimitBytes(size_t) OVERRIDE; // WebCompositorOutputSurfaceClient implementation. @@ -197,6 +197,7 @@ public: void setContentsTexturesPurged(); void resetContentsTexturesPurged(); size_t memoryAllocationLimitBytes() const { return m_memoryAllocationLimitBytes; } + void reduceContentsTextureMemoryOnImplThread(size_t limitBytes); void setViewportSize(const IntSize& layoutViewportSize, const IntSize& deviceViewportSize); const IntSize& layoutViewportSize() const { return m_layoutViewportSize; } diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc index 7305831..9f0b3c4 100644 --- a/cc/layer_tree_host_impl_unittest.cc +++ b/cc/layer_tree_host_impl_unittest.cc @@ -60,6 +60,7 @@ public: : m_onCanDrawStateChangedCalled(false) , m_didRequestCommit(false) , m_didRequestRedraw(false) + , m_reduceMemoryResult(true) { } @@ -86,7 +87,9 @@ public: virtual void setNeedsRedrawOnImplThread() OVERRIDE { m_didRequestRedraw = true; } virtual void setNeedsCommitOnImplThread() OVERRIDE { m_didRequestCommit = true; } virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE { } - virtual void releaseContentsTexturesOnImplThread() OVERRIDE { } + virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes) OVERRIDE { return m_reduceMemoryResult; } + + void setReduceMemoryResult(bool reduceMemoryResult) { m_reduceMemoryResult = reduceMemoryResult; } scoped_ptr<CCLayerTreeHostImpl> createLayerTreeHost(bool partialSwap, scoped_ptr<CCGraphicsContext> graphicsContext, scoped_ptr<CCLayerImpl> root) { @@ -186,6 +189,7 @@ protected: bool m_onCanDrawStateChangedCalled; bool m_didRequestCommit; bool m_didRequestRedraw; + bool m_reduceMemoryResult; CCScopedSettings m_scopedSettings; }; @@ -229,8 +233,19 @@ TEST_P(CCLayerTreeHostImplTest, notifyIfCanDrawChanged) EXPECT_TRUE(m_onCanDrawStateChangedCalled); m_onCanDrawStateChangedCalled = false; - // Toggle contents textures purged to make sure it toggles canDraw - m_hostImpl->releaseContentsTextures(); + // Toggle contents textures purged without causing any evictions, + // and make sure that it does not change canDraw. + setReduceMemoryResult(false); + m_hostImpl->setMemoryAllocationLimitBytes( + m_hostImpl->memoryAllocationLimitBytes() - 1); + EXPECT_TRUE(m_hostImpl->canDraw()); + EXPECT_FALSE(m_onCanDrawStateChangedCalled); + m_onCanDrawStateChangedCalled = false; + + // Toggle contents textures purged to make sure it toggles canDraw. + setReduceMemoryResult(true); + m_hostImpl->setMemoryAllocationLimitBytes( + m_hostImpl->memoryAllocationLimitBytes() - 1); EXPECT_FALSE(m_hostImpl->canDraw()); EXPECT_TRUE(m_onCanDrawStateChangedCalled); m_onCanDrawStateChangedCalled = false; @@ -4009,8 +4024,30 @@ TEST_P(CCLayerTreeHostImplTest, surfaceTextureCachingNoPartialSwap) TEST_P(CCLayerTreeHostImplTest, releaseContentsTextureShouldTriggerCommit) { - m_hostImpl->releaseContentsTextures(); + setReduceMemoryResult(false); + + // Even if changing the memory limit didn't result in anything being + // evicted, we need to re-commit because the new value may result in us + // drawing something different than before. + setReduceMemoryResult(false); + m_hostImpl->setMemoryAllocationLimitBytes( + m_hostImpl->memoryAllocationLimitBytes() - 1); EXPECT_TRUE(m_didRequestCommit); + m_didRequestCommit = false; + + // Especially if changing the memory limit caused evictions, we need + // to re-commit. + setReduceMemoryResult(true); + m_hostImpl->setMemoryAllocationLimitBytes( + m_hostImpl->memoryAllocationLimitBytes() - 1); + EXPECT_TRUE(m_didRequestCommit); + m_didRequestCommit = false; + + // But if we set it to the same value that it was before, we shouldn't + // re-commit. + m_hostImpl->setMemoryAllocationLimitBytes( + m_hostImpl->memoryAllocationLimitBytes()); + EXPECT_FALSE(m_didRequestCommit); } struct RenderPassRemovalTestData : public CCLayerTreeHostImpl::FrameData { @@ -4040,7 +4077,6 @@ public: virtual void didLoseContext() OVERRIDE { } virtual void onSwapBuffersComplete() OVERRIDE { } virtual void setFullRootLayerDamage() OVERRIDE { } - virtual void releaseContentsTextures() OVERRIDE { } virtual void setMemoryAllocationLimitBytes(size_t) OVERRIDE { } protected: diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc index dcce06c..c94c913 100644 --- a/cc/layer_tree_host_unittest.cc +++ b/cc/layer_tree_host_unittest.cc @@ -2507,7 +2507,7 @@ public: virtual void run() OVERRIDE { ASSERT(m_test->m_implForEvictTextures); - m_test->m_implForEvictTextures->releaseContentsTextures(); + m_test->m_implForEvictTextures->reduceContentsTextureMemoryOnImplThread(0); } private: @@ -2664,7 +2664,7 @@ public: void evictTexturesOnImplThread() { ASSERT(m_implForEvictTextures); - m_implForEvictTextures->releaseContentsTextures(); + m_implForEvictTextures->reduceContentsTextureMemoryOnImplThread(0); } // Commit 1: Just commit and draw normally, then at the end, set ourselves diff --git a/cc/prioritized_texture_manager.cc b/cc/prioritized_texture_manager.cc index edd773b..ccde22f 100644 --- a/cc/prioritized_texture_manager.cc +++ b/cc/prioritized_texture_manager.cc @@ -207,11 +207,11 @@ void CCPrioritizedTextureManager::acquireBackingTextureIfNeeded(CCPrioritizedTex backing->updatePriority(); } -void CCPrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy evictionPolicy, CCResourceProvider* resourceProvider) +bool CCPrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy evictionPolicy, CCResourceProvider* resourceProvider) { ASSERT(CCProxy::isImplThread()); if (memoryUseBytes() <= limitBytes) - return; + return false; // Destroy backings until we are below the limit, // or until all backings remaining are above the cutoff. @@ -222,6 +222,7 @@ void CCPrioritizedTextureManager::evictBackingsToReduceMemory(size_t limitBytes, break; evictFirstBackingResource(resourceProvider); } + return true; } void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvider) @@ -263,7 +264,7 @@ void CCPrioritizedTextureManager::clearAllMemory(CCResourceProvider* resourcePro evictBackingsToReduceMemory(0, DoNotRespectManagerPriorityCutoff, resourceProvider); } -void CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider) +bool CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider* resourceProvider) { ASSERT(CCProxy::isImplThread()); ASSERT(resourceProvider); @@ -271,7 +272,7 @@ void CCPrioritizedTextureManager::reduceMemoryOnImplThread(size_t limitBytes, CC // the list are not sorted by priority. Sort them before doing the eviction. if (m_backingsTailNotSorted) sortBackings(); - evictBackingsToReduceMemory(limitBytes, DoNotRespectManagerPriorityCutoff, resourceProvider); + return evictBackingsToReduceMemory(limitBytes, DoNotRespectManagerPriorityCutoff, resourceProvider); } void CCPrioritizedTextureManager::getEvictedBackings(BackingList& evictedBackings) diff --git a/cc/prioritized_texture_manager.h b/cc/prioritized_texture_manager.h index e27e8f2..1ccf538 100644 --- a/cc/prioritized_texture_manager.h +++ b/cc/prioritized_texture_manager.h @@ -68,8 +68,9 @@ public: 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*); + // be called on the impl thread while the main thread is running. Returns true if resources are + // indeed evicted as a result of this call. + bool reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider*); // 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. @@ -134,7 +135,7 @@ private: CCPrioritizedTextureManager(size_t maxMemoryLimitBytes, int maxTextureSize, int pool); - void evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy, CCResourceProvider*); + bool evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy, CCResourceProvider*); CCPrioritizedTexture::Backing* createBacking(IntSize, GC3Denum format, CCResourceProvider*); void evictFirstBackingResource(CCResourceProvider*); void deleteUnlinkedEvictedBackings(); diff --git a/cc/renderer.h b/cc/renderer.h index 48a071f..1b32436 100644 --- a/cc/renderer.h +++ b/cc/renderer.h @@ -21,7 +21,6 @@ public: virtual const CCLayerTreeSettings& settings() const = 0; virtual void didLoseContext() = 0; virtual void onSwapBuffersComplete() = 0; - virtual void releaseContentsTextures() = 0; virtual void setFullRootLayerDamage() = 0; virtual void setMemoryAllocationLimitBytes(size_t) = 0; protected: diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc index a7e0781..c5a07f0 100644 --- a/cc/single_thread_proxy.cc +++ b/cc/single_thread_proxy.cc @@ -280,11 +280,13 @@ void CCSingleThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr m_layerTreeHost->setAnimationEvents(events.Pass(), wallClockTime); } -void CCSingleThreadProxy::releaseContentsTexturesOnImplThread() +bool CCSingleThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes) { ASSERT(isImplThread()); - if (m_layerTreeHost->contentsTextureManager()) - m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); + if (!m_layerTreeHost->contentsTextureManager()) + return false; + + return m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, m_layerTreeHostImpl->resourceProvider()); } // Called by the legacy scheduling path (e.g. where render_widget does the scheduling) diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h index 2bbacef..ed70b80 100644 --- a/cc/single_thread_proxy.h +++ b/cc/single_thread_proxy.h @@ -52,7 +52,7 @@ public: virtual void setNeedsRedrawOnImplThread() OVERRIDE; virtual void setNeedsCommitOnImplThread() OVERRIDE; virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE; - virtual void releaseContentsTexturesOnImplThread() OVERRIDE; + virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes) OVERRIDE; // Called by the legacy path where RenderWidget does the scheduling. void compositeImmediately(); diff --git a/cc/software_renderer_unittest.cc b/cc/software_renderer_unittest.cc index d4618de..ed0a038 100644 --- a/cc/software_renderer_unittest.cc +++ b/cc/software_renderer_unittest.cc @@ -48,7 +48,6 @@ public: virtual void didLoseContext() OVERRIDE { } virtual void onSwapBuffersComplete() OVERRIDE { } virtual void setFullRootLayerDamage() OVERRIDE { } - virtual void releaseContentsTextures() OVERRIDE { } virtual void setMemoryAllocationLimitBytes(size_t) OVERRIDE { } protected: diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc index 2e1e74d..f738f8f 100644 --- a/cc/thread_proxy.cc +++ b/cc/thread_proxy.cc @@ -349,17 +349,21 @@ void CCThreadProxy::postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAni m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadProxy::setAnimationEvents, events.release(), wallClockTime)); } -void CCThreadProxy::releaseContentsTexturesOnImplThread() +bool CCThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes) { ASSERT(isImplThread()); - if (m_layerTreeHost->contentsTextureManager()) - m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(0, m_layerTreeHostImpl->resourceProvider()); + if (!m_layerTreeHost->contentsTextureManager()) + return false; + + if (!m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, m_layerTreeHostImpl->resourceProvider())) + return false; // The texture upload queue may reference textures that were just purged, clear // them from the queue. if (m_currentTextureUpdateControllerOnImplThread.get()) m_currentTextureUpdateControllerOnImplThread->discardUploadsToEvictedResources(); + return true; } void CCThreadProxy::setNeedsRedraw() diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index 2312f01..9b65135 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -61,7 +61,7 @@ public: virtual void setNeedsRedrawOnImplThread() OVERRIDE; virtual void setNeedsCommitOnImplThread() OVERRIDE; virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<CCAnimationEventsVector>, double wallClockTime) OVERRIDE; - virtual void releaseContentsTexturesOnImplThread() OVERRIDE; + virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes) OVERRIDE; // CCSchedulerClient implementation virtual void scheduledActionBeginFrame() OVERRIDE; |