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