// Copyright 2011 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/tiled_layer.h"

#include <limits>
#include <vector>

#include "base/run_loop.h"
#include "cc/resources/bitmap_content_layer_updater.h"
#include "cc/resources/layer_painter.h"
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_update_controller.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_proxy.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/tiled_layer_test_common.h"
#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/transform.h"

namespace cc {
namespace {

class TestOcclusionTracker : public OcclusionTracker<Layer> {
 public:
  TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000)) {
    stack_.push_back(StackObject());
  }

  void SetRenderTarget(Layer* render_target) {
    stack_.back().target = render_target;
  }

  void SetOcclusion(const SimpleEnclosedRegion& occlusion) {
    stack_.back().occlusion_from_inside_target = occlusion;
  }
};

class SynchronousOutputSurfaceClient : public FakeLayerTreeHostClient {
 public:
  SynchronousOutputSurfaceClient()
      : FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D) {}

  bool EnsureOutputSurfaceCreated() {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        run_loop_.QuitClosure(),
        base::TimeDelta::FromSeconds(5));
    run_loop_.Run();
    return output_surface_created_;
  }

  void DidInitializeOutputSurface() override {
    FakeLayerTreeHostClient::DidInitializeOutputSurface();
    output_surface_created_ = true;
    run_loop_.Quit();
  }

  void DidFailToInitializeOutputSurface() override {
    FakeLayerTreeHostClient::DidFailToInitializeOutputSurface();
    output_surface_created_ = false;
    run_loop_.Quit();
  }

 private:
  bool output_surface_created_;
  base::RunLoop run_loop_;
};

class TiledLayerTest : public testing::Test {
 public:
  TiledLayerTest()
      : proxy_(nullptr),
        output_surface_(FakeOutputSurface::Create3d()),
        queue_(make_scoped_ptr(new ResourceUpdateQueue)),
        impl_thread_("ImplThread"),
        occlusion_(nullptr) {
    settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
    settings_.layer_transforms_should_scale_layer_contents = true;
    settings_.verify_property_trees = true;
    settings_.impl_side_painting = false;
  }

  void SetUp() override {
    impl_thread_.Start();
    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
    layer_tree_host_ = LayerTreeHost::CreateThreaded(
        &synchonous_output_surface_client_, shared_bitmap_manager_.get(),
        nullptr, nullptr, settings_, base::MessageLoopProxy::current(),
        impl_thread_.message_loop_proxy(), nullptr);
    synchonous_output_surface_client_.SetLayerTreeHost(layer_tree_host_.get());
    proxy_ = layer_tree_host_->proxy();
    resource_manager_ = PrioritizedResourceManager::Create(proxy_);
    layer_tree_host_->SetLayerTreeHostClientReady();
    CHECK(synchonous_output_surface_client_.EnsureOutputSurfaceCreated());

    layer_tree_host_->SetRootLayer(Layer::Create());

    CHECK(output_surface_->BindToClient(&output_surface_client_));

    DebugScopedSetImplThreadAndMainThreadBlocked
        impl_thread_and_main_thread_blocked(proxy_);
    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
                                                  shared_bitmap_manager_.get(),
                                                  nullptr,
                                                  nullptr,
                                                  0,
                                                  false,
                                                  1);
    host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(
        proxy_, shared_bitmap_manager_.get(), nullptr));
  }

  ~TiledLayerTest() override {
    ResourceManagerClearAllMemory(resource_manager_.get(),
                                  resource_provider_.get());

    DebugScopedSetImplThreadAndMainThreadBlocked
    impl_thread_and_main_thread_blocked(proxy_);
    resource_provider_ = nullptr;
    host_impl_ = nullptr;
  }

  void ResourceManagerClearAllMemory(
      PrioritizedResourceManager* resource_manager,
      ResourceProvider* resource_provider) {
    {
      DebugScopedSetImplThreadAndMainThreadBlocked
      impl_thread_and_main_thread_blocked(proxy_);
      resource_manager->ClearAllMemory(resource_provider);
      resource_manager->ReduceMemory(resource_provider);
    }
    resource_manager->UnlinkAndClearEvictedBackings();
  }

  void UpdateTextures() {
    DebugScopedSetImplThreadAndMainThreadBlocked
    impl_thread_and_main_thread_blocked(proxy_);
    DCHECK(queue_);
    scoped_ptr<ResourceUpdateController> update_controller =
        ResourceUpdateController::Create(nullptr,
                                         proxy_->ImplThreadTaskRunner(),
                                         queue_.Pass(),
                                         resource_provider_.get());
    update_controller->Finalize();
    queue_ = make_scoped_ptr(new ResourceUpdateQueue);
  }

  void LayerPushPropertiesTo(FakeTiledLayer* layer,
                             FakeTiledLayerImpl* layer_impl) {
    DebugScopedSetImplThreadAndMainThreadBlocked
    impl_thread_and_main_thread_blocked(proxy_);
    layer->PushPropertiesTo(layer_impl);
    layer->ResetNumDependentsNeedPushProperties();
  }

  void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
    DebugScopedSetMainThread main_thread(proxy_);
    layer->Update(queue_.get(), occluded);
  }

  void CalcDrawProps(RenderSurfaceLayerList* render_surface_layer_list) {
    if (occlusion_)
      occlusion_->SetRenderTarget(layer_tree_host_->root_layer());

    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
        layer_tree_host_->root_layer(),
        layer_tree_host_->device_viewport_size(),
        render_surface_layer_list);
    inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
    inputs.max_texture_size =
        layer_tree_host_->GetRendererCapabilities().max_texture_size;
    inputs.can_adjust_raster_scales = true;
    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
  }

  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
    scoped_refptr<FakeTiledLayer> layer2;
    scoped_ptr<FakeTiledLayerImpl> layer_impl2;
    return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
  }

  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
                     const scoped_refptr<FakeTiledLayer>& layer2,
                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
    // Get textures
    resource_manager_->ClearPriorities();
    if (layer1.get())
      layer1->SetTexturePriorities(priority_calculator_);
    if (layer2.get())
      layer2->SetTexturePriorities(priority_calculator_);
    resource_manager_->PrioritizeTextures();

    // Save paint properties
    if (layer1.get())
      layer1->SavePaintProperties();
    if (layer2.get())
      layer2->SavePaintProperties();

    // Update content
    if (layer1.get())
      layer1->Update(queue_.get(), occlusion_);
    if (layer2.get())
      layer2->Update(queue_.get(), occlusion_);

    bool needs_update = false;
    if (layer1.get())
      needs_update |= layer1->NeedsIdlePaint();
    if (layer2.get())
      needs_update |= layer2->NeedsIdlePaint();

    // Update textures and push.
    UpdateTextures();
    if (layer1.get())
      LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
    if (layer2.get())
      LayerPushPropertiesTo(layer2.get(), layer_impl2.get());

    return needs_update;
  }

 public:
  Proxy* proxy_;
  LayerTreeSettings settings_;
  FakeOutputSurfaceClient output_surface_client_;
  scoped_ptr<OutputSurface> output_surface_;
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
  scoped_ptr<ResourceProvider> resource_provider_;
  scoped_ptr<ResourceUpdateQueue> queue_;
  PriorityCalculator priority_calculator_;
  base::Thread impl_thread_;
  SynchronousOutputSurfaceClient synchonous_output_surface_client_;
  scoped_ptr<LayerTreeHost> layer_tree_host_;
  scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
  scoped_ptr<PrioritizedResourceManager> resource_manager_;
  TestOcclusionTracker* occlusion_;
};

