Index: cc/debug/rasterize_and_record_benchmark.cc |
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f56151d063862c92a69a8df1ed2d00d8946dc759 |
--- /dev/null |
+++ b/cc/debug/rasterize_and_record_benchmark.cc |
@@ -0,0 +1,140 @@ |
+// 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 kTileGridSize = 512; |
+const int kTileGridBorder = 1; |
+ |
+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) { |
+ 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() {} |
+ |
+void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* 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, |
+ base::Unretained(this)))); |
+} |
+ |
+void RasterizeAndRecordBenchmark::Run(Layer* layer) { |
+ layer->RunMicroBenchmark(this); |
+} |
+ |
+void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) { |
+ ContentLayerClient* painter = layer->client(); |
+ gfx::Size content_bounds = layer->content_bounds(); |
+ |
+ SkTileGridPicture::TileGridInfo tile_grid_info; |
+ tile_grid_info.fTileInterval.set(kTileGridSize - 2 * kTileGridBorder, |
+ kTileGridSize - 2 * kTileGridBorder); |
+ tile_grid_info.fMargin.set(kTileGridBorder, kTileGridBorder); |
+ tile_grid_info.fOffset.set(-kTileGridBorder, -kTileGridBorder); |
+ |
+ 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 |