| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/renderer/gpu/gpu_benchmarking_extension.h" | 5 #include "content/renderer/gpu/gpu_benchmarking_extension.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 12 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "cc/layers/layer.h" |
| 14 #include "content/common/browser_rendering_stats.h" | 15 #include "content/common/browser_rendering_stats.h" |
| 15 #include "content/common/gpu/gpu_rendering_stats.h" | 16 #include "content/common/gpu/gpu_rendering_stats.h" |
| 16 #include "content/public/renderer/render_thread.h" | 17 #include "content/public/renderer/render_thread.h" |
| 17 #include "content/renderer/gpu/render_widget_compositor.h" | 18 #include "content/renderer/gpu/render_widget_compositor.h" |
| 18 #include "content/renderer/render_view_impl.h" | 19 #include "content/renderer/render_view_impl.h" |
| 19 #include "content/renderer/skia_benchmarking_extension.h" | 20 #include "content/renderer/skia_benchmarking_extension.h" |
| 20 #include "third_party/WebKit/public/web/WebFrame.h" | 21 #include "third_party/WebKit/public/web/WebFrame.h" |
| 21 #include "third_party/WebKit/public/web/WebImageCache.h" | 22 #include "third_party/WebKit/public/web/WebImageCache.h" |
| 22 #include "third_party/WebKit/public/web/WebView.h" | 23 #include "third_party/WebKit/public/web/WebView.h" |
| 23 #include "third_party/WebKit/public/web/WebViewBenchmarkSupport.h" | |
| 24 #include "third_party/skia/include/core/SkData.h" | 24 #include "third_party/skia/include/core/SkData.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/SkPicture.h" |
| 27 #include "third_party/skia/include/core/SkPixelRef.h" | 27 #include "third_party/skia/include/core/SkPixelRef.h" |
| 28 #include "third_party/skia/include/core/SkStream.h" | 28 #include "third_party/skia/include/core/SkStream.h" |
| 29 #include "ui/gfx/codec/png_codec.h" | 29 #include "ui/gfx/codec/png_codec.h" |
| 30 #include "v8/include/v8.h" | 30 #include "v8/include/v8.h" |
| 31 #include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h" | 31 #include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h" |
| 32 | 32 |
| 33 using WebKit::WebCanvas; | 33 using WebKit::WebCanvas; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 52 } | 52 } |
| 53 std::vector<unsigned char> vector; | 53 std::vector<unsigned char> vector; |
| 54 if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) { | 54 if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) { |
| 55 return SkData::NewWithCopy(&vector.front() , vector.size()); | 55 return SkData::NewWithCopy(&vector.front() , vector.size()); |
| 56 } | 56 } |
| 57 return NULL; | 57 return NULL; |
| 58 } | 58 } |
| 59 | 59 |
| 60 namespace { | 60 namespace { |
| 61 | 61 |
| 62 class SkPictureRecorder : public WebViewBenchmarkSupport::PaintClient { | 62 class SkPictureSerializer { |
| 63 public: | 63 public: |
| 64 explicit SkPictureRecorder(const base::FilePath& dirpath) | 64 explicit SkPictureSerializer(const base::FilePath& dirpath) |
| 65 : dirpath_(dirpath), | 65 : dirpath_(dirpath), |
| 66 layer_id_(0) { | 66 layer_id_(0) { |
| 67 // Let skia register known effect subclasses. This basically enables | 67 // Let skia register known effect subclasses. This basically enables |
| 68 // reflection on those subclasses required for picture serialization. | 68 // reflection on those subclasses required for picture serialization. |
| 69 content::SkiaBenchmarkingExtension::InitSkGraphics(); | 69 content::SkiaBenchmarkingExtension::InitSkGraphics(); |
| 70 } | 70 } |
| 71 | 71 |
| 72 virtual WebCanvas* willPaint(const WebSize& size) { | 72 // Recursively serializes the layer tree. |
| 73 return picture_.beginRecording(size.width, size.height); | 73 // Each layer in the tree is serialized into a separate skp file |
| 74 } | 74 // in the given directory. |
| 75 void Serialize(const cc::Layer* layer) { |
| 76 // First serialize the children to avoid keeping too much stuff on stack. |
| 77 const cc::LayerList& children = layer->children(); |
| 78 for (size_t i = 0; i < children.size(); ++i) { |
| 79 Serialize(children[i].get()); |
| 80 } |
| 75 | 81 |
| 76 virtual void didPaint(WebCanvas* canvas) { | 82 skia::RefPtr<SkPicture> picture = layer->GetPicture(); |
| 77 DCHECK(canvas == picture_.getRecordingCanvas()); | 83 if (!picture) |
| 78 picture_.endRecording(); | 84 return; |
| 85 |
| 79 // Serialize picture to file. | 86 // Serialize picture to file. |
| 80 // TODO(alokp): Note that for this to work Chrome needs to be launched with | 87 // TODO(alokp): Note that for this to work Chrome needs to be launched with |
| 81 // --no-sandbox command-line flag. Get rid of this limitation. | 88 // --no-sandbox command-line flag. Get rid of this limitation. |
| 82 // CRBUG: 139640. | 89 // CRBUG: 139640. |
| 83 std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp"; | 90 std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp"; |
| 84 std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII(); | 91 std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII(); |
| 85 DCHECK(!filepath.empty()); | 92 DCHECK(!filepath.empty()); |
| 86 SkFILEWStream file(filepath.c_str()); | 93 SkFILEWStream file(filepath.c_str()); |
| 87 DCHECK(file.isValid()); | 94 DCHECK(file.isValid()); |
| 88 picture_.serialize(&file, &EncodeBitmapToData); | 95 picture->serialize(&file, &EncodeBitmapToData); |
| 89 } | 96 } |
| 90 | 97 |
| 91 private: | 98 private: |
| 92 base::FilePath dirpath_; | 99 base::FilePath dirpath_; |
| 93 int layer_id_; | 100 int layer_id_; |
| 94 SkPicture picture_; | |
| 95 }; | 101 }; |
| 96 | 102 |
| 97 class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator { | 103 class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator { |
| 98 public: | 104 public: |
| 99 RenderingStatsEnumerator(v8::Handle<v8::Object> stats_object) | 105 RenderingStatsEnumerator(v8::Handle<v8::Object> stats_object) |
| 100 : stats_object(stats_object) { } | 106 : stats_object(stats_object) { } |
| 101 | 107 |
| 102 virtual void AddInt64(const char* name, int64 value) OVERRIDE { | 108 virtual void AddInt64(const char* name, int64 value) OVERRIDE { |
| 103 stats_object->Set(v8::String::New(name), v8::Number::New(value)); | 109 stats_object->Set(v8::String::New(name), v8::Number::New(value)); |
| 104 } | 110 } |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 return; | 332 return; |
| 327 | 333 |
| 328 WebFrame* web_frame = WebFrame::frameForCurrentContext(); | 334 WebFrame* web_frame = WebFrame::frameForCurrentContext(); |
| 329 if (!web_frame) | 335 if (!web_frame) |
| 330 return; | 336 return; |
| 331 | 337 |
| 332 WebView* web_view = web_frame->view(); | 338 WebView* web_view = web_frame->view(); |
| 333 if (!web_view) | 339 if (!web_view) |
| 334 return; | 340 return; |
| 335 | 341 |
| 336 WebViewBenchmarkSupport* benchmark_support = web_view->benchmarkSupport(); | 342 RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view); |
| 337 if (!benchmark_support) | 343 if (!render_view_impl) |
| 344 return; |
| 345 |
| 346 RenderWidgetCompositor* compositor = render_view_impl->compositor(); |
| 347 if (!compositor) |
| 348 return; |
| 349 |
| 350 const cc::Layer* root_layer = compositor->GetRootLayer(); |
| 351 if (!root_layer) |
| 338 return; | 352 return; |
| 339 | 353 |
| 340 base::FilePath dirpath( | 354 base::FilePath dirpath( |
| 341 base::FilePath::StringType(*dirname, *dirname + dirname.length())); | 355 base::FilePath::StringType(*dirname, *dirname + dirname.length())); |
| 342 if (!file_util::CreateDirectory(dirpath) || | 356 if (!file_util::CreateDirectory(dirpath) || |
| 343 !base::PathIsWritable(dirpath)) { | 357 !base::PathIsWritable(dirpath)) { |
| 344 std::string msg("Path is not writable: "); | 358 std::string msg("Path is not writable: "); |
| 345 msg.append(dirpath.MaybeAsASCII()); | 359 msg.append(dirpath.MaybeAsASCII()); |
| 346 v8::ThrowException(v8::Exception::Error( | 360 v8::ThrowException(v8::Exception::Error( |
| 347 v8::String::New(msg.c_str(), msg.length()))); | 361 v8::String::New(msg.c_str(), msg.length()))); |
| 348 return; | 362 return; |
| 349 } | 363 } |
| 350 | 364 |
| 351 SkPictureRecorder recorder(dirpath); | 365 SkPictureSerializer serializer(dirpath); |
| 352 benchmark_support->paint(&recorder, | 366 serializer.Serialize(root_layer); |
| 353 WebViewBenchmarkSupport::PaintModeEverything); | |
| 354 } | 367 } |
| 355 | 368 |
| 356 static void OnSmoothScrollCompleted( | 369 static void OnSmoothScrollCompleted( |
| 357 CallbackAndContext* callback_and_context) { | 370 CallbackAndContext* callback_and_context) { |
| 358 v8::HandleScope scope(callback_and_context->isolate()); | 371 v8::HandleScope scope(callback_and_context->isolate()); |
| 359 v8::Handle<v8::Context> context = callback_and_context->GetContext(); | 372 v8::Handle<v8::Context> context = callback_and_context->GetContext(); |
| 360 v8::Context::Scope context_scope(context); | 373 v8::Context::Scope context_scope(context); |
| 361 WebFrame* frame = WebFrame::frameForContext(context); | 374 WebFrame* frame = WebFrame::frameForContext(context); |
| 362 if (frame) { | 375 if (frame) { |
| 363 frame->callFunctionEvenIfScriptDisabled( | 376 frame->callFunctionEvenIfScriptDisabled( |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 const v8::FunctionCallbackInfo<v8::Value>& args) { | 529 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 517 WebImageCache::clear(); | 530 WebImageCache::clear(); |
| 518 } | 531 } |
| 519 }; | 532 }; |
| 520 | 533 |
| 521 v8::Extension* GpuBenchmarkingExtension::Get() { | 534 v8::Extension* GpuBenchmarkingExtension::Get() { |
| 522 return new GpuBenchmarkingWrapper(); | 535 return new GpuBenchmarkingWrapper(); |
| 523 } | 536 } |
| 524 | 537 |
| 525 } // namespace content | 538 } // namespace content |
| OLD | NEW |