Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/heads_up_display_layer_impl.h" | 5 #include "cc/heads_up_display_layer_impl.h" |
| 6 | 6 |
| 7 #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...
| |
| 8 | |
| 7 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 8 #include "cc/debug_rect_history.h" | 10 #include "cc/debug_rect_history.h" |
| 9 #include "cc/font_atlas.h" | 11 #include "cc/font_atlas.h" |
| 10 #include "cc/frame_rate_counter.h" | 12 #include "cc/frame_rate_counter.h" |
| 11 #include "cc/layer_tree_host_impl.h" | 13 #include "cc/layer_tree_host_impl.h" |
| 12 #include "cc/quad_sink.h" | 14 #include "cc/quad_sink.h" |
| 13 #include "cc/texture_draw_quad.h" | 15 #include "cc/texture_draw_quad.h" |
| 14 #include "skia/ext/platform_canvas.h" | 16 #include "skia/ext/platform_canvas.h" |
| 15 #include "skia/ext/platform_canvas.h" | 17 #include "skia/ext/platform_canvas.h" |
| 16 #include "third_party/khronos/GLES2/gl2.h" | 18 #include "third_party/khronos/GLES2/gl2.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 30 SkColorMatrix swizzleMatrix; | 32 SkColorMatrix swizzleMatrix; |
| 31 for (int i = 0; i < 20; ++i) | 33 for (int i = 0; i < 20; ++i) |
| 32 swizzleMatrix.fMat[i] = 0; | 34 swizzleMatrix.fMat[i] = 0; |
| 33 swizzleMatrix.fMat[0 + 5 * 2] = 1; | 35 swizzleMatrix.fMat[0 + 5 * 2] = 1; |
| 34 swizzleMatrix.fMat[1 + 5 * 1] = 1; | 36 swizzleMatrix.fMat[1 + 5 * 1] = 1; |
| 35 swizzleMatrix.fMat[2 + 5 * 0] = 1; | 37 swizzleMatrix.fMat[2 + 5 * 0] = 1; |
| 36 swizzleMatrix.fMat[3 + 5 * 3] = 1; | 38 swizzleMatrix.fMat[3 + 5 * 3] = 1; |
| 37 | 39 |
| 38 SkPaint paint; | 40 SkPaint paint; |
| 39 paint.setColorFilter(new SkColorMatrixFilter(swizzleMatrix))->unref(); | 41 paint.setColorFilter(new SkColorMatrixFilter(swizzleMatrix))->unref(); |
| 42 | |
| 40 return paint; | 43 return paint; |
| 41 } | 44 } |
| 42 | 45 |
| 43 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(int id) | 46 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(int id) |
| 44 : LayerImpl(id) | 47 : LayerImpl(id) |
| 45 , m_averageFPS(0) | 48 , m_averageFPS(0) |
| 46 , m_stdDeviation(0) | 49 , m_minFPS(0) |
| 50 , m_maxFPS(0) | |
| 47 , m_showFPSCounter(false) | 51 , m_showFPSCounter(false) |
| 48 { | 52 { |
| 49 } | 53 } |
| 50 | 54 |
| 51 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() | 55 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() |
| 52 { | 56 { |
| 53 } | 57 } |
| 54 | 58 |
| 55 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas) | 59 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas) |
| 56 { | 60 { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 std::string layerTree = layerTreeHostImpl()->layerTreeAsText(); | 163 std::string layerTree = layerTreeHostImpl()->layerTreeAsText(); |
| 160 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, pl atformLayerTreeTop), bounds()); | 164 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, pl atformLayerTreeTop), bounds()); |
| 161 } | 165 } |
| 162 | 166 |
| 163 if (settings.showDebugRects()) | 167 if (settings.showDebugRects()) |
| 164 drawDebugRects(canvas, layerTreeHostImpl()->debugRectHistory()); | 168 drawDebugRects(canvas, layerTreeHostImpl()->debugRectHistory()); |
| 165 } | 169 } |
| 166 | 170 |
| 167 int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter* fpsCounter) | 171 int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter* fpsCounter) |
| 168 { | 172 { |
| 169 const int left = 2; | |
| 170 const int top = 2; | |
| 171 | |
| 172 const int padding = 4; | 173 const int padding = 4; |
| 174 const int gap = 6; | |
| 173 | 175 |
| 174 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0; | 176 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0; |
| 175 const int graphWidth = fpsCounter->timeStampHistorySize() - 3; | 177 |
| 178 const int graphWidth = 120; | |
| 176 const int graphHeight = 40; | 179 const int graphHeight = 40; |
| 177 | 180 |
| 178 const int width = graphWidth + 2 * padding; | 181 const int histogramWidth = 37; |
| 182 | |
| 183 const int width = graphWidth + histogramWidth + 4 * padding; | |
| 179 const int height = fontHeight + graphHeight + 4 * padding + 2; | 184 const int height = fontHeight + graphHeight + 4 * padding + 2; |
| 180 | 185 |
| 186 const int left = bounds().width() - width - 2; | |
| 187 const int top = 2; | |
| 188 | |
| 181 SkPaint paint = createPaint(); | 189 SkPaint paint = createPaint(); |
| 182 | 190 |
| 183 // Draw background. | 191 // Draw background. |
| 184 paint.setColor(SkColorSetARGB(215, 17, 17, 17)); | 192 paint.setColor(SkColorSetARGB(215, 17, 17, 17)); |
| 185 canvas->drawRect(SkRect::MakeXYWH(left, top, width, height), paint); | 193 canvas->drawRect(SkRect::MakeXYWH(left, top, width, height), paint); |
| 186 | 194 |
| 187 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid th, fontHeight); | 195 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid th + histogramWidth + gap + 2, fontHeight); |
| 188 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight); | 196 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight); |
| 197 SkRect histogramBounds = SkRect::MakeXYWH(graphBounds.right() + gap, graphBo unds.top(), histogramWidth, graphHeight); | |
| 189 | 198 |
| 190 drawFPSCounterText(canvas, paint, fpsCounter, textBounds); | 199 drawFPSCounterText(canvas, paint, fpsCounter, textBounds); |
| 191 drawFPSCounterGraph(canvas, paint, fpsCounter, graphBounds); | 200 drawFPSCounterGraphAndHistogram(canvas, paint, fpsCounter, graphBounds, hist ogramBounds); |
| 192 | 201 |
| 193 return top + height; | 202 return top + height; |
| 194 } | 203 } |
| 195 | 204 |
| 196 void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& pain t, FrameRateCounter* fpsCounter, SkRect bounds) | 205 void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& pain t, FrameRateCounter* fpsCounter, SkRect bounds) |
| 197 { | 206 { |
| 198 // Update FPS text - not every frame so text is readable | 207 // Update FPS text - not every frame so text is readable |
| 199 if (base::TimeDelta(fpsCounter->timeStampOfRecentFrame(0) - textUpdateTime). InSecondsF() > 0.25) { | 208 if (base::TimeDelta(fpsCounter->timeStampOfRecentFrame(0) - textUpdateTime). InSecondsF() > 0.25) { |
| 200 fpsCounter->getAverageFPSAndStandardDeviation(m_averageFPS, m_stdDeviati on); | 209 m_averageFPS = fpsCounter->getAverageFPS(); |
| 201 textUpdateTime = fpsCounter->timeStampOfRecentFrame(0); | 210 textUpdateTime = fpsCounter->timeStampOfRecentFrame(0); |
| 202 } | 211 } |
| 203 | 212 |
| 204 // Draw FPS text. | 213 // Draw FPS text. |
| 205 if (m_fontAtlas.get()) { | 214 if (m_fontAtlas.get()) { |
| 206 std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS); | 215 std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS); |
| 207 std::string deviationText = base::StringPrintf("+/-%4.1f", m_stdDeviatio n); | 216 std::string minMaxText = base::StringPrintf("%.0f-%.0f", std::min( m_min FPS, m_maxFPS), m_maxFPS); |
|
egraether
2012/11/12 23:44:06
Shows the min/max fps instead of standard deviatio
| |
| 208 | 217 |
| 209 int deviationWidth = m_fontAtlas->textSize(deviationText).width(); | 218 int minMaxWidth = m_fontAtlas->textSize(minMaxText).width(); |
| 210 gfx::Size textArea(bounds.width(), bounds.height()); | 219 gfx::Size textArea(bounds.width(), bounds.height()); |
| 211 | 220 |
| 212 paint.setColor(SK_ColorRED); | 221 paint.setColor(SK_ColorRED); |
| 213 m_fontAtlas->drawText(canvas, paint, fpsText, gfx::Point(bounds.left(), bounds.top()), textArea); | 222 m_fontAtlas->drawText(canvas, paint, fpsText, gfx::Point(bounds.left(), bounds.top()), textArea); |
| 214 m_fontAtlas->drawText(canvas, paint, deviationText, gfx::Point(bounds.ri ght() - deviationWidth, bounds.top()), textArea); | 223 m_fontAtlas->drawText(canvas, paint, minMaxText, gfx::Point(bounds.right () - minMaxWidth, bounds.top()), textArea); |
| 215 } | 224 } |
| 216 } | 225 } |
| 217 | 226 |
| 218 void HeadsUpDisplayLayerImpl::drawFPSCounterGraph(SkCanvas* canvas, SkPaint& pai nt, FrameRateCounter* fpsCounter, SkRect bounds) | 227 void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect graphBounds, SkRect histogr amBounds) |
| 219 { | 228 { |
| 220 const double loFPS = 0; | 229 const double loFPS = 0; |
| 221 const double hiFPS = 80; | 230 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
| |
| 222 | |
| 223 paint.setStyle(SkPaint::kStroke_Style); | |
| 224 paint.setStrokeWidth(1); | |
| 225 | 231 |
| 226 // Draw top and bottom line. | 232 // Draw top and bottom line. |
| 227 paint.setColor(SkColorSetRGB(150, 150, 150)); | 233 paint.setColor(SkColorSetRGB(130, 130, 130)); |
| 228 canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top () - 1, paint); | 234 canvas->drawLine(graphBounds.left(), graphBounds.top() - 1, graphBounds.righ t(), graphBounds.top() - 1, paint); |
| 229 canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bott om(), paint); | 235 canvas->drawLine(graphBounds.left(), graphBounds.bottom(), graphBounds.right (), graphBounds.bottom(), paint); |
| 230 | 236 |
| 231 // Draw 60fps line. | 237 // Draw 60fps line. |
| 238 const double top60 = graphBounds.top() + graphBounds.height() * (1 - ((60 - loFPS) / (hiFPS - loFPS))) - 1; | |
| 232 paint.setColor(SkColorSetRGB(100, 100, 100)); | 239 paint.setColor(SkColorSetRGB(100, 100, 100)); |
| 233 canvas->drawLine(bounds.left(), bounds.top() + bounds.height() / 4, bounds.r ight(), bounds.top() + bounds.height() / 4, paint); | 240 canvas->drawLine(graphBounds.left(), top60, graphBounds.right(), top60, pain t); |
| 234 | 241 |
| 235 // Draw FPS graph. | 242 // Collect graph and histogram data. |
| 236 int x = 0; | 243 double x = 0; |
| 244 const double timeScale = 60; // in pixels/second | |
| 237 SkPath path; | 245 SkPath path; |
| 238 | 246 |
| 239 for (int i = 1; i < fpsCounter->timeStampHistorySize() - 1; ++i) { | 247 m_minFPS = DBL_MAX; |
| 248 m_maxFPS = 0; | |
| 249 | |
| 250 const int histogramSize = 20; | |
| 251 double histogram[histogramSize] = {0}; | |
| 252 double maxBucketValue = 0; | |
| 253 | |
| 254 for (int i = fpsCounter->timeStampHistorySize() - 2; i > 0 && x <= graphBoun ds.width(); --i) { | |
| 240 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsC ounter->timeStampOfRecentFrame(i); | 255 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsC ounter->timeStampOfRecentFrame(i); |
| 241 | 256 |
| 242 // Skip plotting this particular instantaneous frame rate if it is not l ikely to have been valid. | 257 // Skip this particular instantaneous frame rate if it is not likely to have been valid. |
| 243 if (!fpsCounter->isBadFrameInterval(delta)) { | 258 if (!fpsCounter->isBadFrameInterval(delta)) { |
| 259 | |
| 244 double fps = 1.0 / delta.InSecondsF(); | 260 double fps = 1.0 / delta.InSecondsF(); |
| 245 | 261 |
| 262 m_minFPS = std::min(fps, m_minFPS); | |
| 263 m_maxFPS = std::max(fps, m_maxFPS); | |
| 264 | |
| 246 // Clamp the FPS to the range we want to plot visually. | 265 // Clamp the FPS to the range we want to plot visually. |
| 247 double p = 1 - ((fps - loFPS) / (hiFPS - loFPS)); | 266 double p = (fps - loFPS) / (hiFPS - loFPS); |
| 248 if (p < 0) | 267 if (p < 0) |
| 249 p = 0; | 268 p = 0; |
| 250 if (p > 1) | 269 if (p > 1) |
| 251 p = 1; | 270 p = 1; |
| 252 | 271 |
| 253 // Plot this data point. | 272 // Plot this data point. |
| 254 SkPoint cur = SkPoint::Make(bounds.left() + x, bounds.top() + p * bo unds.height()); | 273 SkPoint cur = SkPoint::Make(graphBounds.right() - x, graphBounds.bot tom() - p * graphBounds.height()); |
| 255 if (path.isEmpty()) | 274 if (path.isEmpty()) |
| 256 path.moveTo(cur); | 275 path.moveTo(cur); |
| 257 else | 276 else |
| 258 path.lineTo(cur); | 277 path.lineTo(cur); |
| 278 | |
| 279 // Use the fps value to find the right bucket in the histogram. | |
| 280 int bucketIndex = floor(p * (histogramSize - 1)); | |
| 281 | |
| 282 // Add the delta time to take the time spent at that fps rate into a ccount. | |
| 283 histogram[bucketIndex] += delta.InSecondsF(); | |
| 284 maxBucketValue = std::max(histogram[bucketIndex], maxBucketValue); | |
| 259 } | 285 } |
| 260 | 286 |
| 261 x += 1; | 287 x += delta.InSecondsF() * timeScale; |
|
egraether
2012/11/12 23:44:06
Move x based on time spent between frames.
| |
| 262 } | 288 } |
| 263 | 289 |
| 290 // Draw FPS histogram. | |
| 291 paint.setColor(SkColorSetRGB(130, 130, 130)); | |
| 292 canvas->drawLine(histogramBounds.left() - 1, histogramBounds.top() - 1, hist ogramBounds.left() - 1, histogramBounds.bottom() + 1, paint); | |
| 293 canvas->drawLine(histogramBounds.right() + 1, histogramBounds.top() - 1, his togramBounds.right() + 1, histogramBounds.bottom() + 1, paint); | |
| 294 | |
| 295 paint.setColor(SK_ColorRED); | |
| 296 const double barHeight = histogramBounds.height() / histogramSize; | |
| 297 | |
| 298 for (int i = histogramSize - 1; i >= 0; --i) { | |
| 299 if (histogram[i] > 0) { | |
| 300 double barWidth = histogram[i] / maxBucketValue * histogramBounds.wi dth(); | |
|
egraether
2012/11/12 23:44:06
Scale the width of the bar to the maximum in the h
| |
| 301 canvas->drawRect(SkRect::MakeXYWH(histogramBounds.left(), histogramB ounds.bottom() - (i + 1) * barHeight, barWidth, 1), paint); | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 // Draw FPS graph. | |
| 264 paint.setAntiAlias(true); | 306 paint.setAntiAlias(true); |
| 265 paint.setColor(SK_ColorRED); | 307 paint.setStyle(SkPaint::kStroke_Style); |
| 308 paint.setStrokeWidth(1); | |
| 309 | |
| 266 canvas->drawPath(path, paint); | 310 canvas->drawPath(path, paint); |
| 267 } | 311 } |
| 268 | 312 |
| 269 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory* debugRectHistory) | 313 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory* debugRectHistory) |
| 270 { | 314 { |
| 271 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects(); | 315 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects(); |
| 272 | 316 |
| 273 for (size_t i = 0; i < debugRects.size(); ++i) { | 317 for (size_t i = 0; i < debugRects.size(); ++i) { |
| 274 SkColor strokeColor = 0; | 318 SkColor strokeColor = 0; |
| 275 SkColor fillColor = 0; | 319 SkColor fillColor = 0; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 canvas->drawRect(skRect, paint); | 363 canvas->drawRect(skRect, paint); |
| 320 } | 364 } |
| 321 } | 365 } |
| 322 | 366 |
| 323 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const | 367 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const |
| 324 { | 368 { |
| 325 return "HeadsUpDisplayLayer"; | 369 return "HeadsUpDisplayLayer"; |
| 326 } | 370 } |
| 327 | 371 |
| 328 } // namespace cc | 372 } // namespace cc |
| OLD | NEW |