Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / layers / picture_layer_impl_unittest.cc
index 46f0ef3..4b42eca 100644 (file)
@@ -28,8 +28,8 @@
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/size_conversions.h"
+#include "ui/gfx/geometry/rect_conversions.h"
+#include "ui/gfx/geometry/size_conversions.h"
 
 namespace cc {
 namespace {
@@ -38,7 +38,7 @@ class MockCanvas : public SkCanvas {
  public:
   explicit MockCanvas(int w, int h) : SkCanvas(w, h) {}
 
-  virtual void drawRect(const SkRect& rect, const SkPaint& paint) OVERRIDE {
+  void drawRect(const SkRect& rect, const SkPaint& paint) override {
     // Capture calls before SkCanvas quickReject() kicks in.
     rects_.push_back(rect);
   }
@@ -59,9 +59,9 @@ class PictureLayerImplTest : public testing::Test {
       : proxy_(base::MessageLoopProxy::current()),
         host_impl_(LowResTilingsSettings(), &proxy_, &shared_bitmap_manager_),
         id_(7),
-        pending_layer_(NULL),
-        old_pending_layer_(NULL),
-        active_layer_(NULL) {}
+        pending_layer_(nullptr),
+        old_pending_layer_(nullptr),
+        active_layer_(nullptr) {}
 
   explicit PictureLayerImplTest(const LayerTreeSettings& settings)
       : proxy_(base::MessageLoopProxy::current()),
@@ -71,13 +71,12 @@ class PictureLayerImplTest : public testing::Test {
   virtual ~PictureLayerImplTest() {
   }
 
-  virtual void SetUp() OVERRIDE {
+  virtual void SetUp() override {
     InitializeRenderer();
   }
 
   virtual void InitializeRenderer() {
-    host_impl_.InitializeRenderer(
-        FakeOutputSurface::Create3d().PassAs<OutputSurface>());
+    host_impl_.InitializeRenderer(FakeOutputSurface::Create3d());
   }
 
   void SetupDefaultTrees(const gfx::Size& layer_bounds) {
@@ -96,7 +95,7 @@ class PictureLayerImplTest : public testing::Test {
     CHECK(!host_impl_.pending_tree());
     CHECK(host_impl_.recycle_tree());
     old_pending_layer_ = pending_layer_;
-    pending_layer_ = NULL;
+    pending_layer_ = nullptr;
     active_layer_ = static_cast<FakePictureLayerImpl*>(
         host_impl_.active_tree()->LayerById(id_));
   }
@@ -139,13 +138,24 @@ class PictureLayerImplTest : public testing::Test {
     host_impl_.CreatePendingTree();
     host_impl_.pending_tree()->SetPageScaleFactorAndLimits(1.f, 0.25f, 100.f);
     LayerTreeImpl* pending_tree = host_impl_.pending_tree();
-    // Clear recycled tree.
-    pending_tree->DetachLayerTree();
 
-    scoped_ptr<FakePictureLayerImpl> pending_layer =
-        FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pile);
-    pending_layer->SetDrawsContent(true);
-    pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
+    // Steal from the recycled tree.
+    scoped_ptr<LayerImpl> old_pending_root = pending_tree->DetachLayerTree();
+    DCHECK_IMPLIES(old_pending_root, old_pending_root->id() == id_);
+
+    scoped_ptr<FakePictureLayerImpl> pending_layer;
+    if (old_pending_root) {
+      pending_layer.reset(
+          static_cast<FakePictureLayerImpl*>(old_pending_root.release()));
+      pending_layer->SetPile(pile);
+    } else {
+      pending_layer =
+          FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pile);
+      pending_layer->SetDrawsContent(true);
+    }
+    // The bounds() just mirror the pile size.
+    pending_layer->SetBounds(pending_layer->pile()->tiling_size());
+    pending_tree->SetRootLayer(pending_layer.Pass());
 
     pending_layer_ = static_cast<FakePictureLayerImpl*>(
         host_impl_.pending_tree()->LayerById(id_));
@@ -178,7 +188,7 @@ class PictureLayerImplTest : public testing::Test {
          iter;
          ++iter) {
       EXPECT_TRUE(*iter);
-      EXPECT_EQ(pile, iter->picture_pile());
+      EXPECT_EQ(pile, iter->raster_source());
     }
   }
 
@@ -258,8 +268,8 @@ class PictureLayerImplTest : public testing::Test {
     std::vector<SkRect>::const_iterator rect_iter = rects.begin();
     for (tile_iter = tiles.begin(); tile_iter < tiles.end(); tile_iter++) {
       MockCanvas mock_canvas(1000, 1000);
-      active_pile->RasterDirect(
-          &mock_canvas, (*tile_iter)->content_rect(), 1.0f, NULL);
+      active_pile->RasterDirect(&mock_canvas, (*tile_iter)->content_rect(),
+                                1.0f);
 
       // This test verifies that when drawing the contents of a specific tile
       // at content scale 1.0, the playback canvas never receives content from
@@ -354,18 +364,14 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
                                         viewport_rect_for_tile_priority,
                                         transform_for_tile_priority,
                                         resourceless_software_draw);
-  active_layer_->draw_properties().visible_content_rect = viewport;
-  active_layer_->draw_properties().screen_space_transform = transform;
-  active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+  host_impl_.active_tree()->UpdateDrawProperties();
 
   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 impl.
-  EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(),
-            viewport_rect_for_tile_priority_in_view_space);
-
   // 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_->GetViewportForTilePriorityInContentSpace());
   PictureLayerTilingSet* tilings = active_layer_->tilings();
   for (size_t i = 0; i < tilings->num_tilings(); i++) {
     PictureLayerTiling* tiling = tilings->tiling_at(i);
@@ -392,9 +398,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
                                         viewport_rect_for_tile_priority,
                                         transform_for_tile_priority,
                                         resourceless_software_draw);
-  active_layer_->draw_properties().visible_content_rect = viewport;
-  active_layer_->draw_properties().screen_space_transform = transform;
-  active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+  host_impl_.active_tree()->UpdateDrawProperties();
 
   gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization);
   bool success = transform_for_tile_priority.GetInverse(&screen_to_view);
@@ -408,10 +412,8 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) {
       gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
           screen_to_view, viewport_rect_for_tile_priority));
 
-  // Verify the viewport rect for tile priority is used in PictureLayerImpl.
-  EXPECT_EQ(active_layer_->viewport_rect_for_tile_priority(),
-            viewport_rect_for_tile_priority_in_view_space);
-
+  EXPECT_EQ(viewport_rect_for_tile_priority_in_view_space,
+            active_layer_->GetViewportForTilePriorityInContentSpace());
   tilings = active_layer_->tilings();
   for (size_t i = 0; i < tilings->num_tilings(); i++) {
     PictureLayerTiling* tiling = tilings->tiling_at(i);
@@ -461,11 +463,8 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
   gfx::Rect visible_rect_for_tile_priority =
       active_layer_->visible_rect_for_tile_priority();
   EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty());
-  gfx::Rect viewport_rect_for_tile_priority =
-      active_layer_->viewport_rect_for_tile_priority();
-  EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty());
   gfx::Transform screen_space_transform_for_tile_priority =
-      active_layer_->screen_space_transform_for_tile_priority();
+      active_layer_->screen_space_transform();
 
   // Expand viewport and set it as invalid for prioritizing tiles.
   // Should update viewport and transform, but not update visible rect.
@@ -485,10 +484,9 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
                                         resourceless_software_draw);
   active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
 
-  // Viewport and transform for tile priority are updated.
-  EXPECT_EQ(viewport, active_layer_->viewport_rect_for_tile_priority());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      transform, active_layer_->screen_space_transform_for_tile_priority());
+  // Transform for tile priority is updated.
+  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+                                  active_layer_->screen_space_transform());
   // Visible rect for tile priority retains old value.
   EXPECT_EQ(visible_rect_for_tile_priority,
             active_layer_->visible_rect_for_tile_priority());
