Home | History | Annotate | Download | only in layers
      1 // Copyright 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/layers/tiled_layer.h"
      6 
      7 #include <limits>
      8 #include <vector>
      9 
     10 #include "cc/debug/overdraw_metrics.h"
     11 #include "cc/resources/bitmap_content_layer_updater.h"
     12 #include "cc/resources/layer_painter.h"
     13 #include "cc/resources/prioritized_resource_manager.h"
     14 #include "cc/resources/resource_update_controller.h"
     15 #include "cc/test/animation_test_common.h"
     16 #include "cc/test/fake_layer_tree_host_client.h"
     17 #include "cc/test/fake_layer_tree_host_impl.h"
     18 #include "cc/test/fake_output_surface.h"
     19 #include "cc/test/fake_output_surface_client.h"
     20 #include "cc/test/fake_proxy.h"
     21 #include "cc/test/fake_rendering_stats_instrumentation.h"
     22 #include "cc/test/geometry_test_utils.h"
     23 #include "cc/test/tiled_layer_test_common.h"
     24 #include "cc/trees/single_thread_proxy.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 #include "ui/gfx/rect_conversions.h"
     27 #include "ui/gfx/transform.h"
     28 
     29 namespace cc {
     30 namespace {
     31 
     32 class TestOcclusionTracker : public OcclusionTracker {
     33  public:
     34   TestOcclusionTracker() : OcclusionTracker(gfx::Rect(0, 0, 1000, 1000), true) {
     35     stack_.push_back(StackObject());
     36   }
     37 
     38   void SetRenderTarget(Layer* render_target) {
     39     stack_.back().target = render_target;
     40   }
     41 
     42   void SetOcclusion(const Region& occlusion) {
     43     stack_.back().occlusion_from_inside_target = occlusion;
     44   }
     45 };
     46 
     47 class TiledLayerTest : public testing::Test {
     48  public:
     49   TiledLayerTest()
     50       : proxy_(NULL),
     51         output_surface_(FakeOutputSurface::Create3d()),
     52         queue_(make_scoped_ptr(new ResourceUpdateQueue)),
     53         impl_thread_("ImplThread"),
     54         fake_layer_tree_host_client_(FakeLayerTreeHostClient::DIRECT_3D),
     55         occlusion_(NULL) {
     56     settings_.max_partial_texture_updates = std::numeric_limits<size_t>::max();
     57     settings_.layer_transforms_should_scale_layer_contents = true;
     58   }
     59 
     60   virtual void SetUp() {
     61     impl_thread_.Start();
     62     layer_tree_host_ = LayerTreeHost::CreateThreaded(
     63         &fake_layer_tree_host_client_,
     64         NULL,
     65         settings_,
     66         impl_thread_.message_loop_proxy());
     67     proxy_ = layer_tree_host_->proxy();
     68     resource_manager_ = PrioritizedResourceManager::Create(proxy_);
     69     layer_tree_host_->SetLayerTreeHostClientReady();
     70     layer_tree_host_->InitializeOutputSurfaceIfNeeded();
     71     layer_tree_host_->SetRootLayer(Layer::Create());
     72 
     73     CHECK(output_surface_->BindToClient(&output_surface_client_));
     74 
     75     DebugScopedSetImplThreadAndMainThreadBlocked
     76         impl_thread_and_main_thread_blocked(proxy_);
     77     resource_provider_ =
     78         ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
     79     host_impl_ = make_scoped_ptr(new FakeLayerTreeHostImpl(proxy_));
     80   }
     81 
     82   virtual ~TiledLayerTest() {
     83     ResourceManagerClearAllMemory(resource_manager_.get(),
     84                                   resource_provider_.get());
     85 
     86     DebugScopedSetImplThreadAndMainThreadBlocked
     87     impl_thread_and_main_thread_blocked(proxy_);
     88     resource_provider_.reset();
     89     host_impl_.reset();
     90   }
     91 
     92   void ResourceManagerClearAllMemory(
     93       PrioritizedResourceManager* resource_manager,
     94       ResourceProvider* resource_provider) {
     95     {
     96       DebugScopedSetImplThreadAndMainThreadBlocked
     97       impl_thread_and_main_thread_blocked(proxy_);
     98       resource_manager->ClearAllMemory(resource_provider);
     99       resource_manager->ReduceMemory(resource_provider);
    100     }
    101     resource_manager->UnlinkAndClearEvictedBackings();
    102   }
    103 
    104   void UpdateTextures() {
    105     DebugScopedSetImplThreadAndMainThreadBlocked
    106     impl_thread_and_main_thread_blocked(proxy_);
    107     DCHECK(queue_);
    108     scoped_ptr<ResourceUpdateController> update_controller =
    109         ResourceUpdateController::Create(NULL,
    110                                          proxy_->ImplThreadTaskRunner(),
    111                                          queue_.Pass(),
    112                                          resource_provider_.get());
    113     update_controller->Finalize();
    114     queue_ = make_scoped_ptr(new ResourceUpdateQueue);
    115   }
    116 
    117   void LayerPushPropertiesTo(FakeTiledLayer* layer,
    118                              FakeTiledLayerImpl* layer_impl) {
    119     DebugScopedSetImplThreadAndMainThreadBlocked
    120     impl_thread_and_main_thread_blocked(proxy_);
    121     layer->PushPropertiesTo(layer_impl);
    122     layer->ResetNumDependentsNeedPushProperties();
    123   }
    124 
    125   void LayerUpdate(FakeTiledLayer* layer, TestOcclusionTracker* occluded) {
    126     DebugScopedSetMainThread main_thread(proxy_);
    127     layer->Update(queue_.get(), occluded);
    128   }
    129 
    130   void CalcDrawProps(RenderSurfaceLayerList* render_surface_layer_list) {
    131     if (occlusion_)
    132       occlusion_->SetRenderTarget(layer_tree_host_->root_layer());
    133 
    134     LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
    135         layer_tree_host_->root_layer(),
    136         layer_tree_host_->device_viewport_size(),
    137         render_surface_layer_list);
    138     inputs.device_scale_factor = layer_tree_host_->device_scale_factor();
    139     inputs.max_texture_size =
    140         layer_tree_host_->GetRendererCapabilities().max_texture_size;
    141     inputs.can_adjust_raster_scales = true;
    142     LayerTreeHostCommon::CalculateDrawProperties(&inputs);
    143   }
    144 
    145   bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
    146                      const scoped_ptr<FakeTiledLayerImpl>& layer_impl1) {
    147     scoped_refptr<FakeTiledLayer> layer2;
    148     scoped_ptr<FakeTiledLayerImpl> layer_impl2;
    149     return UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
    150   }
    151 
    152   bool UpdateAndPush(const scoped_refptr<FakeTiledLayer>& layer1,
    153                      const scoped_ptr<FakeTiledLayerImpl>& layer_impl1,
    154                      const scoped_refptr<FakeTiledLayer>& layer2,
    155                      const scoped_ptr<FakeTiledLayerImpl>& layer_impl2) {
    156     // Get textures
    157     resource_manager_->ClearPriorities();
    158     if (layer1.get())
    159       layer1->SetTexturePriorities(priority_calculator_);
    160     if (layer2.get())
    161       layer2->SetTexturePriorities(priority_calculator_);
    162     resource_manager_->PrioritizeTextures();
    163 
    164     // Save paint properties
    165     if (layer1.get())
    166       layer1->SavePaintProperties();
    167     if (layer2.get())
    168       layer2->SavePaintProperties();
    169 
    170     // Update content
    171     if (layer1.get())
    172       layer1->Update(queue_.get(), occlusion_);
    173     if (layer2.get())
    174       layer2->Update(queue_.get(), occlusion_);
    175 
    176     bool needs_update = false;
    177     if (layer1.get())
    178       needs_update |= layer1->NeedsIdlePaint();
    179     if (layer2.get())
    180       needs_update |= layer2->NeedsIdlePaint();
    181 
    182     // Update textures and push.
    183     UpdateTextures();
    184     if (layer1.get())
    185       LayerPushPropertiesTo(layer1.get(), layer_impl1.get());
    186     if (layer2.get())
    187       LayerPushPropertiesTo(layer2.get(), layer_impl2.get());
    188 
    189     return needs_update;
    190   }
    191 
    192  public:
    193   Proxy* proxy_;
    194   LayerTreeSettings settings_;
    195   FakeOutputSurfaceClient output_surface_client_;
    196   scoped_ptr<OutputSurface> output_surface_;
    197   scoped_ptr<ResourceProvider> resource_provider_;
    198   scoped_ptr<ResourceUpdateQueue> queue_;
    199   PriorityCalculator priority_calculator_;
    200   base::Thread impl_thread_;
    201   FakeLayerTreeHostClient fake_layer_tree_host_client_;
    202   scoped_ptr<LayerTreeHost> layer_tree_host_;
    203   scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
    204   scoped_ptr<PrioritizedResourceManager> resource_manager_;
    205   TestOcclusionTracker* occlusion_;
    206 };
    207 
    208 TEST_F(TiledLayerTest, PushDirtyTiles) {
    209   scoped_refptr<FakeTiledLayer> layer =
    210       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    211   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    212       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    213   RenderSurfaceLayerList render_surface_layer_list;
    214 
    215   layer_tree_host_->root_layer()->AddChild(layer);
    216 
    217   // The tile size is 100x100, so this invalidates and then paints two tiles.
    218   layer->SetBounds(gfx::Size(100, 200));
    219   CalcDrawProps(&render_surface_layer_list);
    220   UpdateAndPush(layer, layer_impl);
    221 
    222   // We should have both tiles on the impl side.
    223   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    224   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    225 
    226   // Invalidates both tiles, but then only update one of them.
    227   layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 200));
    228   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
    229   UpdateAndPush(layer, layer_impl);
    230 
    231   // We should only have the first tile since the other tile was invalidated but
    232   // not painted.
    233   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    234   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
    235 }
    236 
    237 TEST_F(TiledLayerTest, PushOccludedDirtyTiles) {
    238   scoped_refptr<FakeTiledLayer> layer =
    239       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    240   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    241       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    242   TestOcclusionTracker occluded;
    243   occlusion_ = &occluded;
    244   layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
    245 
    246   layer_tree_host_->root_layer()->AddChild(layer);
    247 
    248   {
    249     RenderSurfaceLayerList render_surface_layer_list;
    250 
    251     // The tile size is 100x100, so this invalidates and then paints two tiles.
    252     layer->SetBounds(gfx::Size(100, 200));
    253     CalcDrawProps(&render_surface_layer_list);
    254     UpdateAndPush(layer, layer_impl);
    255 
    256     EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
    257     EXPECT_NEAR(
    258         occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
    259     EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
    260 
    261     // We should have both tiles on the impl side.
    262     EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    263     EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    264   }
    265 
    266   {
    267     RenderSurfaceLayerList render_surface_layer_list;
    268 
    269     // Invalidates part of the top tile...
    270     layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
    271     // ....but the area is occluded.
    272     occluded.SetOcclusion(gfx::Rect(0, 0, 50, 50));
    273     CalcDrawProps(&render_surface_layer_list);
    274     UpdateAndPush(layer, layer_impl);
    275 
    276     EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
    277     EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
    278                 20000 + 2500,
    279                 1);
    280     EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
    281 
    282     // We should still have both tiles, as part of the top tile is still
    283     // unoccluded.
    284     EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    285     EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    286   }
    287 }
    288 
    289 TEST_F(TiledLayerTest, PushDeletedTiles) {
    290   scoped_refptr<FakeTiledLayer> layer =
    291       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    292   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    293       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    294   RenderSurfaceLayerList render_surface_layer_list;
    295 
    296   layer_tree_host_->root_layer()->AddChild(layer);
    297 
    298   // The tile size is 100x100, so this invalidates and then paints two tiles.
    299   layer->SetBounds(gfx::Size(100, 200));
    300   CalcDrawProps(&render_surface_layer_list);
    301   UpdateAndPush(layer, layer_impl);
    302 
    303   // We should have both tiles on the impl side.
    304   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    305   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    306 
    307   resource_manager_->ClearPriorities();
    308   ResourceManagerClearAllMemory(resource_manager_.get(),
    309                                 resource_provider_.get());
    310   resource_manager_->SetMaxMemoryLimitBytes(4 * 1024 * 1024);
    311 
    312   // This should drop the tiles on the impl thread.
    313   LayerPushPropertiesTo(layer.get(), layer_impl.get());
    314 
    315   // We should now have no textures on the impl thread.
    316   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
    317   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
    318 
    319   // This should recreate and update one of the deleted textures.
    320   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
    321   UpdateAndPush(layer, layer_impl);
    322 
    323   // We should have one tiles on the impl side.
    324   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    325   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
    326 }
    327 
    328 TEST_F(TiledLayerTest, PushIdlePaintTiles) {
    329   scoped_refptr<FakeTiledLayer> layer =
    330       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    331   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    332       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    333   RenderSurfaceLayerList render_surface_layer_list;
    334 
    335   layer_tree_host_->root_layer()->AddChild(layer);
    336 
    337   // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the
    338   // center.  This paints 1 visible of the 25 invalid tiles.
    339   layer->SetBounds(gfx::Size(500, 500));
    340   CalcDrawProps(&render_surface_layer_list);
    341   layer->draw_properties().visible_content_rect = gfx::Rect(200, 200, 100, 100);
    342   bool needs_update = UpdateAndPush(layer, layer_impl);
    343   // We should need idle-painting for surrounding tiles.
    344   EXPECT_TRUE(needs_update);
    345 
    346   // We should have one tile on the impl side.
    347   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(2, 2));
    348 
    349   // For the next four updates, we should detect we still need idle painting.
    350   for (int i = 0; i < 4; i++) {
    351     needs_update = UpdateAndPush(layer, layer_impl);
    352     EXPECT_TRUE(needs_update);
    353   }
    354 
    355   // We should always finish painting eventually.
    356   for (int i = 0; i < 20; i++)
    357     needs_update = UpdateAndPush(layer, layer_impl);
    358 
    359   // We should have pre-painted all of the surrounding tiles.
    360   for (int i = 0; i < 5; i++) {
    361     for (int j = 0; j < 5; j++)
    362       EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
    363   }
    364 
    365   EXPECT_FALSE(needs_update);
    366 }
    367 
    368 TEST_F(TiledLayerTest, PredictivePainting) {
    369   scoped_refptr<FakeTiledLayer> layer =
    370       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    371   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    372       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    373 
    374   layer_tree_host_->root_layer()->AddChild(layer);
    375 
    376   // Prepainting should occur in the scroll direction first, and the
    377   // visible rect should be extruded only along the dominant axis.
    378   gfx::Vector2d directions[6] = { gfx::Vector2d(-10, 0), gfx::Vector2d(10, 0),
    379                                   gfx::Vector2d(0, -10), gfx::Vector2d(0, 10),
    380                                   gfx::Vector2d(10, 20),
    381                                   gfx::Vector2d(-20, 10) };
    382   // We should push all tiles that touch the extruded visible rect.
    383   gfx::Rect pushed_visible_tiles[6] = {
    384     gfx::Rect(2, 2, 2, 1), gfx::Rect(1, 2, 2, 1), gfx::Rect(2, 2, 1, 2),
    385     gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 1, 1, 2), gfx::Rect(2, 2, 2, 1)
    386   };
    387   // The first pre-paint should also paint first in the scroll
    388   // direction so we should find one additional tile in the scroll direction.
    389   gfx::Rect pushed_prepaint_tiles[6] = {
    390     gfx::Rect(2, 2, 3, 1), gfx::Rect(0, 2, 3, 1), gfx::Rect(2, 2, 1, 3),
    391     gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 0, 1, 3), gfx::Rect(2, 2, 3, 1)
    392   };
    393   for (int k = 0; k < 6; k++) {
    394     // The tile size is 100x100. Setup 5x5 tiles with one visible tile
    395     // in the center.
    396     gfx::Size bounds = gfx::Size(500, 500);
    397     gfx::Rect visible_rect = gfx::Rect(200, 200, 100, 100);
    398     gfx::Rect previous_visible_rect =
    399         gfx::Rect(visible_rect.origin() + directions[k], visible_rect.size());
    400     gfx::Rect next_visible_rect =
    401         gfx::Rect(visible_rect.origin() - directions[k], visible_rect.size());
    402 
    403     // Setup. Use the previous_visible_rect to setup the prediction for next
    404     // frame.
    405     layer->SetBounds(bounds);
    406 
    407     RenderSurfaceLayerList render_surface_layer_list;
    408     CalcDrawProps(&render_surface_layer_list);
    409     layer->draw_properties().visible_content_rect = previous_visible_rect;
    410     bool needs_update = UpdateAndPush(layer, layer_impl);
    411 
    412     // Invalidate and move the visible_rect in the scroll direction.
    413     // Check that the correct tiles have been painted in the visible pass.
    414     layer->SetNeedsDisplay();
    415     layer->draw_properties().visible_content_rect = visible_rect;
    416     needs_update = UpdateAndPush(layer, layer_impl);
    417     for (int i = 0; i < 5; i++) {
    418       for (int j = 0; j < 5; j++)
    419         EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
    420                   pushed_visible_tiles[k].Contains(i, j));
    421     }
    422 
    423     // Move the transform in the same direction without invalidating.
    424     // Check that non-visible pre-painting occured in the correct direction.
    425     // Ignore diagonal scrolls here (k > 3) as these have new visible content
    426     // now.
    427     if (k <= 3) {
    428       layer->draw_properties().visible_content_rect = next_visible_rect;
    429       needs_update = UpdateAndPush(layer, layer_impl);
    430       for (int i = 0; i < 5; i++) {
    431         for (int j = 0; j < 5; j++)
    432           EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j),
    433                     pushed_prepaint_tiles[k].Contains(i, j));
    434       }
    435     }
    436 
    437     // We should always finish painting eventually.
    438     for (int i = 0; i < 20; i++)
    439       needs_update = UpdateAndPush(layer, layer_impl);
    440     EXPECT_FALSE(needs_update);
    441   }
    442 }
    443 
    444 TEST_F(TiledLayerTest, PushTilesAfterIdlePaintFailed) {
    445   // Start with 2mb of memory, but the test is going to try to use just more
    446   // than 1mb, so we reduce to 1mb later.
    447   resource_manager_->SetMaxMemoryLimitBytes(2 * 1024 * 1024);
    448   scoped_refptr<FakeTiledLayer> layer1 =
    449       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    450   scoped_ptr<FakeTiledLayerImpl> layer_impl1 =
    451       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    452   scoped_refptr<FakeTiledLayer> layer2 =
    453       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    454   scoped_ptr<FakeTiledLayerImpl> layer_impl2 =
    455       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
    456   RenderSurfaceLayerList render_surface_layer_list;
    457 
    458   layer_tree_host_->root_layer()->AddChild(layer1);
    459   layer_tree_host_->root_layer()->AddChild(layer2);
    460 
    461   // For this test we have two layers. layer1 exhausts most texture memory,
    462   // leaving room for 2 more tiles from layer2, but not all three tiles. First
    463   // we paint layer1, and one tile from layer2. Then when we idle paint layer2,
    464   // we will fail on the third tile of layer2, and this should not leave the
    465   // second tile in a bad state.
    466 
    467   // This uses 960000 bytes, leaving 88576 bytes of memory left, which is enough
    468   // for 2 tiles only in the other layer.
    469   gfx::Rect layer1_rect(0, 0, 100, 2400);
    470 
    471   // This requires 4*30000 bytes of memory.
    472   gfx::Rect layer2_rect(0, 0, 100, 300);
    473 
    474   // Paint a single tile in layer2 so that it will idle paint.
    475   layer1->SetBounds(layer1_rect.size());
    476   layer2->SetBounds(layer2_rect.size());
    477   CalcDrawProps(&render_surface_layer_list);
    478   layer1->draw_properties().visible_content_rect = layer1_rect;
    479   layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
    480   bool needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
    481   // We should need idle-painting for both remaining tiles in layer2.
    482   EXPECT_TRUE(needs_update);
    483 
    484   // Reduce our memory limits to 1mb.
    485   resource_manager_->SetMaxMemoryLimitBytes(1024 * 1024);
    486 
    487   // Now idle paint layer2. We are going to run out of memory though!
    488   // Oh well, commit the frame and push.
    489   for (int i = 0; i < 4; i++) {
    490     needs_update = UpdateAndPush(layer1, layer_impl1, layer2, layer_impl2);
    491   }
    492 
    493   // Sanity check, we should have textures for the big layer.
    494   EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 0));
    495   EXPECT_TRUE(layer_impl1->HasResourceIdForTileAt(0, 23));
    496 
    497   // We should only have the first two tiles from layer2 since
    498   // it failed to idle update the last tile.
    499   EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
    500   EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 0));
    501   EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
    502   EXPECT_TRUE(layer_impl2->HasResourceIdForTileAt(0, 1));
    503 
    504   EXPECT_FALSE(needs_update);
    505   EXPECT_FALSE(layer_impl2->HasResourceIdForTileAt(0, 2));
    506 }
    507 
    508 TEST_F(TiledLayerTest, PushIdlePaintedOccludedTiles) {
    509   scoped_refptr<FakeTiledLayer> layer =
    510       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    511   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    512       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    513   RenderSurfaceLayerList render_surface_layer_list;
    514   TestOcclusionTracker occluded;
    515   occlusion_ = &occluded;
    516 
    517   layer_tree_host_->root_layer()->AddChild(layer);
    518 
    519   // The tile size is 100x100, so this invalidates one occluded tile, culls it
    520   // during paint, but prepaints it.
    521   occluded.SetOcclusion(gfx::Rect(0, 0, 100, 100));
    522 
    523   layer->SetBounds(gfx::Size(100, 100));
    524   CalcDrawProps(&render_surface_layer_list);
    525   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
    526   UpdateAndPush(layer, layer_impl);
    527 
    528   // We should have the prepainted tile on the impl side, but culled it during
    529   // paint.
    530   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    531   EXPECT_EQ(1, occluded.overdraw_metrics()->tiles_culled_for_upload());
    532 }
    533 
    534 TEST_F(TiledLayerTest, PushTilesMarkedDirtyDuringPaint) {
    535   scoped_refptr<FakeTiledLayer> layer =
    536       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    537   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    538       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    539   RenderSurfaceLayerList render_surface_layer_list;
    540 
    541   layer_tree_host_->root_layer()->AddChild(layer);
    542 
    543   // The tile size is 100x100, so this invalidates and then paints two tiles.
    544   // However, during the paint, we invalidate one of the tiles. This should
    545   // not prevent the tile from being pushed.
    546   layer->fake_layer_updater()->SetRectToInvalidate(
    547       gfx::Rect(0, 50, 100, 50), layer.get());
    548   layer->SetBounds(gfx::Size(100, 200));
    549   CalcDrawProps(&render_surface_layer_list);
    550   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    551   UpdateAndPush(layer, layer_impl);
    552 
    553   // We should have both tiles on the impl side.
    554   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    555   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    556 }
    557 
    558 TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnNextLayer) {
    559   scoped_refptr<FakeTiledLayer> layer1 =
    560       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    561   scoped_refptr<FakeTiledLayer> layer2 =
    562       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    563   scoped_ptr<FakeTiledLayerImpl> layer1_impl =
    564       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    565   scoped_ptr<FakeTiledLayerImpl> layer2_impl =
    566       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
    567   RenderSurfaceLayerList render_surface_layer_list;
    568 
    569   layer_tree_host_->root_layer()->AddChild(layer1);
    570   layer_tree_host_->root_layer()->AddChild(layer2);
    571 
    572   // Invalidate a tile on layer1, during update of layer 2.
    573   layer2->fake_layer_updater()->SetRectToInvalidate(
    574       gfx::Rect(0, 50, 100, 50), layer1.get());
    575   layer1->SetBounds(gfx::Size(100, 200));
    576   layer2->SetBounds(gfx::Size(100, 200));
    577   CalcDrawProps(&render_surface_layer_list);
    578   layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    579   layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    580   UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
    581 
    582   // We should have both tiles on the impl side for all layers.
    583   EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
    584   EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
    585   EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
    586   EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
    587 }
    588 
    589 TEST_F(TiledLayerTest, PushTilesLayerMarkedDirtyDuringPaintOnPreviousLayer) {
    590   scoped_refptr<FakeTiledLayer> layer1 =
    591       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    592   scoped_refptr<FakeTiledLayer> layer2 =
    593       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    594   scoped_ptr<FakeTiledLayerImpl> layer1_impl =
    595       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    596   scoped_ptr<FakeTiledLayerImpl> layer2_impl =
    597       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 2));
    598   RenderSurfaceLayerList render_surface_layer_list;
    599 
    600   layer_tree_host_->root_layer()->AddChild(layer1);
    601   layer_tree_host_->root_layer()->AddChild(layer2);
    602 
    603   layer1->fake_layer_updater()->SetRectToInvalidate(
    604       gfx::Rect(0, 50, 100, 50), layer2.get());
    605   layer1->SetBounds(gfx::Size(100, 200));
    606   layer2->SetBounds(gfx::Size(100, 200));
    607   CalcDrawProps(&render_surface_layer_list);
    608   layer1->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    609   layer2->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    610   UpdateAndPush(layer1, layer1_impl, layer2, layer2_impl);
    611 
    612   // We should have both tiles on the impl side for all layers.
    613   EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 0));
    614   EXPECT_TRUE(layer1_impl->HasResourceIdForTileAt(0, 1));
    615   EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 0));
    616   EXPECT_TRUE(layer2_impl->HasResourceIdForTileAt(0, 1));
    617 }
    618 
    619 TEST_F(TiledLayerTest, PaintSmallAnimatedLayersImmediately) {
    620   // Create a LayerTreeHost that has the right viewportsize,
    621   // so the layer is considered small enough.
    622   bool run_out_of_memory[2] = { false, true };
    623   for (int i = 0; i < 2; i++) {
    624     // Create a layer with 5x5 tiles, with 4x4 size viewport.
    625     int viewport_width = 4 * FakeTiledLayer::tile_size().width();
    626     int viewport_height = 4 * FakeTiledLayer::tile_size().width();
    627     int layer_width = 5 * FakeTiledLayer::tile_size().width();
    628     int layer_height = 5 * FakeTiledLayer::tile_size().height();
    629     int memory_for_layer = layer_width * layer_height * 4;
    630     layer_tree_host_->SetViewportSize(
    631         gfx::Size(viewport_width, viewport_height));
    632 
    633     // Use 10x5 tiles to run out of memory.
    634     if (run_out_of_memory[i])
    635       layer_width *= 2;
    636 
    637     resource_manager_->SetMaxMemoryLimitBytes(memory_for_layer);
    638 
    639     scoped_refptr<FakeTiledLayer> layer =
    640         make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    641     scoped_ptr<FakeTiledLayerImpl> layer_impl =
    642         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    643     RenderSurfaceLayerList render_surface_layer_list;
    644 
    645     layer_tree_host_->root_layer()->AddChild(layer);
    646 
    647     // Full size layer with half being visible.
    648     layer->SetBounds(gfx::Size(layer_width, layer_height));
    649     gfx::Rect visible_rect(0, 0, layer_width / 2, layer_height);
    650     CalcDrawProps(&render_surface_layer_list);
    651 
    652     // Pretend the layer is animating.
    653     layer->draw_properties().target_space_transform_is_animating = true;
    654     layer->draw_properties().visible_content_rect = visible_rect;
    655     layer->SetLayerTreeHost(layer_tree_host_.get());
    656 
    657     // The layer should paint its entire contents on the first paint
    658     // if it is close to the viewport size and has the available memory.
    659     layer->SetTexturePriorities(priority_calculator_);
    660     resource_manager_->PrioritizeTextures();
    661     layer->SavePaintProperties();
    662     layer->Update(queue_.get(), NULL);
    663     UpdateTextures();
    664     LayerPushPropertiesTo(layer.get(), layer_impl.get());
    665 
    666     // We should have all the tiles for the small animated layer.
    667     // We should still have the visible tiles when we didn't
    668     // have enough memory for all the tiles.
    669     if (!run_out_of_memory[i]) {
    670       for (int i = 0; i < 5; ++i) {
    671         for (int j = 0; j < 5; ++j)
    672           EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(i, j));
    673       }
    674     } else {
    675       for (int i = 0; i < 10; ++i) {
    676         for (int j = 0; j < 5; ++j)
    677           EXPECT_EQ(layer_impl->HasResourceIdForTileAt(i, j), i < 5);
    678       }
    679     }
    680 
    681     layer->RemoveFromParent();
    682   }
    683 }
    684 
    685 TEST_F(TiledLayerTest, IdlePaintOutOfMemory) {
    686   scoped_refptr<FakeTiledLayer> layer =
    687       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    688   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    689       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    690   RenderSurfaceLayerList render_surface_layer_list;
    691 
    692   layer_tree_host_->root_layer()->AddChild(layer);
    693 
    694   // We have enough memory for only the visible rect, so we will run out of
    695   // memory in first idle paint.
    696   int memory_limit = 4 * 100 * 100;  // 1 tiles, 4 bytes per pixel.
    697   resource_manager_->SetMaxMemoryLimitBytes(memory_limit);
    698 
    699   // The tile size is 100x100, so this invalidates and then paints two tiles.
    700   bool needs_update = false;
    701   layer->SetBounds(gfx::Size(300, 300));
    702   CalcDrawProps(&render_surface_layer_list);
    703   layer->draw_properties().visible_content_rect = gfx::Rect(100, 100, 100, 100);
    704   for (int i = 0; i < 2; i++)
    705     needs_update = UpdateAndPush(layer, layer_impl);
    706 
    707   // Idle-painting should see no more priority tiles for painting.
    708   EXPECT_FALSE(needs_update);
    709 
    710   // We should have one tile on the impl side.
    711   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
    712 }
    713 
    714 TEST_F(TiledLayerTest, IdlePaintZeroSizedLayer) {
    715   scoped_refptr<FakeTiledLayer> layer =
    716       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    717   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    718       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    719 
    720   layer_tree_host_->root_layer()->AddChild(layer);
    721 
    722   bool animating[2] = { false, true };
    723   for (int i = 0; i < 2; i++) {
    724     // Pretend the layer is animating.
    725     layer->draw_properties().target_space_transform_is_animating = animating[i];
    726 
    727     // The layer's bounds are empty.
    728     // Empty layers don't paint or idle-paint.
    729     layer->SetBounds(gfx::Size());
    730 
    731     RenderSurfaceLayerList render_surface_layer_list;
    732     CalcDrawProps(&render_surface_layer_list);
    733     layer->draw_properties().visible_content_rect = gfx::Rect();
    734     bool needs_update = UpdateAndPush(layer, layer_impl);
    735 
    736     // Empty layers don't have tiles.
    737     EXPECT_EQ(0u, layer->NumPaintedTiles());
    738 
    739     // Empty layers don't need prepaint.
    740     EXPECT_FALSE(needs_update);
    741 
    742     // Empty layers don't have tiles.
    743     EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
    744   }
    745 }
    746 
    747 TEST_F(TiledLayerTest, IdlePaintNonVisibleLayers) {
    748   scoped_refptr<FakeTiledLayer> layer =
    749       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    750   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    751       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    752 
    753   // Alternate between not visible and visible.
    754   gfx::Rect v(0, 0, 100, 100);
    755   gfx::Rect nv(0, 0, 0, 0);
    756   gfx::Rect visible_rect[10] = { nv, nv, v, v, nv, nv, v, v, nv, nv };
    757   bool invalidate[10] = { true, true, true, true, true, true, true, true, false,
    758                           false };
    759 
    760   // We should not have any tiles except for when the layer was visible
    761   // or after the layer was visible and we didn't invalidate.
    762   bool have_tile[10] = { false, false, true, true, false, false, true, true,
    763                          true, true };
    764 
    765   layer_tree_host_->root_layer()->AddChild(layer);
    766 
    767   for (int i = 0; i < 10; i++) {
    768     layer->SetBounds(gfx::Size(100, 100));
    769 
    770     RenderSurfaceLayerList render_surface_layer_list;
    771     CalcDrawProps(&render_surface_layer_list);
    772     layer->draw_properties().visible_content_rect = visible_rect[i];
    773 
    774     if (invalidate[i])
    775       layer->InvalidateContentRect(gfx::Rect(0, 0, 100, 100));
    776     bool needs_update = UpdateAndPush(layer, layer_impl);
    777 
    778     // We should never signal idle paint, as we painted the entire layer
    779     // or the layer was not visible.
    780     EXPECT_FALSE(needs_update);
    781     EXPECT_EQ(layer_impl->HasResourceIdForTileAt(0, 0), have_tile[i]);
    782   }
    783 }
    784 
    785 TEST_F(TiledLayerTest, InvalidateFromPrepare) {
    786   scoped_refptr<FakeTiledLayer> layer =
    787       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    788   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    789       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    790   RenderSurfaceLayerList render_surface_layer_list;
    791 
    792   layer_tree_host_->root_layer()->AddChild(layer);
    793 
    794   // The tile size is 100x100, so this invalidates and then paints two tiles.
    795   layer->SetBounds(gfx::Size(100, 200));
    796   CalcDrawProps(&render_surface_layer_list);
    797   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 200);
    798   UpdateAndPush(layer, layer_impl);
    799 
    800   // We should have both tiles on the impl side.
    801   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    802   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    803 
    804   layer->fake_layer_updater()->ClearPrepareCount();
    805   // Invoke update again. As the layer is valid update shouldn't be invoked on
    806   // the LayerUpdater.
    807   UpdateAndPush(layer, layer_impl);
    808   EXPECT_EQ(0, layer->fake_layer_updater()->prepare_count());
    809 
    810   // SetRectToInvalidate triggers InvalidateContentRect() being invoked from
    811   // update.
    812   layer->fake_layer_updater()->SetRectToInvalidate(
    813       gfx::Rect(25, 25, 50, 50), layer.get());
    814   layer->fake_layer_updater()->ClearPrepareCount();
    815   layer->InvalidateContentRect(gfx::Rect(0, 0, 50, 50));
    816   UpdateAndPush(layer, layer_impl);
    817   EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
    818   layer->fake_layer_updater()->ClearPrepareCount();
    819 
    820   // The layer should still be invalid as update invoked invalidate.
    821   UpdateAndPush(layer, layer_impl);  // visible
    822   EXPECT_EQ(1, layer->fake_layer_updater()->prepare_count());
    823 }
    824 
    825 TEST_F(TiledLayerTest, VerifyUpdateRectWhenContentBoundsAreScaled) {
    826   // The update rect (that indicates what was actually painted) should be in
    827   // layer space, not the content space.
    828   scoped_refptr<FakeTiledLayerWithScaledBounds> layer = make_scoped_refptr(
    829       new FakeTiledLayerWithScaledBounds(resource_manager_.get()));
    830 
    831   layer_tree_host_->root_layer()->AddChild(layer);
    832 
    833   gfx::Rect layer_bounds(0, 0, 300, 200);
    834   gfx::Rect content_bounds(0, 0, 200, 250);
    835 
    836   layer->SetBounds(layer_bounds.size());
    837   layer->SetContentBounds(content_bounds.size());
    838   layer->draw_properties().visible_content_rect = content_bounds;
    839 
    840   // On first update, the update_rect includes all tiles, even beyond the
    841   // boundaries of the layer.
    842   // However, it should still be in layer space, not content space.
    843   layer->InvalidateContentRect(content_bounds);
    844 
    845   layer->SetTexturePriorities(priority_calculator_);
    846   resource_manager_->PrioritizeTextures();
    847   layer->SavePaintProperties();
    848   layer->Update(queue_.get(), NULL);
    849   EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 300, 300 * 0.8), layer->update_rect());
    850   UpdateTextures();
    851 
    852   // After the tiles are updated once, another invalidate only needs to update
    853   // the bounds of the layer.
    854   layer->SetTexturePriorities(priority_calculator_);
    855   resource_manager_->PrioritizeTextures();
    856   layer->InvalidateContentRect(content_bounds);
    857   layer->SavePaintProperties();
    858   layer->Update(queue_.get(), NULL);
    859   EXPECT_FLOAT_RECT_EQ(gfx::RectF(layer_bounds), layer->update_rect());
    860   UpdateTextures();
    861 
    862   // Partial re-paint should also be represented by the update rect in layer
    863   // space, not content space.
    864   gfx::Rect partial_damage(30, 100, 10, 10);
    865   layer->InvalidateContentRect(partial_damage);
    866   layer->SetTexturePriorities(priority_calculator_);
    867   resource_manager_->PrioritizeTextures();
    868   layer->SavePaintProperties();
    869   layer->Update(queue_.get(), NULL);
    870   EXPECT_FLOAT_RECT_EQ(gfx::RectF(45, 80, 15, 8), layer->update_rect());
    871 }
    872 
    873 TEST_F(TiledLayerTest, VerifyInvalidationWhenContentsScaleChanges) {
    874   scoped_refptr<FakeTiledLayer> layer =
    875       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    876   scoped_ptr<FakeTiledLayerImpl> layer_impl =
    877       make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
    878   RenderSurfaceLayerList render_surface_layer_list;
    879 
    880   layer_tree_host_->root_layer()->AddChild(layer);
    881 
    882   // Create a layer with one tile.
    883   layer->SetBounds(gfx::Size(100, 100));
    884   CalcDrawProps(&render_surface_layer_list);
    885   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 100, 100);
    886   layer->Update(queue_.get(), NULL);
    887   UpdateTextures();
    888   EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
    889                        layer->last_needs_display_rect());
    890 
    891   // Push the tiles to the impl side and check that there is exactly one.
    892   layer->SetTexturePriorities(priority_calculator_);
    893   resource_manager_->PrioritizeTextures();
    894   layer->SavePaintProperties();
    895   layer->Update(queue_.get(), NULL);
    896   UpdateTextures();
    897   LayerPushPropertiesTo(layer.get(), layer_impl.get());
    898   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    899   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
    900   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
    901   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
    902 
    903   layer->SetNeedsDisplayRect(gfx::Rect());
    904   EXPECT_FLOAT_RECT_EQ(gfx::RectF(), layer->last_needs_display_rect());
    905 
    906   // Change the contents scale.
    907   layer->UpdateContentsScale(2.f);
    908   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 200, 200);
    909 
    910   // The impl side should get 2x2 tiles now.
    911   layer->SetTexturePriorities(priority_calculator_);
    912   resource_manager_->PrioritizeTextures();
    913   layer->SavePaintProperties();
    914   layer->Update(queue_.get(), NULL);
    915   UpdateTextures();
    916   LayerPushPropertiesTo(layer.get(), layer_impl.get());
    917   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 0));
    918   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(0, 1));
    919   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 0));
    920   EXPECT_TRUE(layer_impl->HasResourceIdForTileAt(1, 1));
    921 
    922   // Verify that changing the contents scale caused invalidation, and
    923   // that the layer-space rectangle requiring painting is not scaled.
    924   EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100),
    925                        layer->last_needs_display_rect());
    926 
    927   // Invalidate the entire layer again, but do not paint. All tiles should be
    928   // gone now from the impl side.
    929   layer->SetNeedsDisplay();
    930   layer->SetTexturePriorities(priority_calculator_);
    931   resource_manager_->PrioritizeTextures();
    932 
    933   LayerPushPropertiesTo(layer.get(), layer_impl.get());
    934   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 0));
    935   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(0, 1));
    936   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 0));
    937   EXPECT_FALSE(layer_impl->HasResourceIdForTileAt(1, 1));
    938 }
    939 
    940 TEST_F(TiledLayerTest, SkipsDrawGetsReset) {
    941   // Create two 300 x 300 tiled layers.
    942   gfx::Size content_bounds(300, 300);
    943   gfx::Rect content_rect(content_bounds);
    944 
    945   // We have enough memory for only one of the two layers.
    946   int memory_limit = 4 * 300 * 300;  // 4 bytes per pixel.
    947 
    948   scoped_refptr<FakeTiledLayer> root_layer = make_scoped_refptr(
    949       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
    950   scoped_refptr<FakeTiledLayer> child_layer = make_scoped_refptr(
    951       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
    952   root_layer->AddChild(child_layer);
    953 
    954   root_layer->SetBounds(content_bounds);
    955   root_layer->draw_properties().visible_content_rect = content_rect;
    956   root_layer->SetPosition(gfx::PointF(0, 0));
    957   child_layer->SetBounds(content_bounds);
    958   child_layer->draw_properties().visible_content_rect = content_rect;
    959   child_layer->SetPosition(gfx::PointF(0, 0));
    960   root_layer->InvalidateContentRect(content_rect);
    961   child_layer->InvalidateContentRect(content_rect);
    962 
    963   layer_tree_host_->SetRootLayer(root_layer);
    964   layer_tree_host_->SetViewportSize(gfx::Size(300, 300));
    965   layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
    966       memory_limit);
    967 
    968   layer_tree_host_->UpdateLayers(queue_.get());
    969 
    970   // We'll skip the root layer.
    971   EXPECT_TRUE(root_layer->SkipsDraw());
    972   EXPECT_FALSE(child_layer->SkipsDraw());
    973 
    974   layer_tree_host_->CommitComplete();
    975 
    976   // Remove the child layer.
    977   root_layer->RemoveAllChildren();
    978 
    979   layer_tree_host_->UpdateLayers(queue_.get());
    980   EXPECT_FALSE(root_layer->SkipsDraw());
    981 
    982   ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
    983                                 resource_provider_.get());
    984   layer_tree_host_->SetRootLayer(NULL);
    985 }
    986 
    987 TEST_F(TiledLayerTest, ResizeToSmaller) {
    988   scoped_refptr<FakeTiledLayer> layer =
    989       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
    990 
    991   layer_tree_host_->root_layer()->AddChild(layer);
    992 
    993   layer->SetBounds(gfx::Size(700, 700));
    994   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
    995   layer->InvalidateContentRect(gfx::Rect(0, 0, 700, 700));
    996 
    997   layer->SetTexturePriorities(priority_calculator_);
    998   resource_manager_->PrioritizeTextures();
    999   layer->SavePaintProperties();
   1000   layer->Update(queue_.get(), NULL);
   1001 
   1002   layer->SetBounds(gfx::Size(200, 200));
   1003   layer->InvalidateContentRect(gfx::Rect(0, 0, 200, 200));
   1004 }
   1005 
   1006 TEST_F(TiledLayerTest, HugeLayerUpdateCrash) {
   1007   scoped_refptr<FakeTiledLayer> layer =
   1008       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1009 
   1010   layer_tree_host_->root_layer()->AddChild(layer);
   1011 
   1012   int size = 1 << 30;
   1013   layer->SetBounds(gfx::Size(size, size));
   1014   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 700, 700);
   1015   layer->InvalidateContentRect(gfx::Rect(0, 0, size, size));
   1016 
   1017   // Ensure no crash for bounds where size * size would overflow an int.
   1018   layer->SetTexturePriorities(priority_calculator_);
   1019   resource_manager_->PrioritizeTextures();
   1020   layer->SavePaintProperties();
   1021   layer->Update(queue_.get(), NULL);
   1022 }
   1023 
   1024 class TiledLayerPartialUpdateTest : public TiledLayerTest {
   1025  public:
   1026   TiledLayerPartialUpdateTest() { settings_.max_partial_texture_updates = 4; }
   1027 };
   1028 
   1029 TEST_F(TiledLayerPartialUpdateTest, PartialUpdates) {
   1030   // Create one 300 x 200 tiled layer with 3 x 2 tiles.
   1031   gfx::Size content_bounds(300, 200);
   1032   gfx::Rect content_rect(content_bounds);
   1033 
   1034   scoped_refptr<FakeTiledLayer> layer = make_scoped_refptr(
   1035       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
   1036   layer->SetBounds(content_bounds);
   1037   layer->SetPosition(gfx::PointF(0, 0));
   1038   layer->draw_properties().visible_content_rect = content_rect;
   1039   layer->InvalidateContentRect(content_rect);
   1040 
   1041   layer_tree_host_->SetRootLayer(layer);
   1042   layer_tree_host_->SetViewportSize(gfx::Size(300, 200));
   1043 
   1044   // Full update of all 6 tiles.
   1045   layer_tree_host_->UpdateLayers(queue_.get());
   1046   {
   1047     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1048         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1049     EXPECT_EQ(6u, queue_->FullUploadSize());
   1050     EXPECT_EQ(0u, queue_->PartialUploadSize());
   1051     UpdateTextures();
   1052     EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
   1053     EXPECT_FALSE(queue_->HasMoreUpdates());
   1054     layer->fake_layer_updater()->ClearUpdateCount();
   1055     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1056   }
   1057   layer_tree_host_->CommitComplete();
   1058 
   1059   // Full update of 3 tiles and partial update of 3 tiles.
   1060   layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 150));
   1061   layer_tree_host_->UpdateLayers(queue_.get());
   1062   {
   1063     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1064         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1065     EXPECT_EQ(3u, queue_->FullUploadSize());
   1066     EXPECT_EQ(3u, queue_->PartialUploadSize());
   1067     UpdateTextures();
   1068     EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
   1069     EXPECT_FALSE(queue_->HasMoreUpdates());
   1070     layer->fake_layer_updater()->ClearUpdateCount();
   1071     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1072   }
   1073   layer_tree_host_->CommitComplete();
   1074 
   1075   // Partial update of 6 tiles.
   1076   layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
   1077   {
   1078     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1079         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1080     layer_tree_host_->UpdateLayers(queue_.get());
   1081     EXPECT_EQ(2u, queue_->FullUploadSize());
   1082     EXPECT_EQ(4u, queue_->PartialUploadSize());
   1083     UpdateTextures();
   1084     EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
   1085     EXPECT_FALSE(queue_->HasMoreUpdates());
   1086     layer->fake_layer_updater()->ClearUpdateCount();
   1087     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1088   }
   1089   layer_tree_host_->CommitComplete();
   1090 
   1091   // Checkerboard all tiles.
   1092   layer->InvalidateContentRect(gfx::Rect(0, 0, 300, 200));
   1093   {
   1094     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1095         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1096     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1097   }
   1098   layer_tree_host_->CommitComplete();
   1099 
   1100   // Partial update of 6 checkerboard tiles.
   1101   layer->InvalidateContentRect(gfx::Rect(50, 50, 200, 100));
   1102   {
   1103     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1104         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1105     layer_tree_host_->UpdateLayers(queue_.get());
   1106     EXPECT_EQ(6u, queue_->FullUploadSize());
   1107     EXPECT_EQ(0u, queue_->PartialUploadSize());
   1108     UpdateTextures();
   1109     EXPECT_EQ(6, layer->fake_layer_updater()->update_count());
   1110     EXPECT_FALSE(queue_->HasMoreUpdates());
   1111     layer->fake_layer_updater()->ClearUpdateCount();
   1112     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1113   }
   1114   layer_tree_host_->CommitComplete();
   1115 
   1116   // Partial update of 4 tiles.
   1117   layer->InvalidateContentRect(gfx::Rect(50, 50, 100, 100));
   1118   {
   1119     scoped_ptr<FakeTiledLayerImpl> layer_impl =
   1120         make_scoped_ptr(new FakeTiledLayerImpl(host_impl_->active_tree(), 1));
   1121     layer_tree_host_->UpdateLayers(queue_.get());
   1122     EXPECT_EQ(0u, queue_->FullUploadSize());
   1123     EXPECT_EQ(4u, queue_->PartialUploadSize());
   1124     UpdateTextures();
   1125     EXPECT_EQ(4, layer->fake_layer_updater()->update_count());
   1126     EXPECT_FALSE(queue_->HasMoreUpdates());
   1127     layer->fake_layer_updater()->ClearUpdateCount();
   1128     LayerPushPropertiesTo(layer.get(), layer_impl.get());
   1129   }
   1130   layer_tree_host_->CommitComplete();
   1131 
   1132   ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
   1133                                 resource_provider_.get());
   1134   layer_tree_host_->SetRootLayer(NULL);
   1135 }
   1136 
   1137 TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
   1138   scoped_refptr<FakeTiledLayer> layer =
   1139       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1140   RenderSurfaceLayerList render_surface_layer_list;
   1141 
   1142   layer_tree_host_->root_layer()->AddChild(layer);
   1143 
   1144   // The tile size is 100x100, so this invalidates and then paints two tiles.
   1145   layer->SetBounds(gfx::Size(100, 200));
   1146   CalcDrawProps(&render_surface_layer_list);
   1147 
   1148   layer->SetTexturePriorities(priority_calculator_);
   1149   resource_manager_->PrioritizeTextures();
   1150   layer->SavePaintProperties();
   1151   layer->Update(queue_.get(), NULL);
   1152   EXPECT_EQ(2, layer->fake_layer_updater()->update_count());
   1153 }
   1154 
   1155 TEST_F(TiledLayerTest, TilesPaintedWithOcclusion) {
   1156   scoped_refptr<FakeTiledLayer> layer =
   1157       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1158   RenderSurfaceLayerList render_surface_layer_list;
   1159   TestOcclusionTracker occluded;
   1160   occlusion_ = &occluded;
   1161 
   1162   layer_tree_host_->root_layer()->AddChild(layer);
   1163 
   1164   // The tile size is 100x100.
   1165 
   1166   layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
   1167   layer->SetBounds(gfx::Size(600, 600));
   1168   CalcDrawProps(&render_surface_layer_list);
   1169 
   1170   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
   1171   layer->draw_properties().drawable_content_rect =
   1172       gfx::Rect(layer->content_bounds());
   1173   layer->draw_properties().visible_content_rect =
   1174       gfx::Rect(layer->content_bounds());
   1175   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1176 
   1177   layer->SetTexturePriorities(priority_calculator_);
   1178   resource_manager_->PrioritizeTextures();
   1179   layer->SavePaintProperties();
   1180   layer->Update(queue_.get(), &occluded);
   1181   EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
   1182 
   1183   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1184   EXPECT_NEAR(
   1185       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
   1186   EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1187 
   1188   layer->fake_layer_updater()->ClearUpdateCount();
   1189   layer->SetTexturePriorities(priority_calculator_);
   1190   resource_manager_->PrioritizeTextures();
   1191 
   1192   occluded.SetOcclusion(gfx::Rect(250, 200, 300, 100));
   1193   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1194   layer->SavePaintProperties();
   1195   layer->Update(queue_.get(), &occluded);
   1196   EXPECT_EQ(36 - 2, layer->fake_layer_updater()->update_count());
   1197 
   1198   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1199   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1200               330000 + 340000,
   1201               1);
   1202   EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1203 
   1204   layer->fake_layer_updater()->ClearUpdateCount();
   1205   layer->SetTexturePriorities(priority_calculator_);
   1206   resource_manager_->PrioritizeTextures();
   1207 
   1208   occluded.SetOcclusion(gfx::Rect(250, 250, 300, 100));
   1209   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1210   layer->SavePaintProperties();
   1211   layer->Update(queue_.get(), &occluded);
   1212   EXPECT_EQ(36, layer->fake_layer_updater()->update_count());
   1213 
   1214   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1215   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1216               330000 + 340000 + 360000,
   1217               1);
   1218   EXPECT_EQ(3 + 2, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1219 }
   1220 
   1221 TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndVisiblityConstraints) {
   1222   scoped_refptr<FakeTiledLayer> layer =
   1223       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1224   RenderSurfaceLayerList render_surface_layer_list;
   1225   TestOcclusionTracker occluded;
   1226   occlusion_ = &occluded;
   1227 
   1228   layer_tree_host_->root_layer()->AddChild(layer);
   1229 
   1230   // The tile size is 100x100.
   1231 
   1232   layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
   1233   layer->SetBounds(gfx::Size(600, 600));
   1234   CalcDrawProps(&render_surface_layer_list);
   1235 
   1236   // The partially occluded tiles (by the 150 occlusion height) are visible
   1237   // beyond the occlusion, so not culled.
   1238   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
   1239   layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 360);
   1240   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 360);
   1241   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1242 
   1243   layer->SetTexturePriorities(priority_calculator_);
   1244   resource_manager_->PrioritizeTextures();
   1245   layer->SavePaintProperties();
   1246   layer->Update(queue_.get(), &occluded);
   1247   EXPECT_EQ(24 - 3, layer->fake_layer_updater()->update_count());
   1248 
   1249   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1250   EXPECT_NEAR(
   1251       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 210000, 1);
   1252   EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1253 
   1254   layer->fake_layer_updater()->ClearUpdateCount();
   1255 
   1256   // Now the visible region stops at the edge of the occlusion so the partly
   1257   // visible tiles become fully occluded.
   1258   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
   1259   layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 350);
   1260   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 350);
   1261   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1262   layer->SetTexturePriorities(priority_calculator_);
   1263   resource_manager_->PrioritizeTextures();
   1264   layer->SavePaintProperties();
   1265   layer->Update(queue_.get(), &occluded);
   1266   EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
   1267 
   1268   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1269   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1270               210000 + 180000,
   1271               1);
   1272   EXPECT_EQ(3 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1273 
   1274   layer->fake_layer_updater()->ClearUpdateCount();
   1275 
   1276   // Now the visible region is even smaller than the occlusion, it should have
   1277   // the same result.
   1278   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 150));
   1279   layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 340);
   1280   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 340);
   1281   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1282   layer->SetTexturePriorities(priority_calculator_);
   1283   resource_manager_->PrioritizeTextures();
   1284   layer->SavePaintProperties();
   1285   layer->Update(queue_.get(), &occluded);
   1286   EXPECT_EQ(24 - 6, layer->fake_layer_updater()->update_count());
   1287 
   1288   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1289   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1290               210000 + 180000 + 180000,
   1291               1);
   1292   EXPECT_EQ(3 + 6 + 6, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1293 }
   1294 
   1295 TEST_F(TiledLayerTest, TilesNotPaintedWithoutInvalidation) {
   1296   scoped_refptr<FakeTiledLayer> layer =
   1297       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1298   RenderSurfaceLayerList render_surface_layer_list;
   1299   TestOcclusionTracker occluded;
   1300   occlusion_ = &occluded;
   1301 
   1302   layer_tree_host_->root_layer()->AddChild(layer);
   1303 
   1304   // The tile size is 100x100.
   1305 
   1306   layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
   1307   layer->SetBounds(gfx::Size(600, 600));
   1308   CalcDrawProps(&render_surface_layer_list);
   1309 
   1310   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
   1311   layer->draw_properties().drawable_content_rect = gfx::Rect(0, 0, 600, 600);
   1312   layer->draw_properties().visible_content_rect = gfx::Rect(0, 0, 600, 600);
   1313   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1314   layer->SetTexturePriorities(priority_calculator_);
   1315   resource_manager_->PrioritizeTextures();
   1316   layer->SavePaintProperties();
   1317   layer->Update(queue_.get(), &occluded);
   1318   EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
   1319   { UpdateTextures(); }
   1320 
   1321   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1322   EXPECT_NEAR(
   1323       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
   1324   EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1325 
   1326   layer->fake_layer_updater()->ClearUpdateCount();
   1327   layer->SetTexturePriorities(priority_calculator_);
   1328   resource_manager_->PrioritizeTextures();
   1329   layer->SavePaintProperties();
   1330 
   1331   // Repaint without marking it dirty. The 3 culled tiles will be pre-painted
   1332   // now.
   1333   layer->Update(queue_.get(), &occluded);
   1334   EXPECT_EQ(3, layer->fake_layer_updater()->update_count());
   1335 
   1336   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1337   EXPECT_NEAR(
   1338       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
   1339   EXPECT_EQ(6, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1340 }
   1341 
   1342 TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndTransforms) {
   1343   scoped_refptr<FakeTiledLayer> layer =
   1344       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1345   RenderSurfaceLayerList render_surface_layer_list;
   1346   TestOcclusionTracker occluded;
   1347   occlusion_ = &occluded;
   1348 
   1349   layer_tree_host_->root_layer()->AddChild(layer);
   1350 
   1351   // The tile size is 100x100.
   1352 
   1353   // This makes sure the painting works when the occluded region (in screen
   1354   // space) is transformed differently than the layer.
   1355   layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
   1356   layer->SetBounds(gfx::Size(600, 600));
   1357   CalcDrawProps(&render_surface_layer_list);
   1358   gfx::Transform screen_transform;
   1359   screen_transform.Scale(0.5, 0.5);
   1360   layer->draw_properties().screen_space_transform = screen_transform;
   1361   layer->draw_properties().target_space_transform = screen_transform;
   1362 
   1363   occluded.SetOcclusion(gfx::Rect(100, 100, 150, 50));
   1364   layer->draw_properties().drawable_content_rect =
   1365       gfx::Rect(layer->content_bounds());
   1366   layer->draw_properties().visible_content_rect =
   1367       gfx::Rect(layer->content_bounds());
   1368   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1369   layer->SetTexturePriorities(priority_calculator_);
   1370   resource_manager_->PrioritizeTextures();
   1371   layer->SavePaintProperties();
   1372   layer->Update(queue_.get(), &occluded);
   1373   EXPECT_EQ(36 - 3, layer->fake_layer_updater()->update_count());
   1374 
   1375   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1376   EXPECT_NEAR(
   1377       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 330000, 1);
   1378   EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1379 }
   1380 
   1381 TEST_F(TiledLayerTest, TilesPaintedWithOcclusionAndScaling) {
   1382   scoped_refptr<FakeTiledLayer> layer =
   1383       new FakeTiledLayer(resource_manager_.get());
   1384   RenderSurfaceLayerList render_surface_layer_list;
   1385   TestOcclusionTracker occluded;
   1386   occlusion_ = &occluded;
   1387 
   1388   scoped_refptr<FakeTiledLayer> scale_layer =
   1389       new FakeTiledLayer(resource_manager_.get());
   1390   gfx::Transform scale_transform;
   1391   scale_transform.Scale(2.0, 2.0);
   1392   scale_layer->SetTransform(scale_transform);
   1393 
   1394   layer_tree_host_->root_layer()->AddChild(scale_layer);
   1395 
   1396   // The tile size is 100x100.
   1397 
   1398   // This makes sure the painting works when the content space is scaled to
   1399   // a different layer space.
   1400   layer_tree_host_->SetViewportSize(gfx::Size(600, 600));
   1401   layer->SetAnchorPoint(gfx::PointF());
   1402   layer->SetBounds(gfx::Size(300, 300));
   1403   scale_layer->AddChild(layer);
   1404   CalcDrawProps(&render_surface_layer_list);
   1405   EXPECT_FLOAT_EQ(2.f, layer->contents_scale_x());
   1406   EXPECT_FLOAT_EQ(2.f, layer->contents_scale_y());
   1407   EXPECT_EQ(gfx::Size(600, 600).ToString(),
   1408             layer->content_bounds().ToString());
   1409 
   1410   // No tiles are covered by the 300x50 occlusion.
   1411   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 50));
   1412   layer->draw_properties().drawable_content_rect =
   1413       gfx::Rect(layer->bounds());
   1414   layer->draw_properties().visible_content_rect =
   1415       gfx::Rect(layer->content_bounds());
   1416   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1417   layer->SetTexturePriorities(priority_calculator_);
   1418   resource_manager_->PrioritizeTextures();
   1419   layer->SavePaintProperties();
   1420   layer->Update(queue_.get(), &occluded);
   1421   int visible_tiles1 = 6 * 6;
   1422   EXPECT_EQ(visible_tiles1, layer->fake_layer_updater()->update_count());
   1423 
   1424   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1425   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1426               visible_tiles1 * 100 * 100,
   1427               1);
   1428   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1429 
   1430   layer->fake_layer_updater()->ClearUpdateCount();
   1431 
   1432   // The occlusion of 300x100 will be cover 3 tiles as tiles are 100x100 still.
   1433   occluded.SetOcclusion(gfx::Rect(200, 200, 300, 100));
   1434   layer->draw_properties().drawable_content_rect =
   1435       gfx::Rect(layer->bounds());
   1436   layer->draw_properties().visible_content_rect =
   1437       gfx::Rect(layer->content_bounds());
   1438   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1439   layer->SetTexturePriorities(priority_calculator_);
   1440   resource_manager_->PrioritizeTextures();
   1441   layer->SavePaintProperties();
   1442   layer->Update(queue_.get(), &occluded);
   1443   int visible_tiles2 = 6 * 6 - 3;
   1444   EXPECT_EQ(visible_tiles2, layer->fake_layer_updater()->update_count());
   1445 
   1446   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1447   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1448               visible_tiles2 * 100 * 100 +
   1449               visible_tiles1 * 100 * 100,
   1450               1);
   1451   EXPECT_EQ(3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1452 
   1453   layer->fake_layer_updater()->ClearUpdateCount();
   1454 
   1455   // This makes sure content scaling and transforms work together.
   1456   // When the tiles are scaled down by half, they are 50x50 each in the
   1457   // screen.
   1458   gfx::Transform screen_transform;
   1459   screen_transform.Scale(0.5, 0.5);
   1460   layer->draw_properties().screen_space_transform = screen_transform;
   1461   layer->draw_properties().target_space_transform = screen_transform;
   1462 
   1463   // An occlusion of 150x100 will cover 3*2 = 6 tiles.
   1464   occluded.SetOcclusion(gfx::Rect(100, 100, 150, 100));
   1465 
   1466   gfx::Rect layer_bounds_rect(layer->bounds());
   1467   layer->draw_properties().drawable_content_rect =
   1468       gfx::ScaleToEnclosingRect(layer_bounds_rect, 0.5f);
   1469   layer->draw_properties().visible_content_rect =
   1470       gfx::Rect(layer->content_bounds());
   1471   layer->InvalidateContentRect(gfx::Rect(0, 0, 600, 600));
   1472   layer->SetTexturePriorities(priority_calculator_);
   1473   resource_manager_->PrioritizeTextures();
   1474   layer->SavePaintProperties();
   1475   layer->Update(queue_.get(), &occluded);
   1476   int visible_tiles3 = 6 * 6 - 6;
   1477   EXPECT_EQ(visible_tiles3, layer->fake_layer_updater()->update_count());
   1478 
   1479   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1480   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1481               visible_tiles3 * 100 * 100 +
   1482               visible_tiles2 * 100 * 100 +
   1483               visible_tiles1 * 100 * 100,
   1484               1);
   1485   EXPECT_EQ(6 + 3, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1486 }
   1487 
   1488 TEST_F(TiledLayerTest, VisibleContentOpaqueRegion) {
   1489   scoped_refptr<FakeTiledLayer> layer =
   1490       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1491   RenderSurfaceLayerList render_surface_layer_list;
   1492   TestOcclusionTracker occluded;
   1493   occlusion_ = &occluded;
   1494   layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
   1495 
   1496   layer_tree_host_->root_layer()->AddChild(layer);
   1497 
   1498   // The tile size is 100x100, so this invalidates and then paints two tiles in
   1499   // various ways.
   1500 
   1501   gfx::Rect opaque_paint_rect;
   1502   Region opaque_contents;
   1503 
   1504   gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 200);
   1505   gfx::Rect visible_bounds = gfx::Rect(0, 0, 100, 150);
   1506 
   1507   layer->SetBounds(content_bounds.size());
   1508   CalcDrawProps(&render_surface_layer_list);
   1509   layer->draw_properties().drawable_content_rect = visible_bounds;
   1510   layer->draw_properties().visible_content_rect = visible_bounds;
   1511 
   1512   // If the layer doesn't paint opaque content, then the
   1513   // VisibleContentOpaqueRegion should be empty.
   1514   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1515   layer->InvalidateContentRect(content_bounds);
   1516   layer->SetTexturePriorities(priority_calculator_);
   1517   resource_manager_->PrioritizeTextures();
   1518   layer->SavePaintProperties();
   1519   layer->Update(queue_.get(), &occluded);
   1520   opaque_contents = layer->VisibleContentOpaqueRegion();
   1521   EXPECT_TRUE(opaque_contents.IsEmpty());
   1522 
   1523   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000, 1);
   1524   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1525   EXPECT_NEAR(
   1526       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 20000, 1);
   1527   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1528 
   1529   // VisibleContentOpaqueRegion should match the visible part of what is painted
   1530   // opaque.
   1531   opaque_paint_rect = gfx::Rect(10, 10, 90, 190);
   1532   layer->fake_layer_updater()->SetOpaquePaintRect(opaque_paint_rect);
   1533   layer->InvalidateContentRect(content_bounds);
   1534   layer->SetTexturePriorities(priority_calculator_);
   1535   resource_manager_->PrioritizeTextures();
   1536   layer->SavePaintProperties();
   1537   layer->Update(queue_.get(), &occluded);
   1538   UpdateTextures();
   1539   opaque_contents = layer->VisibleContentOpaqueRegion();
   1540   EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
   1541             opaque_contents.ToString());
   1542 
   1543   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
   1544   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
   1545   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1546               20000 + 20000 - 17100,
   1547               1);
   1548   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1549 
   1550   // If we paint again without invalidating, the same stuff should be opaque.
   1551   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1552   layer->SetTexturePriorities(priority_calculator_);
   1553   resource_manager_->PrioritizeTextures();
   1554   layer->SavePaintProperties();
   1555   layer->Update(queue_.get(), &occluded);
   1556   UpdateTextures();
   1557   opaque_contents = layer->VisibleContentOpaqueRegion();
   1558   EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
   1559             opaque_contents.ToString());
   1560 
   1561   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2, 1);
   1562   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
   1563   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1564               20000 + 20000 - 17100,
   1565               1);
   1566   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1567 
   1568   // If we repaint a non-opaque part of the tile, then it shouldn't lose its
   1569   // opaque-ness. And other tiles should not be affected.
   1570   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1571   layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
   1572   layer->SetTexturePriorities(priority_calculator_);
   1573   resource_manager_->PrioritizeTextures();
   1574   layer->SavePaintProperties();
   1575   layer->Update(queue_.get(), &occluded);
   1576   UpdateTextures();
   1577   opaque_contents = layer->VisibleContentOpaqueRegion();
   1578   EXPECT_EQ(gfx::IntersectRects(opaque_paint_rect, visible_bounds).ToString(),
   1579             opaque_contents.ToString());
   1580 
   1581   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1, 1);
   1582   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
   1583   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1584               20000 + 20000 - 17100 + 1,
   1585               1);
   1586   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1587 
   1588   // If we repaint an opaque part of the tile, then it should lose its
   1589   // opaque-ness. But other tiles should still not be affected.
   1590   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1591   layer->InvalidateContentRect(gfx::Rect(10, 10, 1, 1));
   1592   layer->SetTexturePriorities(priority_calculator_);
   1593   resource_manager_->PrioritizeTextures();
   1594   layer->SavePaintProperties();
   1595   layer->Update(queue_.get(), &occluded);
   1596   UpdateTextures();
   1597   opaque_contents = layer->VisibleContentOpaqueRegion();
   1598   EXPECT_EQ(gfx::IntersectRects(gfx::Rect(10, 100, 90, 100),
   1599                                 visible_bounds).ToString(),
   1600             opaque_contents.ToString());
   1601 
   1602   EXPECT_NEAR(
   1603       occluded.overdraw_metrics()->pixels_painted(), 20000 * 2 + 1 + 1, 1);
   1604   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 17100, 1);
   1605   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1606               20000 + 20000 - 17100 + 1 + 1,
   1607               1);
   1608   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1609 }
   1610 
   1611 TEST_F(TiledLayerTest, PixelsPaintedMetrics) {
   1612   scoped_refptr<FakeTiledLayer> layer =
   1613       make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
   1614   RenderSurfaceLayerList render_surface_layer_list;
   1615   TestOcclusionTracker occluded;
   1616   occlusion_ = &occluded;
   1617   layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
   1618 
   1619   layer_tree_host_->root_layer()->AddChild(layer);
   1620 
   1621   // The tile size is 100x100, so this invalidates and then paints two tiles in
   1622   // various ways.
   1623 
   1624   gfx::Rect opaque_paint_rect;
   1625   Region opaque_contents;
   1626 
   1627   gfx::Rect content_bounds = gfx::Rect(0, 0, 100, 300);
   1628   layer->SetBounds(content_bounds.size());
   1629   CalcDrawProps(&render_surface_layer_list);
   1630 
   1631   // Invalidates and paints the whole layer.
   1632   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1633   layer->InvalidateContentRect(content_bounds);
   1634   layer->SetTexturePriorities(priority_calculator_);
   1635   resource_manager_->PrioritizeTextures();
   1636   layer->SavePaintProperties();
   1637   layer->Update(queue_.get(), &occluded);
   1638   UpdateTextures();
   1639   opaque_contents = layer->VisibleContentOpaqueRegion();
   1640   EXPECT_TRUE(opaque_contents.IsEmpty());
   1641 
   1642   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_painted(), 30000, 1);
   1643   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1644   EXPECT_NEAR(
   1645       occluded.overdraw_metrics()->pixels_uploaded_translucent(), 30000, 1);
   1646   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1647 
   1648   // Invalidates an area on the top and bottom tile, which will cause us to
   1649   // paint the tile in the middle, even though it is not dirty and will not be
   1650   // uploaded.
   1651   layer->fake_layer_updater()->SetOpaquePaintRect(gfx::Rect());
   1652   layer->InvalidateContentRect(gfx::Rect(0, 0, 1, 1));
   1653   layer->InvalidateContentRect(gfx::Rect(50, 200, 10, 10));
   1654   layer->SetTexturePriorities(priority_calculator_);
   1655   resource_manager_->PrioritizeTextures();
   1656   layer->SavePaintProperties();
   1657   layer->Update(queue_.get(), &occluded);
   1658   UpdateTextures();
   1659   opaque_contents = layer->VisibleContentOpaqueRegion();
   1660   EXPECT_TRUE(opaque_contents.IsEmpty());
   1661 
   1662   // The middle tile was painted even though not invalidated.
   1663   EXPECT_NEAR(
   1664       occluded.overdraw_metrics()->pixels_painted(), 30000 + 60 * 210, 1);
   1665   // The pixels uploaded will not include the non-invalidated tile in the
   1666   // middle.
   1667   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_opaque(), 0, 1);
   1668   EXPECT_NEAR(occluded.overdraw_metrics()->pixels_uploaded_translucent(),
   1669               30000 + 1 + 100,
   1670               1);
   1671   EXPECT_EQ(0, occluded.overdraw_metrics()->tiles_culled_for_upload());
   1672 }
   1673 
   1674 TEST_F(TiledLayerTest, DontAllocateContentsWhenTargetSurfaceCantBeAllocated) {
   1675   // Tile size is 100x100.
   1676   gfx::Rect root_rect(0, 0, 300, 200);
   1677   gfx::Rect child_rect(0, 0, 300, 100);
   1678   gfx::Rect child2_rect(0, 100, 300, 100);
   1679 
   1680   scoped_refptr<FakeTiledLayer> root = make_scoped_refptr(
   1681       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
   1682   scoped_refptr<Layer> surface = Layer::Create();
   1683   scoped_refptr<FakeTiledLayer> child = make_scoped_refptr(
   1684       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
   1685   scoped_refptr<FakeTiledLayer> child2 = make_scoped_refptr(
   1686       new FakeTiledLayer(layer_tree_host_->contents_texture_manager()));
   1687 
   1688   root->SetBounds(root_rect.size());
   1689   root->SetAnchorPoint(gfx::PointF());
   1690   root->draw_properties().drawable_content_rect = root_rect;
   1691   root->draw_properties().visible_content_rect = root_rect;
   1692   root->AddChild(surface);
   1693 
   1694   surface->SetForceRenderSurface(true);
   1695   surface->SetAnchorPoint(gfx::PointF());
   1696   surface->SetOpacity(0.5);
   1697   surface->AddChild(child);
   1698   surface->AddChild(child2);
   1699 
   1700   child->SetBounds(child_rect.size());
   1701   child->SetAnchorPoint(gfx::PointF());
   1702   child->SetPosition(child_rect.origin());
   1703   child->draw_properties().visible_content_rect = child_rect;
   1704   child->draw_properties().drawable_content_rect = root_rect;
   1705 
   1706   child2->SetBounds(child2_rect.size());
   1707   child2->SetAnchorPoint(gfx::PointF());
   1708   child2->SetPosition(child2_rect.origin());
   1709   child2->draw_properties().visible_content_rect = child2_rect;
   1710   child2->draw_properties().drawable_content_rect = root_rect;
   1711 
   1712   layer_tree_host_->SetRootLayer(root);
   1713   layer_tree_host_->SetViewportSize(root_rect.size());
   1714 
   1715   // With a huge memory limit, all layers should update and push their textures.
   1716   root->InvalidateContentRect(root_rect);
   1717   child->InvalidateContentRect(child_rect);
   1718   child2->InvalidateContentRect(child2_rect);
   1719   layer_tree_host_->UpdateLayers(queue_.get());
   1720   {
   1721     UpdateTextures();
   1722     EXPECT_EQ(6, root->fake_layer_updater()->update_count());
   1723     EXPECT_EQ(3, child->fake_layer_updater()->update_count());
   1724     EXPECT_EQ(3, child2->fake_layer_updater()->update_count());
   1725     EXPECT_FALSE(queue_->HasMoreUpdates());
   1726 
   1727     root->fake_layer_updater()->ClearUpdateCount();
   1728     child->fake_layer_updater()->ClearUpdateCount();
   1729     child2->fake_layer_updater()->ClearUpdateCount();
   1730 
   1731     scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
   1732         new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
   1733     scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
   1734         new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
   1735     scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
   1736         new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
   1737     LayerPushPropertiesTo(child2.get(), child2_impl.get());
   1738     LayerPushPropertiesTo(child.get(), child_impl.get());
   1739     LayerPushPropertiesTo(root.get(), root_impl.get());
   1740 
   1741     for (unsigned i = 0; i < 3; ++i) {
   1742       for (unsigned j = 0; j < 2; ++j)
   1743         EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
   1744       EXPECT_TRUE(child_impl->HasResourceIdForTileAt(i, 0));
   1745       EXPECT_TRUE(child2_impl->HasResourceIdForTileAt(i, 0));
   1746     }
   1747   }
   1748   layer_tree_host_->CommitComplete();
   1749 
   1750   // With a memory limit that includes only the root layer (3x2 tiles) and half
   1751   // the surface that the child layers draw into, the child layers will not be
   1752   // allocated. If the surface isn't accounted for, then one of the children
   1753   // would fit within the memory limit.
   1754   root->InvalidateContentRect(root_rect);
   1755   child->InvalidateContentRect(child_rect);
   1756   child2->InvalidateContentRect(child2_rect);
   1757 
   1758   size_t memory_limit = (3 * 2 + 3 * 1) * (100 * 100) * 4;
   1759   layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
   1760       memory_limit);
   1761   layer_tree_host_->UpdateLayers(queue_.get());
   1762   {
   1763     UpdateTextures();
   1764     EXPECT_EQ(6, root->fake_layer_updater()->update_count());
   1765     EXPECT_EQ(0, child->fake_layer_updater()->update_count());
   1766     EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
   1767     EXPECT_FALSE(queue_->HasMoreUpdates());
   1768 
   1769     root->fake_layer_updater()->ClearUpdateCount();
   1770     child->fake_layer_updater()->ClearUpdateCount();
   1771     child2->fake_layer_updater()->ClearUpdateCount();
   1772 
   1773     scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
   1774         new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
   1775     scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
   1776         new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
   1777     scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
   1778         new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
   1779     LayerPushPropertiesTo(child2.get(), child2_impl.get());
   1780     LayerPushPropertiesTo(child.get(), child_impl.get());
   1781     LayerPushPropertiesTo(root.get(), root_impl.get());
   1782 
   1783     for (unsigned i = 0; i < 3; ++i) {
   1784       for (unsigned j = 0; j < 2; ++j)
   1785         EXPECT_TRUE(root_impl->HasResourceIdForTileAt(i, j));
   1786       EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
   1787       EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
   1788     }
   1789   }
   1790   layer_tree_host_->CommitComplete();
   1791 
   1792   // With a memory limit that includes only half the root layer, no contents
   1793   // will be allocated. If render surface memory wasn't accounted for, there is
   1794   // enough space for one of the children layers, but they draw into a surface
   1795   // that can't be allocated.
   1796   root->InvalidateContentRect(root_rect);
   1797   child->InvalidateContentRect(child_rect);
   1798   child2->InvalidateContentRect(child2_rect);
   1799 
   1800   memory_limit = (3 * 1) * (100 * 100) * 4;
   1801   layer_tree_host_->contents_texture_manager()->SetMaxMemoryLimitBytes(
   1802       memory_limit);
   1803   layer_tree_host_->UpdateLayers(queue_.get());
   1804   {
   1805     UpdateTextures();
   1806     EXPECT_EQ(0, root->fake_layer_updater()->update_count());
   1807     EXPECT_EQ(0, child->fake_layer_updater()->update_count());
   1808     EXPECT_EQ(0, child2->fake_layer_updater()->update_count());
   1809     EXPECT_FALSE(queue_->HasMoreUpdates());
   1810 
   1811     root->fake_layer_updater()->ClearUpdateCount();
   1812     child->fake_layer_updater()->ClearUpdateCount();
   1813     child2->fake_layer_updater()->ClearUpdateCount();
   1814 
   1815     scoped_ptr<FakeTiledLayerImpl> root_impl = make_scoped_ptr(
   1816         new FakeTiledLayerImpl(host_impl_->active_tree(), root->id()));
   1817     scoped_ptr<FakeTiledLayerImpl> child_impl = make_scoped_ptr(
   1818         new FakeTiledLayerImpl(host_impl_->active_tree(), child->id()));
   1819     scoped_ptr<FakeTiledLayerImpl> child2_impl = make_scoped_ptr(
   1820         new FakeTiledLayerImpl(host_impl_->active_tree(), child2->id()));
   1821     LayerPushPropertiesTo(child2.get(), child2_impl.get());
   1822     LayerPushPropertiesTo(child.get(), child_impl.get());
   1823     LayerPushPropertiesTo(root.get(), root_impl.get());
   1824 
   1825     for (unsigned i = 0; i < 3; ++i) {
   1826       for (unsigned j = 0; j < 2; ++j)
   1827         EXPECT_FALSE(root_impl->HasResourceIdForTileAt(i, j));
   1828       EXPECT_FALSE(child_impl->HasResourceIdForTileAt(i, 0));
   1829       EXPECT_FALSE(child2_impl->HasResourceIdForTileAt(i, 0));
   1830     }
   1831   }
   1832   layer_tree_host_->CommitComplete();
   1833 
   1834   ResourceManagerClearAllMemory(layer_tree_host_->contents_texture_manager(),
   1835                                 resource_provider_.get());
   1836   layer_tree_host_->SetRootLayer(NULL);
   1837 }
   1838 
   1839 class TrackingLayerPainter : public LayerPainter {
   1840  public:
   1841   static scoped_ptr<TrackingLayerPainter> Create() {
   1842     return make_scoped_ptr(new TrackingLayerPainter());
   1843   }
   1844 
   1845   virtual void Paint(SkCanvas* canvas,
   1846                      gfx::Rect content_rect,
   1847                      gfx::RectF* opaque) OVERRIDE {
   1848     painted_rect_ = content_rect;
   1849   }
   1850 
   1851   gfx::Rect PaintedRect() const { return painted_rect_; }
   1852   void ResetPaintedRect() { painted_rect_ = gfx::Rect(); }
   1853 
   1854  private:
   1855   gfx::Rect painted_rect_;
   1856 };
   1857 
   1858 class UpdateTrackingTiledLayer : public FakeTiledLayer {
   1859  public:
   1860   explicit UpdateTrackingTiledLayer(PrioritizedResourceManager* manager)
   1861       : FakeTiledLayer(manager) {
   1862     scoped_ptr<TrackingLayerPainter> painter(TrackingLayerPainter::Create());
   1863     tracking_layer_painter_ = painter.get();
   1864     layer_updater_ =
   1865         BitmapContentLayerUpdater::Create(painter.PassAs<LayerPainter>(),
   1866                                           &stats_instrumentation_,
   1867                                           0);
   1868   }
   1869 
   1870   TrackingLayerPainter* tracking_layer_painter() const {
   1871     return tracking_layer_painter_;
   1872   }
   1873 
   1874  private:
   1875   virtual LayerUpdater* Updater() const OVERRIDE {
   1876     return layer_updater_.get();
   1877   }
   1878   virtual ~UpdateTrackingTiledLayer() {}
   1879 
   1880   TrackingLayerPainter* tracking_layer_painter_;
   1881   scoped_refptr<BitmapContentLayerUpdater> layer_updater_;
   1882   FakeRenderingStatsInstrumentation stats_instrumentation_;
   1883 };
   1884 
   1885 TEST_F(TiledLayerTest, NonIntegerContentsScaleIsNotDistortedDuringPaint) {
   1886   scoped_refptr<UpdateTrackingTiledLayer> layer =
   1887       make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
   1888 
   1889   layer_tree_host_->root_layer()->AddChild(layer);
   1890 
   1891   gfx::Rect layer_rect(0, 0, 30, 31);
   1892   layer->SetPosition(layer_rect.origin());
   1893   layer->SetBounds(layer_rect.size());
   1894   layer->UpdateContentsScale(1.5f);
   1895 
   1896   gfx::Rect content_rect(0, 0, 45, 47);
   1897   EXPECT_EQ(content_rect.size(), layer->content_bounds());
   1898   layer->draw_properties().visible_content_rect = content_rect;
   1899   layer->draw_properties().drawable_content_rect = content_rect;
   1900 
   1901   layer->SetTexturePriorities(priority_calculator_);
   1902   resource_manager_->PrioritizeTextures();
   1903   layer->SavePaintProperties();
   1904 
   1905   // Update the whole tile.
   1906   layer->Update(queue_.get(), NULL);
   1907   layer->tracking_layer_painter()->ResetPaintedRect();
   1908 
   1909   EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
   1910   UpdateTextures();
   1911 
   1912   // Invalidate the entire layer in content space. When painting, the rect given
   1913   // to webkit should match the layer's bounds.
   1914   layer->InvalidateContentRect(content_rect);
   1915   layer->Update(queue_.get(), NULL);
   1916 
   1917   EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
   1918 }
   1919 
   1920 TEST_F(TiledLayerTest,
   1921        NonIntegerContentsScaleIsNotDistortedDuringInvalidation) {
   1922   scoped_refptr<UpdateTrackingTiledLayer> layer =
   1923       make_scoped_refptr(new UpdateTrackingTiledLayer(resource_manager_.get()));
   1924 
   1925   layer_tree_host_->root_layer()->AddChild(layer);
   1926 
   1927   gfx::Rect layer_rect(0, 0, 30, 31);
   1928   layer->SetPosition(layer_rect.origin());
   1929   layer->SetBounds(layer_rect.size());
   1930   layer->UpdateContentsScale(1.3f);
   1931 
   1932   gfx::Rect content_rect(layer->content_bounds());
   1933   layer->draw_properties().visible_content_rect = content_rect;
   1934   layer->draw_properties().drawable_content_rect = content_rect;
   1935 
   1936   layer->SetTexturePriorities(priority_calculator_);
   1937   resource_manager_->PrioritizeTextures();
   1938   layer->SavePaintProperties();
   1939 
   1940   // Update the whole tile.
   1941   layer->Update(queue_.get(), NULL);
   1942   layer->tracking_layer_painter()->ResetPaintedRect();
   1943 
   1944   EXPECT_RECT_EQ(gfx::Rect(), layer->tracking_layer_painter()->PaintedRect());
   1945   UpdateTextures();
   1946 
   1947   // Invalidate the entire layer in layer space. When painting, the rect given
   1948   // to webkit should match the layer's bounds.
   1949   layer->SetNeedsDisplayRect(layer_rect);
   1950   layer->Update(queue_.get(), NULL);
   1951 
   1952   EXPECT_RECT_EQ(layer_rect, layer->tracking_layer_painter()->PaintedRect());
   1953 }
   1954 
   1955 }  // namespace
   1956 }  // namespace cc
   1957