Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / cc / debug / rasterize_and_record_benchmark_impl.cc
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.
4
5 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
6
7 #include <algorithm>
8 #include <limits>
9
10 #include "base/basictypes.h"
11 #include "base/values.h"
12 #include "cc/debug/lap_timer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/layers/picture_layer_impl.h"
15 #include "cc/resources/raster_worker_pool.h"
16 #include "cc/trees/layer_tree_host_common.h"
17 #include "cc/trees/layer_tree_host_impl.h"
18 #include "ui/gfx/rect.h"
19
20 namespace cc {
21
22 namespace {
23
24 const int kDefaultRasterizeRepeatCount = 100;
25
26 class BenchmarkRasterTask : public Task {
27  public:
28   BenchmarkRasterTask(PicturePileImpl* picture_pile,
29                       const gfx::Rect& content_rect,
30                       float contents_scale,
31                       size_t repeat_count)
32       : picture_pile_(picture_pile),
33         content_rect_(content_rect),
34         contents_scale_(contents_scale),
35         repeat_count_(repeat_count),
36         is_solid_color_(false),
37         best_time_(base::TimeDelta::Max()) {}
38
39   // Overridden from Task:
40   virtual void RunOnWorkerThread() OVERRIDE {
41     // Parameters for LapTimer.
42     const int kTimeLimitMillis = 1;
43     const int kWarmupRuns = 0;
44     const int kTimeCheckInterval = 1;
45
46     for (size_t i = 0; i < repeat_count_; ++i) {
47       // Run for a minimum amount of time to avoid problems with timer
48       // quantization when the layer is very small.
49       LapTimer timer(kWarmupRuns,
50                      base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
51                      kTimeCheckInterval);
52       do {
53         SkBitmap bitmap;
54         bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
55                                                       content_rect_.height()));
56         SkCanvas canvas(bitmap);
57         PicturePileImpl::Analysis analysis;
58
59         picture_pile_->AnalyzeInRect(
60             content_rect_, contents_scale_, &analysis, NULL);
61         picture_pile_->RasterToBitmap(
62             &canvas, content_rect_, contents_scale_, NULL);
63
64         is_solid_color_ = analysis.is_solid_color;
65
66         timer.NextLap();
67       } while (!timer.HasTimeLimitExpired());
68       base::TimeDelta duration =
69           base::TimeDelta::FromMillisecondsD(timer.MsPerLap());
70       if (duration < best_time_)
71         best_time_ = duration;
72     }
73   }
74
75   bool IsSolidColor() const { return is_solid_color_; }
76   base::TimeDelta GetBestTime() const { return best_time_; }
77
78  private:
79   virtual ~BenchmarkRasterTask() {}
80
81   PicturePileImpl* picture_pile_;
82   gfx::Rect content_rect_;
83   float contents_scale_;
84   size_t repeat_count_;
85   bool is_solid_color_;
86   base::TimeDelta best_time_;
87 };
88
89 class FixedInvalidationPictureLayerTilingClient
90     : public PictureLayerTilingClient {
91  public:
92   FixedInvalidationPictureLayerTilingClient(
93       PictureLayerTilingClient* base_client,
94       const Region invalidation)
95       : base_client_(base_client), invalidation_(invalidation) {}
96
97   virtual scoped_refptr<Tile> CreateTile(
98       PictureLayerTiling* tiling,
99       const gfx::Rect& content_rect) OVERRIDE {
100     return base_client_->CreateTile(tiling, content_rect);
101   }
102
103   virtual PicturePileImpl* GetPile() OVERRIDE {
104     return base_client_->GetPile();
105   }
106
107   virtual gfx::Size CalculateTileSize(
108       const gfx::Size& content_bounds) const OVERRIDE {
109     return base_client_->CalculateTileSize(content_bounds);
110   }
111
112   // This is the only function that returns something different from the base
113   // client.
114   virtual const Region* GetInvalidation() OVERRIDE { return &invalidation_; }
115
116   virtual const PictureLayerTiling* GetTwinTiling(
117       const PictureLayerTiling* tiling) const OVERRIDE {
118     return base_client_->GetTwinTiling(tiling);
119   }
120
121   virtual PictureLayerTiling* GetRecycledTwinTiling(
122       const PictureLayerTiling* tiling) OVERRIDE {
123     return base_client_->GetRecycledTwinTiling(tiling);
124   }
125
126   virtual size_t GetMaxTilesForInterestArea() const OVERRIDE {
127     return base_client_->GetMaxTilesForInterestArea();
128   }
129
130   virtual float GetSkewportTargetTimeInSeconds() const OVERRIDE {
131     return base_client_->GetSkewportTargetTimeInSeconds();
132   }
133
134   virtual int GetSkewportExtrapolationLimitInContentPixels() const OVERRIDE {
135     return base_client_->GetSkewportExtrapolationLimitInContentPixels();
136   }
137
138   virtual WhichTree GetTree() const OVERRIDE { return base_client_->GetTree(); }
139
140  private:
141   PictureLayerTilingClient* base_client_;
142   Region invalidation_;
143 };
144
145 }  // namespace
146
147 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
148     scoped_refptr<base::MessageLoopProxy> origin_loop,
149     base::Value* value,
150     const MicroBenchmarkImpl::DoneCallback& callback)
151     : MicroBenchmarkImpl(callback, origin_loop),
152       rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
153   base::DictionaryValue* settings = NULL;
154   value->GetAsDictionary(&settings);
155   if (!settings)
156     return;
157
158   if (settings->HasKey("rasterize_repeat_count"))
159     settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
160 }
161
162 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
163
164 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
165     LayerTreeHostImpl* host) {
166   LayerTreeHostCommon::CallFunctionForSubtree(
167       host->RootLayer(),
168       base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
169                  base::Unretained(this)));
170
171   scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
172   result->SetDouble("rasterize_time_ms",
173                     rasterize_results_.total_best_time.InMillisecondsF());
174   result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
175   result->SetInteger("pixels_rasterized_with_non_solid_color",
176                      rasterize_results_.pixels_rasterized_with_non_solid_color);
177   result->SetInteger("pixels_rasterized_as_opaque",
178                      rasterize_results_.pixels_rasterized_as_opaque);
179   result->SetInteger("total_layers", rasterize_results_.total_layers);
180   result->SetInteger("total_picture_layers",
181                      rasterize_results_.total_picture_layers);
182   result->SetInteger("total_picture_layers_with_no_content",
183                      rasterize_results_.total_picture_layers_with_no_content);
184   result->SetInteger("total_picture_layers_off_screen",
185                      rasterize_results_.total_picture_layers_off_screen);
186
187   NotifyDone(result.PassAs<base::Value>());
188 }
189
190 void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
191   rasterize_results_.total_layers++;
192   layer->RunMicroBenchmark(this);
193 }
194
195 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
196   rasterize_results_.total_picture_layers++;
197   if (!layer->DrawsContent()) {
198     rasterize_results_.total_picture_layers_with_no_content++;
199     return;
200   }
201   if (layer->visible_content_rect().IsEmpty()) {
202     rasterize_results_.total_picture_layers_off_screen++;
203     return;
204   }
205
206   TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner();
207   DCHECK(task_graph_runner);
208
209   if (!task_namespace_.IsValid())
210     task_namespace_ = task_graph_runner->GetNamespaceToken();
211
212   FixedInvalidationPictureLayerTilingClient client(
213       layer, gfx::Rect(layer->content_bounds()));
214   PictureLayerTilingSet tiling_set(&client, layer->content_bounds());
215
216   PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
217   tiling->CreateAllTilesForTesting();
218   for (PictureLayerTiling::CoverageIterator it(
219            tiling, layer->contents_scale_x(), layer->visible_content_rect());
220        it;
221        ++it) {
222     DCHECK(*it);
223
224     PicturePileImpl* picture_pile = (*it)->picture_pile();
225     gfx::Rect content_rect = (*it)->content_rect();
226     float contents_scale = (*it)->contents_scale();
227
228     scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
229         new BenchmarkRasterTask(picture_pile,
230                                 content_rect,
231                                 contents_scale,
232                                 rasterize_repeat_count_));
233
234     TaskGraph graph;
235
236     graph.nodes.push_back(
237         TaskGraph::Node(benchmark_raster_task.get(),
238                         RasterWorkerPool::kBenchmarkRasterTaskPriority,
239                         0u));
240
241     task_graph_runner->ScheduleTasks(task_namespace_, &graph);
242     task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
243
244     Task::Vector completed_tasks;
245     task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
246     DCHECK_EQ(1u, completed_tasks.size());
247     DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
248
249     int tile_size = content_rect.width() * content_rect.height();
250     base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
251     bool is_solid_color = benchmark_raster_task->IsSolidColor();
252
253     if (layer->contents_opaque())
254       rasterize_results_.pixels_rasterized_as_opaque += tile_size;
255
256     if (!is_solid_color) {
257       rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
258     }
259
260     rasterize_results_.pixels_rasterized += tile_size;
261     rasterize_results_.total_best_time += min_time;
262   }
263 }
264
265 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
266     : pixels_rasterized(0),
267       pixels_rasterized_with_non_solid_color(0),
268       pixels_rasterized_as_opaque(0),
269       total_layers(0),
270       total_picture_layers(0),
271       total_picture_layers_with_no_content(0),
272       total_picture_layers_off_screen(0) {}
273
274 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
275
276 }  // namespace cc