@@ -506,13 +504,9 @@ TEST_F(PictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
                                         resourceless_software_draw);
   active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
 
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      transform, active_layer_->screen_space_transform_for_tile_priority());
+  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+                                  active_layer_->screen_space_transform());
   EXPECT_EQ(viewport, active_layer_->visible_rect_for_tile_priority());
-
-  // Match the reverse translate in |transform|.
-  EXPECT_EQ(viewport - gfx::Vector2d(1, 1),
-            active_layer_->viewport_rect_for_tile_priority());
 }
 
 TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
@@ -546,9 +540,9 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) {
       EXPECT_TRUE(*iter);
       EXPECT_FALSE(iter.geometry_rect().IsEmpty());
       if (iter.geometry_rect().Intersects(content_invalidation))
-        EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+        EXPECT_EQ(pending_pile.get(), iter->raster_source());
       else
-        EXPECT_EQ(active_pile.get(), iter->picture_pile());
+        EXPECT_EQ(active_pile.get(), iter->raster_source());
     }
   }
 }
@@ -615,9 +609,9 @@ TEST_F(PictureLayerImplTest, NoInvalidationBoundsChange) {
           iter.geometry_rect().bottom() >= active_content_bounds.height() ||
           active_tiles[0]->content_rect().size() !=
               pending_tiles[0]->content_rect().size()) {
-        EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+        EXPECT_EQ(pending_pile.get(), iter->raster_source());
       } else {
-        EXPECT_EQ(active_pile.get(), iter->picture_pile());
+        EXPECT_EQ(active_pile.get(), iter->raster_source());
       }
     }
   }
@@ -664,15 +658,15 @@ TEST_F(PictureLayerImplTest, AddTilesFromNewRecording) {
          ++iter) {
       EXPECT_FALSE(iter.full_tile_geometry_rect().IsEmpty());
       // Ensure there is a recording for this tile.
-      bool in_pending = pending_pile->CanRaster(tiling->contents_scale(),
-                                                iter.full_tile_geometry_rect());
-      bool in_active = active_pile->CanRaster(tiling->contents_scale(),
-                                              iter.full_tile_geometry_rect());
+      bool in_pending = pending_pile->CoversRect(iter.full_tile_geometry_rect(),
+                                                 tiling->contents_scale());
+      bool in_active = active_pile->CoversRect(iter.full_tile_geometry_rect(),
+                                               tiling->contents_scale());
 
       if (in_pending && !in_active)
-        EXPECT_EQ(pending_pile.get(), iter->picture_pile());
+        EXPECT_EQ(pending_pile.get(), iter->raster_source());
       else if (in_active)
-        EXPECT_EQ(active_pile.get(), iter->picture_pile());
+        EXPECT_EQ(active_pile.get(), iter->raster_source());
       else
         EXPECT_FALSE(*iter);
     }
@@ -1109,7 +1103,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
   EXPECT_BOTH_EQ(LowResTiling()->contents_scale(), low_res_factor);
   EXPECT_BOTH_EQ(num_tilings(), 2u);
 
-  // Page scale animation, new high res, but not new low res because animating.
+  // 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.
   contents_scale = 2.f;
   page_scale = 2.f;
   maximum_animation_scale = 2.f;
@@ -1120,7 +1115,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
                                maximum_animation_scale,
                                animating_transform);
   EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f);
-  EXPECT_BOTH_EQ(LowResTiling()->contents_scale(), low_res_factor);
+  EXPECT_FALSE(active_layer_->LowResTiling());
+  EXPECT_FALSE(pending_layer_->LowResTiling());
   EXPECT_BOTH_EQ(num_tilings(), 3u);
 
   // Stop animating, new low res gets created for final page scale.
@@ -1136,8 +1132,15 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) {
 }
 
 TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
-  gfx::Size tile_size(host_impl_.settings().default_tile_size);
-  SetupDefaultTrees(tile_size);
+  gfx::Size layer_bounds(host_impl_.settings().default_tile_size);
+  gfx::Size tile_size(100, 100);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+  SetupTrees(pending_pile, active_pile);
 
   float low_res_factor = host_impl_.settings().low_res_contents_scale_factor;
   float device_scale = 1.f;
