summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 01:30:29 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 01:30:29 +0000
commit666d7cffc8025696c6743889fcd4c9bb2980ba70 (patch)
tree3372cd68db769e6ec1649998d17ff697feadb577
parentd31c53449787ba09aaea6251d9ac878669218817 (diff)
downloadchromium_src-666d7cffc8025696c6743889fcd4c9bb2980ba70.zip
chromium_src-666d7cffc8025696c6743889fcd4c9bb2980ba70.tar.gz
chromium_src-666d7cffc8025696c6743889fcd4c9bb2980ba70.tar.bz2
cc: Add MicroBenchmarkController plumbing.
This patch adds the necessary plumbing for micro benchmark controller. The plan is as follows: - MicroBenchmarkController will live on LayerTreeHost - The schedule functionality will be exposed to gpu benchmarking extension - Javascript bindings will allow external code to schedule certain benchmarks (specified by name) to be run right after Layer::Update. R=enne@chromium.org,nduca@chromium.org Review URL: https://codereview.chromium.org/26593002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228299 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/cc.gyp2
-rw-r--r--cc/cc_tests.gyp3
-rw-r--r--cc/debug/micro_benchmark.cc2
-rw-r--r--cc/debug/micro_benchmark_controller.cc3
-rw-r--r--cc/debug/micro_benchmark_controller_unittest.cc99
-rw-r--r--cc/debug/unittest_only_benchmark.cc19
-rw-r--r--cc/debug/unittest_only_benchmark.h23
-rw-r--r--cc/layers/layer.cc4
-rw-r--r--cc/layers/layer.h3
-rw-r--r--cc/test/fake_layer_tree_host.cc34
-rw-r--r--cc/test/fake_layer_tree_host.h39
-rw-r--r--cc/trees/layer_tree_host.cc14
-rw-r--r--cc/trees/layer_tree_host.h11
-rw-r--r--content/renderer/gpu/gpu_benchmarking_extension.cc56
-rw-r--r--content/renderer/gpu/render_widget_compositor.cc12
-rw-r--r--content/renderer/gpu/render_widget_compositor.h4
16 files changed, 302 insertions, 26 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index aafaf74..f3a5cf9 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -107,6 +107,8 @@
'debug/traced_picture.h',
'debug/traced_value.cc',
'debug/traced_value.h',
+ 'debug/unittest_only_benchmark.cc',
+ 'debug/unittest_only_benchmark.h',
'input/input_handler.h',
'input/page_scale_animation.cc',
'input/page_scale_animation.h',
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index ca2e861..8763184 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -19,6 +19,7 @@
'base/scoped_ptr_vector_unittest.cc',
'base/tiling_data_unittest.cc',
'base/util_unittest.cc',
+ 'debug/micro_benchmark_controller_unittest.cc',
'input/top_controls_manager_unittest.cc',
'layers/content_layer_unittest.cc',
'layers/contents_scaling_layer_unittest.cc',
@@ -116,6 +117,8 @@
'test/fake_layer_tree_host_impl_client.cc',
'test/fake_layer_tree_host_impl_client.h',
'test/fake_layer_tree_host_impl.h',
+ 'test/fake_layer_tree_host.cc',
+ 'test/fake_layer_tree_host.h',
'test/fake_painted_scrollbar_layer.cc',
'test/fake_painted_scrollbar_layer.h',
'test/fake_picture_layer.cc',
diff --git a/cc/debug/micro_benchmark.cc b/cc/debug/micro_benchmark.cc
index fe9bf97..1742e7f 100644
--- a/cc/debug/micro_benchmark.cc
+++ b/cc/debug/micro_benchmark.cc
@@ -11,7 +11,7 @@
namespace cc {
MicroBenchmark::MicroBenchmark(const DoneCallback& callback)
- : callback_(callback) {}
+ : callback_(callback), is_done_(false) {}
MicroBenchmark::~MicroBenchmark() {}
diff --git a/cc/debug/micro_benchmark_controller.cc b/cc/debug/micro_benchmark_controller.cc
index 35b4585..a8af78c 100644
--- a/cc/debug/micro_benchmark_controller.cc
+++ b/cc/debug/micro_benchmark_controller.cc
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/values.h"
+#include "cc/debug/unittest_only_benchmark.h"
#include "cc/trees/layer_tree_host.h"
namespace cc {
@@ -18,6 +19,8 @@ scoped_ptr<MicroBenchmark> CreateBenchmark(
const std::string& name,
const MicroBenchmark::DoneCallback& callback) {
// TODO(vmpstr): Add benchmarks.
+ if (name == "unittest_only_benchmark")
+ return scoped_ptr<MicroBenchmark>(new UnittestOnlyBenchmark(callback));
return scoped_ptr<MicroBenchmark>();
}
diff --git a/cc/debug/micro_benchmark_controller_unittest.cc b/cc/debug/micro_benchmark_controller_unittest.cc
new file mode 100644
index 0000000..6efc38e
--- /dev/null
+++ b/cc/debug/micro_benchmark_controller_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/debug/micro_benchmark.h"
+#include "cc/debug/micro_benchmark_controller.h"
+#include "cc/layers/layer.h"
+#include "cc/resources/resource_update_queue.h"
+#include "cc/test/fake_layer_tree_host.h"
+#include "cc/test/fake_proxy.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+class MicroBenchmarkControllerTest : public testing::Test {
+ public:
+ virtual void SetUp() {
+ layer_tree_host_ = FakeLayerTreeHost::Create();
+ layer_tree_host_->SetRootLayer(Layer::Create());
+ layer_tree_host_->InitializeForTesting(
+ scoped_ptr<Proxy>(new FakeProxy));
+ }
+
+ scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
+};
+
+void Noop(scoped_ptr<base::Value> value) {
+}
+
+void IncrementCallCount(int* count, scoped_ptr<base::Value> value) {
+ ++(*count);
+}
+
+TEST_F(MicroBenchmarkControllerTest, ScheduleFail) {
+ bool result = layer_tree_host_->ScheduleMicroBenchmark(
+ "non_existant_benchmark", base::Bind(&Noop));
+ EXPECT_FALSE(result);
+}
+
+TEST_F(MicroBenchmarkControllerTest, CommitScheduled) {
+ EXPECT_FALSE(layer_tree_host_->needs_commit());
+ bool result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark", base::Bind(&Noop));
+ EXPECT_TRUE(result);
+ EXPECT_TRUE(layer_tree_host_->needs_commit());
+}
+
+TEST_F(MicroBenchmarkControllerTest, BenchmarkRan) {
+ int run_count = 0;
+ bool result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark",
+ base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ EXPECT_TRUE(result);
+
+ scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
+ layer_tree_host_->SetOutputSurfaceLostForTesting(false);
+ layer_tree_host_->UpdateLayers(queue.get());
+
+ EXPECT_EQ(1, run_count);
+}
+
+TEST_F(MicroBenchmarkControllerTest, MultipleBenchmarkRan) {
+ int run_count = 0;
+ bool result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark",
+ base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ EXPECT_TRUE(result);
+ result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark",
+ base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ EXPECT_TRUE(result);
+
+ scoped_ptr<ResourceUpdateQueue> queue(new ResourceUpdateQueue);
+ layer_tree_host_->SetOutputSurfaceLostForTesting(false);
+ layer_tree_host_->UpdateLayers(queue.get());
+
+ EXPECT_EQ(2, run_count);
+
+ result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark",
+ base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ EXPECT_TRUE(result);
+ result = layer_tree_host_->ScheduleMicroBenchmark(
+ "unittest_only_benchmark",
+ base::Bind(&IncrementCallCount, base::Unretained(&run_count)));
+ EXPECT_TRUE(result);
+
+ layer_tree_host_->UpdateLayers(queue.get());
+ EXPECT_EQ(4, run_count);
+
+ layer_tree_host_->UpdateLayers(queue.get());
+ EXPECT_EQ(4, run_count);
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/debug/unittest_only_benchmark.cc b/cc/debug/unittest_only_benchmark.cc
new file mode 100644
index 0000000..951a49f
--- /dev/null
+++ b/cc/debug/unittest_only_benchmark.cc
@@ -0,0 +1,19 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/values.h"
+#include "cc/debug/unittest_only_benchmark.h"
+
+namespace cc {
+
+UnittestOnlyBenchmark::UnittestOnlyBenchmark(const DoneCallback& callback)
+ : MicroBenchmark(callback) {}
+
+UnittestOnlyBenchmark::~UnittestOnlyBenchmark() {}
+
+void UnittestOnlyBenchmark::DidUpdateLayers(LayerTreeHost* host) {
+ NotifyDone(scoped_ptr<base::Value>());
+}
+
+} // namespace cc
diff --git a/cc/debug/unittest_only_benchmark.h b/cc/debug/unittest_only_benchmark.h
new file mode 100644
index 0000000..9570b66
--- /dev/null
+++ b/cc/debug/unittest_only_benchmark.h
@@ -0,0 +1,23 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_DEBUG_UNITTEST_ONLY_BENCHMARK_H_
+#define CC_DEBUG_UNITTEST_ONLY_BENCHMARK_H_
+
+#include "cc/debug/micro_benchmark.h"
+
+namespace cc {
+
+class UnittestOnlyBenchmark : public MicroBenchmark {
+ public:
+ explicit UnittestOnlyBenchmark(const DoneCallback& callback);
+ virtual ~UnittestOnlyBenchmark();
+
+ virtual void DidUpdateLayers(LayerTreeHost* host) OVERRIDE;
+};
+
+} // namespace cc
+
+#endif // CC_DEBUG_UNITTEST_ONLY_BENCHMARK_H_
+
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 5a9f859..15de223 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1086,4 +1086,8 @@ void Layer::RemoveFromClipTree() {
clip_parent_ = NULL;
}
+void Layer::RunMicroBenchmark(MicroBenchmark* benchmark) {
+ benchmark->RunOnLayer(this);
+}
+
} // namespace cc
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 1f8c8ac..6f391ac 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -16,6 +16,7 @@
#include "cc/base/cc_export.h"
#include "cc/base/region.h"
#include "cc/base/scoped_ptr_vector.h"
+#include "cc/debug/micro_benchmark.h"
#include "cc/layers/compositing_reasons.h"
#include "cc/layers/draw_properties.h"
#include "cc/layers/layer_lists.h"
@@ -425,6 +426,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer>,
return num_dependents_need_push_properties_ > 0;
}
+ virtual void RunMicroBenchmark(MicroBenchmark* benchmark);
+
protected:
friend class LayerImpl;
friend class TreeSynchronizer;
diff --git a/cc/test/fake_layer_tree_host.cc b/cc/test/fake_layer_tree_host.cc
new file mode 100644
index 0000000..c6d92ab
--- /dev/null
+++ b/cc/test/fake_layer_tree_host.cc
@@ -0,0 +1,34 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/test/fake_layer_tree_host.h"
+
+namespace cc {
+
+scoped_ptr<FakeLayerTreeHost> FakeLayerTreeHost::Create() {
+ static FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
+ static LayerTreeSettings settings;
+ return make_scoped_ptr(new FakeLayerTreeHost(&client, settings));
+}
+
+scoped_ptr<FakeLayerTreeHost> FakeLayerTreeHost::Create(
+ const LayerTreeSettings& settings) {
+ static FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
+ return make_scoped_ptr(new FakeLayerTreeHost(&client, settings));
+}
+
+void FakeLayerTreeHost::SetNeedsCommit() { needs_commit_ = true; }
+
+LayerImpl* FakeLayerTreeHost::CommitAndCreateLayerImplTree() {
+ scoped_ptr<LayerImpl> old_root_layer_impl = active_tree()->DetachLayerTree();
+
+ scoped_ptr<LayerImpl> layer_impl = TreeSynchronizer::SynchronizeTrees(
+ root_layer(), old_root_layer_impl.Pass(), active_tree());
+ TreeSynchronizer::PushProperties(root_layer(), layer_impl.get());
+
+ active_tree()->SetRootLayer(layer_impl.Pass());
+ return active_tree()->root_layer();
+}
+
+} // namespace cc
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h
index 8874ff4..074355d 100644
--- a/cc/test/fake_layer_tree_host.h
+++ b/cc/test/fake_layer_tree_host.h
@@ -16,52 +16,43 @@ namespace cc {
class FakeLayerTreeHost : protected LayerTreeHost {
public:
- static scoped_ptr<FakeLayerTreeHost> Create() {
- static FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- static LayerTreeSettings settings;
- return make_scoped_ptr(new FakeLayerTreeHost(&client, settings));
- }
+ static scoped_ptr<FakeLayerTreeHost> Create();
static scoped_ptr<FakeLayerTreeHost> Create(
- const LayerTreeSettings& settings) {
- static FakeLayerTreeHostClient client(FakeLayerTreeHostClient::DIRECT_3D);
- return make_scoped_ptr(new FakeLayerTreeHost(&client, settings));
- }
+ const LayerTreeSettings& settings);
virtual ~FakeLayerTreeHost() {}
- virtual void SetNeedsCommit() OVERRIDE {}
+ virtual void SetNeedsCommit() OVERRIDE;
virtual void SetNeedsFullTreeSync() OVERRIDE {}
using LayerTreeHost::SetRootLayer;
using LayerTreeHost::root_layer;
- LayerImpl* CommitAndCreateLayerImplTree() {
- scoped_ptr<LayerImpl> old_root_layer_impl =
- active_tree()->DetachLayerTree();
+ LayerImpl* CommitAndCreateLayerImplTree();
- scoped_ptr<LayerImpl> layer_impl =
- TreeSynchronizer::SynchronizeTrees(
- root_layer(),
- old_root_layer_impl.Pass(),
- active_tree());
- TreeSynchronizer::PushProperties(root_layer(), layer_impl.get());
+ FakeLayerTreeHostImpl* host_impl() { return &host_impl_; }
+ LayerTreeImpl* active_tree() { return host_impl_.active_tree(); }
- active_tree()->SetRootLayer(layer_impl.Pass());
- return active_tree()->root_layer();
+ using LayerTreeHost::ScheduleMicroBenchmark;
+ using LayerTreeHost::SetOutputSurfaceLostForTesting;
+ using LayerTreeHost::InitializeForTesting;
+ void UpdateLayers(ResourceUpdateQueue* queue) {
+ LayerTreeHost::UpdateLayers(queue);
}
- FakeLayerTreeHostImpl* host_impl() { return &host_impl_; }
- LayerTreeImpl* active_tree() { return host_impl_.active_tree(); }
+ bool needs_commit() { return needs_commit_; }
private:
FakeLayerTreeHost(LayerTreeHostClient* client,
const LayerTreeSettings& settings)
: LayerTreeHost(client, settings),
- host_impl_(settings, &proxy_) {}
+ host_impl_(settings, &proxy_),
+ needs_commit_(false) {}
FakeImplProxy proxy_;
FakeLayerTreeHostImpl host_impl_;
+ bool needs_commit_;
};
} // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 930ec05..baa0afb 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <stack>
+#include <string>
#include "base/bind.h"
#include "base/command_line.h"
@@ -114,6 +115,7 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client,
client_(client),
source_frame_number_(0),
rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()),
+ micro_benchmark_controller_(this),
output_surface_can_be_initialized_(true),
output_surface_lost_(true),
num_failed_recreate_attempts_(0),
@@ -739,7 +741,11 @@ bool LayerTreeHost::UpdateLayers(ResourceUpdateQueue* queue) {
DCHECK(!root_layer()->parent());
- return UpdateLayers(root_layer(), queue);
+ bool result = UpdateLayers(root_layer(), queue);
+
+ micro_benchmark_controller_.DidUpdateLayers();
+
+ return result;
}
static Layer* FindFirstScrollableLayer(Layer* layer) {
@@ -1255,4 +1261,10 @@ void LayerTreeHost::RegisterViewportLayers(
outer_viewport_scroll_layer_ = outer_viewport_scroll_layer;
}
+bool LayerTreeHost::ScheduleMicroBenchmark(
+ const std::string& benchmark_name,
+ const MicroBenchmark::DoneCallback& callback) {
+ return micro_benchmark_controller_.ScheduleRun(benchmark_name, callback);
+}
+
} // namespace cc
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index d92200f..e84f292 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -7,6 +7,7 @@
#include <limits>
#include <list>
+#include <string>
#include <vector>
#include "base/basictypes.h"
@@ -19,6 +20,8 @@
#include "cc/animation/animation_events.h"
#include "cc/base/cc_export.h"
#include "cc/base/scoped_ptr_vector.h"
+#include "cc/debug/micro_benchmark.h"
+#include "cc/debug/micro_benchmark_controller.h"
#include "cc/input/input_handler.h"
#include "cc/input/scrollbar.h"
#include "cc/input/top_controls_state.h"
@@ -314,10 +317,16 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
bool UsingSharedMemoryResources();
int id() const { return tree_id_; }
+ bool ScheduleMicroBenchmark(const std::string& benchmark_name,
+ const MicroBenchmark::DoneCallback& callback);
+
protected:
LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings);
bool Initialize(scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner);
bool InitializeForTesting(scoped_ptr<Proxy> proxy_for_testing);
+ void SetOutputSurfaceLostForTesting(bool is_lost) {
+ output_surface_lost_ = is_lost;
+ }
private:
bool InitializeProxy(scoped_ptr<Proxy> proxy);
@@ -373,6 +382,8 @@ class CC_EXPORT LayerTreeHost : NON_EXPORTED_BASE(public RateLimiterClient) {
int source_frame_number_;
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation_;
+ MicroBenchmarkController micro_benchmark_controller_;
+
bool output_surface_can_be_initialized_;
bool output_surface_lost_;
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc
index 4561f4c..73016d2 100644
--- a/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -15,6 +15,7 @@
#include "content/common/browser_rendering_stats.h"
#include "content/common/gpu/gpu_rendering_stats.h"
#include "content/public/renderer/render_thread.h"
+#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/skia_benchmarking_extension.h"
@@ -296,6 +297,11 @@ class GpuBenchmarkingWrapper : public v8::Extension {
"chrome.gpuBenchmarking.clearImageCache = function() {"
" native function ClearImageCache();"
" ClearImageCache();"
+ "};"
+ "chrome.gpuBenchmarking.runMicroBenchmark ="
+ " function(name, callback) {"
+ " native function RunMicroBenchmark();"
+ " return RunMicroBenchmark(name, callback);"
"};") {}
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
@@ -318,6 +324,8 @@ class GpuBenchmarkingWrapper : public v8::Extension {
return v8::FunctionTemplate::New(BeginWindowSnapshotPNG);
if (name->Equals(v8::String::New("ClearImageCache")))
return v8::FunctionTemplate::New(ClearImageCache);
+ if (name->Equals(v8::String::New("RunMicroBenchmark")))
+ return v8::FunctionTemplate::New(RunMicroBenchmark);
return v8::Handle<v8::FunctionTemplate>();
}
@@ -590,6 +598,54 @@ class GpuBenchmarkingWrapper : public v8::Extension {
const v8::FunctionCallbackInfo<v8::Value>& args) {
WebImageCache::clear();
}
+
+ static void OnMicroBenchmarkCompleted(
+ CallbackAndContext* callback_and_context,
+ scoped_ptr<base::Value> result) {
+ v8::HandleScope scope(callback_and_context->isolate());
+ v8::Handle<v8::Context> context = callback_and_context->GetContext();
+ v8::Context::Scope context_scope(context);
+ WebFrame* frame = WebFrame::frameForContext(context);
+ if (frame) {
+ scoped_ptr<V8ValueConverter> converter =
+ make_scoped_ptr(V8ValueConverter::create());
+ v8::Handle<v8::Value> value = converter->ToV8Value(result.get(), context);
+ v8::Handle<v8::Value> argv[] = { value };
+
+ frame->callFunctionEvenIfScriptDisabled(
+ callback_and_context->GetCallback(), v8::Object::New(), 1, argv);
+ }
+ }
+
+ static void RunMicroBenchmark(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ GpuBenchmarkingContext context;
+ if (!context.Init(true)) {
+ args.GetReturnValue().Set(false);
+ return;
+ }
+
+ if (args.Length() != 2 ||
+ !args[0]->IsString() ||
+ !args[1]->IsFunction()) {
+ args.GetReturnValue().Set(false);
+ return;
+ }
+
+ v8::Local<v8::Function> callback_local =
+ v8::Local<v8::Function>::Cast(args[1]);
+
+ scoped_refptr<CallbackAndContext> callback_and_context =
+ new CallbackAndContext(args.GetIsolate(),
+ callback_local,
+ context.web_frame()->mainWorldScriptContext());
+
+ v8::String::Utf8Value benchmark(args[0]);
+ DCHECK(*benchmark);
+ args.GetReturnValue().Set(context.compositor()->ScheduleMicroBenchmark(
+ std::string(*benchmark),
+ base::Bind(&OnMicroBenchmarkCompleted, callback_and_context)));
+ }
};
v8::Extension* GpuBenchmarkingExtension::Get() {
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 88fce98..78622ee 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -16,8 +16,10 @@
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
+#include "base/values.h"
#include "cc/base/switches.h"
#include "cc/debug/layer_tree_debug_state.h"
+#include "cc/debug/micro_benchmark.h"
#include "cc/layers/layer.h"
#include "cc/trees/layer_tree_host.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
@@ -29,6 +31,10 @@
#include "ui/gl/gl_switches.h"
#include "webkit/renderer/compositor_bindings/web_layer_impl.h"
+namespace base {
+class Value;
+}
+
namespace cc {
class Layer;
}
@@ -393,6 +399,12 @@ const cc::Layer* RenderWidgetCompositor::GetRootLayer() const {
return layer_tree_host_->root_layer();
}
+bool RenderWidgetCompositor::ScheduleMicroBenchmark(
+ const std::string& name,
+ const base::Callback<void(scoped_ptr<base::Value>)>& callback) {
+ return layer_tree_host_->ScheduleMicroBenchmark(name, callback);
+}
+
bool RenderWidgetCompositor::initialize(cc::LayerTreeSettings settings) {
scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy =
RenderThreadImpl::current()->compositor_message_loop_proxy();
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h
index ec1c438..910d99c 100644
--- a/content/renderer/gpu/render_widget_compositor.h
+++ b/content/renderer/gpu/render_widget_compositor.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
#define CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
+#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "cc/debug/rendering_stats.h"
@@ -54,6 +55,9 @@ class RenderWidgetCompositor : public WebKit::WebLayerTreeView,
int GetLayerTreeId() const;
void NotifyInputThrottledUntilCommit();
const cc::Layer* GetRootLayer() const;
+ bool ScheduleMicroBenchmark(
+ const std::string& name,
+ const base::Callback<void(scoped_ptr<base::Value>)>& callback);
// WebLayerTreeView implementation.
virtual void setSurfaceReady();