Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / renderer / gpu / gpu_benchmarking_extension.cc
index 1af771d..0396d49 100644 (file)
 #include "base/memory/scoped_vector.h"
 #include "base/strings/string_number_conversions.h"
 #include "cc/layers/layer.h"
-#include "content/common/browser_rendering_stats.h"
-#include "content/common/gpu/gpu_rendering_stats.h"
+#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/input/synthetic_tap_gesture_params.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/v8_value_converter.h"
 #include "content/renderer/gpu/render_widget_compositor.h"
 #include "third_party/skia/include/core/SkStream.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "v8/include/v8.h"
-#include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h"
 
-using WebKit::WebCanvas;
-using WebKit::WebFrame;
-using WebKit::WebImageCache;
-using WebKit::WebPrivatePtr;
-using WebKit::WebRenderingStatsImpl;
-using WebKit::WebSize;
-using WebKit::WebView;
+using blink::WebCanvas;
+using blink::WebFrame;
+using blink::WebImageCache;
+using blink::WebPrivatePtr;
+using blink::WebSize;
+using blink::WebView;
 
 const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
 
+// 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) {
-            *offset = bm.pixelRefOffset();
+        if (data != NULL)
             return data;
-        }
     }
     std::vector<unsigned char> vector;
     if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
@@ -67,7 +67,7 @@ class SkPictureSerializer {
         layer_id_(0) {
     // Let skia register known effect subclasses. This basically enables
     // reflection on those subclasses required for picture serialization.
-    content::SkiaBenchmarkingExtension::InitSkGraphics();
+    content::SkiaBenchmarking::Initialize();
   }
 
   // Recursively serializes the layer tree.
@@ -100,33 +100,6 @@ class SkPictureSerializer {
   int layer_id_;
 };
 
-class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator {
- public:
-  RenderingStatsEnumerator(v8::Handle<v8::Object> stats_object)
-      : stats_object(stats_object) { }
-
-  virtual void AddInt64(const char* name, int64 value) OVERRIDE {
-    stats_object->Set(v8::String::New(name), v8::Number::New(value));
-  }
-
-  virtual void AddDouble(const char* name, double value) OVERRIDE {
-    stats_object->Set(v8::String::New(name), v8::Number::New(value));
-  }
-
-  virtual void AddInt(const char* name, int value) OVERRIDE {
-    stats_object->Set(v8::String::New(name), v8::Integer::New(value));
-  }
-
-  virtual void AddTimeDeltaInSecondsF(const char* name,
-                                      const base::TimeDelta& value) OVERRIDE {
-    stats_object->Set(v8::String::New(name),
-                      v8::Number::New(value.InSecondsF()));
-  }
-
- private:
-  v8::Handle<v8::Object> stats_object;
-};
-
 }  // namespace
 
 namespace content {
@@ -159,8 +132,8 @@ class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
   friend class base::RefCounted<CallbackAndContext>;
 
   virtual ~CallbackAndContext() {
-    callback_.Dispose();
-    context_.Dispose();
+    callback_.Reset();
+    context_.Reset();
   }
 
   v8::Isolate* isolate_;
@@ -255,45 +228,68 @@ class GpuBenchmarkingWrapper : public v8::Extension {
           "  native function SetRasterizeOnlyVisibleContent();"
           "  return SetRasterizeOnlyVisibleContent();"
           "};"
-          "chrome.gpuBenchmarking.renderingStats = function() {"
-          "  native function GetRenderingStats();"
-          "  return GetRenderingStats();"
-          "};"
-          "chrome.gpuBenchmarking.gpuRenderingStats = function() {"
-          "  native function GetGpuRenderingStats();"
-          "  return GetGpuRenderingStats();"
-          "};"
           "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.smoothScrollBy = "
-          "    function(pixels_to_scroll, opt_callback, opt_mouse_event_x,"
-          "             opt_mouse_event_y) {"
+          "    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();"
-          "  if (typeof opt_mouse_event_x !== 'undefined' &&"
-          "      typeof opt_mouse_event_y !== 'undefined') {"
-          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
-          "                             Math.abs(pixels_to_scroll),"
-          "                             opt_mouse_event_x, opt_mouse_event_y);"
-          "  } else {"
-          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
-          "                             Math.abs(pixels_to_scroll));"
-          "  }"
+          "  return BeginSmoothScroll(pixels_to_scroll, callback,"
+          "                           gesture_source_type, direction,"
+          "                           speed_in_pixels_s, true,"
+          "                           opt_start_x, opt_start_y);"
           "};"
           "chrome.gpuBenchmarking.smoothScrollBySendsTouch = function() {"
           "  native function SmoothScrollSendsTouch();"
           "  return SmoothScrollSendsTouch();"
           "};"
+          "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.pinchBy = "
-          "    function(zoom_in, pixels_to_move, anchor_x, anchor_y,"
-          "             opt_callback) {"
+          "    function(zoom_in, pixels_to_cover, 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(zoom_in, pixels_to_move,"
-          "                    anchor_x, anchor_y, callback);"
+          "  return BeginPinch(zoom_in, pixels_to_cover,"
+          "                    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 || 0;"
+          "  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();"
@@ -314,32 +310,35 @@ class GpuBenchmarkingWrapper : public v8::Extension {
           "  return HasGpuProcess();"
           "};") {}
 
-  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+      v8::Isolate* isolate,
       v8::Handle<v8::String> name) OVERRIDE {
-    if (name->Equals(v8::String::New("SetNeedsDisplayOnAllLayers")))
-      return v8::FunctionTemplate::New(SetNeedsDisplayOnAllLayers);
-    if (name->Equals(v8::String::New("SetRasterizeOnlyVisibleContent")))
-      return v8::FunctionTemplate::New(SetRasterizeOnlyVisibleContent);
-    if (name->Equals(v8::String::New("GetRenderingStats")))
-      return v8::FunctionTemplate::New(GetRenderingStats);
-    if (name->Equals(v8::String::New("GetGpuRenderingStats")))
-      return v8::FunctionTemplate::New(GetGpuRenderingStats);
-    if (name->Equals(v8::String::New("PrintToSkPicture")))
-      return v8::FunctionTemplate::New(PrintToSkPicture);
-    if (name->Equals(v8::String::New("BeginSmoothScroll")))
-      return v8::FunctionTemplate::New(BeginSmoothScroll);
-    if (name->Equals(v8::String::New("SmoothScrollSendsTouch")))
-      return v8::FunctionTemplate::New(SmoothScrollSendsTouch);
-    if (name->Equals(v8::String::New("BeginPinch")))
-      return v8::FunctionTemplate::New(BeginPinch);
-    if (name->Equals(v8::String::New("BeginWindowSnapshotPNG")))
-      return v8::FunctionTemplate::New(BeginWindowSnapshotPNG);
-    if (name->Equals(v8::String::New("ClearImageCache")))
-      return v8::FunctionTemplate::New(ClearImageCache);
-    if (name->Equals(v8::String::New("RunMicroBenchmark")))
-      return v8::FunctionTemplate::New(RunMicroBenchmark);
-    if (name->Equals(v8::String::New("HasGpuProcess")))
-      return v8::FunctionTemplate::New(HasGpuProcess);
+    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, "BeginSmoothScroll")))
+      return v8::FunctionTemplate::New(isolate, BeginSmoothScroll);
+    if (name->Equals(
+            v8::String::NewFromUtf8(isolate, "SmoothScrollSendsTouch")))
+      return v8::FunctionTemplate::New(isolate, SmoothScrollSendsTouch);
+    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, "HasGpuProcess")))
+      return v8::FunctionTemplate::New(isolate, HasGpuProcess);
 
     return v8::Handle<v8::FunctionTemplate>();
   }