@@ -1185,8 +1188,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) {
   ResetTilingsAndRasterScales();
 
   // Mask layers dont create low res since they always fit on one tile.
-  pending_layer_->pile()->set_is_mask(true);
-  active_layer_->pile()->set_is_mask(true);
+  pending_pile->SetIsMask(true);
+  active_pile->SetIsMask(true);
   SetContentsScaleOnBothLayers(contents_scale,
                                device_scale,
                                page_scale,
@@ -1201,7 +1204,7 @@ TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) {
 
   scoped_refptr<FakePicturePileImpl> valid_pile =
       FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
-  valid_pile->set_is_mask(true);
+  valid_pile->SetIsMask(true);
   SetupPendingTree(valid_pile);
 
   SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
@@ -1217,14 +1220,18 @@ TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) {
   // Mask layers have a tiling with a single tile in it.
   EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
   // The mask resource exists.
-  EXPECT_NE(0u, active_layer_->ContentsResourceId());
+  ResourceProvider::ResourceId mask_resource_id;
+  gfx::Size mask_texture_size;
+  active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+  EXPECT_NE(0u, mask_resource_id);
+  EXPECT_EQ(mask_texture_size, active_layer_->bounds());
 
   // Resize larger than the max texture size.
   int max_texture_size = host_impl_.GetRendererCapabilities().max_texture_size;
   scoped_refptr<FakePicturePileImpl> huge_pile =
       FakePicturePileImpl::CreateFilledPile(
           tile_size, gfx::Size(max_texture_size + 1, 10));
-  huge_pile->set_is_mask(true);
+  huge_pile->SetIsMask(true);
   SetupPendingTree(huge_pile);
 
   SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
@@ -1240,7 +1247,41 @@ TEST_F(PictureLayerImplTest, HugeMasksDontGetTiles) {
   // Mask layers have a tiling, but there should be no tiles in it.
   EXPECT_EQ(0u, active_layer_->HighResTiling()->AllTilesForTesting().size());
   // The mask resource is empty.
-  EXPECT_EQ(0u, active_layer_->ContentsResourceId());
+  active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+  EXPECT_EQ(0u, mask_resource_id);
+}
+
+TEST_F(PictureLayerImplTest, ScaledMaskLayer) {
+  gfx::Size tile_size(100, 100);
+
+  scoped_refptr<FakePicturePileImpl> valid_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1000, 1000));
+  valid_pile->SetIsMask(true);
+  SetupPendingTree(valid_pile);
+
+  float ideal_contents_scale = 1.3f;
+  SetupDrawPropertiesAndUpdateTiles(
+      pending_layer_, ideal_contents_scale, 1.f, 1.f, 1.f, false);
+  EXPECT_EQ(ideal_contents_scale,
+            pending_layer_->HighResTiling()->contents_scale());
+  EXPECT_EQ(1u, pending_layer_->num_tilings());
+
+  pending_layer_->HighResTiling()->CreateAllTilesForTesting();
+  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(
+      pending_layer_->HighResTiling()->AllTilesForTesting());
+
+  ActivateTree();
+
+  // Mask layers have a tiling with a single tile in it.
+  EXPECT_EQ(1u, active_layer_->HighResTiling()->AllTilesForTesting().size());
+  // The mask resource exists.
+  ResourceProvider::ResourceId mask_resource_id;
+  gfx::Size mask_texture_size;
+  active_layer_->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
+  EXPECT_NE(0u, mask_resource_id);
+  gfx::Size expected_mask_texture_size = gfx::ToCeiledSize(
+      gfx::ScaleSize(active_layer_->bounds(), ideal_contents_scale));
+  EXPECT_EQ(mask_texture_size, expected_mask_texture_size);
 }
 
 TEST_F(PictureLayerImplTest, ReleaseResources) {
@@ -1312,8 +1353,8 @@ TEST_F(PictureLayerImplTest, ClampTilesToToMaxTileSize) {
       TestWebGraphicsContext3D::Create();
   context->set_max_texture_size(140);
   host_impl_.DidLoseOutputSurface();
-  host_impl_.InitializeRenderer(FakeOutputSurface::Create3d(
-      context.Pass()).PassAs<OutputSurface>());
+  host_impl_.InitializeRenderer(
+      FakeOutputSurface::Create3d(context.Pass()).Pass());
 
   SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
   ASSERT_EQ(2u, pending_layer_->tilings()->num_tilings());
@@ -1359,8 +1400,8 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
       TestWebGraphicsContext3D::Create();
   context->set_max_texture_size(140);
   host_impl_.DidLoseOutputSurface();
-  host_impl_.InitializeRenderer(FakeOutputSurface::Create3d(
-      context.Pass()).PassAs<OutputSurface>());
+  host_impl_.InitializeRenderer(
+      FakeOutputSurface::Create3d(context.Pass()).Pass());
 
   SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
   ASSERT_LE(1u, pending_layer_->tilings()->num_tilings());
@@ -1379,7 +1420,6 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) {
 }
 
 TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
 
   gfx::Size tile_size(400, 400);
@@ -1400,34 +1440,47 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) {
   AddDefaultTilingsWithInvalidation(invalidation);
 
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_RESOURCELESS_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+  active_layer_->DidDraw(nullptr);
 
   ASSERT_EQ(1U, render_pass->quad_list.size());
   EXPECT_EQ(DrawQuad::PICTURE_CONTENT,
             render_pass->quad_list.front()->material);
 }
 
