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

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