TEST_F(TiledLayerTest, PushDirtyTiles) {
  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));

  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  UpdateAndPush(layer, layer_impl);

  // We should have both tiles on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));

  // Invalidates both tiles, but then only update one of them.
  layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
  UpdateAndPush(layer, layer_impl);

  // We should only have the first tile since the other tile was invalidated but
  // not painted.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
}

TEST_F(TiledLayerTest, Scale) {
  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));

  layer_tree_host_->SetDeviceScaleFactor(1.5);

  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);

  // Change the width so that it doesn't divide cleanly by the scale.
  layer->SetBounds(gfx::Size(101, 200));
  UpdateAndPush(layer, layer_impl);

  EXPECT_EQ(1.5, layer->fake_layer_updater()->last_contents_width_scale());
}

TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;
  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));

  layer_tree_host_->root_layer()->AddChild(layer);

  {
    RenderSurfaceLayerList render_surface_layer_list;

    // The tile size is 100x100, so this invalidates and then paints two tiles.
    layer->SetBounds(gfx::Size(100, 200));
    CalcDrawProps(&render_surface_layer_list);
    UpdateAndPush(layer, layer_impl);

    // We should have both tiles on the impl side.
    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
  }

  {
    RenderSurfaceLayerList render_surface_layer_list;

    // Invalidates part of the top tile...
    layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
    // ....but the area is occluded.
    occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
    CalcDrawProps(&render_surface_layer_list);
    UpdateAndPush(layer, layer_impl);

    // We should still have both tiles, as part of the top tile is still
    // unoccluded.
    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
  }
}

TEST_F(TiledLayerTest, PushDeletedTiles) {
  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));

  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  UpdateAndPush(layer, layer_impl);

  // We should have both tiles on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));

  resource_manager_->ClearPriorities();
  ResourceManagerClearAllMemory(resource_manager_.get(),
                                resource_provider_.get());
  resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);

  // This should drop the tiles on the impl thread.
  LayerPushPropertiesTo(layer.get(), layer_impl.get());

  // We should now have no textures on the impl thread.
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));

  // This should recreate and update one of the deleted textures.
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
  UpdateAndPush(layer, layer_impl);

  // We should have one tiles on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
}

TEST_F(TiledLayerTest, PushIdlePaintTiles) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
  // center.  This paints 1 visible of the 25 invalid tiles.
  layer->SetBounds(gfx::Size(500, 500));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
  bool needs_update = UpdateAndPush(layer, layer_impl);
  // We should need idle-painting for surrounding tiles.
  EXPECT_TRUE(needs_update);

  // We should have one tile on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));

  // For the next four updates, we should detect we still need idle painting.
  for (int i = 0; i < 4; i++) {
    needs_update = UpdateAndPush(layer, layer_impl);
    EXPECT_TRUE(needs_update);
  }

  // We should always finish painting eventually.
  for (int i = 0; i < 20; i++)
    needs_update = UpdateAndPush(layer, layer_impl);

  // We should have pre-painted all of the surrounding tiles.
  for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++)
      EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
  }

  EXPECT_FALSE(needs_update);
}