-TEST_F(PictureLayerImplTest, MarkRequiredNullTiles) {
-  gfx::Size tile_size(100, 100);
-  gfx::Size layer_bounds(1000, 1000);
+TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) {
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+
+  gfx::Size tile_size(1000, 1000);
+  gfx::Size layer_bounds(1500, 1500);
+  gfx::Rect visible_rect(250, 250, 1000, 1000);
 
   scoped_refptr<FakePicturePileImpl> pending_pile =
       FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
-  // Layers with entirely empty piles can't get tilings.
-  pending_pile->AddRecordingAt(0, 0);
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
 
-  SetupPendingTree(pending_pile);
+  pending_pile->set_is_solid_color(true);
+  active_pile->set_is_solid_color(true);
 
-  ASSERT_TRUE(pending_layer_->CanHaveTilings());
-  pending_layer_->AddTiling(1.0f);
-  pending_layer_->AddTiling(2.0f);
+  SetupTrees(pending_pile, active_pile);
 
-  // It should be safe to call this (and MarkVisibleResourcesAsRequired)
-  // on a layer with no recordings.
-  host_impl_.pending_tree()->UpdateDrawProperties();
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  active_layer_->draw_properties().visible_content_rect = visible_rect;
+
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+  active_layer_->DidDraw(nullptr);
+
+  Region remaining = visible_rect;
+  for (const 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, TileScalesWithSolidColorPile) {
@@ -1485,43 +1538,22 @@ TEST_F(PictureLayerImplTest, MarkRequiredOffscreenTiles) {
   ASSERT_TRUE(pending_layer_->CanHaveTilings());
   PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
   host_impl_.pending_tree()->UpdateDrawProperties();
-  EXPECT_EQ(tiling->resolution(), HIGH_RESOLUTION);
   EXPECT_EQ(viewport, pending_layer_->visible_rect_for_tile_priority());
 
-  // Fake set priorities.
-  for (PictureLayerTiling::CoverageIterator iter(
-           tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
-       iter;
-       ++iter) {
-    if (!*iter)
-      continue;
-    Tile* tile = *iter;
-    TilePriority priority;
-    priority.resolution = HIGH_RESOLUTION;
-    gfx::Rect tile_bounds = iter.geometry_rect();
-    if (pending_layer_->visible_rect_for_tile_priority().Intersects(
-            tile_bounds)) {
-      priority.priority_bin = TilePriority::NOW;
-      priority.distance_to_visible = 0.f;
-    } else {
-      priority.priority_bin = TilePriority::SOON;
-      priority.distance_to_visible = 1.f;
-    }
-    tile->SetPriority(PENDING_TREE, priority);
-  }
-
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentBeginFrameArgs(
+      CreateBeginFrameArgsForTesting(time_ticks));
+  pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
+  EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution());
 
   int num_visible = 0;
   int num_offscreen = 0;
 
-  for (PictureLayerTiling::CoverageIterator iter(
-           tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
-       iter;
+  for (PictureLayerTiling::TilingRasterTileIterator iter(tiling); iter;
        ++iter) {
-    if (!*iter)
-      continue;
     const Tile* tile = *iter;
+    DCHECK(tile);
     if (tile->priority(PENDING_TREE).distance_to_visible == 0.f) {
       EXPECT_TRUE(tile->required_for_activation());
       num_visible++;
@@ -1578,8 +1610,6 @@ TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
       CreateBeginFrameArgsForTesting(time_ticks));
   pending_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
 
-  pending_layer_->MarkVisibleResourcesAsRequired();
-
   // Intersect the two rects. Any tile outside should not be required for
   // activation.
   gfx::Rect viewport_for_tile_priority =
@@ -1598,10 +1628,8 @@ TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
     if (viewport_for_tile_priority.Intersects(iter.geometry_rect())) {
       num_inside++;
       // Mark everything in viewport for tile priority as ready to draw.
-      ManagedTileState::TileVersion& tile_version =
-          tile->GetTileVersionForTesting(
-              tile->DetermineRasterModeForTree(PENDING_TREE));
-      tile_version.SetSolidColorForTesting(SK_ColorRED);
+      ManagedTileState::DrawInfo& draw_info = tile->draw_info();
+      draw_info.SetSolidColorForTesting(SK_ColorRED);
     } else {
       num_outside++;
       EXPECT_FALSE(tile->required_for_activation());
@@ -1616,16 +1644,16 @@ TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
   host_impl_.active_tree()->UpdateDrawProperties();
   active_layer_->draw_properties().visible_content_rect = visible_content_rect;
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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) {
@@ -1651,17 +1679,82 @@ TEST_F(PictureLayerImplTest, HighResTileIsComplete) {
       active_layer_->tilings()->tiling_at(0)->AllTilesForTesting();
   host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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) {
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentBeginFrameArgs(
+      CreateBeginFrameArgsForTesting(time_ticks));
+
+  gfx::Size tile_size(100, 100);
+  gfx::Size layer_bounds(200, 200);
+
+  host_impl_.SetViewportSize(layer_bounds);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  SetupPendingTree(pending_pile);
+  ActivateTree();
+
+  active_layer_->set_fixed_tile_size(tile_size);
+  host_impl_.active_tree()->UpdateDrawProperties();
+
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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) {
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentBeginFrameArgs(
+      CreateBeginFrameArgsForTesting(time_ticks));
+
+  gfx::Size tile_size(100, 100);
+  gfx::Size layer_bounds(200, 200);
+
+  host_impl_.SetViewportSize(layer_bounds);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  SetupPendingTree(pending_pile);
+  ActivateTree();
+
+  active_layer_->set_fixed_tile_size(tile_size);
+  host_impl_.active_tree()->UpdateDrawProperties();
+  std::vector<Tile*> low_tiles =
+      active_layer_->tilings()->tiling_at(1)->AllTilesForTesting();
+  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles);
+
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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) {
@@ -1693,17 +1786,17 @@ TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) {
       active_layer_->tilings()->tiling_at(1)->AllTilesForTesting();
   host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(low_tiles);
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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,
@@ -1755,12 +1848,11 @@ TEST_F(PictureLayerImplTest,
       active_layer_->HighResTiling()->AllTilesForTesting();
   host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(high_tiles);
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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);
@@ -1774,6 +1866,7 @@ TEST_F(PictureLayerImplTest,
   // 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, HighResRequiredWhenUnsharedActiveAllReady) {
@@ -1790,7 +1883,9 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenUnsharedActiveAllReady) {
 
   // No shared tiles and all active tiles ready, so pending can only
   // activate with all high res tiles.
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertAllTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
@@ -1810,13 +1905,16 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) {
 
   // When high res are required, even if the active tree is not ready,
   // the high res tiles must be ready.
-  host_impl_.active_tree()->SetRequiresHighResToDraw();
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  host_impl_.SetRequiresHighResToDraw();
+
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertAllTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
 
-TEST_F(PictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
+TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfShared) {
   gfx::Size layer_bounds(400, 400);
   gfx::Size tile_size(100, 100);
   SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
@@ -1828,8 +1926,32 @@ TEST_F(PictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
   EXPECT_FALSE(some_active_tile->IsReadyToDraw());
 
   // All tiles shared (no invalidation), so even though the active tree's
-  // tiles aren't ready, there is nothing required.
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  // tiles aren't ready, the high res tiles are required for activation.
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  AssertAllTilesRequired(pending_layer_->HighResTiling());
+  AssertNoTilesRequired(pending_layer_->LowResTiling());
+}
+
+TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) {
+  gfx::Size layer_bounds(400, 400);
+  gfx::Size tile_size(100, 100);
+  SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
+
+  CreateHighLowResAndSetAllTilesVisible();
+
+  Tile* some_active_tile =
+      active_layer_->HighResTiling()->AllTilesForTesting()[0];
+  EXPECT_FALSE(some_active_tile->IsReadyToDraw());
+
+  pending_layer_->HighResTiling()->set_can_require_tiles_for_activation(false);
+  pending_layer_->LowResTiling()->set_can_require_tiles_for_activation(false);
+
+  // If we disallow required for activation, no tiles can be required.
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertNoTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
@@ -1859,7 +1981,9 @@ TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
 
   // Since the active layer has no tiles at all, the pending layer doesn't
   // need content in order to activate.
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertNoTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
@@ -1884,7 +2008,9 @@ TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) {
   // 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_->MarkVisibleResourcesAsRequired();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertAllTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
@@ -1898,12 +2024,19 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) {
   pending_layer_->SetBounds(pending_layer_bounds);
 
   CreateHighLowResAndSetAllTilesVisible();
+  // TODO(vmpstr): This is confusing. Rework the test to create different bounds
+  // on different trees instead of fudging tilings.
+  pending_layer_->HighResTiling()->ComputeTilePriorityRects(
+      PENDING_TREE, gfx::Rect(pending_layer_bounds), 1.f, 1.f, Occlusion());
 
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
   active_layer_->SetAllTilesReady();
 
   // Since the active layer has different bounds, the pending layer needs all
   // high res tiles in order to activate.
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertAllTilesRequired(pending_layer_->HighResTiling());
   AssertNoTilesRequired(pending_layer_->LowResTiling());
 }
@@ -1920,7 +2053,7 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) {
   scoped_ptr<FakePictureLayerImpl> pending_layer =
       FakePictureLayerImpl::CreateWithPile(pending_tree, id_, pending_pile);
   pending_layer->SetDrawsContent(true);
-  pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>());
+  pending_tree->SetRootLayer(pending_layer.Pass());
 
   pending_layer_ = static_cast<FakePictureLayerImpl*>(
       host_impl_.pending_tree()->LayerById(id_));
@@ -1943,6 +2076,62 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) {
   EXPECT_FALSE(active_layer_->needs_post_commit_initialization());
 }
 
+TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) {
+  SetupDefaultTrees(gfx::Size(1500, 1500));
+
+  PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
+  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());
+
+  // Make a pending tree with an invalidated raster tile 0,0.
+  tiling->CreateAllTilesForTesting();
+  pending_layer_->set_invalidation(first_invalidate);
+
+  // Activate and make a pending tree with an invalidated raster tile 1,1.
+  ActivateTree();
+
+  host_impl_.CreatePendingTree();
+  pending_layer_ = static_cast<FakePictureLayerImpl*>(
+      host_impl_.pending_tree()->root_layer());
+  pending_layer_->set_invalidation(second_invalidate);
+
+  PictureLayerTiling* pending_tiling = pending_layer_->tilings()->tiling_at(0);
+  PictureLayerTiling* active_tiling = active_layer_->tilings()->tiling_at(0);
+
+  pending_tiling->CreateAllTilesForTesting();
+
+  // Tile 0,0 should be shared, but tile 1,1 should not be.
+  EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+  EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+  EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+  EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+  EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared());
+  EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared());
+  EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared());
+  EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared());
+
+  // Drop the tiles on the active tree and recreate them. The same tiles
+  // should be shared or not.
+  active_tiling->ComputeTilePriorityRects(
+      ACTIVE_TREE, gfx::Rect(), 1.f, 1.0, Occlusion());
+  EXPECT_TRUE(active_tiling->AllTilesForTesting().empty());
+  active_tiling->CreateAllTilesForTesting();
+
+  // Tile 0,0 should be shared, but tile 1,1 should not be.
+  EXPECT_EQ(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
+  EXPECT_EQ(active_tiling->TileAt(1, 0), pending_tiling->TileAt(1, 0));
+  EXPECT_EQ(active_tiling->TileAt(0, 1), pending_tiling->TileAt(0, 1));
+  EXPECT_NE(active_tiling->TileAt(1, 1), pending_tiling->TileAt(1, 1));
+  EXPECT_TRUE(pending_tiling->TileAt(0, 0)->is_shared());
+  EXPECT_TRUE(pending_tiling->TileAt(1, 0)->is_shared());
+  EXPECT_TRUE(pending_tiling->TileAt(0, 1)->is_shared());
+  EXPECT_FALSE(pending_tiling->TileAt(1, 1)->is_shared());
+}
+
 TEST_F(PictureLayerImplTest, ShareTilesOnSync) {
   SetupDefaultTrees(gfx::Size(1500, 1500));
   AddDefaultTilingsWithInvalidation(gfx::Rect());
@@ -2139,16 +2328,21 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) {
 }
 
 TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
-  SetupDefaultTrees(gfx::Size(10, 10));
+  gfx::Size tile_size(100, 100);
+
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(10, 10));
+  SetupPendingTree(active_pile);
+  ActivateTree();
   host_impl_.active_tree()->UpdateDrawProperties();
   EXPECT_FALSE(host_impl_.active_tree()->needs_update_draw_properties());
 
   SetupDrawPropertiesAndUpdateTiles(
       active_layer_, 0.5f, 0.5f, 0.5f, 0.5f, false);
   active_layer_->tilings()->RemoveAllTilings();
