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 "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "cc/heads_up_display_layer_impl.h" | 7 #include "cc/heads_up_display_layer_impl.h" |
8 | 8 |
9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
10 #include "cc/debug_rect_history.h" | 10 #include "cc/debug_rect_history.h" |
11 #include "cc/font_atlas.h" | 11 #include "cc/font_atlas.h" |
12 #include "cc/frame_rate_counter.h" | 12 #include "cc/frame_rate_counter.h" |
13 #include "cc/layer_tree_host_impl.h" | 13 #include "cc/layer_tree_host_impl.h" |
14 #include "cc/quad_sink.h" | 14 #include "cc/quad_sink.h" |
15 #include "cc/texture_draw_quad.h" | 15 #include "cc/texture_draw_quad.h" |
16 #include "skia/ext/platform_canvas.h" | 16 #include "skia/ext/platform_canvas.h" |
17 #include "skia/ext/platform_canvas.h" | 17 #include "skia/ext/platform_canvas.h" |
18 #include "third_party/khronos/GLES2/gl2.h" | 18 #include "third_party/khronos/GLES2/gl2.h" |
19 #include "third_party/khronos/GLES2/gl2ext.h" | 19 #include "third_party/khronos/GLES2/gl2ext.h" |
20 #include "third_party/skia/include/core/SkBitmap.h" | 20 #include "third_party/skia/include/core/SkBitmap.h" |
21 #include "third_party/skia/include/core/SkPaint.h" | 21 #include "third_party/skia/include/core/SkPaint.h" |
22 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 22 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
23 #include "ui/gfx/point.h" | 23 #include "ui/gfx/point.h" |
| 24 #include "ui/gfx/size.h" |
24 | 25 |
25 namespace cc { | 26 namespace cc { |
26 | 27 |
27 static inline SkPaint createPaint() | 28 static inline SkPaint createPaint() |
28 { | 29 { |
29 // The SkCanvas is in RGBA but the shader is expecting BGRA, so we need to | 30 // The SkCanvas is in RGBA but the shader is expecting BGRA, so we need to |
30 // swizzle our colors when drawing to the SkCanvas. | 31 // swizzle our colors when drawing to the SkCanvas. |
31 SkColorMatrix swizzleMatrix; | 32 SkColorMatrix swizzleMatrix; |
32 for (int i = 0; i < 20; ++i) | 33 for (int i = 0; i < 20; ++i) |
33 swizzleMatrix.fMat[i] = 0; | 34 swizzleMatrix.fMat[i] = 0; |
34 swizzleMatrix.fMat[0 + 5 * 2] = 1; | 35 swizzleMatrix.fMat[0 + 5 * 2] = 1; |
35 swizzleMatrix.fMat[1 + 5 * 1] = 1; | 36 swizzleMatrix.fMat[1 + 5 * 1] = 1; |
36 swizzleMatrix.fMat[2 + 5 * 0] = 1; | 37 swizzleMatrix.fMat[2 + 5 * 0] = 1; |
37 swizzleMatrix.fMat[3 + 5 * 3] = 1; | 38 swizzleMatrix.fMat[3 + 5 * 3] = 1; |
38 | 39 |
39 SkPaint paint; | 40 SkPaint paint; |
40 paint.setColorFilter(new SkColorMatrixFilter(swizzleMatrix))->unref(); | 41 paint.setColorFilter(new SkColorMatrixFilter(swizzleMatrix))->unref(); |
41 return paint; | 42 return paint; |
42 } | 43 } |
43 | 44 |
44 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(int id) | 45 HeadsUpDisplayLayerImpl::HeadsUpDisplayLayerImpl(int id) |
45 : LayerImpl(id) | 46 : LayerImpl(id) |
| 47 , m_averageFPS(0) |
| 48 , m_stdDeviation(0) |
46 { | 49 { |
47 } | 50 } |
48 | 51 |
49 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() | 52 HeadsUpDisplayLayerImpl::~HeadsUpDisplayLayerImpl() |
50 { | 53 { |
51 } | 54 } |
52 | 55 |
53 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas) | 56 void HeadsUpDisplayLayerImpl::setFontAtlas(scoped_ptr<FontAtlas> fontAtlas) |
54 { | 57 { |
55 m_fontAtlas = fontAtlas.Pass(); | 58 m_fontAtlas = fontAtlas.Pass(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas) | 139 void HeadsUpDisplayLayerImpl::drawHudContents(SkCanvas* canvas) |
137 { | 140 { |
138 const LayerTreeSettings& settings = layerTreeHostImpl()->settings(); | 141 const LayerTreeSettings& settings = layerTreeHostImpl()->settings(); |
139 | 142 |
140 if (settings.showPlatformLayerTree) { | 143 if (settings.showPlatformLayerTree) { |
141 SkPaint paint = createPaint(); | 144 SkPaint paint = createPaint(); |
142 paint.setColor(SkColorSetARGB(192, 0, 0, 0)); | 145 paint.setColor(SkColorSetARGB(192, 0, 0, 0)); |
143 canvas->drawRect(SkRect::MakeXYWH(0, 0, bounds().width(), bounds().heigh
t()), paint); | 146 canvas->drawRect(SkRect::MakeXYWH(0, 0, bounds().width(), bounds().heigh
t()), paint); |
144 } | 147 } |
145 | 148 |
146 int fpsCounterHeight = 40; | 149 int platformLayerTreeTop = 0; |
147 int fpsCounterTop = 2; | |
148 int platformLayerTreeTop; | |
149 | 150 |
150 if (settings.showFPSCounter) | 151 if (settings.showFPSCounter) |
151 platformLayerTreeTop = fpsCounterTop + fpsCounterHeight; | 152 platformLayerTreeTop = drawFPSCounter(canvas, layerTreeHostImpl()->fpsCo
unter()); |
152 else | |
153 platformLayerTreeTop = 0; | |
154 | |
155 if (settings.showFPSCounter) | |
156 drawFPSCounter(canvas, layerTreeHostImpl()->fpsCounter(), fpsCounterTop,
fpsCounterHeight); | |
157 | 153 |
158 if (settings.showPlatformLayerTree && m_fontAtlas.get()) { | 154 if (settings.showPlatformLayerTree && m_fontAtlas.get()) { |
159 std::string layerTree = layerTreeHostImpl()->layerTreeAsText(); | 155 std::string layerTree = layerTreeHostImpl()->layerTreeAsText(); |
160 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, pl
atformLayerTreeTop), bounds()); | 156 m_fontAtlas->drawText(canvas, createPaint(), layerTree, gfx::Point(2, pl
atformLayerTreeTop), bounds()); |
161 } | 157 } |
162 | 158 |
163 if (settings.showDebugRects()) | 159 if (settings.showDebugRects()) |
164 drawDebugRects(canvas, layerTreeHostImpl()->debugRectHistory()); | 160 drawDebugRects(canvas, layerTreeHostImpl()->debugRectHistory()); |
165 } | 161 } |
166 | 162 |
167 void HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter*
fpsCounter, int top, int height) | 163 int HeadsUpDisplayLayerImpl::drawFPSCounter(SkCanvas* canvas, FrameRateCounter*
fpsCounter) |
168 { | 164 { |
169 float textWidth = 170; // so text fits on linux. | 165 const int left = 2; |
170 float graphWidth = fpsCounter->timeStampHistorySize(); | 166 const int top = 2; |
171 | 167 |
172 // Draw the FPS text. | 168 const int padding = 4; |
173 drawFPSCounterText(canvas, fpsCounter, top, textWidth, height); | 169 |
| 170 const int fontHeight = m_fontAtlas.get() ? m_fontAtlas->fontHeight() : 0; |
| 171 const int graphWidth = fpsCounter->timeStampHistorySize() - 3; |
| 172 const int graphHeight = 40; |
| 173 |
| 174 const int width = graphWidth + 2 * padding; |
| 175 const int height = fontHeight + graphHeight + 4 * padding + 2; |
| 176 |
| 177 SkPaint paint = createPaint(); |
| 178 |
| 179 // Draw background. |
| 180 paint.setColor(SkColorSetARGB(215, 17, 17, 17)); |
| 181 canvas->drawRect(SkRect::MakeXYWH(left, top, width, height), paint); |
| 182 |
| 183 SkRect textBounds = SkRect::MakeXYWH(left + padding, top + padding, graphWid
th, fontHeight); |
| 184 SkRect graphBounds = SkRect::MakeXYWH(left + padding, textBounds.bottom() +
2 * padding, graphWidth, graphHeight); |
| 185 |
| 186 drawFPSCounterText(canvas, paint, fpsCounter, textBounds); |
| 187 drawFPSCounterGraph(canvas, paint, fpsCounter, graphBounds); |
| 188 |
| 189 return top + height; |
| 190 } |
| 191 |
| 192 void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, SkPaint& pain
t, FrameRateCounter* fpsCounter, SkRect bounds) |
| 193 { |
| 194 // Update FPS text - not every frame so text is readable |
| 195 if (base::TimeDelta(fpsCounter->timeStampOfRecentFrame(0) - textUpdateTime).
InSecondsF() > 0.25) { |
| 196 fpsCounter->getAverageFPSAndStandardDeviation(m_averageFPS, m_stdDeviati
on); |
| 197 textUpdateTime = fpsCounter->timeStampOfRecentFrame(0); |
| 198 } |
| 199 |
| 200 // Draw FPS text. |
| 201 if (m_fontAtlas.get()) { |
| 202 std::string fpsText = base::StringPrintf("FPS:%5.1f", m_averageFPS); |
| 203 std::string deviationText = base::StringPrintf("+/-%4.1f", m_stdDeviatio
n); |
| 204 |
| 205 int deviationWidth = m_fontAtlas->textSize(deviationText).width(); |
| 206 gfx::Size textArea(bounds.width(), bounds.height()); |
| 207 |
| 208 paint.setColor(SK_ColorRED); |
| 209 m_fontAtlas->drawText(canvas, paint, fpsText, gfx::Point(bounds.left(),
bounds.top()), textArea); |
| 210 m_fontAtlas->drawText(canvas, paint, deviationText, gfx::Point(bounds.ri
ght() - deviationWidth, bounds.top()), textArea); |
| 211 } |
| 212 } |
| 213 |
| 214 void HeadsUpDisplayLayerImpl::drawFPSCounterGraph(SkCanvas* canvas, SkPaint& pai
nt, FrameRateCounter* fpsCounter, SkRect bounds) |
| 215 { |
| 216 const double loFPS = 0; |
| 217 const double hiFPS = 80; |
| 218 |
| 219 paint.setStyle(SkPaint::kStroke_Style); |
| 220 paint.setStrokeWidth(1); |
| 221 |
| 222 // Draw top and bottom line. |
| 223 paint.setColor(SkColorSetRGB(150, 150, 150)); |
| 224 canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top
() - 1, paint); |
| 225 canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), bounds.bott
om(), paint); |
| 226 |
| 227 // Draw 60fps line. |
| 228 paint.setColor(SkColorSetRGB(100, 100, 100)); |
| 229 canvas->drawLine(bounds.left(), bounds.top() + bounds.height() / 4, bounds.r
ight(), bounds.top() + bounds.height() / 4, paint); |
174 | 230 |
175 // Draw FPS graph. | 231 // Draw FPS graph. |
176 const double loFPS = 0; | 232 int x = 0; |
177 const double hiFPS = 80; | 233 SkPath path; |
178 SkPaint paint = createPaint(); | |
179 paint.setColor(SkColorSetRGB(154, 205, 50)); | |
180 canvas->drawRect(SkRect::MakeXYWH(2 + textWidth, top, graphWidth, height / 2
), paint); | |
181 | 234 |
182 paint.setColor(SkColorSetRGB(255, 250, 205)); | 235 for (int i = 1; i < fpsCounter->timeStampHistorySize() - 1; ++i) { |
183 canvas->drawRect(SkRect::MakeXYWH(2 + textWidth, top + height / 2, graphWidt
h, height / 2), paint); | 236 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(i + 1) - fpsC
ounter->timeStampOfRecentFrame(i); |
184 | |
185 int graphLeft = static_cast<int>(textWidth + 3); | |
186 int x = 0; | |
187 double h = static_cast<double>(height - 2); | |
188 SkPath path; | |
189 for (int i = 0; i < fpsCounter->timeStampHistorySize() - 1; ++i) { | |
190 int j = i + 1; | |
191 base::TimeDelta delta = fpsCounter->timeStampOfRecentFrame(j) - fpsCount
er->timeStampOfRecentFrame(i); | |
192 | 237 |
193 // Skip plotting this particular instantaneous frame rate if it is not l
ikely to have been valid. | 238 // Skip plotting this particular instantaneous frame rate if it is not l
ikely to have been valid. |
194 if (fpsCounter->isBadFrameInterval(delta)) { | 239 if (!fpsCounter->isBadFrameInterval(delta)) { |
195 x += 1; | 240 double fps = 1.0 / delta.InSecondsF(); |
196 continue; | 241 |
| 242 // Clamp the FPS to the range we want to plot visually. |
| 243 double p = 1 - ((fps - loFPS) / (hiFPS - loFPS)); |
| 244 if (p < 0) |
| 245 p = 0; |
| 246 if (p > 1) |
| 247 p = 1; |
| 248 |
| 249 // Plot this data point. |
| 250 SkPoint cur = SkPoint::Make(bounds.left() + x, bounds.top() + p * bo
unds.height()); |
| 251 if (path.isEmpty()) |
| 252 path.moveTo(cur); |
| 253 else |
| 254 path.lineTo(cur); |
197 } | 255 } |
198 | 256 |
199 double fps = 1.0 / delta.InSecondsF(); | |
200 | |
201 // Clamp the FPS to the range we want to plot visually. | |
202 double p = 1 - ((fps - loFPS) / (hiFPS - loFPS)); | |
203 if (p < 0) | |
204 p = 0; | |
205 if (p > 1) | |
206 p = 1; | |
207 | |
208 // Plot this data point. | |
209 SkPoint cur = SkPoint::Make(graphLeft + x, 1 + top + p*h); | |
210 if (path.isEmpty()) | |
211 path.moveTo(cur); | |
212 else | |
213 path.lineTo(cur); | |
214 x += 1; | 257 x += 1; |
215 } | 258 } |
| 259 |
| 260 paint.setAntiAlias(true); |
216 paint.setColor(SK_ColorRED); | 261 paint.setColor(SK_ColorRED); |
217 paint.setStyle(SkPaint::kStroke_Style); | |
218 paint.setStrokeWidth(1); | |
219 paint.setAntiAlias(true); | |
220 canvas->drawPath(path, paint); | 262 canvas->drawPath(path, paint); |
221 } | 263 } |
222 | 264 |
223 void HeadsUpDisplayLayerImpl::drawFPSCounterText(SkCanvas* canvas, FrameRateCoun
ter* fpsCounter, int top, int width, int height) | |
224 { | |
225 double averageFPS, stdDeviation; | |
226 fpsCounter->getAverageFPSAndStandardDeviation(averageFPS, stdDeviation); | |
227 | |
228 // Draw background. | |
229 SkPaint paint = createPaint(); | |
230 paint.setColor(SK_ColorBLACK); | |
231 canvas->drawRect(SkRect::MakeXYWH(2, top, width, height), paint); | |
232 | |
233 // Draw FPS text. | |
234 if (m_fontAtlas.get()) | |
235 m_fontAtlas->drawText(canvas, createPaint(), base::StringPrintf("FPS: %4
.1f +/- %3.1f", averageFPS, stdDeviation), gfx::Point(10, height / 3), gfx::Size
(width, height)); | |
236 } | |
237 | |
238 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory*
debugRectHistory) | 265 void HeadsUpDisplayLayerImpl::drawDebugRects(SkCanvas* canvas, DebugRectHistory*
debugRectHistory) |
239 { | 266 { |
240 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects(); | 267 const std::vector<DebugRect>& debugRects = debugRectHistory->debugRects(); |
241 | 268 |
242 for (size_t i = 0; i < debugRects.size(); ++i) { | 269 for (size_t i = 0; i < debugRects.size(); ++i) { |
243 SkColor strokeColor = 0; | 270 SkColor strokeColor = 0; |
244 SkColor fillColor = 0; | 271 SkColor fillColor = 0; |
245 | 272 |
246 switch (debugRects[i].type) { | 273 switch (debugRects[i].type) { |
247 case PaintRectType: | 274 case PaintRectType: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 canvas->drawRect(skRect, paint); | 315 canvas->drawRect(skRect, paint); |
289 } | 316 } |
290 } | 317 } |
291 | 318 |
292 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const | 319 const char* HeadsUpDisplayLayerImpl::layerTypeAsString() const |
293 { | 320 { |
294 return "HeadsUpDisplayLayer"; | 321 return "HeadsUpDisplayLayer"; |
295 } | 322 } |
296 | 323 |
297 } // namespace cc | 324 } // namespace cc |
OLD | NEW |