@@ -362,53 +361,12 @@ class GpuBenchmarkingWrapper : public v8::Extension {
     context.compositor()->SetRasterizeOnlyVisibleContent();
   }
 
-  static void GetRenderingStats(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
-
-    WebRenderingStatsImpl stats;
-    context.render_view_impl()->GetRenderingStats(stats);
-
-    content::GpuRenderingStats gpu_stats;
-    context.render_view_impl()->GetGpuRenderingStats(&gpu_stats);
-    BrowserRenderingStats browser_stats;
-    context.render_view_impl()->GetBrowserRenderingStats(&browser_stats);
-    v8::Handle<v8::Object> stats_object = v8::Object::New();
-
-    RenderingStatsEnumerator enumerator(stats_object);
-    stats.rendering_stats.EnumerateFields(&enumerator);
-    gpu_stats.EnumerateFields(&enumerator);
-    browser_stats.EnumerateFields(&enumerator);
-
-    args.GetReturnValue().Set(stats_object);
-  }
-
-  static void GetGpuRenderingStats(
-      const v8::FunctionCallbackInfo<v8::Value>& args) {
-
-    GpuBenchmarkingContext context;
-    if (!context.Init(false))
-      return;
-
-    content::GpuRenderingStats gpu_stats;
-    context.render_view_impl()->GetGpuRenderingStats(&gpu_stats);
-
-    v8::Handle<v8::Object> stats_object = v8::Object::New();
-    RenderingStatsEnumerator enumerator(stats_object);
-    gpu_stats.EnumerateFields(&enumerator);
-
-    args.GetReturnValue().Set(stats_object);
-  }
-
   static void PrintToSkPicture(
       const v8::FunctionCallbackInfo<v8::Value>& args) {
     if (args.Length() != 1)
       return;
 
-    v8::String::AsciiValue dirname(args[0]);
+    v8::String::Utf8Value dirname(args[0]);
     if (dirname.length() == 0)
       return;
 
@@ -422,12 +380,13 @@ class GpuBenchmarkingWrapper : public v8::Extension {
 
     base::FilePath dirpath(
         base::FilePath::StringType(*dirname, *dirname + dirname.length()));
-    if (!file_util::CreateDirectory(dirpath) ||
+    if (!base::CreateDirectory(dirpath) ||
         !base::PathIsWritable(dirpath)) {
       std::string msg("Path is not writable: ");
       msg.append(dirpath.MaybeAsASCII());
-      v8::ThrowException(v8::Exception::Error(
-          v8::String::New(msg.c_str(), msg.length())));
+      v8::Isolate* isolate = args.GetIsolate();
+      isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
+          isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
       return;
     }
 
@@ -435,15 +394,19 @@ class GpuBenchmarkingWrapper : public v8::Extension {
     serializer.Serialize(root_layer);
   }
 
-  static void OnSmoothScrollCompleted(
+  static void OnSyntheticGestureCompleted(
       CallbackAndContext* callback_and_context) {
-    v8::HandleScope scope(callback_and_context->isolate());
+    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);
     WebFrame* frame = WebFrame::frameForContext(context);
     if (frame) {
       frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(), v8::Object::New(), 0, NULL);
+          callback_and_context->GetCallback(),
+          v8::Object::New(isolate),
+          0,
+          NULL);
     }
   }
 
@@ -463,17 +426,19 @@ class GpuBenchmarkingWrapper : public v8::Extension {
     if (!context.Init(false))
       return;
 
-    // Account for the 2 optional arguments, mouse_event_x and mouse_event_y.
+    // The last two arguments can be undefined. We check their validity later.
     int arglen = args.Length();
-    if (arglen < 3 ||
-        !args[0]->IsBoolean() ||
+    if (arglen < 8 ||
+        !args[0]->IsNumber() ||
         !args[1]->IsFunction() ||
-        !args[2]->IsNumber()) {
+        !args[2]->IsNumber() ||
+        !args[3]->IsString() ||
+        !args[4]->IsNumber() ||
+        !args[5]->IsBoolean()) {
       args.GetReturnValue().Set(false);
       return;
     }
 
-    bool scroll_down = args[0]->BooleanValue();
     v8::Local<v8::Function> callback_local =
         v8::Local<v8::Function>::Cast(args[1]);
 
@@ -482,39 +447,62 @@ class GpuBenchmarkingWrapper : public v8::Extension {
                                callback_local,
                                context.web_frame()->mainWorldScriptContext());
 
-    int pixels_to_scroll = args[2]->IntegerValue();
+    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
+        new SyntheticSmoothScrollGestureParams);
 
-    int mouse_event_x = 0;
-    int mouse_event_y = 0;
+    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
+    float page_scale_factor = context.web_view()->pageScaleFactor();
 
-    if (arglen == 3) {
-      WebKit::WebRect rect = context.render_view_impl()->windowRect();
-      mouse_event_x = rect.x + rect.width / 2;
-      mouse_event_y = rect.y + rect.height / 2;
-    } else {
-      if (arglen != 5 ||
-          !args[3]->IsNumber() ||
-          !args[4]->IsNumber()) {
-        args.GetReturnValue().Set(false);
-        return;
-      }
+    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);
+
+    int distance = args[0]->IntegerValue() * page_scale_factor;
+    v8::String::Utf8Value direction(args[3]);
+    DCHECK(*direction);
+    std::string direction_str(*direction);
+    if (direction_str == "down")
+      gesture_params->distance.set_y(distance);
+    else if (direction_str == "up")
+      gesture_params->distance.set_y(-distance);
+    else if (direction_str == "right")
+      gesture_params->distance.set_x(distance);
+    else if (direction_str == "left")
+      gesture_params->distance.set_x(-distance);
+    else {
+      args.GetReturnValue().Set(false);
+      return;
+    }
 
-      mouse_event_x = args[3]->IntegerValue() *
-          context.web_view()->pageScaleFactor();
-      mouse_event_y = args[4]->IntegerValue() *
-          context.web_view()->pageScaleFactor();
+    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.
+    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
+      blink::WebRect rect = context.render_view_impl()->windowRect();
+      gesture_params->anchor.SetPoint(rect.width / 2, rect.height / 2);
+    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
+      gesture_params->anchor.SetPoint(
+          args[6]->IntegerValue() * page_scale_factor,
+          args[7]->IntegerValue() * page_scale_factor);
+    } 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()->BeginSmoothScroll(
-        scroll_down,
-        base::Bind(&OnSmoothScrollCompleted,
-                   callback_and_context),
-        pixels_to_scroll,
-        mouse_event_x,
-        mouse_event_y);
+    context.render_view_impl()->QueueSyntheticGesture(
+        gesture_params.PassAs<SyntheticGestureParams>(),
+        base::Bind(&OnSyntheticGestureCompleted,
+                   callback_and_context));
 
     args.GetReturnValue().Set(true);
   }
