// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/layers/picture_layer_impl.h"

#include <stddef.h>

#include <algorithm>
#include <limits>
#include <set>
#include <utility>

#include "base/location.h"
#include "base/macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
#include "cc/base/math_util.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/picture_layer.h"
#include "cc/output/buffer_to_texture_target_map.h"
#include "cc/quads/draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/test/begin_frame_args_test.h"
#include "cc/test/fake_compositor_frame_sink.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_picture_layer_impl.h"
#include "cc/test/fake_raster_source.h"
#include "cc/test/fake_recording_source.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/test_layer_tree_host_base.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "cc/tiles/tiling_set_raster_queue_all.h"
#include "cc/tiles/tiling_set_raster_queue_required.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"

namespace cc {
namespace {

#define EXPECT_BOTH_EQ(expression, x)          \
  do {                                         \
    EXPECT_EQ(x, pending_layer()->expression); \
    EXPECT_EQ(x, active_layer()->expression);  \
  } while (false)

#define EXPECT_BOTH_NE(expression, x)          \
  do {                                         \
    EXPECT_NE(x, pending_layer()->expression); \
    EXPECT_NE(x, active_layer()->expression);  \
  } while (false)

#define EXPECT_BOTH_TRUE(expression)          \
  do {                                        \
    EXPECT_TRUE(pending_layer()->expression); \
    EXPECT_TRUE(active_layer()->expression);  \
  } while (false)

#define EXPECT_BOTH_FALSE(expression)          \
  do {                                         \
    EXPECT_FALSE(pending_layer()->expression); \
    EXPECT_FALSE(active_layer()->expression);  \
  } while (false)

class PictureLayerImplTest : public TestLayerTreeHostBase {
 public:
  void SetUp() override {
    TestLayerTreeHostBase::SetUp();
    host_impl()->SetViewportSize(gfx::Size(10000, 10000));
  }

  LayerTreeSettings CreateSettings() override {
    LayerTreeSettings settings;
    settings.layer_transforms_should_scale_layer_contents = true;
    settings.create_low_res_tiling = true;
    settings.verify_clip_tree_calculations = true;
    settings.renderer_settings.buffer_to_texture_target_map =
        DefaultBufferToTextureTargetMapForTesting();
    return settings;
  }

  std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() override {
    return FakeCompositorFrameSink::Create3dForGpuRasterization();
  }

  void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds,
                                          const gfx::Size& tile_size,
                                          const Region& invalidation) {
    scoped_refptr<FakeRasterSource> pending_raster_source =
        FakeRasterSource::CreateFilled(layer_bounds);
    scoped_refptr<FakeRasterSource> active_raster_source =
        FakeRasterSource::CreateFilled(layer_bounds);

    SetupTreesWithFixedTileSize(std::move(pending_raster_source),
                                std::move(active_raster_source), tile_size,
                                invalidation);
  }

  void SetupTreesWithFixedTileSize(
      scoped_refptr<RasterSource> pending_raster_source,
      scoped_refptr<RasterSource> active_raster_source,
      const gfx::Size& tile_size,
      const Region& pending_invalidation) {
    SetupPendingTree(std::move(active_raster_source), tile_size, Region());
    ActivateTree();
    SetupPendingTree(std::move(pending_raster_source), tile_size,
                     pending_invalidation);
  }

  void SetupDefaultTreesWithInvalidation(const gfx::Size& layer_bounds,
                                         const Region& invalidation) {
    scoped_refptr<FakeRasterSource> pending_raster_source =
        FakeRasterSource::CreateFilled(layer_bounds);
    scoped_refptr<FakeRasterSource> active_raster_source =
        FakeRasterSource::CreateFilled(layer_bounds);

    SetupTreesWithInvalidation(std::move(pending_raster_source),
                               std::move(active_raster_source), invalidation);
  }

  void SetupTreesWithInvalidation(
      scoped_refptr<RasterSource> pending_raster_source,
      scoped_refptr<RasterSource> active_raster_source,
      const Region& pending_invalidation) {
    SetupPendingTree(std::move(active_raster_source), gfx::Size(), Region());
    ActivateTree();
    SetupPendingTree(std::move(pending_raster_source), gfx::Size(),
                     pending_invalidation);
  }

  void SetupPendingTreeWithInvalidation(
      scoped_refptr<RasterSource> raster_source,
      const Region& invalidation) {
    SetupPendingTree(std::move(raster_source), gfx::Size(), invalidation);
  }

  void SetupPendingTreeWithFixedTileSize(
      scoped_refptr<RasterSource> raster_source,
      const gfx::Size& tile_size,
      const Region& invalidation) {
    SetupPendingTree(std::move(raster_source), tile_size, invalidation);
  }

  void SetupDrawProperties(FakePictureLayerImpl* layer,
                           float ideal_contents_scale,
                           float device_scale_factor,
                           float page_scale_factor,
                           float maximum_animation_contents_scale,
                           float starting_animation_contents_scale,
                           bool animating_transform_to_screen) {
    layer->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor);
    host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);

    gfx::Transform scale_transform;
    scale_transform.Scale(ideal_contents_scale, ideal_contents_scale);
    layer->draw_properties().screen_space_transform = scale_transform;
    layer->set_is_drawn_render_surface_layer_list_member(true);
    DCHECK_EQ(layer->GetIdealContentsScale(), ideal_contents_scale);
    layer->layer_tree_impl()->property_trees()->SetAnimationScalesForTesting(
        layer->transform_tree_index(), maximum_animation_contents_scale,
        starting_animation_contents_scale);
    layer->draw_properties().screen_space_transform_is_animating =
        animating_transform_to_screen;
  }

  void SetupDrawPropertiesAndUpdateTiles(
      FakePictureLayerImpl* layer,
      float ideal_contents_scale,
      float device_scale_factor,
      float page_scale_factor,
      float maximum_animation_contents_scale,
      float starting_animation_contents_scale,
      bool animating_transform_to_screen) {
    SetupDrawProperties(layer, ideal_contents_scale, device_scale_factor,
                        page_scale_factor, maximum_animation_contents_scale,
                        starting_animation_contents_scale,
                        animating_transform_to_screen);
    layer->UpdateTiles();
  }

  static void VerifyAllPrioritizedTilesExistAndHaveRasterSource(
      const PictureLayerTiling* tiling,
      RasterSource* raster_source) {
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();
    for (PictureLayerTiling::CoverageIterator iter(
             tiling, tiling->contents_scale(),
             gfx::Rect(tiling->tiling_size()));
         iter; ++iter) {
      EXPECT_TRUE(*iter);
      EXPECT_EQ(raster_source, prioritized_tiles[*iter].raster_source());
    }
  }

  void SetContentsScaleOnBothLayers(float contents_scale,
                                    float device_scale_factor,
                                    float page_scale_factor,
                                    float maximum_animation_contents_scale,
                                    float starting_animation_contents_scale,
                                    bool animating_transform) {
    SetupDrawPropertiesAndUpdateTiles(
        pending_layer(), contents_scale, device_scale_factor, page_scale_factor,
        maximum_animation_contents_scale, starting_animation_contents_scale,
        animating_transform);

    SetupDrawPropertiesAndUpdateTiles(
        active_layer(), contents_scale, device_scale_factor, page_scale_factor,
        maximum_animation_contents_scale, starting_animation_contents_scale,
        animating_transform);
  }

  void ResetTilingsAndRasterScales() {
    if (pending_layer()) {
      pending_layer()->ReleaseTileResources();
      EXPECT_FALSE(pending_layer()->tilings());
      pending_layer()->RecreateTileResources();
      EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings());
    }

    if (active_layer()) {
      active_layer()->ReleaseTileResources();
      EXPECT_FALSE(active_layer()->tilings());
      active_layer()->RecreateTileResources();
      EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
    }
  }

  size_t NumberOfTilesRequired(PictureLayerTiling* tiling) {
    size_t num_required = 0;
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    for (size_t i = 0; i < tiles.size(); ++i) {
      if (tiles[i]->required_for_activation())
        num_required++;
    }
    return num_required;
  }

  void AssertAllTilesRequired(PictureLayerTiling* tiling) {
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    for (size_t i = 0; i < tiles.size(); ++i)
      EXPECT_TRUE(tiles[i]->required_for_activation()) << "i: " << i;
    EXPECT_GT(tiles.size(), 0u);
  }

  void AssertNoTilesRequired(PictureLayerTiling* tiling) {
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    for (size_t i = 0; i < tiles.size(); ++i)
      EXPECT_FALSE(tiles[i]->required_for_activation()) << "i: " << i;
    EXPECT_GT(tiles.size(), 0u);
  }

  void SetInitialDeviceScaleFactor(float device_scale_factor) {
    // Device scale factor is a per-tree property. However, tests can't directly
    // set the pending tree's device scale factor before the pending tree is
    // created, and setting it after SetupPendingTree is too late, since
    // draw properties will already have been updated on the tree. To handle
    // this, we initially set only the active tree's device scale factor, and we
    // copy this over to the pending tree inside SetupPendingTree.
    host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor);
  }

  void TestQuadsForSolidColor(bool test_for_solid);
};

class NoLowResPictureLayerImplTest : public PictureLayerImplTest {
 public:
  LayerTreeSettings CreateSettings() override {
    LayerTreeSettings settings = PictureLayerImplTest::CreateSettings();
    settings.create_low_res_tiling = false;
    return settings;
  }
};

TEST_F(PictureLayerImplTest, CloneNoInvalidation) {
  gfx::Size layer_bounds(400, 400);
  SetupDefaultTrees(layer_bounds);

  EXPECT_EQ(pending_layer()->tilings()->num_tilings(),
            active_layer()->tilings()->num_tilings());

  const PictureLayerTilingSet* tilings = pending_layer()->tilings();
  EXPECT_GT(tilings->num_tilings(), 0u);
  for (size_t i = 0; i < tilings->num_tilings(); ++i)
    EXPECT_TRUE(tilings->tiling_at(i)->AllTilesForTesting().empty());
}

TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  gfx::Size layer_bounds(400, 400);
  SetupDefaultTrees(layer_bounds);

  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  // Update tiles with viewport for tile priority as (0, 0, 100, 100) and the
  // identify transform for tile priority.
  gfx::Rect viewport_rect_for_tile_priority = gfx::Rect(0, 0, 100, 100);
  gfx::Transform transform, transform_for_tile_priority;

  host_impl()->SetExternalTilePriorityConstraints(
      viewport_rect_for_tile_priority, transform_for_tile_priority);
  bool update_lcd_text = false;
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);

  gfx::Rect viewport_rect_for_tile_priority_in_view_space =
      viewport_rect_for_tile_priority;

  // Verify the viewport rect for tile priority is used in picture layer tiling.
  EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
            active_layer()->viewport_rect_for_tile_priority_in_content_space());
  PictureLayerTilingSet* tilings = active_layer()->tilings();
  for (size_t i = 0; i < tilings->num_tilings(); i++) {
    PictureLayerTiling* tiling = tilings->tiling_at(i);
    EXPECT_EQ(
        tiling->GetCurrentVisibleRectForTesting(),
        gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space,
                                  tiling->contents_scale()));
  }

  // Update tiles with viewport for tile priority as (200, 200, 100, 100) in
  // screen space and the transform for tile priority is translated and
  // rotated. The actual viewport for tile priority used by PictureLayerImpl
  // should be (200, 200, 100, 100) applied with the said transform.
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  viewport_rect_for_tile_priority = gfx::Rect(200, 200, 100, 100);
  transform_for_tile_priority.Translate(100, 100);
  transform_for_tile_priority.Rotate(45);
  host_impl()->SetExternalTilePriorityConstraints(
      viewport_rect_for_tile_priority, transform_for_tile_priority);
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);

  gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization);
  bool success = transform_for_tile_priority.GetInverse(&screen_to_view);
  EXPECT_TRUE(success);

  // Note that we don't clip this to the layer bounds, since it is expected that
  // the rect will sometimes be outside of the layer bounds. If we clip to
  // bounds, then tile priorities will end up being incorrect in cases of fully
  // offscreen layer.
  viewport_rect_for_tile_priority_in_view_space =
      MathUtil::ProjectEnclosingClippedRect(screen_to_view,
                                            viewport_rect_for_tile_priority);

  EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
            active_layer()->viewport_rect_for_tile_priority_in_content_space());
  tilings = active_layer()->tilings();
  for (size_t i = 0; i < tilings->num_tilings(); i++) {
    PictureLayerTiling* tiling = tilings->tiling_at(i);
    EXPECT_EQ(
        tiling->GetCurrentVisibleRectForTesting(),
        gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space,
                                  tiling->contents_scale()));
  }
}

TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  gfx::Size layer_bounds(400, 400);
  SetupDefaultTrees(layer_bounds);

  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  gfx::Rect viewport_rect_for_tile_priority(0, 0, 100, 100);
  gfx::Transform transform_for_tile_priority;

  host_impl()->SetExternalTilePriorityConstraints(
      viewport_rect_for_tile_priority, transform_for_tile_priority);
  bool update_lcd_text = false;
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);

  EXPECT_EQ(viewport_rect_for_tile_priority,
            active_layer()->viewport_rect_for_tile_priority_in_content_space());

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  gfx::Rect another_viewport_rect_for_tile_priority(11, 11, 50, 50);
  host_impl()->SetExternalTilePriorityConstraints(
      another_viewport_rect_for_tile_priority, transform_for_tile_priority);

  // Didn't call UpdateDrawProperties yet. The viewport rect for tile priority
  // should remain to be the previously cached value.
  EXPECT_EQ(viewport_rect_for_tile_priority,
            active_layer()->viewport_rect_for_tile_priority_in_content_space());
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);

  // Now the UpdateDrawProperties is called. The viewport rect for tile
  // priority should be the latest value.
  EXPECT_EQ(another_viewport_rect_for_tile_priority,
            active_layer()->viewport_rect_for_tile_priority_in_content_space());
}

TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
  gfx::Size layer_bounds(400, 400);
  gfx::Rect layer_invalidation(150, 200, 30, 180);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> lost_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTreeWithFixedTileSize(lost_raster_source, gfx::Size(50, 50),
                                    Region());
  ActivateTree();
  // Add a unique tiling on the active tree.
  PictureLayerTiling* tiling = active_layer()->AddTiling(3.f);
  tiling->set_resolution(HIGH_RESOLUTION);
  tiling->CreateAllTilesForTesting();

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Then setup a new pending tree and activate it.
  SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source,
                              gfx::Size(50, 50), layer_invalidation);

  EXPECT_EQ(1u, pending_layer()->num_tilings());
  EXPECT_EQ(3u, active_layer()->num_tilings());

  const PictureLayerTilingSet* tilings = pending_layer()->tilings();
  EXPECT_GT(tilings->num_tilings(), 0u);
  for (size_t i = 0; i < tilings->num_tilings(); ++i) {
    const PictureLayerTiling* tiling = tilings->tiling_at(i);
    gfx::Rect content_invalidation =
        gfx::ScaleToEnclosingRect(layer_invalidation, tiling->contents_scale());
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();
    for (PictureLayerTiling::CoverageIterator iter(
             tiling, tiling->contents_scale(),
             gfx::Rect(tiling->tiling_size()));
         iter; ++iter) {
      // We don't always have a tile, but when we do it's because it was
      // invalidated and it has the latest raster source.
      if (*iter) {
        EXPECT_FALSE(iter.geometry_rect().IsEmpty());
        EXPECT_EQ(pending_raster_source.get(),
                  prioritized_tiles[*iter].raster_source());
        EXPECT_TRUE(iter.geometry_rect().Intersects(content_invalidation));
      } else {
        // We don't create tiles in non-invalidated regions.
        EXPECT_FALSE(iter.geometry_rect().Intersects(content_invalidation));
      }
    }
  }

  tilings = active_layer()->tilings();
  EXPECT_GT(tilings->num_tilings(), 0u);
  for (size_t i = 0; i < tilings->num_tilings(); ++i) {
    const PictureLayerTiling* tiling = tilings->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();
    for (PictureLayerTiling::CoverageIterator iter(
             tiling, tiling->contents_scale(),
             gfx::Rect(tiling->tiling_size()));
         iter; ++iter) {
      EXPECT_TRUE(*iter);
      EXPECT_FALSE(iter.geometry_rect().IsEmpty());
      // Raster source will be updated upon activation.
      EXPECT_EQ(active_raster_source.get(),
                prioritized_tiles[*iter].raster_source());
    }
  }
}

TEST_F(PictureLayerImplTest, CloneFullInvalidation) {
  gfx::Size layer_bounds(300, 500);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupTreesWithInvalidation(pending_raster_source, active_raster_source,
                             gfx::Rect(layer_bounds));

  EXPECT_EQ(pending_layer()->tilings()->num_tilings(),
            active_layer()->tilings()->num_tilings());

  const PictureLayerTilingSet* tilings = pending_layer()->tilings();
  EXPECT_GT(tilings->num_tilings(), 0u);
  for (size_t i = 0; i < tilings->num_tilings(); ++i) {
    VerifyAllPrioritizedTilesExistAndHaveRasterSource(
        tilings->tiling_at(i), pending_raster_source.get());
  }
}

TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  active_layer()->ReleaseTileResources();
  EXPECT_FALSE(active_layer()->tilings());
  active_layer()->RecreateTileResources();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());

  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    6.f,  // ideal contents scale
                                    3.f,  // device scale
                                    2.f,  // page scale
                                    1.f,  // maximum animation scale
                                    0.f,  // starting animation scale
                                    false);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(6.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  // If we change the page scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    6.6f,  // ideal contents scale
                                    3.f,   // device scale
                                    2.2f,  // page scale
                                    1.f,   // maximum animation scale
                                    0.f,   // starting animation scale
                                    false);
  ASSERT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.6f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(6.6f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // If we change the device scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    7.26f,  // ideal contents scale
                                    3.3f,   // device scale
                                    2.2f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(6u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(7.26f * low_res_factor,
                  active_layer()->tilings()->tiling_at(3)->contents_scale());

  // If we change the device scale factor, but end up at the same total scale
  // factor somehow, then we don't get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    7.26f,  // ideal contents scale
                                    2.2f,   // device scale
                                    3.3f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(6u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(7.26f * low_res_factor,
                  active_layer()->tilings()->tiling_at(3)->contents_scale());
}

TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  pending_layer()->ReleaseTileResources();
  EXPECT_FALSE(pending_layer()->tilings());
  pending_layer()->RecreateTileResources();
  EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings());

  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    6.f,  // ideal contents scale
                                    3.f,  // device scale
                                    2.f,  // page scale
                                    1.f,  // maximum animation scale
                                    0.f,  // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the page scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    6.6f,  // ideal contents scale
                                    3.f,   // device scale
                                    2.2f,  // page scale
                                    1.f,   // maximum animation scale
                                    0.f,   // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.6f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    7.26f,  // ideal contents scale
                                    3.3f,   // device scale
                                    2.2f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, but end up at the same total scale
  // factor somehow, then we don't get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    7.26f,  // ideal contents scale
                                    2.2f,   // device scale
                                    3.3f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());
}

TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) {
  // This test makes sure that if a layer can have tilings, then a commit makes
  // it not able to have tilings (empty size), and then a future commit that
  // makes it valid again should be able to create tilings.
  gfx::Size layer_bounds(1300, 1900);

  scoped_refptr<FakeRasterSource> empty_raster_source =
      FakeRasterSource::CreateEmpty(layer_bounds);
  scoped_refptr<FakeRasterSource> valid_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(valid_raster_source);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());

  ActivateTree();
  SetupPendingTree(empty_raster_source);
  EXPECT_FALSE(pending_layer()->CanHaveTilings());
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  ASSERT_EQ(0u, pending_layer()->tilings()->num_tilings());

  ActivateTree();
  EXPECT_FALSE(active_layer()->CanHaveTilings());
  ASSERT_EQ(0u, active_layer()->tilings()->num_tilings());

  SetupPendingTree(valid_raster_source);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  ASSERT_EQ(0u, active_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, LowResTilingStaysOnActiveTree) {
  gfx::Size layer_bounds(1300, 1900);

  scoped_refptr<FakeRasterSource> valid_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> other_valid_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(valid_raster_source);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());

  ActivateTree();
  SetupPendingTree(other_valid_raster_source);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  auto* low_res_tiling =
      active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION);
  EXPECT_TRUE(low_res_tiling);

  ActivateTree();
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  auto* other_low_res_tiling =
      active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION);
  EXPECT_TRUE(other_low_res_tiling);
  EXPECT_EQ(low_res_tiling, other_low_res_tiling);
}

TEST_F(PictureLayerImplTest, ZoomOutCrash) {
  gfx::Size layer_bounds(1300, 1900);

  // Set up the high and low res tilings before pinch zoom.
  SetupDefaultTrees(layer_bounds);
  ResetTilingsAndRasterScales();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  SetContentsScaleOnBothLayers(32.0f, 1.0f, 32.0f, 1.0f, 0.f, false);
  EXPECT_EQ(32.f, active_layer()->HighResTiling()->contents_scale());
  host_impl()->PinchGestureBegin();
  SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false);
  SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false);
  EXPECT_EQ(active_layer()->tilings()->NumHighResTilings(), 1);
}

TEST_F(PictureLayerImplTest, ScaledBoundsOverflowInt) {
  // Limit visible size.
  gfx::Size viewport_size(1, 1);
  host_impl()->SetViewportSize(viewport_size);

  gfx::Size layer_bounds(600000, 60);

  // Set up the high and low res tilings before pinch zoom.
  SetupDefaultTrees(layer_bounds);
  ResetTilingsAndRasterScales();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  float scale = 8000.f;

  // Verify this will overflow an int.
  EXPECT_GT(static_cast<float>(layer_bounds.width()) * scale,
            static_cast<float>(std::numeric_limits<int>::max()));

  SetContentsScaleOnBothLayers(scale, 1.0f, scale, 1.0f, 0.f, false);
  float adjusted_scale = active_layer()->HighResTiling()->contents_scale();
  EXPECT_LT(adjusted_scale, scale);

  // PopulateSharedQuadState CHECKs for overflows.
  // See http://crbug.com/679035
  active_layer()->draw_properties().visible_layer_rect =
      gfx::Rect(layer_bounds);
  SharedQuadState state;
  active_layer()->PopulateScaledSharedQuadState(&state, adjusted_scale,
                                                adjusted_scale);
}

TEST_F(PictureLayerImplTest, PinchGestureTilings) {
  gfx::Size layer_bounds(1300, 1900);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  // Set up the high and low res tilings before pinch zoom.
  SetupDefaultTrees(layer_bounds);
  ResetTilingsAndRasterScales();

  SetContentsScaleOnBothLayers(2.f, 1.0f, 2.f, 1.0f, 0.f, false);
  EXPECT_EQ(active_layer()->num_tilings(), 2u);
  EXPECT_EQ(pending_layer()->num_tilings(), 1u);
  EXPECT_EQ(active_layer()->tilings()->tiling_at(0)->contents_scale(), 2.f);
  EXPECT_EQ(active_layer()->tilings()->tiling_at(1)->contents_scale(),
            2.f * low_res_factor);
  // One of the tilings has to be a low resolution one.
  EXPECT_EQ(LOW_RESOLUTION,
            active_layer()->tilings()->tiling_at(1)->resolution());

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Start a pinch gesture.
  host_impl()->PinchGestureBegin();

  // Zoom out by a small amount. We should create a tiling at half
  // the scale (2/kMaxScaleRatioDuringPinch).
  SetContentsScaleOnBothLayers(1.8f, 1.0f, 1.8f, 1.0f, 0.f, false);
  EXPECT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(2.0f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.0f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(2.0f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());
  // Since we're pinching, we shouldn't create a low resolution tiling.
  EXPECT_FALSE(
      active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION));

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Zoom out further, close to our low-res scale factor. We should
  // use that tiling as high-res, and not create a new tiling.
  SetContentsScaleOnBothLayers(low_res_factor * 2.1f, 1.0f,
                               low_res_factor * 2.1f, 1.0f, 0.f, false);
  EXPECT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FALSE(
      active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION));

  // Zoom in a lot now. Since we increase by increments of
  // kMaxScaleRatioDuringPinch, this will create a new tiling at 4.0.
  SetContentsScaleOnBothLayers(3.8f, 1.0f, 3.8f, 1.f, 0.f, false);
  EXPECT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(4.0f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  // Although one of the tilings matches the low resolution scale, it still
  // shouldn't be marked as low resolution since we're pinching.
  auto* low_res_tiling =
      active_layer()->tilings()->FindTilingWithScaleKey(4.f * low_res_factor);
  EXPECT_TRUE(low_res_tiling);
  EXPECT_NE(LOW_RESOLUTION, low_res_tiling->resolution());

  // Stop a pinch gesture.
  host_impl()->PinchGestureEnd();

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // After pinch ends, set the scale to what the raster scale was updated to
  // (checked above).
  SetContentsScaleOnBothLayers(4.0f, 1.0f, 4.0f, 1.f, 0.f, false);
  EXPECT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(4.0f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  // Now that we stopped pinching, the low resolution tiling that existed should
  // now be marked as low resolution.
  low_res_tiling =
      active_layer()->tilings()->FindTilingWithScaleKey(4.f * low_res_factor);
  EXPECT_TRUE(low_res_tiling);
  EXPECT_EQ(LOW_RESOLUTION, low_res_tiling->resolution());
}

TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) {
  gfx::Size layer_bounds(2600, 3800);
  SetupDefaultTrees(layer_bounds);

  ResetTilingsAndRasterScales();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());

  // Set up the high and low res tilings before pinch zoom.
  SetContentsScaleOnBothLayers(0.24f, 1.0f, 0.24f, 1.0f, 0.f, false);
  EXPECT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(0.24f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(0.0625f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Start a pinch gesture.
  host_impl()->PinchGestureBegin();

  // Zoom out by a small amount. We should create a tiling at half
  // the scale (1/kMaxScaleRatioDuringPinch).
  SetContentsScaleOnBothLayers(0.2f, 1.0f, 0.2f, 1.0f, 0.f, false);
  EXPECT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(0.24f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(0.12f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(0.0625,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Zoom out further, close to our low-res scale factor. We should
  // use that tiling as high-res, and not create a new tiling.
  SetContentsScaleOnBothLayers(0.1f, 1.0f, 0.1f, 1.0f, 0.f, false);
  EXPECT_EQ(3u, active_layer()->tilings()->num_tilings());

  // Zoom in. 0.25(desired_scale) should be snapped to 0.24 during zoom-in
  // because 0.25(desired_scale) is within the ratio(1.2).
  SetContentsScaleOnBothLayers(0.25f, 1.0f, 0.25f, 1.0f, 0.f, false);
  EXPECT_EQ(3u, active_layer()->tilings()->num_tilings());

  // Zoom in a lot. Since we move in factors of two, we should get a scale that
  // is a power of 2 times 0.24.
  SetContentsScaleOnBothLayers(1.f, 1.0f, 1.f, 1.0f, 0.f, false);
  EXPECT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.92f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
}

TEST_F(PictureLayerImplTest, CleanUpTilings) {
  gfx::Size layer_bounds(1300, 1900);

  std::vector<PictureLayerTiling*> used_tilings;

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  float scale = 1.f;
  float page_scale = 1.f;

  SetupDefaultTrees(layer_bounds);
  active_layer()->SetHasWillChangeTransformHint(true);
  EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  // Ensure UpdateTiles won't remove any tilings. Note this is unrelated to
  // |used_tilings| variable, and it's here only to ensure that active_layer()
  // won't remove tilings before the test has a chance to verify behavior.
  active_layer()->MarkAllTilingsUsed();

  // We only have ideal tilings, so they aren't removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  host_impl()->PinchGestureBegin();

  // Changing the ideal but not creating new tilings.
  scale = 1.5f;
  page_scale = 1.5f;
  SetContentsScaleOnBothLayers(scale, 1.f, page_scale, 1.f, 0.f, false);
  EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  // The tilings are still our target scale, so they aren't removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  host_impl()->PinchGestureEnd();

  // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2.
  scale = 1.2f;
  page_scale = 1.2f;
  SetContentsScaleOnBothLayers(1.2f, 1.f, page_scale, 1.f, 0.f, false);
  ASSERT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(3)->contents_scale());

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Mark the non-ideal tilings as used. They won't be removed.
  used_tilings.clear();
  used_tilings.push_back(active_layer()->tilings()->tiling_at(1));
  used_tilings.push_back(active_layer()->tilings()->tiling_at(3));
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(4u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());
  EXPECT_FLOAT_EQ(1.f * low_res_factor,
                  active_layer()->tilings()->tiling_at(3)->contents_scale());

  // Now move the ideal scale to 0.5. Our target stays 1.2.
  SetContentsScaleOnBothLayers(0.5f, 1.f, page_scale, 1.f, 0.f, false);

  // The high resolution tiling is between target and ideal, so is not
  // removed.  The low res tiling for the old ideal=1.0 scale is removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // Now move the ideal scale to 1.0. Our target stays 1.2.
  SetContentsScaleOnBothLayers(1.f, 1.f, page_scale, 1.f, 0.f, false);

  // All the tilings are between are target and the ideal, so they are not
  // removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2.
  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.1f, 1.f, page_scale, 1.f,
                                    0.f, false);

  // Because the pending layer's ideal scale is still 1.0, our tilings fall
  // in the range [1.0,1.2] and are kept.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // Move the ideal scale on the pending layer to 1.1 as well. Our target stays
  // 1.2 still.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.1f, 1.f, page_scale, 1.f,
                                    0.f, false);

  // Our 1.0 tiling now falls outside the range between our ideal scale and our
  // target raster scale. But it is in our used tilings set, so nothing is
  // deleted.
  used_tilings.clear();
  used_tilings.push_back(active_layer()->tilings()->tiling_at(1));
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
  EXPECT_FLOAT_EQ(1.2f * low_res_factor,
                  active_layer()->tilings()->tiling_at(2)->contents_scale());

  // If we remove it from our used tilings set, it is outside the range to keep
  // so it is deleted.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.2f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_FLOAT_EQ(1.2 * low_res_factor,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());
}

TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
  // Make sure this layer covers multiple tiles, since otherwise low
  // res won't get created because it is too small.
  gfx::Size tile_size(host_impl()->settings().default_tile_size);
  // Avoid max untiled layer size heuristics via fixed tile size.
  gfx::Size layer_bounds(tile_size.width() + 1, tile_size.height() + 1);
  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  float contents_scale = 1.f;
  float device_scale = 1.f;
  float page_scale = 1.f;
  float maximum_animation_scale = 1.f;
  float starting_animation_scale = 0.f;
  bool animating_transform = true;

  ResetTilingsAndRasterScales();

  // Animating, so don't create low res even if there isn't one already.
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
  EXPECT_BOTH_EQ(num_tilings(), 1u);

  // Stop animating, low res gets created.
  animating_transform = false;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);
  EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), low_res_factor);
  EXPECT_EQ(active_layer()->num_tilings(), 2u);
  EXPECT_EQ(pending_layer()->num_tilings(), 1u);

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Page scale animation, new high res, but no low res. We still have
  // a tiling at the previous scale, it's just not marked as low res on the
  // active layer. The pending layer drops non-ideal tilings.
  contents_scale = 2.f;
  page_scale = 2.f;
  maximum_animation_scale = 2.f;
  animating_transform = true;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
  EXPECT_FALSE(active_layer()->LowResTiling());
  EXPECT_FALSE(pending_layer()->LowResTiling());
  EXPECT_EQ(3u, active_layer()->num_tilings());
  EXPECT_EQ(1u, pending_layer()->num_tilings());

  // Stop animating, new low res gets created for final page scale.
  animating_transform = false;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
  EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(),
            2.f * low_res_factor);
  EXPECT_EQ(4u, active_layer()->num_tilings());
  EXPECT_EQ(1u, pending_layer()->num_tilings());
}

TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
  gfx::Size layer_bounds(host_impl()->settings().default_tile_size);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupTrees(pending_raster_source, active_raster_source);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  float device_scale = 1.f;
  float page_scale = 1.f;
  float maximum_animation_scale = 1.f;
  float starting_animation_scale = 0.f;
  bool animating_transform = false;

  // Contents exactly fit on one tile at scale 1, no low res.
  float contents_scale = 1.f;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale);
  EXPECT_BOTH_EQ(num_tilings(), 1u);

  ResetTilingsAndRasterScales();

  // Contents that are smaller than one tile, no low res.
  contents_scale = 0.123f;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale);
  EXPECT_BOTH_EQ(num_tilings(), 1u);

  // TODO(danakj): Remove these when raster scale doesn't get fixed?
  ResetTilingsAndRasterScales();

  // Any content bounds that would create more than one tile will
  // generate a low res tiling.
  contents_scale = 2.5f;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale);
  EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(),
            contents_scale * low_res_factor);
  EXPECT_FALSE(pending_layer()->LowResTiling());
  EXPECT_EQ(active_layer()->num_tilings(), 2u);
  EXPECT_EQ(pending_layer()->num_tilings(), 1u);

  // Mask layers dont create low res since they always fit on one tile.
  std::unique_ptr<FakePictureLayerImpl> mask =
      FakePictureLayerImpl::CreateMaskWithRasterSource(
          host_impl()->pending_tree(), 3, pending_raster_source);
  mask->SetBounds(layer_bounds);
  mask->SetDrawsContent(true);
  pending_layer()->test_properties()->SetMaskLayer(std::move(mask));
  pending_layer()->test_properties()->force_render_surface = true;
  RebuildPropertyTreesOnPendingTree();
  host_impl()->pending_tree()->UpdateDrawProperties(false);

  FakePictureLayerImpl* mask_raw = static_cast<FakePictureLayerImpl*>(
      pending_layer()->test_properties()->mask_layer);
  // We did an UpdateDrawProperties above, which will set a contents scale on
  // the mask layer, so allow us to reset the contents scale.
  mask_raw->ReleaseTileResources();
  mask_raw->RecreateTileResources();

  SetupDrawPropertiesAndUpdateTiles(
      mask_raw, contents_scale, device_scale, page_scale,
      maximum_animation_scale, starting_animation_scale, animating_transform);
  EXPECT_EQ(mask_raw->HighResTiling()->contents_scale(), contents_scale);
  EXPECT_EQ(mask_raw->num_tilings(), 1u);
}

TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size layer_bounds(1000, 1000);

  scoped_refptr<FakeRasterSource> valid_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(valid_raster_source);

  std::unique_ptr<FakePictureLayerImpl> mask_ptr =
      FakePictureLayerImpl::CreateMaskWithRasterSource(
          host_impl()->pending_tree(), 3, valid_raster_source);
  mask_ptr->SetBounds(layer_bounds);
  mask_ptr->SetDrawsContent(true);
  pending_layer()->test_properties()->SetMaskLayer(std::move(mask_ptr));
  pending_layer()->test_properties()->force_render_surface = true;

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  FakePictureLayerImpl* pending_mask = static_cast<FakePictureLayerImpl*>(
      pending_layer()->test_properties()->mask_layer);

  EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale());
  EXPECT_EQ(1u, pending_mask->num_tilings());

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      pending_mask->HighResTiling()->AllTilesForTesting());

  ActivateTree();

  FakePictureLayerImpl* active_mask = static_cast<FakePictureLayerImpl*>(
      host_impl()->active_tree()->LayerById(pending_mask->id()));

  // Mask layers have a tiling with a single tile in it.
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  // The mask resource exists.
  ResourceId mask_resource_id;
  gfx::Size mask_texture_size;
  active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
  EXPECT_NE(0u, mask_resource_id);
  EXPECT_EQ(active_mask->bounds(), mask_texture_size);

  // Drop resources and recreate them, still the same.
  pending_mask->ReleaseTileResources();
  active_mask->ReleaseTileResources();
  pending_mask->RecreateTileResources();
  active_mask->RecreateTileResources();
  SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  active_mask->HighResTiling()->CreateAllTilesForTesting();
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  EXPECT_NE(0u, mask_resource_id);
  EXPECT_EQ(active_mask->bounds(), mask_texture_size);

  // Resize larger than the max texture size.
  int max_texture_size = host_impl()->resource_provider()->max_texture_size();
  gfx::Size huge_bounds(max_texture_size + 1, 10);
  scoped_refptr<FakeRasterSource> huge_raster_source =
      FakeRasterSource::CreateFilled(huge_bounds);

  SetupPendingTree(huge_raster_source);
  pending_mask->SetBounds(huge_bounds);
  pending_mask->SetRasterSourceOnPending(huge_raster_source, Region());

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  // The mask tiling gets scaled down.
  EXPECT_LT(pending_mask->HighResTiling()->contents_scale(), 1.f);
  EXPECT_EQ(1u, pending_mask->num_tilings());

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      pending_mask->HighResTiling()->AllTilesForTesting());

  ActivateTree();

  // Mask layers have a tiling with a single tile in it.
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  // The mask resource exists.
  active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
  EXPECT_NE(0u, mask_resource_id);
  gfx::Size expected_size = active_mask->bounds();
  expected_size.SetToMin(gfx::Size(max_texture_size, max_texture_size));
  EXPECT_EQ(expected_size, mask_texture_size);

  // Drop resources and recreate them, still the same.
  pending_mask->ReleaseTileResources();
  active_mask->ReleaseTileResources();
  pending_mask->RecreateTileResources();
  active_mask->RecreateTileResources();
  SetupDrawPropertiesAndUpdateTiles(active_mask, 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  active_mask->HighResTiling()->CreateAllTilesForTesting();
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  EXPECT_NE(0u, mask_resource_id);
  EXPECT_EQ(expected_size, mask_texture_size);

  // Do another activate, the same holds.
  SetupPendingTree(huge_raster_source);
  ActivateTree();
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  active_layer()->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
  EXPECT_EQ(expected_size, mask_texture_size);
  EXPECT_EQ(0u, mask_resource_id);

  // Resize even larger, so that the scale would be smaller than the minimum
  // contents scale. Then the layer should no longer have any tiling.
  float min_contents_scale = host_impl()->settings().minimum_contents_scale;
  gfx::Size extra_huge_bounds(max_texture_size / min_contents_scale + 1, 10);
  scoped_refptr<FakeRasterSource> extra_huge_raster_source =
      FakeRasterSource::CreateFilled(extra_huge_bounds);

  SetupPendingTree(extra_huge_raster_source);
  pending_mask->SetBounds(extra_huge_bounds);
  pending_mask->SetRasterSourceOnPending(extra_huge_raster_source, Region());

  EXPECT_FALSE(pending_mask->CanHaveTilings());

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  EXPECT_EQ(0u, pending_mask->num_tilings());
}

TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size layer_bounds(1000, 1000);

  SetInitialDeviceScaleFactor(1.3f);

  scoped_refptr<FakeRasterSource> valid_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(valid_raster_source);

  std::unique_ptr<FakePictureLayerImpl> mask_ptr =
      FakePictureLayerImpl::CreateMaskWithRasterSource(
          host_impl()->pending_tree(), 3, valid_raster_source);
  mask_ptr->SetBounds(layer_bounds);
  mask_ptr->SetDrawsContent(true);
  pending_layer()->test_properties()->SetMaskLayer(std::move(mask_ptr));
  pending_layer()->test_properties()->force_render_surface = true;

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  FakePictureLayerImpl* pending_mask = static_cast<FakePictureLayerImpl*>(
      pending_layer()->test_properties()->mask_layer);

  // Masks are scaled, and do not have a low res tiling.
  EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale());
  EXPECT_EQ(1u, pending_mask->num_tilings());

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      pending_mask->HighResTiling()->AllTilesForTesting());

  ActivateTree();

  FakePictureLayerImpl* active_mask = static_cast<FakePictureLayerImpl*>(
      host_impl()->active_tree()->LayerById(pending_mask->id()));

  // Mask layers have a tiling with a single tile in it.
  EXPECT_EQ(1u, active_mask->HighResTiling()->AllTilesForTesting().size());
  // The mask resource exists.
  ResourceId mask_resource_id;
  gfx::Size mask_texture_size;
  active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
  EXPECT_NE(0u, mask_resource_id);
  gfx::Size expected_mask_texture_size =
      gfx::ScaleToCeiledSize(active_mask->bounds(), 1.3f);
  EXPECT_EQ(mask_texture_size, expected_mask_texture_size);
}

TEST_F(PictureLayerImplTest, ReleaseTileResources) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());

  // All tilings should be removed when losing output surface.
  active_layer()->ReleaseTileResources();
  EXPECT_FALSE(active_layer()->tilings());
  active_layer()->RecreateTileResources();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  pending_layer()->ReleaseTileResources();
  EXPECT_FALSE(pending_layer()->tilings());
  pending_layer()->RecreateTileResources();
  EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings());

  // This should create new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    1.f,  // ideal contents scale
                                    1.f,  // device scale
                                    1.f,  // page scale
                                    1.f,  // maximum animation scale
                                    0.f,  // starting animation_scale
                                    false);
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
}

// ReleaseResources should behave identically to ReleaseTileResources.
TEST_F(PictureLayerImplTest, ReleaseResources) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());

  // All tilings should be removed when losing output surface.
  active_layer()->ReleaseResources();
  EXPECT_FALSE(active_layer()->tilings());
  active_layer()->RecreateTileResources();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  pending_layer()->ReleaseResources();
  EXPECT_FALSE(pending_layer()->tilings());
  pending_layer()->RecreateTileResources();
  EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) {
  gfx::Size layer_bounds(5000, 5000);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(pending_raster_source);
  EXPECT_GE(pending_layer()->tilings()->num_tilings(), 1u);

  pending_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting();

  // The default value.
  EXPECT_EQ(gfx::Size(256, 256).ToString(),
            host_impl()->settings().default_tile_size.ToString());

  Tile* tile =
      pending_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0];
  EXPECT_EQ(gfx::Size(256, 256).ToString(),
            tile->content_rect().size().ToString());

  ResetTilingsAndRasterScales();

  // Change the max texture size on the output surface context.
  std::unique_ptr<TestWebGraphicsContext3D> context =
      TestWebGraphicsContext3D::Create();
  context->set_max_texture_size(140);
  ResetCompositorFrameSink(
      FakeCompositorFrameSink::Create3d(std::move(context)));

  SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());

  pending_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting();

  // Verify the tiles are not larger than the context's max texture size.
  tile = pending_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0];
  EXPECT_GE(140, tile->content_rect().width());
  EXPECT_GE(140, tile->content_rect().height());
}

TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
  gfx::Size layer_bounds(500, 500);
  SetupDefaultTrees(layer_bounds);
  EXPECT_GE(active_layer()->tilings()->num_tilings(), 1u);

  active_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting();

  // The default value. The layer is smaller than this.
  EXPECT_EQ(gfx::Size(512, 512).ToString(),
            host_impl()->settings().max_untiled_layer_size.ToString());

  // There should be a single tile since the layer is small.
  PictureLayerTiling* high_res_tiling = active_layer()->tilings()->tiling_at(0);
  EXPECT_EQ(1u, high_res_tiling->AllTilesForTesting().size());

  ResetTilingsAndRasterScales();

  // Change the max texture size on the output surface context.
  std::unique_ptr<TestWebGraphicsContext3D> context =
      TestWebGraphicsContext3D::Create();
  context->set_max_texture_size(140);
  ResetCompositorFrameSink(
      FakeCompositorFrameSink::Create3d(std::move(context)));

  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  ASSERT_LE(1u, active_layer()->tilings()->num_tilings());

  active_layer()->tilings()->tiling_at(0)->CreateAllTilesForTesting();

  // There should be more than one tile since the max texture size won't cover
  // the layer.
  high_res_tiling = active_layer()->tilings()->tiling_at(0);
  EXPECT_LT(1u, high_res_tiling->AllTilesForTesting().size());

  // Verify the tiles are not larger than the context's max texture size.
  Tile* tile = active_layer()->tilings()->tiling_at(0)->AllTilesForTesting()[0];
  EXPECT_GE(140, tile->content_rect().width());
  EXPECT_GE(140, tile->content_rect().height());
}

TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();

  gfx::Size layer_bounds(1300, 1900);
  gfx::Rect layer_rect(layer_bounds);

  gfx::Rect layer_invalidation(150, 200, 30, 180);
  SetupDefaultTreesWithInvalidation(layer_bounds, layer_invalidation);

  active_layer()->SetContentsOpaque(true);
  active_layer()->draw_properties().visible_layer_rect =
      gfx::Rect(layer_bounds);

  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  ASSERT_EQ(1u, render_pass->quad_list.size());
  EXPECT_EQ(DrawQuad::PICTURE_CONTENT,
            render_pass->quad_list.front()->material);
  EXPECT_EQ(render_pass->quad_list.front()->rect, layer_rect);
  EXPECT_EQ(render_pass->quad_list.front()->opaque_rect, layer_rect);
  EXPECT_EQ(render_pass->quad_list.front()->visible_rect, layer_rect);
}

TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) {
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();

  gfx::Size tile_size(400, 400);
  gfx::Size layer_bounds(700, 650);
  gfx::Rect layer_rect(layer_bounds);
  SetInitialDeviceScaleFactor(2.f);

  gfx::Rect recorded_viewport(20, 30, 40, 50);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds, recorded_viewport);

  SetupPendingTree(active_raster_source);
  ActivateTree();

  active_layer()->SetContentsOpaque(true);
  gfx::Rect visible_rect(30, 35, 10, 5);
  active_layer()->draw_properties().visible_layer_rect = visible_rect;

  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  gfx::Rect scaled_visible = gfx::ScaleToEnclosingRect(visible_rect, 2.f);
  gfx::Rect scaled_recorded = gfx::ScaleToEnclosingRect(recorded_viewport, 2.f);
  gfx::Rect quad_visible = gfx::IntersectRects(scaled_visible, scaled_recorded);

  ASSERT_EQ(1U, render_pass->quad_list.size());
  EXPECT_EQ(DrawQuad::PICTURE_CONTENT,
            render_pass->quad_list.front()->material);
  const DrawQuad* quad = render_pass->quad_list.front();
  EXPECT_EQ(quad_visible, quad->rect);
  EXPECT_EQ(quad_visible, quad->opaque_rect);
  EXPECT_EQ(quad_visible, quad->visible_rect);
}

TEST_F(PictureLayerImplTest, ResourcelessEmptyRecording) {
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();

  gfx::Size layer_bounds(700, 650);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds, gfx::Rect());
  SetupPendingTree(active_raster_source);
  ActivateTree();

  active_layer()->SetContentsOpaque(true);
  active_layer()->draw_properties().visible_layer_rect =
      gfx::Rect(layer_bounds);

  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  EXPECT_EQ(0U, render_pass->quad_list.size());
}

TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) {
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();

  gfx::Size layer_bounds(1500, 1500);
  gfx::Rect visible_rect(250, 250, 1000, 1000);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilledSolidColor(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilledSolidColor(layer_bounds);

  SetupTrees(pending_raster_source, active_raster_source);

  active_layer()->draw_properties().visible_layer_rect = visible_rect;

  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  Region remaining = visible_rect;
  for (auto* quad : render_pass->quad_list) {
    EXPECT_TRUE(visible_rect.Contains(quad->rect));
    EXPECT_TRUE(remaining.Contains(quad->rect));
    remaining.Subtract(quad->rect);
  }

  EXPECT_TRUE(remaining.IsEmpty());
}

TEST_F(PictureLayerImplTest, TileScalesWithSolidColorRasterSource) {
  gfx::Size layer_bounds(200, 200);
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilledSolidColor(layer_bounds);

  SetupTrees(pending_raster_source, active_raster_source);
  // Solid color raster source should not allow tilings at any scale.
  EXPECT_FALSE(active_layer()->CanHaveTilings());
  EXPECT_EQ(0.f, active_layer()->ideal_contents_scale());

  // Activate non-solid-color pending raster source makes active layer can have
  // tilings.
  ActivateTree();
  EXPECT_TRUE(active_layer()->CanHaveTilings());
  EXPECT_GT(active_layer()->ideal_contents_scale(), 0.f);
}

TEST_F(NoLowResPictureLayerImplTest, MarkRequiredOffscreenTiles) {
  gfx::Size layer_bounds(200, 200);

  gfx::Transform transform;
  gfx::Rect viewport(0, 0, 100, 200);
  host_impl()->SetExternalTilePriorityConstraints(viewport, transform);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, gfx::Size(100, 100),
                                    Region());

  EXPECT_EQ(1u, pending_layer()->num_tilings());
  EXPECT_EQ(
      viewport,
      pending_layer()->viewport_rect_for_tile_priority_in_content_space());

  base::TimeTicks time_ticks;
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  pending_layer()->UpdateTiles();

  int num_visible = 0;
  int num_offscreen = 0;

  std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  for (; !queue->IsEmpty(); queue->Pop()) {
    const PrioritizedTile& prioritized_tile = queue->Top();
    DCHECK(prioritized_tile.tile());
    if (prioritized_tile.priority().distance_to_visible == 0.f) {
      EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
      num_visible++;
    } else {
      EXPECT_FALSE(prioritized_tile.tile()->required_for_activation());
      num_offscreen++;
    }
  }

  EXPECT_GT(num_visible, 0);
  EXPECT_GT(num_offscreen, 0);
}

TEST_F(NoLowResPictureLayerImplTest,
       TileOutsideOfViewportForTilePriorityNotRequired) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(400, 400);
  gfx::Rect external_viewport_for_tile_priority(400, 200);
  gfx::Rect visible_layer_rect(200, 400);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  ASSERT_EQ(1u, pending_layer()->num_tilings());
  ASSERT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale());

  // Set external viewport for tile priority.
  gfx::Transform transform;
  gfx::Transform transform_for_tile_priority;
  host_impl()->SetExternalTilePriorityConstraints(
      external_viewport_for_tile_priority, transform_for_tile_priority);
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  // Set visible content rect that is different from
  // external_viewport_for_tile_priority.
  pending_layer()->draw_properties().visible_layer_rect = visible_layer_rect;
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
  pending_layer()->UpdateTiles();

  // Intersect the two rects. Any tile outside should not be required for
  // activation.
  gfx::Rect viewport_for_tile_priority =
      pending_layer()->viewport_rect_for_tile_priority_in_content_space();
  viewport_for_tile_priority.Intersect(pending_layer()->visible_layer_rect());

  EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty());

  int num_inside = 0;
  int num_outside = 0;
  for (PictureLayerTiling::CoverageIterator iter(
           active_layer()->HighResTiling(), 1.f, gfx::Rect(layer_bounds));
       iter; ++iter) {
    if (!*iter)
      continue;
    Tile* tile = *iter;
    if (viewport_for_tile_priority.Intersects(iter.geometry_rect())) {
      num_inside++;
      // Mark everything in viewport for tile priority as ready to draw.
      TileDrawInfo& draw_info = tile->draw_info();
      draw_info.SetSolidColorForTesting(SK_ColorRED);
    } else {
      num_outside++;
      EXPECT_FALSE(tile->required_for_activation());
    }
  }

  EXPECT_GT(num_inside, 0);
  EXPECT_GT(num_outside, 0);

  // Activate and draw active layer.
  host_impl()->ActivateSyncTree();
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);
  active_layer()->draw_properties().visible_layer_rect = visible_layer_rect;

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  // All tiles in activation rect is ready to draw.
  EXPECT_EQ(0u, data.num_missing_tiles);
  EXPECT_EQ(0u, data.num_incomplete_tiles);
  EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, HighResTileIsComplete) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  // All high res tiles have resources.
  std::vector<Tile*> tiles =
      active_layer()->tilings()->tiling_at(0)->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  // All high res tiles drew, nothing was incomplete.
  EXPECT_EQ(9u, render_pass->quad_list.size());
  EXPECT_EQ(0u, data.num_missing_tiles);
  EXPECT_EQ(0u, data.num_incomplete_tiles);
  EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  EXPECT_EQ(1u, render_pass->quad_list.size());
  EXPECT_EQ(1u, data.num_missing_tiles);
  EXPECT_EQ(0u, data.num_incomplete_tiles);
  EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  std::vector<Tile*> low_tiles =
      active_layer()->tilings()->tiling_at(1)->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      low_tiles);

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  EXPECT_EQ(1u, render_pass->quad_list.size());
  EXPECT_EQ(0u, data.num_missing_tiles);
  EXPECT_EQ(1u, data.num_incomplete_tiles);
  EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  // All high res tiles have resources except one.
  std::vector<Tile*> high_tiles =
      active_layer()->tilings()->tiling_at(0)->AllTilesForTesting();
  high_tiles.erase(high_tiles.begin());
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      high_tiles);

  // All low res tiles have resources.
  std::vector<Tile*> low_tiles =
      active_layer()->tilings()->tiling_at(1)->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      low_tiles);

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  // The missing high res tile was replaced by a low res tile.
  EXPECT_EQ(9u, render_pass->quad_list.size());
  EXPECT_EQ(0u, data.num_missing_tiles);
  EXPECT_EQ(1u, data.num_incomplete_tiles);
  EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest,
       HighResAndIdealResTileIsCompleteWhenRasterScaleIsNotIdeal) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);
  gfx::Size viewport_size(400, 400);

  host_impl()->SetViewportSize(viewport_size);
  SetInitialDeviceScaleFactor(2.f);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());
  active_layer()->SetHasWillChangeTransformHint(true);

  // One ideal tile exists, this will get used when drawing.
  std::vector<Tile*> ideal_tiles;
  EXPECT_EQ(2.f, active_layer()->HighResTiling()->contents_scale());
  ideal_tiles.push_back(active_layer()->HighResTiling()->TileAt(0, 0));
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      ideal_tiles);

  // Due to layer scale throttling, the raster contents scale is changed to 1,
  // while the ideal is still 2.
  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  SetupDrawPropertiesAndUpdateTiles(active_layer(), 2.f, 1.f, 1.f, 1.f, 0.f,
                                    false);

  EXPECT_EQ(1.f, active_layer()->HighResTiling()->contents_scale());
  EXPECT_EQ(1.f, active_layer()->raster_contents_scale());
  EXPECT_EQ(2.f, active_layer()->ideal_contents_scale());

  // Both tilings still exist.
  EXPECT_EQ(2.f, active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_EQ(1.f, active_layer()->tilings()->tiling_at(1)->contents_scale());

  // All high res tiles have resources.
  std::vector<Tile*> high_tiles =
      active_layer()->HighResTiling()->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      high_tiles);

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  // All high res tiles drew, and the one ideal res tile drew.
  ASSERT_GT(render_pass->quad_list.size(), 9u);
  EXPECT_EQ(gfx::Rect(0, 0, 99, 99), render_pass->quad_list.front()->rect);
  EXPECT_EQ(gfx::RectF(0.f, 0.f, 99.f, 99.f),
            TileDrawQuad::MaterialCast(render_pass->quad_list.front())
                ->tex_coord_rect);
  EXPECT_EQ(gfx::Rect(99, 0, 100, 99),
            render_pass->quad_list.ElementAt(1)->rect);
  EXPECT_EQ(gfx::RectF(49.5f, 0.f, 50.f, 49.5f),
            TileDrawQuad::MaterialCast(render_pass->quad_list.ElementAt(1))
                ->tex_coord_rect);

  // Neither the high res nor the ideal tiles were considered as incomplete.
  EXPECT_EQ(0u, data.num_missing_tiles);
  EXPECT_EQ(0u, data.num_incomplete_tiles);
  EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);
  gfx::Rect recorded_viewport(0, 0, 150, 150);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds, recorded_viewport);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  EXPECT_EQ(1u, render_pass->quad_list.size());
  EXPECT_EQ(1u, data.num_missing_tiles);
  EXPECT_EQ(0u, data.num_incomplete_tiles);
  EXPECT_EQ(40000, data.checkerboarded_visible_content_area);
  EXPECT_EQ(17500, data.checkerboarded_no_recording_content_area);
  EXPECT_EQ(22500, data.checkerboarded_needs_raster_content_area);
  EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads());
}

TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size,
                                     gfx::Rect(layer_bounds));

  active_layer()->SetAllTilesReady();

  // All active tiles ready, so pending can only activate with all high res
  // tiles.
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  EXPECT_FALSE(pending_layer()->LowResTiling());

  AssertAllTilesRequired(pending_layer()->HighResTiling());
}

TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  // No invalidation.
  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  // Verify active tree not ready.
  Tile* some_active_tile =
      active_layer()->HighResTiling()->AllTilesForTesting()[0];
  EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw());

  // When high res are required, all tiles in active high res tiling should be
  // required for activation.
  host_impl()->SetRequiresHighResToDraw();

  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  EXPECT_FALSE(pending_layer()->LowResTiling());
  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty());
  AssertAllTilesRequired(active_layer()->HighResTiling());
  AssertNoTilesRequired(active_layer()->LowResTiling());
}

TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  Tile* some_active_tile =
      active_layer()->HighResTiling()->AllTilesForTesting()[0];
  EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw());

  // Since there are no invalidations, pending tree should have no tiles.
  EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty());
  EXPECT_FALSE(pending_layer()->LowResTiling());

  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  AssertAllTilesRequired(active_layer()->HighResTiling());
  AssertNoTilesRequired(active_layer()->LowResTiling());
}

TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  Tile* some_active_tile =
      active_layer()->HighResTiling()->AllTilesForTesting()[0];
  EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw());

  EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty());
  EXPECT_FALSE(pending_layer()->LowResTiling());
  active_layer()->HighResTiling()->set_can_require_tiles_for_activation(false);
  active_layer()->LowResTiling()->set_can_require_tiles_for_activation(false);
  pending_layer()->HighResTiling()->set_can_require_tiles_for_activation(false);

  // If we disallow required for activation, no tiles can be required.
  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  AssertNoTilesRequired(active_layer()->HighResTiling());
  AssertNoTilesRequired(active_layer()->LowResTiling());
}

TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  // This raster source will create tilings, but has no recordings so will not
  // create any tiles.  This is attempting to simulate scrolling past the end of
  // recorded content on the active layer, where the recordings are so far away
  // that no tiles are created.
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds, gfx::Rect());

  SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source,
                              tile_size, Region());

  // Active layer has tilings, but no tiles due to missing recordings.
  EXPECT_TRUE(active_layer()->CanHaveTilings());
  EXPECT_EQ(active_layer()->tilings()->num_tilings(), 2u);
  EXPECT_EQ(active_layer()->HighResTiling()->AllTilesForTesting().size(), 0u);

  // Since the active layer has no tiles at all, the pending layer doesn't
  // need content in order to activate.
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  EXPECT_FALSE(pending_layer()->LowResTiling());

  AssertNoTilesRequired(pending_layer()->HighResTiling());
}

TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateEmpty(layer_bounds);
  SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source,
                              tile_size, Region());

  // Active layer can't have tiles.
  EXPECT_FALSE(active_layer()->CanHaveTilings());

  // All high res tiles required.  This should be considered identical
  // to the case where there is no active layer, to avoid flashing content.
  // This can happen if a layer exists for a while and switches from
  // not being able to have content to having content.
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  EXPECT_FALSE(pending_layer()->LowResTiling());

  AssertAllTilesRequired(pending_layer()->HighResTiling());
}

TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) {
  gfx::Size pending_layer_bounds(400, 400);
  gfx::Size active_layer_bounds(200, 200);
  gfx::Size tile_size(100, 100);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(pending_layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(active_layer_bounds);

  SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source,
                              tile_size, Region());

  // Since the active layer has different bounds, the pending layer needs all
  // high res tiles in order to activate.
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  EXPECT_FALSE(pending_layer()->LowResTiling());
  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  AssertAllTilesRequired(pending_layer()->HighResTiling());
  AssertAllTilesRequired(active_layer()->HighResTiling());
  AssertNoTilesRequired(active_layer()->LowResTiling());
}

TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) {
  gfx::Size layer_bounds(400, 400);
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->CreatePendingTree();
  LayerTreeImpl* pending_tree = host_impl()->pending_tree();

  std::unique_ptr<FakePictureLayerImpl> pending_layer =
      FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(),
                                                   pending_raster_source);
  pending_layer->SetDrawsContent(true);
  pending_tree->SetRootLayerForTesting(std::move(pending_layer));
  pending_tree->BuildLayerListForTesting();

  FakePictureLayerImpl* raw_pending_layer = static_cast<FakePictureLayerImpl*>(
      host_impl()->pending_tree()->LayerById(layer_id()));

  // Set some state on the pending layer, make sure it is not clobbered
  // by a sync from the active layer.  This could happen because if the
  // pending layer has not been post-commit initialized it will attempt
  // to sync from the active layer.
  float raster_page_scale = 10.f * raw_pending_layer->raster_page_scale();
  raw_pending_layer->set_raster_page_scale(raster_page_scale);

  host_impl()->ActivateSyncTree();

  FakePictureLayerImpl* raw_active_layer = static_cast<FakePictureLayerImpl*>(
      host_impl()->active_tree()->LayerById(layer_id()));

  EXPECT_EQ(0u, raw_active_layer->num_tilings());
  EXPECT_EQ(raster_page_scale, raw_active_layer->raster_page_scale());
}

TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) {
  gfx::Size layer_bounds(1500, 1500);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(pending_raster_source);

  PictureLayerTiling* tiling = pending_layer()->HighResTiling();
  gfx::Rect first_invalidate = tiling->TilingDataForTesting().TileBounds(0, 0);
  first_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
                         tiling->TilingDataForTesting().border_texels());
  gfx::Rect second_invalidate = tiling->TilingDataForTesting().TileBounds(1, 1);
  second_invalidate.Inset(tiling->TilingDataForTesting().border_texels(),
                          tiling->TilingDataForTesting().border_texels());

  ActivateTree();

  // Make a pending tree with an invalidated raster tile 0,0.
  SetupPendingTreeWithInvalidation(pending_raster_source, first_invalidate);

  // Activate and make a pending tree with an invalidated raster tile 1,1.
  ActivateTree();

  SetupPendingTreeWithInvalidation(pending_raster_source, second_invalidate);

  PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0);
  PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0);

  // Tile 0,0 not exist on pending, but tile 1,1 should.
  EXPECT_TRUE(active_tiling->TileAt(0, 0));
  EXPECT_TRUE(active_tiling->TileAt(1, 0));
  EXPECT_TRUE(active_tiling->TileAt(0, 1));
  EXPECT_FALSE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 0));
  EXPECT_FALSE(pending_tiling->TileAt(0, 1));
  EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
  EXPECT_TRUE(active_tiling->TileAt(1, 1));
  EXPECT_TRUE(pending_tiling->TileAt(1, 1));

  // Drop the tiles on the active tree and recreate them.
  active_layer()->tilings()->UpdateTilePriorities(gfx::Rect(), 1.f, 1.0,
                                                  Occlusion(), true);
  EXPECT_TRUE(active_tiling->AllTilesForTesting().empty());
  active_tiling->CreateAllTilesForTesting();

  // Tile 0,0 not exist on pending, but tile 1,1 should.
  EXPECT_TRUE(active_tiling->TileAt(0, 0));
  EXPECT_TRUE(active_tiling->TileAt(1, 0));
  EXPECT_TRUE(active_tiling->TileAt(0, 1));
  EXPECT_FALSE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 0));
  EXPECT_FALSE(pending_tiling->TileAt(0, 1));
  EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
  EXPECT_TRUE(active_tiling->TileAt(1, 1));
  EXPECT_TRUE(pending_tiling->TileAt(1, 1));
}

TEST_F(PictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) {
  SetupDefaultTrees(gfx::Size(1500, 1500));

  EXPECT_GE(active_layer()->num_tilings(), 1u);
  EXPECT_GE(pending_layer()->num_tilings(), 1u);

  // No invalidation.
  PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0);
  PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0);
  ASSERT_TRUE(active_tiling);
  ASSERT_TRUE(pending_tiling);

  EXPECT_TRUE(active_tiling->TileAt(0, 0));
  EXPECT_TRUE(active_tiling->TileAt(1, 0));
  EXPECT_TRUE(active_tiling->TileAt(0, 1));
  EXPECT_TRUE(active_tiling->TileAt(1, 1));

  EXPECT_FALSE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 0));
  EXPECT_FALSE(pending_tiling->TileAt(0, 1));
  EXPECT_FALSE(pending_tiling->TileAt(1, 1));
}

TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) {
  gfx::Size layer_bounds(1500, 1500);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupTreesWithInvalidation(pending_raster_source, active_raster_source,
                             gfx::Rect(1, 1));
  // Activate the invalidation.
  ActivateTree();
  // Make another pending tree without any invalidation in it.
  scoped_refptr<FakeRasterSource> pending_raster_source2 =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(pending_raster_source2);

  EXPECT_GE(active_layer()->num_tilings(), 1u);
  EXPECT_GE(pending_layer()->num_tilings(), 1u);

  // The active tree invalidation was handled by the active tiles.
  PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0);
  PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0);
  ASSERT_TRUE(active_tiling);
  ASSERT_TRUE(pending_tiling);

  EXPECT_TRUE(active_tiling->TileAt(0, 0));
  EXPECT_TRUE(active_tiling->TileAt(1, 0));
  EXPECT_TRUE(active_tiling->TileAt(0, 1));
  EXPECT_TRUE(active_tiling->TileAt(1, 1));

  EXPECT_FALSE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 0));
  EXPECT_FALSE(pending_tiling->TileAt(0, 1));
  EXPECT_FALSE(pending_tiling->TileAt(1, 1));
}

TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) {
  // Set some invalidation on the pending tree. We should replace raster tiles
  // that touch this.
  SetupDefaultTreesWithInvalidation(gfx::Size(1500, 1500), gfx::Rect(1, 1));

  EXPECT_GE(active_layer()->num_tilings(), 1u);
  EXPECT_GE(pending_layer()->num_tilings(), 1u);

  // The pending tree invalidation creates tiles on the pending tree.
  PictureLayerTiling* active_tiling = active_layer()->tilings()->tiling_at(0);
  PictureLayerTiling* pending_tiling = pending_layer()->tilings()->tiling_at(0);
  ASSERT_TRUE(active_tiling);
  ASSERT_TRUE(pending_tiling);

  EXPECT_TRUE(active_tiling->TileAt(0, 0));
  EXPECT_TRUE(active_tiling->TileAt(1, 0));
  EXPECT_TRUE(active_tiling->TileAt(0, 1));
  EXPECT_TRUE(active_tiling->TileAt(1, 1));

  EXPECT_TRUE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 0));
  EXPECT_FALSE(pending_tiling->TileAt(0, 1));
  EXPECT_FALSE(pending_tiling->TileAt(1, 1));

  EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
}

TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size layer_bounds(10, 10);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupTrees(pending_raster_source, active_raster_source);

  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
  EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));

  // Gpu rasterization is disabled by default.
  EXPECT_FALSE(host_impl()->use_gpu_rasterization());
  EXPECT_EQ(0u, pending_layer()->release_tile_resources_count());
  EXPECT_EQ(0u, active_layer()->release_tile_resources_count());
  EXPECT_EQ(0u, pending_layer()->release_resources_count());
  EXPECT_EQ(0u, active_layer()->release_resources_count());
  // Toggling the gpu rasterization clears all tilings on both trees.
  host_impl()->SetHasGpuRasterizationTrigger(true);
  host_impl()->SetContentIsSuitableForGpuRasterization(true);
  host_impl()->CommitComplete();
  EXPECT_EQ(1u, pending_layer()->release_tile_resources_count());
  EXPECT_EQ(1u, active_layer()->release_tile_resources_count());
  EXPECT_EQ(1u, pending_layer()->release_resources_count());
  EXPECT_EQ(1u, active_layer()->release_resources_count());

  // But the pending layer gets a tiling back, and can activate it.
  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());

  ActivateTree();
  EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));

  SetupPendingTree(pending_raster_source);
  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));

  // Toggling the gpu rasterization clears all tilings on both trees.
  EXPECT_TRUE(host_impl()->use_gpu_rasterization());
  host_impl()->SetHasGpuRasterizationTrigger(false);
  host_impl()->CommitComplete();
  EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT,
            host_impl()->gpu_rasterization_status());
  EXPECT_EQ(2u, pending_layer()->release_tile_resources_count());
  EXPECT_EQ(2u, active_layer()->release_tile_resources_count());
  EXPECT_EQ(2u, pending_layer()->release_resources_count());
  EXPECT_EQ(2u, active_layer()->release_resources_count());

  host_impl()->SetHasGpuRasterizationTrigger(true);
  host_impl()->SetContentIsSuitableForGpuRasterization(false);
  host_impl()->CommitComplete();
  EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT,
            host_impl()->gpu_rasterization_status());
}

TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
  // Put 0.5 as high res.
  SetInitialDeviceScaleFactor(0.5f);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(gfx::Size(10, 10));
  SetupPendingTree(pending_raster_source);

  // Sanity checks.
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(0.5f));

  ActivateTree();

  // Now, set the bounds to be 1x1, so that minimum contents scale becomes 1.
  pending_raster_source = FakeRasterSource::CreateFilled(gfx::Size(1, 1));
  SetupPendingTree(pending_raster_source);

  // Another sanity check.
  EXPECT_EQ(1.f, pending_layer()->MinimumContentsScale());

  // Since the MinContentsScale is 1, the 0.5 tiling should have been replaced
  // by a 1.0 tiling during the UDP in SetupPendingTree.
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
  PictureLayerTiling* tiling =
      pending_layer()->tilings()->FindTilingWithScaleKey(1.0f);
  ASSERT_TRUE(tiling);
  EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution());
}

TEST_F(PictureLayerImplTest, LowResTilingWithoutGpuRasterization) {
  gfx::Size default_tile_size(host_impl()->settings().default_tile_size);
  gfx::Size layer_bounds(default_tile_size.width() * 4,
                         default_tile_size.height() * 4);

  host_impl()->SetHasGpuRasterizationTrigger(false);

  SetupDefaultTrees(layer_bounds);
  EXPECT_FALSE(host_impl()->use_gpu_rasterization());
  // Should have only a high-res tiling.
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
  ActivateTree();
  // Should add a high and a low res for active tree.
  EXPECT_EQ(2u, active_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) {
  gfx::Size default_tile_size(host_impl()->settings().default_tile_size);
  gfx::Size layer_bounds(default_tile_size.width() * 4,
                         default_tile_size.height() * 4);

  host_impl()->SetHasGpuRasterizationTrigger(true);
  host_impl()->SetContentIsSuitableForGpuRasterization(true);
  host_impl()->CommitComplete();

  SetupDefaultTrees(layer_bounds);
  EXPECT_TRUE(host_impl()->use_gpu_rasterization());
  // Should only have the high-res tiling.
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
  ActivateTree();
  // Should only have the high-res tiling.
  EXPECT_EQ(1u, active_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, RequiredTilesWithGpuRasterization) {
  host_impl()->SetHasGpuRasterizationTrigger(true);
  host_impl()->SetContentIsSuitableForGpuRasterization(true);
  host_impl()->CommitComplete();

  gfx::Size viewport_size(1000, 1000);
  host_impl()->SetViewportSize(viewport_size);

  gfx::Size layer_bounds(4000, 4000);
  SetupDefaultTrees(layer_bounds);
  EXPECT_TRUE(host_impl()->use_gpu_rasterization());

  // Should only have the high-res tiling.
  EXPECT_EQ(1u, active_layer()->tilings()->num_tilings());

  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();

  // High res tiling should have 64 tiles (4x16 tile grid).
  EXPECT_EQ(64u, active_layer()->HighResTiling()->AllTilesForTesting().size());

  // Visible viewport should be covered by 4 tiles.  No other
  // tiles should be required for activation.
  EXPECT_EQ(4u, NumberOfTilesRequired(active_layer()->HighResTiling()));
}

TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) {
  // Set up layers with tilings.
  SetupDefaultTrees(gfx::Size(10, 10));
  SetContentsScaleOnBothLayers(1.f, 1.f, 1.f, 1.f, 0.f, false);
  pending_layer()->PushPropertiesTo(active_layer());
  EXPECT_TRUE(pending_layer()->DrawsContent());
  EXPECT_TRUE(pending_layer()->CanHaveTilings());
  EXPECT_GE(pending_layer()->num_tilings(), 0u);
  EXPECT_GE(active_layer()->num_tilings(), 0u);

  // Set content to false, which should make CanHaveTilings return false.
  pending_layer()->SetDrawsContent(false);
  EXPECT_FALSE(pending_layer()->DrawsContent());
  EXPECT_FALSE(pending_layer()->CanHaveTilings());

  // No tilings should be pushed to active layer.
  pending_layer()->PushPropertiesTo(active_layer());
  EXPECT_EQ(0u, active_layer()->num_tilings());
}

TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) {
  SetupDefaultTrees(gfx::Size(10, 10));

  // We start with a tiling at scale 1.
  EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale());

  // When we page scale up by 2.3, we get a new tiling that is a power of 2, in
  // this case 4.
  host_impl()->PinchGestureBegin();
  float high_res_scale = 2.3f;
  SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f,
                               false);
  EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale());
}

TEST_F(PictureLayerImplTest, PinchingTooSmall) {
  SetupDefaultTrees(gfx::Size(10, 10));

  // We start with a tiling at scale 1.
  EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale());

  host_impl()->PinchGestureBegin();
  float high_res_scale = 0.0001f;
  EXPECT_LT(high_res_scale, pending_layer()->MinimumContentsScale());

  SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f,
                               false);
  EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(),
                  pending_layer()->HighResTiling()->contents_scale());
}

TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) {
  SetupDefaultTrees(gfx::Size(10, 10));

  ResetTilingsAndRasterScales();

  float contents_scale = 0.15f;
  SetContentsScaleOnBothLayers(contents_scale, 1.f, 1.f, 1.f, 0.f, false);

  ASSERT_GE(pending_layer()->num_tilings(), 0u);
  EXPECT_FLOAT_EQ(contents_scale,
                  pending_layer()->HighResTiling()->contents_scale());

  host_impl()->PinchGestureBegin();

  float page_scale = 0.0001f;
  EXPECT_LT(page_scale * contents_scale,
            pending_layer()->MinimumContentsScale());

  SetContentsScaleOnBothLayers(contents_scale * page_scale, 1.f, page_scale,
                               1.f, 0.f, false);
  ASSERT_GE(pending_layer()->num_tilings(), 0u);
  EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(),
                  pending_layer()->HighResTiling()->contents_scale());
}

TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) {
  gfx::Size viewport_size(1000, 1000);
  host_impl()->SetViewportSize(viewport_size);

  gfx::Size layer_bounds(100, 100);
  SetupDefaultTrees(layer_bounds);

  float contents_scale = 2.f;
  float device_scale = 1.f;
  float page_scale = 1.f;
  float maximum_animation_scale = 3.f;
  float starting_animation_scale = 1.f;
  bool animating_transform = true;

  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);

  // Maximum animation scale is greater than starting animation scale
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);

  animating_transform = false;

  // Once we stop animating, a new high-res tiling should be created.
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);

  // Starting animation scale greater than maximum animation scale
  // Bounds at starting scale within the viewport
  animating_transform = true;
  starting_animation_scale = 5.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 5.f);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;
  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);

  // Starting Animation scale greater than maximum animation scale
  // Bounds at starting scale outisde the viewport
  animating_transform = true;
  starting_animation_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
}

TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) {
  gfx::Size viewport_size(1000, 1000);
  host_impl()->SetViewportSize(viewport_size);

  gfx::Size layer_bounds(100, 100);
  SetupDefaultTrees(layer_bounds);

  float contents_scale = 1.f;
  float device_scale = 1.f;
  float page_scale = 1.f;
  float maximum_animation_scale = 1.f;
  float starting_animation_scale = 0.f;
  bool animating_transform = false;

  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f);

  // Starting an animation should cause tiling resolution to get set to the
  // maximum animation scale factor.
  animating_transform = true;
  maximum_animation_scale = 3.f;
  contents_scale = 2.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);

  // Further changes to scale during the animation should not cause a new
  // high-res tiling to get created.
  contents_scale = 4.f;
  maximum_animation_scale = 5.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);

  // When animating with an unknown maximum animation scale factor, a new
  // high-res tiling should be created at a source scale of 1.
  animating_transform = true;
  contents_scale = 2.f;
  maximum_animation_scale = 0.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale);

  // Further changes to scale during the animation should not cause a new
  // high-res tiling to get created.
  contents_scale = 3.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;
  contents_scale = 4.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);

  // When animating with a maxmium animation scale factor that is so large
  // that the layer grows larger than the viewport at this scale, a new
  // high-res tiling should get created at a source scale of 1, not at its
  // maximum scale.
  animating_transform = true;
  contents_scale = 2.f;
  maximum_animation_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;
  contents_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 11.f);

  // When animating with a maxmium animation scale factor that is so large
  // that the layer grows larger than the viewport at this scale, and where
  // the intial source scale is < 1, a new high-res tiling should get created
  // at source scale 1.
  animating_transform = true;
  contents_scale = 0.1f;
  maximum_animation_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), device_scale * page_scale);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;
  contents_scale = 12.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 12.f);

  // When animating toward a smaller scale, but that is still so large that the
  // layer grows larger than the viewport at this scale, a new high-res tiling
  // should get created at source scale 1.
  animating_transform = true;
  contents_scale = 11.f;
  maximum_animation_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), device_scale * page_scale);

  // Once we stop animating, a new high-res tiling should be created.
  animating_transform = false;
  contents_scale = 11.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 11.f);
}

TEST_F(PictureLayerImplTest, TilingSetRasterQueue) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  host_impl()->SetViewportSize(gfx::Size(500, 500));

  gfx::Size layer_bounds(1000, 1000);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(pending_raster_source);
  EXPECT_EQ(1u, pending_layer()->num_tilings());

  std::set<Tile*> unique_tiles;
  bool reached_prepaint = false;
  int non_ideal_tile_count = 0u;
  int low_res_tile_count = 0u;
  int high_res_tile_count = 0u;
  int high_res_now_tiles = 0u;
  std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    TilePriority priority = prioritized_tile.priority();

    EXPECT_TRUE(prioritized_tile.tile());

    // Non-high res tiles only get visible tiles. Also, prepaint should only
    // come at the end of the iteration.
    if (priority.resolution != HIGH_RESOLUTION) {
      EXPECT_EQ(TilePriority::NOW, priority.priority_bin);
    } else if (reached_prepaint) {
      EXPECT_NE(TilePriority::NOW, priority.priority_bin);
    } else {
      reached_prepaint = priority.priority_bin != TilePriority::NOW;
      if (!reached_prepaint)
        ++high_res_now_tiles;
    }

    non_ideal_tile_count += priority.resolution == NON_IDEAL_RESOLUTION;
    low_res_tile_count += priority.resolution == LOW_RESOLUTION;
    high_res_tile_count += priority.resolution == HIGH_RESOLUTION;

    unique_tiles.insert(prioritized_tile.tile());
    queue->Pop();
  }

  EXPECT_TRUE(reached_prepaint);
  EXPECT_EQ(0, non_ideal_tile_count);
  EXPECT_EQ(0, low_res_tile_count);

  // With layer size being 1000x1000 and default tile size 256x256, we expect to
  // see 4 now tiles out of 16 total high res tiles.
  EXPECT_EQ(16, high_res_tile_count);
  EXPECT_EQ(4, high_res_now_tiles);
  EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count,
            static_cast<int>(unique_tiles.size()));

  std::unique_ptr<TilingSetRasterQueueRequired> required_queue(
      new TilingSetRasterQueueRequired(
          pending_layer()->picture_layer_tiling_set(),
          RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW));
  EXPECT_TRUE(required_queue->IsEmpty());

  required_queue.reset(new TilingSetRasterQueueRequired(
      pending_layer()->picture_layer_tiling_set(),
      RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION));
  EXPECT_FALSE(required_queue->IsEmpty());
  int required_for_activation_count = 0;
  while (!required_queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = required_queue->Top();
    EXPECT_TRUE(prioritized_tile.tile()->required_for_activation());
    EXPECT_FALSE(prioritized_tile.tile()->draw_info().IsReadyToDraw());
    ++required_for_activation_count;
    required_queue->Pop();
  }

  // All of the high res tiles should be required for activation, since there is
  // no active twin.
  EXPECT_EQ(high_res_now_tiles, required_for_activation_count);

  // No NOW tiles.
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  pending_layer()->draw_properties().visible_layer_rect =
      gfx::Rect(1100, 1100, 500, 500);
  pending_layer()->UpdateTiles();

  unique_tiles.clear();
  high_res_tile_count = 0u;
  queue.reset(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    TilePriority priority = prioritized_tile.priority();

    EXPECT_TRUE(prioritized_tile.tile());

    // Non-high res tiles only get visible tiles.
    EXPECT_EQ(HIGH_RESOLUTION, priority.resolution);
    EXPECT_NE(TilePriority::NOW, priority.priority_bin);

    high_res_tile_count += priority.resolution == HIGH_RESOLUTION;

    unique_tiles.insert(prioritized_tile.tile());
    queue->Pop();
  }

  EXPECT_EQ(16, high_res_tile_count);
  EXPECT_EQ(high_res_tile_count, static_cast<int>(unique_tiles.size()));

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));

  pending_layer()->draw_properties().visible_layer_rect =
      gfx::Rect(0, 0, 500, 500);
  pending_layer()->UpdateTiles();

  std::vector<Tile*> high_res_tiles =
      pending_layer()->HighResTiling()->AllTilesForTesting();
  for (std::vector<Tile*>::iterator tile_it = high_res_tiles.begin();
       tile_it != high_res_tiles.end();
       ++tile_it) {
    Tile* tile = *tile_it;
    TileDrawInfo& draw_info = tile->draw_info();
    draw_info.SetSolidColorForTesting(SK_ColorRED);
  }

  queue.reset(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), true));
  EXPECT_TRUE(queue->IsEmpty());
}

TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  host_impl()->SetViewportSize(gfx::Size(500, 500));

  gfx::Size layer_bounds(1000, 1000);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTree(pending_raster_source);
  ActivateTree();
  EXPECT_EQ(2u, active_layer()->num_tilings());

  std::unique_ptr<TilingSetRasterQueueRequired> queue(
      new TilingSetRasterQueueRequired(
          active_layer()->picture_layer_tiling_set(),
          RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW));
  EXPECT_FALSE(queue->IsEmpty());
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    EXPECT_TRUE(prioritized_tile.tile()->required_for_draw());
    EXPECT_FALSE(prioritized_tile.tile()->draw_info().IsReadyToDraw());
    queue->Pop();
  }

  queue.reset(new TilingSetRasterQueueRequired(
      active_layer()->picture_layer_tiling_set(),
      RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION));
  EXPECT_TRUE(queue->IsEmpty());
}

TEST_F(PictureLayerImplTest, TilingSetRasterQueueRequiredNoHighRes) {
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilledSolidColor(gfx::Size(1024, 1024));

  SetupPendingTree(pending_raster_source);
  EXPECT_FALSE(
      pending_layer()->picture_layer_tiling_set()->FindTilingWithResolution(
          HIGH_RESOLUTION));

  std::unique_ptr<TilingSetRasterQueueRequired> queue(
      new TilingSetRasterQueueRequired(
          pending_layer()->picture_layer_tiling_set(),
          RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION));
  EXPECT_TRUE(queue->IsEmpty());
}

TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) {
  gfx::Size layer_bounds(1000, 1000);
  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;

  host_impl()->SetViewportSize(gfx::Size(500, 500));

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  // TODO(vmpstr): Add a test with tilings other than high res on the active
  // tree (crbug.com/519607).
  SetupPendingTree(pending_raster_source);
  EXPECT_EQ(1u, pending_layer()->num_tilings());

  std::vector<Tile*> all_tiles;
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end());
  }

  std::set<Tile*> all_tiles_set(all_tiles.begin(), all_tiles.end());

  bool mark_required = false;
  size_t number_of_marked_tiles = 0u;
  size_t number_of_unmarked_tiles = 0u;
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    for (PictureLayerTiling::CoverageIterator iter(
             tiling, 1.f, pending_layer()->visible_layer_rect());
         iter; ++iter) {
      if (mark_required) {
        number_of_marked_tiles++;
        iter->set_required_for_activation(true);
      } else {
        number_of_unmarked_tiles++;
      }
      mark_required = !mark_required;
    }
  }

  // Sanity checks.
  EXPECT_EQ(16u, all_tiles.size());
  EXPECT_EQ(16u, all_tiles_set.size());
  EXPECT_GT(number_of_marked_tiles, 1u);
  EXPECT_GT(number_of_unmarked_tiles, 1u);

  // Tiles don't have resources yet.
  std::unique_ptr<TilingSetEvictionQueue> queue(
      new TilingSetEvictionQueue(pending_layer()->picture_layer_tiling_set()));
  EXPECT_TRUE(queue->IsEmpty());

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      all_tiles);

  std::set<Tile*> unique_tiles;
  float expected_scales[] = {low_res_factor, 1.f};
  size_t scale_index = 0;
  bool reached_visible = false;
  PrioritizedTile last_tile;
  size_t distance_decreasing = 0;
  size_t distance_increasing = 0;
  queue.reset(
      new TilingSetEvictionQueue(pending_layer()->picture_layer_tiling_set()));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    Tile* tile = prioritized_tile.tile();
    if (!last_tile.tile())
      last_tile = prioritized_tile;

    EXPECT_TRUE(tile);

    TilePriority priority = prioritized_tile.priority();

    if (priority.priority_bin == TilePriority::NOW) {
      reached_visible = true;
      last_tile = prioritized_tile;
      break;
    }

    EXPECT_FALSE(tile->required_for_activation());

    while (std::abs(tile->contents_scale() - expected_scales[scale_index]) >
           std::numeric_limits<float>::epsilon()) {
      ++scale_index;
      ASSERT_LT(scale_index, arraysize(expected_scales));
    }

    EXPECT_FLOAT_EQ(tile->contents_scale(), expected_scales[scale_index]);
    unique_tiles.insert(tile);

    if (tile->required_for_activation() ==
            last_tile.tile()->required_for_activation() &&
        std::abs(tile->contents_scale() - last_tile.tile()->contents_scale()) <
            std::numeric_limits<float>::epsilon()) {
      if (priority.distance_to_visible <=
          last_tile.priority().distance_to_visible)
        ++distance_decreasing;
      else
        ++distance_increasing;
    }

    last_tile = prioritized_tile;
    queue->Pop();
  }

  // 4 high res tiles are inside the viewport, the rest are evicted.
  EXPECT_TRUE(reached_visible);
  EXPECT_EQ(12u, unique_tiles.size());
  EXPECT_EQ(1u, distance_increasing);
  EXPECT_EQ(11u, distance_decreasing);

  scale_index = 0;
  bool reached_required = false;
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    Tile* tile = prioritized_tile.tile();
    EXPECT_TRUE(tile);

    TilePriority priority = prioritized_tile.priority();
    EXPECT_EQ(TilePriority::NOW, priority.priority_bin);

    if (reached_required) {
      EXPECT_TRUE(tile->required_for_activation());
    } else if (tile->required_for_activation()) {
      reached_required = true;
      scale_index = 0;
    }

    while (std::abs(tile->contents_scale() - expected_scales[scale_index]) >
           std::numeric_limits<float>::epsilon()) {
      ++scale_index;
      ASSERT_LT(scale_index, arraysize(expected_scales));
    }

    EXPECT_FLOAT_EQ(tile->contents_scale(), expected_scales[scale_index]);
    unique_tiles.insert(tile);
    queue->Pop();
  }

  EXPECT_TRUE(reached_required);
  EXPECT_EQ(all_tiles_set.size(), unique_tiles.size());
}

TEST_F(PictureLayerImplTest, Occlusion) {
  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(1000, 1000);

  LayerTestCommon::LayerImplTest impl;
  host_impl()->SetViewportSize(viewport_size);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  std::vector<Tile*> tiles =
      active_layer()->HighResTiling()->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);

  {
    SCOPED_TRACE("No occlusion");
    gfx::Rect occluded;
    impl.AppendQuadsWithOcclusion(active_layer(), occluded);

    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
                                                 gfx::Rect(layer_bounds));
    EXPECT_EQ(100u, impl.quad_list().size());
  }

  {
    SCOPED_TRACE("Full occlusion");
    gfx::Rect occluded(active_layer()->visible_layer_rect());
    impl.AppendQuadsWithOcclusion(active_layer(), occluded);

    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
    EXPECT_EQ(impl.quad_list().size(), 0u);
  }

  {
    SCOPED_TRACE("Partial occlusion");
    gfx::Rect occluded(150, 0, 200, 1000);
    impl.AppendQuadsWithOcclusion(active_layer(), occluded);

    size_t partially_occluded_count = 0;
    LayerTestCommon::VerifyQuadsAreOccluded(
        impl.quad_list(), occluded, &partially_occluded_count);
    // The layer outputs one quad, which is partially occluded.
    EXPECT_EQ(100u - 10u, impl.quad_list().size());
    EXPECT_EQ(10u + 10u, partially_occluded_count);
  }
}

TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) {
  gfx::Size tile_size(host_impl()->settings().default_tile_size);
  SetupDefaultTrees(tile_size);

  ResetTilingsAndRasterScales();

  float contents_scale = 2.f;
  float device_scale = 1.f;
  float page_scale = 1.f;
  float maximum_animation_scale = 1.f;
  float starting_animation_scale = 0.f;
  bool animating_transform = false;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);

  // Changing the source scale without being in an animation will cause
  // the layer to change scale.
  contents_scale = 3.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);

  contents_scale = 0.5f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f);

  // However, if the layer has a will-change property, then the raster scale
  // will get fixed at the last value.
  active_layer()->SetHasWillChangeTransformHint(true);
  pending_layer()->SetHasWillChangeTransformHint(true);

  contents_scale = 3.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f);

  // Further changes to the source scale will no longer be reflected in the
  // contents scale.
  contents_scale = 1.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f);

  // Disabling the will-change hint will once again make the raster scale update
  // with the ideal scale.
  active_layer()->SetHasWillChangeTransformHint(false);
  pending_layer()->SetHasWillChangeTransformHint(false);

  contents_scale = 3.f;

  SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale,
                               maximum_animation_scale,
                               starting_animation_scale, animating_transform);
  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f);
}

TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) {
  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(1000, 1000);

  // Make sure pending tree has tiles.
  gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);

  // All pending layer tiles required are not ready.
  EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());

  // Initialize all low-res tiles.
  EXPECT_FALSE(pending_layer()->LowResTiling());
  pending_layer()->SetAllTilesReadyInTiling(active_layer()->LowResTiling());

  // Low-res tiles should not be enough.
  EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());

  // Initialize remaining tiles.
  pending_layer()->SetAllTilesReady();
  active_layer()->SetAllTilesReady();

  EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}

TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) {
  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(1000, 1000);

  // Make sure pending tree has tiles.
  gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);

  // All pending layer tiles required are not ready.
  EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());

  // Initialize all high-res tiles.
  pending_layer()->SetAllTilesReadyInTiling(pending_layer()->HighResTiling());
  active_layer()->SetAllTilesReadyInTiling(active_layer()->HighResTiling());

  // High-res tiles should be enough, since they cover everything visible.
  EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}

TEST_F(PictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) {
  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(1000, 1000);

  // Make sure pending tree has tiles.
  gfx::Rect invalidation(gfx::Point(50, 50), tile_size);
  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, invalidation);

  // Initialize all high-res tiles in the active layer.
  active_layer()->SetAllTilesReadyInTiling(active_layer()->HighResTiling());

  // The pending high-res tiles are not ready, so we cannot activate.
  EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());

  // When the pending high-res tiles are ready, we can activate.
  pending_layer()->SetAllTilesReadyInTiling(pending_layer()->HighResTiling());
  EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}

TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  ResetTilingsAndRasterScales();

  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    6.f,  // ideal contents scale
                                    3.f,  // device scale
                                    2.f,  // page scale
                                    1.f,  // maximum animation scale
                                    0.f,  // starting animation scale
                                    false);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the page scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    6.6f,  // ideal contents scale
                                    3.f,   // device scale
                                    2.2f,  // page scale
                                    1.f,   // maximum animation scale
                                    0.f,   // starting animation scale
                                    false);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.6f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    7.26f,  // ideal contents scale
                                    3.3f,   // device scale
                                    2.2f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, but end up at the same total scale
  // factor somehow, then we don't get new tilings.
  SetupDrawPropertiesAndUpdateTiles(active_layer(),
                                    7.26f,  // ideal contents scale
                                    2.2f,   // device scale
                                    3.3f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(3u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  active_layer()->tilings()->tiling_at(0)->contents_scale());
}

TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  ResetTilingsAndRasterScales();

  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    6.f,  // ideal contents scale
                                    3.f,  // device scale
                                    2.f,  // page scale
                                    1.f,  // maximum animation scale
                                    0.f,  // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the page scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    6.6f,  // ideal contents scale
                                    3.f,   // device scale
                                    2.2f,  // page scale
                                    1.f,   // maximum animation scale
                                    0.f,   // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(6.6f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, then we should get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    7.26f,  // ideal contents scale
                                    3.3f,   // device scale
                                    2.2f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());

  // If we change the device scale factor, but end up at the same total scale
  // factor somehow, then we don't get new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    7.26f,  // ideal contents scale
                                    2.2f,   // device scale
                                    3.3f,   // page scale
                                    1.f,    // maximum animation scale
                                    0.f,    // starting animation scale
                                    false);
  ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(7.26f,
                  pending_layer()->tilings()->tiling_at(0)->contents_scale());
}

TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region());

  Tile* some_active_tile =
      active_layer()->HighResTiling()->AllTilesForTesting()[0];
  EXPECT_FALSE(some_active_tile->draw_info().IsReadyToDraw());

  // Since there is no invalidation, pending tree should have no tiles.
  EXPECT_TRUE(pending_layer()->HighResTiling()->AllTilesForTesting().empty());
  if (host_impl()->settings().create_low_res_tiling)
    EXPECT_TRUE(pending_layer()->LowResTiling()->AllTilesForTesting().empty());

  active_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  if (host_impl()->settings().create_low_res_tiling)
    active_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  AssertAllTilesRequired(active_layer()->HighResTiling());
  if (host_impl()->settings().create_low_res_tiling)
    AssertNoTilesRequired(active_layer()->LowResTiling());
}

TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
  gfx::Size layer_bounds(400, 400);
  gfx::Size tile_size(100, 100);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  // This raster source will create tilings, but has no recordings so will not
  // create any tiles.  This is attempting to simulate scrolling past the end of
  // recorded content on the active layer, where the recordings are so far away
  // that no tiles are created.
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds, gfx::Rect());

  SetupTreesWithFixedTileSize(pending_raster_source, active_raster_source,
                              tile_size, Region());

  // Active layer has tilings, but no tiles due to missing recordings.
  EXPECT_TRUE(active_layer()->CanHaveTilings());
  EXPECT_EQ(active_layer()->tilings()->num_tilings(),
            host_impl()->settings().create_low_res_tiling ? 2u : 1u);
  EXPECT_EQ(active_layer()->HighResTiling()->AllTilesForTesting().size(), 0u);

  // Since the active layer has no tiles at all, the pending layer doesn't
  // need content in order to activate.
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();
  if (host_impl()->settings().create_low_res_tiling)
    pending_layer()->LowResTiling()->UpdateAllRequiredStateForTesting();

  AssertNoTilesRequired(pending_layer()->HighResTiling());
  if (host_impl()->settings().create_low_res_tiling)
    AssertNoTilesRequired(pending_layer()->LowResTiling());
}

TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) {
  gfx::Size layer_bounds(1300, 1900);
  std::vector<PictureLayerTiling*> used_tilings;
  SetupDefaultTrees(layer_bounds);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  EXPECT_LT(low_res_factor, 1.f);

  float device_scale = 1.7f;
  float page_scale = 3.2f;
  float scale = 1.f;

  active_layer()->SetHasWillChangeTransformHint(true);
  ResetTilingsAndRasterScales();

  SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, 0.f,
                               false);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());

  // Ensure UpdateTiles won't remove any tilings. Note this is unrelated to
  // |used_tilings| variable, and it's here only to ensure that active_layer()
  // won't remove tilings before the test has a chance to verify behavior.
  active_layer()->MarkAllTilingsUsed();

  // We only have ideal tilings, so they aren't removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());

  host_impl()->PinchGestureBegin();

  // Changing the ideal but not creating new tilings.
  scale *= 1.5f;
  page_scale *= 1.5f;
  SetContentsScaleOnBothLayers(scale, device_scale, page_scale, 1.f, 0.f,
                               false);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());

  // The tilings are still our target scale, so they aren't removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());

  host_impl()->PinchGestureEnd();

  // Create a 1.2 scale tiling. Now we have 1.0 and 1.2 tilings. Ideal = 1.2.
  scale /= 4.f;
  page_scale /= 4.f;
  SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, 0.f, false);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_FLOAT_EQ(1.f,
                  active_layer()->tilings()->tiling_at(1)->contents_scale());

  // Ensure UpdateTiles won't remove any tilings.
  active_layer()->MarkAllTilingsUsed();

  // Mark the non-ideal tilings as used. They won't be removed.
  used_tilings.clear();
  used_tilings.push_back(active_layer()->tilings()->tiling_at(1));
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());

  // Now move the ideal scale to 0.5. Our target stays 1.2.
  SetContentsScaleOnBothLayers(0.5f, device_scale, page_scale, 1.f, 0.f, false);

  // The high resolution tiling is between target and ideal, so is not
  // removed.  The low res tiling for the old ideal=1.0 scale is removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());

  // Now move the ideal scale to 1.0. Our target stays 1.2.
  SetContentsScaleOnBothLayers(1.f, device_scale, page_scale, 1.f, 0.f, false);

  // All the tilings are between are target and the ideal, so they are not
  // removed.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());

  // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2.
  SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.1f, device_scale,
                                    page_scale, 1.f, 0.f, false);

  // Because the pending layer's ideal scale is still 1.0, our tilings fall
  // in the range [1.0,1.2] and are kept.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());

  // Move the ideal scale on the pending layer to 1.1 as well. Our target stays
  // 1.2 still.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.1f, device_scale,
                                    page_scale, 1.f, 0.f, false);

  // Our 1.0 tiling now falls outside the range between our ideal scale and our
  // target raster scale. But it is in our used tilings set, so nothing is
  // deleted.
  used_tilings.clear();
  used_tilings.push_back(active_layer()->tilings()->tiling_at(1));
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(2u, active_layer()->tilings()->num_tilings());

  // If we remove it from our used tilings set, it is outside the range to keep
  // so it is deleted.
  used_tilings.clear();
  active_layer()->CleanUpTilingsOnActiveLayer(used_tilings);
  ASSERT_EQ(1u, active_layer()->tilings()->num_tilings());
}

TEST_F(NoLowResPictureLayerImplTest, ReleaseTileResources) {
  gfx::Size layer_bounds(1300, 1900);
  SetupDefaultTrees(layer_bounds);
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
  EXPECT_EQ(1u, active_layer()->tilings()->num_tilings());

  // All tilings should be removed when losing output surface.
  active_layer()->ReleaseTileResources();
  EXPECT_FALSE(active_layer()->tilings());
  active_layer()->RecreateTileResources();
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  pending_layer()->ReleaseTileResources();
  EXPECT_FALSE(pending_layer()->tilings());
  pending_layer()->RecreateTileResources();
  EXPECT_EQ(0u, pending_layer()->tilings()->num_tilings());

  // This should create new tilings.
  SetupDrawPropertiesAndUpdateTiles(pending_layer(),
                                    1.3f,  // ideal contents scale
                                    2.7f,  // device scale
                                    3.2f,  // page scale
                                    1.f,   // maximum animation scale
                                    0.f,   // starting animation scale
                                    false);
  EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();

  gfx::Size layer_bounds(1000, 2000);
  host_impl()->SetViewportSize(gfx::Size(10000, 20000));
  SetupDefaultTrees(layer_bounds);

  ResetTilingsAndRasterScales();
  SetupDrawPropertiesAndUpdateTiles(active_layer(), 2.5f, 1.f, 1.f, 1.f, 0.f,
                                    false);

  float max_contents_scale = active_layer()->MaximumTilingContentsScale();
  EXPECT_EQ(2.5f, max_contents_scale);

  gfx::Transform scaled_draw_transform = active_layer()->DrawTransform();
  scaled_draw_transform.Scale(SK_MScalar1 / max_contents_scale,
                              SK_MScalar1 / max_contents_scale);

  AppendQuadsData data;
  active_layer()->AppendQuads(render_pass.get(), &data);

  // SharedQuadState should have be of size 1, as we are doing AppenQuad once.
  EXPECT_EQ(1u, render_pass->shared_quad_state_list.size());
  // The quad_to_target_transform should be scaled by the
  // MaximumTilingContentsScale on the layer.
  EXPECT_EQ(scaled_draw_transform.ToString(),
            render_pass->shared_quad_state_list.front()
                ->quad_to_target_transform.ToString());
  // The content_bounds should be scaled by the
  // MaximumTilingContentsScale on the layer.
  EXPECT_EQ(gfx::Size(2500u, 5000u).ToString(),
            render_pass->shared_quad_state_list.front()
                ->quad_layer_bounds.ToString());
  // The visible_layer_rect should be scaled by the
  // MaximumTilingContentsScale on the layer.
  EXPECT_EQ(gfx::Rect(0u, 0u, 2500u, 5000u).ToString(),
            render_pass->shared_quad_state_list.front()
                ->visible_quad_layer_rect.ToString());
}

class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
 public:
  std::unique_ptr<CompositorFrameSink> CreateCompositorFrameSink() override {
    return FakeCompositorFrameSink::Create3d();
  }
};

TEST_F(PictureLayerImplTestWithDelegatingRenderer,
       DelegatingRendererWithTileOOM) {
  // This test is added for crbug.com/402321, where quad should be produced when
  // raster on demand is not allowed and tile is OOM.
  gfx::Size layer_bounds(1000, 1000);

  // Create tiles.
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(pending_raster_source);
  pending_layer()->SetBounds(layer_bounds);
  ActivateTree();
  bool update_lcd_text = false;
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);
  std::vector<Tile*> tiles =
      active_layer()->HighResTiling()->AllTilesForTesting();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);

  // Force tiles after max_tiles to be OOM. TileManager uses
  // GlobalStateThatImpactsTilesPriority from LayerTreeHostImpl, and we cannot
  // directly set state to host_impl_, so we set policy that would change the
  // state. We also need to update tree priority separately.
  GlobalStateThatImpactsTilePriority state;
  size_t max_tiles = 1;
  gfx::Size tile_size(host_impl()->settings().default_tile_size);
  size_t memory_limit = max_tiles * 4 * tile_size.width() * tile_size.height();
  size_t resource_limit = max_tiles;
  ManagedMemoryPolicy policy(memory_limit,
                             gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
                             resource_limit);
  host_impl()->SetMemoryPolicy(policy);
  host_impl()->SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
  host_impl()->PrepareTiles();

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_HARDWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  // Even when OOM, quads should be produced, and should be different material
  // from quads with resource.
  EXPECT_LT(max_tiles, render_pass->quad_list.size());
  EXPECT_EQ(DrawQuad::Material::TILED_CONTENT,
            render_pass->quad_list.front()->material);
  EXPECT_EQ(DrawQuad::Material::SOLID_COLOR,
            render_pass->quad_list.back()->material);
}

class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest {
 public:
  LayerTreeSettings CreateSettings() override {
    LayerTreeSettings settings = PictureLayerImplTest::CreateSettings();
    settings.use_occlusion_for_tile_prioritization = true;
    return settings;
  }

  void VerifyEvictionConsidersOcclusion(FakePictureLayerImpl* layer,
                                        WhichTree tree,
                                        size_t expected_occluded_tile_count,
                                        int source_line) {
    size_t occluded_tile_count = 0u;
    PrioritizedTile last_tile;

    std::unique_ptr<TilingSetEvictionQueue> queue(
        new TilingSetEvictionQueue(layer->picture_layer_tiling_set()));
    while (!queue->IsEmpty()) {
      PrioritizedTile prioritized_tile = queue->Top();
      Tile* tile = prioritized_tile.tile();
      if (!last_tile.tile())
        last_tile = prioritized_tile;

      // The only way we will encounter an occluded tile after an unoccluded
      // tile is if the priorty bin decreased, the tile is required for
      // activation, or the scale changed.
      bool tile_is_occluded = prioritized_tile.is_occluded();
      if (tile_is_occluded) {
        occluded_tile_count++;

        bool last_tile_is_occluded = last_tile.is_occluded();
        if (!last_tile_is_occluded) {
          TilePriority::PriorityBin tile_priority_bin =
              prioritized_tile.priority().priority_bin;
          TilePriority::PriorityBin last_tile_priority_bin =
              last_tile.priority().priority_bin;

          EXPECT_TRUE(tile_priority_bin < last_tile_priority_bin ||
                      tile->required_for_activation() ||
                      tile->contents_scale() !=
                          last_tile.tile()->contents_scale())
              << "line: " << source_line;
        }
      }
      last_tile = prioritized_tile;
      queue->Pop();
    }
    EXPECT_EQ(expected_occluded_tile_count, occluded_tile_count)
        << "line: " << source_line;
  }
};

TEST_F(OcclusionTrackingPictureLayerImplTest,
       OccludedTilesSkippedDuringRasterization) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(500, 500);
  gfx::PointF occluding_layer_position(310.f, 0.f);

  host_impl()->SetViewportSize(viewport_size);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());

  // No occlusion.
  int unoccluded_tile_count = 0;
  std::unique_ptr<TilingSetRasterQueueAll> queue(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    Tile* tile = prioritized_tile.tile();

    // Occluded tiles should not be iterated over.
    EXPECT_FALSE(prioritized_tile.is_occluded());

    // Some tiles may not be visible (i.e. outside the viewport). The rest are
    // visible and at least partially unoccluded, verified by the above expect.
    bool tile_is_visible =
        tile->content_rect().Intersects(pending_layer()->visible_layer_rect());
    if (tile_is_visible)
      unoccluded_tile_count++;
    queue->Pop();
  }
  EXPECT_EQ(unoccluded_tile_count, 25);

  // Partial occlusion.
  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 1));
  LayerImpl* layer1 = pending_layer()->test_properties()->children[0];
  layer1->SetBounds(layer_bounds);
  layer1->SetDrawsContent(true);
  layer1->SetContentsOpaque(true);
  layer1->SetPosition(occluding_layer_position);

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  unoccluded_tile_count = 0;
  queue.reset(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    Tile* tile = prioritized_tile.tile();

    EXPECT_FALSE(prioritized_tile.is_occluded());

    bool tile_is_visible =
        tile->content_rect().Intersects(pending_layer()->visible_layer_rect());
    if (tile_is_visible)
      unoccluded_tile_count++;
    queue->Pop();
  }
  EXPECT_EQ(20, unoccluded_tile_count);

  // Full occlusion.
  layer1->SetPosition(gfx::PointF());
  layer1->NoteLayerPropertyChanged();

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  unoccluded_tile_count = 0;
  queue.reset(new TilingSetRasterQueueAll(
      pending_layer()->picture_layer_tiling_set(), false));
  while (!queue->IsEmpty()) {
    PrioritizedTile prioritized_tile = queue->Top();
    Tile* tile = prioritized_tile.tile();

    EXPECT_FALSE(prioritized_tile.is_occluded());

    bool tile_is_visible =
        tile->content_rect().Intersects(pending_layer()->visible_layer_rect());
    if (tile_is_visible)
      unoccluded_tile_count++;
    queue->Pop();
  }
  EXPECT_EQ(unoccluded_tile_count, 0);
}

TEST_F(OcclusionTrackingPictureLayerImplTest,
       OccludedTilesNotMarkedAsRequired) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(500, 500);
  gfx::PointF occluding_layer_position(310.f, 0.f);

  host_impl()->SetViewportSize(viewport_size);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());

  // No occlusion.
  int occluded_tile_count = 0;
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    occluded_tile_count = 0;
    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
                                                   gfx::Rect(layer_bounds));
         iter; ++iter) {
      if (!*iter)
        continue;
      const Tile* tile = *iter;

      // Fully occluded tiles are not required for activation.
      if (prioritized_tiles[tile].is_occluded()) {
        EXPECT_FALSE(tile->required_for_activation());
        occluded_tile_count++;
      }
    }
    EXPECT_EQ(occluded_tile_count, 0);
  }

  // Partial occlusion.
  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 1));
  LayerImpl* layer1 = pending_layer()->test_properties()->children[0];
  layer1->SetBounds(layer_bounds);
  layer1->SetDrawsContent(true);
  layer1->SetContentsOpaque(true);
  layer1->SetPosition(occluding_layer_position);

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    occluded_tile_count = 0;
    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
                                                   gfx::Rect(layer_bounds));
         iter; ++iter) {
      if (!*iter)
        continue;
      const Tile* tile = *iter;

      if (prioritized_tiles[tile].is_occluded()) {
        EXPECT_FALSE(tile->required_for_activation());
        occluded_tile_count++;
      }
    }
    switch (i) {
      case 0:
        EXPECT_EQ(occluded_tile_count, 5);
        break;
      case 1:
        EXPECT_EQ(occluded_tile_count, 2);
        break;
      default:
        NOTREACHED();
    }
  }

  // Full occlusion.
  layer1->SetPosition(gfx::PointF());
  layer1->NoteLayerPropertyChanged();

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200));
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    occluded_tile_count = 0;
    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
                                                   gfx::Rect(layer_bounds));
         iter; ++iter) {
      if (!*iter)
        continue;
      const Tile* tile = *iter;

      if (prioritized_tiles[tile].is_occluded()) {
        EXPECT_FALSE(tile->required_for_activation());
        occluded_tile_count++;
      }
    }
    switch (i) {
      case 0:
        EXPECT_EQ(25, occluded_tile_count);
        break;
      case 1:
        EXPECT_EQ(4, occluded_tile_count);
        break;
      default:
        NOTREACHED();
    }
  }
}

TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(500, 500);
  gfx::PointF occluding_layer_position(310.f, 0.f);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->SetViewportSize(viewport_size);

  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ASSERT_TRUE(pending_layer()->CanHaveTilings());

  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 1));
  LayerImpl* layer1 = pending_layer()->test_properties()->children[0];
  layer1->SetBounds(layer_bounds);
  layer1->SetDrawsContent(true);
  layer1->SetContentsOpaque(true);
  layer1->SetPosition(occluding_layer_position);

  pending_layer()->tilings()->RemoveAllTilings();
  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  pending_layer()->AddTiling(low_res_factor)->set_resolution(LOW_RESOLUTION);
  pending_layer()->AddTiling(0.3f)->set_resolution(HIGH_RESOLUTION);
  pending_layer()->AddTiling(0.7f)->set_resolution(HIGH_RESOLUTION);
  pending_layer()->AddTiling(1.0f)->set_resolution(HIGH_RESOLUTION);
  pending_layer()->AddTiling(2.0f)->set_resolution(HIGH_RESOLUTION);

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  // UpdateDrawProperties with the occluding layer.
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  EXPECT_EQ(5u, pending_layer()->num_tilings());

  int occluded_tile_count = 0;
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();

    occluded_tile_count = 0;
    for (size_t j = 0; j < tiles.size(); ++j) {
      if (prioritized_tiles[tiles[j]].is_occluded()) {
        gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
            tiles[j]->content_rect(), 1.f / tiles[j]->contents_scale());
        EXPECT_GE(scaled_content_rect.x(), occluding_layer_position.x());
        occluded_tile_count++;
      }
    }

    switch (i) {
      case 0:
        EXPECT_EQ(occluded_tile_count, 30);
        break;
      case 1:
        EXPECT_EQ(occluded_tile_count, 5);
        break;
      case 2:
        EXPECT_EQ(occluded_tile_count, 4);
        break;
      case 4:
      case 3:
        EXPECT_EQ(occluded_tile_count, 2);
        break;
      default:
        NOTREACHED();
    }
  }
}

TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(1000, 1000);
  gfx::PointF occluding_layer_position(310.f, 0.f);
  gfx::Rect invalidation_rect(230, 230, 102, 102);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->SetViewportSize(viewport_size);
  SetupPendingTree(active_raster_source);

  // Partially occlude the active layer.
  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 2));
  LayerImpl* layer1 = pending_layer()->test_properties()->children[0];
  layer1->SetBounds(layer_bounds);
  layer1->SetDrawsContent(true);
  layer1->SetContentsOpaque(true);
  layer1->SetPosition(occluding_layer_position);

  ActivateTree();

  for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
                                                   gfx::Rect(layer_bounds));
         iter; ++iter) {
      if (!*iter)
        continue;
      const Tile* tile = *iter;

      gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
          tile->content_rect(), 1.f / tile->contents_scale());
      // Tiles are occluded on the active tree iff they lie beneath the
      // occluding layer.
      EXPECT_EQ(prioritized_tiles[tile].is_occluded(),
                scaled_content_rect.x() >= occluding_layer_position.x());
    }
  }

  // Partially invalidate the pending layer.
  SetupPendingTreeWithInvalidation(pending_raster_source, invalidation_rect);

  for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    for (PictureLayerTiling::CoverageIterator iter(tiling, 1.f,
                                                   gfx::Rect(layer_bounds));
         iter; ++iter) {
      if (!*iter)
        continue;
      const Tile* tile = *iter;
      EXPECT_TRUE(tile);

      // All tiles are unoccluded, because the pending tree has no occlusion.
      EXPECT_FALSE(prioritized_tiles[tile].is_occluded());

      if (tiling->resolution() == LOW_RESOLUTION) {
        EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinTiling(tiling));
        continue;
      }

      Tile* twin_tile =
          active_layer()->GetPendingOrActiveTwinTiling(tiling)->TileAt(
              iter.i(), iter.j());
      gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
          tile->content_rect(), 1.f / tile->contents_scale());

      if (scaled_content_rect.Intersects(invalidation_rect)) {
        // Tiles inside the invalidation rect exist on both trees.
        EXPECT_TRUE(twin_tile);
        EXPECT_NE(tile, twin_tile);
      } else {
        // Tiles outside the invalidation rect only exist on the active tree.
        EXPECT_FALSE(twin_tile);
      }
    }
  }
}

TEST_F(OcclusionTrackingPictureLayerImplTest,
       OccludedTilesConsideredDuringEviction) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(1000, 1000);
  gfx::PointF pending_occluding_layer_position(310.f, 0.f);
  gfx::PointF active_occluding_layer_position(0.f, 310.f);
  gfx::Rect invalidation_rect(230, 230, 152, 152);

  host_impl()->SetViewportSize(viewport_size);
  SetInitialDeviceScaleFactor(2.f);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTreeWithFixedTileSize(active_raster_source, tile_size, Region());

  // Partially occlude the active layer.
  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 2));
  LayerImpl* active_occluding_layer =
      pending_layer()->test_properties()->children[0];
  active_occluding_layer->SetBounds(layer_bounds);
  active_occluding_layer->SetDrawsContent(true);
  active_occluding_layer->SetContentsOpaque(true);
  active_occluding_layer->SetPosition(active_occluding_layer_position);

  ActivateTree();

  // Partially invalidate the pending layer. Tiles inside the invalidation rect
  // are created.
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size,
                                    invalidation_rect);

  // Partially occlude the pending layer in a different way.
  pending_layer()->test_properties()->AddChild(
      LayerImpl::Create(host_impl()->pending_tree(), 3));
  LayerImpl* pending_occluding_layer =
      pending_layer()->test_properties()->children[0];
  pending_occluding_layer->SetBounds(layer_bounds);
  pending_occluding_layer->SetDrawsContent(true);
  pending_occluding_layer->SetContentsOpaque(true);
  pending_occluding_layer->SetPosition(pending_occluding_layer_position);

  EXPECT_EQ(1u, pending_layer()->num_tilings());
  EXPECT_EQ(2u, active_layer()->num_tilings());

  RebuildPropertyTreesOnPendingTree();
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
  // UpdateDrawProperties with the occluding layer.
  bool update_lcd_text = false;
  host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text);

  float dest_scale = std::max(active_layer()->MaximumTilingContentsScale(),
                              pending_layer()->MaximumTilingContentsScale());
  gfx::Rect dest_layer_bounds =
      gfx::ScaleToEnclosingRect(gfx::Rect(layer_bounds), dest_scale);
  gfx::Rect dest_invalidation_rect =
      gfx::ScaleToEnclosingRect(invalidation_rect, dest_scale);

  // The expected number of occluded tiles on each of the 2 tilings for each of
  // the 3 tree priorities.
  size_t expected_occluded_tile_count_on_pending[] = {4u, 0u};
  size_t expected_occluded_tile_count_on_active[] = {12u, 3u};
  size_t total_expected_occluded_tile_count_on_trees[] = {15u, 4u};

  // Verify number of occluded tiles on the pending layer for each tiling.
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    size_t occluded_tile_count_on_pending = 0u;
    for (PictureLayerTiling::CoverageIterator iter(tiling, dest_scale,
                                                   dest_layer_bounds);
         iter; ++iter) {
      Tile* tile = *iter;

      if (dest_invalidation_rect.Intersects(iter.geometry_rect()))
        EXPECT_TRUE(tile);
      else
        EXPECT_FALSE(tile);

      if (!tile)
        continue;
      if (prioritized_tiles[tile].is_occluded())
        occluded_tile_count_on_pending++;
    }
    EXPECT_EQ(expected_occluded_tile_count_on_pending[i],
              occluded_tile_count_on_pending)
        << tiling->contents_scale();
  }

  // Verify number of occluded tiles on the active layer for each tiling.
  for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
    auto prioritized_tiles =
        tiling->UpdateAndGetAllPrioritizedTilesForTesting();

    size_t occluded_tile_count_on_active = 0u;
    for (PictureLayerTiling::CoverageIterator iter(tiling, dest_scale,
                                                   dest_layer_bounds);
         iter; ++iter) {
      Tile* tile = *iter;

      if (!tile)
        continue;
      if (prioritized_tiles[tile].is_occluded())
        occluded_tile_count_on_active++;
    }
    EXPECT_EQ(expected_occluded_tile_count_on_active[i],
              occluded_tile_count_on_active)
        << i;
  }

  std::vector<Tile*> all_tiles;
  for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i);
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end());
  }
  for (size_t i = 0; i < active_layer()->num_tilings(); ++i) {
    PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i);
    std::vector<Tile*> tiles = tiling->AllTilesForTesting();
    all_tiles.insert(all_tiles.end(), tiles.begin(), tiles.end());
  }

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      all_tiles);

  VerifyEvictionConsidersOcclusion(
      pending_layer(), PENDING_TREE,
      total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__);
  VerifyEvictionConsidersOcclusion(
      active_layer(), ACTIVE_TREE,
      total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__);

  // Repeat the tests without valid active tree priorities.
  active_layer()->set_has_valid_tile_priorities(false);
  VerifyEvictionConsidersOcclusion(
      pending_layer(), PENDING_TREE,
      total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__);
  VerifyEvictionConsidersOcclusion(
      active_layer(), ACTIVE_TREE,
      total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__);
  active_layer()->set_has_valid_tile_priorities(true);

  // Repeat the tests without valid pending tree priorities.
  pending_layer()->set_has_valid_tile_priorities(false);
  VerifyEvictionConsidersOcclusion(
      active_layer(), ACTIVE_TREE,
      total_expected_occluded_tile_count_on_trees[ACTIVE_TREE], __LINE__);
  VerifyEvictionConsidersOcclusion(
      pending_layer(), PENDING_TREE,
      total_expected_occluded_tile_count_on_trees[PENDING_TREE], __LINE__);
  pending_layer()->set_has_valid_tile_priorities(true);
}

TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) {
  gfx::Size layer_bounds(1000, 1000);

  scoped_refptr<FakeRasterSource> raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(raster_source);
  EXPECT_FALSE(pending_layer()->GetPendingOrActiveTwinLayer());

  ActivateTree();
  EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer());

  SetupPendingTree(raster_source);
  EXPECT_TRUE(pending_layer()->GetPendingOrActiveTwinLayer());
  EXPECT_TRUE(active_layer()->GetPendingOrActiveTwinLayer());
  EXPECT_EQ(pending_layer(), active_layer()->GetPendingOrActiveTwinLayer());
  EXPECT_EQ(active_layer(), pending_layer()->GetPendingOrActiveTwinLayer());

  ActivateTree();
  EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer());

  // Make an empty pending tree.
  host_impl()->CreatePendingTree();
  host_impl()->pending_tree()->DetachLayers();
  EXPECT_FALSE(active_layer()->GetPendingOrActiveTwinLayer());
}

void GetClientDataAndUpdateInvalidation(RecordingSource* recording_source,
                                        FakeContentLayerClient* client,
                                        Region invalidation,
                                        gfx::Size layer_bounds) {
  gfx::Rect new_recorded_viewport = client->PaintableRegion();
  scoped_refptr<DisplayItemList> display_list =
      client->PaintContentsToDisplayList(
          ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
  size_t painter_reported_memory_usage =
      client->GetApproximateUnsharedMemoryUsage();

  recording_source->UpdateAndExpandInvalidation(&invalidation, layer_bounds,
                                                new_recorded_viewport);
  recording_source->UpdateDisplayItemList(display_list,
                                          painter_reported_memory_usage);
}

void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);
  gfx::Rect layer_rect(layer_bounds);

  FakeContentLayerClient client;
  client.set_bounds(layer_bounds);
  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
  FakeLayerTreeHostClient host_client;
  TestTaskGraphRunner task_graph_runner;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
      &host_client, &task_graph_runner, animation_host.get());
  host->SetRootLayer(layer);
  RecordingSource* recording_source = layer->GetRecordingSourceForTesting();

  client.set_fill_with_nonsolid_color(!test_for_solid);

  Region invalidation(layer_rect);

  GetClientDataAndUpdateInvalidation(recording_source, &client, invalidation,
                                     layer_bounds);

  scoped_refptr<RasterSource> pending_raster_source =
      recording_source->CreateRasterSource(true);

  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());
  ActivateTree();

  if (test_for_solid) {
    EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
  } else {
    ASSERT_TRUE(active_layer()->tilings());
    ASSERT_GT(active_layer()->tilings()->num_tilings(), 0u);
    std::vector<Tile*> tiles =
        active_layer()->tilings()->tiling_at(0)->AllTilesForTesting();
    EXPECT_FALSE(tiles.empty());
    host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
  }

  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer()->AppendQuads(render_pass.get(), &data);
  active_layer()->DidDraw(nullptr);

  DrawQuad::Material expected = test_for_solid
                                    ? DrawQuad::Material::SOLID_COLOR
                                    : DrawQuad::Material::TILED_CONTENT;
  EXPECT_EQ(expected, render_pass->quad_list.front()->material);
}

TEST_F(PictureLayerImplTest, DrawSolidQuads) {
  TestQuadsForSolidColor(true);
}

TEST_F(PictureLayerImplTest, DrawNonSolidQuads) {
  TestQuadsForSolidColor(false);
}

TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(200, 200);
  gfx::Rect layer_rect(layer_bounds);

  FakeContentLayerClient client;
  client.set_bounds(layer_bounds);
  scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client);
  FakeLayerTreeHostClient host_client;
  TestTaskGraphRunner task_graph_runner;
  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
      &host_client, &task_graph_runner, animation_host.get());
  host->SetRootLayer(layer);
  RecordingSource* recording_source = layer->GetRecordingSourceForTesting();

  client.set_fill_with_nonsolid_color(true);

  recording_source->SetNeedsDisplayRect(layer_rect);
  Region invalidation1;

  GetClientDataAndUpdateInvalidation(recording_source, &client, invalidation1,
                                     layer_bounds);

  scoped_refptr<RasterSource> raster_source1 =
      recording_source->CreateRasterSource(true);

  SetupPendingTree(raster_source1);
  ActivateTree();
  bool update_lcd_text = false;
  host_impl()->active_tree()->UpdateDrawProperties(update_lcd_text);

  // We've started with a solid layer that contains some tilings.
  ASSERT_TRUE(active_layer()->tilings());
  EXPECT_NE(0u, active_layer()->tilings()->num_tilings());

  client.set_fill_with_nonsolid_color(false);

  recording_source->SetNeedsDisplayRect(layer_rect);
  Region invalidation2;

  GetClientDataAndUpdateInvalidation(recording_source, &client, invalidation2,
                                     layer_bounds);

  scoped_refptr<RasterSource> raster_source2 =
      recording_source->CreateRasterSource(true);

  SetupPendingTree(raster_source2);
  ActivateTree();

  // We've switched to a solid color, so we should end up with no tilings.
  ASSERT_TRUE(active_layer()->tilings());
  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
}

TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size layer_bounds(400, 4000);
  SetupDefaultTrees(layer_bounds);

  Region invalidation;
  gfx::Rect viewport = gfx::Rect(0, 0, 100, 100);
  gfx::Transform transform;

  host_impl()->SetRequiresHighResToDraw();

  // Update tiles.
  pending_layer()->draw_properties().visible_layer_rect = viewport;
  pending_layer()->draw_properties().screen_space_transform = transform;
  SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();

  // Ensure we can't activate.
  EXPECT_FALSE(host_impl()->tile_manager()->IsReadyToActivate());

  // Now in the same frame, move the viewport (this can happen during
  // animation).
  viewport = gfx::Rect(0, 2000, 100, 100);

  // Update tiles.
  pending_layer()->draw_properties().visible_layer_rect = viewport;
  pending_layer()->draw_properties().screen_space_transform = transform;
  SetupDrawPropertiesAndUpdateTiles(pending_layer(), 1.f, 1.f, 1.f, 1.f, 0.f,
                                    false);
  pending_layer()->HighResTiling()->UpdateAllRequiredStateForTesting();

  // Make sure all viewport tiles (viewport from the tiling) are ready to draw.
  std::vector<Tile*> tiles;
  for (PictureLayerTiling::CoverageIterator iter(
           pending_layer()->HighResTiling(), 1.f,
           pending_layer()->HighResTiling()->GetCurrentVisibleRectForTesting());
       iter; ++iter) {
    if (*iter)
      tiles.push_back(*iter);
  }
  for (PictureLayerTiling::CoverageIterator iter(
           active_layer()->HighResTiling(), 1.f,
           active_layer()->HighResTiling()->GetCurrentVisibleRectForTesting());
       iter; ++iter) {
    if (*iter)
      tiles.push_back(*iter);
  }

  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles);

  // Ensure we can activate.
  EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate());
}

TEST_F(PictureLayerImplTest, CloneMissingRecordings) {
  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(400, 400);

  scoped_refptr<FakeRasterSource> filled_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  scoped_refptr<FakeRasterSource> partial_raster_source =
      FakeRasterSource::CreatePartiallyFilled(layer_bounds,
                                              gfx::Rect(100, 100, 300, 300));

  SetupPendingTreeWithFixedTileSize(filled_raster_source, tile_size, Region());
  ActivateTree();

  PictureLayerTiling* pending_tiling = old_pending_layer()->HighResTiling();
  PictureLayerTiling* active_tiling = active_layer()->HighResTiling();

  // We should have all tiles on active, and none on pending.
  EXPECT_EQ(0u, pending_tiling->AllTilesForTesting().size());
  EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());

  // Now put a partially-recorded raster source on the pending tree (and
  // invalidate everything, since the main thread recording will invalidate
  // dropped recordings). This will cause us to be missing some tiles.
  SetupPendingTreeWithFixedTileSize(partial_raster_source, tile_size,
                                    Region(gfx::Rect(layer_bounds)));
  EXPECT_EQ(3u * 3u, pending_tiling->AllTilesForTesting().size());
  EXPECT_FALSE(pending_tiling->TileAt(0, 0));
  EXPECT_FALSE(pending_tiling->TileAt(1, 1));
  EXPECT_TRUE(pending_tiling->TileAt(2, 2));

  // Active is not affected yet.
  EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());

  // Activate the tree. The same tiles go missing on the active tree.
  ActivateTree();
  EXPECT_EQ(3u * 3u, active_tiling->AllTilesForTesting().size());
  EXPECT_FALSE(active_tiling->TileAt(0, 0));
  EXPECT_FALSE(active_tiling->TileAt(1, 1));
  EXPECT_TRUE(active_tiling->TileAt(2, 2));

  // Now put a full recording on the pending tree again. We'll get all our tiles
  // back.
  SetupPendingTreeWithFixedTileSize(filled_raster_source, tile_size,
                                    Region(gfx::Rect(layer_bounds)));
  EXPECT_EQ(5u * 5u, pending_tiling->AllTilesForTesting().size());
  Tile::Id tile00 = pending_tiling->TileAt(0, 0)->id();
  Tile::Id tile11 = pending_tiling->TileAt(1, 1)->id();
  Tile::Id tile22 = pending_tiling->TileAt(2, 2)->id();

  // Active is not affected yet.
  EXPECT_EQ(3u * 3u, active_tiling->AllTilesForTesting().size());

  // Activate the tree. The tiles are moved to the active tree.
  ActivateTree();
  EXPECT_EQ(5u * 5u, active_tiling->AllTilesForTesting().size());
  EXPECT_EQ(tile00, active_tiling->TileAt(0, 0)->id());
  EXPECT_EQ(tile11, active_tiling->TileAt(1, 1)->id());
  EXPECT_EQ(tile22, active_tiling->TileAt(2, 2)->id());
}

TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(100, 100);
  gfx::Size viewport_size(100, 100);

  host_impl()->SetViewportSize(viewport_size);
  SetInitialDeviceScaleFactor(1.f);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  scoped_refptr<FakeRasterSource> active_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  SetupPendingTreeWithFixedTileSize(active_raster_source, tile_size, Region());

  ActivateTree();
  EXPECT_TRUE(active_layer()->HighResTiling()->has_tiles());

  host_impl()->SetExternalTilePriorityConstraints(gfx::Rect(0, 5000, 100, 100),
                                                  gfx::Transform());

  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size,
                                    gfx::Rect());

  EXPECT_FALSE(pending_layer()->HighResTiling()->has_tiles());
  EXPECT_TRUE(pending_layer()->HighResTiling()->live_tiles_rect().IsEmpty());
  ActivateTree();
  EXPECT_FALSE(active_layer()->HighResTiling()->has_tiles());
  EXPECT_TRUE(active_layer()->HighResTiling()->live_tiles_rect().IsEmpty());

  host_impl()->SetExternalTilePriorityConstraints(gfx::Rect(0, 110, 100, 100),
                                                  gfx::Transform());

  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size,
                                    gfx::Rect());

  EXPECT_FALSE(pending_layer()->HighResTiling()->has_tiles());
  EXPECT_FALSE(pending_layer()->HighResTiling()->live_tiles_rect().IsEmpty());
  ActivateTree();
  EXPECT_TRUE(active_layer()->HighResTiling()->has_tiles());
  EXPECT_FALSE(active_layer()->HighResTiling()->live_tiles_rect().IsEmpty());
}

TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(100, 100);

  host_impl()->SetViewportSize(viewport_size);
  SetInitialDeviceScaleFactor(1.f);

  SetupDefaultTrees(layer_bounds);

  active_layer()->SetCurrentScrollOffset(gfx::ScrollOffset(0.0, 50.0));
  host_impl()->active_tree()->UpdateDrawProperties(false);
  EXPECT_EQ("0,50 100x100", active_layer()
                                ->HighResTiling()
                                ->GetCurrentVisibleRectForTesting()
                                .ToString());

  EXPECT_EQ("0,0 100x100", pending_layer()
                               ->HighResTiling()
                               ->GetCurrentVisibleRectForTesting()
                               .ToString());
  host_impl()->pending_tree()->UpdateDrawProperties(false);
  EXPECT_EQ("0,50 100x100", pending_layer()
                                ->HighResTiling()
                                ->GetCurrentVisibleRectForTesting()
                                .ToString());
}

TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) {
  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  gfx::Size tile_size(102, 102);
  gfx::Size layer_bounds(100, 100);
  gfx::Size viewport_size(100, 100);

  host_impl()->SetViewportSize(viewport_size);
  SetInitialDeviceScaleFactor(1.f);

  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilledLCD(layer_bounds);
  SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region());

  EXPECT_TRUE(pending_layer()->RasterSourceUsesLCDText());
  EXPECT_TRUE(pending_layer()->HighResTiling()->has_tiles());
  std::vector<Tile*> tiles =
      pending_layer()->HighResTiling()->AllTilesForTesting();
  auto prioritized_tiles = pending_layer()
                               ->HighResTiling()
                               ->UpdateAndGetAllPrioritizedTilesForTesting();

  for (Tile* tile : tiles)
    EXPECT_EQ(pending_layer()->raster_source(),
              prioritized_tiles[tile].raster_source());

  pending_layer()->SetContentsOpaque(false);
  pending_layer()->UpdateCanUseLCDTextAfterCommit();

  EXPECT_FALSE(pending_layer()->RasterSourceUsesLCDText());
  EXPECT_NE(pending_raster_source.get(), pending_layer()->raster_source());
  EXPECT_TRUE(pending_layer()->HighResTiling()->has_tiles());
  tiles = pending_layer()->HighResTiling()->AllTilesForTesting();
  prioritized_tiles = pending_layer()
                          ->HighResTiling()
                          ->UpdateAndGetAllPrioritizedTilesForTesting();
  for (Tile* tile : tiles)
    EXPECT_EQ(pending_layer()->raster_source(),
              prioritized_tiles[tile].raster_source());
}

TEST_F(PictureLayerImplTest, TilingAllTilesDone) {
  gfx::Size tile_size = host_impl()->settings().default_tile_size;
  size_t tile_mem = 4 * tile_size.width() * tile_size.height();
  gfx::Size layer_bounds(1000, 1000);

  // Create tiles.
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);
  SetupPendingTree(pending_raster_source);
  pending_layer()->SetBounds(layer_bounds);
  ActivateTree();
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      active_layer()->HighResTiling()->AllTilesForTesting());
  host_impl()->SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);

  EXPECT_FALSE(active_layer()->HighResTiling()->all_tiles_done());

  {
    // Set a memory policy that will fit all tiles.
    size_t max_tiles = 16;
    size_t memory_limit = max_tiles * tile_mem;
    ManagedMemoryPolicy policy(memory_limit,
                               gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
                               max_tiles);
    host_impl()->SetMemoryPolicy(policy);
    host_impl()->PrepareTiles();

    EXPECT_TRUE(active_layer()->HighResTiling()->all_tiles_done());
  }

  {
    // Set a memory policy that will cause tile eviction.
    size_t max_tiles = 1;
    size_t memory_limit = max_tiles * tile_mem;
    ManagedMemoryPolicy policy(memory_limit,
                               gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
                               max_tiles);
    host_impl()->SetMemoryPolicy(policy);
    host_impl()->PrepareTiles();

    EXPECT_FALSE(active_layer()->HighResTiling()->all_tiles_done());
  }
}

class TileSizeTest : public PictureLayerImplTest {
 public:
  LayerTreeSettings CreateSettings() override {
    LayerTreeSettings settings = PictureLayerImplTest::CreateSettings();
    settings.default_tile_size = gfx::Size(100, 100);
    settings.max_untiled_layer_size = gfx::Size(200, 200);
    return settings;
  }
};

TEST_F(TileSizeTest, TileSizes) {
  host_impl()->CreatePendingTree();

  LayerTreeImpl* pending_tree = host_impl()->pending_tree();
  std::unique_ptr<FakePictureLayerImpl> layer =
      FakePictureLayerImpl::Create(pending_tree, layer_id());

  host_impl()->SetViewportSize(gfx::Size(1000, 1000));
  gfx::Size result;

  host_impl()->SetContentIsSuitableForGpuRasterization(true);
  host_impl()->SetHasGpuRasterizationTrigger(false);
  host_impl()->CommitComplete();
  EXPECT_EQ(host_impl()->gpu_rasterization_status(),
            GpuRasterizationStatus::OFF_VIEWPORT);

  // Default tile-size for large layers.
  result = layer->CalculateTileSize(gfx::Size(10000, 10000));
  EXPECT_EQ(result.width(), 100);
  EXPECT_EQ(result.height(), 100);
  // Don't tile and round-up, when under max_untiled_layer_size.
  result = layer->CalculateTileSize(gfx::Size(42, 42));
  EXPECT_EQ(result.width(), 64);
  EXPECT_EQ(result.height(), 64);
  result = layer->CalculateTileSize(gfx::Size(191, 191));
  EXPECT_EQ(result.width(), 192);
  EXPECT_EQ(result.height(), 192);
  result = layer->CalculateTileSize(gfx::Size(199, 199));
  EXPECT_EQ(result.width(), 200);
  EXPECT_EQ(result.height(), 200);

  // Gpu-rasterization uses 25% viewport-height tiles.
  // The +2's below are for border texels.
  host_impl()->SetHasGpuRasterizationTrigger(true);
  host_impl()->CommitComplete();
  EXPECT_EQ(host_impl()->gpu_rasterization_status(),
            GpuRasterizationStatus::ON);
  host_impl()->SetViewportSize(gfx::Size(2000, 2000));

  layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size());
  result = layer->CalculateTileSize(gfx::Size(10000, 10000));
  EXPECT_EQ(result.width(),
            MathUtil::UncheckedRoundUp(
                2000 + 2 * PictureLayerTiling::kBorderTexels, 32));
  EXPECT_EQ(result.height(), 512);  // 500 + 2, 32-byte aligned.

  // Clamp and round-up, when smaller than viewport.
  // Tile-height doubles to 50% when width shrinks to <= 50%.
  host_impl()->SetViewportSize(gfx::Size(1000, 1000));
  layer->set_gpu_raster_max_texture_size(host_impl()->device_viewport_size());
  result = layer->CalculateTileSize(gfx::Size(447, 10000));
  EXPECT_EQ(result.width(), 448);
  EXPECT_EQ(result.height(), 512);  // 500 + 2, 32-byte aliged.

  // Largest layer is 50% of viewport width (rounded up), and
  // 50% of viewport in height.
  result = layer->CalculateTileSize(gfx::Size(447, 400));
  EXPECT_EQ(result.width(), 448);
  EXPECT_EQ(result.height(), 448);
  result = layer->CalculateTileSize(gfx::Size(500, 499));
  EXPECT_EQ(result.width(), 512);
  EXPECT_EQ(result.height(), 512);  // 500 + 2, 32-byte aligned.
}

TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) {
  gfx::Size layer_bounds(1300, 1900);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;
  SetupDefaultTrees(layer_bounds);
  ResetTilingsAndRasterScales();

  float page_scale = 2.f;
  SetContentsScaleOnBothLayers(page_scale, 1.0f, page_scale, 1.0f, 0.f, false);
  EXPECT_BOTH_EQ(num_tilings(), 1u);
  EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale(), page_scale);

  host_impl()->PinchGestureBegin();

  // Zoom out to exactly the low res factor so that the previous high res
  // would be equal to the current low res (if it were possible to have one).
  float zoomed = page_scale / low_res_factor;
  SetContentsScaleOnBothLayers(zoomed, 1.0f, zoomed, 1.0f, 0.f, false);
  EXPECT_EQ(1u, pending_layer()->num_tilings());
  EXPECT_EQ(zoomed, pending_layer()->tilings()->tiling_at(0)->contents_scale());
}

TEST_F(PictureLayerImplTest, HighResWasLowResCollision) {
  gfx::Size layer_bounds(1300, 1900);

  float low_res_factor = host_impl()->settings().low_res_contents_scale_factor;

  SetupDefaultTrees(layer_bounds);
  ResetTilingsAndRasterScales();

  float page_scale = 4.f;
  float low_res = page_scale * low_res_factor;
  float extra_low_res = low_res * low_res_factor;
  SetupDrawPropertiesAndUpdateTiles(active_layer(), page_scale, 1.0f,
                                    page_scale, 1.0f, 0.f, false);
  EXPECT_EQ(2u, active_layer()->tilings()->num_tilings());
  EXPECT_EQ(page_scale,
            active_layer()->tilings()->tiling_at(0)->contents_scale());
  EXPECT_EQ(low_res, active_layer()->tilings()->tiling_at(1)->contents_scale());

  // Grab a current low res tile.
  PictureLayerTiling* old_low_res_tiling =
      active_layer()->tilings()->tiling_at(1);
  Tile::Id old_low_res_tile_id =
      active_layer()->tilings()->tiling_at(1)->TileAt(0, 0)->id();

  // The tiling knows it has low res content.
  EXPECT_TRUE(active_layer()
                  ->tilings()
                  ->tiling_at(1)
                  ->may_contain_low_resolution_tiles());

  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));

  // Zoom in to exactly the low res factor so that the previous low res
  // would be equal to the current high res.
  SetupDrawPropertiesAndUpdateTiles(active_layer(), low_res, 1.0f, low_res,
                                    1.0f, 0.f, false);
  // 3 tilings. The old high res, the new high res (old low res) and the new low
  // res.
  EXPECT_EQ(3u, active_layer()->num_tilings());

  PictureLayerTilingSet* tilings = active_layer()->tilings();
  EXPECT_EQ(page_scale, tilings->tiling_at(0)->contents_scale());
  EXPECT_EQ(low_res, tilings->tiling_at(1)->contents_scale());
  EXPECT_EQ(extra_low_res, tilings->tiling_at(2)->contents_scale());

  EXPECT_EQ(NON_IDEAL_RESOLUTION, tilings->tiling_at(0)->resolution());
  EXPECT_EQ(HIGH_RESOLUTION, tilings->tiling_at(1)->resolution());
  EXPECT_EQ(LOW_RESOLUTION, tilings->tiling_at(2)->resolution());

  // The old low res tile was destroyed and replaced.
  EXPECT_EQ(old_low_res_tiling, tilings->tiling_at(1));
  EXPECT_NE(old_low_res_tile_id, tilings->tiling_at(1)->TileAt(0, 0)->id());
  EXPECT_TRUE(tilings->tiling_at(1)->TileAt(0, 0));

  // New high res tiling.
  EXPECT_FALSE(tilings->tiling_at(0)->may_contain_low_resolution_tiles());
  // New low res tiling.
  EXPECT_TRUE(tilings->tiling_at(2)->may_contain_low_resolution_tiles());

  // This tiling will be high res now, it won't contain low res content since it
  // was all destroyed.
  EXPECT_FALSE(tilings->tiling_at(1)->may_contain_low_resolution_tiles());
}

TEST_F(PictureLayerImplTest, CompositedImageCalculateContentsScale) {
  gfx::Size layer_bounds(400, 400);
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->CreatePendingTree();
  LayerTreeImpl* pending_tree = host_impl()->pending_tree();

  std::unique_ptr<FakePictureLayerImpl> pending_layer =
      FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(),
                                                   pending_raster_source);
  pending_layer->set_is_directly_composited_image(true);
  pending_layer->SetDrawsContent(true);
  FakePictureLayerImpl* pending_layer_ptr = pending_layer.get();
  pending_tree->SetRootLayerForTesting(std::move(pending_layer));
  pending_tree->BuildLayerListAndPropertyTreesForTesting();

  SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, 2.f, 3.f, 4.f, 1.f, 1.f,
                                    false);
  EXPECT_FLOAT_EQ(1.f, pending_layer_ptr->MaximumTilingContentsScale());
}

TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) {
  gfx::Size layer_bounds(400, 400);
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->SetViewportSize(layer_bounds);
  host_impl()->CreatePendingTree();
  LayerTreeImpl* pending_tree = host_impl()->pending_tree();

  std::unique_ptr<FakePictureLayerImpl> pending_layer =
      FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(),
                                                   pending_raster_source);
  pending_layer->set_is_directly_composited_image(true);
  pending_layer->SetDrawsContent(true);
  FakePictureLayerImpl* pending_layer_ptr = pending_layer.get();
  pending_tree->SetRootLayerForTesting(std::move(pending_layer));
  pending_tree->BuildLayerListAndPropertyTreesForTesting();

  // Set PictureLayerImpl::ideal_contents_scale_ to 2.f.
  const float suggested_ideal_contents_scale = 2.f;
  const float device_scale_factor = 3.f;
  const float page_scale_factor = 4.f;
  const float animation_contents_scale = 1.f;
  const bool animating_transform_to_screen = false;
  SetupDrawPropertiesAndUpdateTiles(
      pending_layer_ptr, suggested_ideal_contents_scale, device_scale_factor,
      page_scale_factor, animation_contents_scale, animation_contents_scale,
      animating_transform_to_screen);
  EXPECT_EQ(1.f, pending_layer_ptr->tilings()->tiling_at(0)->contents_scale());

  // Push to active layer.
  host_impl()->ActivateSyncTree();

  FakePictureLayerImpl* active_layer = static_cast<FakePictureLayerImpl*>(
      host_impl()->active_tree()->root_layer_for_testing());
  SetupDrawPropertiesAndUpdateTiles(
      active_layer, suggested_ideal_contents_scale, device_scale_factor,
      page_scale_factor, animation_contents_scale, animation_contents_scale,
      animating_transform_to_screen);
  EXPECT_EQ(1.f, active_layer->tilings()->tiling_at(0)->contents_scale());
  active_layer->set_visible_layer_rect(gfx::Rect(layer_bounds));

  // Create resources for the tiles.
  host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(
      active_layer->tilings()->tiling_at(0)->AllTilesForTesting());

  // Draw.
  std::unique_ptr<RenderPass> render_pass = RenderPass::Create();
  AppendQuadsData data;
  active_layer->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
  active_layer->AppendQuads(render_pass.get(), &data);
  active_layer->DidDraw(nullptr);

  ASSERT_FALSE(render_pass->quad_list.empty());
  EXPECT_EQ(DrawQuad::TILED_CONTENT, render_pass->quad_list.front()->material);

  // Tiles are ready at correct scale, so should not set had_incomplete_tile.
  EXPECT_EQ(0, data.num_incomplete_tiles);
}

TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) {
  gfx::Size layer_bounds(400, 400);
  scoped_refptr<FakeRasterSource> pending_raster_source =
      FakeRasterSource::CreateFilled(layer_bounds);

  host_impl()->CreatePendingTree();
  LayerTreeImpl* pending_tree = host_impl()->pending_tree();

  std::unique_ptr<FakePictureLayerImpl> pending_layer =
      FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(),
                                                   pending_raster_source);
  pending_layer->set_is_directly_composited_image(true);
  pending_layer->SetDrawsContent(true);
  FakePictureLayerImpl* pending_layer_ptr = pending_layer.get();
  pending_tree->SetRootLayerForTesting(std::move(pending_layer));
  pending_tree->BuildLayerListAndPropertyTreesForTesting();

  float expected_contents_scale = 0.25f;
  for (int i = 1; i < 30; ++i) {
    float ideal_contents_scale = 0.1f * i - 1e-6;
    switch (i) {
      // Scale 0.3.
      case 3:
        expected_contents_scale = 0.5f;
        break;
      // Scale 0.6.
      case 6:
        expected_contents_scale = 1.f;
        break;
    }
    SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, ideal_contents_scale,
                                      1.f, 1.f, 1.f, 1.f, false);
    EXPECT_FLOAT_EQ(expected_contents_scale,
                    pending_layer_ptr->picture_layer_tiling_set()
                        ->FindTilingWithResolution(HIGH_RESOLUTION)
                        ->contents_scale())
        << "ideal_contents_scale: " << ideal_contents_scale;
  }

  expected_contents_scale = 1.f;
  for (int i = 30; i >= 1; --i) {
    float ideal_contents_scale = 0.1f * i - 1e-6;
    switch (i) {
      // Scale 0.2.
      case 2:
        expected_contents_scale = 0.5f;
        break;
      // Scale 0.1.
      case 1:
        expected_contents_scale = 0.25f;
        break;
    }
    SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, ideal_contents_scale,
                                      1.f, 1.f, 1.f, 1.f, false);
    EXPECT_FLOAT_EQ(expected_contents_scale,
                    pending_layer_ptr->picture_layer_tiling_set()
                        ->FindTilingWithResolution(HIGH_RESOLUTION)
                        ->contents_scale())
        << "ideal_contents_scale: " << ideal_contents_scale;
  }
}

}  // namespace
}  // namespace cc
