summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 20:32:08 +0000
committervmpstr@chromium.org <vmpstr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-18 20:32:08 +0000
commit8cac9fe3496911e1e4dacd94cb2073b59cfa86d4 (patch)
treedf5f7a59c054fe7cc7316c2aff4a17a1a4ee64a3 /cc
parent7b06b28ab5e49cc32075a9a28db6d91c381967a9 (diff)
downloadchromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.zip
chromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.tar.gz
chromium_src-8cac9fe3496911e1e4dacd94cb2073b59cfa86d4.tar.bz2
cc: Add rasterize and record micro benchmark.
This patch adds a rasterize and record micro benchmark. It depends on https://codereview.chromium.org/67563002/ R=enne@chromium.org, nduca@chromium.org, ernstm@chromium.org Review URL: https://codereview.chromium.org/66213007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235805 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/cc.gyp4
-rw-r--r--cc/debug/micro_benchmark_controller.cc4
-rw-r--r--cc/debug/rasterize_and_record_benchmark.cc142
-rw-r--r--cc/debug/rasterize_and_record_benchmark.h66
-rw-r--r--cc/debug/rasterize_and_record_benchmark_impl.cc117
-rw-r--r--cc/debug/rasterize_and_record_benchmark_impl.h49
-rw-r--r--cc/resources/picture_pile_base.cc25
-rw-r--r--cc/resources/picture_pile_base.h3
8 files changed, 400 insertions, 10 deletions
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 27d198f..a3ec808 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -94,6 +94,10 @@
'debug/paint_time_counter.h',
'debug/picture_record_benchmark.cc',
'debug/picture_record_benchmark.h',
+ 'debug/rasterize_and_record_benchmark.cc',
+ 'debug/rasterize_and_record_benchmark.h',
+ 'debug/rasterize_and_record_benchmark_impl.cc',
+ 'debug/rasterize_and_record_benchmark_impl.h',
'debug/rendering_stats.cc',
'debug/rendering_stats.h',
'debug/rendering_stats_instrumentation.cc',
diff --git a/cc/debug/micro_benchmark_controller.cc b/cc/debug/micro_benchmark_controller.cc
index 52e91ae..7d9025c 100644
--- a/cc/debug/micro_benchmark_controller.cc
+++ b/cc/debug/micro_benchmark_controller.cc
@@ -10,6 +10,7 @@
#include "base/message_loop/message_loop_proxy.h"
#include "base/values.h"
#include "cc/debug/picture_record_benchmark.h"
+#include "cc/debug/rasterize_and_record_benchmark.h"
#include "cc/debug/unittest_only_benchmark.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_impl.h"
@@ -25,6 +26,9 @@ scoped_ptr<MicroBenchmark> CreateBenchmark(
if (name == "picture_record_benchmark") {
return scoped_ptr<MicroBenchmark>(
new PictureRecordBenchmark(value.Pass(), callback));
+ } else if (name == "rasterize_and_record_benchmark") {
+ return scoped_ptr<MicroBenchmark>(
+ new RasterizeAndRecordBenchmark(value.Pass(), callback));
} else if (name == "unittest_only_benchmark") {
return scoped_ptr<MicroBenchmark>(
new UnittestOnlyBenchmark(value.Pass(), callback));
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc
new file mode 100644
index 0000000..4646afd
--- /dev/null
+++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -0,0 +1,142 @@
+// 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/debug/rasterize_and_record_benchmark.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "base/basictypes.h"
+#include "base/values.h"
+#include "cc/debug/rasterize_and_record_benchmark_impl.h"
+#include "cc/layers/layer.h"
+#include "cc/layers/picture_layer.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_host_common.h"
+#include "ui/gfx/rect.h"
+
+namespace cc {
+
+namespace {
+
+const int kDefaultRecordRepeatCount = 100;
+
+base::TimeTicks Now() {
+ return base::TimeTicks::IsThreadNowSupported()
+ ? base::TimeTicks::ThreadNow()
+ : base::TimeTicks::HighResNow();
+}
+
+} // namespace
+
+RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark(
+ scoped_ptr<base::Value> value,
+ const MicroBenchmark::DoneCallback& callback)
+ : MicroBenchmark(callback),
+ record_repeat_count_(kDefaultRecordRepeatCount),
+ settings_(value.Pass()),
+ main_thread_benchmark_done_(false),
+ host_(NULL),
+ weak_ptr_factory_(this) {
+ base::DictionaryValue* settings = NULL;
+ settings_->GetAsDictionary(&settings);
+ if (!settings)
+ return;
+
+ if (settings->HasKey("record_repeat_count"))
+ settings->GetInteger("record_repeat_count", &record_repeat_count_);
+}
+
+RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() {
+ weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
+void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
+ host_ = host;
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ host->root_layer(),
+ base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this)));
+
+ DCHECK(!results_.get());
+ results_ = make_scoped_ptr(new base::DictionaryValue);
+ results_->SetInteger("pixels_recorded", record_results_.pixels_recorded);
+ results_->SetDouble("record_time_ms",
+ record_results_.total_best_time.InMillisecondsF());
+ main_thread_benchmark_done_ = true;
+}
+
+void RasterizeAndRecordBenchmark::RecordRasterResults(
+ scoped_ptr<base::Value> results_value) {
+ DCHECK(main_thread_benchmark_done_);
+
+ base::DictionaryValue* results = NULL;
+ results_value->GetAsDictionary(&results);
+
+ DCHECK(results);
+ DCHECK(results->HasKey("pixels_rasterized"));
+ DCHECK(results->HasKey("rasterize_time_ms"));
+
+ int pixels_rasterized;
+ results->GetInteger("pixels_rasterized", &pixels_rasterized);
+ double rasterize_time_ms;
+ results->GetDouble("rasterize_time_ms", &rasterize_time_ms);
+
+ results_->SetInteger("pixels_rasterized", pixels_rasterized);
+ results_->SetDouble("rasterize_time_ms", rasterize_time_ms);
+
+ NotifyDone(results_.PassAs<base::Value>());
+}
+
+scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
+ scoped_refptr<base::MessageLoopProxy> origin_loop) {
+ return scoped_ptr<MicroBenchmarkImpl>(new RasterizeAndRecordBenchmarkImpl(
+ origin_loop,
+ settings_.get(),
+ base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults,
+ weak_ptr_factory_.GetWeakPtr())));
+}
+
+void RasterizeAndRecordBenchmark::Run(Layer* layer) {
+ layer->RunMicroBenchmark(this);
+}
+
+void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
+ ContentLayerClient* painter = layer->client();
+ gfx::Size content_bounds = layer->content_bounds();
+
+ DCHECK(host_);
+ gfx::Size tile_grid_size = host_->settings().default_tile_size;
+
+ SkTileGridPicture::TileGridInfo tile_grid_info;
+ PicturePileBase::ComputeTileGridInfo(tile_grid_size, &tile_grid_info);
+
+ gfx::Rect visible_content_rect = gfx::ScaleToEnclosingRect(
+ layer->visible_content_rect(), 1.f / layer->contents_scale_x());
+ if (visible_content_rect.IsEmpty())
+ return;
+
+ scoped_refptr<Picture> picture = Picture::Create(visible_content_rect);
+
+ base::TimeDelta min_time =
+ base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
+ for (int i = 0; i < record_repeat_count_; ++i) {
+ base::TimeTicks start = Now();
+ picture->Record(painter, tile_grid_info);
+ base::TimeTicks end = Now();
+ base::TimeDelta duration = end - start;
+ if (duration < min_time)
+ min_time = duration;
+ }
+
+ record_results_.pixels_recorded +=
+ visible_content_rect.width() * visible_content_rect.height();
+ record_results_.total_best_time += min_time;
+}
+
+RasterizeAndRecordBenchmark::RecordResults::RecordResults()
+ : pixels_recorded(0) {}
+
+RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {}
+
+} // namespace cc
diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h
new file mode 100644
index 0000000..2cea16a
--- /dev/null
+++ b/cc/debug/rasterize_and_record_benchmark.h
@@ -0,0 +1,66 @@
+// 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_RASTERIZE_AND_RECORD_BENCHMARK_H_
+#define CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_H_
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "cc/debug/micro_benchmark_controller.h"
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace cc {
+
+class LayerTreeHost;
+class Layer;
+class RasterizeAndRecordBenchmark : public MicroBenchmark {
+ public:
+ explicit RasterizeAndRecordBenchmark(
+ scoped_ptr<base::Value> value,
+ const MicroBenchmark::DoneCallback& callback);
+ virtual ~RasterizeAndRecordBenchmark();
+
+ // Implements MicroBenchmark interface.
+ virtual void DidUpdateLayers(LayerTreeHost* host) OVERRIDE;
+ virtual void RunOnLayer(PictureLayer* layer) OVERRIDE;
+
+ virtual scoped_ptr<MicroBenchmarkImpl> CreateBenchmarkImpl(
+ scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE;
+
+ private:
+ void Run(Layer* layer);
+
+ void RecordRasterResults(scoped_ptr<base::Value> results);
+
+ struct RecordResults {
+ RecordResults();
+ ~RecordResults();
+
+ int pixels_recorded;
+ base::TimeDelta total_best_time;
+ };
+
+ RecordResults record_results_;
+ int record_repeat_count_;
+ scoped_ptr<base::Value> settings_;
+ scoped_ptr<base::DictionaryValue> results_;
+
+ // The following is used in DCHECKs.
+ bool main_thread_benchmark_done_;
+
+ LayerTreeHost* host_;
+
+ base::WeakPtrFactory<RasterizeAndRecordBenchmark> weak_ptr_factory_;
+};
+
+} // namespace cc
+
+#endif // CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_H_
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.cc b/cc/debug/rasterize_and_record_benchmark_impl.cc
new file mode 100644
index 0000000..ecf2688
--- /dev/null
+++ b/cc/debug/rasterize_and_record_benchmark_impl.cc
@@ -0,0 +1,117 @@
+// 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/debug/rasterize_and_record_benchmark_impl.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "base/basictypes.h"
+#include "base/values.h"
+#include "cc/layers/layer_impl.h"
+#include "cc/layers/picture_layer_impl.h"
+#include "cc/trees/layer_tree_host_common.h"
+#include "cc/trees/layer_tree_host_impl.h"
+#include "ui/gfx/rect.h"
+
+namespace cc {
+
+namespace {
+
+const int kDefaultRasterizeRepeatCount = 100;
+
+base::TimeTicks Now() {
+ return base::TimeTicks::IsThreadNowSupported()
+ ? base::TimeTicks::ThreadNow()
+ : base::TimeTicks::HighResNow();
+}
+
+} // namespace
+
+RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
+ scoped_refptr<base::MessageLoopProxy> origin_loop,
+ base::Value* value,
+ const MicroBenchmarkImpl::DoneCallback& callback)
+ : MicroBenchmarkImpl(callback, origin_loop),
+ rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
+ base::DictionaryValue* settings = NULL;
+ value->GetAsDictionary(&settings);
+ if (!settings)
+ return;
+
+ if (settings->HasKey("rasterize_repeat_count"))
+ settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
+}
+
+RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
+
+void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
+ LayerTreeHostImpl* host) {
+ LayerTreeHostCommon::CallFunctionForSubtree(
+ host->RootLayer(),
+ base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
+ base::Unretained(this)));
+
+ scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
+ result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
+ result->SetDouble("rasterize_time_ms",
+ rasterize_results_.total_best_time.InMillisecondsF());
+
+ NotifyDone(result.PassAs<base::Value>());
+}
+
+void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
+ layer->RunMicroBenchmark(this);
+}
+
+void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
+ if (layer->visible_content_rect().IsEmpty())
+ return;
+
+ PictureLayerTilingSet tiling_set(layer, layer->content_bounds());
+
+ PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
+ tiling->CreateAllTilesForTesting();
+ for (PictureLayerTiling::CoverageIterator it(
+ tiling, layer->contents_scale_x(), layer->visible_content_rect());
+ it;
+ ++it) {
+ DCHECK(*it);
+
+ PicturePileImpl* picture_pile = (*it)->picture_pile();
+ gfx::Rect content_rect = (*it)->content_rect();
+ float contents_scale = (*it)->contents_scale();
+
+ base::TimeDelta min_time =
+ base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
+ for (int i = 0; i < rasterize_repeat_count_; ++i) {
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ content_rect.width(),
+ content_rect.height());
+ bitmap.allocPixels();
+
+ SkBitmapDevice device(bitmap);
+ SkCanvas canvas(&device);
+
+ base::TimeTicks start = Now();
+ picture_pile->RasterToBitmap(&canvas, content_rect, contents_scale, NULL);
+ base::TimeTicks end = Now();
+ base::TimeDelta duration = end - start;
+ if (duration < min_time)
+ min_time = duration;
+ }
+
+ rasterize_results_.pixels_rasterized +=
+ content_rect.width() * content_rect.height();
+ rasterize_results_.total_best_time += min_time;
+ }
+}
+
+RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
+ : pixels_rasterized(0) {}
+
+RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
+
+} // namespace cc
diff --git a/cc/debug/rasterize_and_record_benchmark_impl.h b/cc/debug/rasterize_and_record_benchmark_impl.h
new file mode 100644
index 0000000..0f9de9b
--- /dev/null
+++ b/cc/debug/rasterize_and_record_benchmark_impl.h
@@ -0,0 +1,49 @@
+// 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_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_
+#define CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "base/time/time.h"
+#include "cc/debug/micro_benchmark_impl.h"
+
+namespace cc {
+
+class LayerTreeHostImpl;
+class PictureLayerImpl;
+class LayerImpl;
+class RasterizeAndRecordBenchmarkImpl : public MicroBenchmarkImpl {
+ public:
+ explicit RasterizeAndRecordBenchmarkImpl(
+ scoped_refptr<base::MessageLoopProxy> origin_loop,
+ base::Value* value,
+ const MicroBenchmarkImpl::DoneCallback& callback);
+ virtual ~RasterizeAndRecordBenchmarkImpl();
+
+ // Implements MicroBenchmark interface.
+ virtual void DidCompleteCommit(LayerTreeHostImpl* host) OVERRIDE;
+ virtual void RunOnLayer(PictureLayerImpl* layer) OVERRIDE;
+
+ private:
+ void Run(LayerImpl* layer);
+
+ struct RasterizeResults {
+ RasterizeResults();
+ ~RasterizeResults();
+
+ int pixels_rasterized;
+ base::TimeDelta total_best_time;
+ };
+
+ RasterizeResults rasterize_results_;
+ int rasterize_repeat_count_;
+};
+
+} // namespace cc
+
+#endif // CC_DEBUG_RASTERIZE_AND_RECORD_BENCHMARK_IMPL_H_
diff --git a/cc/resources/picture_pile_base.cc b/cc/resources/picture_pile_base.cc
index 69e6143..b6e1aa5 100644
--- a/cc/resources/picture_pile_base.cc
+++ b/cc/resources/picture_pile_base.cc
@@ -128,19 +128,24 @@ void PicturePileBase::SetMinContentsScale(float min_contents_scale) {
min_contents_scale_ = min_contents_scale;
}
-void PicturePileBase::SetTileGridSize(gfx::Size tile_grid_size) {
- tile_grid_info_.fTileInterval.set(
- tile_grid_size.width() - 2 * kTileGridBorderPixels,
- tile_grid_size.height() - 2 * kTileGridBorderPixels);
- DCHECK_GT(tile_grid_info_.fTileInterval.width(), 0);
- DCHECK_GT(tile_grid_info_.fTileInterval.height(), 0);
- tile_grid_info_.fMargin.set(kTileGridBorderPixels,
- kTileGridBorderPixels);
+// static
+void PicturePileBase::ComputeTileGridInfo(
+ gfx::Size tile_grid_size,
+ SkTileGridPicture::TileGridInfo* info) {
+ DCHECK(info);
+ info->fTileInterval.set(tile_grid_size.width() - 2 * kTileGridBorderPixels,
+ tile_grid_size.height() - 2 * kTileGridBorderPixels);
+ DCHECK_GT(info->fTileInterval.width(), 0);
+ DCHECK_GT(info->fTileInterval.height(), 0);
+ info->fMargin.set(kTileGridBorderPixels, kTileGridBorderPixels);
// Offset the tile grid coordinate space to take into account the fact
// that the top-most and left-most tiles do not have top and left borders
// respectively.
- tile_grid_info_.fOffset.set(-kTileGridBorderPixels,
- -kTileGridBorderPixels);
+ info->fOffset.set(-kTileGridBorderPixels, -kTileGridBorderPixels);
+}
+
+void PicturePileBase::SetTileGridSize(gfx::Size tile_grid_size) {
+ ComputeTileGridInfo(tile_grid_size, &tile_grid_info_);
}
void PicturePileBase::SetBufferPixels(int new_buffer_pixels) {
diff --git a/cc/resources/picture_pile_base.h b/cc/resources/picture_pile_base.h
index 325feff..d7b7e9c 100644
--- a/cc/resources/picture_pile_base.h
+++ b/cc/resources/picture_pile_base.h
@@ -41,6 +41,9 @@ class CC_EXPORT PicturePileBase : public base::RefCounted<PicturePileBase> {
bool HasRecordingAt(int x, int y);
bool CanRaster(float contents_scale, gfx::Rect content_rect);
+ static void ComputeTileGridInfo(gfx::Size tile_grid_size,
+ SkTileGridPicture::TileGridInfo* info);
+
void SetTileGridSize(gfx::Size tile_grid_size);
TilingData& tiling() { return tiling_; }