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_impl.h"
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/tile_task_worker_pool.h"
16 #include "cc/trees/layer_tree_host_common.h"
17 #include "cc/trees/layer_tree_host_impl.h"
18 #include "cc/trees/layer_tree_impl.h"
19 #include "ui/gfx/geometry/rect.h"
25 const int kDefaultRasterizeRepeatCount
= 100;
27 void RunBenchmark(RasterSource
* raster_source
,
28 const gfx::Rect
& content_rect
,
31 base::TimeDelta
* min_time
,
32 bool* is_solid_color
) {
33 // Parameters for LapTimer.
34 const int kTimeLimitMillis
= 1;
35 const int kWarmupRuns
= 0;
36 const int kTimeCheckInterval
= 1;
38 *min_time
= base::TimeDelta::Max();
39 for (size_t i
= 0; i
< repeat_count
; ++i
) {
40 // Run for a minimum amount of time to avoid problems with timer
41 // quantization when the layer is very small.
42 LapTimer
timer(kWarmupRuns
,
43 base::TimeDelta::FromMilliseconds(kTimeLimitMillis
),
47 bitmap
.allocPixels(SkImageInfo::MakeN32Premul(content_rect
.width(),
48 content_rect
.height()));
49 SkCanvas
canvas(bitmap
);
50 RasterSource::SolidColorAnalysis analysis
;
52 raster_source
->PerformSolidColorAnalysis(content_rect
, contents_scale
,
54 raster_source
->PlaybackToCanvas(&canvas
, content_rect
, contents_scale
);
56 *is_solid_color
= analysis
.is_solid_color
;
59 } while (!timer
.HasTimeLimitExpired());
60 base::TimeDelta duration
=
61 base::TimeDelta::FromMillisecondsD(timer
.MsPerLap());
62 if (duration
< *min_time
)
67 class FixedInvalidationPictureLayerTilingClient
68 : public PictureLayerTilingClient
{
70 FixedInvalidationPictureLayerTilingClient(
71 PictureLayerTilingClient
* base_client
,
72 const Region invalidation
)
73 : base_client_(base_client
), invalidation_(invalidation
) {}
75 scoped_refptr
<Tile
> CreateTile(float contents_scale
,
76 const gfx::Rect
& content_rect
) override
{
77 return base_client_
->CreateTile(contents_scale
, content_rect
);
80 gfx::Size
CalculateTileSize(const gfx::Size
& content_bounds
) const override
{
81 return base_client_
->CalculateTileSize(content_bounds
);
84 // This is the only function that returns something different from the base
85 // client. Avoids sharing tiles in this area.
86 const Region
* GetPendingInvalidation() override
{ return &invalidation_
; }
88 const PictureLayerTiling
* GetPendingOrActiveTwinTiling(
89 const PictureLayerTiling
* tiling
) const override
{
90 return base_client_
->GetPendingOrActiveTwinTiling(tiling
);
93 PictureLayerTiling
* GetRecycledTwinTiling(
94 const PictureLayerTiling
* tiling
) override
{
95 return base_client_
->GetRecycledTwinTiling(tiling
);
98 TilePriority::PriorityBin
GetMaxTilePriorityBin() const override
{
99 return base_client_
->GetMaxTilePriorityBin();
102 WhichTree
GetTree() const override
{ return base_client_
->GetTree(); }
104 bool RequiresHighResToDraw() const override
{
105 return base_client_
->RequiresHighResToDraw();
109 PictureLayerTilingClient
* base_client_
;
110 Region invalidation_
;
115 RasterizeAndRecordBenchmarkImpl::RasterizeAndRecordBenchmarkImpl(
116 scoped_refptr
<base::MessageLoopProxy
> origin_loop
,
118 const MicroBenchmarkImpl::DoneCallback
& callback
)
119 : MicroBenchmarkImpl(callback
, origin_loop
),
120 rasterize_repeat_count_(kDefaultRasterizeRepeatCount
) {
121 base::DictionaryValue
* settings
= nullptr;
122 value
->GetAsDictionary(&settings
);
126 if (settings
->HasKey("rasterize_repeat_count"))
127 settings
->GetInteger("rasterize_repeat_count", &rasterize_repeat_count_
);
130 RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() {}
132 void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit(
133 LayerTreeHostImpl
* host
) {
134 LayerTreeHostCommon::CallFunctionForSubtree(
135 host
->RootLayer(), [this](LayerImpl
* layer
) {
136 rasterize_results_
.total_layers
++;
137 layer
->RunMicroBenchmark(this);
140 scoped_ptr
<base::DictionaryValue
> result(new base::DictionaryValue());
141 result
->SetDouble("rasterize_time_ms",
142 rasterize_results_
.total_best_time
.InMillisecondsF());
143 result
->SetDouble("total_pictures_in_pile_size",
144 rasterize_results_
.total_memory_usage
);
145 result
->SetInteger("pixels_rasterized", rasterize_results_
.pixels_rasterized
);
146 result
->SetInteger("pixels_rasterized_with_non_solid_color",
147 rasterize_results_
.pixels_rasterized_with_non_solid_color
);
148 result
->SetInteger("pixels_rasterized_as_opaque",
149 rasterize_results_
.pixels_rasterized_as_opaque
);
150 result
->SetInteger("total_layers", rasterize_results_
.total_layers
);
151 result
->SetInteger("total_picture_layers",
152 rasterize_results_
.total_picture_layers
);
153 result
->SetInteger("total_picture_layers_with_no_content",
154 rasterize_results_
.total_picture_layers_with_no_content
);
155 result
->SetInteger("total_picture_layers_off_screen",
156 rasterize_results_
.total_picture_layers_off_screen
);
158 NotifyDone(result
.Pass());
161 void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl
* layer
) {
162 rasterize_results_
.total_picture_layers
++;
163 if (!layer
->CanHaveTilings()) {
164 rasterize_results_
.total_picture_layers_with_no_content
++;
167 if (layer
->visible_content_rect().IsEmpty()) {
168 rasterize_results_
.total_picture_layers_off_screen
++;
172 FixedInvalidationPictureLayerTilingClient
client(
173 layer
, gfx::Rect(layer
->content_bounds()));
175 // In this benchmark, we will create a local tiling set and measure how long
176 // it takes to rasterize content. As such, the actual settings used here don't
178 const LayerTreeSettings
& settings
= layer
->layer_tree_impl()->settings();
179 scoped_ptr
<PictureLayerTilingSet
> tiling_set
= PictureLayerTilingSet::Create(
180 &client
, settings
.max_tiles_for_interest_area
,
181 settings
.skewport_target_time_in_seconds
,
182 settings
.skewport_extrapolation_limit_in_content_pixels
);
184 PictureLayerTiling
* tiling
= tiling_set
->AddTiling(layer
->contents_scale_x(),
185 layer
->GetRasterSource());
186 tiling
->CreateAllTilesForTesting();
187 for (PictureLayerTiling::CoverageIterator
it(
188 tiling
, layer
->contents_scale_x(), layer
->visible_content_rect());
193 RasterSource
* raster_source
= (*it
)->raster_source();
194 gfx::Rect content_rect
= (*it
)->content_rect();
195 float contents_scale
= (*it
)->contents_scale();
197 base::TimeDelta min_time
;
198 bool is_solid_color
= false;
199 RunBenchmark(raster_source
, content_rect
, contents_scale
,
200 rasterize_repeat_count_
, &min_time
, &is_solid_color
);
202 int tile_size
= content_rect
.width() * content_rect
.height();
203 if (layer
->contents_opaque())
204 rasterize_results_
.pixels_rasterized_as_opaque
+= tile_size
;
207 rasterize_results_
.pixels_rasterized_with_non_solid_color
+= tile_size
;
209 rasterize_results_
.pixels_rasterized
+= tile_size
;
210 rasterize_results_
.total_best_time
+= min_time
;
213 const RasterSource
* layer_raster_source
= layer
->GetRasterSource();
214 rasterize_results_
.total_memory_usage
+=
215 layer_raster_source
->GetPictureMemoryUsage();
218 RasterizeAndRecordBenchmarkImpl::RasterizeResults::RasterizeResults()
219 : pixels_rasterized(0),
220 pixels_rasterized_with_non_solid_color(0),
221 pixels_rasterized_as_opaque(0),
222 total_memory_usage(0),
224 total_picture_layers(0),
225 total_picture_layers_with_no_content(0),
226 total_picture_layers_off_screen(0) {
229 RasterizeAndRecordBenchmarkImpl::RasterizeResults::~RasterizeResults() {}