Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2999)

Unified Diff: cc/heads_up_display_layer_impl.cc

Issue 11820014: cc: PaintTimeCounter display on the HudLayer in continuous painting mode (Closed) Base URL: http://git.chromium.org/chromium/src.git@paint
Patch Set: updated to base::TimeDelta APIs in PaintTimeCounter Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/heads_up_display_layer_impl.h ('k') | cc/layer_tree_debug_state.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/heads_up_display_layer_impl.cc
diff --git a/cc/heads_up_display_layer_impl.cc b/cc/heads_up_display_layer_impl.cc
index 190229667783378229e0a45590080b10a1e87b2a..fe89e66f83e9dfee3a1e9ba527f8ca88953e3750 100644
--- a/cc/heads_up_display_layer_impl.cc
+++ b/cc/heads_up_display_layer_impl.cc
@@ -4,14 +4,13 @@
#include "cc/heads_up_display_layer_impl.h"
-#include <limits>
-
#include "base/stringprintf.h"
#include "cc/debug_colors.h"
#include "cc/debug_rect_history.h"
#include "cc/font_atlas.h"
#include "cc/frame_rate_counter.h"
#include "cc/layer_tree_impl.h"
+#include "cc/paint_time_counter.h"
#include "cc/quad_sink.h"
#include "cc/renderer.h"
#include "cc/texture_draw_quad.h"
@@ -48,11 +47,27 @@ static inline SkPaint createPaint()
return paint;
}
+HeadsUpDisplayLayerImpl::Graph::Graph(double indicatorValue, double startUpperBound)
+ : value(0)
+ , min(0)
+ , max(0)
+ , currentUpperBound(startUpperBound)
+ , defaultUpperBound(startUpperBound)
+ , indicator(indicatorValue)
+{
+}
+
+double HeadsUpDisplayLayerImpl::Graph::updateUpperBound(Graph* graph)
+{
+ double targetUpperBound = std::max(graph->max, graph->defaultUpperBound);
+ graph->currentUpperBound += (targetUpperBound - graph->currentUpperBound) * 0.5;
+ return graph->currentUpperBound;
+}
+
HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* treeImpl, int id)
: LayerImpl(treeImpl, id)
- , m_averageFPS(0)
- , m_minFPS(0)
- , m_maxFPS(0)
+ , m_fpsGraph(60.0, 80.0)
+ , m_paintTimeGraph(16.0, 48.0)
{
}
@@ -158,34 +173,98 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
{
const LayerTreeDebugState& debugState = layerTreeImpl()->debug_state();
+ FrameRateCounter* fpsCounter = layerTreeImpl()->frame_rate_counter();
+ PaintTimeCounter* paintTimeCounter = layerTreeImpl()->paint_time_counter();
+
if (debugState.showPlatformLayerTree) {
SkPaint paint = createPaint();
- paint.setColor(SkColorSetARGB(192, 0, 0, 0));
- canvas->drawRect(SkRect::MakeXYWH(0, 0, bounds().width(), bounds().height()), paint);
+ drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(0, 0, bounds().width(), bounds().height()));
}
- int platformLayerTreeTop = 0;
+ int top = 2;
+
+ if (debugState.continuousPainting || debugState.showFPSCounter) {
+ // Update numbers not every frame so text is readable
+ base::TimeTicks now = base::TimeTicks::Now();
+ if (base::TimeDelta(now - m_timeOfLastGraphUpdate).InSecondsF() > 0.25) {
+ m_fpsGraph.value = fpsCounter->getAverageFPS();
+ fpsCounter->getMinAndMaxFPS(m_fpsGraph.min, m_fpsGraph.max);
+
+ base::TimeDelta latest, min, max;
+ latest = paintTimeCounter->GetPaintTimeOfRecentFrame(paintTimeCounter->HistorySize() - 1);
+ paintTimeCounter->GetMinAndMaxPaintTime(&min, &max);
- if (debugState.showFPSCounter)
- platformLayerTreeTop = drawFPSCounter(canvas, layerTreeImpl()->frame_rate_counter());
+ m_paintTimeGraph.value = latest.InMillisecondsF();
+ m_paintTimeGraph.min = min.InMillisecondsF();
+ m_paintTimeGraph.max = max.InMillisecondsF();
+
+ m_timeOfLastGraphUpdate = now;
+ }
+
+ 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)
+ top = drawFPSDisplay(canvas, fpsCounter, top);
+ }
if (debugState.showPlatformLayerTree && m_fontAtlas) {
std::string layerTree = layerTreeImpl()->layer_tree_as_text();
- m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, platformLayerTreeTop), bounds());
+ m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, top), bounds());
}
if (debugState.showHudRects())
drawDebugRects(canvas, layerTreeImpl()->debug_rect_history());
}
-int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter* fpsCounter)
+void HeadsUpDisplayLayerImpl::drawTextLeftAligned(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds, const std::string& text)
+{
+ if (!m_fontAtlas)
+ return;
+
+ m_fontAtlas->drawText(canvas, *paint, text, gfx::Point(bounds.left(), bounds.top()), gfx::Size(bounds.width(), bounds.height()));
+}
+
+void HeadsUpDisplayLayerImpl::drawTextRightAligned(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds, const std::string& text)
+{
+ if (!m_fontAtlas)
+ return;
+
+ int textWidth = m_fontAtlas->textSize(text).width();
+
+ gfx::Point textPosition(bounds.right() - textWidth, bounds.top());
+ gfx::Size textArea(bounds.width(), bounds.height());
+
+ m_fontAtlas->drawText(canvas, *paint, text, textPosition, textArea);
+}
+
+void HeadsUpDisplayLayerImpl::drawGraphBackground(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds)
+{
+ paint->setColor(SkColorSetARGB(215, 17, 17, 17));
+ canvas->drawRect(bounds, *paint);
+}
+
+void HeadsUpDisplayLayerImpl::drawGraphLines(SkCanvas* canvas, SkPaint* paint, const SkRect& bounds, const Graph& graph)
+{
+ // Draw top and bottom line.
+ paint->setColor(SkColorSetRGB(130, 130, 130));
+ canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top() - 1, *paint);
+ canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bottom(), *paint);
+
+ // Draw indicator line.
+ paint->setColor(SkColorSetRGB(100, 100, 100));
+ const double indicatorTop = bounds.height() * (1 - graph.indicator / graph.currentUpperBound) - 1;
+ canvas->drawLine(bounds.left(), bounds.top() + indicatorTop, bounds.right(), bounds.top() + indicatorTop, *paint);
+}
+
+int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter* fpsCounter, const int& top)
{
const int padding = 4;
const int gap = 6;
const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
- const int graphWidth = fpsCounter->timeStampHistorySize() - 3;
+ const int graphWidth = fpsCounter->timeStampHistorySize() - 2;
const int graphHeight = 40;
const int histogramWidth = 37;
@@ -194,74 +273,29 @@ int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter*
const int height = fontHeight + graphHeight + 4 * padding + 2;
const int left = bounds().width() - width - 2;
- const int top = 2;
SkPaint paint = createPaint();
-
- // Draw background.
- paint.setColor(SkColorSetARGB(215, 17, 17, 17));
- canvas->drawRect(SkRect::MakeXYWH(left, top, width, height), paint);
+ drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(left, top, width, height));
SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWidth + histogramWidth + gap + 2, fontHeight);
SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight);
SkRect histogramBounds = SkRect::MakeXYWH(graphBounds.right() + gap, graphBounds.top(), histogramWidth, graphHeight);
- drawFPSCounterText(canvas, paint, fpsCounter, textBounds);
- drawFPSCounterGraphAndHistogram(canvas, paint, fpsCounter, graphBounds, histogramBounds);
+ 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));
- return top + height;
-}
-
-void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect bounds)
-{
- // Update FPS text - not every frame so text is readable
- base::TimeTicks now = base::TimeTicks::Now();
- if (base::TimeDelta(now - textUpdateTime).InSecondsF() > 0.25) {
- m_averageFPS = fpsCounter->getAverageFPS();
- textUpdateTime = now;
- }
-
- // Draw FPS text.
- if (m_fontAtlas.get()) {
- std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS);
- std::string minMaxText = base::StringPrintf("%.0f-%.0f", std::min( m_minFPS, m_maxFPS), m_maxFPS);
-
- int minMaxWidth = m_fontAtlas->textSize(minMaxText).width();
- gfx::Size textArea(bounds.width(), bounds.height());
-
- paint.setColor(SK_ColorRED);
- m_fontAtlas->drawText(canvas, paint, fpsText, gfx::Point(bounds.left(), bounds.top()), textArea);
- m_fontAtlas->drawText(canvas, paint, minMaxText, gfx::Point(bounds.right() - minMaxWidth, bounds.top()), textArea);
- }
-}
-
-void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect graphBounds, SkRect histogramBounds)
-{
- const double loFPS = 0;
- const double hiFPS = std::max(m_maxFPS + 10.0, 80.0);
-
- // Draw top and bottom line.
- paint.setColor(SkColorSetRGB(130, 130, 130));
- canvas->drawLine(graphBounds.left(), graphBounds.top() - 1, graphBounds.right(), graphBounds.top() - 1, paint);
- canvas->drawLine(graphBounds.left(), graphBounds.bottom(), graphBounds.right(), graphBounds.bottom(), paint);
-
- // Draw 60fps line.
- const double top60 = graphBounds.top() + graphBounds.height() * (1 - ((60 - loFPS) / (hiFPS - loFPS))) - 1;
- paint.setColor(SkColorSetRGB(100, 100, 100));
- canvas->drawLine(graphBounds.left(), top60, graphBounds.right(), top60, paint);
+ const double upperBound = Graph::updateUpperBound(&m_fpsGraph);
+ drawGraphLines(canvas, &paint, graphBounds, m_fpsGraph);
// Collect graph and histogram data.
int x = 0;
SkPath path;
- m_minFPS = std::numeric_limits<double>::max();
- m_maxFPS = 0;
-
const int histogramSize = 20;
double histogram[histogramSize] = {0};
double maxBucketValue = 0;
- for (size_t i = 1; i < fpsCounter->timeStampHistorySize() - 1; ++i) {
+ for (size_t i = 0; i < fpsCounter->timeStampHistorySize() - 1; ++i) {
base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsCounter->timeStampOfRecentFrame(i);
// Skip this particular instantaneous frame rate if it is not likely to have been valid.
@@ -269,13 +303,8 @@ void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas,
double fps = 1.0 / delta.InSecondsF();
- m_minFPS = std::min(fps, m_minFPS);
- m_maxFPS = std::max(fps, m_maxFPS);
-
// Clamp the FPS to the range we want to plot visually.
- double p = (fps - loFPS) / (hiFPS - loFPS);
- if (p < 0)
- p = 0;
+ double p = fps / upperBound;
if (p > 1)
p = 1;
@@ -318,6 +347,53 @@ void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas,
paint.setStrokeWidth(1);
canvas->drawPath(path, paint);
+
+ return top + height + 2;
+}
+
+int HeadsUpDisplayLayerImpl::drawPaintTimeDisplay(SkCanvas* canvas, PaintTimeCounter* paintTimeCounter, const int& top)
+{
+ const int padding = 4;
+ const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
+
+ const int graphWidth = paintTimeCounter->HistorySize() * 2 - 1;
+ const int graphHeight = 40;
+
+ const int width = graphWidth + 2 * padding;
+ const int height = fontHeight + graphHeight + 4 * padding + 2 + fontHeight + padding;
+
+ const int left = bounds().width() - width - 2;
+
+ SkPaint paint = createPaint();
+ drawGraphBackground(canvas, &paint, SkRect::MakeXYWH(left, top, width, height));
+
+ SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWidth, fontHeight);
+ SkRect textBounds2 = SkRect::MakeXYWH(left + padding, textBounds.bottom() + padding, graphWidth, fontHeight);
+ SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds2.bottom() + 2 * padding, graphWidth, graphHeight);
+
+ drawTextLeftAligned(canvas, &paint, textBounds, "Page paint time (ms)");
+ drawTextLeftAligned(canvas, &paint, textBounds2, base::StringPrintf("%5.1f", m_paintTimeGraph.value));
+ drawTextRightAligned(canvas, &paint, textBounds2, base::StringPrintf("%.1f-%.1f", m_paintTimeGraph.min, m_paintTimeGraph.max));
+
+ const double upperBound = Graph::updateUpperBound(&m_paintTimeGraph);
+ drawGraphLines(canvas, &paint, graphBounds, m_paintTimeGraph);
+
+ // Same green as used for paint times in the WebInspector Timeline
+ paint.setColor(SkColorSetRGB(95, 160, 80));
+ for (size_t i = 0; i < paintTimeCounter->HistorySize(); ++i) {
+ double pt = paintTimeCounter->GetPaintTimeOfRecentFrame(i).InMillisecondsF();
+
+ if (pt == 0.0)
+ continue;
+
+ double p = pt / upperBound;
+ if (p > 1)
+ p = 1;
+
+ canvas->drawRect(SkRect::MakeXYWH(graphBounds.left() + i * 2, graphBounds.bottom() - p * graphBounds.height(), 1, p * graphBounds.height()), paint);
+ }
+
+ return top + height + 2;
}
void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory* debugRectHistory)
« no previous file with comments | « cc/heads_up_display_layer_impl.h ('k') | cc/layer_tree_debug_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698