Chromium Code Reviews| 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 17064c90bb2c13c2f5598ab1fdb9a955f46f47a1..6cef56cb2615e8d7c737f63749513982e0f179bc 100644 |
| --- a/cc/heads_up_display_layer_impl.cc |
| +++ b/cc/heads_up_display_layer_impl.cc |
| @@ -4,6 +4,8 @@ |
| #include "cc/heads_up_display_layer_impl.h" |
| +#include <float.h> |
|
egraether
2012/11/12 23:44:06
Necessary to set member m_minFPS to DBL_MAX. Worke
nduca
2012/11/13 00:51:46
I think there is a numeric limts thing for this...
|
| + |
| #include "base/stringprintf.h" |
| #include "cc/debug_rect_history.h" |
| #include "cc/font_atlas.h" |
| @@ -37,13 +39,15 @@ static inline SkPaint createPaint() |
| SkPaint paint; |
| paint.setColorFilter(new SkColorMatrixFilter(swizzleMatrix))->unref(); |
| + |
| return paint; |
| } |
| HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(int id) |
| : LayerImpl(id) |
| , m_averageFPS(0) |
| - , m_stdDeviation(0) |
| + , m_minFPS(0) |
| + , m_maxFPS(0) |
| , m_showFPSCounter(false) |
| { |
| } |
| @@ -166,29 +170,34 @@ void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas) |
| int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter* fpsCounter) |
| { |
| - const int left = 2; |
| - const int top = 2; |
| - |
| 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 = 120; |
| const int graphHeight = 40; |
| - const int width = graphWidth + 2 * padding; |
| + const int histogramWidth = 37; |
| + |
| + const int width = graphWidth + histogramWidth + 4 * padding; |
| 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); |
| - SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWidth, fontHeight); |
| + 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); |
| - drawFPSCounterGraph(canvas, paint, fpsCounter, graphBounds); |
| + drawFPSCounterGraphAndHistogram(canvas, paint, fpsCounter, graphBounds, histogramBounds); |
| return top + height; |
| } |
| @@ -197,72 +206,107 @@ void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& pain |
| { |
| // Update FPS text - not every frame so text is readable |
| if (base::TimeDelta(fpsCounter->timeStampOfRecentFrame(0) - textUpdateTime).InSecondsF() > 0.25) { |
| - fpsCounter->getAverageFPSAndStandardDeviation(m_averageFPS, m_stdDeviation); |
| + m_averageFPS = fpsCounter->getAverageFPS(); |
| textUpdateTime = fpsCounter->timeStampOfRecentFrame(0); |
| } |
| // Draw FPS text. |
| if (m_fontAtlas.get()) { |
| std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS); |
| - std::string deviationText = base::StringPrintf("+/-%4.1f", m_stdDeviation); |
| + std::string minMaxText = base::StringPrintf("%.0f-%.0f", std::min( m_minFPS, m_maxFPS), m_maxFPS); |
|
egraether
2012/11/12 23:44:06
Shows the min/max fps instead of standard deviatio
|
| - int deviationWidth = m_fontAtlas->textSize(deviationText).width(); |
| + 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, deviationText, gfx::Point(bounds.right() - deviationWidth, bounds.top()), textArea); |
| + m_fontAtlas->drawText(canvas, paint, minMaxText, gfx::Point(bounds.right() - minMaxWidth, bounds.top()), textArea); |
| } |
| } |
| -void HeadsUpDisplayLayerImpl::drawFPSCounterGraph(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect bounds) |
| +void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect graphBounds, SkRect histogramBounds) |
| { |
| const double loFPS = 0; |
| - const double hiFPS = 80; |
| - |
| - paint.setStyle(SkPaint::kStroke_Style); |
| - paint.setStrokeWidth(1); |
| + const double hiFPS = std::max(m_maxFPS + 10.0, 80.0); |
|
egraether
2012/11/12 23:44:06
Setting the upper fps bound of graph and histogram
|
| // Draw top and bottom line. |
| - paint.setColor(SkColorSetRGB(150, 150, 150)); |
| - canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top() - 1, paint); |
| - canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bottom(), paint); |
| + 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(bounds.left(), bounds.top() + bounds.height() / 4, bounds.right(), bounds.top() + bounds.height() / 4, paint); |
| + canvas->drawLine(graphBounds.left(), top60, graphBounds.right(), top60, paint); |
| - // Draw FPS graph. |
| - int x = 0; |
| + // Collect graph and histogram data. |
| + double x = 0; |
| + const double timeScale = 60; // in pixels/second |
| SkPath path; |
| - for (int i = 1; i < fpsCounter->timeStampHistorySize() - 1; ++i) { |
| + m_minFPS = DBL_MAX; |
| + m_maxFPS = 0; |
| + |
| + const int histogramSize = 20; |
| + double histogram[histogramSize] = {0}; |
| + double maxBucketValue = 0; |
| + |
| + for (int i = fpsCounter->timeStampHistorySize() - 2; i > 0 && x <= graphBounds.width(); --i) { |
| base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsCounter->timeStampOfRecentFrame(i); |
| - // Skip plotting this particular instantaneous frame rate if it is not likely to have been valid. |
| + // Skip this particular instantaneous frame rate if it is not likely to have been valid. |
| if (!fpsCounter->isBadFrameInterval(delta)) { |
| + |
| 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 = 1 - ((fps - loFPS) / (hiFPS - loFPS)); |
| + double p = (fps - loFPS) / (hiFPS - loFPS); |
| if (p < 0) |
| p = 0; |
| if (p > 1) |
| p = 1; |
| // Plot this data point. |
| - SkPoint cur = SkPoint::Make(bounds.left() + x, bounds.top() + p * bounds.height()); |
| + SkPoint cur = SkPoint::Make(graphBounds.right() - x, graphBounds.bottom() - p * graphBounds.height()); |
| if (path.isEmpty()) |
| path.moveTo(cur); |
| else |
| path.lineTo(cur); |
| + |
| + // Use the fps value to find the right bucket in the histogram. |
| + int bucketIndex = floor(p * (histogramSize - 1)); |
| + |
| + // Add the delta time to take the time spent at that fps rate into account. |
| + histogram[bucketIndex] += delta.InSecondsF(); |
| + maxBucketValue = std::max(histogram[bucketIndex], maxBucketValue); |
| } |
| - x += 1; |
| + x += delta.InSecondsF() * timeScale; |
|
egraether
2012/11/12 23:44:06
Move x based on time spent between frames.
|
| } |
| - paint.setAntiAlias(true); |
| + // Draw FPS histogram. |
| + paint.setColor(SkColorSetRGB(130, 130, 130)); |
| + canvas->drawLine(histogramBounds.left() - 1, histogramBounds.top() - 1, histogramBounds.left() - 1, histogramBounds.bottom() + 1, paint); |
| + canvas->drawLine(histogramBounds.right() + 1, histogramBounds.top() - 1, histogramBounds.right() + 1, histogramBounds.bottom() + 1, paint); |
| + |
| paint.setColor(SK_ColorRED); |
| + const double barHeight = histogramBounds.height() / histogramSize; |
| + |
| + for (int i = histogramSize - 1; i >= 0; --i) { |
| + if (histogram[i] > 0) { |
| + double barWidth = histogram[i] / maxBucketValue * histogramBounds.width(); |
|
egraether
2012/11/12 23:44:06
Scale the width of the bar to the maximum in the h
|
| + canvas->drawRect(SkRect::MakeXYWH(histogramBounds.left(), histogramBounds.bottom() - (i + 1) * barHeight, barWidth, 1), paint); |
| + } |
| + } |
| + |
| + // Draw FPS graph. |
| + paint.setAntiAlias(true); |
| + paint.setStyle(SkPaint::kStroke_Style); |
| + paint.setStrokeWidth(1); |
| + |
| canvas->drawPath(path, paint); |
| } |