1 // Copyright 2014 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/layers/picture_layer_impl.h"
6 
7 #include "base/threading/thread_task_runner_handle.h"
8 #include "base/timer/lap_timer.h"
9 #include "cc/test/fake_picture_layer_impl.h"
10 #include "cc/test/fake_raster_source.h"
11 #include "cc/test/layer_tree_impl_test_base.h"
12 #include "cc/tiles/tiling_set_raster_queue_all.h"
13 #include "cc/trees/layer_tree_impl.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/perf/perf_result_reporter.h"
16 
17 namespace cc {
18 namespace {
19 
20 static const int kTimeLimitMillis = 2000;
21 static const int kWarmupRuns = 5;
22 static const int kTimeCheckInterval = 10;
23 
AddTiling(float scale,FakePictureLayerImpl * layer,std::vector<Tile * > * all_tiles)24 void AddTiling(float scale,
25                FakePictureLayerImpl* layer,
26                std::vector<Tile*>* all_tiles) {
27   PictureLayerTiling* tiling =
28       layer->AddTiling(gfx::AxisTransform2d(scale, gfx::Vector2dF()));
29 
30   tiling->set_resolution(HIGH_RESOLUTION);
31   tiling->CreateAllTilesForTesting();
32   std::vector<Tile*> tiling_tiles = tiling->AllTilesForTesting();
33   std::copy(
34       tiling_tiles.begin(), tiling_tiles.end(), std::back_inserter(*all_tiles));
35 }
36 
37 class PictureLayerImplPerfTest : public LayerTreeImplTestBase,
38                                  public testing::Test {
39  public:
PictureLayerImplPerfTest()40   PictureLayerImplPerfTest()
41       : timer_(kWarmupRuns,
42                base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
43                kTimeCheckInterval) {}
44 
45   PictureLayerImplPerfTest(const PictureLayerImplPerfTest&) = delete;
46   PictureLayerImplPerfTest& operator=(const PictureLayerImplPerfTest&) = delete;
47 
SetupPendingTree(const gfx::Size & layer_bounds)48   void SetupPendingTree(const gfx::Size& layer_bounds) {
49     scoped_refptr<FakeRasterSource> raster_source =
50         FakeRasterSource::CreateFilled(layer_bounds);
51     host_impl()->CreatePendingTree();
52     LayerTreeImpl* pending_tree = host_impl()->pending_tree();
53     pending_tree->DetachLayers();
54 
55     std::unique_ptr<FakePictureLayerImpl> pending_layer =
56         FakePictureLayerImpl::Create(pending_tree, 7, raster_source);
57     pending_layer->SetDrawsContent(true);
58     pending_layer_ = pending_layer.get();
59     pending_tree->SetElementIdsForTesting();
60     SetupRootProperties(pending_layer_);
61     pending_tree->SetRootLayerForTesting(std::move(pending_layer));
62 
63     PrepareForUpdateDrawProperties(pending_tree);
64     // Don't update draw properties because the tilings will conflict with the
65     // tilings that will be added in the tests.
66   }
67 
RunRasterQueueConstructAndIterateTest(const std::string & test_name,int num_tiles,const gfx::Rect & viewport_rect)68   void RunRasterQueueConstructAndIterateTest(const std::string& test_name,
69                                              int num_tiles,
70                                              const gfx::Rect& viewport_rect) {
71     host_impl()->active_tree()->SetDeviceViewportRect(viewport_rect);
72     host_impl()->pending_tree()->UpdateDrawProperties();
73 
74     timer_.Reset();
75     do {
76       int count = num_tiles;
77       std::unique_ptr<TilingSetRasterQueueAll> queue(
78           new TilingSetRasterQueueAll(
79               pending_layer_->picture_layer_tiling_set(), false, true));
80       while (count--) {
81         ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count;
82         ASSERT_TRUE(queue->Top().tile()) << "count: " << count;
83         queue->Pop();
84       }
85       timer_.NextLap();
86     } while (!timer_.HasTimeLimitExpired());
87 
88     perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
89     reporter.AddResult("_raster_queue_construct_and_iterate",
90                        timer_.LapsPerSecond());
91   }
92 
RunRasterQueueConstructTest(const std::string & test_name,const gfx::Rect & viewport)93   void RunRasterQueueConstructTest(const std::string& test_name,
94                                    const gfx::Rect& viewport) {
95     host_impl()->active_tree()->SetDeviceViewportRect(viewport);
96     host_impl()
97         ->pending_tree()
98         ->property_trees()
99         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
100             pending_layer_->element_id(),
101             gfx::ScrollOffset(viewport.x(), viewport.y()));
102     host_impl()->pending_tree()->UpdateDrawProperties();
103 
104     timer_.Reset();
105     do {
106       std::unique_ptr<TilingSetRasterQueueAll> queue(
107           new TilingSetRasterQueueAll(
108               pending_layer_->picture_layer_tiling_set(), false, true));
109       timer_.NextLap();
110     } while (!timer_.HasTimeLimitExpired());
111 
112     perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
113     reporter.AddResult("_raster_queue_construct", timer_.LapsPerSecond());
114   }
115 
RunEvictionQueueConstructAndIterateTest(const std::string & test_name,int num_tiles,const gfx::Rect & viewport_rect)116   void RunEvictionQueueConstructAndIterateTest(const std::string& test_name,
117                                                int num_tiles,
118                                                const gfx::Rect& viewport_rect) {
119     host_impl()->active_tree()->SetDeviceViewportRect(viewport_rect);
120     host_impl()->pending_tree()->UpdateDrawProperties();
121 
122     timer_.Reset();
123     do {
124       int count = num_tiles;
125       std::unique_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue(
126           pending_layer_->picture_layer_tiling_set(),
127           pending_layer_->contributes_to_drawn_render_surface()));
128       while (count--) {
129         ASSERT_TRUE(!queue->IsEmpty()) << "count: " << count;
130         ASSERT_TRUE(queue->Top().tile()) << "count: " << count;
131         queue->Pop();
132       }
133       timer_.NextLap();
134     } while (!timer_.HasTimeLimitExpired());
135 
136     perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
137     reporter.AddResult("_eviction_queue_construct_and_iterate",
138                        timer_.LapsPerSecond());
139   }
140 
RunEvictionQueueConstructTest(const std::string & test_name,const gfx::Rect & viewport)141   void RunEvictionQueueConstructTest(const std::string& test_name,
142                                      const gfx::Rect& viewport) {
143     host_impl()->active_tree()->SetDeviceViewportRect(viewport);
144     host_impl()
145         ->pending_tree()
146         ->property_trees()
147         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
148             pending_layer_->element_id(),
149             gfx::ScrollOffset(viewport.x(), viewport.y()));
150     host_impl()->pending_tree()->UpdateDrawProperties();
151 
152     timer_.Reset();
153     do {
154       std::unique_ptr<TilingSetEvictionQueue> queue(new TilingSetEvictionQueue(
155           pending_layer_->picture_layer_tiling_set(),
156           pending_layer_->contributes_to_drawn_render_surface()));
157       timer_.NextLap();
158     } while (!timer_.HasTimeLimitExpired());
159 
160     perf_test::PerfResultReporter reporter = SetUpReporter(test_name);
161     reporter.AddResult("_eviction_queue_construct", timer_.LapsPerSecond());
162   }
163 
164  protected:
SetUpReporter(const std::string & story_name)165   perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) {
166     perf_test::PerfResultReporter reporter("tiling_set", story_name);
167     reporter.RegisterImportantMetric("_raster_queue_construct_and_iterate",
168                                      "runs/s");
169     reporter.RegisterImportantMetric("_raster_queue_construct", "runs/s");
170     reporter.RegisterImportantMetric("_eviction_queue_construct_and_iterate",
171                                      "runs/s");
172     return reporter;
173   }
174 
175   FakePictureLayerImpl* pending_layer_;
176   base::LapTimer timer_;
177 };
178 
TEST_F(PictureLayerImplPerfTest,TilingSetRasterQueueConstructAndIterate)179 TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) {
180   SetupPendingTree(gfx::Size(10000, 10000));
181 
182   float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
183 
184   pending_layer_->AddTiling(
185       gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF()));
186   pending_layer_->AddTiling(gfx::AxisTransform2d(0.3f, gfx::Vector2dF()));
187   pending_layer_->AddTiling(gfx::AxisTransform2d(0.7f, gfx::Vector2dF()));
188   pending_layer_->AddTiling(gfx::AxisTransform2d(1.0f, gfx::Vector2dF()));
189   pending_layer_->AddTiling(gfx::AxisTransform2d(2.0f, gfx::Vector2dF()));
190 
191   RunRasterQueueConstructAndIterateTest("32_100x100", 32, gfx::Rect(100, 100));
192   RunRasterQueueConstructAndIterateTest("32_500x500", 32, gfx::Rect(500, 500));
193   RunRasterQueueConstructAndIterateTest("64_100x100", 64, gfx::Rect(100, 100));
194   RunRasterQueueConstructAndIterateTest("64_500x500", 64, gfx::Rect(500, 500));
195 }
196 
TEST_F(PictureLayerImplPerfTest,TilingSetRasterQueueConstruct)197 TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) {
198   SetupPendingTree(gfx::Size(10000, 10000));
199 
200   float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
201 
202   pending_layer_->AddTiling(
203       gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF()));
204   pending_layer_->AddTiling(gfx::AxisTransform2d(0.3f, gfx::Vector2dF()));
205   pending_layer_->AddTiling(gfx::AxisTransform2d(0.7f, gfx::Vector2dF()));
206   pending_layer_->AddTiling(gfx::AxisTransform2d(1.0f, gfx::Vector2dF()));
207   pending_layer_->AddTiling(gfx::AxisTransform2d(2.0f, gfx::Vector2dF()));
208 
209   RunRasterQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
210   RunRasterQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100));
211   RunRasterQueueConstructTest("9999_0_100x100", gfx::Rect(9999, 0, 100, 100));
212 }
213 
TEST_F(PictureLayerImplPerfTest,TilingSetEvictionQueueConstructAndIterate)214 TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) {
215   SetupPendingTree(gfx::Size(10000, 10000));
216 
217   float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
218 
219   std::vector<Tile*> all_tiles;
220   AddTiling(low_res_factor, pending_layer_, &all_tiles);
221   AddTiling(0.3f, pending_layer_, &all_tiles);
222   AddTiling(0.7f, pending_layer_, &all_tiles);
223   AddTiling(1.0f, pending_layer_, &all_tiles);
224   AddTiling(2.0f, pending_layer_, &all_tiles);
225 
226   ASSERT_TRUE(host_impl()->tile_manager() != nullptr);
227   host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
228       all_tiles);
229 
230   RunEvictionQueueConstructAndIterateTest("32_100x100", 32,
231                                           gfx::Rect(100, 100));
232   RunEvictionQueueConstructAndIterateTest("32_500x500", 32,
233                                           gfx::Rect(500, 500));
234   RunEvictionQueueConstructAndIterateTest("64_100x100", 64,
235                                           gfx::Rect(100, 100));
236   RunEvictionQueueConstructAndIterateTest("64_500x500", 64,
237                                           gfx::Rect(500, 500));
238 }
239 
TEST_F(PictureLayerImplPerfTest,TilingSetEvictionQueueConstruct)240 TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstruct) {
241   SetupPendingTree(gfx::Size(10000, 10000));
242 
243   float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
244 
245   std::vector<Tile*> all_tiles;
246   AddTiling(low_res_factor, pending_layer_, &all_tiles);
247   AddTiling(0.3f, pending_layer_, &all_tiles);
248   AddTiling(0.7f, pending_layer_, &all_tiles);
249   AddTiling(1.0f, pending_layer_, &all_tiles);
250   AddTiling(2.0f, pending_layer_, &all_tiles);
251 
252   ASSERT_TRUE(host_impl()->tile_manager() != nullptr);
253   host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
254       all_tiles);
255 
256   RunEvictionQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
257   RunEvictionQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100));
258   RunEvictionQueueConstructTest("9999_0_100x100", gfx::Rect(9999, 0, 100, 100));
259 }
260 
261 }  // namespace
262 }  // namespace cc
263