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

Side by Side Diff: content/renderer/skia_benchmarking_extension.cc

Issue 942533002: Refactor BenchmarkingCanvas to avoid internal Skia dependencies (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: speculative Win warnings fix Created 5 years, 10 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/renderer/skia_benchmarking_extension.h" 5 #include "content/renderer/skia_benchmarking_extension.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/time/time.h" 8 #include "base/time/time.h"
9 #include "base/values.h" 9 #include "base/values.h"
10 #include "cc/base/math_util.h" 10 #include "cc/base/math_util.h"
11 #include "cc/resources/picture.h" 11 #include "cc/resources/picture.h"
12 #include "content/public/child/v8_value_converter.h" 12 #include "content/public/child/v8_value_converter.h"
13 #include "content/renderer/chrome_object_extensions_utils.h" 13 #include "content/renderer/chrome_object_extensions_utils.h"
14 #include "content/renderer/render_thread_impl.h" 14 #include "content/renderer/render_thread_impl.h"
15 #include "gin/arguments.h" 15 #include "gin/arguments.h"
16 #include "gin/handle.h" 16 #include "gin/handle.h"
17 #include "gin/object_template_builder.h" 17 #include "gin/object_template_builder.h"
18 #include "skia/ext/benchmarking_canvas.h" 18 #include "skia/ext/benchmarking_canvas.h"
19 #include "third_party/WebKit/public/web/WebArrayBuffer.h" 19 #include "third_party/WebKit/public/web/WebArrayBuffer.h"
20 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" 20 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h"
21 #include "third_party/WebKit/public/web/WebFrame.h" 21 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebKit.h" 22 #include "third_party/WebKit/public/web/WebKit.h"
23 #include "third_party/skia/include/core/SkCanvas.h" 23 #include "third_party/skia/include/core/SkCanvas.h"
24 #include "third_party/skia/include/core/SkColorPriv.h" 24 #include "third_party/skia/include/core/SkColorPriv.h"
25 #include "third_party/skia/include/core/SkGraphics.h" 25 #include "third_party/skia/include/core/SkGraphics.h"
26 #include "third_party/skia/include/core/SkPicture.h"
26 #include "third_party/skia/include/core/SkStream.h" 27 #include "third_party/skia/include/core/SkStream.h"
27 #include "third_party/skia/src/utils/debugger/SkDebugCanvas.h"
28 #include "third_party/skia/src/utils/debugger/SkDrawCommand.h"
29 #include "ui/gfx/geometry/rect_conversions.h" 28 #include "ui/gfx/geometry/rect_conversions.h"
30 #include "ui/gfx/skia_util.h" 29 #include "ui/gfx/skia_util.h"
31 #include "v8/include/v8.h" 30 #include "v8/include/v8.h"
32 31
33 namespace content { 32 namespace content {
34 33
35 namespace { 34 namespace {
36 35
37 scoped_ptr<base::Value> ParsePictureArg(v8::Isolate* isolate, 36 scoped_ptr<base::Value> ParsePictureArg(v8::Isolate* isolate,
38 v8::Handle<v8::Value> arg) { 37 v8::Handle<v8::Value> arg) {
(...skipping 12 matching lines...) Expand all
51 } 50 }
52 51
53 scoped_refptr<cc::Picture> ParsePictureHash(v8::Isolate* isolate, 52 scoped_refptr<cc::Picture> ParsePictureHash(v8::Isolate* isolate,
54 v8::Handle<v8::Value> arg) { 53 v8::Handle<v8::Value> arg) {
55 scoped_ptr<base::Value> picture_value = ParsePictureArg(isolate, arg); 54 scoped_ptr<base::Value> picture_value = ParsePictureArg(isolate, arg);
56 if (!picture_value) 55 if (!picture_value)
57 return NULL; 56 return NULL;
58 return cc::Picture::CreateFromValue(picture_value.get()); 57 return cc::Picture::CreateFromValue(picture_value.get());
59 } 58 }
60 59
60 class PicturePlaybackController : public SkPicture::AbortCallback {
61 public:
62 PicturePlaybackController(const skia::BenchmarkingCanvas& canvas,
63 size_t count)
64 : canvas_(canvas)
65 , playback_count_(count) {
66 }
67
68 bool abort() override {
69 return canvas_.CommandCount() > playback_count_;
70 }
71
72 private:
73 const skia::BenchmarkingCanvas& canvas_;
74 size_t playback_count_;
75 };
76
61 } // namespace 77 } // namespace
62 78
63 gin::WrapperInfo SkiaBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; 79 gin::WrapperInfo SkiaBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin};
64 80
65 // static 81 // static
66 void SkiaBenchmarking::Install(blink::WebFrame* frame) { 82 void SkiaBenchmarking::Install(blink::WebFrame* frame) {
67 v8::Isolate* isolate = blink::mainThreadIsolate(); 83 v8::Isolate* isolate = blink::mainThreadIsolate();
68 v8::HandleScope handle_scope(isolate); 84 v8::HandleScope handle_scope(isolate);
69 v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); 85 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
70 if (context.IsEmpty()) 86 if (context.IsEmpty())
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 if (!bitmap.tryAllocN32Pixels(snapped_clip.width(), snapped_clip.height())) 172 if (!bitmap.tryAllocN32Pixels(snapped_clip.width(), snapped_clip.height()))
157 return; 173 return;
158 bitmap.eraseARGB(0, 0, 0, 0); 174 bitmap.eraseARGB(0, 0, 0, 0);
159 175
160 SkCanvas canvas(bitmap); 176 SkCanvas canvas(bitmap);
161 canvas.translate(SkFloatToScalar(-clip.x()), SkFloatToScalar(-clip.y())); 177 canvas.translate(SkFloatToScalar(-clip.x()), SkFloatToScalar(-clip.y()));
162 canvas.clipRect(gfx::RectToSkRect(snapped_clip)); 178 canvas.clipRect(gfx::RectToSkRect(snapped_clip));
163 canvas.scale(scale, scale); 179 canvas.scale(scale, scale);
164 canvas.translate(picture->LayerRect().x(), picture->LayerRect().y()); 180 canvas.translate(picture->LayerRect().x(), picture->LayerRect().y());
165 181
166 // First, build a debug canvas for the given picture. 182 // FIXME: no overdraw support ATM.
pdr. 2015/02/20 04:48:00 Maybe we should just take this out? Overdraw seems
f(malita) 2015/02/20 13:57:00 Sounds reasonable. The only reason I'm hesitating
167 SkDebugCanvas debug_canvas(picture->LayerRect().width(), 183 skia::BenchmarkingCanvas benchmarking_canvas(&canvas);
168 picture->LayerRect().height()); 184 size_t playback_count = (stop_index < 0) ?
169 picture->Replay(&debug_canvas); 185 std::numeric_limits<size_t>::max() : stop_index;
170 186 PicturePlaybackController controller(benchmarking_canvas, playback_count);
171 // Raster the requested command subset into the bitmap-backed canvas. 187 picture->Replay(&benchmarking_canvas, &controller);
172 int last_index = debug_canvas.getSize() - 1;
173 if (last_index >= 0) {
174 debug_canvas.setOverdrawViz(overdraw);
175 debug_canvas.drawTo(
176 &canvas,
177 stop_index < 0 ? last_index : std::min(last_index, stop_index));
178 }
179 188
180 blink::WebArrayBuffer buffer = 189 blink::WebArrayBuffer buffer =
181 blink::WebArrayBuffer::create(bitmap.getSize(), 1); 190 blink::WebArrayBuffer::create(bitmap.getSize(), 1);
182 uint32* packed_pixels = reinterpret_cast<uint32*>(bitmap.getPixels()); 191 uint32* packed_pixels = reinterpret_cast<uint32*>(bitmap.getPixels());
183 uint8* buffer_pixels = reinterpret_cast<uint8*>(buffer.data()); 192 uint8* buffer_pixels = reinterpret_cast<uint8*>(buffer.data());
184 // Swizzle from native Skia format to RGBA as we copy out. 193 // Swizzle from native Skia format to RGBA as we copy out.
185 for (size_t i = 0; i < bitmap.getSize(); i += 4) { 194 for (size_t i = 0; i < bitmap.getSize(); i += 4) {
186 uint32 c = packed_pixels[i >> 2]; 195 uint32 c = packed_pixels[i >> 2];
187 buffer_pixels[i] = SkGetPackedR32(c); 196 buffer_pixels[i] = SkGetPackedR32(c);
188 buffer_pixels[i + 1] = SkGetPackedG32(c); 197 buffer_pixels[i + 1] = SkGetPackedG32(c);
(...skipping 17 matching lines...) Expand all
206 v8::Isolate* isolate = args->isolate(); 215 v8::Isolate* isolate = args->isolate();
207 if (args->PeekNext().IsEmpty()) 216 if (args->PeekNext().IsEmpty())
208 return; 217 return;
209 v8::Handle<v8::Value> picture_handle; 218 v8::Handle<v8::Value> picture_handle;
210 args->GetNext(&picture_handle); 219 args->GetNext(&picture_handle);
211 scoped_refptr<cc::Picture> picture = 220 scoped_refptr<cc::Picture> picture =
212 ParsePictureHash(isolate, picture_handle); 221 ParsePictureHash(isolate, picture_handle);
213 if (!picture.get()) 222 if (!picture.get())
214 return; 223 return;
215 224
216 gfx::Rect bounds = picture->LayerRect(); 225 SkCanvas canvas(picture->LayerRect().width(),
217 SkDebugCanvas canvas(bounds.width(), bounds.height()); 226 picture->LayerRect().height());
218 picture->Replay(&canvas); 227 skia::BenchmarkingCanvas benchmarking_canvas(&canvas);
228 picture->Replay(&benchmarking_canvas);
219 229
220 v8::Handle<v8::Array> result = v8::Array::New(isolate, canvas.getSize()); 230 v8::Handle<v8::Context> context = isolate->GetCurrentContext();
221 for (int i = 0; i < canvas.getSize(); ++i) { 231 scoped_ptr<content::V8ValueConverter> converter(
222 SkDrawCommand::OpType cmd_type = canvas.getDrawCommandAt(i)->getType(); 232 content::V8ValueConverter::create());
223 v8::Handle<v8::Object> cmd = v8::Object::New(isolate);
224 cmd->Set(v8::String::NewFromUtf8(isolate, "cmd_type"),
225 v8::Integer::New(isolate, cmd_type));
226 cmd->Set(v8::String::NewFromUtf8(isolate, "cmd_string"),
227 v8::String::NewFromUtf8(
228 isolate, SkDrawCommand::GetCommandString(cmd_type)));
229 233
230 const SkTDArray<SkString*>* info = canvas.getCommandInfo(i); 234 args->Return(converter->ToV8Value(&benchmarking_canvas.Commands(), context));
231 DCHECK(info);
232
233 v8::Local<v8::Array> v8_info = v8::Array::New(isolate, info->count());
234 for (int j = 0; j < info->count(); ++j) {
235 const SkString* info_str = (*info)[j];
236 DCHECK(info_str);
237 v8_info->Set(j, v8::String::NewFromUtf8(isolate, info_str->c_str()));
238 }
239
240 cmd->Set(v8::String::NewFromUtf8(isolate, "info"), v8_info);
241
242 result->Set(i, cmd);
243 }
244
245 args->Return(result.As<v8::Object>());
246 } 235 }
247 236
248 void SkiaBenchmarking::GetOpTimings(gin::Arguments* args) { 237 void SkiaBenchmarking::GetOpTimings(gin::Arguments* args) {
249 v8::Isolate* isolate = args->isolate(); 238 v8::Isolate* isolate = args->isolate();
250 if (args->PeekNext().IsEmpty()) 239 if (args->PeekNext().IsEmpty())
251 return; 240 return;
252 v8::Handle<v8::Value> picture_handle; 241 v8::Handle<v8::Value> picture_handle;
253 args->GetNext(&picture_handle); 242 args->GetNext(&picture_handle);
254 scoped_refptr<cc::Picture> picture = 243 scoped_refptr<cc::Picture> picture =
255 ParsePictureHash(isolate, picture_handle); 244 ParsePictureHash(isolate, picture_handle);
256 if (!picture.get()) 245 if (!picture.get())
257 return; 246 return;
258 247
259 gfx::Rect bounds = picture->LayerRect(); 248 gfx::Rect bounds = picture->LayerRect();
260 249
261 // Measure the total time by drawing straight into a bitmap-backed canvas. 250 // Measure the total time by drawing straight into a bitmap-backed canvas.
262 SkBitmap bitmap; 251 SkBitmap bitmap;
263 bitmap.allocN32Pixels(bounds.width(), bounds.height()); 252 bitmap.allocN32Pixels(bounds.width(), bounds.height());
264 SkCanvas bitmap_canvas(bitmap); 253 SkCanvas bitmap_canvas(bitmap);
265 bitmap_canvas.clear(SK_ColorTRANSPARENT); 254 bitmap_canvas.clear(SK_ColorTRANSPARENT);
266 base::TimeTicks t0 = base::TimeTicks::Now(); 255 base::TimeTicks t0 = base::TimeTicks::Now();
267 picture->Replay(&bitmap_canvas); 256 picture->Replay(&bitmap_canvas);
268 base::TimeDelta total_time = base::TimeTicks::Now() - t0; 257 base::TimeDelta total_time = base::TimeTicks::Now() - t0;
269 258
270 // Gather per-op timing info by drawing into a BenchmarkingCanvas. 259 // Gather per-op timing info by drawing into a BenchmarkingCanvas.
271 skia::BenchmarkingCanvas benchmarking_canvas(bounds.width(), bounds.height()); 260 SkCanvas canvas(bitmap);
261 canvas.clear(SK_ColorTRANSPARENT);
262 skia::BenchmarkingCanvas benchmarking_canvas(&canvas);
272 picture->Replay(&benchmarking_canvas); 263 picture->Replay(&benchmarking_canvas);
273 264
274 v8::Local<v8::Array> op_times = 265 v8::Local<v8::Array> op_times =
275 v8::Array::New(isolate, benchmarking_canvas.CommandCount()); 266 v8::Array::New(isolate, benchmarking_canvas.CommandCount());
276 for (size_t i = 0; i < benchmarking_canvas.CommandCount(); ++i) 267 for (size_t i = 0; i < benchmarking_canvas.CommandCount(); ++i) {
277 op_times->Set(i, v8::Number::New(isolate, benchmarking_canvas.GetTime(i))); 268 op_times->Set(i, v8::Number::New(isolate, benchmarking_canvas.GetTime(i)));
269 }
278 270
279 v8::Handle<v8::Object> result = v8::Object::New(isolate); 271 v8::Handle<v8::Object> result = v8::Object::New(isolate);
280 result->Set(v8::String::NewFromUtf8(isolate, "total_time"), 272 result->Set(v8::String::NewFromUtf8(isolate, "total_time"),
281 v8::Number::New(isolate, total_time.InMillisecondsF())); 273 v8::Number::New(isolate, total_time.InMillisecondsF()));
282 result->Set(v8::String::NewFromUtf8(isolate, "cmd_times"), op_times); 274 result->Set(v8::String::NewFromUtf8(isolate, "cmd_times"), op_times);
283 275
284 args->Return(result); 276 args->Return(result);
285 } 277 }
286 278
287 void SkiaBenchmarking::GetInfo(gin::Arguments* args) { 279 void SkiaBenchmarking::GetInfo(gin::Arguments* args) {
(...skipping 10 matching lines...) Expand all
298 v8::Handle<v8::Object> result = v8::Object::New(isolate); 290 v8::Handle<v8::Object> result = v8::Object::New(isolate);
299 result->Set(v8::String::NewFromUtf8(isolate, "width"), 291 result->Set(v8::String::NewFromUtf8(isolate, "width"),
300 v8::Number::New(isolate, picture->LayerRect().width())); 292 v8::Number::New(isolate, picture->LayerRect().width()));
301 result->Set(v8::String::NewFromUtf8(isolate, "height"), 293 result->Set(v8::String::NewFromUtf8(isolate, "height"),
302 v8::Number::New(isolate, picture->LayerRect().height())); 294 v8::Number::New(isolate, picture->LayerRect().height()));
303 295
304 args->Return(result); 296 args->Return(result);
305 } 297 }
306 298
307 } // namespace content 299 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698