TEST_F(TiledLayerTest, PredictivePainting) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));

  layer_tree_host_->root_layer()->AddChild(layer);

  // Prepainting should occur in the scroll direction first, and the
  // visible rect should be extruded only along the dominant axis.
  gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
                                  gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
                                  gfx::Vector2d(10, 20),
                                  gfx::Vector2d(-20, 10) };
  // We should push all tiles that touch the extruded visible rect.
  gfx::Rect pushed_visible_tiles[6] = {
    gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
    gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
  };
  // The first pre-paint should also paint first in the scroll
  // direction so we should find one additional tile in the scroll direction.
  gfx::Rect pushed_prepaint_tiles[6] = {
    gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
    gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
  };
  for (int k = 0; k < 6; k++) {
    // The tile size is 100x100. Setup 5x5 tiles with one visible tile
    // in the center.
    gfx::Size bounds = gfx::Size(500, 500);
    gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
    gfx::Rect previous_visible_rect =
        gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
    gfx::Rect next_visible_rect =
        gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());

    // Setup. Use the previous_visible_rect to setup the prediction for next
    // frame.
    layer->SetBounds(bounds);

    RenderSurfaceLayerList render_surface_layer_list;
    CalcDrawProps(&render_surface_layer_list);
    layer->draw_properties().visible_content_rect = previous_visible_rect;
    bool needs_update = UpdateAndPush(layer, layer_impl);

    // Invalidate and move the visible_rect in the scroll direction.
    // Check that the correct tiles have been painted in the visible pass.
    layer->SetNeedsDisplay();
    layer->draw_properties().visible_content_rect = visible_rect;
    needs_update = UpdateAndPush(layer, layer_impl);
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 5; j++)
        EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
                  pushed_visible_tiles[k].Contains(i, j));
    }

    // Move the transform in the same direction without invalidating.
    // Check that non-visible pre-painting occured in the correct direction.
    // Ignore diagonal scrolls here (k > 3) as these have new visible content
    // now.
    if (k <= 3) {
      layer->draw_properties().visible_content_rect = next_visible_rect;
      needs_update = UpdateAndPush(layer, layer_impl);
      for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++)
          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
                    pushed_prepaint_tiles[k].Contains(i, j));
      }
    }

    // We should always finish painting eventually.
    for (int i = 0; i < 20; i++)
      needs_update = UpdateAndPush(layer, layer_impl);
    EXPECT_FALSE(needs_update);
  }
}

TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
  // Start with 2mb of memory, but the test is going to try to use just more
  // than 1mb, so we reduce to 1mb later.
  resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
  scoped_refptr<FakeTiledLayer> layer1 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  scoped_refptr<FakeTiledLayer> layer2 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer1);
  layer_tree_host_->root_layer()->AddChild(layer2);

  // For this test we have two layers. layer1 exhausts most texture memory,
  // leaving room for 2 more tiles from layer2, but not all three tiles. First
  // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
  // we will fail on the third tile of layer2, and this should not leave the
  // second tile in a bad state.

  // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
  // for 2 tiles only in the other layer.
  gfx::Rect layer1_rect(0, 0, 100, 2400);

  // This requires 4*30000 bytes of memory.
  gfx::Rect layer2_rect(0, 0, 100, 300);

  // Paint a single tile in layer2 so that it will idle paint.
  layer1->SetBounds(layer1_rect.size());
  layer2->SetBounds(layer2_rect.size());
  CalcDrawProps(&render_surface_layer_list);
  layer1->draw_properties().visible_content_rect = layer1_rect;
  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
  bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
  // We should need idle-painting for both remaining tiles in layer2.
  EXPECT_TRUE(needs_update);

  // Reduce our memory limits to 1mb.
  resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);

  // Now idle paint layer2. We are going to run out of memory though!
  // Oh well, commit the frame and push.
  for (int i = 0; i < 4; i++) {
    needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
  }

  // Sanity check, we should have textures for the big layer.
  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));

  // We should only have the first two tiles from layer2 since
  // it failed to idle update the last tile.
  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));

  EXPECT_FALSE(needs_update);
  EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
}

TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates one occluded tile, culls it
  // during paint, but prepaints it.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));

  layer->SetBounds(gfx::Size(100, 100));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
  UpdateAndPush(layer, layer_impl);

  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
}

TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  // However, during the paint, we invalidate one of the tiles. This should
  // not prevent the tile from being pushed.
  layer->fake_layer_updater()->SetRectToInvalidate(
      gfx::Rect(0, 50, 100, 50), layer.get());
  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  UpdateAndPush(layer, layer_impl);

  // We should have both tiles on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
}

TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
  scoped_refptr<FakeTiledLayer> layer1 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_refptr<FakeTiledLayer> layer2 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer1);
  layer_tree_host_->root_layer()->AddChild(layer2);

  // Invalidate a tile on layer1, during update of layer 2.
  layer2->fake_layer_updater()->SetRectToInvalidate(
      gfx::Rect(0, 50, 100, 50), layer1.get());
  layer1->SetBounds(gfx::Size(100, 200));
  layer2->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);

  // We should have both tiles on the impl side for all layers.
  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
}

TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
  scoped_refptr<FakeTiledLayer> layer1 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_refptr<FakeTiledLayer> layer2 =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer1);
  layer_tree_host_->root_layer()->AddChild(layer2);

  layer1->fake_layer_updater()->SetRectToInvalidate(
      gfx::Rect(0, 50, 100, 50), layer2.get());
  layer1->SetBounds(gfx::Size(100, 200));
  layer2->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);

  // We should have both tiles on the impl side for all layers.
  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
}

TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
  // Create a LayerTreeHost that has the right viewportsize,
  // so the layer is considered small enough.
  bool run_out_of_memory[2] = { false, true };
  for (int i = 0; i < 2; i++) {
    // Create a layer with 5x5 tiles, with 4x4 size viewport.
    int viewport_width = 4 * FakeTiledLayer::tile_size().width();
    int viewport_height = 4 * FakeTiledLayer::tile_size().width();
    int layer_width = 5 * FakeTiledLayer::tile_size().width();
    int layer_height = 5 * FakeTiledLayer::tile_size().height();
    int memory_for_layer = layer_width * layer_height * 4;
    layer_tree_host_->SetViewportSize(
        gfx::Size(viewport_width, viewport_height));

    // Use 10x5 tiles to run out of memory.
    if (run_out_of_memory[i])
      layer_width *= 2;

    resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);

    scoped_refptr<FakeTiledLayer> layer =
        make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    RenderSurfaceLayerList render_surface_layer_list;

    layer_tree_host_->root_layer()->AddChild(layer);

    // Full size layer with half being visible.
    layer->SetBounds(gfx::Size(layer_width, layer_height));
    gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
    CalcDrawProps(&render_surface_layer_list);

    // Pretend the layer is animating.
    layer->draw_properties().target_space_transform_is_animating = true;
    layer->draw_properties().visible_content_rect = visible_rect;
    layer->SetLayerTreeHost(layer_tree_host_.get());

    // The layer should paint its entire contents on the first paint
    // if it is close to the viewport size and has the available memory.
    layer->SetTexturePriorities(priority_calculator_);
    resource_manager_->PrioritizeTextures();
    layer->SavePaintProperties();
    layer->Update(queue_.get(), nullptr);
    UpdateTextures();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());

    // We should have all the tiles for the small animated layer.
    // We should still have the visible tiles when we didn't
    // have enough memory for all the tiles.
    if (!run_out_of_memory[i]) {
      for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 5; ++j)
          EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
      }
    } else {
      for (int i = 0; i < 10; ++i) {
        for (int j = 0; j < 5; ++j)
          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
      }
    }

    layer->RemoveFromParent();
  }
}

TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // We have enough memory for only the visible rect, so we will run out of
  // memory in first idle paint.
  int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
  resource_manager_->SetMaxMemoryLimitBytes(memory_limit);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  bool needs_update = false;
  layer->SetBounds(gfx::Size(300, 300));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
  for (int i = 0; i < 2; i++)
    needs_update = UpdateAndPush(layer, layer_impl);

  // Idle-painting should see no more priority tiles for painting.
  EXPECT_FALSE(needs_update);

  // We should have one tile on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
}

TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));

  layer_tree_host_->root_layer()->AddChild(layer);

  bool animating[2] = { false, true };
  for (int i = 0; i < 2; i++) {
    // Pretend the layer is animating.
    layer->draw_properties().target_space_transform_is_animating = animating[i];

    // The layer's bounds are empty.
    // Empty layers don't paint or idle-paint.
    layer->SetBounds(gfx::Size());

    RenderSurfaceLayerList render_surface_layer_list;
    CalcDrawProps(&render_surface_layer_list);
    layer->draw_properties().visible_content_rect = gfx::Rect();
    bool needs_update = UpdateAndPush(layer, layer_impl);

    // Empty layers don't have tiles.
    EXPECT_EQ(0u, layer->NumPaintedTiles());

    // Empty layers don't need prepaint.
    EXPECT_FALSE(needs_update);

    // Empty layers don't have tiles.
    EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
  }
}

TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));

  // Alternate between not visible and visible.
  gfx::Rect v(0, 0, 100, 100);
  gfx::Rect nv(0, 0, 0, 0);
  gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
  bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
                          false };

  // We should not have any tiles except for when the layer was visible
  // or after the layer was visible and we didn't invalidate.
  bool have_tile[10] = { false, false, true, true, false, false, true, true,
                         true, true };

  layer_tree_host_->root_layer()->AddChild(layer);

  for (int i = 0; i < 10; i++) {
    layer->SetBounds(gfx::Size(100, 100));

    RenderSurfaceLayerList render_surface_layer_list;
    CalcDrawProps(&render_surface_layer_list);
    layer->draw_properties().visible_content_rect = visible_rect[i];

    if (invalidate[i])
      layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
    bool needs_update = UpdateAndPush(layer, layer_impl);

    // We should never signal idle paint, as we painted the entire layer
    // or the layer was not visible.
    EXPECT_FALSE(needs_update);
    EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
  }
}

