Chromium Code Reviews| 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..503dfd12f101e3ac98bffb2c82485e51ad758fe1 |
| --- /dev/null |
| +++ b/cc/debug/rasterize_and_record_benchmark.cc |
| @@ -0,0 +1,143 @@ |
| +// 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), |
| + 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) { |
| + 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(); |
| + |
| + SkTileGridPicture::TileGridInfo tile_grid_info; |
|
enne (OOO)
2013/11/14 00:24:05
Maybe add this as a static accessor on cc::Picture
vmpstr
2013/11/14 19:38:24
Unfortunately we don't store tile_grid_info on the
enne (OOO)
2013/11/14 19:44:59
They could both get it from a static accessor on c
vmpstr
2013/11/14 20:04:35
Done. (added it to PicturePileBase since that's wh
|
| + 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 |