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

Side by Side 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 size_t 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 unified diff | Download patch
OLDNEW
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 <limits>
8
9 #include "base/stringprintf.h" 7 #include "base/stringprintf.h"
10 #include "cc/debug_colors.h" 8 #include "cc/debug_colors.h"
11 #include "cc/debug_rect_history.h" 9 #include "cc/debug_rect_history.h"
12 #include "cc/font_atlas.h" 10 #include "cc/font_atlas.h"
13 #include "cc/frame_rate_counter.h" 11 #include "cc/frame_rate_counter.h"
14 #include "cc/layer_tree_impl.h" 12 #include "cc/layer_tree_impl.h"
13 #include "cc/paint_time_counter.h"
15 #include "cc/quad_sink.h" 14 #include "cc/quad_sink.h"
16 #include "cc/renderer.h" 15 #include "cc/renderer.h"
17 #include "cc/texture_draw_quad.h" 16 #include "cc/texture_draw_quad.h"
18 #include "skia/ext/platform_canvas.h" 17 #include "skia/ext/platform_canvas.h"
19 #include "skia/ext/platform_canvas.h" 18 #include "skia/ext/platform_canvas.h"
20 #include "third_party/khronos/GLES2/gl2.h" 19 #include "third_party/khronos/GLES2/gl2.h"
21 #include "third_party/khronos/GLES2/gl2ext.h" 20 #include "third_party/khronos/GLES2/gl2ext.h"
22 #include "third_party/skia/include/core/SkBitmap.h" 21 #include "third_party/skia/include/core/SkBitmap.h"
23 #include "third_party/skia/include/core/SkPaint.h" 22 #include "third_party/skia/include/core/SkPaint.h"
24 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" 23 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
(...skipping 15 matching lines...) Expand all
40 swizzleMatrix.fMat[3 + 5 * 3] = 1; 39 swizzleMatrix.fMat[3 + 5 * 3] = 1;
41 40
42 SkPaint paint; 41 SkPaint paint;
43 skia::RefPtr<SkColorMatrixFilter> filter = 42 skia::RefPtr<SkColorMatrixFilter> filter =
44 skia::AdoptRef(new SkColorMatrixFilter(swizzleMatrix)); 43 skia::AdoptRef(new SkColorMatrixFilter(swizzleMatrix));
45 paint.setColorFilter(filter.get()); 44 paint.setColorFilter(filter.get());
46 45
47 return paint; 46 return paint;
48 } 47 }
49 48
49 HeadsUpDisplayLayerImpl::Graph::Graph(double indicatorValue, double startHigh)
50 : current(0)
51 , min(0)
52 , max(0)
53 , high(startHigh)
54 , defaultHigh(startHigh)
55 , indicator(indicatorValue)
56 {
57 }
58
59 double HeadsUpDisplayLayerImpl::Graph::updateHigh(Graph& graph)
60 {
61 double targetHigh = std::max(graph.max, graph.defaultHigh);
62 graph.high += (targetHigh - graph.high) * 0.5;
63 return graph.high;
64 }
65
50 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* treeImpl, int id ) 66 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(LayerTreeImpl* treeImpl, int id )
51 : LayerImpl(treeImpl, id) 67 : LayerImpl(treeImpl, id)
52 , m_averageFPS(0) 68 , m_fpsGraph(60.0, 80.0)
53 , m_minFPS(0) 69 , m_paintTimeGraph(16.0, 48.0)
54 , m_maxFPS(0)
55 { 70 {
56 } 71 }
57 72
58 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() 73 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl()
59 { 74 {
60 } 75 }
61 76
62 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas) 77 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas)
63 { 78 {
64 m_fontAtlas = fontAtlas.Pass(); 79 m_fontAtlas = fontAtlas.Pass();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 165
151 bool HeadsUpDisplayLayerImpl::layerIsAlwaysDamaged() const 166 bool HeadsUpDisplayLayerImpl::layerIsAlwaysDamaged() const
152 { 167 {
153 return true; 168 return true;
154 } 169 }
155 170
156 void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas) 171 void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas)
157 { 172 {
158 const LayerTreeDebugState& debugState = layerTreeImpl()->debug_state(); 173 const LayerTreeDebugState& debugState = layerTreeImpl()->debug_state();
159 174
175 FrameRateCounter* fpsCounter = layerTreeImpl()->frame_rate_counter();
176 PaintTimeCounter* paintTimeCounter = layerTreeImpl()->paint_time_counter();
177
160 if (debugState.showPlatformLayerTree) { 178 if (debugState.showPlatformLayerTree) {
161 SkPaint paint = createPaint(); 179 SkPaint paint = createPaint();
162 paint.setColor(SkColorSetARGB(192, 0, 0, 0)); 180 drawGraphBackground(canvas, paint, SkRect::MakeXYWH(0, 0, bounds().width (), bounds().height()));
163 canvas->drawRect(SkRect::MakeXYWH(0, 0, bounds().width(), bounds().heigh t()), paint);
164 } 181 }
165 182
166 int platformLayerTreeTop = 0; 183 int top = 0;
167 184
168 if (debugState.showFPSCounter) 185 if (debugState.continuousPainting || debugState.showFPSCounter) {
169 platformLayerTreeTop = drawFPSCounter(canvas, layerTreeImpl()->frame_rat e_counter()); 186 // Update numbers not every frame so text is readable
187 base::TimeTicks now = base::TimeTicks::Now();
188 if (base::TimeDelta(now - m_lastGraphNumbersUpdate).InSecondsF() > 0.25) {
189 m_fpsGraph.current = fpsCounter->getAverageFPS();
190 fpsCounter->getMinAndMaxFPS(m_fpsGraph.min, m_fpsGraph.max);
191
192 m_paintTimeGraph.current = paintTimeCounter->GetPaintTimeOfRecentFra me(paintTimeCounter->HistorySize() - 1);
193 paintTimeCounter->GetMinAndMaxPaintTime(&m_paintTimeGraph.min, &m_pa intTimeGraph.max);
194
195 m_lastGraphNumbersUpdate = now;
196 }
197
198 if (debugState.continuousPainting)
199 top = drawPaintTimeDisplay(canvas, paintTimeCounter, top);
200 // Don't show the FPS display when continuous painting is enabled, becau se it would show misleading numbers.
201 else if (debugState.showFPSCounter)
202 top = drawFPSDisplay(canvas, fpsCounter, top);
203 }
170 204
171 if (debugState.showPlatformLayerTree && m_fontAtlas) { 205 if (debugState.showPlatformLayerTree && m_fontAtlas) {
172 std::string layerTree = layerTreeImpl()->layer_tree_as_text(); 206 std::string layerTree = layerTreeImpl()->layer_tree_as_text();
173 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, pl atformLayerTreeTop), bounds()); 207 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, to p), bounds());
174 } 208 }
175 209
176 if (debugState.showHudRects()) 210 if (debugState.showHudRects())
177 drawDebugRects(canvas, layerTreeImpl()->debug_rect_history()); 211 drawDebugRects(canvas, layerTreeImpl()->debug_rect_history());
178 } 212 }
179 213
180 int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter* fpsCounter) 214 void HeadsUpDisplayLayerImpl::drawTextLeftAligned(SkCanvas* canvas, SkPaint& pai nt, SkRect bounds, std::string text)
215 {
216 if (!m_fontAtlas)
217 return;
218
219 m_fontAtlas->drawText(canvas, paint, text, gfx::Point(bounds.left(), bounds. top()), gfx::Size(bounds.width(), bounds.height()));
220 }
221
222 void HeadsUpDisplayLayerImpl::drawTextRightAligned(SkCanvas* canvas, SkPaint& pa int, SkRect bounds, std::string text)
223 {
224 if (!m_fontAtlas)
225 return;
226
227 int textWidth = m_fontAtlas->textSize(text).width();
228
229 gfx::Point textPosition(bounds.right() - textWidth, bounds.top());
230 gfx::Size textArea(bounds.width(), bounds.height());
231
232 m_fontAtlas->drawText(canvas, paint, text, textPosition, textArea);
233 }
234
235 void HeadsUpDisplayLayerImpl::drawGraphBackground(SkCanvas* canvas, SkPaint& pai nt, SkRect bounds)
236 {
237 paint.setColor(SkColorSetARGB(215, 17, 17, 17));
238 canvas->drawRect(bounds, paint);
239 }
240
241 void HeadsUpDisplayLayerImpl::drawGraphLines(SkCanvas* canvas, SkPaint& paint, S kRect bounds, Graph& graph)
242 {
243 // Draw top and bottom line.
244 paint.setColor(SkColorSetRGB(130, 130, 130));
245 canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top () - 1, paint);
246 canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bott om(), paint);
247
248 // Draw indicator line.
249 paint.setColor(SkColorSetRGB(100, 100, 100));
250 const double indicatorTop = bounds.height() * (1 - graph.indicator / graph.h igh) - 1;
251 canvas->drawLine(bounds.left(), bounds.top() + indicatorTop, bounds.right(), bounds.top() + indicatorTop, paint);
252 }
253
254 int HeadsUpDisplayLayerImpl::drawFPSDisplay(SkCanvas* canvas, FrameRateCounter* fpsCounter, int top)
181 { 255 {
182 const int padding = 4; 256 const int padding = 4;
183 const int gap = 6; 257 const int gap = 6;
184 258
185 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0; 259 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
186 260
187 const int graphWidth = fpsCounter->timeStampHistorySize() - 3; 261 const int graphWidth = fpsCounter->timeStampHistorySize() - 2;
188 const int graphHeight = 40; 262 const int graphHeight = 40;
189 263
190 const int histogramWidth = 37; 264 const int histogramWidth = 37;
191 265
192 const int width = graphWidth + histogramWidth + 4 * padding; 266 const int width = graphWidth + histogramWidth + 4 * padding;
193 const int height = fontHeight + graphHeight + 4 * padding + 2; 267 const int height = fontHeight + graphHeight + 4 * padding + 2;
194 268
195 const int left = bounds().width() - width - 2; 269 const int left = bounds().width() - width - 2;
196 const int top = 2; 270 top += 2;
197 271
198 SkPaint paint = createPaint(); 272 SkPaint paint = createPaint();
199 273 drawGraphBackground(canvas, paint, SkRect::MakeXYWH(left, top, width, height ));
200 // Draw background.
201 paint.setColor(SkColorSetARGB(215, 17, 17, 17));
202 canvas->drawRect(SkRect::MakeXYWH(left, top, width, height), paint);
203 274
204 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid th + histogramWidth + gap + 2, fontHeight); 275 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid th + histogramWidth + gap + 2, fontHeight);
205 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight); 276 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() + 2 * padding, graphWidth, graphHeight);
206 SkRect histogramBounds = SkRect::MakeXYWH(graphBounds.right() + gap, graphBo unds.top(), histogramWidth, graphHeight); 277 SkRect histogramBounds = SkRect::MakeXYWH(graphBounds.right() + gap, graphBo unds.top(), histogramWidth, graphHeight);
207 278
208 drawFPSCounterText(canvas, paint, fpsCounter, textBounds); 279 drawTextLeftAligned(canvas, paint, textBounds, base::StringPrintf("FPS:%5.1f ", m_fpsGraph.current));
209 drawFPSCounterGraphAndHistogram(canvas, paint, fpsCounter, graphBounds, hist ogramBounds); 280 drawTextRightAligned(canvas, paint, textBounds, base::StringPrintf("%.0f-%.0 f", m_fpsGraph.min, m_fpsGraph.max));
210 281
211 return top + height; 282 const double high = Graph::updateHigh(m_fpsGraph);
212 } 283 drawGraphLines(canvas, paint, graphBounds, m_fpsGraph);
213
214 void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& pain t, FrameRateCounter* fpsCounter, SkRect bounds)
215 {
216 // Update FPS text - not every frame so text is readable
217 base::TimeTicks now = base::TimeTicks::Now();
218 if (base::TimeDelta(now - textUpdateTime).InSecondsF() > 0.25) {
219 m_averageFPS = fpsCounter->getAverageFPS();
220 textUpdateTime = now;
221 }
222
223 // Draw FPS text.
224 if (m_fontAtlas.get()) {
225 std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS);
226 std::string minMaxText = base::StringPrintf("%.0f-%.0f", std::min( m_min FPS, m_maxFPS), m_maxFPS);
227
228 int minMaxWidth = m_fontAtlas->textSize(minMaxText).width();
229 gfx::Size textArea(bounds.width(), bounds.height());
230
231 paint.setColor(SK_ColorRED);
232 m_fontAtlas->drawText(canvas, paint, fpsText, gfx::Point(bounds.left(), bounds.top()), textArea);
233 m_fontAtlas->drawText(canvas, paint, minMaxText, gfx::Point(bounds.right () - minMaxWidth, bounds.top()), textArea);
234 }
235 }
236
237 void HeadsUpDisplayLayerImpl::drawFPSCounterGraphAndHistogram(SkCanvas* canvas, SkPaint& paint, FrameRateCounter* fpsCounter, SkRect graphBounds, SkRect histogr amBounds)
238 {
239 const double loFPS = 0;
240 const double hiFPS = std::max(m_maxFPS + 10.0, 80.0);
241
242 // Draw top and bottom line.
243 paint.setColor(SkColorSetRGB(130, 130, 130));
244 canvas->drawLine(graphBounds.left(), graphBounds.top() - 1, graphBounds.righ t(), graphBounds.top() - 1, paint);
245 canvas->drawLine(graphBounds.left(), graphBounds.bottom(), graphBounds.right (), graphBounds.bottom(), paint);
246
247 // Draw 60fps line.
248 const double top60 = graphBounds.top() + graphBounds.height() * (1 - ((60 - loFPS) / (hiFPS - loFPS))) - 1;
249 paint.setColor(SkColorSetRGB(100, 100, 100));
250 canvas->drawLine(graphBounds.left(), top60, graphBounds.right(), top60, pain t);
251 284
252 // Collect graph and histogram data. 285 // Collect graph and histogram data.
253 int x = 0; 286 int x = 0;
254 SkPath path; 287 SkPath path;
255 288
256 m_minFPS = std::numeric_limits<double>::max();
257 m_maxFPS = 0;
258
259 const int histogramSize = 20; 289 const int histogramSize = 20;
260 double histogram[histogramSize] = {0}; 290 double histogram[histogramSize] = {0};
261 double maxBucketValue = 0; 291 double maxBucketValue = 0;
262 292
263 for (size_t i = 1; i < fpsCounter->timeStampHistorySize() - 1; ++i) { 293 for (size_t i = 0; i < fpsCounter->timeStampHistorySize() - 1; ++i) {
264 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsC ounter->timeStampOfRecentFrame(i); 294 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsC ounter->timeStampOfRecentFrame(i);
265 295
266 // Skip this particular instantaneous frame rate if it is not likely to have been valid. 296 // Skip this particular instantaneous frame rate if it is not likely to have been valid.
267 if (!fpsCounter->isBadFrameInterval(delta)) { 297 if (!fpsCounter->isBadFrameInterval(delta)) {
268 298
269 double fps = 1.0 / delta.InSecondsF(); 299 double fps = 1.0 / delta.InSecondsF();
270 300
271 m_minFPS = std::min(fps, m_minFPS);
272 m_maxFPS = std::max(fps, m_maxFPS);
273
274 // Clamp the FPS to the range we want to plot visually. 301 // Clamp the FPS to the range we want to plot visually.
275 double p = (fps - loFPS) / (hiFPS - loFPS); 302 double p = fps / high;
276 if (p < 0)
277 p = 0;
278 if (p > 1) 303 if (p > 1)
279 p = 1; 304 p = 1;
280 305
281 // Plot this data point. 306 // Plot this data point.
282 SkPoint cur = SkPoint::Make(graphBounds.left() + x, graphBounds.bott om() - p * graphBounds.height()); 307 SkPoint cur = SkPoint::Make(graphBounds.left() + x, graphBounds.bott om() - p * graphBounds.height());
283 if (path.isEmpty()) 308 if (path.isEmpty())
284 path.moveTo(cur); 309 path.moveTo(cur);
285 else 310 else
286 path.lineTo(cur); 311 path.lineTo(cur);
287 312
(...skipping 22 matching lines...) Expand all
310 canvas->drawRect(SkRect::MakeXYWH(histogramBounds.left(), histogramB ounds.bottom() - (i + 1) * barHeight, barWidth, 1), paint); 335 canvas->drawRect(SkRect::MakeXYWH(histogramBounds.left(), histogramB ounds.bottom() - (i + 1) * barHeight, barWidth, 1), paint);
311 } 336 }
312 } 337 }
313 338
314 // Draw FPS graph. 339 // Draw FPS graph.
315 paint.setAntiAlias(true); 340 paint.setAntiAlias(true);
316 paint.setStyle(SkPaint::kStroke_Style); 341 paint.setStyle(SkPaint::kStroke_Style);
317 paint.setStrokeWidth(1); 342 paint.setStrokeWidth(1);
318 343
319 canvas->drawPath(path, paint); 344 canvas->drawPath(path, paint);
345
346 return top + height;
347 }
348
349 int HeadsUpDisplayLayerImpl::drawPaintTimeDisplay(SkCanvas* canvas, PaintTimeCou nter* paintTimeCounter, int top)
350 {
351 const int padding = 4;
352 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0;
353
354 const int graphWidth = paintTimeCounter->HistorySize() * 2 - 1;
355 const int graphHeight = 40;
356
357 const int width = graphWidth + 2 * padding;
358 const int height = fontHeight + graphHeight + 4 * padding + 2 + fontHeight + padding;
359
360 const int left = bounds().width() - width - 2;
361 top += 2;
362
363 SkPaint paint = createPaint();
364 drawGraphBackground(canvas, paint, SkRect::MakeXYWH(left, top, width, height ));
365
366 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid th, fontHeight);
367 SkRect textBounds2 = SkRect::MakeXYWH(left + padding, textBounds.bottom() + padding, graphWidth, fontHeight);
368 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds2.bottom() + 2 * padding, graphWidth, graphHeight);
369
370 drawTextLeftAligned(canvas, paint, textBounds, "Page paint time (ms)");
371 drawTextLeftAligned(canvas, paint, textBounds2, base::StringPrintf("%5.1f", m_paintTimeGraph.current));
372 drawTextRightAligned(canvas, paint, textBounds2, base::StringPrintf("%.1f-%. 1f", m_paintTimeGraph.min, m_paintTimeGraph.max));
373
374 const double high = Graph::updateHigh(m_paintTimeGraph);
375 drawGraphLines(canvas, paint, graphBounds, m_paintTimeGraph);
376
377 // Same green as used for paint times in the WebInspector Timeline
378 paint.setColor(SkColorSetRGB(95, 160, 80));
379 for (size_t i = 0; i < paintTimeCounter->HistorySize(); ++i) {
380 double pt = paintTimeCounter->GetPaintTimeOfRecentFrame(i);
381
382 if (pt == 0.0)
383 continue;
384
385 double p = pt / high;
386 if (p > 1)
387 p = 1;
388
389 canvas->drawRect(SkRect::MakeXYWH(graphBounds.left() + i * 2, graphBound s.bottom() - p * graphBounds.height(), 1, p * graphBounds.height()), paint);
390 }
391
392 return top + height;
320 } 393 }
321 394
322 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory* debugRectHistory) 395 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory* debugRectHistory)
323 { 396 {
324 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects(); 397 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects();
325 float rectScale = 1 / layerTreeImpl()->device_scale_factor(); 398 float rectScale = 1 / layerTreeImpl()->device_scale_factor();
326 399
327 canvas->save(); 400 canvas->save();
328 canvas->scale(rectScale, rectScale); 401 canvas->scale(rectScale, rectScale);
329 402
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 457
385 canvas->restore(); 458 canvas->restore();
386 } 459 }
387 460
388 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const 461 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const
389 { 462 {
390 return "HeadsUpDisplayLayer"; 463 return "HeadsUpDisplayLayer";
391 } 464 }
392 465
393 } // namespace cc 466 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698