tiled_layer_unittest.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/fake_proxy.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/fake_rendering_stats_instrumentation.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/geometry_test_utils.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/tiled_layer_test_common.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/single_thread_proxy.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect_conversions.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestOcclusionTracker : public OcclusionTracker {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.push_back(StackObject());
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetRenderTarget(Layer* render_target) {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().target = render_target;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetOcclusion(const Region& occlusion) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    stack_.back().occlusion_from_inside_target = occlusion;
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerTest : public testing::Test {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerTest()
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : proxy_(NULL),
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        output_surface_(CreateFakeOutputSurface()),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        queue_(make_scoped_ptr(new ResourceUpdateQueue)),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fake_layer_impl_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D),
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        occlusion_(NULL) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    settings_.layer_transforms_should_scale_layer_contents = true;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() {
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer_tree_host_ = LayerTreeHost::Create(&fake_layer_impl_tree_host_client_,
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                             settings_,
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                             NULL);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    proxy_ = layer_tree_host_->proxy();
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_ = PrioritizedResourceManager::Create(proxy_);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->InitializeOutputSurfaceIfNeeded();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->SetRootLayer(Layer::Create());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    resource_provider_ = ResourceProvider::Create(output_surface_.get(), 0);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TiledLayerTest() {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceManagerClearAllMemory(resource_manager_.get(),
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  resource_provider_.get());
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_provider_.reset();
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_impl_.reset();
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResourceManagerClearAllMemory(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PrioritizedResourceManager* resource_manager,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResourceProvider* resource_provider) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DebugScopedSetImplThreadAndMainThreadBlocked
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      impl_thread_and_main_thread_blocked(proxy_);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ClearAllMemory(resource_provider);
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_manager->ReduceMemory(resource_provider);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager->UnlinkAndClearEvictedBackings();
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateTextures() {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(queue_);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ResourceUpdateController> update_controller =
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ResourceUpdateController::Create(NULL,
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                         proxy_->ImplThreadTaskRunner(),
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         queue_.Pass(),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         resource_provider_.get());
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    update_controller->Finalize();
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queue_ = make_scoped_ptr(new ResourceUpdateQueue);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerPushPropertiesTo(FakeTiledLayer* layer,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FakeTiledLayerImpl* layer_impl) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetImplThreadAndMainThreadBlocked
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    impl_thread_and_main_thread_blocked(proxy_);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->PushPropertiesTo(layer_impl);
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    layer->ResetNumDependentsNeedPushProperties();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThread main_thread(proxy_);
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), occluded);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  void CalcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1,
122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                     RenderSurfaceLayerList* render_surface_layer_list) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer2;
124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer1, layer2, render_surface_layer_list);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CalcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1,
128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                     const scoped_refptr<FakeTiledLayer>& layer2,
129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                     RenderSurfaceLayerList* render_surface_layer_list) {
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get() && !layer1->parent())
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->root_layer()->AddChild(layer1);
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get() && !layer2->parent())
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->root_layer()->AddChild(layer2);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (occlusion_)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
137558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->root_layer(),
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->device_viewport_size(),
140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        render_surface_layer_list);
141558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
142558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.max_texture_size =
143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        layer_tree_host_->GetRendererCapabilities().max_texture_size;
144558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    inputs.can_adjust_raster_scales = true;
145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer2;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl2;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_refptr<FakeTiledLayer>& layer2,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get textures
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->ClearPriorities();
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer1->SetTexturePriorities(priority_calculator_);
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer2->SetTexturePriorities(priority_calculator_);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Save paint properties
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer1->SavePaintProperties();
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      layer2->SavePaintProperties();
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update content
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer1->Update(queue_.get(), occlusion_);
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      layer2->Update(queue_.get(), occlusion_);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = false;
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer1->NeedsIdlePaint();
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update |= layer2->NeedsIdlePaint();
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update textures and push.
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get())
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return needs_update;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Proxy* proxy_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerTreeSettings settings_;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<OutputSurface> output_surface_;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider_;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceUpdateQueue> queue_;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PriorityCalculator priority_calculator_;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeLayerTreeHostClient fake_layer_impl_tree_host_client_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerTreeHost> layer_tree_host_;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<PrioritizedResourceManager> resource_manager_;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker* occlusion_;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDirtyTiles) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates both tiles, but then only update one of them.
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first tile since the other tile was invalidated but
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not painted.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // The tile size is 100x100, so this invalidates and then paints two tiles.
249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->SetBounds(gfx::Size(100, 200));
250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(
255ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
256ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should have both tiles on the impl side.
259ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
260ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Invalidates part of the top tile...
267ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
268ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // ....but the area is occluded.
269ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    occluded.SetOcclusion(gfx::Rect(0, 0, 50, 50));
270ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
271ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UpdateAndPush(layer, layer_impl);
272ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
273ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
274ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
275ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                20000 + 2500,
276ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                1);
277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // We should still have both tiles, as part of the top tile is still
280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // unoccluded.
281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
282ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDeletedTiles) {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->ClearPriorities();
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(resource_manager_.get(),
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should drop the tiles on the impl thread.
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should now have no textures on the impl thread.
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should recreate and update one of the deleted textures.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tiles on the impl side.
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintTiles) {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // center.  This paints 1 visible of the 25 invalid tiles.
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(500, 500));
333ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer, layer_impl);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for surrounding tiles.
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For the next four updates, we should detect we still need idle painting.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(needs_update);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should always finish painting eventually.
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 20; i++)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have pre-painted all of the surrounding tiles.
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int j = 0; j < 5; j++)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PredictivePainting) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepainting should occur in the scroll direction first, and the
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible rect should be extruded only along the dominant axis.
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(10, 20),
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(-20, 10) };
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should push all tiles that touch the extruded visible rect.
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_visible_tiles[6] = {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first pre-paint should also paint first in the scroll
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // direction so we should find one additional tile in the scroll direction.
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_prepaint_tiles[6] = {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int k = 0; k < 6; k++) {
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The tile size is 100x100. Setup 5x5 tiles with one visible tile
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // in the center.
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Size bounds = gfx::Size(500, 500);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect previous_visible_rect =
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect next_visible_rect =
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Setup. Use the previous_visible_rect to setup the prediction for next
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame.
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(bounds);
397ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
398ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
399ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = previous_visible_rect;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Invalidate and move the visible_rect in the scroll direction.
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that the correct tiles have been painted in the visible pass.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetNeedsDisplay();
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 5; i++) {
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int j = 0; j < 5; j++)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  pushed_visible_tiles[k].Contains(i, j));
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move the transform in the same direction without invalidating.
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that non-visible pre-painting occured in the correct direction.
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore diagonal scrolls here (k > 3) as these have new visible content
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // now.
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (k <= 3) {
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->draw_properties().visible_content_rect = next_visible_rect;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; i++) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; j++)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    pushed_prepaint_tiles[k].Contains(i, j));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should always finish painting eventually.
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 20; i++)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start with 2mb of memory, but the test is going to try to use just more
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // than 1mb, so we reduce to 1mb later.
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
447ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For this test we have two layers. layer1 exhausts most texture memory,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // leaving room for 2 more tiles from layer2, but not all three tiles. First
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we will fail on the third tile of layer2, and this should not leave the
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // second tile in a bad state.
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for 2 tiles only in the other layer.
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer1_rect(0, 0, 100, 2400);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This requires 4*30000 bytes of memory.
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer2_rect(0, 0, 100, 300);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Paint a single tile in layer2 so that it will idle paint.
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(layer1_rect.size());
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(layer2_rect.size());
465ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer1, layer2, &render_surface_layer_list);
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = layer1_rect;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for both remaining tiles in layer2.
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reduce our memory limits to 1mb.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now idle paint layer2. We are going to run out of memory though!
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Oh well, commit the frame and push.
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sanity check, we should have textures for the big layer.
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first two tiles from layer2 since
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it failed to idle update the last tile.
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
501ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates one occluded tile, culls it
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during paint, but prepaints it.
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(0, 0, 100, 100));
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
510ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have the prepainted tile on the impl side, but culled it during
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, occluded.overdraw_metrics()->tiles_culled_for_upload());
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
525ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, during the paint, we invalidate one of the tiles. This should
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not prevent the tile from being pushed.
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer.get());
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
533ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
551ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate a tile on layer1, during update of layer 2.
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->fake_layer_updater()->SetRectToInvalidate(
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer1.get());
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
558ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer1, layer2, &render_surface_layer_list);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->fake_layer_updater()->SetRectToInvalidate(
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer2.get());
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer1, layer2, &render_surface_layer_list);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a LayerTreeHost that has the right viewportsize,
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the layer is considered small enough.
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool run_out_of_memory[2] = { false, true };
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a layer with 5x5 tiles, with 4x4 size viewport.
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_width = 4 * FakeTiledLayer::tile_size().width();
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_height = 4 * FakeTiledLayer::tile_size().width();
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_width = 5 * FakeTiledLayer::tile_size().width();
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_height = 5 * FakeTiledLayer::tile_size().height();
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int memory_for_layer = layer_width * layer_height * 4;
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->SetViewportSize(
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Size(viewport_width, viewport_height));
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use 10x5 tiles to run out of memory.
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (run_out_of_memory[i])
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_width *= 2;
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer =
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
621ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Full size layer with half being visible.
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(layer_width, layer_height));
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
626ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = true;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetLayerTreeHost(layer_tree_host_.get());
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer should paint its entire contents on the first paint
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // if it is close to the viewport size and has the available memory.
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetTexturePriorities(priority_calculator_);
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer->SavePaintProperties();
638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    layer->Update(queue_.get(), NULL);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should have all the tiles for the small animated layer.
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should still have the visible tiles when we didn't
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // have enough memory for all the tiles.
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!run_out_of_memory[i]) {
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; ++i) {
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 10; ++i) {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
664ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only the visible rect, so we will run out of
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // memory in first idle paint.
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = false;
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
674ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Idle-painting should see no more priority tiles for painting.
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool animating[2] = { false, true };
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = animating[i];
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer's bounds are empty.
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't paint or idle-paint.
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size());
700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
701ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
702ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = gfx::Rect();
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, layer->NumPaintedTiles());
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't need prepaint.
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Alternate between not visible and visible.
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect v(0, 0, 100, 100);
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect nv(0, 0, 0, 0);
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          false };
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not have any tiles except for when the layer was visible
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or after the layer was visible and we didn't invalidate.
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_tile[10] = { false, false, true, true, false, false, true, true,
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         true, true };
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 10; i++) {
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(100, 100));
737ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
738ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    RenderSurfaceLayerList render_surface_layer_list;
739ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    CalcDrawProps(layer, &render_surface_layer_list);
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect[i];
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (invalidate[i])
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should never signal idle paint, as we painted the entire layer
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // or the layer was not visible.
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, InvalidateFromPrepare) {
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
758ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
762ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invoke update again. As the layer is valid update shouldn't be invoked on
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the LayerUpdater.
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // update.
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(25, 25, 50, 50), layer.get());
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The layer should still be invalid as update invoked invalidate.
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);  // visible
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The update rect (that indicates what was actually painted) should be in
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // layer space, not the content space.
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds(0, 0, 300, 200);
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds(0, 0, 200, 250);
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_bounds.size());
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetContentBounds(content_bounds.size());
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_bounds;
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On first update, the update_rect includes all tiles, even beyond the
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // boundaries of the layer.
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, it should still be in layer space, not content space.
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
812eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer->update_rect());
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After the tiles are updated once, another invalidate only needs to update
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the bounds of the layer.
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial re-paint should also be represented by the update rect in layer
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space, not content space.
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect partial_damage(30, 100, 10, 10);
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(partial_damage);
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer->update_rect());
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
842ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a layer with one tile.
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
846ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
8487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  layer->Update(queue_.get(), NULL);
8497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UpdateTextures();
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Push the tiles to the impl side and check that there is exactly one.
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(gfx::Rect());
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the contents scale.
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(2.f);
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The impl side should get 2x2 tiles now.
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that changing the contents scale caused invalidation, and
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that the layer-space rectangle requiring painting is not scaled.
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer again, but do not paint. All tiles should be
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // gone now from the impl side.
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplay();
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create two 300 x 300 tiled layers.
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 300);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only one of the two layers.
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->AddChild(child_layer);
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetBounds(content_bounds);
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->draw_properties().visible_content_rect = content_rect;
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetPosition(gfx::PointF(0, 0));
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetBounds(content_bounds);
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->draw_properties().visible_content_rect = content_rect;
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetPosition(gfx::PointF(0, 0));
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->InvalidateContentRect(content_rect);
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->InvalidateContentRect(content_rect);
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root_layer);
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), memory_limit);
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We'll skip the root layer.
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_layer->SkipsDraw());
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(child_layer->SkipsDraw());
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the child layer.
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->RemoveAllChildren();
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), memory_limit);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(root_layer->SkipsDraw());
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, ResizeToSmaller) {
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(700, 700));
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(200, 200));
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int size = 1 << 30;
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(size, size));
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure no crash for bounds where size * size would overflow an int.
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerPartialUpdateTest : public TiledLayerTest {
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create one 300 x 200 tiled layer with 3 x 2 tiles.
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 200);
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds);
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(gfx::PointF(0, 0));
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(layer);
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of all 6 tiles.
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of 3 tiles and partial update of 3 tiles.
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->FullUploadSize());
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->PartialUploadSize());
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 tiles.
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(2u, queue_->FullUploadSize());
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Checkerboard all tiles.
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
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)  // Partial update of 6 checkerboard tiles.
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 4 tiles.
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->FullUploadSize());
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
1105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 200, 300, 100));
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000,
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 250, 300, 100));
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000 + 360000,
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The partially occluded tiles (by the 150 occlusion height) are visible
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // beyond the occlusion, so not culled.
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region stops at the edge of the occlusion so the partly
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible tiles become fully occluded.
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000,
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region is even smaller than the occlusion, it should have
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the same result.
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000 + 180000,
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { UpdateTextures(); }
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now.
1286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
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)
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the occluded region (in screen
13052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space) is transformed differently than the layer.
1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
13072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
1308ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
13092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 50));
13152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
1334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1339b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> scale_layer =
1340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gfx::Transform scale_transform;
1342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_transform.Scale(2.0, 2.0);
1343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->SetTransform(scale_transform);
1344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the content space is scaled to
1348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // a different layer space.
1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
1350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetAnchorPoint(gfx::PointF());
1351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
1352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->AddChild(layer);
1353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(scale_layer, &render_surface_layer_list);
1354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
1355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
1356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(gfx::Size(600, 600).ToString(),
1357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            layer->content_bounds().ToString());
1358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // No tiles are covered by the 300x50 occlusion.
1360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 50));
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
13632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles1 = 6 * 6;
1371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
1376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              1);
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles2 = 6 * 6 - 3;
1393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure content scaling and transforms work together.
1405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // When the tiles are scaled down by half, they are 50x50 each in the
1406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // screen.
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1412b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // An occlusion of 150x100 will cover 3*2 = 6 tiles.
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 100));
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds_rect(layer->bounds());
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
141790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
1425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles3 = 6 * 6 - 6;
1426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles3 * 100 * 100 +
1431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1434b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(6 + 3, occluded.overdraw_metrics()->tiles_culled_for_upload());
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VisibleContentOpaqueRegion) {
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 200);
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_bounds = gfx::Rect(0, 0, 100, 150);
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
1455ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = visible_bounds;
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = visible_bounds;
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the layer doesn't paint opaque content, then the
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should be empty.
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000, 1);
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should match the visible part of what is painted
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque.
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_paint_rect = gfx::Rect(10, 10, 90, 190);
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect);
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we paint again without invalidating, the same stuff should be opaque.
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint a non-opaque part of the tile, then it shouldn't lose its
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. And other tiles should not be affected.
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1522eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1,
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint an opaque part of the tile, then it should lose its
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. But other tiles should still not be affected.
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                visible_bounds).ToString(),
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1 + 1,
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, Pixels_paintedMetrics) {
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
1561ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  RenderSurfaceLayerList render_surface_layer_list;
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 300);
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
1574ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  CalcDrawProps(layer, &render_surface_layer_list);
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates and paints the whole layer.
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1582eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 30000, 1);
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates an area on the top and bottom tile, which will cause us to
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint the tile in the middle, even though it is not dirty and will not be
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // uploaded.
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
1602eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), &occluded);
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The middle tile was painted even though not invalidated.
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The pixels uploaded will not include the non-invalidated tile in the
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // middle.
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              30000 + 1 + 100,
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tile size is 100x100.
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect root_rect(0, 0, 300, 200);
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child_rect(0, 0, 300, 100);
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child2_rect(0, 100, 300, 100);
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Layer> surface = Layer::Create();
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetBounds(root_rect.size());
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetAnchorPoint(gfx::PointF());
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().drawable_content_rect = root_rect;
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().visible_content_rect = root_rect;
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->AddChild(surface);
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetForceRenderSurface(true);
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetAnchorPoint(gfx::PointF());
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetOpacity(0.5);
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child);
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child2);
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetBounds(child_rect.size());
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetAnchorPoint(gfx::PointF());
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetPosition(child_rect.origin());
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().visible_content_rect = child_rect;
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().drawable_content_rect = root_rect;
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetBounds(child2_rect.size());
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetAnchorPoint(gfx::PointF());
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetPosition(child2_rect.origin());
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().visible_content_rect = child2_rect;
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().drawable_content_rect = root_rect;
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root);
1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(root_rect.size());
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a huge memory limit, all layers should update and push their textures.
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child->fake_layer_updater()->update_count());
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
16847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
16857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only the root layer (3x2 tiles) and half
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the surface that the child layers draw into, the child layers will not be
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // allocated. If the surface isn't accounted for, then one of the children
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // would fit within the memory limit.
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 (3 * 2 + 3 * 1) * (100 * 100) * 4);
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
17237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
17247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only half the root layer, no contents
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be allocated. If render surface memory wasn't accounted for, there is
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enough space for one of the children layers, but they draw into a surface
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that can't be allocated.
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), (3 * 1) * (100 * 100) * 4);
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, root->fake_layer_updater()->update_count());
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
17617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(child.get(), child_impl.get());
17627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerPushPropertiesTo(root.get(), root_impl.get());
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TrackingLayerPainter : public LayerPainter {
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<TrackingLayerPainter> Create() {
17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new TrackingLayerPainter());
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Paint(SkCanvas* canvas,
17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::Rect content_rect,
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::RectF* opaque) OVERRIDE {
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    painted_rect_ = content_rect;
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect PaintedRect() const { return painted_rect_; }
17912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect painted_rect_;
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UpdateTrackingTiledLayer : public FakeTiledLayer {
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FakeTiledLayer(manager) {
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_layer_painter_ = painter.get();
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_updater_ =
1804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
180590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &stats_instrumentation_,
180690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          0);
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter() const {
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tracking_layer_painter_;
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LayerUpdater* Updater() const OVERRIDE {
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return layer_updater_.get();
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateTrackingTiledLayer() {}
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter_;
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
1821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeRenderingStatsInstrumentation stats_instrumentation_;
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.5f);
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(0, 0, 45, 47);
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(content_rect.size(), layer->content_bounds());
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
18372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in content space. When painting, the rect given
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
1852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest,
18582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
18612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
18632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
18642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
18652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.3f);
18662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(layer->content_bounds());
18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
18702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
1876eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
18802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
18812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in layer space. When painting, the rect given
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(layer_rect);
1885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  layer->Update(queue_.get(), NULL);
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1892