12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/tiled_layer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <limits>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/bitmap_content_layer_updater.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/layer_painter.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/prioritized_resource_manager.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/resource_update_controller.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/animation_test_common.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_layer_tree_host_client.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_layer_tree_host_impl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_output_surface.h"
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/test/fake_output_surface_client.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_proxy.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/fake_rendering_stats_instrumentation.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/geometry_test_utils.h"
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "cc/test/test_shared_bitmap_manager.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/tiled_layer_test_common.h"
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "cc/trees/occlusion_tracker.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class TestOcclusionTracker : public OcclusionTracker<Layer> {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000)) {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.push_back(StackObject());
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetRenderTarget(Layer* render_target) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().target = render_target;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void SetOcclusion(const SimpleEnclosedRegion& occlusion) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().occlusion_from_inside_target = occlusion;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SynchronousOutputSurfaceLayerTreeHost : public LayerTreeHost {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static scoped_ptr<SynchronousOutputSurfaceLayerTreeHost> Create(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostClient* client,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SharedBitmapManager* manager,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const LayerTreeSettings& settings,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return make_scoped_ptr(new SynchronousOutputSurfaceLayerTreeHost(
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        client, manager, settings, impl_task_runner));
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~SynchronousOutputSurfaceLayerTreeHost() {}
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool EnsureOutputSurfaceCreated() {
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        run_loop_.QuitClosure(),
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeDelta::FromSeconds(5));
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_loop_.Run();
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return output_surface_created_;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void OnCreateAndInitializeOutputSurfaceAttempted(
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool success) OVERRIDE {
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    LayerTreeHost::OnCreateAndInitializeOutputSurfaceAttempted(success);
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    output_surface_created_ = success;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    run_loop_.Quit();
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SynchronousOutputSurfaceLayerTreeHost(
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerTreeHostClient* client,
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SharedBitmapManager* manager,
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const LayerTreeSettings& settings,
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : LayerTreeHost(client, manager, settings),
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        output_surface_created_(false) {
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LayerTreeHost::InitializeThreaded(base::MessageLoopProxy::current(),
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      impl_task_runner);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool output_surface_created_;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop run_loop_;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerTest : public testing::Test {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerTest()
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : proxy_(NULL),
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        output_surface_(FakeOutputSurface::Create3d()),
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        queue_(make_scoped_ptr(new ResourceUpdateQueue)),
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        impl_thread_("ImplThread"),
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D),
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        occlusion_(NULL) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    settings_.layer_transforms_should_scale_layer_contents = true;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    impl_thread_.Start();
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    layer_tree_host_ = SynchronousOutputSurfaceLayerTreeHost::Create(
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &fake_layer_tree_host_client_,
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        shared_bitmap_manager_.get(),
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        settings_,
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        impl_thread_.message_loop_proxy());
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fake_layer_tree_host_client_.SetLayerTreeHost(layer_tree_host_.get());
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    proxy_ = layer_tree_host_->proxy();
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_ = PrioritizedResourceManager::Create(proxy_);
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host_->SetLayerTreeHostClientReady();
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CHECK(layer_tree_host_->EnsureOutputSurfaceCreated());
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->SetRootLayer(Layer::Create());
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(output_surface_->BindToClient(&output_surface_client_));
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        impl_thread_and_main_thread_blocked(proxy_);
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  shared_bitmap_manager_.get(),
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  NULL,
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  0,
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  false,
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  1,
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                  false);
13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    host_impl_ = make_scoped_ptr(
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        new FakeLayerTreeHostImpl(proxy_, shared_bitmap_manager_.get()));
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TiledLayerTest() {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceManagerClearAllMemory(resource_manager_.get(),
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  resource_provider_.get());
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_.reset();
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_impl_.reset();
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResourceManagerClearAllMemory(
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrioritizedResourceManager* resource_manager,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceProvider* resource_provider) {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DebugScopedSetImplThreadAndMainThreadBlocked
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      impl_thread_and_main_thread_blocked(proxy_);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ClearAllMemory(resource_provider);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ReduceMemory(resource_provider);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager->UnlinkAndClearEvictedBackings();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateTextures() {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(queue_);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceUpdateController> update_controller =
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ResourceUpdateController::Create(NULL,
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         proxy_->ImplThreadTaskRunner(),
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         queue_.Pass(),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         resource_provider_.get());
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_controller->Finalize();
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queue_ = make_scoped_ptr(new ResourceUpdateQueue);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerPushPropertiesTo(FakeTiledLayer* layer,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FakeTiledLayerImpl* layer_impl) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->PushPropertiesTo(layer_impl);
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    layer->ResetNumDependentsNeedPushProperties();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThread main_thread(proxy_);
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), occluded);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void CalcDrawProps(RenderSurfaceLayerList* render_surface_layer_list) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (occlusion_)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->root_layer(),
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->device_viewport_size(),
192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        render_surface_layer_list);
193558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
194558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.max_texture_size =
195558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        layer_tree_host_->GetRendererCapabilities().max_texture_size;
196558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.can_adjust_raster_scales = true;
197558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer2;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl2;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_refptr<FakeTiledLayer>& layer2,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get textures
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->ClearPriorities();
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer1->SetTexturePriorities(priority_calculator_);
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer2->SetTexturePriorities(priority_calculator_);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Save paint properties
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer1->SavePaintProperties();
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer2->SavePaintProperties();
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update content
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer1->Update(queue_.get(), occlusion_);
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer2->Update(queue_.get(), occlusion_);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = false;
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer1->NeedsIdlePaint();
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer2->NeedsIdlePaint();
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update textures and push.
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return needs_update;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Proxy* proxy_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeSettings settings_;
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client_;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface_;
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider_;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue_;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityCalculator priority_calculator_;
2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Thread impl_thread_;
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeLayerTreeHostClient fake_layer_tree_host_client_;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<SynchronousOutputSurfaceLayerTreeHost> layer_tree_host_;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<PrioritizedResourceManager> resource_manager_;
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker* occlusion_;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDirtyTiles) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates both tiles, but then only update one of them.
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first tile since the other tile was invalidated but
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not painted.
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TiledLayerTest, Scale) {
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer_tree_host_->SetDeviceScaleFactor(1.5);
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<FakeTiledLayer> layer =
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RenderSurfaceLayerList render_surface_layer_list;
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer_tree_host_->root_layer()->AddChild(layer);
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer->SetBounds(gfx::Size(100, 200));
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CalcDrawProps(&render_surface_layer_list);
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Change the width so that it doesn't divide cleanly by the scale.
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer->SetBounds(gfx::Size(101, 200));
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UpdateAndPush(layer, layer_impl);
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1.5, layer->fake_layer_updater()->last_contents_width_scale());
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // The tile size is 100x100, so this invalidates and then paints two tiles.
329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->SetBounds(gfx::Size(100, 200));
330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should have both tiles on the impl side.
334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Invalidates part of the top tile...
342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // ....but the area is occluded.
34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 50, 50)));
345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should still have both tiles, as part of the top tile is still
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // unoccluded.
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDeletedTiles) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->ClearPriorities();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(resource_manager_.get(),
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should drop the tiles on the impl thread.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should now have no textures on the impl thread.
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should recreate and update one of the deleted textures.
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tiles on the impl side.
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintTiles) {
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // center.  This paints 1 visible of the 25 invalid tiles.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(500, 500));
406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer, layer_impl);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for surrounding tiles.
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For the next four updates, we should detect we still need idle painting.
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(needs_update);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should always finish painting eventually.
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 20; i++)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have pre-painted all of the surrounding tiles.
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int j = 0; j < 5; j++)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PredictivePainting) {
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepainting should occur in the scroll direction first, and the
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible rect should be extruded only along the dominant axis.
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(10, 20),
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(-20, 10) };
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should push all tiles that touch the extruded visible rect.
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_visible_tiles[6] = {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first pre-paint should also paint first in the scroll
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // direction so we should find one additional tile in the scroll direction.
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_prepaint_tiles[6] = {
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int k = 0; k < 6; k++) {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The tile size is 100x100. Setup 5x5 tiles with one visible tile
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // in the center.
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Size bounds = gfx::Size(500, 500);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect previous_visible_rect =
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect next_visible_rect =
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Setup. Use the previous_visible_rect to setup the prediction for next
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame.
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(bounds);
472ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
473ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = previous_visible_rect;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Invalidate and move the visible_rect in the scroll direction.
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that the correct tiles have been painted in the visible pass.
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetNeedsDisplay();
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 5; i++) {
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int j = 0; j < 5; j++)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  pushed_visible_tiles[k].Contains(i, j));
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move the transform in the same direction without invalidating.
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that non-visible pre-painting occured in the correct direction.
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore diagonal scrolls here (k > 3) as these have new visible content
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // now.
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (k <= 3) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->draw_properties().visible_content_rect = next_visible_rect;
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; i++) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; j++)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    pushed_prepaint_tiles[k].Contains(i, j));
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should always finish painting eventually.
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 20; i++)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start with 2mb of memory, but the test is going to try to use just more
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // than 1mb, so we reduce to 1mb later.
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
522ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For this test we have two layers. layer1 exhausts most texture memory,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // leaving room for 2 more tiles from layer2, but not all three tiles. First
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we will fail on the third tile of layer2, and this should not leave the
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // second tile in a bad state.
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for 2 tiles only in the other layer.
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer1_rect(0, 0, 100, 2400);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This requires 4*30000 bytes of memory.
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer2_rect(0, 0, 100, 300);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Paint a single tile in layer2 so that it will idle paint.
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(layer1_rect.size());
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(layer2_rect.size());
543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = layer1_rect;
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for both remaining tiles in layer2.
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reduce our memory limits to 1mb.
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now idle paint layer2. We are going to run out of memory though!
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Oh well, commit the frame and push.
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sanity check, we should have textures for the big layer.
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first two tiles from layer2 since
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it failed to idle update the last tile.
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates one occluded tile, culls it
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during paint, but prepaints it.
58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(0, 0, 100, 100)));
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
602ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, during the paint, we invalidate one of the tiles. This should
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not prevent the tile from being pushed.
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer.get());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
630ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate a tile on layer1, during update of layer 2.
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->fake_layer_updater()->SetRectToInvalidate(
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer1.get());
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
661ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->fake_layer_updater()->SetRectToInvalidate(
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer2.get());
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a LayerTreeHost that has the right viewportsize,
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the layer is considered small enough.
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool run_out_of_memory[2] = { false, true };
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a layer with 5x5 tiles, with 4x4 size viewport.
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_width = 4 * FakeTiledLayer::tile_size().width();
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_height = 4 * FakeTiledLayer::tile_size().width();
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_width = 5 * FakeTiledLayer::tile_size().width();
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_height = 5 * FakeTiledLayer::tile_size().height();
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int memory_for_layer = layer_width * layer_height * 4;
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->SetViewportSize(
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Size(viewport_width, viewport_height));
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use 10x5 tiles to run out of memory.
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (run_out_of_memory[i])
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_width *= 2;
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer =
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
706ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
708a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    layer_tree_host_->root_layer()->AddChild(layer);
709a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Full size layer with half being visible.
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(layer_width, layer_height));
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = true;
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetLayerTreeHost(layer_tree_host_.get());
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer should paint its entire contents on the first paint
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // if it is close to the viewport size and has the available memory.
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetTexturePriorities(priority_calculator_);
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer->SavePaintProperties();
725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), NULL);
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should have all the tiles for the small animated layer.
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should still have the visible tiles when we didn't
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // have enough memory for all the tiles.
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!run_out_of_memory[i]) {
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; ++i) {
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 10; ++i) {
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    layer->RemoveFromParent();
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
753ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only the visible rect, so we will run out of
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // memory in first idle paint.
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = false;
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Idle-painting should see no more priority tiles for painting.
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
783a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
784a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool animating[2] = { false, true };
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = animating[i];
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer's bounds are empty.
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't paint or idle-paint.
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size());
793ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
794ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
795a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = gfx::Rect();
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, layer->NumPaintedTiles());
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't need prepaint.
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Alternate between not visible and visible.
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect v(0, 0, 100, 100);
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect nv(0, 0, 0, 0);
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          false };
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not have any tiles except for when the layer was visible
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or after the layer was visible and we didn't invalidate.
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_tile[10] = { false, false, true, true, false, false, true, true,
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         true, true };
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
828a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
829a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 10; i++) {
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(100, 100));
832ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
833ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
834a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect[i];
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (invalidate[i])
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should never signal idle paint, as we painted the entire layer
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // or the layer was not visible.
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, InvalidateFromPrepare) {
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
853ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
855a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
856a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
859a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invoke update again. As the layer is valid update shouldn't be invoked on
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the LayerUpdater.
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // update.
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(25, 25, 50, 50), layer.get());
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The layer should still be invalid as update invoked invalidate.
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);  // visible
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The update rect (that indicates what was actually painted) should be in
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // layer space, not the content space.
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
894a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
895a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds(0, 0, 300, 200);
8971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect content_bounds(0, 0, 150, 250);
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_bounds.size());
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetContentBounds(content_bounds.size());
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_bounds;
9021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer->draw_properties().contents_scale_x = .5f;
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  layer->draw_properties().contents_scale_y = 1.25f;
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On first update, the update_rect includes all tiles, even beyond the
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // boundaries of the layer.
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, it should still be in layer space, not content space.
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Update rect is 200x300 (tile size of 100x100). Scaled this gives 400x240.
9161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 400, 240), layer->update_rect());
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After the tiles are updated once, another invalidate only needs to update
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the bounds of the layer.
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial re-paint should also be represented by the update rect in layer
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space, not content space.
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect partial_damage(30, 100, 10, 10);
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(partial_damage);
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FLOAT_RECT_EQ(gfx::RectF(60, 80, 20, 8), layer->update_rect());
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
945ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
947a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
948a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a layer with one tile.
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
951a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
9537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  layer->Update(queue_.get(), NULL);
9547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UpdateTextures();
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Push the tiles to the impl side and check that there is exactly one.
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(gfx::Rect());
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the contents scale.
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(2.f);
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The impl side should get 2x2 tiles now.
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that changing the contents scale caused invalidation, and
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that the layer-space rectangle requiring painting is not scaled.
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer again, but do not paint. All tiles should be
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // gone now from the impl side.
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplay();
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create two 300 x 300 tiled layers.
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 300);
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only one of the two layers.
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->AddChild(child_layer);
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetBounds(content_bounds);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->draw_properties().visible_content_rect = content_rect;
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetPosition(gfx::PointF(0, 0));
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetBounds(content_bounds);
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->draw_properties().visible_content_rect = content_rect;
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetPosition(gfx::PointF(0, 0));
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->InvalidateContentRect(content_rect);
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->InvalidateContentRect(content_rect);
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root_layer);
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
103268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
103368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We'll skip the root layer.
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_layer->SkipsDraw());
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(child_layer->SkipsDraw());
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the child layer.
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->RemoveAllChildren();
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(root_layer->SkipsDraw());
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, ResizeToSmaller) {
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1058a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1059a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(700, 700));
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(200, 200));
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1077a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int size = 1 << 30;
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(size, size));
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure no crash for bounds where size * size would overflow an int.
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerPartialUpdateTest : public TiledLayerTest {
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create one 300 x 200 tiled layer with 3 x 2 tiles.
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 200);
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds);
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(gfx::PointF(0, 0));
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(layer);
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of all 6 tiles.
111268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of 3 tiles and partial update of 3 tiles.
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
112868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->FullUploadSize());
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->PartialUploadSize());
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 tiles.
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
114768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(2u, queue_->FullUploadSize());
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Checkerboard all tiles.
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 checkerboard tiles.
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
117268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 4 tiles.
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
118868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->FullUploadSize());
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
1213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1225ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
123703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
125403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 200, 300, 100)));
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
126403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(250, 250, 300, 100)));
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The partially occluded tiles (by the 150 occlusion height) are visible
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // beyond the occlusion, so not culled.
128803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region stops at the edge of the occlusion so the partly
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible tiles become fully occluded.
130303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region is even smaller than the occlusion, it should have
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the same result.
131703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 150)));
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
134303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
1352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UpdateTextures();
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now.
1361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the occluded region (in screen
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space) is transformed differently than the layer.
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
138603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 50)));
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
1401b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1402ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> scale_layer =
1407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gfx::Transform scale_transform;
1409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_transform.Scale(2.0, 2.0);
1410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->SetTransform(scale_transform);
1411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(scale_layer);
1413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the content space is scaled to
1417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // a different layer space.
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
1419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
1420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->AddChild(layer);
1421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
1422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
1423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
1424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(gfx::Size(600, 600).ToString(),
1425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            layer->content_bounds().ToString());
1426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // No tiles are covered by the 300x50 occlusion.
142803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 50)));
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1438b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles1 = 6 * 6;
1439b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
144403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(200, 200, 300, 100)));
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles2 = 6 * 6 - 3;
1455b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure content scaling and transforms work together.
1460b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // When the tiles are scaled down by half, they are 50x50 each in the
1461b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // screen.
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1467b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // An occlusion of 150x100 will cover 3*2 = 6 tiles.
146803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  occluded.SetOcclusion(SimpleEnclosedRegion(gfx::Rect(100, 100, 150, 100)));
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds_rect(layer->bounds());
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
147290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles3 = 6 * 6 - 6;
1481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tile size is 100x100.
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect root_rect(0, 0, 300, 200);
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child_rect(0, 0, 300, 100);
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child2_rect(0, 100, 300, 100);
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Layer> surface = Layer::Create();
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetBounds(root_rect.size());
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().drawable_content_rect = root_rect;
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().visible_content_rect = root_rect;
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->AddChild(surface);
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetForceRenderSurface(true);
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetOpacity(0.5);
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child);
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child2);
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetBounds(child_rect.size());
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetPosition(child_rect.origin());
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().visible_content_rect = child_rect;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().drawable_content_rect = root_rect;
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetBounds(child2_rect.size());
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetPosition(child2_rect.origin());
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().visible_content_rect = child2_rect;
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().drawable_content_rect = root_rect;
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root);
1519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(root_rect.size());
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a huge memory limit, all layers should update and push their textures.
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
152568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child->fake_layer_updater()->update_count());
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
15447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
15457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only the root layer (3x2 tiles) and half
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the surface that the child layers draw into, the child layers will not be
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // allocated. If the surface isn't accounted for, then one of the children
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // would fit within the memory limit.
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
156368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
156468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_t memory_limit = (3 * 2 + 3 * 1) * (100 * 100) * 4;
156568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
156668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
156768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
15867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
15877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only half the root layer, no contents
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be allocated. If render surface memory wasn't accounted for, there is
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enough space for one of the children layers, but they draw into a surface
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that can't be allocated.
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
160568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
160668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  memory_limit = (3 * 1) * (100 * 100) * 4;
160768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
160868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
160968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, root->fake_layer_updater()->update_count());
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
16287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
16297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TrackingLayerPainter : public LayerPainter {
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<TrackingLayerPainter> Create() {
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new TrackingLayerPainter());
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void Paint(SkCanvas* canvas, const gfx::Rect& content_rect) OVERRIDE {
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    painted_rect_ = content_rect;
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect PaintedRect() const { return painted_rect_; }
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect painted_rect_;
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UpdateTrackingTiledLayer : public FakeTiledLayer {
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FakeTiledLayer(manager) {
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_layer_painter_ = painter.get();
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_updater_ =
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
167090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &stats_instrumentation_,
167190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          0);
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter() const {
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tracking_layer_painter_;
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LayerUpdater* Updater() const OVERRIDE {
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return layer_updater_.get();
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateTrackingTiledLayer() {}
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter_;
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeRenderingStatsInstrumentation stats_instrumentation_;
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1693a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1694a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.5f);
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(0, 0, 45, 47);
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(content_rect.size(), layer->content_bounds());
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in content space. When painting, the rect given
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
1719eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Rounding leads to an extra pixel.
17221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect expanded_layer_rect(layer_rect);
17231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  expanded_layer_rect.set_height(32);
17241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_RECT_EQ(expanded_layer_rect,
17251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 layer->tracking_layer_painter()->PaintedRect());
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest,
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1733a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.3f);
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(layer->content_bounds());
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in layer space. When painting, the rect given
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(layer_rect);
1758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Rounding leads to an extra pixel.
17611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect expanded_layer_rect(layer_rect);
17621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  expanded_layer_rect.set_height(32);
17631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_RECT_EQ(expanded_layer_rect,
17641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 layer->tracking_layer_painter()->PaintedRect());
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1769