- add sources.
[platform/framework/web/crosswalk.git] / src / cc / resources / tile_manager_unittest.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/resources/tile.h"
6 #include "cc/resources/tile_priority.h"
7 #include "cc/test/fake_output_surface.h"
8 #include "cc/test/fake_output_surface_client.h"
9 #include "cc/test/fake_picture_pile_impl.h"
10 #include "cc/test/fake_tile_manager.h"
11 #include "cc/test/fake_tile_manager_client.h"
12 #include "cc/test/test_tile_priorities.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace cc {
16 namespace {
17
18 class TileManagerTest : public testing::TestWithParam<bool> {
19  public:
20   typedef std::vector<scoped_refptr<Tile> > TileVector;
21
22   void Initialize(int max_tiles,
23                   TileMemoryLimitPolicy memory_limit_policy,
24                   TreePriority tree_priority) {
25     output_surface_ = FakeOutputSurface::Create3d();
26     CHECK(output_surface_->BindToClient(&output_surface_client_));
27
28     resource_provider_ =
29         ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
30     tile_manager_ = make_scoped_ptr(
31         new FakeTileManager(&tile_manager_client_, resource_provider_.get()));
32
33     memory_limit_policy_ = memory_limit_policy;
34     max_memory_tiles_ = max_tiles;
35     GlobalStateThatImpactsTilePriority state;
36     gfx::Size tile_size = settings_.default_tile_size;
37
38     // The parametrization specifies whether the max tile limit should
39     // be applied to RAM or to tile limit.
40     if (GetParam()) {
41       state.memory_limit_in_bytes =
42           max_tiles * 4 * tile_size.width() * tile_size.height();
43       state.num_resources_limit = 100;
44     } else {
45       state.memory_limit_in_bytes = 100 * 1000 * 1000;
46       state.num_resources_limit = max_tiles;
47     }
48     state.unused_memory_limit_in_bytes = state.memory_limit_in_bytes;
49     state.memory_limit_policy = memory_limit_policy;
50     state.tree_priority = tree_priority;
51
52     global_state_ = state;
53     tile_manager_->ManageTiles(state);
54     picture_pile_ = FakePicturePileImpl::CreatePile();
55   }
56
57   void SetTreePriority(TreePriority tree_priority) {
58     GlobalStateThatImpactsTilePriority state;
59     gfx::Size tile_size = settings_.default_tile_size;
60     state.memory_limit_in_bytes =
61         max_memory_tiles_ * 4 * tile_size.width() * tile_size.height();
62     state.unused_memory_limit_in_bytes = state.memory_limit_in_bytes;
63     state.memory_limit_policy = memory_limit_policy_;
64     state.num_resources_limit = 100;
65     state.tree_priority = tree_priority;
66     global_state_ = state;
67   }
68
69   virtual void TearDown() OVERRIDE {
70     tile_manager_.reset(NULL);
71     picture_pile_ = NULL;
72
73     testing::Test::TearDown();
74   }
75
76   TileVector CreateTilesWithSize(int count,
77                                  TilePriority active_priority,
78                                  TilePriority pending_priority,
79                                  gfx::Size tile_size) {
80     TileVector tiles;
81     for (int i = 0; i < count; ++i) {
82       scoped_refptr<Tile> tile = tile_manager_->CreateTile(picture_pile_.get(),
83                                                            tile_size,
84                                                            gfx::Rect(),
85                                                            gfx::Rect(),
86                                                            1.0,
87                                                            0,
88                                                            0,
89                                                            true);
90       tile->SetPriority(ACTIVE_TREE, active_priority);
91       tile->SetPriority(PENDING_TREE, pending_priority);
92       tiles.push_back(tile);
93     }
94     return tiles;
95   }
96
97   TileVector CreateTiles(int count,
98                          TilePriority active_priority,
99                          TilePriority pending_priority) {
100     return CreateTilesWithSize(count,
101                                active_priority,
102                                pending_priority,
103                                settings_.default_tile_size);
104   }
105
106   FakeTileManager* tile_manager() {
107     return tile_manager_.get();
108   }
109
110   int AssignedMemoryCount(const TileVector& tiles) {
111     int has_memory_count = 0;
112     for (TileVector::const_iterator it = tiles.begin();
113          it != tiles.end();
114          ++it) {
115       if (tile_manager_->HasBeenAssignedMemory(*it))
116         ++has_memory_count;
117     }
118     return has_memory_count;
119   }
120
121   int TilesWithLCDCount(const TileVector& tiles) {
122     int has_lcd_count = 0;
123     for (TileVector::const_iterator it = tiles.begin();
124          it != tiles.end();
125          ++it) {
126       if ((*it)->GetRasterModeForTesting() == HIGH_QUALITY_RASTER_MODE)
127         ++has_lcd_count;
128     }
129     return has_lcd_count;
130   }
131
132  protected:
133   GlobalStateThatImpactsTilePriority global_state_;
134
135  private:
136   FakeTileManagerClient tile_manager_client_;
137   LayerTreeSettings settings_;
138   scoped_ptr<FakeTileManager> tile_manager_;
139   scoped_refptr<FakePicturePileImpl> picture_pile_;
140   FakeOutputSurfaceClient output_surface_client_;
141   scoped_ptr<FakeOutputSurface> output_surface_;
142   scoped_ptr<ResourceProvider> resource_provider_;
143   TileMemoryLimitPolicy memory_limit_policy_;
144   int max_memory_tiles_;
145 };
146
147 TEST_P(TileManagerTest, EnoughMemoryAllowAnything) {
148   // A few tiles of each type of priority, with enough memory for all tiles.
149
150   Initialize(10, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
151   TileVector active_now =
152       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
153   TileVector pending_now =
154       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
155   TileVector active_pending_soon = CreateTiles(
156       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
157   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
158
159   tile_manager()->AssignMemoryToTiles(global_state_);
160
161   EXPECT_EQ(3, AssignedMemoryCount(active_now));
162   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
163   EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
164   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
165 }
166
167 TEST_P(TileManagerTest, EnoughMemoryAllowPrepaintOnly) {
168   // A few tiles of each type of priority, with enough memory for all tiles,
169   // with the exception of never bin.
170
171   Initialize(10, ALLOW_PREPAINT_ONLY, SMOOTHNESS_TAKES_PRIORITY);
172   TileVector active_now =
173       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
174   TileVector pending_now =
175       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
176   TileVector active_pending_soon = CreateTiles(
177       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
178   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
179
180   tile_manager()->AssignMemoryToTiles(global_state_);
181
182   EXPECT_EQ(3, AssignedMemoryCount(active_now));
183   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
184   EXPECT_EQ(3, AssignedMemoryCount(active_pending_soon));
185   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
186 }
187
188 TEST_P(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) {
189   // A few tiles of each type of priority, with enough memory for all tiles,
190   // with the exception of never and soon bins.
191
192   Initialize(10, ALLOW_ABSOLUTE_MINIMUM, SMOOTHNESS_TAKES_PRIORITY);
193   TileVector active_now =
194       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
195   TileVector pending_now =
196       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
197   TileVector active_pending_soon = CreateTiles(
198       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
199   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
200
201   tile_manager()->AssignMemoryToTiles(global_state_);
202
203   EXPECT_EQ(3, AssignedMemoryCount(active_now));
204   EXPECT_EQ(3, AssignedMemoryCount(pending_now));
205   EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
206   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
207 }
208
209 TEST_P(TileManagerTest, EnoughMemoryAllowNothing) {
210   // A few tiles of each type of priority, with enough memory for all tiles,
211   // but allow nothing should not assign any memory.
212
213   Initialize(10, ALLOW_NOTHING, SMOOTHNESS_TAKES_PRIORITY);
214   TileVector active_now =
215       CreateTiles(3, TilePriorityForNowBin(), TilePriority());
216   TileVector pending_now =
217       CreateTiles(3, TilePriority(), TilePriorityForNowBin());
218   TileVector active_pending_soon = CreateTiles(
219       3, TilePriorityForSoonBin(), TilePriorityForSoonBin());
220   TileVector never_bin = CreateTiles(1, TilePriority(), TilePriority());
221
222   tile_manager()->AssignMemoryToTiles(global_state_);
223
224   EXPECT_EQ(0, AssignedMemoryCount(active_now));
225   EXPECT_EQ(0, AssignedMemoryCount(pending_now));
226   EXPECT_EQ(0, AssignedMemoryCount(active_pending_soon));
227   EXPECT_EQ(0, AssignedMemoryCount(never_bin));
228 }
229
230 TEST_P(TileManagerTest, PartialOOMMemoryToPending) {
231   // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are
232   // required for activation, but only enough memory for 8 tiles. The result
233   // is all pending tree tiles get memory, and 3 of the active tree tiles
234   // get memory.
235
236   Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
237   TileVector active_tree_tiles =
238       CreateTiles(5, TilePriorityForEventualBin(), TilePriority());
239   TileVector pending_tree_tiles =
240       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
241
242   tile_manager()->AssignMemoryToTiles(global_state_);
243
244   EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
245   EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
246
247   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
248   tile_manager()->AssignMemoryToTiles(global_state_);
249
250   EXPECT_EQ(3, AssignedMemoryCount(active_tree_tiles));
251   EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles));
252 }
253
254 TEST_P(TileManagerTest, PartialOOMMemoryToActive) {
255   // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin,
256   // but only enough memory for 8 tiles. The result is all active tree tiles
257   // get memory, and 3 of the pending tree tiles get memory.
258
259   Initialize(8, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
260   TileVector active_tree_tiles =
261       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
262   TileVector pending_tree_tiles =
263       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
264
265   tile_manager()->AssignMemoryToTiles(global_state_);
266
267   EXPECT_EQ(5, AssignedMemoryCount(active_tree_tiles));
268   EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles));
269 }
270
271 TEST_P(TileManagerTest, TotalOOMMemoryToPending) {
272   // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are
273   // required for activation, but only enough memory for 4 tiles. The result
274   // is 4 pending tree tiles get memory, and none of the active tree tiles
275   // get memory.
276
277   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
278   TileVector active_tree_tiles =
279       CreateTiles(5, TilePriorityForEventualBin(), TilePriority());
280   TileVector pending_tree_tiles =
281       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
282
283   tile_manager()->AssignMemoryToTiles(global_state_);
284
285   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
286   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
287
288   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
289   tile_manager()->AssignMemoryToTiles(global_state_);
290
291   EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
292   EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
293 }
294
295 TEST_P(TileManagerTest, TotalOOMActiveSoonMemoryToPending) {
296   // 5 tiles on active tree soon bin, 5 tiles on pending tree that are
297   // required for activation, but only enough memory for 4 tiles. The result
298   // is 4 pending tree tiles get memory, and none of the active tree tiles
299   // get memory.
300
301   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
302   TileVector active_tree_tiles =
303       CreateTiles(5, TilePriorityForSoonBin(), TilePriority());
304   TileVector pending_tree_tiles =
305       CreateTiles(5, TilePriority(), TilePriorityRequiredForActivation());
306
307   tile_manager()->AssignMemoryToTiles(global_state_);
308
309   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
310   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
311
312   SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
313   tile_manager()->AssignMemoryToTiles(global_state_);
314
315   EXPECT_EQ(0, AssignedMemoryCount(active_tree_tiles));
316   EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles));
317 }
318
319 TEST_P(TileManagerTest, TotalOOMMemoryToActive) {
320   // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin,
321   // but only enough memory for 4 tiles. The result is 5 active tree tiles
322   // get memory, and none of the pending tree tiles get memory.
323
324   Initialize(4, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
325   TileVector active_tree_tiles =
326       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
327   TileVector pending_tree_tiles =
328       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
329
330   tile_manager()->AssignMemoryToTiles(global_state_);
331
332   EXPECT_EQ(4, AssignedMemoryCount(active_tree_tiles));
333   EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles));
334 }
335
336
337
338 TEST_P(TileManagerTest, RasterAsLCD) {
339   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
340   TileVector active_tree_tiles =
341       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
342   TileVector pending_tree_tiles =
343       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
344
345   tile_manager()->ManageTiles(global_state_);
346
347   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
348   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
349 }
350
351 TEST_P(TileManagerTest, RasterAsNoLCD) {
352   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
353   TileVector active_tree_tiles =
354       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
355   TileVector pending_tree_tiles =
356       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
357
358   for (TileVector::iterator it = active_tree_tiles.begin();
359        it != active_tree_tiles.end();
360        ++it) {
361     (*it)->set_can_use_lcd_text(false);
362   }
363   for (TileVector::iterator it = pending_tree_tiles.begin();
364        it != pending_tree_tiles.end();
365        ++it) {
366     (*it)->set_can_use_lcd_text(false);
367   }
368
369   tile_manager()->ManageTiles(global_state_);
370
371   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
372   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
373 }
374
375 TEST_P(TileManagerTest, ReRasterAsNoLCD) {
376   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
377   TileVector active_tree_tiles =
378       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
379   TileVector pending_tree_tiles =
380       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
381
382   tile_manager()->ManageTiles(global_state_);
383
384   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
385   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
386
387   for (TileVector::iterator it = active_tree_tiles.begin();
388        it != active_tree_tiles.end();
389        ++it) {
390     (*it)->set_can_use_lcd_text(false);
391   }
392   for (TileVector::iterator it = pending_tree_tiles.begin();
393        it != pending_tree_tiles.end();
394        ++it) {
395     (*it)->set_can_use_lcd_text(false);
396   }
397
398   tile_manager()->ManageTiles(global_state_);
399
400   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
401   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
402 }
403
404 TEST_P(TileManagerTest, NoTextDontReRasterAsNoLCD) {
405   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
406   TileVector active_tree_tiles =
407       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
408   TileVector pending_tree_tiles =
409       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
410
411   tile_manager()->ManageTiles(global_state_);
412
413   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
414   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
415
416   for (TileVector::iterator it = active_tree_tiles.begin();
417        it != active_tree_tiles.end();
418        ++it) {
419     ManagedTileState::TileVersion& tile_version =
420         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
421     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
422     (*it)->set_can_use_lcd_text(false);
423     EXPECT_TRUE((*it)->IsReadyToDraw());
424   }
425   for (TileVector::iterator it = pending_tree_tiles.begin();
426        it != pending_tree_tiles.end();
427        ++it) {
428     ManagedTileState::TileVersion& tile_version =
429         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
430     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
431     (*it)->set_can_use_lcd_text(false);
432     EXPECT_TRUE((*it)->IsReadyToDraw());
433   }
434
435   tile_manager()->ManageTiles(global_state_);
436
437   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
438   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
439 }
440
441 TEST_P(TileManagerTest, TextReRasterAsNoLCD) {
442   Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
443   TileVector active_tree_tiles =
444       CreateTiles(5, TilePriorityForNowBin(), TilePriority());
445   TileVector pending_tree_tiles =
446       CreateTiles(5, TilePriority(), TilePriorityForNowBin());
447
448   tile_manager()->ManageTiles(global_state_);
449
450   EXPECT_EQ(5, TilesWithLCDCount(active_tree_tiles));
451   EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles));
452
453   for (TileVector::iterator it = active_tree_tiles.begin();
454        it != active_tree_tiles.end();
455        ++it) {
456     ManagedTileState::TileVersion& tile_version =
457         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
458     tile_version.SetSolidColorForTesting(SkColorSetARGB(0, 0, 0, 0));
459     tile_version.SetHasTextForTesting(true);
460     (*it)->set_can_use_lcd_text(false);
461
462     EXPECT_TRUE((*it)->IsReadyToDraw());
463   }
464   for (TileVector::iterator it = pending_tree_tiles.begin();
465        it != pending_tree_tiles.end();
466        ++it) {
467     ManagedTileState::TileVersion& tile_version =
468         (*it)->GetTileVersionForTesting(HIGH_QUALITY_RASTER_MODE);
469     tile_version.SetSolidColorForTesting(
470         SkColorSetARGB(0, 0, 0, 0));
471     tile_version.SetHasTextForTesting(true);
472     (*it)->set_can_use_lcd_text(false);
473
474     EXPECT_TRUE((*it)->IsReadyToDraw());
475   }
476
477   tile_manager()->ManageTiles(global_state_);
478
479   EXPECT_EQ(0, TilesWithLCDCount(active_tree_tiles));
480   EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles));
481 }
482
483 TEST_P(TileManagerTest, RespectMemoryLimit) {
484   Initialize(5, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY);
485   TileVector large_tiles = CreateTiles(
486       5, TilePriorityForNowBin(), TilePriority());
487
488   size_t memory_required_bytes;
489   size_t memory_nice_to_have_bytes;
490   size_t memory_allocated_bytes;
491   size_t memory_used_bytes;
492
493   tile_manager()->ManageTiles(global_state_);
494   tile_manager()->GetMemoryStats(&memory_required_bytes,
495                                  &memory_nice_to_have_bytes,
496                                  &memory_allocated_bytes,
497                                  &memory_used_bytes);
498   // Allocated bytes should never be more than the memory limit.
499   EXPECT_LE(memory_allocated_bytes, global_state_.memory_limit_in_bytes);
500
501   // Finish raster of large tiles.
502   tile_manager()->UpdateVisibleTiles();
503
504   // Remove all large tiles. This will leave the memory currently
505   // used by these tiles as unused when ManageTiles() is called.
506   large_tiles.clear();
507
508   // Create a new set of tiles using a different size. These tiles
509   // can use the memory currently assigned to the lerge tiles but
510   // they can't use the same resources as the size doesn't match.
511   TileVector small_tiles = CreateTilesWithSize(
512       5, TilePriorityForNowBin(), TilePriority(), gfx::Size(128, 128));
513
514   tile_manager()->ManageTiles(global_state_);
515   tile_manager()->GetMemoryStats(&memory_required_bytes,
516                                  &memory_nice_to_have_bytes,
517                                  &memory_allocated_bytes,
518                                  &memory_used_bytes);
519   // Allocated bytes should never be more than the memory limit.
520   EXPECT_LE(memory_allocated_bytes, global_state_.memory_limit_in_bytes);
521 }
522
523 // If true, the max tile limit should be applied as bytes; if false,
524 // as num_resources_limit.
525 INSTANTIATE_TEST_CASE_P(TileManagerTests,
526                         TileManagerTest,
527                         ::testing::Values(true, false));
528
529 }  // namespace
530 }  // namespace cc