15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/gpu/gpu_benchmarking_extension.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/base64.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/layers/layer.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_gesture_params.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_pinch_gesture_params.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/common/input/synthetic_tap_gesture_params.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/v8_value_converter.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/gpu/render_widget_compositor.h"
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/renderer/skia_benchmarking_extension.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebImageCache.h"
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "third_party/WebKit/public/web/WebLocalFrame.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkData.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkGraphics.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPixelRef.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkStream.h"
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCanvas;
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebLocalFrame;
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebImageCache;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPrivatePtr;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSize;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebView;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// offset parameter is deprecated/ignored, and will be remove from the
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// signature in a future skia release. <reed@google.com>
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SkPixelRef* pr = bm.pixelRef();
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (pr != NULL) {
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        SkData* data = pr->refEncodedData();
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (data != NULL)
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            return data;
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<unsigned char> vector;
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return SkData::NewWithCopy(&vector.front() , vector.size());
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class SkPictureSerializer {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit SkPictureSerializer(const base::FilePath& dirpath)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : dirpath_(dirpath),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        layer_id_(0) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let skia register known effect subclasses. This basically enables
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reflection on those subclasses required for picture serialization.
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::SkiaBenchmarking::Initialize();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Recursively serializes the layer tree.
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Each layer in the tree is serialized into a separate skp file
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the given directory.
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void Serialize(const cc::Layer* layer) {
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const cc::LayerList& children = layer->children();
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for (size_t i = 0; i < children.size(); ++i) {
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      Serialize(children[i].get());
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    skia::RefPtr<SkPicture> picture = layer->GetPicture();
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!picture)
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Serialize picture to file.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(alokp): Note that for this to work Chrome needs to be launched with
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // --no-sandbox command-line flag. Get rid of this limitation.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CRBUG: 139640.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!filepath.empty());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkFILEWStream file(filepath.c_str());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(file.isValid());
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    picture->serialize(&file, &EncodeBitmapToData);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dirpath_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int layer_id_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CallbackAndContext(v8::Isolate* isolate,
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Function> callback,
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Context> context)
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : isolate_(isolate) {
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Reset(isolate_, callback);
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context_.Reset(isolate_, context);
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate() {
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return isolate_;
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Function> GetCallback() {
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Function>::New(isolate_, callback_);
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Context> GetContext() {
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Context>::New(isolate_, context_);
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  friend class base::RefCounted<CallbackAndContext>;
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~CallbackAndContext() {
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_.Reset();
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_.Reset();
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate_;
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Function> callback_;
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Context> context_;
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackAndContext);
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class GpuBenchmarkingContext {
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  GpuBenchmarkingContext()
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      : web_frame_(NULL),
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        web_view_(NULL),
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        render_view_impl_(NULL),
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        compositor_(NULL) {}
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool Init(bool init_compositor) {
154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    web_frame_ = WebLocalFrame::frameForCurrentContext();
155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!web_frame_)
156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    web_view_ = web_frame_->view();
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!web_view_) {
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_view_impl_ = RenderViewImpl::FromWebView(web_view_);
165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!render_view_impl_) {
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_view_ = NULL;
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!init_compositor)
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    compositor_ = render_view_impl_->compositor();
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!compositor_) {
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_view_ = NULL;
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      render_view_impl_ = NULL;
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return true;
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  WebLocalFrame* web_frame() const {
186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(web_frame_ != NULL);
187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return web_frame_;
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebView* web_view() const {
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(web_view_ != NULL);
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return web_view_;
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderViewImpl* render_view_impl() const {
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(render_view_impl_ != NULL);
195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return render_view_impl_;
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderWidgetCompositor* compositor() const {
198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(compositor_ != NULL);
199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return compositor_;
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  WebLocalFrame* web_frame_;
204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebView* web_view_;
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderViewImpl* render_view_impl_;
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderWidgetCompositor* compositor_;
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuBenchmarkingWrapper : public v8::Extension {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuBenchmarkingWrapper() :
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Extension(kGpuBenchmarkingExtensionName,
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "if (typeof(chrome) == 'undefined') {"
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  chrome = {};"
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  chrome.gpuBenchmarking = {};"
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function SetNeedsDisplayOnAllLayers();"
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return SetNeedsDisplayOnAllLayers();"
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent = "
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "function() {"
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function SetRasterizeOnlyVisibleContent();"
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return SetRasterizeOnlyVisibleContent();"
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function PrintToSkPicture();"
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return PrintToSkPicture(dirname);"
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.DEFAULT_INPUT = 0;"
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.TOUCH_INPUT = 1;"
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.MOUSE_INPUT = 2;"
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.gestureSourceTypeSupported = "
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(gesture_source_type) {"
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function GestureSourceTypeSupported();"
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return GestureSourceTypeSupported(gesture_source_type);"
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.smoothScrollBy = "
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(pixels_to_scroll, opt_callback, opt_start_x,"
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_start_y, opt_gesture_source_type,"
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_direction, opt_speed_in_pixels_s) {"
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  pixels_to_scroll = pixels_to_scroll || 0;"
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  callback = opt_callback || function() { };"
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  gesture_source_type = opt_gesture_source_type ||"
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  direction = opt_direction || 'down';"
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginSmoothScroll();"
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return BeginSmoothScroll(pixels_to_scroll, callback,"
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           gesture_source_type, direction,"
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           speed_in_pixels_s, true,"
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           opt_start_x, opt_start_y);"
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.swipe = "
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(direction, distance, opt_callback,"
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_start_x, opt_start_y,"
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_speed_in_pixels_s) {"
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  direction = direction || 'up';"
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  distance = distance || 0;"
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  callback = opt_callback || function() { };"
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginSmoothScroll();"
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return BeginSmoothScroll(-distance, callback,"
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           chrome.gpuBenchmarking.TOUCH_INPUT,"
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           direction, speed_in_pixels_s, false,"
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           opt_start_x, opt_start_y);"
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.scrollBounce = "
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(direction, distance, overscroll, opt_repeat_count,"
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_callback, opt_start_x, opt_start_y,"
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_speed_in_pixels_s) {"
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  direction = direction || 'down';"
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  distance = distance || 0;"
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  overscroll = overscroll || 0;"
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  repeat_count = opt_repeat_count || 1;"
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  callback = opt_callback || function() { };"
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginScrollBounce();"
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return BeginScrollBounce(direction, distance, overscroll,"
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           repeat_count, callback,"
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           speed_in_pixels_s,"
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                           opt_start_x, opt_start_y);"
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            // TODO(dominikg): Remove once JS interface changes have rolled into
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            //                 stable.
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.newPinchInterface = true;"
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.pinchBy = "
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(scale_factor, anchor_x, anchor_y,"
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_callback, "
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "opt_relative_pointer_speed_in_pixels_s) {"
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  callback = opt_callback || function() { };"
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  relative_pointer_speed_in_pixels_s ="
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "      opt_relative_pointer_speed_in_pixels_s || 800;"
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginPinch();"
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return BeginPinch(scale_factor, anchor_x, anchor_y, callback,"
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                    relative_pointer_speed_in_pixels_s);"
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.tap = "
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(position_x, position_y, opt_callback, "
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "opt_duration_ms,"
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "             opt_gesture_source_type) {"
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  callback = opt_callback || function() { };"
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  duration_ms = opt_duration_ms || 50;"
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  gesture_source_type = opt_gesture_source_type ||"
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginTap();"
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return BeginTap(position_x, position_y, callback, duration_ms,"
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                  gesture_source_type);"
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.beginWindowSnapshotPNG = "
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "function(callback) {"
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function BeginWindowSnapshotPNG();"
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  BeginWindowSnapshotPNG(callback);"
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.clearImageCache = function() {"
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function ClearImageCache();"
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  ClearImageCache();"
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.runMicroBenchmark ="
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(name, callback, opt_arguments) {"
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  arguments = opt_arguments || {};"
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function RunMicroBenchmark();"
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return RunMicroBenchmark(name, callback, arguments);"
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.sendMessageToMicroBenchmark ="
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "    function(id, arguments) {"
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function SendMessageToMicroBenchmark();"
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return SendMessageToMicroBenchmark(id, arguments);"
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};"
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "chrome.gpuBenchmarking.hasGpuProcess = function() {"
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  native function HasGpuProcess();"
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  return HasGpuProcess();"
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "};") {}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      v8::Isolate* isolate,
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::String> name) OVERRIDE {
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers")))
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers);
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent")))
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SetRasterizeOnlyVisibleContent);
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "PrintToSkPicture")))
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, PrintToSkPicture);
3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (name->Equals(
3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            v8::String::NewFromUtf8(isolate, "GestureSourceTypeSupported")))
3540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return v8::FunctionTemplate::New(isolate, GestureSourceTypeSupported);
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginSmoothScroll")))
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginSmoothScroll);
35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginScrollBounce")))
35823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginScrollBounce);
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginPinch")))
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginPinch);
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginTap")))
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginTap);
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG")))
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG);
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache")))
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, ClearImageCache);
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark")))
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, RunMicroBenchmark);
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (name->Equals(
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SendMessageToMicroBenchmark")))
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SendMessageToMicroBenchmark);
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess")))
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, HasGpuProcess);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::Handle<v8::FunctionTemplate>();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetNeedsDisplayOnAllLayers(
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
381d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.compositor()->SetNeedsDisplayOnAllLayers();
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetRasterizeOnlyVisibleContent(
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.compositor()->SetRasterizeOnlyVisibleContent();
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void PrintToSkPicture(
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args.Length() != 1)
4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::String::Utf8Value dirname(args[0]);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dirname.length() == 0)
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
410d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const cc::Layer* root_layer = context.compositor()->GetRootLayer();
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!root_layer)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath dirpath(
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::StringType(*dirname, *dirname + dirname.length()));
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!base::CreateDirectory(dirpath) ||
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        !base::PathIsWritable(dirpath)) {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string msg("Path is not writable: ");
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      msg.append(dirpath.MaybeAsASCII());
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      v8::Isolate* isolate = args.GetIsolate();
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SkPictureSerializer serializer(dirpath);
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    serializer.Serialize(root_layer);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void OnSyntheticGestureCompleted(
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CallbackAndContext* callback_and_context) {
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate = callback_and_context->isolate();
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::HandleScope scope(isolate);
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Context::Scope context_scope(context);
436a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (frame) {
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback_and_context->GetCallback(),
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          v8::Object::New(isolate),
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          0,
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          NULL);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  static void GestureSourceTypeSupported(
4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const v8::FunctionCallbackInfo<v8::Value>& args) {
4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (args.Length() != 1 || !args[0]->IsNumber()) {
4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      args.GetReturnValue().Set(false);
4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int gesture_source_type = args[0]->IntegerValue();
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (gesture_source_type < 0 ||
4550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
4560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      args.GetReturnValue().Set(false);
4570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
4580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool is_supported = SyntheticGestureParams::IsGestureSourceTypeSupported(
4610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        static_cast<SyntheticGestureParams::GestureSourceType>(
4620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            gesture_source_type));
4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    args.GetReturnValue().Set(is_supported);
4647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginSmoothScroll(
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
4707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // The last two arguments can be undefined. We check their validity later.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int arglen = args.Length();
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (arglen < 8 ||
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[0]->IsNumber() ||
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[1]->IsFunction() ||
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[2]->IsNumber() ||
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[3]->IsString() ||
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[4]->IsNumber() ||
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[5]->IsBoolean()) {
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      args.GetReturnValue().Set(false);
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[1]);
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new SyntheticSmoothScrollGestureParams);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int gesture_source_type = args[2]->IntegerValue();
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (gesture_source_type < 0 ||
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      args.GetReturnValue().Set(false);
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->gesture_source_type =
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        static_cast<SyntheticGestureParams::GestureSourceType>(
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            gesture_source_type);
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
50923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->speed_in_pixels_s = args[4]->IntegerValue();
51023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->prevent_fling = args[5]->BooleanValue();
51123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
51223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Account for the 2 optional arguments, start_x and start_y.
51323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Point anchor;
51423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
51523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      blink::WebRect rect = context.render_view_impl()->windowRect();
51623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      anchor.SetPoint(rect.width / 2, rect.height / 2);
51723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
51823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      anchor.SetPoint(args[6]->IntegerValue() * page_scale_factor,
51923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                      args[7]->IntegerValue() * page_scale_factor);
52023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    } else {
52123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      args.GetReturnValue().Set(false);
52223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return;
52323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
52423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->anchor = anchor;
52523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
52623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int distance_length = args[0]->IntegerValue() * page_scale_factor;
52723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Vector2d distance;
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::String::Utf8Value direction(args[3]);
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(*direction);
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string direction_str(*direction);
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (direction_str == "down")
53223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_y(-distance_length);
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "up")
53423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_y(distance_length);
535a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "right")
53623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_x(-distance_length);
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "left")
53823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_x(distance_length);
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else {
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->distances.push_back(distance);
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
54623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
54723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // somehow.
54823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
54923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
55023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
55123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   callback_and_context));
55223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
55323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    args.GetReturnValue().Set(true);
55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
55523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
55623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  static void BeginScrollBounce(
55723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
55823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    GpuBenchmarkingContext context;
55923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (!context.Init(false))
56023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return;
56123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
56223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // The last two arguments can be undefined. We check their validity later.
56323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int arglen = args.Length();
56423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (arglen < 8 ||
56523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[0]->IsString() ||
56623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[1]->IsNumber() ||
56723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[2]->IsNumber() ||
56823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[3]->IsNumber() ||
56923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[4]->IsFunction() ||
57023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        !args[5]->IsNumber()) {
57123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      args.GetReturnValue().Set(false);
57223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return;
57323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
57423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
57523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
57623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        v8::Local<v8::Function>::Cast(args[4]);
57723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
57823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
57923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
58023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                               callback_local,
58123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
58223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
58323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
58423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        new SyntheticSmoothScrollGestureParams);
58523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
58623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
58723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
58823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
58923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->speed_in_pixels_s = args[5]->IntegerValue();
590a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
591a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Account for the 2 optional arguments, start_x and start_y.
59223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Point start;
593a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebRect rect = context.render_view_impl()->windowRect();
59523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      start.SetPoint(rect.width / 2, rect.height / 2);
596a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
59723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      start.SetPoint(args[6]->IntegerValue() * page_scale_factor,
59823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                     args[7]->IntegerValue() * page_scale_factor);
599a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
600a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int distance_length = args[1]->IntegerValue() * page_scale_factor;
60523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int overscroll_length = args[2]->IntegerValue() * page_scale_factor;
60623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Vector2d distance;
60723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gfx::Vector2d overscroll;
60823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    v8::String::Utf8Value direction(args[0]);
60923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(*direction);
61023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    std::string direction_str(*direction);
61123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (direction_str == "down") {
61223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_y(-distance_length);
61323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      overscroll.set_y(overscroll_length);
61423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
61523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    else if (direction_str == "up") {
61623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_y(distance_length);
61723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      overscroll.set_y(-overscroll_length);
61823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
61923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    else if (direction_str == "right") {
62023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_x(-distance_length);
62123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      overscroll.set_x(overscroll_length);
62223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
62323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    else if (direction_str == "left") {
62423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      distance.set_x(distance_length);
62523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      overscroll.set_x(-overscroll_length);
62623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
62723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    else {
62823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      args.GetReturnValue().Set(false);
62923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      return;
63023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
63123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
63223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int repeat_count = args[3]->IntegerValue();
63323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    gesture_params->anchor = start;
63423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    for (int i = 0; i < repeat_count; i++) {
63523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      gesture_params->distances.push_back(distance);
63623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      gesture_params->distances.push_back(-distance + overscroll);
63723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
63823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // somehow.
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   callback_and_context));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(true);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static void BeginPinch(
65158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
65368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
65458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
65558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
65658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int arglen = args.Length();
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (arglen < 5 ||
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !args[0]->IsNumber() ||
65958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[1]->IsNumber() ||
66058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[2]->IsNumber() ||
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !args[3]->IsFunction() ||
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !args[4]->IsNumber()) {
66358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      args.GetReturnValue().Set(false);
66458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
66558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
66658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SyntheticPinchGestureParams> gesture_params(
668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new SyntheticPinchGestureParams);
669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gesture_params->scale_factor = args[0]->NumberValue();
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->anchor.SetPoint(
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        args[1]->IntegerValue() * page_scale_factor,
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        args[2]->IntegerValue() * page_scale_factor);
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->relative_pointer_speed_in_pixels_s =
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        args[4]->IntegerValue();
67958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[3]);
68258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
68458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
68558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               callback_local,
686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
68758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // somehow.
692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
69558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   callback_and_context));
69658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
69758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    args.GetReturnValue().Set(true);
69858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
69958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static void BeginTap(
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GpuBenchmarkingContext context;
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!context.Init(false))
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int arglen = args.Length();
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (arglen < 5 ||
708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[0]->IsNumber() ||
709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[1]->IsNumber() ||
710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[2]->IsFunction() ||
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[3]->IsNumber() ||
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[4]->IsNumber()) {
713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
717a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SyntheticTapGestureParams> gesture_params(
718a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new SyntheticTapGestureParams);
719a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
720a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->position.SetPoint(
724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        args[0]->IntegerValue() * page_scale_factor,
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        args[1]->IntegerValue() * page_scale_factor);
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->duration_ms = args[3]->IntegerValue();
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int gesture_source_type = args[4]->IntegerValue();
729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (gesture_source_type < 0 ||
730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
731a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
732a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
733a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->gesture_source_type =
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        static_cast<SyntheticGestureParams::GestureSourceType>(
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            gesture_source_type);
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
739a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[2]);
740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
741a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
743a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               callback_local,
744a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
745a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
746a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
747a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
748a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
749a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // somehow.
750a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
752a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
753a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   callback_and_context));
754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
755a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    args.GetReturnValue().Set(true);
756a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
757a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Size& size,
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::vector<unsigned char>& png) {
761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Isolate* isolate = callback_and_context->isolate();
762a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::HandleScope scope(isolate);
763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Context::Scope context_scope(context);
765a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame) {
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> result;
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if(!size.IsEmpty()) {
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        v8::Handle<v8::Object> result_object;
772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object = v8::Object::New(isolate);
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
775a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::Number::New(isolate, size.width()));
776a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::Number::New(isolate, size.height()));
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string base64_png;
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Base64Encode(base::StringPiece(
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            reinterpret_cast<const char*>(&*png.begin()), png.size()),
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &base64_png);
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
784a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
785a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::String::NewFromUtf8(isolate,
786a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   base64_png.c_str(),
787a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   v8::String::kNormalString,
788a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   base64_png.size()));
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = result_object;
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
792a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result = v8::Null(isolate);
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { result };
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback_and_context->GetCallback(),
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          v8::Object::New(isolate),
8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          1,
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          argv);
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginWindowSnapshotPNG(
8067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
807d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
80868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!args[0]->IsFunction())
8127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[0]);
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
819868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
820d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.render_view_impl()->GetWindowSnapshot(
823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&OnSnapshotCompleted, callback_and_context));
824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void ClearImageCache(
8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebImageCache::clear();
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void OnMicroBenchmarkCompleted(
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      CallbackAndContext* callback_and_context,
8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<base::Value> result) {
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::Isolate* isolate = callback_and_context->isolate();
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    v8::HandleScope scope(isolate);
8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Context::Scope context_scope(context);
838a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebLocalFrame* frame = WebLocalFrame::frameForContext(context);
8394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (frame) {
8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<V8ValueConverter> converter =
8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          make_scoped_ptr(V8ValueConverter::create());
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { value };
8444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          callback_and_context->GetCallback(),
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          v8::Object::New(isolate),
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          1,
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          argv);
8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void RunMicroBenchmark(
8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GpuBenchmarkingContext context;
8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!context.Init(true)) {
857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      args.GetReturnValue().Set(0);
8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (args.Length() != 3 ||
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        !args[0]->IsString() ||
8638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !args[1]->IsFunction() ||
8648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !args[2]->IsObject()) {
865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      args.GetReturnValue().Set(0);
8664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
8674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        v8::Local<v8::Function>::Cast(args[1]);
8714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               callback_local,
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<V8ValueConverter> converter =
8788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        make_scoped_ptr(V8ValueConverter::create());
8798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<base::Value> value =
8818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        make_scoped_ptr(converter->FromV8Value(args[2], v8_context));
8828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::String::Utf8Value benchmark(args[0]);
8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(*benchmark);
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark(
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string(*benchmark),
8878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        value.Pass(),
8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&OnMicroBenchmarkCompleted, callback_and_context)));
8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
891cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static void SendMessageToMicroBenchmark(
892cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GpuBenchmarkingContext context;
894cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!context.Init(true)) {
895cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      args.GetReturnValue().Set(0);
896cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
897cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
898cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
899cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (args.Length() != 2 || !args[0]->IsNumber() || !args[1]->IsObject()) {
900cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      args.GetReturnValue().Set(0);
901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
902cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
903cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
904cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<V8ValueConverter> converter =
905cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        make_scoped_ptr(V8ValueConverter::create());
906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    v8::Handle<v8::Context> v8_context =
907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        context.web_frame()->mainWorldScriptContext();
908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<base::Value> value =
909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        make_scoped_ptr(converter->FromV8Value(args[1], v8_context));
910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int id = 0;
912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    converter->FromV8Value(args[0], v8_context)->GetAsInteger(&id);
913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    args.GetReturnValue().Set(
914cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        context.compositor()->SendMessageToMicroBenchmark(id, value.Pass()));
915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) {
9181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel();
9191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    args.GetReturnValue().Set(!!gpu_channel);
9201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)v8::Extension* GpuBenchmarkingExtension::Get() {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new GpuBenchmarkingWrapper();
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
928