-  PictureLayerTiling* tiling = active_layer_->tilings()->AddTiling(0.5f);
-  active_layer_->tilings()->AddTiling(1.5f);
-  active_layer_->tilings()->AddTiling(0.25f);
+  PictureLayerTiling* tiling = active_layer_->AddTiling(0.5f);
+  active_layer_->AddTiling(1.5f);
+  active_layer_->AddTiling(0.25f);
   tiling->set_resolution(HIGH_RESOLUTION);
 
   // Sanity checks.
@@ -2159,14 +2353,13 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
   // 1.0f). Note that we should also ensure that the pending layer needs post
   // commit initialization, since this is what would happen during commit. In
   // other words we want the pending layer to sync from the active layer.
-  pending_layer_->SetBounds(gfx::Size(1, 1));
-  pending_layer_->SetNeedsPostCommitInitialization();
-  pending_layer_->set_twin_layer(NULL);
-  active_layer_->set_twin_layer(NULL);
-  EXPECT_TRUE(pending_layer_->needs_post_commit_initialization());
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, gfx::Size(1, 1));
+  SetupPendingTree(pending_pile);
 
   // Update the draw properties: sync from active tree should happen here.
   host_impl_.pending_tree()->UpdateDrawProperties();
+  EXPECT_FALSE(pending_layer_->needs_post_commit_initialization());
 
   // Another sanity check.
   ASSERT_EQ(1.f, pending_layer_->MinimumContentsScale());
