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