summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/delegated_renderer_layer_impl_unittest.cc1
-rw-r--r--cc/gl_renderer.cc5
-rw-r--r--cc/gl_renderer.h2
-rw-r--r--cc/layer_tree_host_impl.cc2
-rw-r--r--cc/layer_tree_host_impl.h1
-rw-r--r--cc/layer_tree_host_impl_unittest.cc1
-rw-r--r--cc/prioritized_texture_manager.cc34
-rw-r--r--cc/prioritized_texture_manager.h12
-rw-r--r--cc/prioritized_texture_unittest.cc63
-rw-r--r--cc/priority_calculator.cc10
-rw-r--r--cc/priority_calculator.h1
-rw-r--r--cc/renderer.h2
-rw-r--r--cc/single_thread_proxy.cc10
-rw-r--r--cc/single_thread_proxy.h1
-rw-r--r--cc/software_renderer.h2
-rw-r--r--cc/thread_proxy.cc10
-rw-r--r--cc/thread_proxy.h1
17 files changed, 155 insertions, 3 deletions
diff --git a/cc/delegated_renderer_layer_impl_unittest.cc b/cc/delegated_renderer_layer_impl_unittest.cc
index 8e3b43e..c8ecda0 100644
--- a/cc/delegated_renderer_layer_impl_unittest.cc
+++ b/cc/delegated_renderer_layer_impl_unittest.cc
@@ -52,6 +52,7 @@ public:
virtual void setNeedsCommitOnImplThread() OVERRIDE { }
virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector>, double wallClockTime) OVERRIDE { }
virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff) OVERRIDE { return true; }
+ virtual void sendManagedMemoryStats() OVERRIDE { }
protected:
scoped_ptr<GraphicsContext> createContext()
diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc
index b059d76..f287aec 100644
--- a/cc/gl_renderer.cc
+++ b/cc/gl_renderer.cc
@@ -184,6 +184,11 @@ void GLRenderer::setVisible(bool visible)
enforceMemoryPolicy();
}
+void GLRenderer::sendManagedMemoryStats(size_t bytesVisible, size_t bytesVisibleAndNearby, size_t bytesAllocated)
+{
+ // This message cannot reach the GPU process until WebKit changes land.
+}
+
void GLRenderer::releaseRenderPassTextures()
{
m_renderPassTextures.clear();
diff --git a/cc/gl_renderer.h b/cc/gl_renderer.h
index 0a5ec31..fc6810f 100644
--- a/cc/gl_renderer.h
+++ b/cc/gl_renderer.h
@@ -56,6 +56,8 @@ public:
virtual void setVisible(bool) OVERRIDE;
+ virtual void sendManagedMemoryStats(size_t bytesVisible, size_t bytesVisibleAndNearby, size_t bytesAllocated) OVERRIDE;
+
protected:
GLRenderer(RendererClient*, ResourceProvider*);
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc
index d228ba1..eca5aa2 100644
--- a/cc/layer_tree_host_impl.cc
+++ b/cc/layer_tree_host_impl.cc
@@ -259,6 +259,7 @@ void LayerTreeHostImpl::commitComplete()
// Recompute max scroll position; must be after layer content bounds are
// updated.
updateMaxScrollPosition();
+ m_client->sendManagedMemoryStats();
}
bool LayerTreeHostImpl::canDraw()
@@ -648,6 +649,7 @@ void LayerTreeHostImpl::enforceManagedMemoryPolicy(const ManagedMemoryPolicy& po
m_client->setNeedsCommitOnImplThread();
m_client->onCanDrawStateChanged(canDraw());
}
+ m_client->sendManagedMemoryStats();
}
void LayerTreeHostImpl::setManagedMemoryPolicy(const ManagedMemoryPolicy& policy)
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index 7ce1d31..1dc750d 100644
--- a/cc/layer_tree_host_impl.h
+++ b/cc/layer_tree_host_impl.h
@@ -43,6 +43,7 @@ public:
virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector>, double wallClockTime) = 0;
// Returns true if resources were deleted by this call.
virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff) = 0;
+ virtual void sendManagedMemoryStats() = 0;
};
// PinchZoomViewport models the bounds and offset of the viewport that is used during a pinch-zoom operation.
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc
index 68a4b7f..106a702 100644
--- a/cc/layer_tree_host_impl_unittest.cc
+++ b/cc/layer_tree_host_impl_unittest.cc
@@ -88,6 +88,7 @@ public:
virtual void setNeedsCommitOnImplThread() OVERRIDE { m_didRequestCommit = true; }
virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector>, double wallClockTime) OVERRIDE { }
virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff) OVERRIDE { return m_reduceMemoryResult; }
+ virtual void sendManagedMemoryStats() OVERRIDE { }
void setReduceMemoryResult(bool reduceMemoryResult) { m_reduceMemoryResult = reduceMemoryResult; }
diff --git a/cc/prioritized_texture_manager.cc b/cc/prioritized_texture_manager.cc
index 6ad408e..c41b347 100644
--- a/cc/prioritized_texture_manager.cc
+++ b/cc/prioritized_texture_manager.cc
@@ -25,6 +25,10 @@ PrioritizedTextureManager::PrioritizedTextureManager(size_t maxMemoryLimitBytes,
, m_memoryAvailableBytes(0)
, m_pool(pool)
, m_backingsTailNotSorted(false)
+ , m_memoryVisibleBytes(0)
+ , m_memoryVisibleAndNearbyBytes(0)
+ , m_memoryVisibleLastPushedBytes(0)
+ , m_memoryVisibleAndNearbyLastPushedBytes(0)
{
}
@@ -40,6 +44,18 @@ PrioritizedTextureManager::~PrioritizedTextureManager()
DCHECK(m_backings.empty());
}
+size_t PrioritizedTextureManager::memoryVisibleBytes() const
+{
+ DCHECK(Proxy::isImplThread());
+ return m_memoryVisibleLastPushedBytes;
+}
+
+size_t PrioritizedTextureManager::memoryVisibleAndNearbyBytes() const
+{
+ DCHECK(Proxy::isImplThread());
+ return m_memoryVisibleAndNearbyLastPushedBytes;
+}
+
void PrioritizedTextureManager::prioritizeTextures()
{
TRACE_EVENT0("cc", "PrioritizedTextureManager::prioritizeTextures");
@@ -52,9 +68,17 @@ void PrioritizedTextureManager::prioritizeTextures()
TextureVector& sortedTextures = m_tempTextureVector;
sortedTextures.clear();
- // Copy all textures into a vector and sort them.
- for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); ++it)
- sortedTextures.push_back(*it);
+ // Copy all textures into a vector, sort them, and collect memory requirements statistics.
+ m_memoryVisibleBytes = 0;
+ m_memoryVisibleAndNearbyBytes = 0;
+ for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); ++it) {
+ PrioritizedTexture* texture = (*it);
+ sortedTextures.push_back(texture);
+ if (PriorityCalculator::priorityIsHigher(texture->requestPriority(), PriorityCalculator::allowVisibleOnlyCutoff()))
+ m_memoryVisibleBytes += texture->bytes();
+ if (PriorityCalculator::priorityIsHigher(texture->requestPriority(), PriorityCalculator::allowVisibleAndNearbyCutoff()))
+ m_memoryVisibleAndNearbyBytes += texture->bytes();
+ }
std::sort(sortedTextures.begin(), sortedTextures.end(), compareTextures);
// Compute a priority cutoff based on memory pressure
@@ -118,6 +142,10 @@ void PrioritizedTextureManager::pushTexturePrioritiesToBackings()
(*it)->updatePriority();
sortBackings();
assertInvariants();
+
+ // Push memory requirements to the impl thread structure.
+ m_memoryVisibleLastPushedBytes = m_memoryVisibleBytes;
+ m_memoryVisibleAndNearbyLastPushedBytes = m_memoryVisibleAndNearbyBytes;
}
void PrioritizedTextureManager::updateBackingsInDrawingImplTree()
diff --git a/cc/prioritized_texture_manager.h b/cc/prioritized_texture_manager.h
index 47f283a..952b584 100644
--- a/cc/prioritized_texture_manager.h
+++ b/cc/prioritized_texture_manager.h
@@ -69,6 +69,10 @@ public:
// than this cutoff will be allowed.
void setExternalPriorityCutoff(int priorityCutoff) { m_externalPriorityCutoff = priorityCutoff; }
+ // Return the amount of texture memory required at particular cutoffs.
+ size_t memoryVisibleBytes() const;
+ size_t memoryVisibleAndNearbyBytes() const;
+
void prioritizeTextures();
void clearPriorities();
@@ -174,6 +178,14 @@ private:
TextureVector m_tempTextureVector;
+ // Statistics about memory usage at priority cutoffs, computed at prioritizeTextures.
+ size_t m_memoryVisibleBytes;
+ size_t m_memoryVisibleAndNearbyBytes;
+
+ // Statistics copied at the time of pushTexturePrioritiesToBackings.
+ size_t m_memoryVisibleLastPushedBytes;
+ size_t m_memoryVisibleAndNearbyLastPushedBytes;
+
DISALLOW_COPY_AND_ASSIGN(PrioritizedTextureManager);
};
diff --git a/cc/prioritized_texture_unittest.cc b/cc/prioritized_texture_unittest.cc
index c223870..61c80d3 100644
--- a/cc/prioritized_texture_unittest.cc
+++ b/cc/prioritized_texture_unittest.cc
@@ -642,4 +642,67 @@ TEST_F(PrioritizedTextureTest, clearUploadsToEvictedResources)
}
+TEST_F(PrioritizedTextureTest, usageStatistics)
+{
+ const size_t maxTextures = 5;
+ scoped_ptr<PrioritizedTextureManager> textureManager = createManager(maxTextures);
+ scoped_ptr<PrioritizedTexture> textures[maxTextures];
+
+ for (size_t i = 0; i < maxTextures; ++i)
+ textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
+
+ textures[0]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
+ textures[1]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff());
+ textures[2]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() - 1);
+ textures[3]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff());
+ textures[4]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() + 1);
+
+ // Set max limit to 2 textures.
+ textureManager->setMaxMemoryLimitBytes(texturesMemorySize(2));
+ prioritizeTexturesAndBackings(textureManager.get());
+
+ // The first two textures should be available, others should not.
+ for (size_t i = 0; i < 2; ++i)
+ EXPECT_TRUE(validateTexture(textures[i], false));
+ for (size_t i = 2; i < maxTextures; ++i)
+ EXPECT_FALSE(validateTexture(textures[i], false));
+
+ // Validate the statistics.
+ {
+ DebugScopedSetImplThread implThread;
+ EXPECT_EQ(texturesMemorySize(2), textureManager->memoryUseBytes());
+ EXPECT_EQ(texturesMemorySize(1), textureManager->memoryVisibleBytes());
+ EXPECT_EQ(texturesMemorySize(3), textureManager->memoryVisibleAndNearbyBytes());
+ }
+
+ // Re-prioritize the textures, but do not push the values to backings.
+ textures[0]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
+ textures[1]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
+ textures[2]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
+ textures[3]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() - 1);
+ textures[4]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff());
+ textureManager->prioritizeTextures();
+
+ // Verify that we still see the old values.
+ {
+ DebugScopedSetImplThread implThread;
+ EXPECT_EQ(texturesMemorySize(2), textureManager->memoryUseBytes());
+ EXPECT_EQ(texturesMemorySize(1), textureManager->memoryVisibleBytes());
+ EXPECT_EQ(texturesMemorySize(3), textureManager->memoryVisibleAndNearbyBytes());
+ }
+
+ // Push priorities to backings, and verify we see the new values.
+ {
+ DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked;
+ textureManager->pushTexturePrioritiesToBackings();
+ EXPECT_EQ(texturesMemorySize(2), textureManager->memoryUseBytes());
+ EXPECT_EQ(texturesMemorySize(3), textureManager->memoryVisibleBytes());
+ EXPECT_EQ(texturesMemorySize(4), textureManager->memoryVisibleAndNearbyBytes());
+ }
+
+ DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked;
+ textureManager->clearAllMemory(resourceProvider());
+}
+
+
} // namespace
diff --git a/cc/priority_calculator.cc b/cc/priority_calculator.cc
index e2bb0c7..fc250d9 100644
--- a/cc/priority_calculator.cc
+++ b/cc/priority_calculator.cc
@@ -27,6 +27,10 @@ static const int visibleOnlyPriorityCutoff = 4;
static const int notVisibleBasePriority = 1000000;
static const int notVisibleLimitPriority = 1900000;
+// Arbitrarily define "nearby" to be 2000 pixels. A better estimate
+// would be percent-of-viewport or percent-of-screen.
+static const int visibleAndNearbyPriorityCutoff = notVisibleBasePriority + 2000;
+
// Small animated layers are treated as though they are 512 pixels
// from being visible.
static const int smallAnimatedLayerPriority = notVisibleBasePriority + 512;
@@ -116,6 +120,12 @@ int PriorityCalculator::allowVisibleOnlyCutoff()
}
// static
+int PriorityCalculator::allowVisibleAndNearbyCutoff()
+{
+ return visibleAndNearbyPriorityCutoff;
+}
+
+// static
int PriorityCalculator::allowEverythingCutoff()
{
return everythingPriorityCutoff;
diff --git a/cc/priority_calculator.h b/cc/priority_calculator.h
index e8daa90..761b6d5 100644
--- a/cc/priority_calculator.h
+++ b/cc/priority_calculator.h
@@ -27,6 +27,7 @@ public:
static int allowNothingCutoff();
static int allowVisibleOnlyCutoff();
+ static int allowVisibleAndNearbyCutoff();
static int allowEverythingCutoff();
};
diff --git a/cc/renderer.h b/cc/renderer.h
index 5edd957..dfb6a87 100644
--- a/cc/renderer.h
+++ b/cc/renderer.h
@@ -67,6 +67,8 @@ public:
virtual void setVisible(bool) = 0;
+ virtual void sendManagedMemoryStats(size_t bytesVisible, size_t bytesVisibleAndNearby, size_t bytesAllocated) = 0;
+
protected:
explicit Renderer(RendererClient* client)
: m_client(client)
diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc
index 9667e75..d9918fa 100644
--- a/cc/single_thread_proxy.cc
+++ b/cc/single_thread_proxy.cc
@@ -286,6 +286,16 @@ bool SingleThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitByte
return m_layerTreeHost->contentsTextureManager()->reduceMemoryOnImplThread(limitBytes, priorityCutoff, m_layerTreeHostImpl->resourceProvider());
}
+void SingleThreadProxy::sendManagedMemoryStats()
+{
+ DCHECK(Proxy::isImplThread());
+ if (m_layerTreeHostImpl.get() && m_layerTreeHostImpl->renderer())
+ m_layerTreeHostImpl->renderer()->sendManagedMemoryStats(
+ m_layerTreeHost->contentsTextureManager()->memoryVisibleBytes(),
+ m_layerTreeHost->contentsTextureManager()->memoryVisibleAndNearbyBytes(),
+ m_layerTreeHost->contentsTextureManager()->memoryUseBytes());
+}
+
// Called by the legacy scheduling path (e.g. where render_widget does the scheduling)
void SingleThreadProxy::compositeImmediately()
{
diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h
index 5b5e208..9ade5f8 100644
--- a/cc/single_thread_proxy.h
+++ b/cc/single_thread_proxy.h
@@ -54,6 +54,7 @@ public:
virtual void setNeedsCommitOnImplThread() OVERRIDE;
virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector>, double wallClockTime) OVERRIDE;
virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff) OVERRIDE;
+ virtual void sendManagedMemoryStats() OVERRIDE;
// Called by the legacy path where RenderWidget does the scheduling.
void compositeImmediately();
diff --git a/cc/software_renderer.h b/cc/software_renderer.h
index 92961ca..1f1604b 100644
--- a/cc/software_renderer.h
+++ b/cc/software_renderer.h
@@ -36,6 +36,8 @@ public:
virtual void setVisible(bool) OVERRIDE;
+ virtual void sendManagedMemoryStats(size_t bytesVisible, size_t bytesVisibleAndNearby, size_t bytesAllocated) OVERRIDE { }
+
protected:
virtual void bindFramebufferToOutputSurface(DrawingFrame&) OVERRIDE;
virtual bool bindFramebufferToTexture(DrawingFrame&, const ScopedTexture*, const gfx::Rect& framebufferRect) OVERRIDE;
diff --git a/cc/thread_proxy.cc b/cc/thread_proxy.cc
index 94685da..ace26b5 100644
--- a/cc/thread_proxy.cc
+++ b/cc/thread_proxy.cc
@@ -368,6 +368,16 @@ bool ThreadProxy::reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int
return true;
}
+void ThreadProxy::sendManagedMemoryStats()
+{
+ DCHECK(isImplThread());
+ if (m_layerTreeHostImpl.get() && m_layerTreeHostImpl->renderer())
+ m_layerTreeHostImpl->renderer()->sendManagedMemoryStats(
+ m_layerTreeHost->contentsTextureManager()->memoryVisibleBytes(),
+ m_layerTreeHost->contentsTextureManager()->memoryVisibleAndNearbyBytes(),
+ m_layerTreeHost->contentsTextureManager()->memoryUseBytes());
+}
+
void ThreadProxy::setNeedsRedraw()
{
DCHECK(isMainThread());
diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h
index aab144a..58c8fd4 100644
--- a/cc/thread_proxy.h
+++ b/cc/thread_proxy.h
@@ -62,6 +62,7 @@ public:
virtual void setNeedsCommitOnImplThread() OVERRIDE;
virtual void postAnimationEventsToMainThreadOnImplThread(scoped_ptr<AnimationEventsVector>, double wallClockTime) OVERRIDE;
virtual bool reduceContentsTextureMemoryOnImplThread(size_t limitBytes, int priorityCutoff) OVERRIDE;
+ virtual void sendManagedMemoryStats() OVERRIDE;
// SchedulerClient implementation
virtual void scheduledActionBeginFrame() OVERRIDE;