@@ -526,20 +514,31 @@ class GpuBenchmarkingWrapper : public v8::Extension {
       return;
 
     int arglen = args.Length();
-    if (arglen < 5 ||
+    if (arglen < 6 ||
         !args[0]->IsBoolean() ||
         !args[1]->IsNumber() ||
         !args[2]->IsNumber() ||
         !args[3]->IsNumber() ||
-        !args[4]->IsFunction()) {
+        !args[4]->IsFunction() ||
+        !args[5]->IsNumber()) {
       args.GetReturnValue().Set(false);
       return;
     }
 
-    bool zoom_in = args[0]->BooleanValue();
-    int pixels_to_move = args[1]->IntegerValue();
-    int anchor_x = args[2]->IntegerValue();
-    int anchor_y = args[3]->IntegerValue();
+    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();
+
+    gesture_params->zoom_in = args[0]->BooleanValue();
+    gesture_params->total_num_pixels_covered =
+        args[1]->IntegerValue() * page_scale_factor;
+    gesture_params->anchor.SetPoint(
+        args[2]->IntegerValue() * page_scale_factor,
+        args[3]->IntegerValue() * page_scale_factor);
+    gesture_params->relative_pointer_speed_in_pixels_s =
+        args[5]->IntegerValue();
 
     v8::Local<v8::Function> callback_local =
         v8::Local<v8::Function>::Cast(args[4]);
@@ -553,12 +552,67 @@ class GpuBenchmarkingWrapper : public v8::Extension {
     // 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()->BeginPinch(
-        zoom_in,
-        pixels_to_move,
-        anchor_x,
-        anchor_y,
-        base::Bind(&OnSmoothScrollCompleted,
+    context.render_view_impl()->QueueSyntheticGesture(
+        gesture_params.PassAs<SyntheticGestureParams>(),
+        base::Bind(&OnSyntheticGestureCompleted,
+                   callback_and_context));
+
+    args.GetReturnValue().Set(true);
+  }
+
+  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);
+
+    // 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();
+
+    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.PassAs<SyntheticGestureParams>(),
+        base::Bind(&OnSyntheticGestureCompleted,
                    callback_and_context));
 
     args.GetReturnValue().Set(true);
@@ -567,7 +621,8 @@ class GpuBenchmarkingWrapper : public v8::Extension {
   static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
                                   const gfx::Size& size,
                                   const std::vector<unsigned char>& png) {
-    v8::HandleScope scope(callback_and_context->isolate());
+    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);
     WebFrame* frame = WebFrame::frameForContext(context);
@@ -577,30 +632,36 @@ class GpuBenchmarkingWrapper : public v8::Extension {
 
       if(!size.IsEmpty()) {
         v8::Handle<v8::Object> result_object;
-        result_object = v8::Object::New();
+        result_object = v8::Object::New(isolate);
 
-        result_object->Set(v8::String::New("width"),
-                           v8::Number::New(size.width()));
-        result_object->Set(v8::String::New("height"),
-                           v8::Number::New(size.height()));
+        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::New("data"),
-            v8::String::New(base64_png.c_str(), base64_png.size()));
+        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();
+        result = v8::Null(isolate);
       }
 
       v8::Handle<v8::Value> argv[] = { result };
 
       frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
+          callback_and_context->GetCallback(),
+          v8::Object::New(isolate),
+          1,
+          argv);
     }
   }
 
@@ -633,7 +694,8 @@ class GpuBenchmarkingWrapper : public v8::Extension {
   static void OnMicroBenchmarkCompleted(
       CallbackAndContext* callback_and_context,
       scoped_ptr<base::Value> result) {
-    v8::HandleScope scope(callback_and_context->isolate());
+    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);
     WebFrame* frame = WebFrame::frameForContext(context);
@@ -644,7 +706,10 @@ class GpuBenchmarkingWrapper : public v8::Extension {
       v8::Handle<v8::Value> argv[] = { value };
 
       frame->callFunctionEvenIfScriptDisabled(
-          callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
+          callback_and_context->GetCallback(),
+          v8::Object::New(isolate),
+          1,
+          argv);
     }
   }