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/debug/trace_event_synthetic_delay.h" |
10 #include "base/file_util.h" | 11 #include "base/file_util.h" |
11 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
12 #include "base/memory/scoped_vector.h" | 13 #include "base/memory/scoped_vector.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "cc/layers/layer.h" | 15 #include "cc/layers/layer.h" |
15 #include "content/common/browser_rendering_stats.h" | 16 #include "content/common/browser_rendering_stats.h" |
16 #include "content/common/gpu/gpu_rendering_stats.h" | 17 #include "content/common/gpu/gpu_rendering_stats.h" |
17 #include "content/common/input/synthetic_gesture_params.h" | 18 #include "content/common/input/synthetic_gesture_params.h" |
18 #include "content/common/input/synthetic_pinch_gesture_params.h" | 19 #include "content/common/input/synthetic_pinch_gesture_params.h" |
19 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" | 20 #include "content/common/input/synthetic_smooth_scroll_gesture_params.h" |
| 21 #include "content/common/synthetic_delay_configuration.h" |
20 #include "content/public/renderer/render_thread.h" | 22 #include "content/public/renderer/render_thread.h" |
21 #include "content/public/renderer/v8_value_converter.h" | 23 #include "content/public/renderer/v8_value_converter.h" |
22 #include "content/renderer/gpu/render_widget_compositor.h" | 24 #include "content/renderer/gpu/render_widget_compositor.h" |
23 #include "content/renderer/render_thread_impl.h" | 25 #include "content/renderer/render_thread_impl.h" |
24 #include "content/renderer/render_view_impl.h" | 26 #include "content/renderer/render_view_impl.h" |
25 #include "content/renderer/skia_benchmarking_extension.h" | 27 #include "content/renderer/skia_benchmarking_extension.h" |
26 #include "third_party/WebKit/public/web/WebFrame.h" | 28 #include "third_party/WebKit/public/web/WebFrame.h" |
27 #include "third_party/WebKit/public/web/WebImageCache.h" | 29 #include "third_party/WebKit/public/web/WebImageCache.h" |
28 #include "third_party/WebKit/public/web/WebView.h" | 30 #include "third_party/WebKit/public/web/WebView.h" |
29 #include "third_party/skia/include/core/SkData.h" | 31 #include "third_party/skia/include/core/SkData.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 "};" | 326 "};" |
325 "chrome.gpuBenchmarking.runMicroBenchmark =" | 327 "chrome.gpuBenchmarking.runMicroBenchmark =" |
326 " function(name, callback, opt_arguments) {" | 328 " function(name, callback, opt_arguments) {" |
327 " arguments = opt_arguments || {};" | 329 " arguments = opt_arguments || {};" |
328 " native function RunMicroBenchmark();" | 330 " native function RunMicroBenchmark();" |
329 " return RunMicroBenchmark(name, callback, arguments);" | 331 " return RunMicroBenchmark(name, callback, arguments);" |
330 "};" | 332 "};" |
331 "chrome.gpuBenchmarking.hasGpuProcess = function() {" | 333 "chrome.gpuBenchmarking.hasGpuProcess = function() {" |
332 " native function HasGpuProcess();" | 334 " native function HasGpuProcess();" |
333 " return HasGpuProcess();" | 335 " return HasGpuProcess();" |
| 336 "};" |
| 337 "chrome.gpuBenchmarking.configureSyntheticDelays = " |
| 338 " function(delays, opt_callback) {" |
| 339 " callback = opt_callback || function() { };" |
| 340 " native function ConfigureSyntheticDelays();" |
| 341 " return ConfigureSyntheticDelays(delays, callback);" |
334 "};") {} | 342 "};") {} |
335 | 343 |
336 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( | 344 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
337 v8::Isolate* isolate, | 345 v8::Isolate* isolate, |
338 v8::Handle<v8::String> name) OVERRIDE { | 346 v8::Handle<v8::String> name) OVERRIDE { |
339 if (name->Equals( | 347 if (name->Equals( |
340 v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers"))) | 348 v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers"))) |
341 return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers); | 349 return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers); |
342 if (name->Equals( | 350 if (name->Equals( |
343 v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent"))) | 351 v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent"))) |
(...skipping 13 matching lines...) Expand all Loading... |
357 return v8::FunctionTemplate::New(isolate, BeginPinch); | 365 return v8::FunctionTemplate::New(isolate, BeginPinch); |
358 if (name->Equals( | 366 if (name->Equals( |
359 v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG"))) | 367 v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG"))) |
360 return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG); | 368 return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG); |
361 if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache"))) | 369 if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache"))) |
362 return v8::FunctionTemplate::New(isolate, ClearImageCache); | 370 return v8::FunctionTemplate::New(isolate, ClearImageCache); |
363 if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark"))) | 371 if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark"))) |
364 return v8::FunctionTemplate::New(isolate, RunMicroBenchmark); | 372 return v8::FunctionTemplate::New(isolate, RunMicroBenchmark); |
365 if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess"))) | 373 if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess"))) |
366 return v8::FunctionTemplate::New(isolate, HasGpuProcess); | 374 return v8::FunctionTemplate::New(isolate, HasGpuProcess); |
| 375 if (name->Equals(v8::String::New("ConfigureSyntheticDelays"))) |
| 376 return v8::FunctionTemplate::New(ConfigureSyntheticDelays); |
367 | 377 |
368 return v8::Handle<v8::FunctionTemplate>(); | 378 return v8::Handle<v8::FunctionTemplate>(); |
369 } | 379 } |
370 | 380 |
371 static void SetNeedsDisplayOnAllLayers( | 381 static void SetNeedsDisplayOnAllLayers( |
372 const v8::FunctionCallbackInfo<v8::Value>& args) { | 382 const v8::FunctionCallbackInfo<v8::Value>& args) { |
373 GpuBenchmarkingContext context; | 383 GpuBenchmarkingContext context; |
374 if (!context.Init(true)) | 384 if (!context.Init(true)) |
375 return; | 385 return; |
376 | 386 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 v8::HandleScope scope(callback_and_context->isolate()); | 476 v8::HandleScope scope(callback_and_context->isolate()); |
467 v8::Handle<v8::Context> context = callback_and_context->GetContext(); | 477 v8::Handle<v8::Context> context = callback_and_context->GetContext(); |
468 v8::Context::Scope context_scope(context); | 478 v8::Context::Scope context_scope(context); |
469 WebFrame* frame = WebFrame::frameForContext(context); | 479 WebFrame* frame = WebFrame::frameForContext(context); |
470 if (frame) { | 480 if (frame) { |
471 frame->callFunctionEvenIfScriptDisabled( | 481 frame->callFunctionEvenIfScriptDisabled( |
472 callback_and_context->GetCallback(), v8::Object::New(), 0, NULL); | 482 callback_and_context->GetCallback(), v8::Object::New(), 0, NULL); |
473 } | 483 } |
474 } | 484 } |
475 | 485 |
| 486 static void OnConfigureSyntheticDelayCompleted( |
| 487 CallbackAndContext* callback_and_context) { |
| 488 v8::HandleScope scope(callback_and_context->isolate()); |
| 489 v8::Handle<v8::Context> context = callback_and_context->GetContext(); |
| 490 v8::Context::Scope context_scope(context); |
| 491 WebFrame* frame = WebFrame::frameForContext(context); |
| 492 if (frame) { |
| 493 frame->callFunctionEvenIfScriptDisabled( |
| 494 callback_and_context->GetCallback(), v8::Object::New(), 0, NULL); |
| 495 } |
| 496 } |
| 497 |
476 static void SmoothScrollSendsTouch( | 498 static void SmoothScrollSendsTouch( |
477 const v8::FunctionCallbackInfo<v8::Value>& args) { | 499 const v8::FunctionCallbackInfo<v8::Value>& args) { |
478 // TODO(epenner): Should other platforms emulate touch events? | 500 // TODO(epenner): Should other platforms emulate touch events? |
479 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) | 501 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
480 args.GetReturnValue().Set(true); | 502 args.GetReturnValue().Set(true); |
481 #else | 503 #else |
482 args.GetReturnValue().Set(false); | 504 args.GetReturnValue().Set(false); |
483 #endif | 505 #endif |
484 } | 506 } |
485 | 507 |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark( | 752 args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark( |
731 std::string(*benchmark), | 753 std::string(*benchmark), |
732 value.Pass(), | 754 value.Pass(), |
733 base::Bind(&OnMicroBenchmarkCompleted, callback_and_context))); | 755 base::Bind(&OnMicroBenchmarkCompleted, callback_and_context))); |
734 } | 756 } |
735 | 757 |
736 static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) { | 758 static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) { |
737 GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel(); | 759 GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel(); |
738 args.GetReturnValue().Set(!!gpu_channel); | 760 args.GetReturnValue().Set(!!gpu_channel); |
739 } | 761 } |
| 762 |
| 763 static void ConfigureSyntheticDelays( |
| 764 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 765 GpuBenchmarkingContext context; |
| 766 if (!context.Init(false)) { |
| 767 args.GetReturnValue().Set(false); |
| 768 return; |
| 769 } |
| 770 |
| 771 if (args.Length() != 2 || |
| 772 !args[0]->IsObject() || |
| 773 !args[1]->IsObject()) { |
| 774 args.GetReturnValue().Set(false); |
| 775 return; |
| 776 } |
| 777 v8::Isolate* isolate = args.GetIsolate(); |
| 778 v8::Local<v8::Function> callback_local = |
| 779 v8::Local<v8::Function>::Cast(args[1]); |
| 780 v8::Handle<v8::String> duration_key( |
| 781 v8::String::NewFromUtf8(isolate, "target_duration")); |
| 782 v8::Handle<v8::String> mode_key(v8::String::NewFromUtf8(isolate, "mode")); |
| 783 |
| 784 std::vector<SyntheticDelayConfiguration> delay_configs; |
| 785 v8::Handle<v8::Object> delay_settings(args[0]->ToObject()); |
| 786 v8::Handle<v8::Array> delay_names(delay_settings->GetOwnPropertyNames()); |
| 787 for (size_t i = 0; i < delay_names->Length(); ++i) { |
| 788 v8::Handle<v8::Value> key(delay_names->Get(i)); |
| 789 if (!key->IsString()) { |
| 790 args.GetReturnValue().Set(false); |
| 791 return; |
| 792 } |
| 793 v8::String::Utf8Value name_utf8(key->ToString()); |
| 794 v8::Handle<v8::Value> settings_value = delay_settings->Get(key); |
| 795 if (!settings_value ->IsObject()) { |
| 796 args.GetReturnValue().Set(false); |
| 797 return; |
| 798 } |
| 799 |
| 800 v8::Handle<v8::Object> settings(settings_value->ToObject()); |
| 801 SyntheticDelayConfiguration delay_config; |
| 802 delay_config.name = std::string(*name_utf8); |
| 803 |
| 804 if (settings->HasOwnProperty(duration_key)) { |
| 805 v8::Handle<v8::Value> value = settings->Get(duration_key); |
| 806 if (!value->IsNumber()) { |
| 807 args.GetReturnValue().Set(false); |
| 808 return; |
| 809 } |
| 810 delay_config.target_duration = |
| 811 base::TimeDelta::FromMicroseconds(value->NumberValue() * 1e6); |
| 812 } |
| 813 if (settings->HasOwnProperty(mode_key)) { |
| 814 v8::Handle<v8::Value> value = settings->Get(mode_key); |
| 815 if (!value->IsString()) { |
| 816 args.GetReturnValue().Set(false); |
| 817 return; |
| 818 } |
| 819 v8::String::Utf8Value mode_utf8(value->ToString()); |
| 820 std::string mode(*mode_utf8); |
| 821 if (mode == "static") { |
| 822 delay_config.mode = |
| 823 static_cast<SyntheticDelayConfiguration::Mode>( |
| 824 content::SyntheticDelayConfiguration::STATIC); |
| 825 } else if (mode == "oneshot") { |
| 826 delay_config.mode = |
| 827 static_cast<SyntheticDelayConfiguration::Mode>( |
| 828 content::SyntheticDelayConfiguration::ONE_SHOT); |
| 829 } else if (mode == "alternating") { |
| 830 delay_config.mode = |
| 831 static_cast<SyntheticDelayConfiguration::Mode>( |
| 832 content::SyntheticDelayConfiguration::ALTERNATING); |
| 833 } else { |
| 834 args.GetReturnValue().Set(false); |
| 835 return; |
| 836 } |
| 837 } |
| 838 delay_configs.push_back(delay_config); |
| 839 } |
| 840 |
| 841 scoped_refptr<CallbackAndContext> callback_and_context = |
| 842 new CallbackAndContext(args.GetIsolate(), |
| 843 callback_local, |
| 844 context.web_frame()->mainWorldScriptContext()); |
| 845 context.render_view_impl()->ConfigureSyntheticDelays( |
| 846 delay_configs, |
| 847 base::Bind(&OnConfigureSyntheticDelayCompleted, |
| 848 callback_and_context)); |
| 849 args.GetReturnValue().Set(true); |
| 850 } |
740 }; | 851 }; |
741 | 852 |
742 v8::Extension* GpuBenchmarkingExtension::Get() { | 853 v8::Extension* GpuBenchmarkingExtension::Get() { |
743 return new GpuBenchmarkingWrapper(); | 854 return new GpuBenchmarkingWrapper(); |
744 } | 855 } |
745 | 856 |
746 } // namespace content | 857 } // namespace content |
OLD | NEW |