Upstream version 7.36.149.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/layers/layer_impl.h"
13 #include "cc/layers/picture_layer_impl.h"
14 #include "cc/resources/raster_worker_pool.h"
15 #include "cc/trees/layer_tree_host_common.h"
16 #include "cc/trees/layer_tree_host_impl.h"
17 #include "ui/gfx/rect.h"
18
19 namespace cc {
20
21 namespace {
22
23 const int kDefaultRasterizeRepeatCount = 100;
24
25 base::TimeTicks Now() {
26   return base::TimeTicks::IsThreadNowSupported()
27              ? base::TimeTicks::ThreadNow()
28              : base::TimeTicks::HighResNow();
29 }
30
31 class BenchmarkRasterTask : public Task {
32  public:
33   BenchmarkRasterTask(PicturePileImpl* picture_pile,
34                       const gfx::Rect& content_rect,
35                       float contents_scale,
36                       size_t repeat_count)
37       : picture_pile_(picture_pile),
38         content_rect_(content_rect),
39         contents_scale_(contents_scale),
40         repeat_count_(repeat_count),
41         is_solid_color_(false),
42         best_time_(base::TimeDelta::Max()) {}
43
44   // Overridden from Task:
45   virtual void RunOnWorkerThread() OVERRIDE {
46     PicturePileImpl* picture_pile = picture_pile_->GetCloneForDrawingOnThread(
47         RasterWorkerPool::GetPictureCloneIndexForCurrentThread());
48
49     for (size_t i = 0; i < repeat_count_; ++i) {
50       SkBitmap bitmap;
51       bitmap.allocPixels(SkImageInfo::MakeN32Premul(content_rect_.width(),
52                                                     content_rect_.height()));
53       SkCanvas canvas(bitmap);
54       PicturePileImpl::Analysis analysis;
55
56       base::TimeTicks start = Now();
57       picture_pile->AnalyzeInRect(
58           content_rect_, contents_scale_, &analysis, NULL);
59       picture_pile->RasterToBitmap(
60           &canvas, content_rect_, contents_scale_, NULL);
61       base::TimeTicks end = Now();
62       base::TimeDelta duration = end - start;
63       if (duration < best_time_)
64         best_time_ = duration;
65
66       is_solid_color_ = analysis.is_solid_color;
67     }
68   }
69
70   bool IsSolidColor() const { return is_solid_color_; }
71   base::TimeDelta GetBestTime() const { return best_time_; }
72
73  private:
74   virtual ~BenchmarkRasterTask() {}
75
76   PicturePileImpl* picture_pile_;
77   gfx::Rect content_rect_;
78   float contents_scale_;
79   size_t repeat_count_;
80   bool is_solid_color_;
81   base::TimeDelta best_time_;
82 };
83
84 }  // namespace
85
86 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
87     scoped_refptr<base::MessageLoopProxy> origin_loop,
88     base::Value* value,
89     const MicroBenchmarkImpl::DoneCallback& callback)
90     : MicroBenchmarkImpl(callback, origin_loop),
91       rasterize_repeat_count_(kDefaultRasterizeRepeatCount) {
92   base::DictionaryValue* settings = NULL;
93   value->GetAsDictionary(&settings);
94   if (!settings)
95     return;
96
97   if (settings->HasKey("rasterize_repeat_count"))
98     settings->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_);
99 }
100
101 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
102
103 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
104     LayerTreeHostImpl* host) {
105   LayerTreeHostCommon::CallFunctionForSubtree(
106       host->RootLayer(),
107       base::Bind(&RasterizeAndRecordBenchmarkImpl::Run,
108                  base::Unretained(this)));
109
110   scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
111   result->SetDouble("rasterize_time_ms",
112                     rasterize_results_.total_best_time.InMillisecondsF());
113   result->SetInteger("pixels_rasterized", rasterize_results_.pixels_rasterized);
114   result->SetInteger("pixels_rasterized_with_non_solid_color",
115                      rasterize_results_.pixels_rasterized_with_non_solid_color);
116   result->SetInteger("pixels_rasterized_as_opaque",
117                      rasterize_results_.pixels_rasterized_as_opaque);
118   result->SetInteger("total_layers", rasterize_results_.total_layers);
119   result->SetInteger("total_picture_layers",
120                      rasterize_results_.total_picture_layers);
121   result->SetInteger("total_picture_layers_with_no_content",
122                      rasterize_results_.total_picture_layers_with_no_content);
123   result->SetInteger("total_picture_layers_off_screen",
124                      rasterize_results_.total_picture_layers_off_screen);
125
126   NotifyDone(result.PassAs<base::Value>());
127 }
128
129 void RasterizeAndRecordBenchmarkImpl::Run(LayerImpl* layer) {
130   rasterize_results_.total_layers++;
131   layer->RunMicroBenchmark(this);
132 }
133
134 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) {
135   rasterize_results_.total_picture_layers++;
136   if (!layer->DrawsContent()) {
137     rasterize_results_.total_picture_layers_with_no_content++;
138     return;
139   }
140   if (layer->visible_content_rect().IsEmpty()) {
141     rasterize_results_.total_picture_layers_off_screen++;
142     return;
143   }
144
145   TaskGraphRunner* task_graph_runner = RasterWorkerPool::GetTaskGraphRunner();
146   DCHECK(task_graph_runner);
147
148   if (!task_namespace_.IsValid())
149     task_namespace_ = task_graph_runner->GetNamespaceToken();
150
151   PictureLayerTilingSet tiling_set(layer, layer->content_bounds());
152
153   PictureLayerTiling* tiling = tiling_set.AddTiling(layer->contents_scale_x());
154   tiling->CreateAllTilesForTesting();
155   for (PictureLayerTiling::CoverageIterator it(
156            tiling, layer->contents_scale_x(), layer->visible_content_rect());
157        it;
158        ++it) {
159     DCHECK(*it);
160
161     PicturePileImpl* picture_pile = (*it)->picture_pile();
162     gfx::Rect content_rect = (*it)->content_rect();
163     float contents_scale = (*it)->contents_scale();
164
165     scoped_refptr<BenchmarkRasterTask> benchmark_raster_task(
166         new BenchmarkRasterTask(picture_pile,
167                                 content_rect,
168                                 contents_scale,
169                                 rasterize_repeat_count_));
170
171     TaskGraph graph;
172
173     graph.nodes.push_back(
174         TaskGraph::Node(benchmark_raster_task,
175                         RasterWorkerPool::kBenchmarkRasterTaskPriority,
176                         0u));
177
178     task_graph_runner->ScheduleTasks(task_namespace_, &graph);
179     task_graph_runner->WaitForTasksToFinishRunning(task_namespace_);
180
181     Task::Vector completed_tasks;
182     task_graph_runner->CollectCompletedTasks(task_namespace_, &completed_tasks);
183     DCHECK_EQ(1u, completed_tasks.size());
184     DCHECK_EQ(completed_tasks[0], benchmark_raster_task);
185
186     int tile_size = content_rect.width() * content_rect.height();
187     base::TimeDelta min_time = benchmark_raster_task->GetBestTime();
188     bool is_solid_color = benchmark_raster_task->IsSolidColor();
189
190     if (layer->contents_opaque())
191       rasterize_results_.pixels_rasterized_as_opaque += tile_size;
192
193     if (!is_solid_color) {
194       rasterize_results_.pixels_rasterized_with_non_solid_color += tile_size;
195     }
196
197     rasterize_results_.pixels_rasterized += tile_size;
198     rasterize_results_.total_best_time += min_time;
199   }
200 }
201
202 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
203     : pixels_rasterized(0),
204       pixels_rasterized_with_non_solid_color(0),
205       pixels_rasterized_as_opaque(0),
206       total_layers(0),
207       total_picture_layers(0),
208       total_picture_layers_with_no_content(0),
209       total_picture_layers_off_screen(0) {}
210
211 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}
212
213 }  // namespace cc