TEST_F(TiledLayerTest, InvalidateFromPrepare) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
  UpdateAndPush(layer, layer_impl);

  // We should have both tiles on the impl side.
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));

  layer->fake_layer_updater()->ClearPrepareCount();
  // Invoke update again. As the layer is valid update shouldn't be invoked on
  // the LayerUpdater.
  UpdateAndPush(layer, layer_impl);
  EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());

  // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
  // update.
  layer->fake_layer_updater()->SetRectToInvalidate(
      gfx::Rect(25, 25, 50, 50), layer.get());
  layer->fake_layer_updater()->ClearPrepareCount();
  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
  UpdateAndPush(layer, layer_impl);
  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
  layer->fake_layer_updater()->ClearPrepareCount();

  // The layer should still be invalid as update invoked invalidate.
  UpdateAndPush(layer, layer_impl);  // visible
  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
}

TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
  // The update rect (that indicates what was actually painted) should be in
  // layer space, not the content space.
  scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
      new FakeTiledLayerWithScaledBounds(resource_manager_.get()));

  layer_tree_host_->root_layer()->AddChild(layer);

  gfx::Rect layer_bounds(0, 0, 300, 200);
  gfx::Rect content_bounds(0, 0, 150, 250);

  layer->SetBounds(layer_bounds.size());
  layer->SetContentBounds(content_bounds.size());
  layer->draw_properties().visible_content_rect = content_bounds;
  layer->draw_properties().contents_scale_x = .5f;
  layer->draw_properties().contents_scale_y = 1.25f;

  // On first update, the update_rect includes all tiles, even beyond the
  // boundaries of the layer.
  // However, it should still be in layer space, not content space.
  layer->InvalidateContentRect(content_bounds);

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);

  // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer->update_rect());
  UpdateTextures();

  // After the tiles are updated once, another invalidate only needs to update
  // the bounds of the layer.
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->InvalidateContentRect(content_bounds);
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
  UpdateTextures();

  // Partial re-paint should also be represented by the update rect in layer
  // space, not content space.
  gfx::Rect partial_damage(30, 100, 10, 10);
  layer->InvalidateContentRect(partial_damage);
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer->update_rect());
}

TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  scoped_ptr<FakeTiledLayerImpl> layer_impl =
      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // Create a layer with one tile.
  layer->SetBounds(gfx::Size(100, 100));
  CalcDrawProps(&render_surface_layer_list);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
  layer->Update(queue_.get(), nullptr);
  UpdateTextures();
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
                       layer->last_needs_display_rect());

  // Push the tiles to the impl side and check that there is exactly one.
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
  UpdateTextures();
  LayerPushPropertiesTo(layer.get(), layer_impl.get());
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));

  layer->SetNeedsDisplayRect(gfx::Rect());
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());

  // Change the contents scale.
  layer->UpdateContentsScale(2.f);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);

  // The impl side should get 2x2 tiles now.
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
  UpdateTextures();
  LayerPushPropertiesTo(layer.get(), layer_impl.get());
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));

  // Verify that changing the contents scale caused invalidation, and
  // that the layer-space rectangle requiring painting is not scaled.
  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
                       layer->last_needs_display_rect());

  // Invalidate the entire layer again, but do not paint. All tiles should be
  // gone now from the impl side.
  layer->SetNeedsDisplay();
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();

  LayerPushPropertiesTo(layer.get(), layer_impl.get());
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
}

TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
  // Create two 300 x 300 tiled layers.
  gfx::Size content_bounds(300, 300);
  gfx::Rect content_rect(content_bounds);

  // We have enough memory for only one of the two layers.
  int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.

  scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
  scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
  root_layer->AddChild(child_layer);

  root_layer->SetBounds(content_bounds);
  root_layer->draw_properties().visible_content_rect = content_rect;
  root_layer->SetPosition(gfx::PointF(0, 0));
  child_layer->SetBounds(content_bounds);
  child_layer->draw_properties().visible_content_rect = content_rect;
  child_layer->SetPosition(gfx::PointF(0, 0));
  root_layer->InvalidateContentRect(content_rect);
  child_layer->InvalidateContentRect(content_rect);

  layer_tree_host_->SetRootLayer(root_layer);
  layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
      memory_limit);

  layer_tree_host_->UpdateLayers(queue_.get());

  // We'll skip the root layer.
  EXPECT_TRUE(root_layer->SkipsDraw());
  EXPECT_FALSE(child_layer->SkipsDraw());

  layer_tree_host_->CommitComplete();

  // Remove the child layer.
  root_layer->RemoveAllChildren();

  layer_tree_host_->UpdateLayers(queue_.get());
  EXPECT_FALSE(root_layer->SkipsDraw());

  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
                                resource_provider_.get());
  layer_tree_host_->SetRootLayer(nullptr);
}

TEST_F(TiledLayerTest, ResizeToSmaller) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));

  layer_tree_host_->root_layer()->AddChild(layer);

  layer->SetBounds(gfx::Size(700, 700));
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
  layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);

  layer->SetBounds(gfx::Size(200, 200));
  layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
}

TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));

  layer_tree_host_->root_layer()->AddChild(layer);

  int size = 1 << 30;
  layer->SetBounds(gfx::Size(size, size));
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
  layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));

  // Ensure no crash for bounds where size * size would overflow an int.
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
}

class TiledLayerPartialUpdateTest : public TiledLayerTest {
 public:
  TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
};

TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
  // Create one 300 x 200 tiled layer with 3 x 2 tiles.
  gfx::Size content_bounds(300, 200);
  gfx::Rect content_rect(content_bounds);

  scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
  layer->SetBounds(content_bounds);
  layer->SetPosition(gfx::PointF(0, 0));
  layer->draw_properties().visible_content_rect = content_rect;
  layer->InvalidateContentRect(content_rect);

  layer_tree_host_->SetRootLayer(layer);
  layer_tree_host_->SetViewportSize(gfx::Size(300, 200));

  // Full update of all 6 tiles.
  layer_tree_host_->UpdateLayers(queue_.get());
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    EXPECT_EQ(6u, queue_->FullUploadSize());
    EXPECT_EQ(0u, queue_->PartialUploadSize());
    UpdateTextures();
    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());
    layer->fake_layer_updater()->ClearUpdateCount();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  // Full update of 3 tiles and partial update of 3 tiles.
  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
  layer_tree_host_->UpdateLayers(queue_.get());
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    EXPECT_EQ(3u, queue_->FullUploadSize());
    EXPECT_EQ(3u, queue_->PartialUploadSize());
    UpdateTextures();
    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());
    layer->fake_layer_updater()->ClearUpdateCount();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  // Partial update of 6 tiles.
  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    layer_tree_host_->UpdateLayers(queue_.get());
    EXPECT_EQ(2u, queue_->FullUploadSize());
    EXPECT_EQ(4u, queue_->PartialUploadSize());
    UpdateTextures();
    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());
    layer->fake_layer_updater()->ClearUpdateCount();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  // Checkerboard all tiles.
  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  // Partial update of 6 checkerboard tiles.
  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    layer_tree_host_->UpdateLayers(queue_.get());
    EXPECT_EQ(6u, queue_->FullUploadSize());
    EXPECT_EQ(0u, queue_->PartialUploadSize());
    UpdateTextures();
    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());
    layer->fake_layer_updater()->ClearUpdateCount();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  // Partial update of 4 tiles.
  layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
  {
    scoped_ptr<FakeTiledLayerImpl> layer_impl =
        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    layer_tree_host_->UpdateLayers(queue_.get());
    EXPECT_EQ(0u, queue_->FullUploadSize());
    EXPECT_EQ(4u, queue_->PartialUploadSize());
    UpdateTextures();
    EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());
    layer->fake_layer_updater()->ClearUpdateCount();
    LayerPushPropertiesTo(layer.get(), layer_impl.get());
  }
  layer_tree_host_->CommitComplete();

  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
                                resource_provider_.get());
  layer_tree_host_->SetRootLayer(nullptr);
}

TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));

  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  RenderSurfaceLayerList render_surface_layer_list;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100, so this invalidates and then paints two tiles.
  layer->SetBounds(gfx::Size(100, 200));
  CalcDrawProps(&render_surface_layer_list);

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), nullptr);
  EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100.

  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
  layer->SetBounds(gfx::Size(600, 600));
  CalcDrawProps(&render_surface_layer_list);

  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
  layer->draw_properties().drawable_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->draw_properties().visible_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();

  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();

  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100.

  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
  layer->SetBounds(gfx::Size(600, 600));
  CalcDrawProps(&render_surface_layer_list);

  // The partially occluded tiles (by the 150 occlusion height) are visible
  // beyond the occlusion, so not culled.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();

  // Now the visible region stops at the edge of the occlusion so the partly
  // visible tiles become fully occluded.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();

  // Now the visible region is even smaller than the occlusion, it should have
  // the same result.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100.

  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
  layer->SetBounds(gfx::Size(600, 600));
  CalcDrawProps(&render_surface_layer_list);

  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
  UpdateTextures();

  layer->fake_layer_updater()->ClearUpdateCount();
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();

  // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
  // now.
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
  scoped_refptr<FakeTiledLayer> layer =
      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  layer_tree_host_->root_layer()->AddChild(layer);

  // The tile size is 100x100.

  // This makes sure the painting works when the occluded region (in screen
  // space) is transformed differently than the layer.
  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
  layer->SetBounds(gfx::Size(600, 600));
  CalcDrawProps(&render_surface_layer_list);
  gfx::Transform screen_transform;
  screen_transform.Scale(0.5, 0.5);
  layer->draw_properties().screen_space_transform = screen_transform;
  layer->draw_properties().target_space_transform = screen_transform;

  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
  layer->draw_properties().drawable_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->draw_properties().visible_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
  scoped_refptr<FakeTiledLayer> layer =
      new FakeTiledLayer(resource_manager_.get());
  RenderSurfaceLayerList render_surface_layer_list;
  TestOcclusionTracker occluded;
  occlusion_ = &occluded;

  scoped_refptr<FakeTiledLayer> scale_layer =
      new FakeTiledLayer(resource_manager_.get());
  gfx::Transform scale_transform;
  scale_transform.Scale(2.0, 2.0);
  scale_layer->SetTransform(scale_transform);

  layer_tree_host_->root_layer()->AddChild(scale_layer);

  // The tile size is 100x100.

  // This makes sure the painting works when the content space is scaled to
  // a different layer space.
  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
  layer->SetBounds(gfx::Size(300, 300));
  scale_layer->AddChild(layer);
  CalcDrawProps(&render_surface_layer_list);
  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
  EXPECT_EQ(gfx::Size(600, 600).ToString(),
            layer->content_bounds().ToString());

  // No tiles are covered by the 300x50 occlusion.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
  layer->draw_properties().drawable_content_rect =
      gfx::Rect(layer->bounds());
  layer->draw_properties().visible_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  int visible_tiles1 = 6 * 6;
  EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();

  // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
  layer->draw_properties().drawable_content_rect =
      gfx::Rect(layer->bounds());
  layer->draw_properties().visible_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  int visible_tiles2 = 6 * 6 - 3;
  EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());

  layer->fake_layer_updater()->ClearUpdateCount();

  // This makes sure content scaling and transforms work together.
  // When the tiles are scaled down by half, they are 50x50 each in the
  // screen.
  gfx::Transform screen_transform;
  screen_transform.Scale(0.5, 0.5);
  layer->draw_properties().screen_space_transform = screen_transform;
  layer->draw_properties().target_space_transform = screen_transform;

  // An occlusion of 150x100 will cover 3*2 = 6 tiles.
  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));

  gfx::Rect layer_bounds_rect(layer->bounds());
  layer->draw_properties().drawable_content_rect =
      gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
  layer->draw_properties().visible_content_rect =
      gfx::Rect(layer->content_bounds());
  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();
  layer->Update(queue_.get(), &occluded);
  int visible_tiles3 = 6 * 6 - 6;
  EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
}

TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
  // Tile size is 100x100.
  gfx::Rect root_rect(0, 0, 300, 200);
  gfx::Rect child_rect(0, 0, 300, 100);
  gfx::Rect child2_rect(0, 100, 300, 100);

  scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
  scoped_refptr<Layer> surface = Layer::Create();
  scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
  scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));

  root->SetBounds(root_rect.size());
  root->draw_properties().drawable_content_rect = root_rect;
  root->draw_properties().visible_content_rect = root_rect;
  root->AddChild(surface);

  surface->SetForceRenderSurface(true);
  surface->SetOpacity(0.5);
  surface->AddChild(child);
  surface->AddChild(child2);

  child->SetBounds(child_rect.size());
  child->SetPosition(child_rect.origin());
  child->draw_properties().visible_content_rect = child_rect;
  child->draw_properties().drawable_content_rect = root_rect;

  child2->SetBounds(child2_rect.size());
  child2->SetPosition(child2_rect.origin());
  child2->draw_properties().visible_content_rect = child2_rect;
  child2->draw_properties().drawable_content_rect = root_rect;

  layer_tree_host_->SetRootLayer(root);
  layer_tree_host_->SetViewportSize(root_rect.size());

  // With a huge memory limit, all layers should update and push their textures.
  root->InvalidateContentRect(root_rect);
  child->InvalidateContentRect(child_rect);
  child2->InvalidateContentRect(child2_rect);
  layer_tree_host_->UpdateLayers(queue_.get());
  {
    UpdateTextures();
    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
    EXPECT_EQ(3, child->fake_layer_updater()->update_count());
    EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());

    root->fake_layer_updater()->ClearUpdateCount();
    child->fake_layer_updater()->ClearUpdateCount();
    child2->fake_layer_updater()->ClearUpdateCount();

    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
    LayerPushPropertiesTo(child2.get(), child2_impl.get());
    LayerPushPropertiesTo(child.get(), child_impl.get());
    LayerPushPropertiesTo(root.get(), root_impl.get());

    for (unsigned i = 0; i < 3; ++i) {
      for (unsigned j = 0; j < 2; ++j)
        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
      EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
      EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
    }
  }
  layer_tree_host_->CommitComplete();

  // With a memory limit that includes only the root layer (3x2 tiles) and half
  // the surface that the child layers draw into, the child layers will not be
  // allocated. If the surface isn't accounted for, then one of the children
  // would fit within the memory limit.
  root->InvalidateContentRect(root_rect);
  child->InvalidateContentRect(child_rect);
  child2->InvalidateContentRect(child2_rect);

  size_t memory_limit = (3 * 2 + 3 * 1) * (100 * 100) * 4;
  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
      memory_limit);
  layer_tree_host_->UpdateLayers(queue_.get());
  {
    UpdateTextures();
    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());

    root->fake_layer_updater()->ClearUpdateCount();
    child->fake_layer_updater()->ClearUpdateCount();
    child2->fake_layer_updater()->ClearUpdateCount();

    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
    LayerPushPropertiesTo(child2.get(), child2_impl.get());
    LayerPushPropertiesTo(child.get(), child_impl.get());
    LayerPushPropertiesTo(root.get(), root_impl.get());

    for (unsigned i = 0; i < 3; ++i) {
      for (unsigned j = 0; j < 2; ++j)
        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
    }
  }
  layer_tree_host_->CommitComplete();

  // With a memory limit that includes only half the root layer, no contents
  // will be allocated. If render surface memory wasn't accounted for, there is
  // enough space for one of the children layers, but they draw into a surface
  // that can't be allocated.
  root->InvalidateContentRect(root_rect);
  child->InvalidateContentRect(child_rect);
  child2->InvalidateContentRect(child2_rect);

  memory_limit = (3 * 1) * (100 * 100) * 4;
  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
      memory_limit);
  layer_tree_host_->UpdateLayers(queue_.get());
  {
    UpdateTextures();
    EXPECT_EQ(0, root->fake_layer_updater()->update_count());
    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
    EXPECT_FALSE(queue_->HasMoreUpdates());

    root->fake_layer_updater()->ClearUpdateCount();
    child->fake_layer_updater()->ClearUpdateCount();
    child2->fake_layer_updater()->ClearUpdateCount();

    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
    LayerPushPropertiesTo(child2.get(), child2_impl.get());
    LayerPushPropertiesTo(child.get(), child_impl.get());
    LayerPushPropertiesTo(root.get(), root_impl.get());

    for (unsigned i = 0; i < 3; ++i) {
      for (unsigned j = 0; j < 2; ++j)
        EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
    }
  }
  layer_tree_host_->CommitComplete();

  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
                                resource_provider_.get());
  layer_tree_host_->SetRootLayer(nullptr);
}

