diff options
author | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-02 06:00:33 +0000 |
---|---|---|
committer | nduca@chromium.org <nduca@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-02 06:00:33 +0000 |
commit | 1191d9d7cd5a8d6a046c4c187d9992b8d78cb7ed (patch) | |
tree | 5cc5cbfb6e32d613817c82275d713e31e2f7198b /cc | |
parent | a3ef4830d5b5fdc52e5d7d0cb33dae8844f0961e (diff) | |
download | chromium_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.gyp | 2 | ||||
-rw-r--r-- | cc/heads_up_display_layer_impl.cc | 52 | ||||
-rw-r--r-- | cc/heads_up_display_layer_impl.h | 2 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 7 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 3 | ||||
-rw-r--r-- | cc/layer_tree_impl.cc | 4 | ||||
-rw-r--r-- | cc/layer_tree_impl.h | 2 | ||||
-rw-r--r-- | cc/memory_history.cc | 50 | ||||
-rw-r--r-- | cc/memory_history.h | 54 | ||||
-rw-r--r-- | cc/ring_buffer.h | 2 | ||||
-rw-r--r-- | cc/tile_manager.cc | 12 | ||||
-rw-r--r-- | cc/tile_manager.h | 4 |
12 files changed, 188 insertions, 6 deletions
@@ -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_; |