gpu_benchmarking_extension.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.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"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/browser_rendering_stats.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_rendering_stats.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_gesture_params.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_pinch_gesture_params.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/common/input/synthetic_tap_gesture_params.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/renderer/v8_value_converter.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/gpu/render_widget_compositor.h"
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/renderer/skia_benchmarking_extension.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebImageCache.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkData.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkGraphics.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPixelRef.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkStream.h"
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCanvas;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebImageCache;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebPrivatePtr;
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebRenderingStatsImpl;
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSize;
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebView;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SkPixelRef* pr = bm.pixelRef();
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (pr != NULL) {
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        SkData* data = pr->refEncodedData();
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (data != NULL) {
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            *offset = bm.pixelRefOffset();
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            return data;
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<unsigned char> vector;
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return SkData::NewWithCopy(&vector.front() , vector.size());
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class SkPictureSerializer {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit SkPictureSerializer(const base::FilePath& dirpath)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : dirpath_(dirpath),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        layer_id_(0) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let skia register known effect subclasses. This basically enables
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reflection on those subclasses required for picture serialization.
74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    content::SkiaBenchmarkingExtension::InitSkGraphics();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Recursively serializes the layer tree.
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Each layer in the tree is serialized into a separate skp file
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the given directory.
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void Serialize(const cc::Layer* layer) {
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const cc::LayerList& children = layer->children();
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for (size_t i = 0; i < children.size(); ++i) {
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      Serialize(children[i].get());
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    skia::RefPtr<SkPicture> picture = layer->GetPicture();
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!picture)
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Serialize picture to file.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(alokp): Note that for this to work Chrome needs to be launched with
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // --no-sandbox command-line flag. Get rid of this limitation.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CRBUG: 139640.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!filepath.empty());
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkFILEWStream file(filepath.c_str());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(file.isValid());
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    picture->serialize(&file, &EncodeBitmapToData);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dirpath_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int layer_id_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RenderingStatsEnumerator(v8::Isolate* isolate,
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::Handle<v8::Object> stats_object)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : isolate(isolate), stats_object(stats_object) {}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt64(const char* name, int64 value) OVERRIDE {
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    stats_object->Set(v8::String::NewFromUtf8(isolate, name),
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      v8::Number::New(isolate, value));
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddDouble(const char* name, double value) OVERRIDE {
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    stats_object->Set(v8::String::NewFromUtf8(isolate, name),
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      v8::Number::New(isolate, value));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt(const char* name, int value) OVERRIDE {
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    stats_object->Set(v8::String::NewFromUtf8(isolate, name),
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      v8::Integer::New(value));
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddTimeDeltaInSecondsF(const char* name,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const base::TimeDelta& value) OVERRIDE {
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    stats_object->Set(v8::String::NewFromUtf8(isolate, name),
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      v8::Number::New(isolate, value.InSecondsF()));
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  v8::Isolate* isolate;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  v8::Handle<v8::Object> stats_object;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CallbackAndContext(v8::Isolate* isolate,
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Function> callback,
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Context> context)
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : isolate_(isolate) {
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Reset(isolate_, callback);
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context_.Reset(isolate_, context);
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate() {
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return isolate_;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Function> GetCallback() {
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Function>::New(isolate_, callback_);
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Context> GetContext() {
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Context>::New(isolate_, context_);
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  friend class base::RefCounted<CallbackAndContext>;
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~CallbackAndContext() {
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    callback_.Reset();
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_.Reset();
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate_;
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Function> callback_;
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Context> context_;
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackAndContext);
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class GpuBenchmarkingContext {
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  GpuBenchmarkingContext()
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      : web_frame_(NULL),
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        web_view_(NULL),
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        render_view_impl_(NULL),
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        compositor_(NULL) {}
188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool Init(bool init_compositor) {
190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    web_frame_ = WebFrame::frameForCurrentContext();
191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!web_frame_)
192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    web_view_ = web_frame_->view();
195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!web_view_) {
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    render_view_impl_ = RenderViewImpl::FromWebView(web_view_);
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!render_view_impl_) {
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_view_ = NULL;
204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!init_compositor)
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    compositor_ = render_view_impl_->compositor();
211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!compositor_) {
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_frame_ = NULL;
213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      web_view_ = NULL;
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      render_view_impl_ = NULL;
215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return true;
219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebFrame* web_frame() const {
222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(web_frame_ != NULL);
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return web_frame_;
224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebView* web_view() const {
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(web_view_ != NULL);
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return web_view_;
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderViewImpl* render_view_impl() const {
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(render_view_impl_ != NULL);
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return render_view_impl_;
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderWidgetCompositor* compositor() const {
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK(compositor_ != NULL);
235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return compositor_;
236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebFrame* web_frame_;
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WebView* web_view_;
241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderViewImpl* render_view_impl_;
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  RenderWidgetCompositor* compositor_;
24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuBenchmarkingWrapper : public v8::Extension {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuBenchmarkingWrapper() :
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Extension(kGpuBenchmarkingExtensionName,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome) == 'undefined') {"
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome = {};"
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome.gpuBenchmarking = {};"
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  native function SetNeedsDisplayOnAllLayers();"
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  return SetNeedsDisplayOnAllLayers();"
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "};"
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent = function() {"
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "  native function SetRasterizeOnlyVisibleContent();"
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "  return SetRasterizeOnlyVisibleContent();"
26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "};"
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.renderingStats = function() {"
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function GetRenderingStats();"
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return GetRenderingStats();"
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "chrome.gpuBenchmarking.gpuRenderingStats = function() {"
2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  native function GetGpuRenderingStats();"
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  return GetGpuRenderingStats();"
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "};"
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function PrintToSkPicture();"
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return PrintToSkPicture(dirname);"
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "chrome.gpuBenchmarking.DEFAULT_INPUT = 0;"
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "chrome.gpuBenchmarking.TOUCH_INPUT = 1;"
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "chrome.gpuBenchmarking.MOUSE_INPUT = 2;"
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.smoothScrollBy = "
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "    function(pixels_to_scroll, opt_callback, opt_start_x,"
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "             opt_start_y, opt_gesture_source_type,"
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "             opt_direction, opt_speed_in_pixels_s) {"
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  pixels_to_scroll = pixels_to_scroll || 0;"
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  callback = opt_callback || function() { };"
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "  gesture_source_type = opt_gesture_source_type ||"
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  direction = opt_direction || 'down';"
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function BeginSmoothScroll();"
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  return BeginSmoothScroll(pixels_to_scroll, callback,"
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           gesture_source_type, direction,"
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           speed_in_pixels_s, true,"
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           opt_start_x, opt_start_y);"
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          "chrome.gpuBenchmarking.smoothScrollBySendsTouch = function() {"
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          "  native function SmoothScrollSendsTouch();"
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          "  return SmoothScrollSendsTouch();"
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          "};"
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "chrome.gpuBenchmarking.swipe = "
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "    function(direction, distance, opt_callback,"
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "             opt_start_x, opt_start_y,"
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "             opt_speed_in_pixels_s) {"
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  direction = direction || 'up';"
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  distance = distance || 0;"
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  callback = opt_callback || function() { };"
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  speed_in_pixels_s = opt_speed_in_pixels_s || 800;"
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  native function BeginSmoothScroll();"
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  return BeginSmoothScroll(-distance, callback,"
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           chrome.gpuBenchmarking.TOUCH_INPUT,"
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           direction, speed_in_pixels_s, false,"
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                           opt_start_x, opt_start_y);"
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "};"
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "chrome.gpuBenchmarking.pinchBy = "
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "    function(zoom_in, pixels_to_cover, anchor_x, anchor_y,"
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "             opt_callback, opt_relative_pointer_speed_in_pixels_s) {"
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "  callback = opt_callback || function() { };"
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "  relative_pointer_speed_in_pixels_s ="
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "      opt_relative_pointer_speed_in_pixels_s || 800;"
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "  native function BeginPinch();"
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "  return BeginPinch(zoom_in, pixels_to_cover,"
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "                    anchor_x, anchor_y, callback,"
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          "                    relative_pointer_speed_in_pixels_s);"
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          "};"
327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "chrome.gpuBenchmarking.tap = "
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "    function(position_x, position_y, opt_callback, opt_duration_ms,"
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "             opt_gesture_source_type) {"
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  callback = opt_callback || function() { };"
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  duration_ms = opt_duration_ms || 0;"
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  gesture_source_type = opt_gesture_source_type ||"
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "      chrome.gpuBenchmarking.DEFAULT_INPUT;"
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  native function BeginTap();"
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "  return BeginTap(position_x, position_y, callback, duration_ms,"
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "                  gesture_source_type);"
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "};"
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "chrome.gpuBenchmarking.beginWindowSnapshotPNG = function(callback) {"
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  native function BeginWindowSnapshotPNG();"
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  BeginWindowSnapshotPNG(callback);"
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "};"
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome.gpuBenchmarking.clearImageCache = function() {"
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "  native function ClearImageCache();"
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "  ClearImageCache();"
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "};"
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "chrome.gpuBenchmarking.runMicroBenchmark ="
3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          "    function(name, callback, opt_arguments) {"
3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          "  arguments = opt_arguments || {};"
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          "  native function RunMicroBenchmark();"
3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          "  return RunMicroBenchmark(name, callback, arguments);"
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "};"
3521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "chrome.gpuBenchmarking.hasGpuProcess = function() {"
3531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  native function HasGpuProcess();"
3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          "  return HasGpuProcess();"
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};") {}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      v8::Isolate* isolate,
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::String> name) OVERRIDE {
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SetNeedsDisplayOnAllLayers")))
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SetNeedsDisplayOnAllLayers);
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SetRasterizeOnlyVisibleContent")))
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SetRasterizeOnlyVisibleContent);
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "GetRenderingStats")))
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, GetRenderingStats);
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "GetGpuRenderingStats")))
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, GetGpuRenderingStats);
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "PrintToSkPicture")))
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, PrintToSkPicture);
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginSmoothScroll")))
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginSmoothScroll);
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "SmoothScrollSendsTouch")))
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, SmoothScrollSendsTouch);
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginPinch")))
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginPinch);
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "BeginTap")))
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginTap);
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            v8::String::NewFromUtf8(isolate, "BeginWindowSnapshotPNG")))
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, BeginWindowSnapshotPNG);
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "ClearImageCache")))
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, ClearImageCache);
386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "RunMicroBenchmark")))
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, RunMicroBenchmark);
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (name->Equals(v8::String::NewFromUtf8(isolate, "HasGpuProcess")))
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return v8::FunctionTemplate::New(isolate, HasGpuProcess);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::Handle<v8::FunctionTemplate>();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetNeedsDisplayOnAllLayers(
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
400d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.compositor()->SetNeedsDisplayOnAllLayers();
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetRasterizeOnlyVisibleContent(
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
409d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.compositor()->SetRasterizeOnlyVisibleContent();
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void GetRenderingStats(
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebRenderingStatsImpl stats;
420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.render_view_impl()->GetRenderingStats(stats);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::GpuRenderingStats gpu_stats;
423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.render_view_impl()->GetGpuRenderingStats(&gpu_stats);
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    BrowserRenderingStats browser_stats;
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.render_view_impl()->GetBrowserRenderingStats(&browser_stats);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Object> stats_object = v8::Object::New();
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderingStatsEnumerator enumerator(args.GetIsolate(), stats_object);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.rendering_stats.EnumerateFields(&enumerator);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_stats.EnumerateFields(&enumerator);
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser_stats.EnumerateFields(&enumerator);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(stats_object);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static void GetGpuRenderingStats(
4371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
4381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GpuBenchmarkingContext context;
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!context.Init(false))
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return;
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    content::GpuRenderingStats gpu_stats;
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    context.render_view_impl()->GetGpuRenderingStats(&gpu_stats);
4451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Isolate* isolate = args.GetIsolate();
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Handle<v8::Object> stats_object = v8::Object::New(isolate);
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RenderingStatsEnumerator enumerator(isolate, stats_object);
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gpu_stats.EnumerateFields(&enumerator);
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    args.GetReturnValue().Set(stats_object);
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void PrintToSkPicture(
4557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args.Length() != 1)
4577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::String::Utf8Value dirname(args[0]);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dirname.length() == 0)
4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(true))
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const cc::Layer* root_layer = context.compositor()->GetRootLayer();
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!root_layer)
4697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath dirpath(
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::StringType(*dirname, *dirname + dirname.length()));
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!base::CreateDirectory(dirpath) ||
4747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        !base::PathIsWritable(dirpath)) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string msg("Path is not writable: ");
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      msg.append(dirpath.MaybeAsASCII());
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      v8::Isolate* isolate = args.GetIsolate();
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SkPictureSerializer serializer(dirpath);
4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    serializer.Serialize(root_layer);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static void OnSyntheticGestureCompleted(
488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CallbackAndContext* callback_and_context) {
489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::HandleScope scope(callback_and_context->isolate());
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Context::Scope context_scope(context);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (frame) {
494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          callback_and_context->GetCallback(), v8::Object::New(), 0, NULL);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void SmoothScrollSendsTouch(
5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const v8::FunctionCallbackInfo<v8::Value>& args) {
5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // TODO(epenner): Should other platforms emulate touch events?
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    args.GetReturnValue().Set(true);
5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else
5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    args.GetReturnValue().Set(false);
5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginSmoothScroll(
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // The last two arguments can be undefined. We check their validity later.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int arglen = args.Length();
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (arglen < 8 ||
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[0]->IsNumber() ||
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[1]->IsFunction() ||
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[2]->IsNumber() ||
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[3]->IsString() ||
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[4]->IsNumber() ||
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[5]->IsBoolean()) {
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      args.GetReturnValue().Set(false);
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[1]);
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SyntheticSmoothScrollGestureParams> gesture_params(
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new SyntheticSmoothScrollGestureParams);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int gesture_source_type = args[2]->IntegerValue();
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (gesture_source_type < 0 ||
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      args.GetReturnValue().Set(false);
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->gesture_source_type =
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        static_cast<SyntheticGestureParams::GestureSourceType>(
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            gesture_source_type);
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int distance = args[0]->IntegerValue() * page_scale_factor;
553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::String::Utf8Value direction(args[3]);
554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(*direction);
555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string direction_str(*direction);
556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (direction_str == "down")
557a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_params->distance.set_y(distance);
558a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "up")
559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_params->distance.set_y(-distance);
560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "right")
561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_params->distance.set_x(distance);
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else if (direction_str == "left")
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_params->distance.set_x(-distance);
564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    else {
565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
568a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->speed_in_pixels_s = args[4]->IntegerValue();
570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->prevent_fling = args[5]->BooleanValue();
571a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Account for the 2 optional arguments, start_x and start_y.
573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (args[6]->IsUndefined() || args[7]->IsUndefined()) {
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebRect rect = context.render_view_impl()->windowRect();
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      gesture_params->anchor.SetPoint(rect.x + rect.width / 2,
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      rect.y + rect.height / 2);
577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else if (args[6]->IsNumber() && args[7]->IsNumber()) {
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      gesture_params->anchor.SetPoint(
579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          args[6]->IntegerValue() * page_scale_factor,
580a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          args[7]->IntegerValue() * page_scale_factor);
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } else {
582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // somehow.
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   callback_and_context));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(true);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static void BeginPinch(
59858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
599d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
60158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
60258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int arglen = args.Length();
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (arglen < 6 ||
60558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[0]->IsBoolean() ||
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[1]->IsNumber() ||
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[2]->IsNumber() ||
60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        !args[3]->IsNumber() ||
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[4]->IsFunction() ||
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        !args[5]->IsNumber()) {
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      args.GetReturnValue().Set(false);
61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
61458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SyntheticPinchGestureParams> gesture_params(
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new SyntheticPinchGestureParams);
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->zoom_in = args[0]->BooleanValue();
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->total_num_pixels_covered =
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        args[1]->IntegerValue() * page_scale_factor;
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->anchor.SetPoint(
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        args[2]->IntegerValue() * page_scale_factor,
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        args[3]->IntegerValue() * page_scale_factor);
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gesture_params->relative_pointer_speed_in_pixels_s =
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        args[5]->IntegerValue();
62958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
63158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        v8::Local<v8::Function>::Cast(args[4]);
63258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
63458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
63558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                               callback_local,
636d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
63758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
64058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
64158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // somehow.
642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
64558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                   callback_and_context));
64658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
64758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    args.GetReturnValue().Set(true);
64858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
64958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
650a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static void BeginTap(
651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
652a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GpuBenchmarkingContext context;
653a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!context.Init(false))
654a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int arglen = args.Length();
657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (arglen < 5 ||
658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[0]->IsNumber() ||
659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[1]->IsNumber() ||
660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[2]->IsFunction() ||
661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[3]->IsNumber() ||
662a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        !args[4]->IsNumber()) {
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
664a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<SyntheticTapGestureParams> gesture_params(
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new SyntheticTapGestureParams);
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Convert coordinates from CSS pixels to density independent pixels (DIPs).
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    float page_scale_factor = context.web_view()->pageScaleFactor();
672a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
673a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->position.SetPoint(
674a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        args[0]->IntegerValue() * page_scale_factor,
675a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        args[1]->IntegerValue() * page_scale_factor);
676a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->duration_ms = args[3]->IntegerValue();
677a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
678a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int gesture_source_type = args[4]->IntegerValue();
679a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (gesture_source_type < 0 ||
680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
681a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      args.GetReturnValue().Set(false);
682a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
683a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
684a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_params->gesture_source_type =
685a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        static_cast<SyntheticGestureParams::GestureSourceType>(
686a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            gesture_source_type);
687a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
688a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
689a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[2]);
690a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
692a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
693a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               callback_local,
694a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // somehow.
700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context.render_view_impl()->QueueSyntheticGesture(
701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gesture_params.PassAs<SyntheticGestureParams>(),
702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Bind(&OnSyntheticGestureCompleted,
703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   callback_and_context));
704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    args.GetReturnValue().Set(true);
706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Size& size,
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::vector<unsigned char>& png) {
711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::Isolate* isolate = callback_and_context->isolate();
712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    v8::HandleScope scope(isolate);
713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Context::Scope context_scope(context);
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame) {
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> result;
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if(!size.IsEmpty()) {
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        v8::Handle<v8::Object> result_object;
722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object = v8::Object::New(isolate);
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "width"),
725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::Number::New(isolate, size.width()));
726a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "height"),
727a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::Number::New(isolate, size.height()));
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string base64_png;
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Base64Encode(base::StringPiece(
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            reinterpret_cast<const char*>(&*png.begin()), png.size()),
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &base64_png);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
734a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result_object->Set(v8::String::NewFromUtf8(isolate, "data"),
735a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           v8::String::NewFromUtf8(isolate,
736a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   base64_png.c_str(),
737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   v8::String::kNormalString,
738a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                   base64_png.size()));
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = result_object;
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        result = v8::Null(isolate);
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { result };
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginWindowSnapshotPNG(
7537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
754d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GpuBenchmarkingContext context;
75568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!context.Init(false))
7567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!args[0]->IsFunction())
7597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
762868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[0]);
763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
767d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
769d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    context.render_view_impl()->GetWindowSnapshot(
770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&OnSnapshotCompleted, callback_and_context));
771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void ClearImageCache(
7747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebImageCache::clear();
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void OnMicroBenchmarkCompleted(
7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      CallbackAndContext* callback_and_context,
7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<base::Value> result) {
7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::HandleScope scope(callback_and_context->isolate());
7824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Context::Scope context_scope(context);
7844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (frame) {
7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      scoped_ptr<V8ValueConverter> converter =
7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          make_scoped_ptr(V8ValueConverter::create());
7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { value };
7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static void RunMicroBenchmark(
7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    GpuBenchmarkingContext context;
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (!context.Init(true)) {
8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      args.GetReturnValue().Set(false);
8014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (args.Length() != 3 ||
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        !args[0]->IsString() ||
8068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !args[1]->IsFunction() ||
8078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        !args[2]->IsObject()) {
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      args.GetReturnValue().Set(false);
8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return;
8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        v8::Local<v8::Function>::Cast(args[1]);
8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               callback_local,
8184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               context.web_frame()->mainWorldScriptContext());
8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<V8ValueConverter> converter =
8218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        make_scoped_ptr(V8ValueConverter::create());
8228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    v8::Handle<v8::Context> v8_context = callback_and_context->GetContext();
8238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_ptr<base::Value> value =
8248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        make_scoped_ptr(converter->FromV8Value(args[2], v8_context));
8258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    v8::String::Utf8Value benchmark(args[0]);
8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(*benchmark);
8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark(
8294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        std::string(*benchmark),
8308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        value.Pass(),
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&OnMicroBenchmarkCompleted, callback_and_context)));
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static void HasGpuProcess(const v8::FunctionCallbackInfo<v8::Value>& args) {
8351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GpuChannelHost* gpu_channel = RenderThreadImpl::current()->GetGpuChannel();
8361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    args.GetReturnValue().Set(!!gpu_channel);
8371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)v8::Extension* GpuBenchmarkingExtension::Get() {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new GpuBenchmarkingWrapper();
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
845