| 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 dfc4abd1734dd0c12ab5122b1e01fd9d0b0526dc..f57a9a781e4249a938f854e04aa17efa6785074a 100644
|
| --- a/content/renderer/gpu/gpu_benchmarking_extension.cc
|
| +++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
|
| @@ -18,11 +18,16 @@
|
| #include "content/common/input/synthetic_tap_gesture_params.h"
|
| #include "content/public/renderer/render_thread.h"
|
| #include "content/public/renderer/v8_value_converter.h"
|
| +#include "content/renderer/chrome_object_extensions_utils.h"
|
| #include "content/renderer/gpu/render_widget_compositor.h"
|
| #include "content/renderer/render_thread_impl.h"
|
| #include "content/renderer/render_view_impl.h"
|
| #include "content/renderer/skia_benchmarking_extension.h"
|
| +#include "gin/arguments.h"
|
| +#include "gin/handle.h"
|
| +#include "gin/object_template_builder.h"
|
| #include "third_party/WebKit/public/web/WebImageCache.h"
|
| +#include "third_party/WebKit/public/web/WebKit.h"
|
| #include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| #include "third_party/WebKit/public/web/WebView.h"
|
| #include "third_party/skia/include/core/SkData.h"
|
| @@ -40,26 +45,26 @@ using blink::WebPrivatePtr;
|
| using blink::WebSize;
|
| using blink::WebView;
|
|
|
| -const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
|
| +namespace content {
|
| +
|
| +namespace {
|
|
|
| // offset parameter is deprecated/ignored, and will be remove from the
|
| // signature in a future skia release. <reed@google.com>
|
| -static SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
|
| - SkPixelRef* pr = bm.pixelRef();
|
| - if (pr != NULL) {
|
| - SkData* data = pr->refEncodedData();
|
| - if (data != NULL)
|
| - return data;
|
| - }
|
| - std::vector<unsigned char> vector;
|
| - if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
|
| - return SkData::NewWithCopy(&vector.front() , vector.size());
|
| - }
|
| - return NULL;
|
| +SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
|
| + SkPixelRef* pr = bm.pixelRef();
|
| + if (pr != NULL) {
|
| + SkData* data = pr->refEncodedData();
|
| + if (data != NULL)
|
| + return data;
|
| + }
|
| + std::vector<unsigned char> vector;
|
| + if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
|
| + return SkData::NewWithCopy(&vector.front(), vector.size());
|
| + }
|
| + return NULL;
|
| }
|
|
|
| -namespace {
|
| -
|
| class SkPictureSerializer {
|
| public:
|
| explicit SkPictureSerializer(const base::FilePath& dirpath)
|
| @@ -67,7 +72,7 @@ class SkPictureSerializer {
|
| layer_id_(0) {
|
| // Let skia register known effect subclasses. This basically enables
|
| // reflection on those subclasses required for picture serialization.
|
| - content::SkiaBenchmarking::Initialize();
|
| + SkiaBenchmarking::Initialize();
|
| }
|
|
|
| // Recursively serializes the layer tree.
|
| @@ -100,11 +105,33 @@ class SkPictureSerializer {
|
| int layer_id_;
|
| };
|
|
|
| -} // namespace
|
| +template <typename T>
|
| +bool GetArg(gin::Arguments* args, T* value) {
|
| + if (!args->GetNext(value)) {
|
| + args->ThrowError();
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
|
|
| -namespace content {
|
| +template <>
|
| +bool GetArg(gin::Arguments* args, int* value) {
|
| + float number;
|
| + bool ret = GetArg(args, &number);
|
| + *value = number;
|
| + return ret;
|
| +}
|
|
|
| -namespace {
|
| +template <typename T>
|
| +bool GetOptionalArg(gin::Arguments* args, T* value) {
|
| + if (args->PeekNext().IsEmpty())
|
| + return true;
|
| + if (args->PeekNext()->IsUndefined()) {
|
| + args->Skip();
|
| + return true;
|
| + }
|
| + return GetArg(args, value);
|
| +}
|
|
|
| class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
|
| public:
|
| @@ -208,716 +235,576 @@ class GpuBenchmarkingContext {
|
| DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
|
| };
|
|
|
| -} // namespace
|
| +void OnMicroBenchmarkCompleted(
|
| + CallbackAndContext* callback_and_context,
|
| + scoped_ptr<base::Value> result) {
|
| + v8::Isolate* isolate = callback_and_context->isolate();
|
| + v8::HandleScope scope(isolate);
|
| + v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| + v8::Context::Scope context_scope(context);
|
| + WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| + if (frame) {
|
| + scoped_ptr<V8ValueConverter> converter =
|
| + make_scoped_ptr(V8ValueConverter::create());
|
| + v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
|
| + v8::Handle<v8::Value> argv[] = { value };
|
| +
|
| + frame->callFunctionEvenIfScriptDisabled(
|
| + callback_and_context->GetCallback(),
|
| + v8::Object::New(isolate),
|
| + 1,
|
| + argv);
|
| + }
|
| +}
|
|
|
| -class GpuBenchmarkingWrapper : public v8::Extension {
|
| - public:
|
| - GpuBenchmarkingWrapper() :
|
| - v8::Extension(kGpuBenchmarkingExtensionName,
|
| - "if (typeof(chrome) == 'undefined') {"
|
| - " chrome = {};"
|
| - "};"
|
| - "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
|
| - " chrome.gpuBenchmarking = {};"
|
| - "};"
|
| - "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
|
| - " native function SetNeedsDisplayOnAllLayers();"
|
| - " return SetNeedsDisplayOnAllLayers();"
|
| - "};"
|
| - "chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent = "
|
| - "function() {"
|
| - " native function SetRasterizeOnlyVisibleContent();"
|
| - " return SetRasterizeOnlyVisibleContent();"
|
| - "};"
|
| - "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
|
| - " native function PrintToSkPicture();"
|
| - " return PrintToSkPicture(dirname);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.DEFAULT_INPUT = 0;"
|
| - "chrome.gpuBenchmarking.TOUCH_INPUT = 1;"
|
| - "chrome.gpuBenchmarking.MOUSE_INPUT = 2;"
|
| - "chrome.gpuBenchmarking.gestureSourceTypeSupported = "
|
| - " function(gesture_source_type) {"
|
| - " native function GestureSourceTypeSupported();"
|
| - " return GestureSourceTypeSupported(gesture_source_type);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.smoothScrollBy = "
|
| - " function(pixels_to_scroll, opt_callback, opt_start_x,"
|
| - " opt_start_y, opt_gesture_source_type,"
|
| - " opt_direction, opt_speed_in_pixels_s) {"
|
| - " pixels_to_scroll = pixels_to_scroll || 0;"
|
| - " callback = opt_callback || function() { };"
|
| - " gesture_source_type = opt_gesture_source_type ||"
|
| - " chrome.gpuBenchmarking.DEFAULT_INPUT;"
|
| - " direction = opt_direction || 'down';"
|
| - " speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
|
| - " native function BeginSmoothScroll();"
|
| - " return BeginSmoothScroll(pixels_to_scroll, callback,"
|
| - " gesture_source_type, direction,"
|
| - " speed_in_pixels_s, true,"
|
| - " opt_start_x, opt_start_y);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.swipe = "
|
| - " function(direction, distance, opt_callback,"
|
| - " opt_start_x, opt_start_y,"
|
| - " opt_speed_in_pixels_s) {"
|
| - " direction = direction || 'up';"
|
| - " distance = distance || 0;"
|
| - " callback = opt_callback || function() { };"
|
| - " speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
|
| - " native function BeginSmoothScroll();"
|
| - " return BeginSmoothScroll(-distance, callback,"
|
| - " chrome.gpuBenchmarking.TOUCH_INPUT,"
|
| - " direction, speed_in_pixels_s, false,"
|
| - " opt_start_x, opt_start_y);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.scrollBounce = "
|
| - " function(direction, distance, overscroll, opt_repeat_count,"
|
| - " opt_callback, opt_start_x, opt_start_y,"
|
| - " opt_speed_in_pixels_s) {"
|
| - " direction = direction || 'down';"
|
| - " distance = distance || 0;"
|
| - " overscroll = overscroll || 0;"
|
| - " repeat_count = opt_repeat_count || 1;"
|
| - " callback = opt_callback || function() { };"
|
| - " speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
|
| - " native function BeginScrollBounce();"
|
| - " return BeginScrollBounce(direction, distance, overscroll,"
|
| - " repeat_count, callback,"
|
| - " speed_in_pixels_s,"
|
| - " opt_start_x, opt_start_y);"
|
| - "};"
|
| - // TODO(dominikg): Remove once JS interface changes have rolled into
|
| - // stable.
|
| - "chrome.gpuBenchmarking.newPinchInterface = true;"
|
| - "chrome.gpuBenchmarking.pinchBy = "
|
| - " function(scale_factor, anchor_x, anchor_y,"
|
| - " opt_callback, "
|
| - "opt_relative_pointer_speed_in_pixels_s) {"
|
| - " callback = opt_callback || function() { };"
|
| - " relative_pointer_speed_in_pixels_s ="
|
| - " opt_relative_pointer_speed_in_pixels_s || 800;"
|
| - " native function BeginPinch();"
|
| - " return BeginPinch(scale_factor, anchor_x, anchor_y, callback,"
|
| - " relative_pointer_speed_in_pixels_s);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.tap = "
|
| - " function(position_x, position_y, opt_callback, "
|
| - "opt_duration_ms,"
|
| - " opt_gesture_source_type) {"
|
| - " callback = opt_callback || function() { };"
|
| - " duration_ms = opt_duration_ms || 50;"
|
| - " gesture_source_type = opt_gesture_source_type ||"
|
| - " chrome.gpuBenchmarking.DEFAULT_INPUT;"
|
| - " native function BeginTap();"
|
| - " return BeginTap(position_x, position_y, callback, duration_ms,"
|
| - " gesture_source_type);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.beginWindowSnapshotPNG = "
|
| - "function(callback) {"
|
| - " native function BeginWindowSnapshotPNG();"
|
| - " BeginWindowSnapshotPNG(callback);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.clearImageCache = function() {"
|
| - " native function ClearImageCache();"
|
| - " ClearImageCache();"
|
| - "};"
|
| - "chrome.gpuBenchmarking.runMicroBenchmark ="
|
| - " function(name, callback, opt_arguments) {"
|
| - " arguments = opt_arguments || {};"
|
| - " native function RunMicroBenchmark();"
|
| - " return RunMicroBenchmark(name, callback, arguments);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.sendMessageToMicroBenchmark ="
|
| - " function(id, arguments) {"
|
| - " native function SendMessageToMicroBenchmark();"
|
| - " return SendMessageToMicroBenchmark(id, arguments);"
|
| - "};"
|
| - "chrome.gpuBenchmarking.hasGpuProcess = function() {"
|
| - " native function HasGpuProcess();"
|
| - " return HasGpuProcess();"
|
| - "};") {}
|
| -
|
| - v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
|
| - v8::Isolate* isolate,
|
| - v8::Handle<v8::String> name) override {
|
| - if (name->Equals(
|
| - v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers")))
|
| - return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers);
|
| - if (name->Equals(
|
| - v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent")))
|
| - return v8::FunctionTemplate::New(isolate, SetRasterizeOnlyVisibleContent);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "PrintToSkPicture")))
|
| - return v8::FunctionTemplate::New(isolate, PrintToSkPicture);
|
| - if (name->Equals(
|
| - v8::String::NewFromUtf8(isolate, "GestureSourceTypeSupported")))
|
| - return v8::FunctionTemplate::New(isolate, GestureSourceTypeSupported);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginSmoothScroll")))
|
| - return v8::FunctionTemplate::New(isolate, BeginSmoothScroll);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginScrollBounce")))
|
| - return v8::FunctionTemplate::New(isolate, BeginScrollBounce);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginPinch")))
|
| - return v8::FunctionTemplate::New(isolate, BeginPinch);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginTap")))
|
| - return v8::FunctionTemplate::New(isolate, BeginTap);
|
| - if (name->Equals(
|
| - v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG")))
|
| - return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache")))
|
| - return v8::FunctionTemplate::New(isolate, ClearImageCache);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark")))
|
| - return v8::FunctionTemplate::New(isolate, RunMicroBenchmark);
|
| - if (name->Equals(
|
| - v8::String::NewFromUtf8(isolate, "SendMessageToMicroBenchmark")))
|
| - return v8::FunctionTemplate::New(isolate, SendMessageToMicroBenchmark);
|
| - if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess")))
|
| - return v8::FunctionTemplate::New(isolate, HasGpuProcess);
|
| -
|
| - return v8::Handle<v8::FunctionTemplate>();
|
| - }
|
| -
|
| - static void SetNeedsDisplayOnAllLayers(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(true))
|
| - return;
|
| +void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
|
| + const gfx::Size& size,
|
| + const std::vector<unsigned char>& png) {
|
| + v8::Isolate* isolate = callback_and_context->isolate();
|
| + v8::HandleScope scope(isolate);
|
| + v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| + v8::Context::Scope context_scope(context);
|
| + WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| + if (frame) {
|
| + v8::Handle<v8::Value> result;
|
| +
|
| + if (!size.IsEmpty()) {
|
| + v8::Handle<v8::Object> result_object;
|
| + result_object = v8::Object::New(isolate);
|
| +
|
| + result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
|
| + v8::Number::New(isolate, size.width()));
|
| + result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
|
| + v8::Number::New(isolate, size.height()));
|
| +
|
| + std::string base64_png;
|
| + base::Base64Encode(
|
| + base::StringPiece(reinterpret_cast<const char*>(&*png.begin()),
|
| + png.size()),
|
| + &base64_png);
|
| +
|
| + result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
|
| + v8::String::NewFromUtf8(isolate,
|
| + base64_png.c_str(),
|
| + v8::String::kNormalString,
|
| + base64_png.size()));
|
| +
|
| + result = result_object;
|
| + } else {
|
| + result = v8::Null(isolate);
|
| + }
|
|
|
| - context.compositor()->SetNeedsDisplayOnAllLayers();
|
| + v8::Handle<v8::Value> argv[] = {result};
|
| +
|
| + frame->callFunctionEvenIfScriptDisabled(
|
| + callback_and_context->GetCallback(), v8::Object::New(isolate), 1, argv);
|
| }
|
| +}
|
|
|
| - static void SetRasterizeOnlyVisibleContent(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(true))
|
| - return;
|
| +void OnSyntheticGestureCompleted(CallbackAndContext* callback_and_context) {
|
| + v8::Isolate* isolate = callback_and_context->isolate();
|
| + v8::HandleScope scope(isolate);
|
| + v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| + v8::Context::Scope context_scope(context);
|
| + WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| + if (frame) {
|
| + frame->callFunctionEvenIfScriptDisabled(
|
| + callback_and_context->GetCallback(), v8::Object::New(isolate), 0, NULL);
|
| + }
|
| +}
|
|
|
| - context.compositor()->SetRasterizeOnlyVisibleContent();
|
| +bool BeginSmoothScroll(v8::Isolate* isolate,
|
| + int pixels_to_scroll,
|
| + v8::Handle<v8::Function> callback,
|
| + int gesture_source_type,
|
| + const std::string& direction,
|
| + int speed_in_pixels_s,
|
| + bool prevent_fling,
|
| + int start_x,
|
| + int start_y) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(false))
|
| + return false;
|
| +
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(
|
| + isolate, callback, context.web_frame()->mainWorldScriptContext());
|
| +
|
| + scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
|
| + new SyntheticSmoothScrollGestureParams);
|
| +
|
| + // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
| +
|
| + if (gesture_source_type < 0 ||
|
| + gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| + return false;
|
| + }
|
| + gesture_params->gesture_source_type =
|
| + static_cast<SyntheticGestureParams::GestureSourceType>(
|
| + gesture_source_type);
|
| +
|
| + gesture_params->speed_in_pixels_s = speed_in_pixels_s;
|
| + gesture_params->prevent_fling = prevent_fling;
|
| +
|
| + gesture_params->anchor.SetPoint(start_x * page_scale_factor,
|
| + start_y * page_scale_factor);
|
| +
|
| + int distance_length = pixels_to_scroll * page_scale_factor;
|
| + gfx::Vector2d distance;
|
| + if (direction == "down")
|
| + distance.set_y(-distance_length);
|
| + else if (direction == "up")
|
| + distance.set_y(distance_length);
|
| + else if (direction == "right")
|
| + distance.set_x(-distance_length);
|
| + else if (direction == "left")
|
| + distance.set_x(distance_length);
|
| + else {
|
| + return false;
|
| }
|
| + gesture_params->distances.push_back(distance);
|
|
|
| - static void PrintToSkPicture(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 1)
|
| - return;
|
| + // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| + // progress, we will leak the callback and context. This needs to be fixed,
|
| + // somehow.
|
| + context.render_view_impl()->QueueSyntheticGesture(
|
| + gesture_params.Pass(),
|
| + base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
|
|
| - v8::String::Utf8Value dirname(args[0]);
|
| - if (dirname.length() == 0)
|
| - return;
|
| + return true;
|
| +}
|
|
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(true))
|
| - return;
|
| +} // namespace
|
|
|
| - const cc::Layer* root_layer = context.compositor()->GetRootLayer();
|
| - if (!root_layer)
|
| - return;
|
| +gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin};
|
|
|
| - base::FilePath dirpath(
|
| - base::FilePath::StringType(*dirname, *dirname + dirname.length()));
|
| - if (!base::CreateDirectory(dirpath) ||
|
| - !base::PathIsWritable(dirpath)) {
|
| - std::string msg("Path is not writable: ");
|
| - msg.append(dirpath.MaybeAsASCII());
|
| - v8::Isolate* isolate = args.GetIsolate();
|
| - isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
|
| - isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
|
| - return;
|
| - }
|
| +// static
|
| +void GpuBenchmarking::Install(blink::WebFrame* frame) {
|
| + v8::Isolate* isolate = blink::mainThreadIsolate();
|
| + v8::HandleScope handle_scope(isolate);
|
| + v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
|
| + if (context.IsEmpty())
|
| + return;
|
|
|
| - SkPictureSerializer serializer(dirpath);
|
| - serializer.Serialize(root_layer);
|
| - }
|
| -
|
| - static void OnSyntheticGestureCompleted(
|
| - CallbackAndContext* callback_and_context) {
|
| - v8::Isolate* isolate = callback_and_context->isolate();
|
| - v8::HandleScope scope(isolate);
|
| - v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| - v8::Context::Scope context_scope(context);
|
| - WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| - if (frame) {
|
| - frame->callFunctionEvenIfScriptDisabled(
|
| - callback_and_context->GetCallback(),
|
| - v8::Object::New(isolate),
|
| - 0,
|
| - NULL);
|
| - }
|
| - }
|
| + v8::Context::Scope context_scope(context);
|
|
|
| - static void GestureSourceTypeSupported(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - if (args.Length() != 1 || !args[0]->IsNumber()) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| + gin::Handle<GpuBenchmarking> controller =
|
| + gin::CreateHandle(isolate, new GpuBenchmarking());
|
| + if (controller.IsEmpty())
|
| + return;
|
|
|
| - int gesture_source_type = args[0]->IntegerValue();
|
| - if (gesture_source_type < 0 ||
|
| - gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| + v8::Handle<v8::Object> chrome = GetOrCreateChromeObject(isolate,
|
| + context->Global());
|
| + chrome->Set(gin::StringToV8(isolate, "gpuBenchmarking"), controller.ToV8());
|
| +}
|
|
|
| - bool is_supported = SyntheticGestureParams::IsGestureSourceTypeSupported(
|
| - static_cast<SyntheticGestureParams::GestureSourceType>(
|
| - gesture_source_type));
|
| - args.GetReturnValue().Set(is_supported);
|
| - }
|
| +GpuBenchmarking::GpuBenchmarking() {
|
| +}
|
|
|
| - static void BeginSmoothScroll(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(false))
|
| - return;
|
| +GpuBenchmarking::~GpuBenchmarking() {
|
| +}
|
|
|
| - // The last two arguments can be undefined. We check their validity later.
|
| - int arglen = args.Length();
|
| - if (arglen < 8 ||
|
| - !args[0]->IsNumber() ||
|
| - !args[1]->IsFunction() ||
|
| - !args[2]->IsNumber() ||
|
| - !args[3]->IsString() ||
|
| - !args[4]->IsNumber() ||
|
| - !args[5]->IsBoolean()) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| +gin::ObjectTemplateBuilder GpuBenchmarking::GetObjectTemplateBuilder(
|
| + v8::Isolate* isolate) {
|
| + return gin::Wrappable<GpuBenchmarking>::GetObjectTemplateBuilder(isolate)
|
| + .SetMethod("setNeedsDisplayOnAllLayers",
|
| + &GpuBenchmarking::SetNeedsDisplayOnAllLayers)
|
| + .SetMethod("setRasterizeOnlyVisibleContent",
|
| + &GpuBenchmarking::SetRasterizeOnlyVisibleContent)
|
| + .SetMethod("printToSkPicture", &GpuBenchmarking::PrintToSkPicture)
|
| + .SetValue("DEFAULT_INPUT", 0)
|
| + .SetValue("TOUCH_INPUT", 1)
|
| + .SetValue("MOUSE_INPUT", 2)
|
| + .SetMethod("gestureSourceTypeSupported",
|
| + &GpuBenchmarking::GestureSourceTypeSupported)
|
| + .SetMethod("smoothScrollBy", &GpuBenchmarking::SmoothScrollBy)
|
| + .SetMethod("swipe", &GpuBenchmarking::Swipe)
|
| + .SetMethod("scrollBounce", &GpuBenchmarking::ScrollBounce)
|
| + // TODO(dominikg): Remove once JS interface changes have rolled into
|
| + // stable.
|
| + .SetValue("newPinchInterface", true)
|
| + .SetMethod("pinchBy", &GpuBenchmarking::PinchBy)
|
| + .SetMethod("tap", &GpuBenchmarking::Tap)
|
| + .SetMethod("beginWindowSnapshotPNG",
|
| + &GpuBenchmarking::BeginWindowSnapshotPNG)
|
| + .SetMethod("clearImageCache", &GpuBenchmarking::ClearImageCache)
|
| + .SetMethod("runMicroBenchmark", &GpuBenchmarking::RunMicroBenchmark)
|
| + .SetMethod("sendMessageToMicroBenchmark",
|
| + &GpuBenchmarking::SendMessageToMicroBenchmark)
|
| + .SetMethod("hasGpuProcess", &GpuBenchmarking::HasGpuProcess);
|
| +}
|
|
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[1]);
|
| +void GpuBenchmarking::SetNeedsDisplayOnAllLayers() {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return;
|
|
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
| + context.compositor()->SetNeedsDisplayOnAllLayers();
|
| +}
|
|
|
| - scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
|
| - new SyntheticSmoothScrollGestureParams);
|
| +void GpuBenchmarking::SetRasterizeOnlyVisibleContent() {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return;
|
|
|
| - // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| - float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + context.compositor()->SetRasterizeOnlyVisibleContent();
|
| +}
|
|
|
| - int gesture_source_type = args[2]->IntegerValue();
|
| - if (gesture_source_type < 0 ||
|
| - gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| - gesture_params->gesture_source_type =
|
| - static_cast<SyntheticGestureParams::GestureSourceType>(
|
| - gesture_source_type);
|
| -
|
| - gesture_params->speed_in_pixels_s = args[4]->IntegerValue();
|
| - gesture_params->prevent_fling = args[5]->BooleanValue();
|
| -
|
| - // Account for the 2 optional arguments, start_x and start_y.
|
| - gfx::Point anchor;
|
| - if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
|
| - blink::WebRect rect = context.render_view_impl()->windowRect();
|
| - anchor.SetPoint(rect.width / 2, rect.height / 2);
|
| - } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
|
| - anchor.SetPoint(args[6]->IntegerValue() * page_scale_factor,
|
| - args[7]->IntegerValue() * page_scale_factor);
|
| - } else {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| - gesture_params->anchor = anchor;
|
| -
|
| - int distance_length = args[0]->IntegerValue() * page_scale_factor;
|
| - gfx::Vector2d distance;
|
| - v8::String::Utf8Value direction(args[3]);
|
| - DCHECK(*direction);
|
| - std::string direction_str(*direction);
|
| - if (direction_str == "down")
|
| - distance.set_y(-distance_length);
|
| - else if (direction_str == "up")
|
| - distance.set_y(distance_length);
|
| - else if (direction_str == "right")
|
| - distance.set_x(-distance_length);
|
| - else if (direction_str == "left")
|
| - distance.set_x(distance_length);
|
| - else {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| - gesture_params->distances.push_back(distance);
|
| +void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
|
| + const std::string& dirname) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return;
|
| +
|
| + const cc::Layer* root_layer = context.compositor()->GetRootLayer();
|
| + if (!root_layer)
|
| + return;
|
| +
|
| + base::FilePath dirpath = base::FilePath::FromUTF8Unsafe(dirname);
|
| + if (!base::CreateDirectory(dirpath) ||
|
| + !base::PathIsWritable(dirpath)) {
|
| + std::string msg("Path is not writable: ");
|
| + msg.append(dirpath.MaybeAsASCII());
|
| + isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
|
| + isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
|
| + return;
|
| + }
|
|
|
| - // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| - // progress, we will leak the callback and context. This needs to be fixed,
|
| - // somehow.
|
| - context.render_view_impl()->QueueSyntheticGesture(
|
| - gesture_params.Pass(),
|
| - base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
| + SkPictureSerializer serializer(dirpath);
|
| + serializer.Serialize(root_layer);
|
| +}
|
|
|
| - args.GetReturnValue().Set(true);
|
| +bool GpuBenchmarking::GestureSourceTypeSupported(int gesture_source_type) {
|
| + if (gesture_source_type < 0 ||
|
| + gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| + return false;
|
| }
|
|
|
| - static void BeginScrollBounce(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(false))
|
| - return;
|
| + return SyntheticGestureParams::IsGestureSourceTypeSupported(
|
| + static_cast<SyntheticGestureParams::GestureSourceType>(
|
| + gesture_source_type));
|
| +}
|
|
|
| - // The last two arguments can be undefined. We check their validity later.
|
| - int arglen = args.Length();
|
| - if (arglen < 8 ||
|
| - !args[0]->IsString() ||
|
| - !args[1]->IsNumber() ||
|
| - !args[2]->IsNumber() ||
|
| - !args[3]->IsNumber() ||
|
| - !args[4]->IsFunction() ||
|
| - !args[5]->IsNumber()) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| +bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return false;
|
| +
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + blink::WebRect rect = context.render_view_impl()->windowRect();
|
| +
|
| + int pixels_to_scroll = 0;
|
| + v8::Handle<v8::Function> callback;
|
| + int start_x = rect.width / (page_scale_factor * 2);
|
| + int start_y = rect.height / (page_scale_factor * 2);
|
| + int gesture_source_type = 0; // DEFAULT_INPUT
|
| + std::string direction = "down";
|
| + int speed_in_pixels_s = 800;
|
| +
|
| + if (!GetOptionalArg(args, &pixels_to_scroll) ||
|
| + !GetOptionalArg(args, &callback) ||
|
| + !GetOptionalArg(args, &start_x) ||
|
| + !GetOptionalArg(args, &start_y) ||
|
| + !GetOptionalArg(args, &gesture_source_type) ||
|
| + !GetOptionalArg(args, &direction) ||
|
| + !GetOptionalArg(args, &speed_in_pixels_s)) {
|
| + return false;
|
| + }
|
|
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[4]);
|
| + return BeginSmoothScroll(args->isolate(),
|
| + pixels_to_scroll,
|
| + callback,
|
| + gesture_source_type,
|
| + direction,
|
| + speed_in_pixels_s,
|
| + true,
|
| + start_x,
|
| + start_y);
|
| +}
|
|
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
| +bool GpuBenchmarking::Swipe(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return false;
|
| +
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + blink::WebRect rect = context.render_view_impl()->windowRect();
|
| +
|
| + std::string direction = "up";
|
| + int pixels_to_scroll = 0;
|
| + v8::Handle<v8::Function> callback;
|
| + int start_x = rect.width / (page_scale_factor * 2);
|
| + int start_y = rect.height / (page_scale_factor * 2);
|
| + int speed_in_pixels_s = 800;
|
| +
|
| + if (!GetOptionalArg(args, &direction) ||
|
| + !GetOptionalArg(args, &pixels_to_scroll) ||
|
| + !GetOptionalArg(args, &callback) ||
|
| + !GetOptionalArg(args, &start_x) ||
|
| + !GetOptionalArg(args, &start_y) ||
|
| + !GetOptionalArg(args, &speed_in_pixels_s)) {
|
| + return false;
|
| + }
|
|
|
| - scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
|
| - new SyntheticSmoothScrollGestureParams);
|
| + return BeginSmoothScroll(args->isolate(),
|
| + -pixels_to_scroll,
|
| + callback,
|
| + 1, // TOUCH_INPUT
|
| + direction,
|
| + speed_in_pixels_s,
|
| + false,
|
| + start_x,
|
| + start_y);
|
| +}
|
|
|
| - // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| - float page_scale_factor = context.web_view()->pageScaleFactor();
|
| +bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(false))
|
| + return false;
|
| +
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + blink::WebRect rect = context.render_view_impl()->windowRect();
|
| +
|
| + std::string direction = "down";
|
| + int distance_length = 0;
|
| + int overscroll_length = 0;
|
| + int repeat_count = 1;
|
| + v8::Handle<v8::Function> callback;
|
| + int start_x = rect.width / (page_scale_factor * 2);
|
| + int start_y = rect.height / (page_scale_factor * 2);
|
| + int speed_in_pixels_s = 800;
|
| +
|
| + if (!GetOptionalArg(args, &direction) ||
|
| + !GetOptionalArg(args, &distance_length) ||
|
| + !GetOptionalArg(args, &overscroll_length) ||
|
| + !GetOptionalArg(args, &repeat_count) ||
|
| + !GetOptionalArg(args, &callback) ||
|
| + !GetOptionalArg(args, &start_x) ||
|
| + !GetOptionalArg(args, &start_y) ||
|
| + !GetOptionalArg(args, &speed_in_pixels_s)) {
|
| + return false;
|
| + }
|
|
|
| - gesture_params->speed_in_pixels_s = args[5]->IntegerValue();
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(args->isolate(),
|
| + callback,
|
| + context.web_frame()->mainWorldScriptContext());
|
| +
|
| + scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
|
| + new SyntheticSmoothScrollGestureParams);
|
| +
|
| + gesture_params->speed_in_pixels_s = speed_in_pixels_s;
|
| +
|
| + gesture_params->anchor.SetPoint(start_x * page_scale_factor,
|
| + start_y * page_scale_factor);
|
| +
|
| + distance_length *= page_scale_factor;
|
| + overscroll_length *= page_scale_factor;
|
| + gfx::Vector2d distance;
|
| + gfx::Vector2d overscroll;
|
| + if (direction == "down") {
|
| + distance.set_y(-distance_length);
|
| + overscroll.set_y(overscroll_length);
|
| + } else if (direction == "up") {
|
| + distance.set_y(distance_length);
|
| + overscroll.set_y(-overscroll_length);
|
| + } else if (direction == "right") {
|
| + distance.set_x(-distance_length);
|
| + overscroll.set_x(overscroll_length);
|
| + } else if (direction == "left") {
|
| + distance.set_x(distance_length);
|
| + overscroll.set_x(-overscroll_length);
|
| + } else {
|
| + return false;
|
| + }
|
|
|
| - // Account for the 2 optional arguments, start_x and start_y.
|
| - gfx::Point start;
|
| - if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
|
| - blink::WebRect rect = context.render_view_impl()->windowRect();
|
| - start.SetPoint(rect.width / 2, rect.height / 2);
|
| - } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
|
| - start.SetPoint(args[6]->IntegerValue() * page_scale_factor,
|
| - args[7]->IntegerValue() * page_scale_factor);
|
| - } else {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| + for (int i = 0; i < repeat_count; i++) {
|
| + gesture_params->distances.push_back(distance);
|
| + gesture_params->distances.push_back(-distance + overscroll);
|
| + }
|
|
|
| - int distance_length = args[1]->IntegerValue() * page_scale_factor;
|
| - int overscroll_length = args[2]->IntegerValue() * page_scale_factor;
|
| - gfx::Vector2d distance;
|
| - gfx::Vector2d overscroll;
|
| - v8::String::Utf8Value direction(args[0]);
|
| - DCHECK(*direction);
|
| - std::string direction_str(*direction);
|
| - if (direction_str == "down") {
|
| - distance.set_y(-distance_length);
|
| - overscroll.set_y(overscroll_length);
|
| - }
|
| - else if (direction_str == "up") {
|
| - distance.set_y(distance_length);
|
| - overscroll.set_y(-overscroll_length);
|
| - }
|
| - else if (direction_str == "right") {
|
| - distance.set_x(-distance_length);
|
| - overscroll.set_x(overscroll_length);
|
| - }
|
| - else if (direction_str == "left") {
|
| - distance.set_x(distance_length);
|
| - overscroll.set_x(-overscroll_length);
|
| - }
|
| - else {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| + // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| + // progress, we will leak the callback and context. This needs to be fixed,
|
| + // somehow.
|
| + context.render_view_impl()->QueueSyntheticGesture(
|
| + gesture_params.Pass(),
|
| + base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
|
|
| - int repeat_count = args[3]->IntegerValue();
|
| - gesture_params->anchor = start;
|
| - for (int i = 0; i < repeat_count; i++) {
|
| - gesture_params->distances.push_back(distance);
|
| - gesture_params->distances.push_back(-distance + overscroll);
|
| - }
|
| + return true;
|
| +}
|
|
|
| - // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| - // progress, we will leak the callback and context. This needs to be fixed,
|
| - // somehow.
|
| - context.render_view_impl()->QueueSyntheticGesture(
|
| - gesture_params.Pass(),
|
| - base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
| +bool GpuBenchmarking::PinchBy(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(false))
|
| + return false;
|
|
|
| - args.GetReturnValue().Set(true);
|
| - }
|
| + float scale_factor;
|
| + int anchor_x;
|
| + int anchor_y;
|
| + v8::Handle<v8::Function> callback;
|
| + int relative_pointer_speed_in_pixels_s = 800;
|
|
|
| - static void BeginPinch(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(false))
|
| - return;
|
|
|
| - int arglen = args.Length();
|
| - if (arglen < 5 ||
|
| - !args[0]->IsNumber() ||
|
| - !args[1]->IsNumber() ||
|
| - !args[2]->IsNumber() ||
|
| - !args[3]->IsFunction() ||
|
| - !args[4]->IsNumber()) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| + if (!GetArg(args, &scale_factor) ||
|
| + !GetArg(args, &anchor_x) ||
|
| + !GetArg(args, &anchor_y) ||
|
| + !GetOptionalArg(args, &callback) ||
|
| + !GetOptionalArg(args, &relative_pointer_speed_in_pixels_s)) {
|
| + return false;
|
| + }
|
|
|
| - scoped_ptr<SyntheticPinchGestureParams> gesture_params(
|
| - new SyntheticPinchGestureParams);
|
| + scoped_ptr<SyntheticPinchGestureParams> gesture_params(
|
| + new SyntheticPinchGestureParams);
|
|
|
| - // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| - float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
|
|
| - gesture_params->scale_factor = args[0]->NumberValue();
|
| - gesture_params->anchor.SetPoint(
|
| - args[1]->IntegerValue() * page_scale_factor,
|
| - args[2]->IntegerValue() * page_scale_factor);
|
| - gesture_params->relative_pointer_speed_in_pixels_s =
|
| - args[4]->IntegerValue();
|
| + gesture_params->scale_factor = scale_factor;
|
| + gesture_params->anchor.SetPoint(anchor_x * page_scale_factor,
|
| + anchor_y * page_scale_factor);
|
| + gesture_params->relative_pointer_speed_in_pixels_s =
|
| + relative_pointer_speed_in_pixels_s;
|
|
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[3]);
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(args->isolate(),
|
| + callback,
|
| + context.web_frame()->mainWorldScriptContext());
|
|
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
|
|
| + // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| + // progress, we will leak the callback and context. This needs to be fixed,
|
| + // somehow.
|
| + context.render_view_impl()->QueueSyntheticGesture(
|
| + gesture_params.Pass(),
|
| + base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
|
|
| - // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| - // progress, we will leak the callback and context. This needs to be fixed,
|
| - // somehow.
|
| - context.render_view_impl()->QueueSyntheticGesture(
|
| - gesture_params.Pass(),
|
| - base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
| + return true;
|
| +}
|
|
|
| - args.GetReturnValue().Set(true);
|
| +bool GpuBenchmarking::Tap(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(false))
|
| + return false;
|
| +
|
| + int position_x;
|
| + int position_y;
|
| + v8::Handle<v8::Function> callback;
|
| + int duration_ms = 50;
|
| + int gesture_source_type = 0; // DEFAULT_INPUT
|
| +
|
| + if (!GetArg(args, &position_x) ||
|
| + !GetArg(args, &position_y) ||
|
| + !GetOptionalArg(args, &callback) ||
|
| + !GetOptionalArg(args, &duration_ms) ||
|
| + !GetOptionalArg(args, &gesture_source_type)) {
|
| + return false;
|
| }
|
|
|
| - static void BeginTap(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(false))
|
| - return;
|
| -
|
| - int arglen = args.Length();
|
| - if (arglen < 5 ||
|
| - !args[0]->IsNumber() ||
|
| - !args[1]->IsNumber() ||
|
| - !args[2]->IsFunction() ||
|
| - !args[3]->IsNumber() ||
|
| - !args[4]->IsNumber()) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| -
|
| - scoped_ptr<SyntheticTapGestureParams> gesture_params(
|
| - new SyntheticTapGestureParams);
|
| + scoped_ptr<SyntheticTapGestureParams> gesture_params(
|
| + new SyntheticTapGestureParams);
|
|
|
| - // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| - float page_scale_factor = context.web_view()->pageScaleFactor();
|
| + // Convert coordinates from CSS pixels to density independent pixels (DIPs).
|
| + float page_scale_factor = context.web_view()->pageScaleFactor();
|
|
|
| - gesture_params->position.SetPoint(
|
| - args[0]->IntegerValue() * page_scale_factor,
|
| - args[1]->IntegerValue() * page_scale_factor);
|
| - gesture_params->duration_ms = args[3]->IntegerValue();
|
| + gesture_params->position.SetPoint(position_x * page_scale_factor,
|
| + position_y * page_scale_factor);
|
| + gesture_params->duration_ms = duration_ms;
|
|
|
| - int gesture_source_type = args[4]->IntegerValue();
|
| - if (gesture_source_type < 0 ||
|
| - gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| - args.GetReturnValue().Set(false);
|
| - return;
|
| - }
|
| - gesture_params->gesture_source_type =
|
| - static_cast<SyntheticGestureParams::GestureSourceType>(
|
| - gesture_source_type);
|
| -
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[2]);
|
| -
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
| -
|
| -
|
| - // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| - // progress, we will leak the callback and context. This needs to be fixed,
|
| - // somehow.
|
| - context.render_view_impl()->QueueSyntheticGesture(
|
| - gesture_params.Pass(),
|
| - base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
| -
|
| - args.GetReturnValue().Set(true);
|
| - }
|
| -
|
| - static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
|
| - const gfx::Size& size,
|
| - const std::vector<unsigned char>& png) {
|
| - v8::Isolate* isolate = callback_and_context->isolate();
|
| - v8::HandleScope scope(isolate);
|
| - v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| - v8::Context::Scope context_scope(context);
|
| - WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| - if (frame) {
|
| -
|
| - v8::Handle<v8::Value> result;
|
| -
|
| - if(!size.IsEmpty()) {
|
| - v8::Handle<v8::Object> result_object;
|
| - result_object = v8::Object::New(isolate);
|
| -
|
| - result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
|
| - v8::Number::New(isolate, size.width()));
|
| - result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
|
| - v8::Number::New(isolate, size.height()));
|
| -
|
| - std::string base64_png;
|
| - base::Base64Encode(base::StringPiece(
|
| - reinterpret_cast<const char*>(&*png.begin()), png.size()),
|
| - &base64_png);
|
| -
|
| - result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
|
| - v8::String::NewFromUtf8(isolate,
|
| - base64_png.c_str(),
|
| - v8::String::kNormalString,
|
| - base64_png.size()));
|
| -
|
| - result = result_object;
|
| - } else {
|
| - result = v8::Null(isolate);
|
| - }
|
| -
|
| - v8::Handle<v8::Value> argv[] = { result };
|
| -
|
| - frame->callFunctionEvenIfScriptDisabled(
|
| - callback_and_context->GetCallback(),
|
| - v8::Object::New(isolate),
|
| - 1,
|
| - argv);
|
| - }
|
| + if (gesture_source_type < 0 ||
|
| + gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
|
| + return false;
|
| }
|
| + gesture_params->gesture_source_type =
|
| + static_cast<SyntheticGestureParams::GestureSourceType>(
|
| + gesture_source_type);
|
| +
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(args->isolate(),
|
| + callback,
|
| + context.web_frame()->mainWorldScriptContext());
|
| +
|
| + // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
|
| + // progress, we will leak the callback and context. This needs to be fixed,
|
| + // somehow.
|
| + context.render_view_impl()->QueueSyntheticGesture(
|
| + gesture_params.Pass(),
|
| + base::Bind(&OnSyntheticGestureCompleted, callback_and_context));
|
| +
|
| + return true;
|
| +}
|
|
|
| - static void BeginWindowSnapshotPNG(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(false))
|
| - return;
|
| -
|
| - if (!args[0]->IsFunction())
|
| - return;
|
| -
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[0]);
|
| -
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
| -
|
| - context.render_view_impl()->GetWindowSnapshot(
|
| - base::Bind(&OnSnapshotCompleted, callback_and_context));
|
| - }
|
| -
|
| - static void ClearImageCache(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - WebImageCache::clear();
|
| - }
|
| -
|
| - static void OnMicroBenchmarkCompleted(
|
| - CallbackAndContext* callback_and_context,
|
| - scoped_ptr<base::Value> result) {
|
| - v8::Isolate* isolate = callback_and_context->isolate();
|
| - v8::HandleScope scope(isolate);
|
| - v8::Handle<v8::Context> context = callback_and_context->GetContext();
|
| - v8::Context::Scope context_scope(context);
|
| - WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
|
| - if (frame) {
|
| - scoped_ptr<V8ValueConverter> converter =
|
| - make_scoped_ptr(V8ValueConverter::create());
|
| - v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
|
| - v8::Handle<v8::Value> argv[] = { value };
|
| -
|
| - frame->callFunctionEvenIfScriptDisabled(
|
| - callback_and_context->GetCallback(),
|
| - v8::Object::New(isolate),
|
| - 1,
|
| - argv);
|
| - }
|
| - }
|
| +void GpuBenchmarking::BeginWindowSnapshotPNG(
|
| + v8::Isolate* isolate,
|
| + v8::Handle<v8::Function> callback) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(false))
|
| + return;
|
|
|
| - static void RunMicroBenchmark(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(true)) {
|
| - args.GetReturnValue().Set(0);
|
| - return;
|
| - }
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(isolate,
|
| + callback,
|
| + context.web_frame()->mainWorldScriptContext());
|
|
|
| - if (args.Length() != 3 ||
|
| - !args[0]->IsString() ||
|
| - !args[1]->IsFunction() ||
|
| - !args[2]->IsObject()) {
|
| - args.GetReturnValue().Set(0);
|
| - return;
|
| - }
|
| + context.render_view_impl()->GetWindowSnapshot(
|
| + base::Bind(&OnSnapshotCompleted, callback_and_context));
|
| +}
|
|
|
| - v8::Local<v8::Function> callback_local =
|
| - v8::Local<v8::Function>::Cast(args[1]);
|
| +void GpuBenchmarking::ClearImageCache() {
|
| + WebImageCache::clear();
|
| +}
|
|
|
| - scoped_refptr<CallbackAndContext> callback_and_context =
|
| - new CallbackAndContext(args.GetIsolate(),
|
| - callback_local,
|
| - context.web_frame()->mainWorldScriptContext());
|
| +int GpuBenchmarking::RunMicroBenchmark(gin::Arguments* args) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return 0;
|
|
|
| - scoped_ptr<V8ValueConverter> converter =
|
| - make_scoped_ptr(V8ValueConverter::create());
|
| - v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
|
| - scoped_ptr<base::Value> value =
|
| - make_scoped_ptr(converter->FromV8Value(args[2], v8_context));
|
| -
|
| - v8::String::Utf8Value benchmark(args[0]);
|
| - DCHECK(*benchmark);
|
| - args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark(
|
| - std::string(*benchmark),
|
| - value.Pass(),
|
| - base::Bind(&OnMicroBenchmarkCompleted, callback_and_context)));
|
| - }
|
| -
|
| - static void SendMessageToMicroBenchmark(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| - GpuBenchmarkingContext context;
|
| - if (!context.Init(true)) {
|
| - args.GetReturnValue().Set(0);
|
| - return;
|
| - }
|
| + std::string name;
|
| + v8::Handle<v8::Function> callback;
|
| + v8::Handle<v8::Object> arguments;
|
|
|
| - if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsObject()) {
|
| - args.GetReturnValue().Set(0);
|
| - return;
|
| - }
|
| + if (!GetArg(args, &name) || !GetArg(args, &callback) ||
|
| + !GetOptionalArg(args, &arguments)) {
|
| + return 0;
|
| + }
|
|
|
| - scoped_ptr<V8ValueConverter> converter =
|
| - make_scoped_ptr(V8ValueConverter::create());
|
| - v8::Handle<v8::Context> v8_context =
|
| - context.web_frame()->mainWorldScriptContext();
|
| - scoped_ptr<base::Value> value =
|
| - make_scoped_ptr(converter->FromV8Value(args[1], v8_context));
|
| + scoped_refptr<CallbackAndContext> callback_and_context =
|
| + new CallbackAndContext(args->isolate(),
|
| + callback,
|
| + context.web_frame()->mainWorldScriptContext());
|
| +
|
| + scoped_ptr<V8ValueConverter> converter =
|
| + make_scoped_ptr(V8ValueConverter::create());
|
| + v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
|
| + scoped_ptr<base::Value> value =
|
| + make_scoped_ptr(converter->FromV8Value(arguments, v8_context));
|
| +
|
| + return context.compositor()->ScheduleMicroBenchmark(
|
| + name,
|
| + value.Pass(),
|
| + base::Bind(&OnMicroBenchmarkCompleted, callback_and_context));
|
| +}
|
|
|
| - int id = 0;
|
| - converter->FromV8Value(args[0], v8_context)->GetAsInteger(&id);
|
| - args.GetReturnValue().Set(
|
| - context.compositor()->SendMessageToMicroBenchmark(id, value.Pass()));
|
| - }
|
| +bool GpuBenchmarking::SendMessageToMicroBenchmark(
|
| + int id,
|
| + v8::Handle<v8::Object> message) {
|
| + GpuBenchmarkingContext context;
|
| + if (!context.Init(true))
|
| + return false;
|
| +
|
| + scoped_ptr<V8ValueConverter> converter =
|
| + make_scoped_ptr(V8ValueConverter::create());
|
| + v8::Handle<v8::Context> v8_context =
|
| + context.web_frame()->mainWorldScriptContext();
|
| + scoped_ptr<base::Value> value =
|
| + make_scoped_ptr(converter->FromV8Value(message, v8_context));
|
| +
|
| + return context.compositor()->SendMessageToMicroBenchmark(id, value.Pass());
|
| +}
|
|
|
| - static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| +bool GpuBenchmarking::HasGpuProcess() {
|
| GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel();
|
| - args.GetReturnValue().Set(!!gpu_channel);
|
| - }
|
| -};
|
| -
|
| -v8::Extension* GpuBenchmarkingExtension::Get() {
|
| - return new GpuBenchmarkingWrapper();
|
| + return !!gpu_channel;
|
| }
|
|
|
| } // namespace content
|
|
|