class TrackingLayerPainter : public LayerPainter {
 public:
  static scoped_ptr<TrackingLayerPainter> Create() {
    return make_scoped_ptr(new TrackingLayerPainter());
  }

  void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) override {
    painted_rect_ = content_rect;
  }

  gfx::Rect PaintedRect() const { return painted_rect_; }
  void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }

 private:
  gfx::Rect painted_rect_;
};

class UpdateTrackingTiledLayer : public FakeTiledLayer {
 public:
  explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
      : FakeTiledLayer(manager) {
    scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
    tracking_layer_painter_ = painter.get();
    layer_updater_ = BitmapContentLayerUpdater::Create(painter.Pass(), 0);
  }

  TrackingLayerPainter* tracking_layer_painter() const {
    return tracking_layer_painter_;
  }

 private:
  LayerUpdater* Updater() const override { return layer_updater_.get(); }
  ~UpdateTrackingTiledLayer() override {}

  TrackingLayerPainter* tracking_layer_painter_;
  scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
};

TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
  scoped_refptr<UpdateTrackingTiledLayer> layer =
      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));

  layer_tree_host_->root_layer()->AddChild(layer);

  gfx::Rect layer_rect(0, 0, 30, 31);
  layer->SetPosition(layer_rect.origin());
  layer->SetBounds(layer_rect.size());
  layer->UpdateContentsScale(1.5f);

  gfx::Rect content_rect(0, 0, 45, 47);
  EXPECT_EQ(content_rect.size(), layer->content_bounds());
  layer->draw_properties().visible_content_rect = content_rect;
  layer->draw_properties().drawable_content_rect = content_rect;

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();

  // Update the whole tile.
  layer->Update(queue_.get(), nullptr);
  layer->tracking_layer_painter()->ResetPaintedRect();

  EXPECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
  UpdateTextures();

  // Invalidate the entire layer in content space. When painting, the rect given
  // to webkit should match the layer's bounds.
  layer->InvalidateContentRect(content_rect);
  layer->Update(queue_.get(), nullptr);

  // Rounding leads to an extra pixel.
  gfx::Rect expanded_layer_rect(layer_rect);
  expanded_layer_rect.set_height(32);
  EXPECT_EQ(expanded_layer_rect,
            layer->tracking_layer_painter()->PaintedRect());
}

TEST_F(TiledLayerTest,
       NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
  scoped_refptr<UpdateTrackingTiledLayer> layer =
      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));

  layer_tree_host_->root_layer()->AddChild(layer);

  gfx::Rect layer_rect(0, 0, 30, 31);
  layer->SetPosition(layer_rect.origin());
  layer->SetBounds(layer_rect.size());
  layer->UpdateContentsScale(1.3f);

  gfx::Rect content_rect(layer->content_bounds());
  layer->draw_properties().visible_content_rect = content_rect;
  layer->draw_properties().drawable_content_rect = content_rect;

  layer->SetTexturePriorities(priority_calculator_);
  resource_manager_->PrioritizeTextures();
  layer->SavePaintProperties();

  // Update the whole tile.
  layer->Update(queue_.get(), nullptr);
  layer->tracking_layer_painter()->ResetPaintedRect();

  EXPECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
  UpdateTextures();

  // Invalidate the entire layer in layer space. When painting, the rect given
  // to webkit should match the layer's bounds.
  layer->SetNeedsDisplayRect(layer_rect);
  layer->Update(queue_.get(), nullptr);

  // Rounding leads to an extra pixel.
  gfx::Rect expanded_layer_rect(layer_rect);
  expanded_layer_rect.set_height(32);
  EXPECT_EQ(expanded_layer_rect,
            layer->tracking_layer_painter()->PaintedRect());
}

}  // namespace
}  // namespace cc
