summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authornduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-02 06:00:33 +0000
committernduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-02 06:00:33 +0000
commit1191d9d7cd5a8d6a046c4c187d9992b8d78cb7ed (patch)
tree5cc5cbfb6e32d613817c82275d713e31e2f7198b /cc
parenta3ef4830d5b5fdc52e5d7d0cb33dae8844f0961e (diff)
downloadchromium_src-1191d9d7cd5a8d6a046c4c187d9992b8d78cb7ed.zip
chromium_src-1191d9d7cd5a8d6a046c4c187d9992b8d78cb7ed.tar.gz
chromium_src-1191d9d7cd5a8d6a046c4c187d9992b8d78cb7ed.tar.bz2
[cc] Show GPU memory usage and overage below FPS counter
R=enne BUG=173301 NOTRY=True Review URL: https://chromiumcodereview.appspot.com/12149004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180246 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/heads_up_display_layer_impl.cc52
-rw-r--r--cc/heads_up_display_layer_impl.h2
-rw-r--r--cc/layer_tree_host_impl.cc7
-rw-r--r--cc/layer_tree_host_impl.h3
-rw-r--r--cc/layer_tree_impl.cc4
-rw-r--r--cc/layer_tree_impl.h2
-rw-r--r--cc/memory_history.cc50
-rw-r--r--cc/memory_history.h54
-rw-r--r--cc/ring_buffer.h2
-rw-r--r--cc/tile_manager.cc12
-rw-r--r--cc/tile_manager.h4
12 files changed, 188 insertions, 6 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 0e6953c..3a2da5b 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -126,6 +126,8 @@
'managed_memory_policy.h',
'math_util.cc',
'math_util.h',
+ 'memory_history.cc',
+ 'memory_history.h',
'nine_patch_layer.cc',
'nine_patch_layer.h',
'nine_patch_layer_impl.cc',
diff --git a/cc/heads_up_display_layer_impl.cc b/cc/heads_up_display_layer_impl.cc
index e581a57..3474f8c 100644
--- a/cc/heads_up_display_layer_impl.cc
+++ b/cc/heads_up_display_layer_impl.cc
@@ -10,10 +10,12 @@
#include "cc/font_atlas.h"
#include "cc/frame_rate_counter.h"
#include "cc/layer_tree_impl.h"
+#include "cc/memory_history.h"
#include "cc/paint_time_counter.h"
#include "cc/quad_sink.h"
#include "cc/renderer.h"
#include "cc/texture_draw_quad.h"
+#include "cc/tile_manager.h"
#include "skia/ext/platform_canvas.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -191,6 +193,7 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
const LayerTreeDebugState& debugState = layerTreeImpl()->debug_state();
FrameRateCounter* fpsCounter = layerTreeImpl()->frame_rate_counter();
+ MemoryHistory* memoryHistory = layerTreeImpl()->memory_history();
PaintTimeCounter* paintTimeCounter = layerTreeImpl()->paint_time_counter();
if (debugState.showPlatformLayerTree) {
@@ -221,8 +224,13 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
if (debugState.continuousPainting)
top = drawPaintTimeDisplay(canvas, paintTimeCounter, top);
// Don't show the FPS display when continuous painting is enabled, because it would show misleading numbers.
- else if (debugState.showFPSCounter)
+ else if (debugState.showFPSCounter) {
top = drawFPSDisplay(canvas, fpsCounter, top);
+ }
+ if (debugState.continuousPainting ||
+ debugState.showFPSCounter) {
+ top = drawMemoryDisplay(canvas, memoryHistory, top);
+ }
}
if (debugState.showPlatformLayerTree && m_fontAtlas) {
@@ -302,6 +310,7 @@ int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter*
if (m_fontAtlas.get())
m_fontAtlas->setColor(DebugColors::FPSDisplayTextAndGraphColor());
+
drawTextLeftAligned(canvas, &paint, textBounds, base::StringPrintf("FPS:%5.1f", m_fpsGraph.value));
drawTextRightAligned(canvas, &paint, textBounds, base::StringPrintf("%.0f-%.0f", m_fpsGraph.min, m_fpsGraph.max));
@@ -372,6 +381,47 @@ int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter*
return top + height + 2;
}
+int HeadsUpDisplayLayerImpl::drawMemoryDisplay(SkCanvas* canvas, MemoryHistory* memoryHistory, const int& initial_top)
+{
+ // Move up by 2 to create no gap between us and previous counter.
+ int top = initial_top - 2;
+ const int padding = 4;
+ const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
+
+ const int width = 181;
+ const int height = 2 * fontHeight + 3 * padding;
+
+ const int left = bounds().width() - width - 2;
+ const double megabyte = static_cast<double>(1024*1024);
+
+ SkPaint paint = createPaint();
+ drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(left, top, width, height));
+
+ SkRect textRun1 = SkRect::MakeXYWH(left + padding, top + padding, width, fontHeight);
+ SkRect textRun2 = SkRect::MakeXYWH(left + padding, top + 2*padding + fontHeight, width, fontHeight);
+
+ if (m_fontAtlas.get())
+ m_fontAtlas->setColor(DebugColors::FPSDisplayTextAndGraphColor());
+
+ std::string text;
+ MemoryHistory::Entry curEntry = memoryHistory->GetEntry(
+ memoryHistory->HistorySize() - 1);
+
+ double curMB = curEntry.bytes_total() / megabyte;
+
+ text = base::StringPrintf(
+ "%6.1f MB used",
+ (curEntry.bytes_unreleasable + curEntry.bytes_allocated) / megabyte);
+ drawTextLeftAligned(canvas, &paint, textRun1, text);
+
+ text = base::StringPrintf(
+ "%6.1f MB over budget",
+ (curEntry.bytes_over) / megabyte);
+ drawTextLeftAligned(canvas, &paint, textRun2, text);
+
+ return top + height + 2;
+}
+
int HeadsUpDisplayLayerImpl::drawPaintTimeDisplay(SkCanvas* canvas, PaintTimeCounter* paintTimeCounter, const int& top)
{
const int padding = 4;
diff --git a/cc/heads_up_display_layer_impl.h b/cc/heads_up_display_layer_impl.h
index 6e5a30d..41ef805 100644
--- a/cc/heads_up_display_layer_impl.h
+++ b/cc/heads_up_display_layer_impl.h
@@ -21,6 +21,7 @@ namespace cc {
class DebugRectHistory;
class FontAtlas;
class FrameRateCounter;
+class MemoryHistory;
class PaintTimeCounter;
class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl {
@@ -75,6 +76,7 @@ private:
void drawGraphLines(SkCanvas*, SkPaint*, const SkRect& bounds, const Graph&);
int drawFPSDisplay(SkCanvas*, FrameRateCounter*, const int& top);
+ int drawMemoryDisplay(SkCanvas*, MemoryHistory*, const int& top);
int drawPaintTimeDisplay(SkCanvas*, PaintTimeCounter*, const int& top);
void drawDebugRects(SkCanvas*, DebugRectHistory*);
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc
index f9401fb..b728474 100644
--- a/cc/layer_tree_host_impl.cc
+++ b/cc/layer_tree_host_impl.cc
@@ -25,6 +25,7 @@
#include "cc/layer_tree_host_common.h"
#include "cc/layer_tree_impl.h"
#include "cc/math_util.h"
+#include "cc/memory_history.h"
#include "cc/overdraw_metrics.h"
#include "cc/page_scale_animation.h"
#include "cc/paint_time_counter.h"
@@ -148,6 +149,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre
, m_pinchGestureActive(false)
, m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread()))
, m_paintTimeCounter(PaintTimeCounter::create())
+ , m_memoryHistory(MemoryHistory::create())
, m_debugRectHistory(DebugRectHistory::create())
, m_numImplThreadScrolls(0)
, m_numMainThreadScrolls(0)
@@ -788,6 +790,11 @@ void LayerTreeHostImpl::drawLayers(FrameData& frame)
// RenderWidget.
m_fpsCounter->saveTimeStamp(base::TimeTicks::Now());
+ if (m_tileManager) {
+ m_memoryHistory->SaveEntry(
+ m_tileManager->memory_stats_from_last_assign());
+ }
+
if (m_debugState.showHudRects())
m_debugRectHistory->saveDebugRectsForCurrentFrame(rootLayer(), *frame.renderSurfaceLayerList, frame.occludingScreenSpaceRects, frame.nonOccludingScreenSpaceRects, m_debugState);
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index 12cecc2..53927f0 100644
--- a/cc/layer_tree_host_impl.h
+++ b/cc/layer_tree_host_impl.h
@@ -34,6 +34,7 @@ class LayerTreeHostImplTimeSourceAdapter;
class LayerTreeImpl;
class PageScaleAnimation;
class PaintTimeCounter;
+class MemoryHistory;
class RenderPassDrawQuad;
class ResourceProvider;
class TopControlsManager;
@@ -205,6 +206,7 @@ public:
FrameRateCounter* fpsCounter() const { return m_fpsCounter.get(); }
PaintTimeCounter* paintTimeCounter() const { return m_paintTimeCounter.get(); }
+ MemoryHistory* memoryHistory() const { return m_memoryHistory.get(); }
DebugRectHistory* debugRectHistory() const { return m_debugRectHistory.get(); }
ResourceProvider* resourceProvider() const { return m_resourceProvider.get(); }
TopControlsManager* topControlsManager() const { return m_topControlsManager.get(); }
@@ -343,6 +345,7 @@ private:
scoped_ptr<FrameRateCounter> m_fpsCounter;
scoped_ptr<PaintTimeCounter> m_paintTimeCounter;
+ scoped_ptr<MemoryHistory> m_memoryHistory;
scoped_ptr<DebugRectHistory> m_debugRectHistory;
int64 m_numImplThreadScrolls;
diff --git a/cc/layer_tree_impl.cc b/cc/layer_tree_impl.cc
index 5f7dea8c..38a40f31 100644
--- a/cc/layer_tree_impl.cc
+++ b/cc/layer_tree_impl.cc
@@ -374,6 +374,10 @@ PaintTimeCounter* LayerTreeImpl::paint_time_counter() const {
return layer_tree_host_impl_->paintTimeCounter();
}
+MemoryHistory* LayerTreeImpl::memory_history() const {
+ return layer_tree_host_impl_->memoryHistory();
+}
+
bool LayerTreeImpl::IsActiveTree() const {
return layer_tree_host_impl_->activeTree() == this;
}
diff --git a/cc/layer_tree_impl.h b/cc/layer_tree_impl.h
index e9b14c7..b8971f8 100644
--- a/cc/layer_tree_impl.h
+++ b/cc/layer_tree_impl.h
@@ -28,6 +28,7 @@ class LayerTreeDebugState;
class LayerTreeHostImpl;
class LayerTreeImpl;
class LayerTreeSettings;
+class MemoryHistory;
class OutputSurface;
class PaintTimeCounter;
class Proxy;
@@ -52,6 +53,7 @@ class CC_EXPORT LayerTreeImpl {
TileManager* tile_manager() const;
FrameRateCounter* frame_rate_counter() const;
PaintTimeCounter* paint_time_counter() const;
+ MemoryHistory* memory_history() const;
bool IsActiveTree() const;
bool IsPendingTree() const;
bool IsRecycleTree() const;
diff --git a/cc/memory_history.cc b/cc/memory_history.cc
new file mode 100644
index 0000000..6934f7f
--- /dev/null
+++ b/cc/memory_history.cc
@@ -0,0 +1,50 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/memory_history.h"
+
+namespace cc {
+
+// static
+scoped_ptr<MemoryHistory> MemoryHistory::create() {
+ return make_scoped_ptr(new MemoryHistory());
+}
+
+MemoryHistory::MemoryHistory() {
+}
+
+MemoryHistory::Entry MemoryHistory::GetEntry(const size_t& n) const {
+ DCHECK(n < ring_buffer_.BufferSize());
+
+ if (ring_buffer_.IsFilledIndex(n))
+ return ring_buffer_.ReadBuffer(n);
+
+ return MemoryHistory::Entry();
+}
+
+void MemoryHistory::SaveEntry(const MemoryHistory::Entry& entry) {
+ ring_buffer_.SaveToBuffer(entry);
+}
+
+void MemoryHistory::GetMinAndMax(size_t* min, size_t* max) const {
+ *min = std::numeric_limits<size_t>::max();
+ *max = 0;
+
+ for (size_t i = 0; i < ring_buffer_.BufferSize(); i++) {
+ if (!ring_buffer_.IsFilledIndex(i))
+ continue;
+ const Entry entry = ring_buffer_.ReadBuffer(i);
+ size_t bytes_total = entry.bytes_total();
+
+ if (bytes_total < *min)
+ *min = bytes_total;
+ if (bytes_total > *max)
+ *max = bytes_total;
+ }
+
+ if (*min > *max)
+ *min = *max;
+}
+
+} // namespace cc
diff --git a/cc/memory_history.h b/cc/memory_history.h
new file mode 100644
index 0000000..eca0a79
--- /dev/null
+++ b/cc/memory_history.h
@@ -0,0 +1,54 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_MEMORY_HISTORY_H_
+#define CC_MEMORY_HISTORY_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/time.h"
+#include "cc/ring_buffer.h"
+
+namespace cc {
+
+// Maintains a history of memory for each frame
+class MemoryHistory {
+ public:
+ static scoped_ptr<MemoryHistory> create();
+
+ size_t HistorySize() const { return ring_buffer_.BufferSize(); }
+
+ struct Entry {
+ Entry()
+ : bytes_allocated(0),
+ bytes_over(0) { }
+
+ size_t bytes_allocated;
+ size_t bytes_unreleasable;
+ size_t bytes_over;
+ size_t bytes_total() const {
+ return bytes_allocated +
+ bytes_unreleasable +
+ bytes_over;
+ }
+ };
+
+ // n = 0 returns the oldest and
+ // n = HistorySize() - 1 the most recent paint time.
+ Entry GetEntry(const size_t& n) const;
+
+ void SaveEntry(const Entry& entry);
+ void GetMinAndMax(size_t* min, size_t* max) const;
+
+ private:
+ MemoryHistory();
+
+ RingBuffer<Entry, 80> ring_buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(MemoryHistory);
+};
+
+} // namespace cc
+
+#endif // CC_MEMORY_HISTORY_H_
diff --git a/cc/ring_buffer.h b/cc/ring_buffer.h
index 84283a9..929d74c 100644
--- a/cc/ring_buffer.h
+++ b/cc/ring_buffer.h
@@ -31,7 +31,7 @@ class RingBuffer {
// n = 0 returns the oldest value and
// n = bufferSize() - 1 returns the most recent value.
- T ReadBuffer(size_t n) const {
+ const T& ReadBuffer(size_t n) const {
DCHECK(IsFilledIndex(n));
return buffer_[BufferIndex(n)];
}
diff --git a/cc/tile_manager.cc b/cc/tile_manager.cc
index d2da74c..9935de5 100644
--- a/cc/tile_manager.cc
+++ b/cc/tile_manager.cc
@@ -452,8 +452,9 @@ void TileManager::AssignGpuMemoryToTiles() {
DidTileRasterStateChange(tile, IDLE_STATE);
}
- size_t bytes_left = global_state_.memory_limit_in_bytes - unreleasable_bytes;
+ size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_bytes;
size_t bytes_that_exceeded_memory_budget = 0;
+ size_t bytes_left = bytes_allocatable;
for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
Tile* tile = *it;
size_t tile_bytes = tile->bytes_consumed_if_allocated();
@@ -481,14 +482,17 @@ void TileManager::AssignGpuMemoryToTiles() {
}
}
- if (bytes_that_exceeded_memory_budget)
- ever_exceeded_memory_budget_ = true;
-
+ ever_exceeded_memory_budget_ |= bytes_that_exceeded_memory_budget > 0;
if (ever_exceeded_memory_budget_) {
TRACE_COUNTER_ID2("cc", "over_memory_budget", this,
"budget", global_state_.memory_limit_in_bytes,
"over", bytes_that_exceeded_memory_budget);
}
+ memory_stats_from_last_assign_.bytes_allocated =
+ bytes_allocatable - bytes_left;
+ memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes;
+ memory_stats_from_last_assign_.bytes_over =
+ bytes_that_exceeded_memory_budget;
// Reverse two tiles_that_need_* vectors such that pop_back gets
// the highest priority tile.
diff --git a/cc/tile_manager.h b/cc/tile_manager.h
index d537079..16212ed 100644
--- a/cc/tile_manager.h
+++ b/cc/tile_manager.h
@@ -12,6 +12,7 @@
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
+#include "cc/memory_history.h"
#include "cc/rendering_stats.h"
#include "cc/resource_pool.h"
#include "cc/tile_priority.h"
@@ -112,6 +113,8 @@ class CC_EXPORT TileManager {
void GetRenderingStats(RenderingStats* stats);
bool HasPendingWorkScheduled(WhichTree tree) const;
+ const MemoryHistory::Entry& memory_stats_from_last_assign() const { return memory_stats_from_last_assign_; }
+
protected:
// Methods called by Tile
friend class Tile;
@@ -186,6 +189,7 @@ class CC_EXPORT TileManager {
TileQueue tiles_with_pending_set_pixels_;
size_t bytes_pending_set_pixels_;
bool ever_exceeded_memory_budget_;
+ MemoryHistory::Entry memory_stats_from_last_assign_;
bool record_rendering_stats_;
RenderingStats rendering_stats_;