gpu_benchmarking_extension.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/common/browser_rendering_stats.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_rendering_stats.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/all_rendering_benchmarks.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/gpu/render_widget_compositor.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/rendering_benchmark.h"
21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/renderer/skia_benchmarking_extension.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebImageCache.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebViewBenchmarkSupport.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkData.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkGraphics.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkPixelRef.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/skia/include/core/SkStream.h"
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebCanvas;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebFrame;
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using WebKit::WebImageCache;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebPrivatePtr;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using WebKit::WebRenderingStatsImpl;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebSize;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebView;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebViewBenchmarkSupport;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static SkData* EncodeBitmapToData(size_t* offset, const SkBitmap& bm) {
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SkPixelRef* pr = bm.pixelRef();
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (pr != NULL) {
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        SkData* data = pr->refEncodedData();
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (data != NULL) {
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            *offset = bm.pixelRefOffset();
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            return data;
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<unsigned char> vector;
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &vector)) {
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        return SkData::NewWithCopy(&vector.front() , vector.size());
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return NULL;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SkPictureRecorder : public WebViewBenchmarkSupport::PaintClient {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SkPictureRecorder(const base::FilePath& dirpath)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : dirpath_(dirpath),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        layer_id_(0) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let skia register known effect subclasses. This basically enables
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reflection on those subclasses required for picture serialization.
71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    content::SkiaBenchmarkingExtension::InitSkGraphics();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebCanvas* willPaint(const WebSize& size) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return picture_.beginRecording(size.width, size.height);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didPaint(WebCanvas* canvas) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(canvas == picture_.getRecordingCanvas());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    picture_.endRecording();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Serialize picture to file.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(alokp): Note that for this to work Chrome needs to be launched with
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // --no-sandbox command-line flag. Get rid of this limitation.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CRBUG: 139640.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!filepath.empty());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkFILEWStream file(filepath.c_str());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(file.isValid());
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    picture_.serialize(&file, &EncodeBitmapToData);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dirpath_;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int layer_id_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPicture picture_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderingStatsEnumerator(v8::Handle<v8::Object> stats_object)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : stats_object(stats_object) { }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt64(const char* name, int64 value) OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Number::New(value));
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddDouble(const char* name, double value) OVERRIDE {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Number::New(value));
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt(const char* name, int value) OVERRIDE {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Integer::New(value));
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddTimeDeltaInSecondsF(const char* name,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const base::TimeDelta& value) OVERRIDE {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name),
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      v8::Number::New(value.InSecondsF()));
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  v8::Handle<v8::Object> stats_object;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace {
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CallbackAndContext(v8::Isolate* isolate,
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Function> callback,
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     v8::Handle<v8::Context> context)
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : isolate_(isolate) {
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Reset(isolate_, callback);
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context_.Reset(isolate_, context);
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate() {
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return isolate_;
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Function> GetCallback() {
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Function>::New(isolate_, callback_);
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Handle<v8::Context> GetContext() {
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return v8::Local<v8::Context>::New(isolate_, context_);
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  friend class base::RefCounted<CallbackAndContext>;
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~CallbackAndContext() {
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Dispose();
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context_.Dispose();
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Isolate* isolate_;
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Function> callback_;
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  v8::Persistent<v8::Context> context_;
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CallbackAndContext);
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuBenchmarkingWrapper : public v8::Extension {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuBenchmarkingWrapper() :
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Extension(kGpuBenchmarkingExtensionName,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome) == 'undefined') {"
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome = {};"
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome.gpuBenchmarking = {};"
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  native function SetNeedsDisplayOnAllLayers();"
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  return SetNeedsDisplayOnAllLayers();"
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "};"
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent = function() {"
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "  native function SetRasterizeOnlyVisibleContent();"
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "  return SetRasterizeOnlyVisibleContent();"
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          "};"
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.renderingStats = function() {"
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function GetRenderingStats();"
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return GetRenderingStats();"
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function PrintToSkPicture();"
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return PrintToSkPicture(dirname);"
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.smoothScrollBy = "
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    function(pixels_to_scroll, opt_callback, opt_mouse_event_x,"
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "             opt_mouse_event_y) {"
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  pixels_to_scroll = pixels_to_scroll || 0;"
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  callback = opt_callback || function() { };"
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function BeginSmoothScroll();"
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  if (typeof opt_mouse_event_x !== 'undefined' &&"
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "      typeof opt_mouse_event_y !== 'undefined') {"
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             Math.abs(pixels_to_scroll),"
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             opt_mouse_event_x, opt_mouse_event_y);"
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  } else {"
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             Math.abs(pixels_to_scroll));"
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  }"
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.runRenderingBenchmarks = function(filter) {"
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function RunRenderingBenchmarks();"
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return RunRenderingBenchmarks(filter);"
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "};"
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "chrome.gpuBenchmarking.beginWindowSnapshotPNG = function(callback) {"
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  native function BeginWindowSnapshotPNG();"
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  BeginWindowSnapshotPNG(callback);"
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "};"
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "chrome.gpuBenchmarking.clearImageCache = function() {"
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "  native function ClearImageCache();"
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          "  ClearImageCache();"
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};") {}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::String> name) OVERRIDE {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (name->Equals(v8::String::New("SetNeedsDisplayOnAllLayers")))
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::FunctionTemplate::New(SetNeedsDisplayOnAllLayers);
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (name->Equals(v8::String::New("SetRasterizeOnlyVisibleContent")))
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return v8::FunctionTemplate::New(SetRasterizeOnlyVisibleContent);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("GetRenderingStats")))
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(GetRenderingStats);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("PrintToSkPicture")))
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(PrintToSkPicture);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("BeginSmoothScroll")))
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(BeginSmoothScroll);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("RunRenderingBenchmarks")))
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(RunRenderingBenchmarks);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (name->Equals(v8::String::New("BeginWindowSnapshotPNG")))
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::FunctionTemplate::New(BeginWindowSnapshotPNG);
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (name->Equals(v8::String::New("ClearImageCache")))
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return v8::FunctionTemplate::New(ClearImageCache);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::Handle<v8::FunctionTemplate>();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetNeedsDisplayOnAllLayers(
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!web_frame)
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebView* web_view = web_frame->view();
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!web_view)
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!render_view_impl)
2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderWidgetCompositor* compositor = render_view_impl->compositor();
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!compositor)
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    compositor->SetNeedsDisplayOnAllLayers();
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void SetRasterizeOnlyVisibleContent(
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!web_frame)
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WebView* web_view = web_frame->view();
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!web_view)
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!render_view_impl)
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    RenderWidgetCompositor* compositor = render_view_impl->compositor();
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!compositor)
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    compositor->SetRasterizeOnlyVisibleContent();
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void GetRenderingStats(
2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!render_view_impl)
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebRenderingStatsImpl stats;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->GetRenderingStats(stats);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::GpuRenderingStats gpu_stats;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->GetGpuRenderingStats(&gpu_stats);
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    BrowserRenderingStats browser_stats;
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    render_view_impl->GetBrowserRenderingStats(&browser_stats);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Object> stats_object = v8::Object::New();
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderingStatsEnumerator enumerator(stats_object);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.rendering_stats.EnumerateFields(&enumerator);
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_stats.EnumerateFields(&enumerator);
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser_stats.EnumerateFields(&enumerator);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(stats_object);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void PrintToSkPicture(
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args.Length() != 1)
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::String::AsciiValue dirname(args[0]);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dirname.length() == 0)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebViewBenchmarkSupport* benchmark_support = web_view->benchmarkSupport();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!benchmark_support)
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath dirpath(
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::StringType(*dirname, *dirname + dirname.length()));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!file_util::CreateDirectory(dirpath) ||
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !file_util::PathIsWritable(dirpath)) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string msg("Path is not writable: ");
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      msg.append(dirpath.MaybeAsASCII());
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      v8::ThrowException(v8::Exception::Error(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          v8::String::New(msg.c_str(), msg.length())));
3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPictureRecorder recorder(dirpath);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    benchmark_support->paint(&recorder,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             WebViewBenchmarkSupport::PaintModeEverything);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static void OnSmoothScrollCompleted(
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CallbackAndContext* callback_and_context) {
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::HandleScope scope(callback_and_context->isolate());
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Context::Scope context_scope(context);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (frame) {
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          callback_and_context->GetCallback(), v8::Object::New(), 0, NULL);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginSmoothScroll(
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!render_view_impl)
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Account for the 2 optional arguments, mouse_event_x and mouse_event_y.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int arglen = args.Length();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (arglen < 3 ||
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[0]->IsBoolean() ||
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[1]->IsFunction() ||
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        !args[2]->IsNumber()) {
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      args.GetReturnValue().Set(false);
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool scroll_down = args[0]->BooleanValue();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[1]);
397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               web_frame->mainWorldScriptContext());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pixels_to_scroll = args[2]->IntegerValue();
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mouse_event_x = 0;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mouse_event_y = 0;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (arglen == 3) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebKit::WebRect rect = render_view_impl->windowRect();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event_x = rect.x + rect.width / 2;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event_y = rect.y + rect.height / 2;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (arglen != 5 ||
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !args[3]->IsNumber() ||
4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          !args[4]->IsNumber()) {
4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        args.GetReturnValue().Set(false);
4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return;
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_event_x = args[3]->IntegerValue() * web_view->pageScaleFactor();
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_event_y = args[4]->IntegerValue() * web_view->pageScaleFactor();
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // somehow.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->BeginSmoothScroll(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        scroll_down,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&OnSmoothScrollCompleted,
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   callback_and_context),
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pixels_to_scroll,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_event_x,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_event_y);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(true);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void RunRenderingBenchmarks(
4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For our name filter, the argument can be undefined or null to run
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // all benchmarks, or a string for filtering by name.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!args.Length() ||
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (!args[0]->IsString() &&
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !(args[0]->IsNull() || args[0]->IsUndefined()))) {
4457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name_filter;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args[0]->IsNull() || args[0]->IsUndefined()) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_filter = "";
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char filter[256];
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      args[0]->ToString()->WriteUtf8(filter, sizeof(filter)-1);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_filter = std::string(filter);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebViewBenchmarkSupport* support = web_view->benchmarkSupport();
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!support)
4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<RenderingBenchmark> benchmarks = AllRenderingBenchmarks();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Array> results = v8::Array::New(0);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<RenderingBenchmark>::const_iterator it;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (it = benchmarks.begin(); it != benchmarks.end(); it++) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderingBenchmark* benchmark = *it;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& name = benchmark->name();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (name_filter != "" &&
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::string::npos == name.find(name_filter)) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      benchmark->SetUp(support);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      double result = benchmark->Run(support);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      benchmark->TearDown(support);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Handle<v8::Object> result_object = v8::Object::New();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_object->Set(v8::String::New("benchmark", 9),
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         v8::String::New(name.c_str(), -1));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_object->Set(v8::String::New("result", 6), v8::Number::New(result));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results->Set(results->Length(), result_object);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    args.GetReturnValue().Set(results);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  static void OnSnapshotCompleted(CallbackAndContext* callback_and_context,
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Size& size,
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::vector<unsigned char>& png) {
497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::HandleScope scope(callback_and_context->isolate());
498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    v8::Handle<v8::Context> context = callback_and_context->GetContext();
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Context::Scope context_scope(context);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame) {
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> result;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if(!size.IsEmpty()) {
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        v8::Handle<v8::Object> result_object;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object = v8::Object::New();
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("width"),
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           v8::Number::New(size.width()));
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("height"),
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           v8::Number::New(size.height()));
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string base64_png;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Base64Encode(base::StringPiece(
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            reinterpret_cast<const char*>(&*png.begin()), png.size()),
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &base64_png);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("data"),
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            v8::String::New(base64_png.c_str(), base64_png.size()));
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = result_object;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = v8::Null();
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { result };
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void BeginWindowSnapshotPNG(
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!web_frame)
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebView* web_view = web_frame->view();
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!web_view)
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!render_view_impl)
5467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!args[0]->IsFunction())
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return;
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        v8::Local<v8::Function>::Cast(args[0]);
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<CallbackAndContext> callback_and_context =
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new CallbackAndContext(args.GetIsolate(),
556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               callback_local,
557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               web_frame->mainWorldScriptContext());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    render_view_impl->GetWindowSnapshot(
560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&OnSnapshotCompleted, callback_and_context));
561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static void ClearImageCache(
5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const v8::FunctionCallbackInfo<v8::Value>& args) {
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebImageCache::clear();
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)v8::Extension* GpuBenchmarkingExtension::Get() {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new GpuBenchmarkingWrapper();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
574