tiled_layer_unittest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_ = LayerTreeHost::Create(&fake_layer_impl_tree_host_client_,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             settings_,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             scoped_ptr<Thread>(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,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         proxy_->ImplThread(),
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);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DebugScopedSetMainThread main_thread(proxy_);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->Update(queue_.get(), occluded, NULL);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CalcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer2;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CalcDrawProps(layer1, layer2);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CalcDrawProps(const scoped_refptr<FakeTiledLayer>& layer1,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const scoped_refptr<FakeTiledLayer>& layer2) {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer1.get() && !layer1->parent())
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->root_layer()->AddChild(layer1);
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get() && !layer2->parent())
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_tree_host_->root_layer()->AddChild(layer2);
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (occlusion_)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LayerList render_surface_layer_list;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeHostCommon::CalculateDrawProperties(
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->root_layer(),
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->device_viewport_size(),
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        gfx::Transform(),
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->device_scale_factor(),
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        1.f,    // page_scale_factor
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NULL,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        layer_tree_host_->GetRendererCapabilities().max_texture_size,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        false,  // can_use_lcd_text
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        true,  // can_adjust_raster_scale
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &render_surface_layer_list);
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())
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer1->Update(queue_.get(), occlusion_, NULL);
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (layer2.get())
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer2->Update(queue_.get(), occlusion_, NULL);
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));
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates both tiles, but then only update one of them.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first tile since the other tile was invalidated but
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not painted.
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates part of the top tile...
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ....but the area is occluded.
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(0, 0, 50, 50));
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 2500,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should still have both tiles, as part of the top tile is still
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unoccluded.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushDeletedTiles) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->ClearPriorities();
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(resource_manager_.get(),
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should drop the tiles on the impl thread.
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should now have no textures on the impl thread.
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should recreate and update one of the deleted textures.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tiles on the impl side.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintTiles) {
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // center.  This paints 1 visible of the 25 invalid tiles.
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(500, 500));
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer, layer_impl);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for surrounding tiles.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For the next four updates, we should detect we still need idle painting.
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(needs_update);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should always finish painting eventually.
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 20; i++)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have pre-painted all of the surrounding tiles.
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 5; i++) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int j = 0; j < 5; j++)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PredictivePainting) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepainting should occur in the scroll direction first, and the
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible rect should be extruded only along the dominant axis.
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(10, 20),
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  gfx::Vector2d(-20, 10) };
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should push all tiles that touch the extruded visible rect.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_visible_tiles[6] = {
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first pre-paint should also paint first in the scroll
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // direction so we should find one additional tile in the scroll direction.
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect pushed_prepaint_tiles[6] = {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int k = 0; k < 6; k++) {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The tile size is 100x100. Setup 5x5 tiles with one visible tile
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // in the center.
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Size bounds = gfx::Size(500, 500);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect previous_visible_rect =
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect next_visible_rect =
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Setup. Use the previous_visible_rect to setup the prediction for next
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // frame.
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(bounds);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CalcDrawProps(layer);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = previous_visible_rect;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Invalidate and move the visible_rect in the scroll direction.
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that the correct tiles have been painted in the visible pass.
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetNeedsDisplay();
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 5; i++) {
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int j = 0; j < 5; j++)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  pushed_visible_tiles[k].Contains(i, j));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move the transform in the same direction without invalidating.
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check that non-visible pre-painting occured in the correct direction.
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ignore diagonal scrolls here (k > 3) as these have new visible content
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // now.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (k <= 3) {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->draw_properties().visible_content_rect = next_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_prepaint_tiles[k].Contains(i, j));
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should always finish painting eventually.
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < 20; i++)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      needs_update = UpdateAndPush(layer, layer_impl);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start with 2mb of memory, but the test is going to try to use just more
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // than 1mb, so we reduce to 1mb later.
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // For this test we have two layers. layer1 exhausts most texture memory,
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // leaving room for 2 more tiles from layer2, but not all three tiles. First
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we will fail on the third tile of layer2, and this should not leave the
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // second tile in a bad state.
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for 2 tiles only in the other layer.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer1_rect(0, 0, 100, 2400);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This requires 4*30000 bytes of memory.
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer2_rect(0, 0, 100, 300);
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Paint a single tile in layer2 so that it will idle paint.
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(layer1_rect.size());
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(layer2_rect.size());
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer1, layer2);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = layer1_rect;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should need idle-painting for both remaining tiles in layer2.
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(needs_update);
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Reduce our memory limits to 1mb.
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now idle paint layer2. We are going to run out of memory though!
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Oh well, commit the frame and push.
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 4; i++) {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sanity check, we should have textures for the big layer.
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should only have the first two tiles from layer2 since
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it failed to idle update the last tile.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates one occluded tile, culls it
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during paint, but prepaints it.
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(0, 0, 100, 100));
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have the prepainted tile on the impl side, but culled it during
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint.
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, occluded.overdraw_metrics()->tiles_culled_for_upload());
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, during the paint, we invalidate one of the tiles. This should
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not prevent the tile from being pushed.
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer.get());
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate a tile on layer1, during update of layer 2.
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->fake_layer_updater()->SetRectToInvalidate(
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer1.get());
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer1, layer2);
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer1 =
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer2 =
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer1_impl =
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer2_impl =
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->fake_layer_updater()->SetRectToInvalidate(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(0, 50, 100, 50), layer2.get());
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->SetBounds(gfx::Size(100, 200));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->SetBounds(gfx::Size(100, 200));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer1, layer2);
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side for all layers.
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a LayerTreeHost that has the right viewportsize,
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // so the layer is considered small enough.
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool run_out_of_memory[2] = { false, true };
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Create a layer with 5x5 tiles, with 4x4 size viewport.
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_width = 4 * FakeTiledLayer::tile_size().width();
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int viewport_height = 4 * FakeTiledLayer::tile_size().width();
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_width = 5 * FakeTiledLayer::tile_size().width();
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int layer_height = 5 * FakeTiledLayer::tile_size().height();
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int memory_for_layer = layer_width * layer_height * 4;
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer_tree_host_->SetViewportSize(
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Size(viewport_width, viewport_height));
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use 10x5 tiles to run out of memory.
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (run_out_of_memory[i])
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_width *= 2;
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<FakeTiledLayer> layer =
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Full size layer with half being visible.
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(layer_width, layer_height));
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CalcDrawProps(layer);
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = true;
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect;
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetLayerTreeHost(layer_tree_host_.get());
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer should paint its entire contents on the first paint
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // if it is close to the viewport size and has the available memory.
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetTexturePriorities(priority_calculator_);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource_manager_->PrioritizeTextures();
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    layer->SavePaintProperties();
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->Update(queue_.get(), 0, NULL);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should have all the tiles for the small animated layer.
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should still have the visible tiles when we didn't
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // have enough memory for all the tiles.
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!run_out_of_memory[i]) {
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 5; ++i) {
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (int i = 0; i < 10; ++i) {
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (int j = 0; j < 5; ++j)
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only the visible rect, so we will run out of
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // memory in first idle paint.
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_update = false;
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_update = UpdateAndPush(layer, layer_impl);
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Idle-painting should see no more priority tiles for painting.
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(needs_update);
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have one tile on the impl side.
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool animating[2] = { false, true };
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; i++) {
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Pretend the layer is animating.
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().target_space_transform_is_animating = animating[i];
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The layer's bounds are empty.
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't paint or idle-paint.
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size());
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CalcDrawProps(layer);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = gfx::Rect();
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, layer->NumPaintedTiles());
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't need prepaint.
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Empty layers don't have tiles.
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Alternate between not visible and visible.
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect v(0, 0, 100, 100);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect nv(0, 0, 0, 0);
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          false };
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should not have any tiles except for when the layer was visible
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or after the layer was visible and we didn't invalidate.
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool have_tile[10] = { false, false, true, true, false, false, true, true,
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         true, true };
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 10; i++) {
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->SetBounds(gfx::Size(100, 100));
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CalcDrawProps(layer);
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->draw_properties().visible_content_rect = visible_rect[i];
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (invalidate[i])
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool needs_update = UpdateAndPush(layer, layer_impl);
7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We should never signal idle paint, as we painted the entire layer
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // or the layer was not visible.
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(needs_update);
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, InvalidateFromPrepare) {
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We should have both tiles on the impl side.
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invoke update again. As the layer is valid update shouldn't be invoked on
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the LayerUpdater.
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // update.
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetRectToInvalidate(
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(25, 25, 50, 50), layer.get());
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearPrepareCount();
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The layer should still be invalid as update invoked invalidate.
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAndPush(layer, layer_impl);  // visible
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The update rect (that indicates what was actually painted) should be in
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // layer space, not the content space.
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds(0, 0, 300, 200);
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds(0, 0, 200, 250);
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_bounds.size());
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetContentBounds(content_bounds.size());
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_bounds;
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On first update, the update_rect includes all tiles, even beyond the
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // boundaries of the layer.
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // However, it should still be in layer space, not content space.
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer->update_rect());
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After the tiles are updated once, another invalidate only needs to update
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the bounds of the layer.
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial re-paint should also be represented by the update rect in layer
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space, not content space.
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect partial_damage(30, 100, 10, 10);
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(partial_damage);
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer->update_rect());
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<FakeTiledLayerImpl> layer_impl =
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a layer with one tile.
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 100));
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Push the tiles to the impl side and check that there is exactly one.
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(gfx::Rect());
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change the contents scale.
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(2.f);
8422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The impl side should get 2x2 tiles now.
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that changing the contents scale caused invalidation, and
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that the layer-space rectangle requiring painting is not scaled.
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       layer->last_needs_display_rect());
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer again, but do not paint. All tiles should be
8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // gone now from the impl side.
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplay();
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerPushPropertiesTo(layer.get(), layer_impl.get());
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create two 300 x 300 tiled layers.
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 300);
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have enough memory for only one of the two layers.
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->AddChild(child_layer);
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetBounds(content_bounds);
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->draw_properties().visible_content_rect = content_rect;
8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->SetPosition(gfx::PointF(0, 0));
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetBounds(content_bounds);
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->draw_properties().visible_content_rect = content_rect;
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->SetPosition(gfx::PointF(0, 0));
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->InvalidateContentRect(content_rect);
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child_layer->InvalidateContentRect(content_rect);
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root_layer);
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), memory_limit);
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We'll skip the root layer.
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_layer->SkipsDraw());
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(child_layer->SkipsDraw());
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the child layer.
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_layer->RemoveAllChildren();
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), memory_limit);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(root_layer->SkipsDraw());
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, ResizeToSmaller) {
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(700, 700));
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(200, 200));
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int size = 1 << 30;
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(size, size));
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure no crash for bounds where size * size would overflow an int.
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TiledLayerPartialUpdateTest : public TiledLayerTest {
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create one 300 x 200 tiled layer with 3 x 2 tiles.
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size content_bounds(300, 200);
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(content_bounds);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds);
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(gfx::PointF(0, 0));
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(layer);
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of all 6 tiles.
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Full update of 3 tiles and partial update of 3 tiles.
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->FullUploadSize());
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(3u, queue_->PartialUploadSize());
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 tiles.
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(2u, queue_->FullUploadSize());
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Checkerboard all tiles.
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 6 checkerboard tiles.
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(6u, queue_->FullUploadSize());
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->PartialUploadSize());
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Partial update of 4 tiles.
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> layer_impl =
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_tree_host_->UpdateLayers(queue_.get(),
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   std::numeric_limits<size_t>::max());
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(0u, queue_->FullUploadSize());
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(4u, queue_->PartialUploadSize());
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer->fake_layer_updater()->ClearUpdateCount();
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(layer.get(), layer_impl.get());
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles.
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(100, 200));
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 200, 300, 100));
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000,
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(250, 250, 300, 100));
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
11382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
11392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              330000 + 340000 + 360000,
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The partially occluded tiles (by the 150 occlusion height) are visible
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // beyond the occlusion, so not culled.
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region stops at the edge of the occlusion so the partly
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visible tiles become fully occluded.
11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000,
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now the visible region is even smaller than the occlusion, it should have
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the same result.
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              210000 + 180000 + 180000,
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3 + 6 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { UpdateTextures(); }
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now.
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(6, occluded.overdraw_metrics()->tiles_culled_for_upload());
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the occluded region (in screen
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // space) is transformed differently than the layer.
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(gfx::Size(600, 600));
12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
12782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
12792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 50));
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
1301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> scale_layer =
1306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      new FakeTiledLayer(resource_manager_.get());
1307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  gfx::Transform scale_transform;
1308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_transform.Scale(2.0, 2.0);
1309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->SetTransform(scale_transform);
1310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100.
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure the painting works when the content space is scaled to
1314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // a different layer space.
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
1316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetAnchorPoint(gfx::PointF());
1317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  layer->SetBounds(gfx::Size(300, 300));
1318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  scale_layer->AddChild(layer);
1319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  CalcDrawProps(scale_layer);
1320b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
1321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
1322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(gfx::Size(600, 600).ToString(),
1323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            layer->content_bounds().ToString());
1324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // No tiles are covered by the 300x50 occlusion.
1326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 50));
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
1336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles1 = 6 * 6;
1337b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
1340b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1341b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
1342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              1);
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1347b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
1348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
13492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
13502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->bounds());
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
1358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles2 = 6 * 6 - 3;
1359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->ClearUpdateCount();
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This makes sure content scaling and transforms work together.
1371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // When the tiles are scaled down by half, they are 50x50 each in the
1372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // screen.
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Transform screen_transform;
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  screen_transform.Scale(0.5, 0.5);
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().screen_space_transform = screen_transform;
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().target_space_transform = screen_transform;
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // An occlusion of 150x100 will cover 3*2 = 6 tiles.
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occluded.SetOcclusion(gfx::Rect(100, 100, 150, 100));
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_bounds_rect(layer->bounds());
13822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect =
138390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect =
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(layer->content_bounds());
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
1391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int visible_tiles3 = 6 * 6 - 6;
1392b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
1396b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles3 * 100 * 100 +
1397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles2 * 100 * 100 +
1398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)              visible_tiles1 * 100 * 100,
13992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
1400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(6 + 3, occluded.overdraw_metrics()->tiles_culled_for_upload());
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, VisibleContentOpaqueRegion) {
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 200);
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect visible_bounds = gfx::Rect(0, 0, 100, 150);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = visible_bounds;
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = visible_bounds;
14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the layer doesn't paint opaque content, then the
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should be empty.
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000, 1);
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
14382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // VisibleContentOpaqueRegion should match the visible part of what is painted
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque.
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_paint_rect = gfx::Rect(10, 10, 90, 190);
14442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect);
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
14572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
14592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we paint again without invalidating, the same stuff should be opaque.
14632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
14672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
14742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100,
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint a non-opaque part of the tile, then it shouldn't lose its
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. And other tiles should not be affected.
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1,
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we repaint an opaque part of the tile, then it should lose its
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // opaque-ness. But other tiles should still not be affected.
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                visible_bounds).ToString(),
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            opaque_contents.ToString());
15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              20000 + 20000 - 17100 + 1 + 1,
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, Pixels_paintedMetrics) {
15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> layer =
15252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestOcclusionTracker occluded;
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  occlusion_ = &occluded;
1528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
15292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The tile size is 100x100, so this invalidates and then paints two tiles in
15312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // various ways.
15322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect opaque_paint_rect;
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Region opaque_contents;
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 300);
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(content_bounds.size());
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CalcDrawProps(layer);
15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates and paints the whole layer.
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_bounds);
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 30000, 1);
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
15552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidates an area on the top and bottom tile, which will cause us to
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // paint the tile in the middle, even though it is not dirty and will not be
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // uploaded.
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), &occluded, NULL);
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  opaque_contents = layer->VisibleContentOpaqueRegion();
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(opaque_contents.IsEmpty());
15702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The middle tile was painted even though not invalidated.
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      occluded.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The pixels uploaded will not include the non-invalidated tile in the
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // middle.
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              30000 + 1 + 100,
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              1);
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tile size is 100x100.
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect root_rect(0, 0, 300, 200);
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child_rect(0, 0, 300, 100);
15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect child2_rect(0, 100, 300, 100);
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Layer> surface = Layer::Create();
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetBounds(root_rect.size());
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->SetAnchorPoint(gfx::PointF());
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().drawable_content_rect = root_rect;
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->draw_properties().visible_content_rect = root_rect;
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->AddChild(surface);
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetForceRenderSurface(true);
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetAnchorPoint(gfx::PointF());
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->SetOpacity(0.5);
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child);
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  surface->AddChild(child2);
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetBounds(child_rect.size());
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetAnchorPoint(gfx::PointF());
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->SetPosition(child_rect.origin());
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().visible_content_rect = child_rect;
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->draw_properties().drawable_content_rect = root_rect;
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetBounds(child2_rect.size());
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetAnchorPoint(gfx::PointF());
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->SetPosition(child2_rect.origin());
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().visible_content_rect = child2_rect;
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->draw_properties().drawable_content_rect = root_rect;
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(root);
1622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer_tree_host_->SetViewportSize(root_rect.size());
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a huge memory limit, all layers should update and push their textures.
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 std::numeric_limits<size_t>::max());
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child->fake_layer_updater()->update_count());
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(root.get(), root_impl.get());
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child.get(), child_impl.get());
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only the root layer (3x2 tiles) and half
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the surface that the child layers draw into, the child layers will not be
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // allocated. If the surface isn't accounted for, then one of the children
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // would fit within the memory limit.
16642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(),
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 (3 * 2 + 3 * 1) * (100 * 100) * 4);
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(6, root->fake_layer_updater()->update_count());
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
16782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
16792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(root.get(), root_impl.get());
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child.get(), child_impl.get());
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // With a memory limit that includes only half the root layer, no contents
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be allocated. If render surface memory wasn't accounted for, there is
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enough space for one of the children layers, but they draw into a surface
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that can't be allocated.
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root->InvalidateContentRect(root_rect);
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child->InvalidateContentRect(child_rect);
17052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  child2->InvalidateContentRect(child2_rect);
17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->UpdateLayers(queue_.get(), (3 * 1) * (100 * 100) * 4);
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateTextures();
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, root->fake_layer_updater()->update_count());
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child->fake_layer_updater()->update_count());
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(queue_->HasMoreUpdates());
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root->fake_layer_updater()->ClearUpdateCount();
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child->fake_layer_updater()->ClearUpdateCount();
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    child2->fake_layer_updater()->ClearUpdateCount();
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(root.get(), root_impl.get());
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child.get(), child_impl.get());
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerPushPropertiesTo(child2.get(), child2_impl.get());
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (unsigned i = 0; i < 3; ++i) {
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (unsigned j = 0; j < 2; ++j)
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->CommitComplete();
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                resource_provider_.get());
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_tree_host_->SetRootLayer(NULL);
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TrackingLayerPainter : public LayerPainter {
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<TrackingLayerPainter> Create() {
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return make_scoped_ptr(new TrackingLayerPainter());
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Paint(SkCanvas* canvas,
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::Rect content_rect,
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     gfx::RectF* opaque) OVERRIDE {
17512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    painted_rect_ = content_rect;
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect PaintedRect() const { return painted_rect_; }
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect painted_rect_;
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UpdateTrackingTiledLayer : public FakeTiledLayer {
17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
17642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : FakeTiledLayer(manager) {
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_layer_painter_ = painter.get();
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_updater_ =
1768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
176990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          &stats_instrumentation_,
177090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          0);
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter() const {
17742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tracking_layer_painter_;
17752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
17782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual LayerUpdater* Updater() const OVERRIDE {
17792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return layer_updater_.get();
17802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~UpdateTrackingTiledLayer() {}
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TrackingLayerPainter* tracking_layer_painter_;
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
1785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeRenderingStatsInstrumentation stats_instrumentation_;
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
17912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.5f);
17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(0, 0, 45, 47);
17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(content_rect.size(), layer->content_bounds());
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
18082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
18092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
18112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in content space. When painting, the rect given
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->InvalidateContentRect(content_rect);
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TiledLayerTest,
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<UpdateTrackingTiledLayer> layer =
18242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
18252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect layer_rect(0, 0, 30, 31);
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetPosition(layer_rect.origin());
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetBounds(layer_rect.size());
18292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->UpdateContentsScale(1.3f);
18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect content_rect(layer->content_bounds());
18322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().visible_content_rect = content_rect;
18332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->draw_properties().drawable_content_rect = content_rect;
18342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetTexturePriorities(priority_calculator_);
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_manager_->PrioritizeTextures();
1837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  layer->SavePaintProperties();
18382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update the whole tile.
18402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->tracking_layer_painter()->ResetPaintedRect();
18422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
18442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateTextures();
18452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Invalidate the entire layer in layer space. When painting, the rect given
18472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to webkit should match the layer's bounds.
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->SetNeedsDisplayRect(layer_rect);
18492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer->Update(queue_.get(), 0, NULL);
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
18552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1856