Index: content/renderer/gpu/gpu_benchmarking_extension.cc |
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc |
index 96c908eddfdfcf67ffe336c8addbe4ebb7a36dea..f0b1c57fdbd81804a5b1ce8f929448d6c612907a 100644 |
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc |
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc |
@@ -7,6 +7,7 @@ |
#include <string> |
#include "base/base64.h" |
+#include "base/debug/trace_event_synthetic_delay.h" |
#include "base/file_util.h" |
#include "base/files/file_path.h" |
#include "base/memory/scoped_vector.h" |
@@ -17,6 +18,7 @@ |
#include "content/common/input/synthetic_gesture_params.h" |
#include "content/common/input/synthetic_pinch_gesture_params.h" |
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h" |
+#include "content/common/synthetic_delay_configuration.h" |
#include "content/public/renderer/render_thread.h" |
#include "content/public/renderer/v8_value_converter.h" |
#include "content/renderer/gpu/render_widget_compositor.h" |
@@ -331,6 +333,12 @@ class GpuBenchmarkingWrapper : public v8::Extension { |
"chrome.gpuBenchmarking.hasGpuProcess = function() {" |
" native function HasGpuProcess();" |
" return HasGpuProcess();" |
+ "};" |
+ "chrome.gpuBenchmarking.configureSyntheticDelays = " |
+ " function(delays, opt_callback) {" |
+ " callback = opt_callback || function() { };" |
+ " native function ConfigureSyntheticDelays();" |
+ " return ConfigureSyntheticDelays(delays, callback);" |
"};") {} |
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
@@ -364,6 +372,8 @@ class GpuBenchmarkingWrapper : public v8::Extension { |
return v8::FunctionTemplate::New(isolate, RunMicroBenchmark); |
if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess"))) |
return v8::FunctionTemplate::New(isolate, HasGpuProcess); |
+ if (name->Equals(v8::String::New("ConfigureSyntheticDelays"))) |
+ return v8::FunctionTemplate::New(ConfigureSyntheticDelays); |
return v8::Handle<v8::FunctionTemplate>(); |
} |
@@ -473,6 +483,18 @@ class GpuBenchmarkingWrapper : public v8::Extension { |
} |
} |
+ static void OnConfigureSyntheticDelayCompleted( |
+ CallbackAndContext* callback_and_context) { |
+ v8::HandleScope scope(callback_and_context->isolate()); |
+ v8::Handle<v8::Context> context = callback_and_context->GetContext(); |
+ v8::Context::Scope context_scope(context); |
+ WebFrame* frame = WebFrame::frameForContext(context); |
+ if (frame) { |
+ frame->callFunctionEvenIfScriptDisabled( |
+ callback_and_context->GetCallback(), v8::Object::New(), 0, NULL); |
+ } |
+ } |
+ |
static void SmoothScrollSendsTouch( |
const v8::FunctionCallbackInfo<v8::Value>& args) { |
// TODO(epenner): Should other platforms emulate touch events? |
@@ -737,6 +759,95 @@ class GpuBenchmarkingWrapper : public v8::Extension { |
GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel(); |
args.GetReturnValue().Set(!!gpu_channel); |
} |
+ |
+ static void ConfigureSyntheticDelays( |
+ const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ GpuBenchmarkingContext context; |
+ if (!context.Init(false)) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ |
+ if (args.Length() != 2 || |
+ !args[0]->IsObject() || |
+ !args[1]->IsObject()) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ v8::Isolate* isolate = args.GetIsolate(); |
+ v8::Local<v8::Function> callback_local = |
+ v8::Local<v8::Function>::Cast(args[1]); |
+ v8::Handle<v8::String> duration_key( |
+ v8::String::NewFromUtf8(isolate, "target_duration")); |
+ v8::Handle<v8::String> mode_key(v8::String::NewFromUtf8(isolate, "mode")); |
+ |
+ std::vector<SyntheticDelayConfiguration> delay_configs; |
+ v8::Handle<v8::Object> delay_settings(args[0]->ToObject()); |
+ v8::Handle<v8::Array> delay_names(delay_settings->GetOwnPropertyNames()); |
+ for (size_t i = 0; i < delay_names->Length(); ++i) { |
+ v8::Handle<v8::Value> key(delay_names->Get(i)); |
+ if (!key->IsString()) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ v8::String::Utf8Value name_utf8(key->ToString()); |
+ v8::Handle<v8::Value> settings_value = delay_settings->Get(key); |
+ if (!settings_value ->IsObject()) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ |
+ v8::Handle<v8::Object> settings(settings_value->ToObject()); |
+ SyntheticDelayConfiguration delay_config; |
+ delay_config.name = std::string(*name_utf8); |
+ |
+ if (settings->HasOwnProperty(duration_key)) { |
+ v8::Handle<v8::Value> value = settings->Get(duration_key); |
+ if (!value->IsNumber()) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ delay_config.target_duration = |
+ base::TimeDelta::FromMicroseconds(value->NumberValue() * 1e6); |
+ } |
+ if (settings->HasOwnProperty(mode_key)) { |
+ v8::Handle<v8::Value> value = settings->Get(mode_key); |
+ if (!value->IsString()) { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ v8::String::Utf8Value mode_utf8(value->ToString()); |
+ std::string mode(*mode_utf8); |
+ if (mode == "static") { |
+ delay_config.mode = |
+ static_cast<SyntheticDelayConfiguration::Mode>( |
+ content::SyntheticDelayConfiguration::STATIC); |
+ } else if (mode == "oneshot") { |
+ delay_config.mode = |
+ static_cast<SyntheticDelayConfiguration::Mode>( |
+ content::SyntheticDelayConfiguration::ONE_SHOT); |
+ } else if (mode == "alternating") { |
+ delay_config.mode = |
+ static_cast<SyntheticDelayConfiguration::Mode>( |
+ content::SyntheticDelayConfiguration::ALTERNATING); |
+ } else { |
+ args.GetReturnValue().Set(false); |
+ return; |
+ } |
+ } |
+ delay_configs.push_back(delay_config); |
+ } |
+ |
+ scoped_refptr<CallbackAndContext> callback_and_context = |
+ new CallbackAndContext(args.GetIsolate(), |
+ callback_local, |
+ context.web_frame()->mainWorldScriptContext()); |
+ context.render_view_impl()->ConfigureSyntheticDelays( |
+ delay_configs, |
+ base::Bind(&OnConfigureSyntheticDelayCompleted, |
+ callback_and_context)); |
+ args.GetReturnValue().Set(true); |
+ } |
}; |
v8::Extension* GpuBenchmarkingExtension::Get() { |