Enable Enhanced Bookmark on Android Tablet
[chromium-blink-merge.git] / cc / debug / rasterize_and_record_benchmark.cc
blob41d62100fb26d15204cc279e8c5af81c85926cde
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/debug/rasterize_and_record_benchmark.h"
7 #include <algorithm>
8 #include <limits>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "cc/debug/lap_timer.h"
15 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
16 #include "cc/layers/layer.h"
17 #include "cc/layers/picture_layer.h"
18 #include "cc/resources/picture_pile.h"
19 #include "cc/trees/layer_tree_host.h"
20 #include "cc/trees/layer_tree_host_common.h"
21 #include "third_party/skia/include/utils/SkPictureUtils.h"
22 #include "ui/gfx/geometry/rect.h"
24 namespace cc {
26 namespace {
28 const int kDefaultRecordRepeatCount = 100;
30 const char* kModeSuffixes[Picture::RECORDING_MODE_COUNT] = {
31 "",
32 "_sk_null_canvas",
33 "_painting_disabled"};
35 } // namespace
37 RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark(
38 scoped_ptr<base::Value> value,
39 const MicroBenchmark::DoneCallback& callback)
40 : MicroBenchmark(callback),
41 record_repeat_count_(kDefaultRecordRepeatCount),
42 settings_(value.Pass()),
43 main_thread_benchmark_done_(false),
44 host_(nullptr),
45 weak_ptr_factory_(this) {
46 base::DictionaryValue* settings = nullptr;
47 settings_->GetAsDictionary(&settings);
48 if (!settings)
49 return;
51 if (settings->HasKey("record_repeat_count"))
52 settings->GetInteger("record_repeat_count", &record_repeat_count_);
55 RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() {
56 weak_ptr_factory_.InvalidateWeakPtrs();
59 void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
60 host_ = host;
61 LayerTreeHostCommon::CallFunctionForSubtree(
62 host->root_layer(),
63 base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this)));
65 DCHECK(!results_.get());
66 results_ = make_scoped_ptr(new base::DictionaryValue);
67 results_->SetInteger("pixels_recorded", record_results_.pixels_recorded);
68 results_->SetInteger("picture_memory_usage", record_results_.bytes_used);
70 for (int i = 0; i < Picture::RECORDING_MODE_COUNT; i++) {
71 std::string name = base::StringPrintf("record_time%s_ms", kModeSuffixes[i]);
72 results_->SetDouble(name,
73 record_results_.total_best_time[i].InMillisecondsF());
75 main_thread_benchmark_done_ = true;
78 void RasterizeAndRecordBenchmark::RecordRasterResults(
79 scoped_ptr<base::Value> results_value) {
80 DCHECK(main_thread_benchmark_done_);
82 base::DictionaryValue* results = nullptr;
83 results_value->GetAsDictionary(&results);
84 DCHECK(results);
86 results_->MergeDictionary(results);
88 NotifyDone(results_.Pass());
91 scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
92 scoped_refptr<base::MessageLoopProxy> origin_loop) {
93 return make_scoped_ptr(new RasterizeAndRecordBenchmarkImpl(
94 origin_loop,
95 settings_.get(),
96 base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults,
97 weak_ptr_factory_.GetWeakPtr())));
100 void RasterizeAndRecordBenchmark::Run(Layer* layer) {
101 layer->RunMicroBenchmark(this);
104 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
105 ContentLayerClient* painter = layer->client();
106 gfx::Size content_bounds = layer->content_bounds();
108 DCHECK(host_);
109 gfx::Size tile_grid_size = host_->settings().default_tile_size;
111 SkTileGridFactory::TileGridInfo tile_grid_info;
112 PicturePile::ComputeTileGridInfo(tile_grid_size, &tile_grid_info);
114 gfx::Rect visible_content_rect = gfx::ScaleToEnclosingRect(
115 layer->visible_content_rect(), 1.f / layer->contents_scale_x());
116 if (visible_content_rect.IsEmpty())
117 return;
119 for (int mode_index = 0; mode_index < Picture::RECORDING_MODE_COUNT;
120 mode_index++) {
121 Picture::RecordingMode mode =
122 static_cast<Picture::RecordingMode>(mode_index);
123 base::TimeDelta min_time = base::TimeDelta::Max();
124 size_t memory_used = 0;
126 // Parameters for LapTimer.
127 const int kTimeLimitMillis = 1;
128 const int kWarmupRuns = 0;
129 const int kTimeCheckInterval = 1;
131 for (int i = 0; i < record_repeat_count_; ++i) {
132 // Run for a minimum amount of time to avoid problems with timer
133 // quantization when the layer is very small.
134 LapTimer timer(kWarmupRuns,
135 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
136 kTimeCheckInterval);
137 scoped_refptr<Picture> picture;
138 do {
139 picture = Picture::Create(visible_content_rect, painter, tile_grid_info,
140 false, mode);
141 timer.NextLap();
142 } while (!timer.HasTimeLimitExpired());
143 base::TimeDelta duration =
144 base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
145 if (duration < min_time)
146 min_time = duration;
147 memory_used = picture->ApproximateMemoryUsage();
150 if (mode == Picture::RECORD_NORMALLY) {
151 record_results_.bytes_used += memory_used;
152 record_results_.pixels_recorded +=
153 visible_content_rect.width() * visible_content_rect.height();
155 record_results_.total_best_time[mode_index] += min_time;
159 RasterizeAndRecordBenchmark::RecordResults::RecordResults()
160 : pixels_recorded(0), bytes_used(0) {
163 RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {}
165 } // namespace cc