gpu_benchmarking_extension.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_number_conversions.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_rendering_stats.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/all_rendering_benchmarks.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/gpu/render_widget_compositor.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/rendering_benchmark.h"
20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "content/renderer/skia_benchmarking_extension.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkGraphics.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPicture.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkStream.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/WebKit/chromium/public/WebViewBenchmarkSupport.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "webkit/compositor_bindings/web_rendering_stats_impl.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebCanvas;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebFrame;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebPrivatePtr;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using WebKit::WebRenderingStatsImpl;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebSize;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebView;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebViewBenchmarkSupport;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGpuBenchmarkingExtensionName[] = "v8/GpuBenchmarking";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static bool PNGEncodeBitmapToStream(SkWStream* stream, const SkBitmap& bm) {
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<unsigned char> vector;
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (gfx::PNGCodec::EncodeBGRASkBitmap(bm, true, &vector)) {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (stream->write(&vector.front() , vector.size()))
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            return true;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SkPictureRecorder : public WebViewBenchmarkSupport::PaintClient {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit SkPictureRecorder(const base::FilePath& dirpath)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : dirpath_(dirpath),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        layer_id_(0) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let skia register known effect subclasses. This basically enables
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reflection on those subclasses required for picture serialization.
59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    content::SkiaBenchmarkingExtension::InitSkGraphics();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebCanvas* willPaint(const WebSize& size) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return picture_.beginRecording(size.width, size.height);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void didPaint(WebCanvas* canvas) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(canvas == picture_.getRecordingCanvas());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    picture_.endRecording();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Serialize picture to file.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(alokp): Note that for this to work Chrome needs to be launched with
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // --no-sandbox command-line flag. Get rid of this limitation.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // CRBUG: 139640.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!filepath.empty());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkFILEWStream file(filepath.c_str());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(file.isValid());
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    picture_.serialize(&file, &PNGEncodeBitmapToStream);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dirpath_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int layer_id_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPicture picture_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RenderingStatsEnumerator : public cc::RenderingStats::Enumerator {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RenderingStatsEnumerator(v8::Handle<v8::Object> stats_object)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : stats_object(stats_object) { }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt64(const char* name, int64 value) OVERRIDE {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Number::New(value));
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddDouble(const char* name, double value) OVERRIDE {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Number::New(value));
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddInt(const char* name, int value) OVERRIDE {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name), v8::Integer::New(value));
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddTimeDeltaInSecondsF(const char* name,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      const base::TimeDelta& value) OVERRIDE {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats_object->Set(v8::String::New(name),
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      v8::Number::New(value.InSecondsF()));
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  v8::Handle<v8::Object> stats_object;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuBenchmarkingWrapper : public v8::Extension {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuBenchmarkingWrapper() :
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Extension(kGpuBenchmarkingExtensionName,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome) == 'undefined') {"
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome = {};"
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "if (typeof(chrome.gpuBenchmarking) == 'undefined') {"
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  chrome.gpuBenchmarking = {};"
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers = function() {"
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  native function SetNeedsDisplayOnAllLayers();"
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "  return SetNeedsDisplayOnAllLayers();"
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "};"
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.renderingStats = function() {"
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function GetRenderingStats();"
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return GetRenderingStats();"
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.printToSkPicture = function(dirname) {"
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function PrintToSkPicture();"
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return PrintToSkPicture(dirname);"
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.smoothScrollBy = "
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    function(pixels_to_scroll, opt_callback, opt_mouse_event_x,"
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "             opt_mouse_event_y) {"
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  pixels_to_scroll = pixels_to_scroll || 0;"
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  callback = opt_callback || function() { };"
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function BeginSmoothScroll();"
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  if (typeof opt_mouse_event_x !== 'undefined' &&"
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "      typeof opt_mouse_event_y !== 'undefined') {"
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             Math.abs(pixels_to_scroll),"
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             opt_mouse_event_x, opt_mouse_event_y);"
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  } else {"
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "    return BeginSmoothScroll(pixels_to_scroll >= 0, callback,"
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "                             Math.abs(pixels_to_scroll));"
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  }"
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};"
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "chrome.gpuBenchmarking.runRenderingBenchmarks = function(filter) {"
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  native function RunRenderingBenchmarks();"
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "  return RunRenderingBenchmarks(filter);"
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "};"
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "chrome.gpuBenchmarking.beginWindowSnapshotPNG = function(callback) {"
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  native function BeginWindowSnapshotPNG();"
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "  BeginWindowSnapshotPNG(callback);"
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "};") {}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::String> name) OVERRIDE {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (name->Equals(v8::String::New("SetNeedsDisplayOnAllLayers")))
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::FunctionTemplate::New(SetNeedsDisplayOnAllLayers);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("GetRenderingStats")))
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(GetRenderingStats);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("PrintToSkPicture")))
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(PrintToSkPicture);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("BeginSmoothScroll")))
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(BeginSmoothScroll);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name->Equals(v8::String::New("RunRenderingBenchmarks")))
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::FunctionTemplate::New(RunRenderingBenchmarks);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (name->Equals(v8::String::New("BeginWindowSnapshotPNG")))
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::FunctionTemplate::New(BeginWindowSnapshotPNG);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::Handle<v8::FunctionTemplate>();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static v8::Handle<v8::Value> SetNeedsDisplayOnAllLayers(
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const v8::Arguments& args) {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!web_frame)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::Undefined();
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WebView* web_view = web_frame->view();
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!web_view)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::Undefined();
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!render_view_impl)
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::Undefined();
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RenderWidgetCompositor* compositor = render_view_impl->compositor();
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!compositor)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return v8::Undefined();
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    compositor->SetNeedsDisplayOnAllLayers();
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return v8::Undefined();
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static v8::Handle<v8::Value> GetRenderingStats(const v8::Arguments& args) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!render_view_impl)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebRenderingStatsImpl stats;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->GetRenderingStats(stats);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::GpuRenderingStats gpu_stats;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->GetGpuRenderingStats(&gpu_stats);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Object> stats_object = v8::Object::New();
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderingStatsEnumerator enumerator(stats_object);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stats.rendering_stats.EnumerateFields(&enumerator);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_stats.EnumerateFields(&enumerator);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return stats_object;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static v8::Handle<v8::Value> PrintToSkPicture(const v8::Arguments& args) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args.Length() != 1)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::String::AsciiValue dirname(args[0]);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dirname.length() == 0)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebViewBenchmarkSupport* benchmark_support = web_view->benchmarkSupport();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!benchmark_support)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath dirpath(
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::StringType(*dirname, *dirname + dirname.length()));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!file_util::CreateDirectory(dirpath) ||
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !file_util::PathIsWritable(dirpath)) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string msg("Path is not writable: ");
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      msg.append(dirpath.MaybeAsASCII());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::ThrowException(v8::Exception::Error(
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          v8::String::New(msg.c_str(), msg.length())));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPictureRecorder recorder(dirpath);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    benchmark_support->paint(&recorder,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             WebViewBenchmarkSupport::PaintModeEverything);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::Undefined();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void OnSmoothScrollCompleted(v8::Persistent<v8::Function> callback,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      v8::Persistent<v8::Context> context) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::HandleScope scope;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Context::Scope context_scope(context);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (frame) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(callback,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              v8::Object::New(),
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              0,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              NULL);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Isolate* isolate = context->GetIsolate();
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Dispose(isolate);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context.Dispose(isolate);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static v8::Handle<v8::Value> BeginSmoothScroll(const v8::Arguments& args) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!render_view_impl)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Account for the 2 optional arguments, mouse_event_x and mouse_event_y.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int arglen = args.Length();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (arglen < 3 ||
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[0]->IsBoolean() ||
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[1]->IsFunction() ||
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !args[2]->IsNumber())
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::False();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool scroll_down = args[0]->BooleanValue();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Local<v8::Function> callback_local =
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        v8::Local<v8::Function>(v8::Function::Cast(*args[1]));
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Isolate* isolate = args.GetIsolate();
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    v8::Persistent<v8::Function> callback(isolate, callback_local);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    v8::Persistent<v8::Context> context(isolate,
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        web_frame->mainWorldScriptContext());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pixels_to_scroll = args[2]->IntegerValue();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mouse_event_x = 0;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int mouse_event_y = 0;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (arglen == 3) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebKit::WebRect rect = render_view_impl->windowRect();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event_x = rect.x + rect.width / 2;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_event_y = rect.y + rect.height / 2;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (arglen != 5 ||
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !args[3]->IsNumber() ||
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !args[4]->IsNumber())
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return v8::False();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_event_x = args[3]->IntegerValue() * web_view->pageScaleFactor();
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mouse_event_y = args[4]->IntegerValue() * web_view->pageScaleFactor();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): If the render_view_impl is destroyed while the gesture is in
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // progress, we will leak the callback and context. This needs to be fixed,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // somehow.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    render_view_impl->BeginSmoothScroll(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        scroll_down,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&OnSmoothScrollCompleted,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   context),
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pixels_to_scroll,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_event_x,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mouse_event_y);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return v8::True();
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static v8::Handle<v8::Value> RunRenderingBenchmarks(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const v8::Arguments& args) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // For our name filter, the argument can be undefined or null to run
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // all benchmarks, or a string for filtering by name.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!args.Length() ||
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (!args[0]->IsString() &&
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         !(args[0]->IsNull() || args[0]->IsUndefined()))) {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name_filter;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (args[0]->IsNull() || args[0]->IsUndefined()) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_filter = "";
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char filter[256];
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      args[0]->ToString()->WriteUtf8(filter, sizeof(filter)-1);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_filter = std::string(filter);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_frame)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebView* web_view = web_frame->view();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_view)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebViewBenchmarkSupport* support = web_view->benchmarkSupport();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!support)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return v8::Undefined();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<RenderingBenchmark> benchmarks = AllRenderingBenchmarks();
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v8::Handle<v8::Array> results = v8::Array::New(0);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedVector<RenderingBenchmark>::const_iterator it;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (it = benchmarks.begin(); it != benchmarks.end(); it++) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderingBenchmark* benchmark = *it;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& name = benchmark->name();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (name_filter != "" &&
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          std::string::npos == name.find(name_filter)) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      benchmark->SetUp(support);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      double result = benchmark->Run(support);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      benchmark->TearDown(support);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v8::Handle<v8::Object> result_object = v8::Object::New();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_object->Set(v8::String::New("benchmark", 9),
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         v8::String::New(name.c_str(), -1));
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_object->Set(v8::String::New("result", 6), v8::Number::New(result));
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results->Set(results->Length(), result_object);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return results;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void OnSnapshotCompleted(v8::Persistent<v8::Function> callback,
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  v8::Persistent<v8::Context> context,
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const gfx::Size& size,
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::vector<unsigned char>& png) {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::HandleScope scope;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Context::Scope context_scope(context);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebFrame* frame = WebFrame::frameForContext(context);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frame) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> result;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if(!size.IsEmpty()) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        v8::Handle<v8::Object> result_object;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object = v8::Object::New();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("width"),
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           v8::Number::New(size.width()));
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("height"),
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           v8::Number::New(size.height()));
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        std::string base64_png;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Base64Encode(base::StringPiece(
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            reinterpret_cast<const char*>(&*png.begin()), png.size()),
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &base64_png);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_object->Set(v8::String::New("data"),
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            v8::String::New(base64_png.c_str(), base64_png.size()));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = result_object;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = v8::Null();
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      v8::Handle<v8::Value> argv[] = { result };
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      frame->callFunctionEvenIfScriptDisabled(callback,
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              v8::Object::New(),
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              1,
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              argv);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Isolate* isolate = context->GetIsolate();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Dispose(isolate);
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context.Dispose(isolate);
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static v8::Handle<v8::Value> BeginWindowSnapshotPNG(
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const v8::Arguments& args) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebFrame* web_frame = WebFrame::frameForCurrentContext();
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!web_frame)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::Undefined();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebView* web_view = web_frame->view();
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!web_view)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::Undefined();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewImpl* render_view_impl = RenderViewImpl::FromWebView(web_view);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!render_view_impl)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::Undefined();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!args[0]->IsFunction())
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return v8::Undefined();
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Local<v8::Function> callback_local =
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        v8::Local<v8::Function>(v8::Function::Cast(*args[0]));
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    v8::Isolate* isolate = args.GetIsolate();
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    v8::Persistent<v8::Function> callback(isolate, callback_local);
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    v8::Persistent<v8::Context> context(isolate,
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        web_frame->mainWorldScriptContext());
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    render_view_impl->GetWindowSnapshot(
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&OnSnapshotCompleted, callback, context));
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return v8::Undefined();
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)v8::Extension* GpuBenchmarkingExtension::Get() {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new GpuBenchmarkingWrapper();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
486