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)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/debug/overdraw_metrics.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"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/tiled_layer_test_common.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestOcclusionTracker : public OcclusionTracker {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.push_back(StackObject());
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetRenderTarget(Layer* render_target) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().target = render_target;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetOcclusion(const Region& occlusion) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().occlusion_from_inside_target = occlusion;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerTest : public testing::Test {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerTest()
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : proxy_(NULL),
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        output_surface_(FakeOutputSurface::Create3d()),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        queue_(make_scoped_ptr(new ResourceUpdateQueue)),
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        impl_thread_("ImplThread"),
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D),
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        occlusion_(NULL) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
57b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    settings_.layer_transforms_should_scale_layer_contents = true;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    impl_thread_.Start();
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    layer_tree_host_ = LayerTreeHost::CreateThreaded(
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &fake_layer_tree_host_client_,
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        NULL,
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        settings_,
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        impl_thread_.message_loop_proxy());
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    proxy_ = layer_tree_host_->proxy();
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_ = PrioritizedResourceManager::Create(proxy_);
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    layer_tree_host_->SetLayerTreeHostClientReady();
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->InitializeOutputSurfaceIfNeeded();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->SetRootLayer(Layer::Create());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(output_surface_->BindToClient(&output_surface_client_));
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        impl_thread_and_main_thread_blocked(proxy_);
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    resource_provider_ =
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_));
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TiledLayerTest() {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceManagerClearAllMemory(resource_manager_.get(),
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  resource_provider_.get());
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_.reset();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_impl_.reset();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResourceManagerClearAllMemory(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrioritizedResourceManager* resource_manager,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceProvider* resource_provider) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DebugScopedSetImplThreadAndMainThreadBlocked
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      impl_thread_and_main_thread_blocked(proxy_);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ClearAllMemory(resource_provider);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ReduceMemory(resource_provider);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager->UnlinkAndClearEvictedBackings();
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateTextures() {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(queue_);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceUpdateController> update_controller =
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ResourceUpdateController::Create(NULL,
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         proxy_->ImplThreadTaskRunner(),
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         queue_.Pass(),
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         resource_provider_.get());
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_controller->Finalize();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queue_ = make_scoped_ptr(new ResourceUpdateQueue);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerPushPropertiesTo(FakeTiledLayer* layer,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FakeTiledLayerImpl* layer_impl) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->PushPropertiesTo(layer_impl);
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    layer->ResetNumDependentsNeedPushProperties();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThread main_thread(proxy_);
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), occluded);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void CalcDrawProps(RenderSurfaceLayerList* render_surface_layer_list) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (occlusion_)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->root_layer(),
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->device_viewport_size(),
137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        render_surface_layer_list);
138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.max_texture_size =
140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        layer_tree_host_->GetRendererCapabilities().max_texture_size;
141558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.can_adjust_raster_scales = true;
142558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer2;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl2;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_refptr<FakeTiledLayer>& layer2,
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get textures
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->ClearPriorities();
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer1->SetTexturePriorities(priority_calculator_);
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer2->SetTexturePriorities(priority_calculator_);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Save paint properties
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer1->SavePaintProperties();
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer2->SavePaintProperties();
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update content
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer1->Update(queue_.get(), occlusion_);
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer2->Update(queue_.get(), occlusion_);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = false;
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer1->NeedsIdlePaint();
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer2->NeedsIdlePaint();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update textures and push.
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return needs_update;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Proxy* proxy_;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeSettings settings_;
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client_;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider_;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue_;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityCalculator priority_calculator_;
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Thread impl_thread_;
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeLayerTreeHostClient fake_layer_tree_host_client_;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerTreeHost> layer_tree_host_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<PrioritizedResourceManager> resource_manager_;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker* occlusion_;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDirtyTiles) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates both tiles, but then only update one of them.
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first tile since the other tile was invalidated but
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not painted.
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // The tile size is 100x100, so this invalidates and then paints two tiles.
252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->SetBounds(gfx::Size(100, 200));
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
257ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(
258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should have both tiles on the impl side.
262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Invalidates part of the top tile...
270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // ....but the area is occluded.
272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    occluded.SetOcclusion(gfx::Rect(0, 0, 50, 50));
273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                20000 + 2500,
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                1);
280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should still have both tiles, as part of the top tile is still
283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // unoccluded.
284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDeletedTiles) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->ClearPriorities();
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(resource_manager_.get(),
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should drop the tiles on the impl thread.
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should now have no textures on the impl thread.
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should recreate and update one of the deleted textures.
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tiles on the impl side.
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintTiles) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // center.  This paints 1 visible of the 25 invalid tiles.
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(500, 500));
340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer, layer_impl);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for surrounding tiles.
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For the next four updates, we should detect we still need idle painting.
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(needs_update);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should always finish painting eventually.
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 20; i++)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have pre-painted all of the surrounding tiles.
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int j = 0; j < 5; j++)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PredictivePainting) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepainting should occur in the scroll direction first, and the
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible rect should be extruded only along the dominant axis.
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(10, 20),
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(-20, 10) };
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should push all tiles that touch the extruded visible rect.
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_visible_tiles[6] = {
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first pre-paint should also paint first in the scroll
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // direction so we should find one additional tile in the scroll direction.
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_prepaint_tiles[6] = {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int k = 0; k < 6; k++) {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The tile size is 100x100. Setup 5x5 tiles with one visible tile
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // in the center.
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Size bounds = gfx::Size(500, 500);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect previous_visible_rect =
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect next_visible_rect =
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Setup. Use the previous_visible_rect to setup the prediction for next
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(bounds);
406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
407ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = previous_visible_rect;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Invalidate and move the visible_rect in the scroll direction.
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that the correct tiles have been painted in the visible pass.
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetNeedsDisplay();
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 5; i++) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int j = 0; j < 5; j++)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  pushed_visible_tiles[k].Contains(i, j));
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move the transform in the same direction without invalidating.
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that non-visible pre-painting occured in the correct direction.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore diagonal scrolls here (k > 3) as these have new visible content
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // now.
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (k <= 3) {
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->draw_properties().visible_content_rect = next_visible_rect;
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; i++) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; j++)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    pushed_prepaint_tiles[k].Contains(i, j));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should always finish painting eventually.
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 20; i++)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start with 2mb of memory, but the test is going to try to use just more
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // than 1mb, so we reduce to 1mb later.
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
456ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For this test we have two layers. layer1 exhausts most texture memory,
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // leaving room for 2 more tiles from layer2, but not all three tiles. First
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we will fail on the third tile of layer2, and this should not leave the
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // second tile in a bad state.
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for 2 tiles only in the other layer.
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer1_rect(0, 0, 100, 2400);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This requires 4*30000 bytes of memory.
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer2_rect(0, 0, 100, 300);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Paint a single tile in layer2 so that it will idle paint.
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(layer1_rect.size());
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(layer2_rect.size());
477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = layer1_rect;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for both remaining tiles in layer2.
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reduce our memory limits to 1mb.
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now idle paint layer2. We are going to run out of memory though!
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Oh well, commit the frame and push.
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sanity check, we should have textures for the big layer.
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first two tiles from layer2 since
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it failed to idle update the last tile.
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
513ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates one occluded tile, culls it
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during paint, but prepaints it.
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(0, 0, 100, 100));
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have the prepainted tile on the impl side, but culled it during
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint.
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, occluded.overdraw_metrics()->tiles_culled_for_upload());
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
539ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, during the paint, we invalidate one of the tiles. This should
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not prevent the tile from being pushed.
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer.get());
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
549a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
567ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate a tile on layer1, during update of layer 2.
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->fake_layer_updater()->SetRectToInvalidate(
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer1.get());
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer1);
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer2);
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->fake_layer_updater()->SetRectToInvalidate(
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer2.get());
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a LayerTreeHost that has the right viewportsize,
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the layer is considered small enough.
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool run_out_of_memory[2] = { false, true };
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a layer with 5x5 tiles, with 4x4 size viewport.
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_width = 4 * FakeTiledLayer::tile_size().width();
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_height = 4 * FakeTiledLayer::tile_size().width();
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_width = 5 * FakeTiledLayer::tile_size().width();
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_height = 5 * FakeTiledLayer::tile_size().height();
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int memory_for_layer = layer_width * layer_height * 4;
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->SetViewportSize(
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Size(viewport_width, viewport_height));
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use 10x5 tiles to run out of memory.
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (run_out_of_memory[i])
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_width *= 2;
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer =
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
643ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    layer_tree_host_->root_layer()->AddChild(layer);
646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Full size layer with half being visible.
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(layer_width, layer_height));
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = true;
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetLayerTreeHost(layer_tree_host_.get());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer should paint its entire contents on the first paint
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // if it is close to the viewport size and has the available memory.
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetTexturePriorities(priority_calculator_);
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer->SavePaintProperties();
662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), NULL);
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should have all the tiles for the small animated layer.
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should still have the visible tiles when we didn't
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // have enough memory for all the tiles.
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!run_out_of_memory[i]) {
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; ++i) {
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 10; ++i) {
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
681a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    layer->RemoveFromParent();
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
690ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
693a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only the visible rect, so we will run out of
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // memory in first idle paint.
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = false;
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
702a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Idle-painting should see no more priority tiles for painting.
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool animating[2] = { false, true };
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = animating[i];
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer's bounds are empty.
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't paint or idle-paint.
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size());
730ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
731ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
732a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = gfx::Rect();
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, layer->NumPaintedTiles());
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't need prepaint.
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Alternate between not visible and visible.
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect v(0, 0, 100, 100);
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect nv(0, 0, 0, 0);
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          false };
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not have any tiles except for when the layer was visible
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or after the layer was visible and we didn't invalidate.
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_tile[10] = { false, false, true, true, false, false, true, true,
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         true, true };
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 10; i++) {
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(100, 100));
769ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
770ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
771a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CalcDrawProps(&render_surface_layer_list);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect[i];
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (invalidate[i])
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should never signal idle paint, as we painted the entire layer
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // or the layer was not visible.
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, InvalidateFromPrepare) {
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
790ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
793a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
796a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invoke update again. As the layer is valid update shouldn't be invoked on
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the LayerUpdater.
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // update.
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(25, 25, 50, 50), layer.get());
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The layer should still be invalid as update invoked invalidate.
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);  // visible
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The update rect (that indicates what was actually painted) should be in
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // layer space, not the content space.
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
831a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
832a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds(0, 0, 300, 200);
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds(0, 0, 200, 250);
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_bounds.size());
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetContentBounds(content_bounds.size());
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_bounds;
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On first update, the update_rect includes all tiles, even beyond the
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // boundaries of the layer.
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, it should still be in layer space, not content space.
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer->update_rect());
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After the tiles are updated once, another invalidate only needs to update
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the bounds of the layer.
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
858eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial re-paint should also be represented by the update rect in layer
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space, not content space.
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect partial_damage(30, 100, 10, 10);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(partial_damage);
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer->update_rect());
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
878ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
880a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
881a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a layer with one tile.
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
884a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
8867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  layer->Update(queue_.get(), NULL);
8877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UpdateTextures();
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Push the tiles to the impl side and check that there is exactly one.
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
895eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(gfx::Rect());
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the contents scale.
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(2.f);
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The impl side should get 2x2 tiles now.
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that changing the contents scale caused invalidation, and
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that the layer-space rectangle requiring painting is not scaled.
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer again, but do not paint. All tiles should be
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // gone now from the impl side.
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplay();
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create two 300 x 300 tiled layers.
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 300);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only one of the two layers.
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->AddChild(child_layer);
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetBounds(content_bounds);
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->draw_properties().visible_content_rect = content_rect;
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetPosition(gfx::PointF(0, 0));
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetBounds(content_bounds);
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->draw_properties().visible_content_rect = content_rect;
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetPosition(gfx::PointF(0, 0));
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->InvalidateContentRect(content_rect);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->InvalidateContentRect(content_rect);
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root_layer);
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
96568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
96668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
96868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We'll skip the root layer.
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_layer->SkipsDraw());
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(child_layer->SkipsDraw());
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the child layer.
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->RemoveAllChildren();
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
97968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(root_layer->SkipsDraw());
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, ResizeToSmaller) {
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
991a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
992a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(700, 700));
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(200, 200));
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1010a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1011a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int size = 1 << 30;
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(size, size));
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure no crash for bounds where size * size would overflow an int.
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerPartialUpdateTest : public TiledLayerTest {
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create one 300 x 200 tiled layer with 3 x 2 tiles.
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 200);
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds);
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(gfx::PointF(0, 0));
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(layer);
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of all 6 tiles.
104568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of 3 tiles and partial update of 3 tiles.
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
106168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->FullUploadSize());
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->PartialUploadSize());
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 tiles.
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
108068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(2u, queue_->FullUploadSize());
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Checkerboard all tiles.
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 checkerboard tiles.
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
110568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 4 tiles.
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
112168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get());
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->FullUploadSize());
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
1146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1158ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 200, 300, 100));
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000,
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 250, 300, 100));
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000 + 360000,
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1224ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The partially occluded tiles (by the 150 occlusion height) are visible
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // beyond the occlusion, so not culled.
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region stops at the edge of the occlusion so the partly
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible tiles become fully occluded.
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000,
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region is even smaller than the occlusion, it should have
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the same result.
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000 + 180000,
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { UpdateTextures(); }
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now.
1333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(6, occluded.overdraw_metrics()->tiles_culled_for_upload());
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the occluded region (in screen
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space) is transformed differently than the layer.
1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 50));
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
1383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> scale_layer =
1389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gfx::Transform scale_transform;
1391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_transform.Scale(2.0, 2.0);
1392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->SetTransform(scale_transform);
1393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(scale_layer);
1395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the content space is scaled to
1399b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // a different layer space.
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
1401b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetAnchorPoint(gfx::PointF());
1402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
1403b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->AddChild(layer);
1404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
1405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
1406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
1407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(gfx::Size(600, 600).ToString(),
1408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            layer->content_bounds().ToString());
1409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // No tiles are covered by the 300x50 occlusion.
1411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 50));
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles1 = 6 * 6;
1422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
1427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              1);
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1433b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles2 = 6 * 6 - 3;
1444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure content scaling and transforms work together.
1456b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // When the tiles are scaled down by half, they are 50x50 each in the
1457b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // screen.
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1463b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // An occlusion of 150x100 will cover 3*2 = 6 tiles.
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 100));
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds_rect(layer->bounds());
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
146890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles3 = 6 * 6 - 6;
1477b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles3 * 100 * 100 +
1482b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(6 + 3, occluded.overdraw_metrics()->tiles_culled_for_upload());
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VisibleContentOpaqueRegion) {
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1491ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 200);
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_bounds = gfx::Rect(0, 0, 100, 150);
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
1508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = visible_bounds;
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = visible_bounds;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the layer doesn't paint opaque content, then the
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should be empty.
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000, 1);
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should match the visible part of what is painted
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque.
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_paint_rect = gfx::Rect(10, 10, 90, 190);
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect);
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we paint again without invalidating, the same stuff should be opaque.
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint a non-opaque part of the tile, then it shouldn't lose its
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. And other tiles should not be affected.
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1,
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint an opaque part of the tile, then it should lose its
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. But other tiles should still not be affected.
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                visible_bounds).ToString(),
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1 + 1,
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(TiledLayerTest, PixelsPaintedMetrics) {
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 300);
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
1629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CalcDrawProps(&render_surface_layer_list);
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates and paints the whole layer.
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1637eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 30000, 1);
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates an area on the top and bottom tile, which will cause us to
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint the tile in the middle, even though it is not dirty and will not be
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // uploaded.
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1657eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The middle tile was painted even though not invalidated.
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The pixels uploaded will not include the non-invalidated tile in the
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // middle.
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              30000 + 1 + 100,
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tile size is 100x100.
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect root_rect(0, 0, 300, 200);
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child_rect(0, 0, 300, 100);
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child2_rect(0, 100, 300, 100);
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Layer> surface = Layer::Create();
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetBounds(root_rect.size());
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetAnchorPoint(gfx::PointF());
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().drawable_content_rect = root_rect;
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().visible_content_rect = root_rect;
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->AddChild(surface);
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetForceRenderSurface(true);
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetAnchorPoint(gfx::PointF());
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetOpacity(0.5);
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child);
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child2);
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetBounds(child_rect.size());
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetAnchorPoint(gfx::PointF());
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetPosition(child_rect.origin());
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().visible_content_rect = child_rect;
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().drawable_content_rect = root_rect;
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetBounds(child2_rect.size());
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetAnchorPoint(gfx::PointF());
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetPosition(child2_rect.origin());
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().visible_content_rect = child2_rect;
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().drawable_content_rect = root_rect;
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root);
1713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(root_rect.size());
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a huge memory limit, all layers should update and push their textures.
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
171968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child->fake_layer_updater()->update_count());
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
17387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
17397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only the root layer (3x2 tiles) and half
17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the surface that the child layers draw into, the child layers will not be
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // allocated. If the surface isn't accounted for, then one of the children
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // would fit within the memory limit.
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
175768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
175868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  size_t memory_limit = (3 * 2 + 3 * 1) * (100 * 100) * 4;
175968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
176068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
176168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
17807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
17817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
17912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only half the root layer, no contents
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be allocated. If render surface memory wasn't accounted for, there is
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enough space for one of the children layers, but they draw into a surface
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that can't be allocated.
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
179968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
180068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  memory_limit = (3 * 1) * (100 * 100) * 4;
180168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
180268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      memory_limit);
180368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get());
18042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, root->fake_layer_updater()->update_count());
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
18227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
18237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TrackingLayerPainter : public LayerPainter {
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<TrackingLayerPainter> Create() {
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new TrackingLayerPainter());
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Paint(SkCanvas* canvas,
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::Rect content_rect,
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::RectF* opaque) OVERRIDE {
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    painted_rect_ = content_rect;
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect PaintedRect() const { return painted_rect_; }
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect painted_rect_;
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UpdateTrackingTiledLayer : public FakeTiledLayer {
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FakeTiledLayer(manager) {
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_layer_painter_ = painter.get();
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_updater_ =
1865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
186690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &stats_instrumentation_,
186790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          0);
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter() const {
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tracking_layer_painter_;
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LayerUpdater* Updater() const OVERRIDE {
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return layer_updater_.get();
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateTrackingTiledLayer() {}
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter_;
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
1882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeRenderingStatsInstrumentation stats_instrumentation_;
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1889a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1890a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.5f);
18952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(0, 0, 45, 47);
18972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(content_rect.size(), layer->content_bounds());
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
19082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in content space. When painting, the rect given
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
1915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest,
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1925a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  layer_tree_host_->root_layer()->AddChild(layer);
1926a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.3f);
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(layer->content_bounds());
19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
19372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in layer space. When painting, the rect given
19482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
19492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(layer_rect);
1950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
19562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1957