[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/renderer/skia_benchmarking_extension.h" |
| 6 | |
avi | 1023d01 | 2015-12-25 02:39:14 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | #include <stdint.h> |
| 9 | |
[email protected] | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 10 | #include "base/base64.h" |
[email protected] | 6497567 | 2013-07-30 18:47:13 | [diff] [blame] | 11 | #include "base/time/time.h" |
[email protected] | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 12 | #include "base/values.h" |
[email protected] | ef20a40 | 2013-07-02 04:30:43 | [diff] [blame] | 13 | #include "cc/base/math_util.h" |
donnd | bd8a661 | 2015-12-02 02:39:58 | [diff] [blame] | 14 | #include "content/public/renderer/chrome_object_extensions_utils.h" |
John Abd-El-Malek | 312a30bb | 2017-10-23 19:51:52 | [diff] [blame] | 15 | #include "content/public/renderer/v8_value_converter.h" |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 16 | #include "content/renderer/render_thread_impl.h" |
| 17 | #include "gin/arguments.h" |
jbroman | 5967a86 | 2017-04-27 16:52:45 | [diff] [blame] | 18 | #include "gin/data_object_builder.h" |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 19 | #include "gin/handle.h" |
| 20 | #include "gin/object_template_builder.h" |
[email protected] | 6497567 | 2013-07-30 18:47:13 | [diff] [blame] | 21 | #include "skia/ext/benchmarking_canvas.h" |
yukishiino | ecc8886 | 2014-12-04 03:53:20 | [diff] [blame] | 22 | #include "third_party/WebKit/public/web/WebArrayBuffer.h" |
[email protected] | 8d5e514 | 2014-02-06 20:10:37 | [diff] [blame] | 23 | #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 24 | #include "third_party/WebKit/public/web/WebKit.h" |
lukasza | df18ba76 | 2017-06-09 22:24:30 | [diff] [blame] | 25 | #include "third_party/WebKit/public/web/WebLocalFrame.h" |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 26 | #include "third_party/skia/include/core/SkCanvas.h" |
[email protected] | 3fcc7b4 | 2013-05-14 20:20:50 | [diff] [blame] | 27 | #include "third_party/skia/include/core/SkColorPriv.h" |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 28 | #include "third_party/skia/include/core/SkGraphics.h" |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 29 | #include "third_party/skia/include/core/SkPicture.h" |
[email protected] | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 30 | #include "third_party/skia/include/core/SkStream.h" |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 31 | #include "ui/gfx/codec/jpeg_codec.h" |
| 32 | #include "ui/gfx/codec/png_codec.h" |
tfarina | 3b0452d | 2014-12-31 15:20:09 | [diff] [blame] | 33 | #include "ui/gfx/geometry/rect_conversions.h" |
[email protected] | ef20a40 | 2013-07-02 04:30:43 | [diff] [blame] | 34 | #include "ui/gfx/skia_util.h" |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 35 | #include "v8/include/v8.h" |
| 36 | |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 37 | namespace content { |
[email protected] | dc5407d4 | 2013-05-24 22:33:03 | [diff] [blame] | 38 | |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 39 | namespace { |
| 40 | |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 41 | class Picture { |
| 42 | public: |
| 43 | gfx::Rect layer_rect; |
fmalita | 9e89d08 | 2016-03-28 15:44:49 | [diff] [blame] | 44 | sk_sp<SkPicture> picture; |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 45 | }; |
| 46 | |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 47 | std::unique_ptr<base::Value> ParsePictureArg(v8::Isolate* isolate, |
| 48 | v8::Local<v8::Value> arg) { |
rdevlin.cronin | 694c605 | 2017-06-13 22:07:35 | [diff] [blame] | 49 | return content::V8ValueConverter::Create()->FromV8Value( |
| 50 | arg, isolate->GetCurrentContext()); |
[email protected] | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 51 | } |
| 52 | |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 53 | std::unique_ptr<Picture> CreatePictureFromEncodedString( |
| 54 | const std::string& encoded) { |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 55 | std::string decoded; |
| 56 | base::Base64Decode(encoded, &decoded); |
fmalita | 9e89d08 | 2016-03-28 15:44:49 | [diff] [blame] | 57 | sk_sp<SkPicture> skpicture = |
Mike Reed | 051e7bd | 2017-12-15 03:55:31 | [diff] [blame] | 58 | SkPicture::MakeFromData(decoded.data(), decoded.size()); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 59 | if (!skpicture) |
| 60 | return nullptr; |
| 61 | |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 62 | std::unique_ptr<Picture> picture(new Picture); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 63 | picture->layer_rect = gfx::SkIRectToRect(skpicture->cullRect().roundOut()); |
fmalita | 9e89d08 | 2016-03-28 15:44:49 | [diff] [blame] | 64 | picture->picture = std::move(skpicture); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 65 | return picture; |
[email protected] | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 66 | } |
[email protected] | cb9118b3 | 2013-06-26 14:15:07 | [diff] [blame] | 67 | |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 68 | std::unique_ptr<Picture> ParsePictureStr(v8::Isolate* isolate, |
| 69 | v8::Local<v8::Value> arg) { |
| 70 | std::unique_ptr<base::Value> picture_value = ParsePictureArg(isolate, arg); |
[email protected] | c883e8b | 2013-09-01 23:36:31 | [diff] [blame] | 71 | if (!picture_value) |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 72 | return nullptr; |
| 73 | // Decode the picture from base64. |
| 74 | std::string encoded; |
| 75 | if (!picture_value->GetAsString(&encoded)) |
| 76 | return nullptr; |
| 77 | return CreatePictureFromEncodedString(encoded); |
| 78 | } |
| 79 | |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 80 | std::unique_ptr<Picture> ParsePictureHash(v8::Isolate* isolate, |
| 81 | v8::Local<v8::Value> arg) { |
| 82 | std::unique_ptr<base::Value> picture_value = ParsePictureArg(isolate, arg); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 83 | if (!picture_value) |
| 84 | return nullptr; |
| 85 | const base::DictionaryValue* value = nullptr; |
| 86 | if (!picture_value->GetAsDictionary(&value)) |
| 87 | return nullptr; |
| 88 | // Decode the picture from base64. |
| 89 | std::string encoded; |
| 90 | if (!value->GetString("skp64", &encoded)) |
| 91 | return nullptr; |
| 92 | return CreatePictureFromEncodedString(encoded); |
[email protected] | cb9118b3 | 2013-06-26 14:15:07 | [diff] [blame] | 93 | } |
| 94 | |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 95 | class PicturePlaybackController : public SkPicture::AbortCallback { |
| 96 | public: |
| 97 | PicturePlaybackController(const skia::BenchmarkingCanvas& canvas, |
| 98 | size_t count) |
| 99 | : canvas_(canvas), playback_count_(count) {} |
| 100 | |
| 101 | bool abort() override { return canvas_.CommandCount() > playback_count_; } |
| 102 | |
| 103 | private: |
| 104 | const skia::BenchmarkingCanvas& canvas_; |
| 105 | size_t playback_count_; |
| 106 | }; |
| 107 | |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 108 | } // namespace |
| 109 | |
| 110 | gin::WrapperInfo SkiaBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 111 | |
| 112 | // static |
lukasza | df18ba76 | 2017-06-09 22:24:30 | [diff] [blame] | 113 | void SkiaBenchmarking::Install(blink::WebLocalFrame* frame) { |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 114 | v8::Isolate* isolate = blink::MainThreadIsolate(); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 115 | v8::HandleScope handle_scope(isolate); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 116 | v8::Local<v8::Context> context = frame->MainWorldScriptContext(); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 117 | if (context.IsEmpty()) |
| 118 | return; |
| 119 | |
| 120 | v8::Context::Scope context_scope(context); |
| 121 | |
| 122 | gin::Handle<SkiaBenchmarking> controller = |
| 123 | gin::CreateHandle(isolate, new SkiaBenchmarking()); |
[email protected] | ad4d203 | 2014-04-28 13:50:59 | [diff] [blame] | 124 | if (controller.IsEmpty()) |
| 125 | return; |
| 126 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 127 | v8::Local<v8::Object> chrome = GetOrCreateChromeObject(isolate, |
kolczyk | e1b79c75 | 2014-10-01 10:06:56 | [diff] [blame] | 128 | context->Global()); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 129 | chrome->Set(gin::StringToV8(isolate, "skiaBenchmarking"), controller.ToV8()); |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 130 | } |
| 131 | |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 132 | // static |
| 133 | void SkiaBenchmarking::Initialize() { |
| 134 | DCHECK(RenderThreadImpl::current()); |
| 135 | // FIXME: remove this after Skia updates SkGraphics::Init() to be |
| 136 | // thread-safe and idempotent. |
| 137 | static bool skia_initialized = false; |
| 138 | if (!skia_initialized) { |
| 139 | LOG(WARNING) << "Enabling unsafe Skia benchmarking extension."; |
| 140 | SkGraphics::Init(); |
| 141 | skia_initialized = true; |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | SkiaBenchmarking::SkiaBenchmarking() { |
| 146 | Initialize(); |
| 147 | } |
| 148 | |
| 149 | SkiaBenchmarking::~SkiaBenchmarking() {} |
| 150 | |
| 151 | gin::ObjectTemplateBuilder SkiaBenchmarking::GetObjectTemplateBuilder( |
| 152 | v8::Isolate* isolate) { |
| 153 | return gin::Wrappable<SkiaBenchmarking>::GetObjectTemplateBuilder(isolate) |
| 154 | .SetMethod("rasterize", &SkiaBenchmarking::Rasterize) |
| 155 | .SetMethod("getOps", &SkiaBenchmarking::GetOps) |
| 156 | .SetMethod("getOpTimings", &SkiaBenchmarking::GetOpTimings) |
| 157 | .SetMethod("getInfo", &SkiaBenchmarking::GetInfo); |
| 158 | } |
| 159 | |
| 160 | void SkiaBenchmarking::Rasterize(gin::Arguments* args) { |
| 161 | v8::Isolate* isolate = args->isolate(); |
| 162 | if (args->PeekNext().IsEmpty()) |
| 163 | return; |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 164 | v8::Local<v8::Value> picture_handle; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 165 | args->GetNext(&picture_handle); |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 166 | std::unique_ptr<Picture> picture = ParsePictureHash(isolate, picture_handle); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 167 | if (!picture.get()) |
| 168 | return; |
| 169 | |
| 170 | double scale = 1.0; |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 171 | gfx::Rect clip_rect(picture->layer_rect); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 172 | int stop_index = -1; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 173 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 174 | v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 175 | if (!args->PeekNext().IsEmpty()) { |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 176 | v8::Local<v8::Value> params; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 177 | args->GetNext(¶ms); |
rdevlin.cronin | 694c605 | 2017-06-13 22:07:35 | [diff] [blame] | 178 | std::unique_ptr<base::Value> params_value = |
| 179 | content::V8ValueConverter::Create()->FromV8Value(params, context); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 180 | |
Ivan Kotenkov | 2c0d2bb3 | 2017-11-01 15:41:28 | [diff] [blame] | 181 | const base::DictionaryValue* params_dict = nullptr; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 182 | if (params_value.get() && params_value->GetAsDictionary(¶ms_dict)) { |
| 183 | params_dict->GetDouble("scale", &scale); |
| 184 | params_dict->GetInteger("stop", &stop_index); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 185 | |
Ivan Kotenkov | 2c0d2bb3 | 2017-11-01 15:41:28 | [diff] [blame] | 186 | const base::Value* clip_value = nullptr; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 187 | if (params_dict->Get("clip", &clip_value)) |
| 188 | cc::MathUtil::FromValue(clip_value, &clip_rect); |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 189 | } |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 190 | } |
| 191 | |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 192 | clip_rect.Intersect(picture->layer_rect); |
danakj | 4606f633 | 2015-08-31 23:56:56 | [diff] [blame] | 193 | gfx::Rect snapped_clip = gfx::ScaleToEnclosingRect(clip_rect, scale); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 194 | |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 195 | SkBitmap bitmap; |
reed | 2247b151d | 2014-09-05 16:26:47 | [diff] [blame] | 196 | if (!bitmap.tryAllocN32Pixels(snapped_clip.width(), snapped_clip.height())) |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 197 | return; |
| 198 | bitmap.eraseARGB(0, 0, 0, 0); |
| 199 | |
| 200 | SkCanvas canvas(bitmap); |
danakj | 4606f633 | 2015-08-31 23:56:56 | [diff] [blame] | 201 | canvas.translate(SkIntToScalar(-clip_rect.x()), |
| 202 | SkIntToScalar(-clip_rect.y())); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 203 | canvas.clipRect(gfx::RectToSkRect(snapped_clip)); |
| 204 | canvas.scale(scale, scale); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 205 | canvas.translate(picture->layer_rect.x(), picture->layer_rect.y()); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 206 | |
fmalita | 6ddebad | 2016-10-03 18:56:55 | [diff] [blame] | 207 | skia::BenchmarkingCanvas benchmarking_canvas(&canvas); |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 208 | size_t playback_count = |
| 209 | (stop_index < 0) ? std::numeric_limits<size_t>::max() : stop_index; |
| 210 | PicturePlaybackController controller(benchmarking_canvas, playback_count); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 211 | picture->picture->playback(&benchmarking_canvas, &controller); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 212 | |
| 213 | blink::WebArrayBuffer buffer = |
Mike Reed | 8eac88c4 | 2017-10-12 21:24:38 | [diff] [blame] | 214 | blink::WebArrayBuffer::Create(bitmap.computeByteSize(), 1); |
avi | 1023d01 | 2015-12-25 02:39:14 | [diff] [blame] | 215 | uint32_t* packed_pixels = reinterpret_cast<uint32_t*>(bitmap.getPixels()); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 216 | uint8_t* buffer_pixels = reinterpret_cast<uint8_t*>(buffer.Data()); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 217 | // Swizzle from native Skia format to RGBA as we copy out. |
Mike Reed | 8eac88c4 | 2017-10-12 21:24:38 | [diff] [blame] | 218 | for (size_t i = 0; i < bitmap.computeByteSize(); i += 4) { |
avi | 1023d01 | 2015-12-25 02:39:14 | [diff] [blame] | 219 | uint32_t c = packed_pixels[i >> 2]; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 220 | buffer_pixels[i] = SkGetPackedR32(c); |
| 221 | buffer_pixels[i + 1] = SkGetPackedG32(c); |
| 222 | buffer_pixels[i + 2] = SkGetPackedB32(c); |
| 223 | buffer_pixels[i + 3] = SkGetPackedA32(c); |
| 224 | } |
| 225 | |
jbroman | 5967a86 | 2017-04-27 16:52:45 | [diff] [blame] | 226 | args->Return(gin::DataObjectBuilder(isolate) |
| 227 | .Set("width", snapped_clip.width()) |
| 228 | .Set("height", snapped_clip.height()) |
| 229 | .Set("data", blink::WebArrayBufferConverter::ToV8Value( |
| 230 | &buffer, context->Global(), isolate)) |
| 231 | .Build()); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | void SkiaBenchmarking::GetOps(gin::Arguments* args) { |
| 235 | v8::Isolate* isolate = args->isolate(); |
| 236 | if (args->PeekNext().IsEmpty()) |
| 237 | return; |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 238 | v8::Local<v8::Value> picture_handle; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 239 | args->GetNext(&picture_handle); |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 240 | std::unique_ptr<Picture> picture = ParsePictureHash(isolate, picture_handle); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 241 | if (!picture.get()) |
| 242 | return; |
| 243 | |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 244 | SkCanvas canvas(picture->layer_rect.width(), picture->layer_rect.height()); |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 245 | skia::BenchmarkingCanvas benchmarking_canvas(&canvas); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 246 | picture->picture->playback(&benchmarking_canvas); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 247 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 248 | v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 249 | |
rdevlin.cronin | 694c605 | 2017-06-13 22:07:35 | [diff] [blame] | 250 | args->Return(content::V8ValueConverter::Create()->ToV8Value( |
| 251 | &benchmarking_canvas.Commands(), context)); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 252 | } |
| 253 | |
| 254 | void SkiaBenchmarking::GetOpTimings(gin::Arguments* args) { |
| 255 | v8::Isolate* isolate = args->isolate(); |
| 256 | if (args->PeekNext().IsEmpty()) |
| 257 | return; |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 258 | v8::Local<v8::Value> picture_handle; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 259 | args->GetNext(&picture_handle); |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 260 | std::unique_ptr<Picture> picture = ParsePictureHash(isolate, picture_handle); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 261 | if (!picture.get()) |
| 262 | return; |
| 263 | |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 264 | gfx::Rect bounds = picture->layer_rect; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 265 | |
| 266 | // Measure the total time by drawing straight into a bitmap-backed canvas. |
[email protected] | e758a237 | 2014-03-05 20:21:52 | [diff] [blame] | 267 | SkBitmap bitmap; |
| 268 | bitmap.allocN32Pixels(bounds.width(), bounds.height()); |
| 269 | SkCanvas bitmap_canvas(bitmap); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 270 | bitmap_canvas.clear(SK_ColorTRANSPARENT); |
charliea | 3be83970 | 2015-01-26 17:35:41 | [diff] [blame] | 271 | base::TimeTicks t0 = base::TimeTicks::Now(); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 272 | picture->picture->playback(&bitmap_canvas); |
charliea | 3be83970 | 2015-01-26 17:35:41 | [diff] [blame] | 273 | base::TimeDelta total_time = base::TimeTicks::Now() - t0; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 274 | |
| 275 | // Gather per-op timing info by drawing into a BenchmarkingCanvas. |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 276 | SkCanvas canvas(bitmap); |
| 277 | canvas.clear(SK_ColorTRANSPARENT); |
| 278 | skia::BenchmarkingCanvas benchmarking_canvas(&canvas); |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 279 | picture->picture->playback(&benchmarking_canvas); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 280 | |
| 281 | v8::Local<v8::Array> op_times = |
| 282 | v8::Array::New(isolate, benchmarking_canvas.CommandCount()); |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 283 | for (size_t i = 0; i < benchmarking_canvas.CommandCount(); ++i) { |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 284 | op_times->Set(i, v8::Number::New(isolate, benchmarking_canvas.GetTime(i))); |
fmalita | f5190e0 | 2015-02-26 15:48:42 | [diff] [blame] | 285 | } |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 286 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 287 | v8::Local<v8::Object> result = v8::Object::New(isolate); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 288 | result->Set(v8::String::NewFromUtf8(isolate, "total_time"), |
| 289 | v8::Number::New(isolate, total_time.InMillisecondsF())); |
| 290 | result->Set(v8::String::NewFromUtf8(isolate, "cmd_times"), op_times); |
| 291 | |
| 292 | args->Return(result); |
| 293 | } |
| 294 | |
| 295 | void SkiaBenchmarking::GetInfo(gin::Arguments* args) { |
| 296 | v8::Isolate* isolate = args->isolate(); |
| 297 | if (args->PeekNext().IsEmpty()) |
| 298 | return; |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 299 | v8::Local<v8::Value> picture_handle; |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 300 | args->GetNext(&picture_handle); |
dcheng | cedca561 | 2016-04-09 01:40:15 | [diff] [blame] | 301 | std::unique_ptr<Picture> picture = ParsePictureStr(isolate, picture_handle); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 302 | if (!picture.get()) |
| 303 | return; |
| 304 | |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 305 | v8::Local<v8::Object> result = v8::Object::New(isolate); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 306 | result->Set(v8::String::NewFromUtf8(isolate, "width"), |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 307 | v8::Number::New(isolate, picture->layer_rect.width())); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 308 | result->Set(v8::String::NewFromUtf8(isolate, "height"), |
vmpstr | e22c508 | 2015-09-24 20:57:54 | [diff] [blame] | 309 | v8::Number::New(isolate, picture->layer_rect.height())); |
[email protected] | cdb6b1e | 2014-01-23 00:06:49 | [diff] [blame] | 310 | |
| 311 | args->Return(result); |
[email protected] | a822825 | 2013-05-14 11:10:05 | [diff] [blame] | 312 | } |
| 313 | |
| 314 | } // namespace content |