picture_layer_impl_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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/layers/picture_layer_impl.h"
6
7#include "cc/layers/picture_layer.h"
8#include "cc/test/fake_content_layer_client.h"
9#include "cc/test/fake_impl_proxy.h"
10#include "cc/test/fake_layer_tree_host_impl.h"
11#include "cc/test/fake_output_surface.h"
12#include "cc/trees/layer_tree_impl.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "third_party/skia/include/core/SkDevice.h"
15#include "ui/gfx/rect_conversions.h"
16
17namespace cc {
18namespace {
19
20class TestablePictureLayerImpl : public PictureLayerImpl {
21 public:
22  static scoped_ptr<TestablePictureLayerImpl> Create(
23      LayerTreeImpl* tree_impl,
24      int id,
25      scoped_refptr<PicturePileImpl> pile)
26  {
27    return make_scoped_ptr(new TestablePictureLayerImpl(tree_impl, id, pile));
28  }
29
30  PictureLayerTilingSet& tilings() { return *tilings_; }
31  Region& invalidation() { return invalidation_; }
32
33  virtual gfx::Size CalculateTileSize(
34      gfx::Size current_tile_size,
35      gfx::Size content_bounds) OVERRIDE {
36    if (current_tile_size.IsEmpty())
37      return gfx::Size(100, 100);
38    return current_tile_size;
39  }
40
41  using PictureLayerImpl::AddTiling;
42  using PictureLayerImpl::CleanUpTilingsOnActiveLayer;
43
44 private:
45  TestablePictureLayerImpl(
46      LayerTreeImpl* tree_impl,
47      int id,
48      scoped_refptr<PicturePileImpl> pile)
49      : PictureLayerImpl(tree_impl, id) {
50    pile_ = pile;
51    SetBounds(pile_->size());
52    CreateTilingSet();
53  }
54};
55
56class ImplSidePaintingSettings : public LayerTreeSettings {
57 public:
58  ImplSidePaintingSettings() {
59    impl_side_painting = true;
60  }
61};
62
63class TestablePicturePileImpl : public PicturePileImpl {
64 public:
65  static scoped_refptr<TestablePicturePileImpl> CreateFilledPile(
66      gfx::Size tile_size,
67      gfx::Size layer_bounds) {
68    scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl());
69    pile->tiling().SetTotalSize(layer_bounds);
70    pile->tiling().SetMaxTextureSize(tile_size);
71    pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_size);
72    for (int x = 0; x < pile->tiling().num_tiles_x(); ++x) {
73      for (int y = 0; y < pile->tiling().num_tiles_y(); ++y)
74        pile->AddRecordingAt(x, y);
75    }
76    pile->UpdateRecordedRegion();
77    return pile;
78  }
79
80  static scoped_refptr<TestablePicturePileImpl> CreateEmptyPile(
81      gfx::Size tile_size,
82      gfx::Size layer_bounds) {
83    scoped_refptr<TestablePicturePileImpl> pile(new TestablePicturePileImpl());
84    pile->tiling().SetTotalSize(layer_bounds);
85    pile->tiling().SetMaxTextureSize(tile_size);
86    pile->SetTileGridSize(ImplSidePaintingSettings().default_tile_size);
87    pile->UpdateRecordedRegion();
88    return pile;
89  }
90
91  TilingData& tiling() { return tiling_; }
92
93  void AddRecordingAt(int x, int y) {
94    EXPECT_GE(x, 0);
95    EXPECT_GE(y, 0);
96    EXPECT_LT(x, tiling_.num_tiles_x());
97    EXPECT_LT(y, tiling_.num_tiles_y());
98
99    if (HasRecordingAt(x, y))
100      return;
101    gfx::Rect bounds(tiling().TileBounds(x, y));
102    scoped_refptr<Picture> picture(Picture::Create(bounds));
103    picture->Record(&client_, NULL, tile_grid_info_);
104    picture_list_map_[std::pair<int, int>(x, y)].push_back(picture);
105    EXPECT_TRUE(HasRecordingAt(x, y));
106
107    UpdateRecordedRegion();
108  }
109
110  void RemoveRecordingAt(int x, int y) {
111    EXPECT_GE(x, 0);
112    EXPECT_GE(y, 0);
113    EXPECT_LT(x, tiling_.num_tiles_x());
114    EXPECT_LT(y, tiling_.num_tiles_y());
115
116    if (!HasRecordingAt(x, y))
117      return;
118    picture_list_map_.erase(std::pair<int, int>(x, y));
119    EXPECT_FALSE(HasRecordingAt(x, y));
120
121    UpdateRecordedRegion();
122  }
123
124  void add_draw_rect(const gfx::Rect& rect) {
125    client_.add_draw_rect(rect);
126  }
127
128 protected:
129  TestablePicturePileImpl() : PicturePileImpl(false) {}
130
131  virtual ~TestablePicturePileImpl() {}
132
133  FakeContentLayerClient client_;
134};
135
136class MockCanvas : public SkCanvas {
137 public:
138  explicit MockCanvas(SkDevice* device) : SkCanvas(device) {}
139
140  virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
141    // Capture calls before SkCanvas quickReject() kicks in.
142    rects_.push_back(rect);
143  }
144
145  std::vector<SkRect> rects_;
146};
147
148class PictureLayerImplTest : public testing::Test {
149 public:
150  PictureLayerImplTest()
151      : host_impl_(ImplSidePaintingSettings(), &proxy_),
152        id_(7) {
153    host_impl_.InitializeRenderer(CreateFakeOutputSurface());
154  }
155
156  virtual ~PictureLayerImplTest() {
157  }
158
159  void SetupTrees(
160      scoped_refptr<PicturePileImpl> pending_pile,
161      scoped_refptr<PicturePileImpl> active_pile) {
162    SetupPendingTree(active_pile);
163    host_impl_.ActivatePendingTree();
164
165    active_layer_ = static_cast<TestablePictureLayerImpl*>(
166        host_impl_.active_tree()->LayerById(id_));
167
168    SetupPendingTree(pending_pile);
169    pending_layer_ = static_cast<TestablePictureLayerImpl*>(
170        host_impl_.pending_tree()->LayerById(id_));
171  }
172
173  void AddDefaultTilingsWithInvalidation(const Region& invalidation) {
174    active_layer_->AddTiling(2.3f);
175    active_layer_->AddTiling(1.0f);
176    active_layer_->AddTiling(0.5f);
177    pending_layer_->invalidation() = invalidation;
178    pending_layer_->SyncFromActiveLayer();
179  }
180
181  void SetupPendingTree(
182      scoped_refptr<PicturePileImpl> pile) {
183    host_impl_.CreatePendingTree();
184    LayerTreeImpl* pending_tree = host_impl_.pending_tree();
185    // Clear recycled tree.
186    pending_tree->DetachLayerTree();
187
188    scoped_ptr<TestablePictureLayerImpl> pending_layer =
189        TestablePictureLayerImpl::Create(pending_tree, id_, pile);
190    pending_layer->SetDrawsContent(true);
191    pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
192  }
193
194  static void VerifyAllTilesExistAndHavePile(
195      const PictureLayerTiling* tiling,
196      PicturePileImpl* pile) {
197    for (PictureLayerTiling::Iterator
198             iter(tiling, tiling->contents_scale(), tiling->ContentRect());
199         iter;
200         ++iter) {
201      EXPECT_TRUE(*iter);
202      EXPECT_EQ(pile, iter->picture_pile());
203    }
204  }
205
206  void SetContentsScaleOnBothLayers(float scale, bool animating_transform) {
207    float result_scale_x, result_scale_y;
208    gfx::Size result_bounds;
209    pending_layer_->CalculateContentsScale(
210        scale, animating_transform,
211        &result_scale_x, &result_scale_y, &result_bounds);
212    active_layer_->CalculateContentsScale(
213        scale, animating_transform,
214        &result_scale_x, &result_scale_y, &result_bounds);
215  }
216
217 protected:
218  void TestTileGridAlignmentCommon() {
219    // Layer to span 4 raster tiles in x and in y
220    ImplSidePaintingSettings settings;
221    gfx::Size layer_size(
222        settings.default_tile_size.width() * 7 / 2,
223        settings.default_tile_size.height() * 7 / 2);
224
225    scoped_refptr<TestablePicturePileImpl> pending_pile =
226        TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size);
227    scoped_refptr<TestablePicturePileImpl> active_pile =
228        TestablePicturePileImpl::CreateFilledPile(layer_size, layer_size);
229
230    SetupTrees(pending_pile, active_pile);
231
232    host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f);
233    float result_scale_x, result_scale_y;
234    gfx::Size result_bounds;
235    active_layer_->CalculateContentsScale(
236        1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
237
238    // Add 1x1 rects at the centers of each tile, then re-record pile contents
239    std::vector<Tile*> tiles =
240        active_layer_->tilings().tiling_at(0)->AllTilesForTesting();
241    EXPECT_EQ(16, tiles.size());
242    std::vector<SkRect> rects;
243    std::vector<Tile*>::const_iterator tile_iter;
244    for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
245      gfx::Point tile_center = (*tile_iter)->content_rect().CenterPoint();
246      gfx::Rect rect(tile_center.x(), tile_center.y(), 1, 1);
247      active_pile->add_draw_rect(rect);
248      rects.push_back(SkRect::MakeXYWH(rect.x(), rect.y(), 1, 1));
249    }
250    // Force re-record with newly injected content
251    active_pile->RemoveRecordingAt(0, 0);
252    active_pile->AddRecordingAt(0, 0);
253
254    SkBitmap store;
255    store.setConfig(SkBitmap::kNo_Config, 1000, 1000);
256    SkDevice device(store);
257    int64 pixels_rasterized;
258
259    std::vector<SkRect>::const_iterator rect_iter = rects.begin();
260    for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
261      MockCanvas mock_canvas(&device);
262      active_pile->Raster(&mock_canvas, (*tile_iter)->content_rect(),
263          1.0f, &pixels_rasterized);
264
265      // This test verifies that when drawing the contents of a specific tile
266      // at content scale 1.0, the playback canvas never receives content from
267      // neighboring tiles which indicates that the tile grid embedded in
268      // SkPicture is perfectly aligned with the compositor's tiles.
269      // Note: There are two rects: the initial clear and the explicitly
270      // recorded rect. We only care about the second one.
271      EXPECT_EQ(2, mock_canvas.rects_.size());
272      EXPECT_EQ(*rect_iter, mock_canvas.rects_[1]);
273      rect_iter++;
274    }
275  }
276
277  FakeImplProxy proxy_;
278  FakeLayerTreeHostImpl host_impl_;
279  int id_;
280  TestablePictureLayerImpl* pending_layer_;
281  TestablePictureLayerImpl* active_layer_;
282
283  DISALLOW_COPY_AND_ASSIGN(PictureLayerImplTest);
284};
285
286TEST_F(PictureLayerImplTest, TileGridAlignment) {
287  host_impl_.SetDeviceScaleFactor(1.f);
288  TestTileGridAlignmentCommon();
289}
290
291TEST_F(PictureLayerImplTest, TileGridAlignmentHiDPI) {
292  host_impl_.SetDeviceScaleFactor(2.f);
293  TestTileGridAlignmentCommon();
294}
295
296TEST_F(PictureLayerImplTest, CloneNoInvalidation) {
297  gfx::Size tile_size(100, 100);
298  gfx::Size layer_bounds(400, 400);
299
300  scoped_refptr<TestablePicturePileImpl> pending_pile =
301      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
302  scoped_refptr<TestablePicturePileImpl> active_pile =
303      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
304
305  SetupTrees(pending_pile, active_pile);
306
307  Region invalidation;
308  AddDefaultTilingsWithInvalidation(invalidation);
309
310  EXPECT_EQ(pending_layer_->tilings().num_tilings(),
311            active_layer_->tilings().num_tilings());
312
313  const PictureLayerTilingSet& tilings = pending_layer_->tilings();
314  EXPECT_GT(tilings.num_tilings(), 0u);
315  for (size_t i = 0; i < tilings.num_tilings(); ++i)
316    VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), active_pile.get());
317}
318
319TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
320  gfx::Size tile_size(100, 100);
321  gfx::Size layer_bounds(400, 400);
322  gfx::Rect layer_invalidation(150, 200, 30, 180);
323
324  scoped_refptr<TestablePicturePileImpl> pending_pile =
325      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
326  scoped_refptr<TestablePicturePileImpl> active_pile =
327      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
328
329  SetupTrees(pending_pile, active_pile);
330
331  Region invalidation(layer_invalidation);
332  AddDefaultTilingsWithInvalidation(invalidation);
333
334  const PictureLayerTilingSet& tilings = pending_layer_->tilings();
335  EXPECT_GT(tilings.num_tilings(), 0u);
336  for (size_t i = 0; i < tilings.num_tilings(); ++i) {
337    const PictureLayerTiling* tiling = tilings.tiling_at(i);
338    gfx::Rect content_invalidation = gfx::ToEnclosingRect(gfx::ScaleRect(
339        layer_invalidation,
340        tiling->contents_scale()));
341    for (PictureLayerTiling::Iterator
342             iter(tiling,
343                  tiling->contents_scale(),
344                  tiling->ContentRect());
345         iter;
346         ++iter) {
347      EXPECT_TRUE(*iter);
348      EXPECT_FALSE(iter.geometry_rect().IsEmpty());
349      if (iter.geometry_rect().Intersects(content_invalidation))
350        EXPECT_EQ(pending_pile, iter->picture_pile());
351      else
352        EXPECT_EQ(active_pile, iter->picture_pile());
353    }
354  }
355}
356
357TEST_F(PictureLayerImplTest, CloneFullInvalidation) {
358  gfx::Size tile_size(90, 80);
359  gfx::Size layer_bounds(300, 500);
360
361  scoped_refptr<TestablePicturePileImpl> pending_pile =
362      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
363  scoped_refptr<TestablePicturePileImpl> active_pile =
364      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
365
366  SetupTrees(pending_pile, active_pile);
367
368  Region invalidation((gfx::Rect(layer_bounds)));
369  AddDefaultTilingsWithInvalidation(invalidation);
370
371  EXPECT_EQ(pending_layer_->tilings().num_tilings(),
372            active_layer_->tilings().num_tilings());
373
374  const PictureLayerTilingSet& tilings = pending_layer_->tilings();
375  EXPECT_GT(tilings.num_tilings(), 0u);
376  for (size_t i = 0; i < tilings.num_tilings(); ++i)
377    VerifyAllTilesExistAndHavePile(tilings.tiling_at(i), pending_pile.get());
378}
379
380TEST_F(PictureLayerImplTest, NoInvalidationBoundsChange) {
381  gfx::Size tile_size(90, 80);
382  gfx::Size active_layer_bounds(300, 500);
383  gfx::Size pending_layer_bounds(400, 800);
384
385  scoped_refptr<TestablePicturePileImpl> pending_pile =
386      TestablePicturePileImpl::CreateFilledPile(tile_size,
387                                                pending_layer_bounds);
388  scoped_refptr<TestablePicturePileImpl> active_pile =
389      TestablePicturePileImpl::CreateFilledPile(tile_size, active_layer_bounds);
390
391  SetupTrees(pending_pile, active_pile);
392
393  Region invalidation;
394  AddDefaultTilingsWithInvalidation(invalidation);
395
396  const PictureLayerTilingSet& tilings = pending_layer_->tilings();
397  EXPECT_GT(tilings.num_tilings(), 0u);
398  for (size_t i = 0; i < tilings.num_tilings(); ++i) {
399    const PictureLayerTiling* tiling = tilings.tiling_at(i);
400    gfx::Rect active_content_bounds = gfx::ToEnclosingRect(gfx::ScaleRect(
401        gfx::Rect(active_layer_bounds),
402        tiling->contents_scale()));
403    for (PictureLayerTiling::Iterator
404             iter(tiling,
405                  tiling->contents_scale(),
406                  tiling->ContentRect());
407         iter;
408         ++iter) {
409      EXPECT_TRUE(*iter);
410      EXPECT_FALSE(iter.geometry_rect().IsEmpty());
411      if (iter.geometry_rect().right() >= active_content_bounds.width() ||
412          iter.geometry_rect().bottom() >= active_content_bounds.height()) {
413        EXPECT_EQ(pending_pile, iter->picture_pile());
414      } else {
415        EXPECT_EQ(active_pile, iter->picture_pile());
416      }
417    }
418  }
419}
420
421TEST_F(PictureLayerImplTest, AddTilesFromNewRecording) {
422  gfx::Size tile_size(400, 400);
423  gfx::Size layer_bounds(1300, 1900);
424
425  scoped_refptr<TestablePicturePileImpl> pending_pile =
426      TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
427  scoped_refptr<TestablePicturePileImpl> active_pile =
428      TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
429
430  // Fill in some of active pile, but more of pending pile.
431  int hole_count = 0;
432  for (int x = 0; x < active_pile->tiling().num_tiles_x(); ++x) {
433    for (int y = 0; y < active_pile->tiling().num_tiles_y(); ++y) {
434      if ((x + y) % 2) {
435        pending_pile->AddRecordingAt(x, y);
436        active_pile->AddRecordingAt(x, y);
437      } else {
438        hole_count++;
439        if (hole_count % 2)
440          pending_pile->AddRecordingAt(x, y);
441      }
442    }
443  }
444
445  SetupTrees(pending_pile, active_pile);
446  Region invalidation;
447  AddDefaultTilingsWithInvalidation(invalidation);
448
449  const PictureLayerTilingSet& tilings = pending_layer_->tilings();
450  EXPECT_GT(tilings.num_tilings(), 0u);
451  for (size_t i = 0; i < tilings.num_tilings(); ++i) {
452    const PictureLayerTiling* tiling = tilings.tiling_at(i);
453
454    for (PictureLayerTiling::Iterator
455             iter(tiling,
456                  tiling->contents_scale(),
457                  tiling->ContentRect());
458         iter;
459         ++iter) {
460      EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty());
461      // Ensure there is a recording for this tile.
462      gfx::Rect layer_rect = gfx::ToEnclosingRect(gfx::ScaleRect(
463          iter.full_tile_geometry_rect(), 1.f / tiling->contents_scale()));
464      layer_rect.Intersect(gfx::Rect(layer_bounds));
465
466      bool in_pending = pending_pile->recorded_region().Contains(layer_rect);
467      bool in_active = active_pile->recorded_region().Contains(layer_rect);
468
469      if (in_pending && !in_active)
470        EXPECT_EQ(pending_pile, iter->picture_pile());
471      else if (in_active)
472        EXPECT_EQ(active_pile, iter->picture_pile());
473      else
474        EXPECT_FALSE(*iter);
475    }
476  }
477}
478
479TEST_F(PictureLayerImplTest, ManageTilingsWithNoRecording) {
480  gfx::Size tile_size(400, 400);
481  gfx::Size layer_bounds(1300, 1900);
482
483  scoped_refptr<TestablePicturePileImpl> pending_pile =
484      TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
485  scoped_refptr<TestablePicturePileImpl> active_pile =
486      TestablePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
487
488  float result_scale_x, result_scale_y;
489  gfx::Size result_bounds;
490
491  SetupTrees(pending_pile, active_pile);
492
493  // These are included in the scale given to the layer.
494  host_impl_.SetDeviceScaleFactor(1.f);
495  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f);
496
497  pending_layer_->CalculateContentsScale(
498      1.f, false, &result_scale_x, &result_scale_y, &result_bounds);
499
500  EXPECT_EQ(0u, pending_layer_->tilings().num_tilings());
501}
502
503TEST_F(PictureLayerImplTest, ManageTilingsCreatesTilings) {
504  gfx::Size tile_size(400, 400);
505  gfx::Size layer_bounds(1300, 1900);
506
507  scoped_refptr<TestablePicturePileImpl> pending_pile =
508      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
509  scoped_refptr<TestablePicturePileImpl> active_pile =
510      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
511
512  float result_scale_x, result_scale_y;
513  gfx::Size result_bounds;
514
515  SetupTrees(pending_pile, active_pile);
516  EXPECT_EQ(0u, pending_layer_->tilings().num_tilings());
517
518  float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
519  EXPECT_LT(low_res_factor, 1.f);
520
521  // These are included in the scale given to the layer.
522  host_impl_.SetDeviceScaleFactor(1.7f);
523  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f);
524
525  pending_layer_->CalculateContentsScale(
526      1.3f, false, &result_scale_x, &result_scale_y, &result_bounds);
527  ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
528  EXPECT_FLOAT_EQ(
529      1.3f,
530      pending_layer_->tilings().tiling_at(0)->contents_scale());
531  EXPECT_FLOAT_EQ(
532      1.3f * low_res_factor,
533      pending_layer_->tilings().tiling_at(1)->contents_scale());
534
535  // If we change the layer's CSS scale factor, then we should not get new
536  // tilings.
537  pending_layer_->CalculateContentsScale(
538      1.8f, false, &result_scale_x, &result_scale_y, &result_bounds);
539  ASSERT_EQ(2u, pending_layer_->tilings().num_tilings());
540  EXPECT_FLOAT_EQ(
541      1.3f,
542      pending_layer_->tilings().tiling_at(0)->contents_scale());
543  EXPECT_FLOAT_EQ(
544      1.3f * low_res_factor,
545      pending_layer_->tilings().tiling_at(1)->contents_scale());
546
547  // If we change the page scale factor, then we should get new tilings.
548  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(2.2f, 2.2f, 2.2f);
549
550  pending_layer_->CalculateContentsScale(
551      1.8f, false, &result_scale_x, &result_scale_y, &result_bounds);
552  ASSERT_EQ(4u, pending_layer_->tilings().num_tilings());
553  EXPECT_FLOAT_EQ(
554      1.8f,
555      pending_layer_->tilings().tiling_at(0)->contents_scale());
556  EXPECT_FLOAT_EQ(
557      1.8f * low_res_factor,
558      pending_layer_->tilings().tiling_at(2)->contents_scale());
559
560  // If we change the device scale factor, then we should get new tilings.
561  host_impl_.SetDeviceScaleFactor(1.4f);
562
563  pending_layer_->CalculateContentsScale(
564      1.9f, false, &result_scale_x, &result_scale_y, &result_bounds);
565  ASSERT_EQ(6u, pending_layer_->tilings().num_tilings());
566  EXPECT_FLOAT_EQ(
567      1.9f,
568      pending_layer_->tilings().tiling_at(0)->contents_scale());
569  EXPECT_FLOAT_EQ(
570      1.9f * low_res_factor,
571      pending_layer_->tilings().tiling_at(3)->contents_scale());
572
573  // If we change the device scale factor, but end up at the same total scale
574  // factor somehow, then we don't get new tilings.
575  host_impl_.SetDeviceScaleFactor(2.2f);
576  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.4f, 1.4f, 1.4f);
577
578  pending_layer_->CalculateContentsScale(
579      1.9f, false, &result_scale_x, &result_scale_y, &result_bounds);
580  ASSERT_EQ(6u, pending_layer_->tilings().num_tilings());
581  EXPECT_FLOAT_EQ(
582      1.9f,
583      pending_layer_->tilings().tiling_at(0)->contents_scale());
584  EXPECT_FLOAT_EQ(
585      1.9f * low_res_factor,
586      pending_layer_->tilings().tiling_at(3)->contents_scale());
587}
588
589TEST_F(PictureLayerImplTest, CleanUpTilings) {
590  gfx::Size tile_size(400, 400);
591  gfx::Size layer_bounds(1300, 1900);
592
593  scoped_refptr<TestablePicturePileImpl> pending_pile =
594      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
595  scoped_refptr<TestablePicturePileImpl> active_pile =
596      TestablePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
597
598  float result_scale_x, result_scale_y;
599  gfx::Size result_bounds;
600  std::vector<PictureLayerTiling*> used_tilings;
601
602  SetupTrees(pending_pile, active_pile);
603  EXPECT_EQ(0u, pending_layer_->tilings().num_tilings());
604
605  float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
606  EXPECT_LT(low_res_factor, 1.f);
607
608  // These are included in the scale given to the layer.
609  host_impl_.SetDeviceScaleFactor(1.7f);
610  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f);
611  host_impl_.active_tree()->SetPageScaleFactorAndLimits(3.2f, 3.2f, 3.2f);
612
613  SetContentsScaleOnBothLayers(1.f, false);
614  ASSERT_EQ(2u, active_layer_->tilings().num_tilings());
615
616  // We only have ideal tilings, so they aren't removed.
617  used_tilings.clear();
618  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
619  ASSERT_EQ(2u, active_layer_->tilings().num_tilings());
620
621  // Changing the ideal but not creating new tilings.
622  SetContentsScaleOnBothLayers(1.5f, false);
623  ASSERT_EQ(2u, active_layer_->tilings().num_tilings());
624
625  // The tilings are still our target scale, so they aren't removed.
626  used_tilings.clear();
627  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
628  ASSERT_EQ(2u, active_layer_->tilings().num_tilings());
629
630  // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2.
631  host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f);
632  host_impl_.active_tree()->SetPageScaleFactorAndLimits(1.2f, 1.2f, 1.2f);
633  SetContentsScaleOnBothLayers(1.2f, false);
634  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
635  EXPECT_FLOAT_EQ(
636      1.f,
637      active_layer_->tilings().tiling_at(1)->contents_scale());
638  EXPECT_FLOAT_EQ(
639      1.f * low_res_factor,
640      active_layer_->tilings().tiling_at(3)->contents_scale());
641
642  // Mark the non-ideal tilings as used. They won't be removed.
643  used_tilings.clear();
644  used_tilings.push_back(active_layer_->tilings().tiling_at(1));
645  used_tilings.push_back(active_layer_->tilings().tiling_at(3));
646  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
647  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
648
649  // Now move the ideal scale to 0.5. Our target stays 1.2.
650  SetContentsScaleOnBothLayers(0.5f, false);
651
652  // All the tilings are between are target and the ideal, so they are not
653  // removed.
654  used_tilings.clear();
655  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
656  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
657
658  // Now move the ideal scale to 1.0. Our target stays 1.2.
659  SetContentsScaleOnBothLayers(1.f, false);
660
661  // All the tilings are between are target and the ideal, so they are not
662  // removed.
663  used_tilings.clear();
664  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
665  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
666
667  // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2.
668  active_layer_->CalculateContentsScale(
669      1.1f, false, &result_scale_x, &result_scale_y, &result_bounds);
670
671  // Because the pending layer's ideal scale is still 1.0, our tilings fall
672  // in the range [1.0,1.2] and are kept.
673  used_tilings.clear();
674  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
675  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
676
677  // Move the ideal scale on the pending layer to 1.1 as well. Our target stays
678  // 1.2 still.
679  pending_layer_->CalculateContentsScale(
680      1.1f, false, &result_scale_x, &result_scale_y, &result_bounds);
681
682  // Our 1.0 tiling now falls outside the range between our ideal scale and our
683  // target raster scale. But it is in our used tilings set, so nothing is
684  // deleted.
685  used_tilings.clear();
686  used_tilings.push_back(active_layer_->tilings().tiling_at(1));
687  used_tilings.push_back(active_layer_->tilings().tiling_at(3));
688  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
689  ASSERT_EQ(4u, active_layer_->tilings().num_tilings());
690
691  // If we remove it from our used tilings set, it is outside the range to keep
692  // so it is deleted. Try one tiling at a time.
693  used_tilings.clear();
694  used_tilings.push_back(active_layer_->tilings().tiling_at(1));
695  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
696  ASSERT_EQ(3u, active_layer_->tilings().num_tilings());
697  used_tilings.clear();
698  active_layer_->CleanUpTilingsOnActiveLayer(used_tilings);
699  ASSERT_EQ(2u, active_layer_->tilings().num_tilings());
700}
701
702}  // namespace
703}  // namespace cc
704