@@ -2273,15 +2466,14 @@ TEST_F(PictureLayerImplTest, PinchingTooSmall) {
 
 class DeferredInitPictureLayerImplTest : public PictureLayerImplTest {
  public:
-  virtual void InitializeRenderer() OVERRIDE {
+  void InitializeRenderer() override {
     bool delegated_rendering = false;
-    host_impl_.InitializeRenderer(
-        FakeOutputSurface::CreateDeferredGL(
-            scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
-            delegated_rendering).PassAs<OutputSurface>());
+    host_impl_.InitializeRenderer(FakeOutputSurface::CreateDeferredGL(
+        scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
+        delegated_rendering));
   }
 
-  virtual void SetUp() OVERRIDE {
+  virtual void SetUp() override {
     PictureLayerImplTest::SetUp();
 
     // Create some default active and pending trees.
@@ -2550,44 +2742,6 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) {
                                maximum_animation_scale,
                                animating_transform);
   EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);
-
-  static_cast<FakePicturePileImpl*>(pending_layer_->pile())->set_has_text(true);
-  static_cast<FakePicturePileImpl*>(active_layer_->pile())->set_has_text(true);
-
-  // Since we're GPU-rasterizing but have text, starting an animation should
-  // cause tiling resolution to get set to the maximum animation scale.
-  animating_transform = true;
-  contents_scale = 2.f;
-  maximum_animation_scale = 3.f;
-
-  SetContentsScaleOnBothLayers(contents_scale,
-                               device_scale,
-                               page_scale,
-                               maximum_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,
-                               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,
-                               animating_transform);
-  EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f);
 }
 
 TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
@@ -2656,7 +2810,7 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
 
   EXPECT_TRUE(reached_prepaint);
   EXPECT_EQ(0u, non_ideal_tile_count);
-  EXPECT_EQ(1u, low_res_tile_count);
+  EXPECT_EQ(0u, low_res_tile_count);
   EXPECT_EQ(16u, high_res_tile_count);
   EXPECT_EQ(low_res_tile_count + high_res_tile_count + non_ideal_tile_count,
             unique_tiles.size());
@@ -2706,17 +2860,14 @@ TEST_F(PictureLayerImplTest, LayerRasterTileIterator) {
        tile_it != high_res_tiles.end();
        ++tile_it) {
     Tile* tile = *tile_it;
-    ManagedTileState::TileVersion& tile_version =
-        tile->GetTileVersionForTesting(
-            tile->DetermineRasterModeForTree(ACTIVE_TREE));
-    tile_version.SetSolidColorForTesting(SK_ColorRED);
+    ManagedTileState::DrawInfo& draw_info = tile->draw_info();
+    draw_info.SetSolidColorForTesting(SK_ColorRED);
   }
 
   non_ideal_tile_count = 0;
   low_res_tile_count = 0;
   high_res_tile_count = 0;
-  for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, false);
-       it;
+  for (it = PictureLayerImpl::LayerRasterTileIterator(pending_layer_, true); it;
        ++it) {
     Tile* tile = *it;
     TilePriority priority = tile->priority(PENDING_TREE);
@@ -2780,7 +2931,7 @@ TEST_F(PictureLayerImplTest, LayerEvictionTileIterator) {
          ++iter) {
       if (mark_required) {
         number_of_marked_tiles++;
-        iter->MarkRequiredForActivation();
+        iter->set_required_for_activation(true);
       } else {
         number_of_unmarked_tiles++;
       }
@@ -2809,7 +2960,7 @@ TEST_F(PictureLayerImplTest, LayerEvictionTileIterator) {
   float expected_scales[] = {2.0f, 0.3f, 0.7f, low_res_factor, 1.0f};
   size_t scale_index = 0;
   bool reached_visible = false;
-  Tile* last_tile = NULL;
+  Tile* last_tile = nullptr;
   for (it = PictureLayerImpl::LayerEvictionTileIterator(
            pending_layer_, SAME_PRIORITY_FOR_BOTH_TREES);
        it;
@@ -2992,7 +3143,6 @@ TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) {
 
   CreateHighLowResAndSetAllTilesVisible();
   active_layer_->SetAllTilesReady();
-  pending_layer_->MarkVisibleResourcesAsRequired();
 
   // All pending layer tiles required are not ready.
   EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
@@ -3020,7 +3170,6 @@ TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) {
 
   CreateHighLowResAndSetAllTilesVisible();
   active_layer_->SetAllTilesReady();
-  pending_layer_->MarkVisibleResourcesAsRequired();
 
   // All pending layer tiles required are not ready.
   EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
@@ -3049,8 +3198,6 @@ TEST_F(PictureLayerImplTest,
   // And all the low-res tiles in the pending layer.
   pending_layer_->SetAllTilesReadyInTiling(pending_layer_->LowResTiling());
 
-  pending_layer_->MarkVisibleResourcesAsRequired();
-
   // The unshared high-res tiles are not ready, so we cannot activate.
   EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
 
@@ -3073,8 +3220,6 @@ TEST_F(PictureLayerImplTest, SharedActiveHighResReadyNotEnoughToActivate) {
   // Initialize all high-res tiles in the active layer.
   active_layer_->SetAllTilesReadyInTiling(active_layer_->HighResTiling());
 
-  pending_layer_->MarkVisibleResourcesAsRequired();
-
   // The unshared high-res tiles are not ready, so we cannot activate.
   EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
 
@@ -3149,28 +3294,7 @@ TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) {
                   pending_layer_->tilings()->tiling_at(0)->contents_scale());
 }
 
-TEST_F(NoLowResPictureLayerImplTest, MarkRequiredNullTiles) {
-  gfx::Size tile_size(100, 100);
-  gfx::Size layer_bounds(1000, 1000);
-
-  scoped_refptr<FakePicturePileImpl> pending_pile =
-      FakePicturePileImpl::CreateEmptyPile(tile_size, layer_bounds);
-  // Layers with entirely empty piles can't get tilings.
-  pending_pile->AddRecordingAt(0, 0);
-
-  SetupPendingTree(pending_pile);
-
-  ASSERT_TRUE(pending_layer_->CanHaveTilings());
-  pending_layer_->AddTiling(1.0f);
-  pending_layer_->AddTiling(2.0f);
-
-  // It should be safe to call this (and MarkVisibleResourcesAsRequired)
-  // on a layer with no recordings.
-  host_impl_.pending_tree()->UpdateDrawProperties();
-  pending_layer_->MarkVisibleResourcesAsRequired();
-}
-
-TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
+TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfShared) {
   gfx::Size layer_bounds(400, 400);
   gfx::Size tile_size(100, 100);
   SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
@@ -3183,11 +3307,13 @@ TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfAllHighResTilesShared) {
 
   // All tiles shared (no invalidation), so even though the active tree's
   // tiles aren't ready, there is nothing required.
-  pending_layer_->MarkVisibleResourcesAsRequired();
-  AssertNoTilesRequired(pending_layer_->HighResTiling());
-  if (host_impl_.settings().create_low_res_tiling) {
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  if (host_impl_.settings().create_low_res_tiling)
+    pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  AssertAllTilesRequired(pending_layer_->HighResTiling());
+  if (host_impl_.settings().create_low_res_tiling)
     AssertNoTilesRequired(pending_layer_->LowResTiling());
-  }
 }
 
 TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
@@ -3216,7 +3342,10 @@ TEST_F(NoLowResPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) {
 
   // Since the active layer has no tiles at all, the pending layer doesn't
   // need content in order to activate.
-  pending_layer_->MarkVisibleResourcesAsRequired();
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+  if (host_impl_.settings().create_low_res_tiling)
+    pending_layer_->LowResTiling()->UpdateAllTilePrioritiesForTesting();
+
   AssertNoTilesRequired(pending_layer_->HighResTiling());
   if (host_impl_.settings().create_low_res_tiling)
     AssertNoTilesRequired(pending_layer_->LowResTiling());
@@ -3261,11 +3390,8 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
   gfx::Rect visible_rect_for_tile_priority =
       active_layer_->visible_rect_for_tile_priority();
   EXPECT_FALSE(visible_rect_for_tile_priority.IsEmpty());
-  gfx::Rect viewport_rect_for_tile_priority =
-      active_layer_->viewport_rect_for_tile_priority();
-  EXPECT_FALSE(viewport_rect_for_tile_priority.IsEmpty());
   gfx::Transform screen_space_transform_for_tile_priority =
-      active_layer_->screen_space_transform_for_tile_priority();
+      active_layer_->screen_space_transform();
 
   // Expand viewport and set it as invalid for prioritizing tiles.
   // Should update viewport and transform, but not update visible rect.
@@ -3285,10 +3411,9 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
                                         resourceless_software_draw);
   active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
 
-  // Viewport and transform for tile priority are updated.
-  EXPECT_EQ(viewport, active_layer_->viewport_rect_for_tile_priority());
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      transform, active_layer_->screen_space_transform_for_tile_priority());
+  // Transform for tile priority is updated.
+  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+                                  active_layer_->screen_space_transform());
   // Visible rect for tile priority retains old value.
   EXPECT_EQ(visible_rect_for_tile_priority,
             active_layer_->visible_rect_for_tile_priority());
@@ -3306,13 +3431,9 @@ TEST_F(NoLowResPictureLayerImplTest, InvalidViewportForPrioritizingTiles) {
                                         resourceless_software_draw);
   active_layer_->UpdateTiles(Occlusion(), resourceless_software_draw);
 
-  EXPECT_TRANSFORMATION_MATRIX_EQ(
-      transform, active_layer_->screen_space_transform_for_tile_priority());
+  EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
+                                  active_layer_->screen_space_transform());
   EXPECT_EQ(viewport, active_layer_->visible_rect_for_tile_priority());
