• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h"
6 
7 #include <algorithm>
8 #include <limits>
9 
10 #include "base/basictypes.h"
11 #include "base/values.h"
12 #include "cc/debug/rasterize_and_record_benchmark_impl.h"
13 #include "cc/layers/layer.h"
14 #include "cc/layers/picture_layer.h"
15 #include "cc/trees/layer_tree_host.h"
16 #include "cc/trees/layer_tree_host_common.h"
17 #include "ui/gfx/rect.h"
18 
19 namespace cc {
20 
21 namespace {
22 
23 const int kDefaultRecordRepeatCount = 100;
24 
Now()25 base::TimeTicks Now() {
26   return base::TimeTicks::IsThreadNowSupported()
27              ? base::TimeTicks::ThreadNow()
28              : base::TimeTicks::HighResNow();
29 }
30 
31 }  // namespace
32 
RasterizeAndRecordBenchmark(scoped_ptr<base::Value> value,const MicroBenchmark::DoneCallback & callback)33 RasterizeAndRecordBenchmark::RasterizeAndRecordBenchmark(
34     scoped_ptr<base::Value> value,
35     const MicroBenchmark::DoneCallback& callback)
36     : MicroBenchmark(callback),
37       record_repeat_count_(kDefaultRecordRepeatCount),
38       settings_(value.Pass()),
39       main_thread_benchmark_done_(false),
40       host_(NULL),
41       weak_ptr_factory_(this) {
42   base::DictionaryValue* settings = NULL;
43   settings_->GetAsDictionary(&settings);
44   if (!settings)
45     return;
46 
47   if (settings->HasKey("record_repeat_count"))
48     settings->GetInteger("record_repeat_count", &record_repeat_count_);
49 }
50 
~RasterizeAndRecordBenchmark()51 RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() {
52   weak_ptr_factory_.InvalidateWeakPtrs();
53 }
54 
DidUpdateLayers(LayerTreeHost * host)55 void RasterizeAndRecordBenchmark::DidUpdateLayers(LayerTreeHost* host) {
56   host_ = host;
57   LayerTreeHostCommon::CallFunctionForSubtree(
58       host->root_layer(),
59       base::Bind(&RasterizeAndRecordBenchmark::Run, base::Unretained(this)));
60 
61   DCHECK(!results_.get());
62   results_ = make_scoped_ptr(new base::DictionaryValue);
63   results_->SetInteger("pixels_recorded", record_results_.pixels_recorded);
64   results_->SetDouble("record_time_ms",
65                       record_results_.total_best_time.InMillisecondsF());
66   main_thread_benchmark_done_ = true;
67 }
68 
RecordRasterResults(scoped_ptr<base::Value> results_value)69 void RasterizeAndRecordBenchmark::RecordRasterResults(
70     scoped_ptr<base::Value> results_value) {
71   DCHECK(main_thread_benchmark_done_);
72 
73   base::DictionaryValue* results = NULL;
74   results_value->GetAsDictionary(&results);
75 
76   DCHECK(results);
77   DCHECK(results->HasKey("pixels_rasterized"));
78   DCHECK(results->HasKey("rasterize_time_ms"));
79 
80   int pixels_rasterized;
81   results->GetInteger("pixels_rasterized", &pixels_rasterized);
82   double rasterize_time_ms;
83   results->GetDouble("rasterize_time_ms", &rasterize_time_ms);
84 
85   results_->SetInteger("pixels_rasterized", pixels_rasterized);
86   results_->SetDouble("rasterize_time_ms", rasterize_time_ms);
87 
88   NotifyDone(results_.PassAs<base::Value>());
89 }
90 
CreateBenchmarkImpl(scoped_refptr<base::MessageLoopProxy> origin_loop)91 scoped_ptr<MicroBenchmarkImpl> RasterizeAndRecordBenchmark::CreateBenchmarkImpl(
92     scoped_refptr<base::MessageLoopProxy> origin_loop) {
93   return scoped_ptr<MicroBenchmarkImpl>(new RasterizeAndRecordBenchmarkImpl(
94       origin_loop,
95       settings_.get(),
96       base::Bind(&RasterizeAndRecordBenchmark::RecordRasterResults,
97                  weak_ptr_factory_.GetWeakPtr())));
98 }
99 
Run(Layer * layer)100 void RasterizeAndRecordBenchmark::Run(Layer* layer) {
101   layer->RunMicroBenchmark(this);
102 }
103 
RunOnLayer(PictureLayer * layer)104 void RasterizeAndRecordBenchmark::RunOnLayer(PictureLayer* layer) {
105   ContentLayerClient* painter = layer->client();
106   gfx::Size content_bounds = layer->content_bounds();
107 
108   DCHECK(host_);
109   gfx::Size tile_grid_size = host_->settings().default_tile_size;
110 
111   SkTileGridPicture::TileGridInfo tile_grid_info;
112   PicturePileBase::ComputeTileGridInfo(tile_grid_size, &tile_grid_info);
113 
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;
118 
119   scoped_refptr<Picture> picture = Picture::Create(visible_content_rect);
120 
121   base::TimeDelta min_time =
122       base::TimeDelta::FromInternalValue(std::numeric_limits<int64>::max());
123   for (int i = 0; i < record_repeat_count_; ++i) {
124     base::TimeTicks start = Now();
125     picture->Record(painter, tile_grid_info);
126     base::TimeTicks end = Now();
127     base::TimeDelta duration = end - start;
128     if (duration < min_time)
129       min_time = duration;
130   }
131 
132   record_results_.pixels_recorded +=
133       visible_content_rect.width() * visible_content_rect.height();
134   record_results_.total_best_time += min_time;
135 }
136 
RecordResults()137 RasterizeAndRecordBenchmark::RecordResults::RecordResults()
138     : pixels_recorded(0) {}
139 
~RecordResults()140 RasterizeAndRecordBenchmark::RecordResults::~RecordResults() {}
141 
142 }  // namespace cc
143