-
-  // Match the reverse translate in |transform|.
-  EXPECT_EQ(viewport - gfx::Vector2d(1, 1),
-            active_layer_->viewport_rect_for_tile_priority());
 }
 
 TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) {
@@ -3532,7 +3653,6 @@ TEST_F(NoLowResPictureLayerImplTest, ReleaseResources) {
 }
 
 TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
 
   gfx::Size tile_size(400, 400);
@@ -3558,24 +3678,25 @@ TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) {
                               SK_MScalar1 / max_contents_scale);
 
   AppendQuadsData data;
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &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 content_to_target_transform should be scaled by the
   // MaximumTilingContentsScale on the layer.
   EXPECT_EQ(scaled_draw_transform.ToString(),
-            render_pass->shared_quad_state_list[0]
+            render_pass->shared_quad_state_list.front()
                 ->content_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[0]->content_bounds.ToString());
+  EXPECT_EQ(
+      gfx::Size(2500u, 5000u).ToString(),
+      render_pass->shared_quad_state_list.front()->content_bounds.ToString());
   // The visible_content_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[0]->visible_content_rect.ToString());
+  EXPECT_EQ(gfx::Rect(0u, 0u, 2500u, 5000u).ToString(),
+            render_pass->shared_quad_state_list.front()
+                ->visible_content_rect.ToString());
 }
 
 TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) {
@@ -3594,7 +3715,7 @@ TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) {
 
   scoped_refptr<FakePicturePileImpl> pending_pile =
       FakePicturePileImpl::CreateFilledPile(tile_size, bounds);
-  pending_pile->set_is_mask(true);
+  pending_pile->SetIsMask(true);
   scoped_ptr<FakePictureLayerImpl> mask = FakePictureLayerImpl::CreateWithPile(
       host_impl_.pending_tree(), 3, pending_pile);
 
@@ -3603,7 +3724,7 @@ TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) {
   mask->SetDrawsContent(true);
 
   FakePictureLayerImpl* pending_mask_content = mask.get();
-  layer_with_mask->SetMaskLayer(mask.PassAs<LayerImpl>());
+  layer_with_mask->SetMaskLayer(mask.Pass());
 
   scoped_ptr<FakePictureLayerImpl> child_of_layer_with_mask =
       FakePictureLayerImpl::Create(host_impl_.pending_tree(), 4);
@@ -3612,9 +3733,9 @@ TEST_F(PictureLayerImplTest, UpdateTilesForMasksWithNoVisibleContent) {
   child_of_layer_with_mask->SetContentBounds(bounds);
   child_of_layer_with_mask->SetDrawsContent(true);
 
-  layer_with_mask->AddChild(child_of_layer_with_mask.PassAs<LayerImpl>());
+  layer_with_mask->AddChild(child_of_layer_with_mask.Pass());
 
-  root->AddChild(layer_with_mask.PassAs<LayerImpl>());
+  root->AddChild(layer_with_mask.Pass());
 
   host_impl_.pending_tree()->SetRootLayer(root.Pass());
 
@@ -3627,9 +3748,8 @@ class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
  public:
   PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() {}
 
-  virtual void InitializeRenderer() OVERRIDE {
-    host_impl_.InitializeRenderer(
-        FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>());
+  void InitializeRenderer() override {
+    host_impl_.InitializeRenderer(FakeOutputSurface::CreateDelegating3d());
   }
 };
 
@@ -3667,12 +3787,11 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer,
   host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
   host_impl_.ManageTiles();
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_HARDWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_HARDWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+  active_layer_->DidDraw(nullptr);
 
   // Even when OOM, quads should be produced, and should be different material
   // from quads with resource.
@@ -3700,7 +3819,7 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest {
          ++priority_count) {
       TreePriority tree_priority = static_cast<TreePriority>(priority_count);
       size_t occluded_tile_count = 0u;
-      Tile* last_tile = NULL;
+      Tile* last_tile = nullptr;
 
       for (PictureLayerImpl::LayerEvictionTileIterator it =
                PictureLayerImpl::LayerEvictionTileIterator(layer,
@@ -3780,7 +3899,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
     if (tile_is_visible)
       unoccluded_tile_count++;
   }
-  EXPECT_EQ(unoccluded_tile_count, 25 + 4);
+  EXPECT_EQ(unoccluded_tile_count, 25);
 
   // Partial occlusion.
   pending_layer_->AddChild(LayerImpl::Create(host_impl_.pending_tree(), 1));
@@ -3810,7 +3929,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
     if (tile_is_visible)
       unoccluded_tile_count++;
   }
-  EXPECT_EQ(unoccluded_tile_count, 20 + 2);
+  EXPECT_EQ(20, unoccluded_tile_count);
 
   // Full occlusion.
   layer1->SetPosition(gfx::Point(0, 0));
@@ -3898,6 +4017,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
 
   for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+    tiling->UpdateAllTilePrioritiesForTesting();
 
     occluded_tile_count = 0;
     for (PictureLayerTiling::CoverageIterator iter(
@@ -3937,6 +4057,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
 
   for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+    tiling->UpdateAllTilePrioritiesForTesting();
 
     occluded_tile_count = 0;
     for (PictureLayerTiling::CoverageIterator iter(
@@ -3956,10 +4077,10 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
     }
     switch (i) {
       case 0:
-        EXPECT_EQ(occluded_tile_count, 25);
+        EXPECT_EQ(25, occluded_tile_count);
         break;
       case 1:
-        EXPECT_EQ(occluded_tile_count, 4);
+        EXPECT_EQ(4, occluded_tile_count);
         break;
       default:
         NOTREACHED();
@@ -4006,6 +4127,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) {
            tilings.begin();
        tiling_iterator != tilings.end();
        ++tiling_iterator) {
+    (*tiling_iterator)->UpdateAllTilePrioritiesForTesting();
     std::vector<Tile*> tiles = (*tiling_iterator)->AllTilesForTesting();
 
     occluded_tile_count = 0;
@@ -4073,6 +4195,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
 
   for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
+    tiling->UpdateAllTilePrioritiesForTesting();
 
     for (PictureLayerTiling::CoverageIterator iter(
              tiling,
@@ -4087,8 +4210,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
       // All tiles are unoccluded on the pending tree.
       EXPECT_FALSE(tile->is_occluded(PENDING_TREE));
 
-      Tile* twin_tile =
-          pending_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j());
+      Tile* twin_tile = pending_layer_->GetPendingOrActiveTwinTiling(tiling)
+                            ->TileAt(iter.i(), iter.j());
       gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
           tile->content_rect(), 1.0f / tile->contents_scale());
 
@@ -4122,8 +4245,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) {
         continue;
       const Tile* tile = *iter;
 
-      Tile* twin_tile =
-          active_layer_->GetTwinTiling(tiling)->TileAt(iter.i(), iter.j());
+      Tile* twin_tile = active_layer_->GetPendingOrActiveTwinTiling(tiling)
+                            ->TileAt(iter.i(), iter.j());
       gfx::Rect scaled_content_rect = ScaleToEnclosingRect(
           tile->content_rect(), 1.0f / tile->contents_scale());
 
@@ -4217,6 +4340,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
   for (size_t i = 0; i < pending_layer_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = pending_layer_->tilings()->tiling_at(i);
     tiling->CreateAllTilesForTesting();
+    tiling->UpdateAllTilePrioritiesForTesting();
 
     size_t occluded_tile_count_on_pending = 0u;
     size_t occluded_tile_count_on_active = 0u;
@@ -4251,6 +4375,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
   for (size_t i = 0; i < active_layer_->num_tilings(); ++i) {
     PictureLayerTiling* tiling = active_layer_->tilings()->tiling_at(i);
     tiling->CreateAllTilesForTesting();
+    tiling->UpdateAllTilePrioritiesForTesting();
 
     size_t occluded_tile_count_on_pending = 0u;
     size_t occluded_tile_count_on_active = 0u;
@@ -4298,6 +4423,33 @@ TEST_F(OcclusionTrackingPictureLayerImplTest,
                                    total_expected_occluded_tile_count);
 }
 
+TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) {
+  gfx::Size tile_size(102, 102);
+  gfx::Size layer_bounds(1000, 1000);
+
+  scoped_refptr<FakePicturePileImpl> pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  SetupPendingTree(pile);
+  EXPECT_FALSE(pending_layer_->GetPendingOrActiveTwinLayer());
+
+  ActivateTree();
+  EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
+
+  SetupPendingTree(pile);
+  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()->DetachLayerTree();
+  EXPECT_FALSE(active_layer_->GetPendingOrActiveTwinLayer());
+}
+
 TEST_F(PictureLayerImplTest, RecycledTwinLayer) {
   gfx::Size tile_size(102, 102);
   gfx::Size layer_bounds(1000, 1000);
@@ -4319,7 +4471,9 @@ TEST_F(PictureLayerImplTest, RecycledTwinLayer) {
   EXPECT_TRUE(active_layer_->GetRecycledTwinLayer());
   EXPECT_EQ(old_pending_layer_, active_layer_->GetRecycledTwinLayer());
 
-  host_impl_.ResetRecycleTreeForTesting();
+  // Make an empty pending tree.
+  host_impl_.CreatePendingTree();
+  host_impl_.pending_tree()->DetachLayerTree();
   EXPECT_FALSE(active_layer_->GetRecycledTwinLayer());
 }
 
@@ -4378,12 +4532,11 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) {
     host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
   }
 
-  MockOcclusionTracker<LayerImpl> occlusion_tracker;
   scoped_ptr<RenderPass> render_pass = RenderPass::Create();
   AppendQuadsData data;
-  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
-  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
-  active_layer_->DidDraw(NULL);
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, nullptr);
+  active_layer_->AppendQuads(render_pass.get(), Occlusion(), &data);
+  active_layer_->DidDraw(nullptr);
 
   DrawQuad::Material expected = test_for_solid
                                     ? DrawQuad::Material::SOLID_COLOR
@@ -4471,5 +4624,129 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) {
   EXPECT_EQ(0u, active_layer_->tilings()->num_tilings());
 }
 
+TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) {
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentBeginFrameArgs(
+      CreateBeginFrameArgsForTesting(time_ticks));
+
+  gfx::Size tile_size(100, 100);
+  gfx::Size layer_bounds(400, 4000);
+
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+
+  SetupTrees(pending_pile, active_pile);
+
+  Region invalidation;
+  gfx::Rect viewport = gfx::Rect(0, 0, 100, 100);
+  gfx::Transform transform;
+
+  host_impl_.SetRequiresHighResToDraw();
+
+  // Update tiles.
+  pending_layer_->draw_properties().visible_content_rect = viewport;
+  pending_layer_->draw_properties().screen_space_transform = transform;
+  SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  // Ensure we can't activate.
+  EXPECT_FALSE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+
+  // 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_content_rect = viewport;
+  pending_layer_->draw_properties().screen_space_transform = transform;
+  SetupDrawPropertiesAndUpdateTiles(pending_layer_, 1.f, 1.f, 1.f, 1.f, false);
+  pending_layer_->HighResTiling()->UpdateAllTilePrioritiesForTesting();
+
+  // 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);
+  }
+
+  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
+
+  // Ensure we can activate.
+  EXPECT_TRUE(pending_layer_->AllTilesRequiredForActivationAreReadyToDraw());
+}
+
+class TileSizeSettings : public ImplSidePaintingSettings {
+ public:
+  TileSizeSettings() {
+    default_tile_size = gfx::Size(100, 100);
+    max_untiled_layer_size = gfx::Size(200, 200);
+  }
+};
+
+class TileSizeTest : public PictureLayerImplTest {
+ public:
+  TileSizeTest() : PictureLayerImplTest(TileSizeSettings()) {}
+};
+
+TEST_F(TileSizeTest, TileSizes) {
+  host_impl_.CreatePendingTree();
+
+  LayerTreeImpl* pending_tree = host_impl_.pending_tree();
+  scoped_ptr<FakePictureLayerImpl> layer =
+      FakePictureLayerImpl::Create(pending_tree, id_);
+
+  host_impl_.SetViewportSize(gfx::Size(1000, 1000));
+  gfx::Size result;
+
+  host_impl_.SetUseGpuRasterization(false);
+
+  // 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_.SetUseGpuRasterization(true);
+  host_impl_.SetViewportSize(gfx::Size(2000, 2000));
+  result = layer->CalculateTileSize(gfx::Size(10000, 10000));
+  EXPECT_EQ(result.width(), 2000);
+  EXPECT_EQ(result.height(), 500 + 2);
+
+  // 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));
+  result = layer->CalculateTileSize(gfx::Size(447, 10000));
+  EXPECT_EQ(result.width(), 448);
+  EXPECT_EQ(result.height(), 500 + 2);
+
+  // 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(), 500 + 2);
+}
+
 }  // namespace
 }  // namespace cc