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/trees/layer_tree_host_impl.h" 6 7 #include <cmath> 8 9 #include "base/bind.h" 10 #include "base/command_line.h" 11 #include "base/containers/hash_tables.h" 12 #include "base/containers/scoped_ptr_hash_map.h" 13 #include "cc/animation/scrollbar_animation_controller_thinning.h" 14 #include "cc/base/latency_info_swap_promise.h" 15 #include "cc/base/math_util.h" 16 #include "cc/input/top_controls_manager.h" 17 #include "cc/layers/delegated_renderer_layer_impl.h" 18 #include "cc/layers/heads_up_display_layer_impl.h" 19 #include "cc/layers/io_surface_layer_impl.h" 20 #include "cc/layers/layer_impl.h" 21 #include "cc/layers/painted_scrollbar_layer_impl.h" 22 #include "cc/layers/quad_sink.h" 23 #include "cc/layers/render_surface_impl.h" 24 #include "cc/layers/solid_color_layer_impl.h" 25 #include "cc/layers/texture_layer_impl.h" 26 #include "cc/layers/tiled_layer_impl.h" 27 #include "cc/layers/video_layer_impl.h" 28 #include "cc/output/begin_frame_args.h" 29 #include "cc/output/compositor_frame_ack.h" 30 #include "cc/output/compositor_frame_metadata.h" 31 #include "cc/output/copy_output_request.h" 32 #include "cc/output/copy_output_result.h" 33 #include "cc/output/gl_renderer.h" 34 #include "cc/quads/render_pass_draw_quad.h" 35 #include "cc/quads/solid_color_draw_quad.h" 36 #include "cc/quads/texture_draw_quad.h" 37 #include "cc/quads/tile_draw_quad.h" 38 #include "cc/resources/etc1_pixel_ref.h" 39 #include "cc/resources/layer_tiling_data.h" 40 #include "cc/test/animation_test_common.h" 41 #include "cc/test/fake_layer_tree_host_impl.h" 42 #include "cc/test/fake_output_surface.h" 43 #include "cc/test/fake_output_surface_client.h" 44 #include "cc/test/fake_picture_layer_impl.h" 45 #include "cc/test/fake_picture_pile_impl.h" 46 #include "cc/test/fake_proxy.h" 47 #include "cc/test/fake_rendering_stats_instrumentation.h" 48 #include "cc/test/fake_video_frame_provider.h" 49 #include "cc/test/geometry_test_utils.h" 50 #include "cc/test/layer_test_common.h" 51 #include "cc/test/render_pass_test_common.h" 52 #include "cc/test/test_web_graphics_context_3d.h" 53 #include "cc/trees/layer_tree_impl.h" 54 #include "cc/trees/single_thread_proxy.h" 55 #include "media/base/media.h" 56 #include "testing/gmock/include/gmock/gmock.h" 57 #include "testing/gtest/include/gtest/gtest.h" 58 #include "ui/gfx/frame_time.h" 59 #include "ui/gfx/rect_conversions.h" 60 #include "ui/gfx/size_conversions.h" 61 #include "ui/gfx/vector2d_conversions.h" 62 63 using ::testing::Mock; 64 using ::testing::Return; 65 using ::testing::AnyNumber; 66 using ::testing::AtLeast; 67 using ::testing::_; 68 using media::VideoFrame; 69 70 namespace cc { 71 namespace { 72 73 class LayerTreeHostImplTest : public testing::Test, 74 public LayerTreeHostImplClient { 75 public: 76 LayerTreeHostImplTest() 77 : proxy_(), 78 always_impl_thread_(&proxy_), 79 always_main_thread_blocked_(&proxy_), 80 on_can_draw_state_changed_called_(false), 81 did_notify_ready_to_activate_(false), 82 did_request_commit_(false), 83 did_request_redraw_(false), 84 did_request_manage_tiles_(false), 85 did_upload_visible_tile_(false), 86 reduce_memory_result_(true), 87 current_limit_bytes_(0), 88 current_priority_cutoff_value_(0) { 89 media::InitializeMediaLibraryForTesting(); 90 } 91 92 LayerTreeSettings DefaultSettings() { 93 LayerTreeSettings settings; 94 settings.minimum_occlusion_tracking_size = gfx::Size(); 95 settings.impl_side_painting = true; 96 settings.texture_id_allocation_chunk_size = 1; 97 return settings; 98 } 99 100 virtual void SetUp() OVERRIDE { 101 CreateHostImpl(DefaultSettings(), CreateOutputSurface()); 102 } 103 104 virtual void TearDown() OVERRIDE {} 105 106 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {} 107 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} 108 virtual void DidSwapBuffersOnImplThread() OVERRIDE {} 109 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE {} 110 virtual void BeginImplFrame(const BeginFrameArgs& args) OVERRIDE {} 111 virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE { 112 on_can_draw_state_changed_called_ = true; 113 } 114 virtual void NotifyReadyToActivate() OVERRIDE { 115 did_notify_ready_to_activate_ = true; 116 host_impl_->ActivatePendingTree(); 117 } 118 virtual void SetNeedsRedrawOnImplThread() OVERRIDE { 119 did_request_redraw_ = true; 120 } 121 virtual void SetNeedsRedrawRectOnImplThread(gfx::Rect damage_rect) OVERRIDE { 122 did_request_redraw_ = true; 123 } 124 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE { 125 did_request_manage_tiles_ = true; 126 } 127 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE { 128 did_upload_visible_tile_ = true; 129 } 130 virtual void SetNeedsCommitOnImplThread() OVERRIDE { 131 did_request_commit_ = true; 132 } 133 virtual void PostAnimationEventsToMainThreadOnImplThread( 134 scoped_ptr<AnimationEventsVector> events, 135 base::Time wall_clock_time) OVERRIDE {} 136 virtual bool ReduceContentsTextureMemoryOnImplThread( 137 size_t limit_bytes, int priority_cutoff) OVERRIDE { 138 current_limit_bytes_ = limit_bytes; 139 current_priority_cutoff_value_ = priority_cutoff; 140 return reduce_memory_result_; 141 } 142 virtual void SendManagedMemoryStats() OVERRIDE {} 143 virtual bool IsInsideDraw() OVERRIDE { return false; } 144 virtual void RenewTreePriority() OVERRIDE {} 145 virtual void RequestScrollbarAnimationOnImplThread(base::TimeDelta delay) 146 OVERRIDE { requested_scrollbar_animation_delay_ = delay; } 147 virtual void DidActivatePendingTree() OVERRIDE {} 148 virtual void DidManageTiles() OVERRIDE {} 149 150 void set_reduce_memory_result(bool reduce_memory_result) { 151 reduce_memory_result_ = reduce_memory_result; 152 } 153 154 bool CreateHostImpl(const LayerTreeSettings& settings, 155 scoped_ptr<OutputSurface> output_surface) { 156 host_impl_ = LayerTreeHostImpl::Create( 157 settings, this, &proxy_, &stats_instrumentation_, NULL, 0); 158 bool init = host_impl_->InitializeRenderer(output_surface.Pass()); 159 host_impl_->SetViewportSize(gfx::Size(10, 10)); 160 return init; 161 } 162 163 void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) { 164 root->SetAnchorPoint(gfx::PointF()); 165 root->SetPosition(gfx::PointF()); 166 root->SetBounds(gfx::Size(10, 10)); 167 root->SetContentBounds(gfx::Size(10, 10)); 168 root->SetDrawsContent(true); 169 root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10); 170 host_impl_->active_tree()->SetRootLayer(root.Pass()); 171 } 172 173 static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) { 174 ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d()); 175 for (size_t i = 0; i < layer->children().size(); ++i) 176 ExpectClearedScrollDeltasRecursive(layer->children()[i]); 177 } 178 179 static void ExpectContains(const ScrollAndScaleSet& scroll_info, 180 int id, 181 gfx::Vector2d scroll_delta) { 182 int times_encountered = 0; 183 184 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { 185 if (scroll_info.scrolls[i].layer_id != id) 186 continue; 187 EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta); 188 times_encountered++; 189 } 190 191 ASSERT_EQ(1, times_encountered); 192 } 193 194 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) { 195 int times_encountered = 0; 196 197 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { 198 if (scroll_info.scrolls[i].layer_id != id) 199 continue; 200 times_encountered++; 201 } 202 203 ASSERT_EQ(0, times_encountered); 204 } 205 206 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl, 207 gfx::Size content_size) { 208 scoped_ptr<LayerImpl> root = 209 LayerImpl::Create(layer_tree_impl, 1); 210 root->SetBounds(content_size); 211 root->SetContentBounds(content_size); 212 root->SetPosition(gfx::PointF()); 213 root->SetAnchorPoint(gfx::PointF()); 214 215 scoped_ptr<LayerImpl> scroll = 216 LayerImpl::Create(layer_tree_impl, 2); 217 LayerImpl* scroll_layer = scroll.get(); 218 scroll->SetScrollable(true); 219 scroll->SetScrollOffset(gfx::Vector2d()); 220 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(), 221 content_size.height())); 222 scroll->SetBounds(content_size); 223 scroll->SetContentBounds(content_size); 224 scroll->SetPosition(gfx::PointF()); 225 scroll->SetAnchorPoint(gfx::PointF()); 226 227 scoped_ptr<LayerImpl> contents = 228 LayerImpl::Create(layer_tree_impl, 3); 229 contents->SetDrawsContent(true); 230 contents->SetBounds(content_size); 231 contents->SetContentBounds(content_size); 232 contents->SetPosition(gfx::PointF()); 233 contents->SetAnchorPoint(gfx::PointF()); 234 235 scroll->AddChild(contents.Pass()); 236 root->AddChild(scroll.Pass()); 237 238 layer_tree_impl->SetRootLayer(root.Pass()); 239 return scroll_layer; 240 } 241 242 LayerImpl* SetupScrollAndContentsLayers(gfx::Size content_size) { 243 LayerImpl* scroll_layer = CreateScrollAndContentsLayers( 244 host_impl_->active_tree(), content_size); 245 host_impl_->active_tree()->DidBecomeActive(); 246 return scroll_layer; 247 } 248 249 scoped_ptr<LayerImpl> CreateScrollableLayer(int id, gfx::Size size) { 250 scoped_ptr<LayerImpl> layer = 251 LayerImpl::Create(host_impl_->active_tree(), id); 252 layer->SetScrollable(true); 253 layer->SetDrawsContent(true); 254 layer->SetBounds(size); 255 layer->SetContentBounds(size); 256 layer->SetMaxScrollOffset(gfx::Vector2d(size.width() * 2, 257 size.height() * 2)); 258 return layer.Pass(); 259 } 260 261 void DrawFrame() { 262 LayerTreeHostImpl::FrameData frame; 263 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 264 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 265 host_impl_->DidDrawAllLayers(frame); 266 } 267 268 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor); 269 void pinch_zoom_pan_viewport_test(float device_scale_factor); 270 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor); 271 void pinch_zoom_pan_viewport_and_scroll_boundary_test( 272 float device_scale_factor); 273 274 void CheckNotifyCalledIfCanDrawChanged(bool always_draw) { 275 // Note: It is not possible to disable the renderer once it has been set, 276 // so we do not need to test that disabling the renderer notifies us 277 // that can_draw changed. 278 EXPECT_FALSE(host_impl_->CanDraw()); 279 on_can_draw_state_changed_called_ = false; 280 281 // Set up the root layer, which allows us to draw. 282 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 283 EXPECT_TRUE(host_impl_->CanDraw()); 284 EXPECT_TRUE(on_can_draw_state_changed_called_); 285 on_can_draw_state_changed_called_ = false; 286 287 // Toggle the root layer to make sure it toggles can_draw 288 host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>()); 289 EXPECT_FALSE(host_impl_->CanDraw()); 290 EXPECT_TRUE(on_can_draw_state_changed_called_); 291 on_can_draw_state_changed_called_ = false; 292 293 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 294 EXPECT_TRUE(host_impl_->CanDraw()); 295 EXPECT_TRUE(on_can_draw_state_changed_called_); 296 on_can_draw_state_changed_called_ = false; 297 298 // Toggle the device viewport size to make sure it toggles can_draw. 299 host_impl_->SetViewportSize(gfx::Size()); 300 if (always_draw) { 301 EXPECT_TRUE(host_impl_->CanDraw()); 302 } else { 303 EXPECT_FALSE(host_impl_->CanDraw()); 304 } 305 EXPECT_TRUE(on_can_draw_state_changed_called_); 306 on_can_draw_state_changed_called_ = false; 307 308 host_impl_->SetViewportSize(gfx::Size(100, 100)); 309 EXPECT_TRUE(host_impl_->CanDraw()); 310 EXPECT_TRUE(on_can_draw_state_changed_called_); 311 on_can_draw_state_changed_called_ = false; 312 313 // Toggle contents textures purged without causing any evictions, 314 // and make sure that it does not change can_draw. 315 set_reduce_memory_result(false); 316 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 317 host_impl_->memory_allocation_limit_bytes() - 1)); 318 EXPECT_TRUE(host_impl_->CanDraw()); 319 EXPECT_FALSE(on_can_draw_state_changed_called_); 320 on_can_draw_state_changed_called_ = false; 321 322 // Toggle contents textures purged to make sure it toggles can_draw. 323 set_reduce_memory_result(true); 324 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 325 host_impl_->memory_allocation_limit_bytes() - 1)); 326 if (always_draw) { 327 EXPECT_TRUE(host_impl_->CanDraw()); 328 } else { 329 EXPECT_FALSE(host_impl_->CanDraw()); 330 } 331 EXPECT_TRUE(on_can_draw_state_changed_called_); 332 on_can_draw_state_changed_called_ = false; 333 334 host_impl_->active_tree()->ResetContentsTexturesPurged(); 335 EXPECT_TRUE(host_impl_->CanDraw()); 336 EXPECT_TRUE(on_can_draw_state_changed_called_); 337 on_can_draw_state_changed_called_ = false; 338 } 339 340 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor); 341 342 protected: 343 virtual scoped_ptr<OutputSurface> CreateOutputSurface() { 344 return CreateFakeOutputSurface(); 345 } 346 347 void DrawOneFrame() { 348 LayerTreeHostImpl::FrameData frame_data; 349 host_impl_->PrepareToDraw(&frame_data, gfx::Rect()); 350 host_impl_->DidDrawAllLayers(frame_data); 351 } 352 353 FakeProxy proxy_; 354 DebugScopedSetImplThread always_impl_thread_; 355 DebugScopedSetMainThreadBlocked always_main_thread_blocked_; 356 357 scoped_ptr<LayerTreeHostImpl> host_impl_; 358 FakeRenderingStatsInstrumentation stats_instrumentation_; 359 bool on_can_draw_state_changed_called_; 360 bool did_notify_ready_to_activate_; 361 bool did_request_commit_; 362 bool did_request_redraw_; 363 bool did_request_manage_tiles_; 364 bool did_upload_visible_tile_; 365 bool reduce_memory_result_; 366 base::TimeDelta requested_scrollbar_animation_delay_; 367 size_t current_limit_bytes_; 368 int current_priority_cutoff_value_; 369 }; 370 371 TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { 372 bool always_draw = false; 373 CheckNotifyCalledIfCanDrawChanged(always_draw); 374 } 375 376 TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) { 377 scoped_ptr<FakeOutputSurface> output_surface( 378 FakeOutputSurface::CreateAlwaysDrawAndSwap3d()); 379 CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); 380 381 bool always_draw = true; 382 CheckNotifyCalledIfCanDrawChanged(always_draw); 383 } 384 385 TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { 386 ASSERT_FALSE(host_impl_->active_tree()->root_layer()); 387 388 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 389 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 390 } 391 392 TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { 393 { 394 scoped_ptr<LayerImpl> root = 395 LayerImpl::Create(host_impl_->active_tree(), 1); 396 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2)); 397 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3)); 398 root->children()[1]->AddChild( 399 LayerImpl::Create(host_impl_->active_tree(), 4)); 400 root->children()[1]->AddChild( 401 LayerImpl::Create(host_impl_->active_tree(), 5)); 402 root->children()[1]->children()[0]->AddChild( 403 LayerImpl::Create(host_impl_->active_tree(), 6)); 404 host_impl_->active_tree()->SetRootLayer(root.Pass()); 405 } 406 LayerImpl* root = host_impl_->active_tree()->root_layer(); 407 408 ExpectClearedScrollDeltasRecursive(root); 409 410 scoped_ptr<ScrollAndScaleSet> scroll_info; 411 412 scroll_info = host_impl_->ProcessScrollDeltas(); 413 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 414 ExpectClearedScrollDeltasRecursive(root); 415 416 scroll_info = host_impl_->ProcessScrollDeltas(); 417 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 418 ExpectClearedScrollDeltasRecursive(root); 419 } 420 421 TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { 422 gfx::Vector2d scroll_offset(20, 30); 423 gfx::Vector2d scroll_delta(11, -15); 424 { 425 scoped_ptr<LayerImpl> root = 426 LayerImpl::Create(host_impl_->active_tree(), 1); 427 root->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 428 root->SetScrollOffset(scroll_offset); 429 root->SetScrollable(true); 430 root->ScrollBy(scroll_delta); 431 host_impl_->active_tree()->SetRootLayer(root.Pass()); 432 } 433 LayerImpl* root = host_impl_->active_tree()->root_layer(); 434 435 scoped_ptr<ScrollAndScaleSet> scroll_info; 436 437 scroll_info = host_impl_->ProcessScrollDeltas(); 438 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 439 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta); 440 ExpectContains(*scroll_info, root->id(), scroll_delta); 441 442 gfx::Vector2d scroll_delta2(-5, 27); 443 root->ScrollBy(scroll_delta2); 444 scroll_info = host_impl_->ProcessScrollDeltas(); 445 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 446 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2); 447 ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2); 448 449 root->ScrollBy(gfx::Vector2d()); 450 scroll_info = host_impl_->ProcessScrollDeltas(); 451 EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2); 452 } 453 454 TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { 455 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 456 host_impl_->SetViewportSize(gfx::Size(50, 50)); 457 DrawFrame(); 458 459 EXPECT_EQ(InputHandler::ScrollStarted, 460 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 461 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 462 host_impl_->ScrollEnd(); 463 EXPECT_TRUE(did_request_redraw_); 464 EXPECT_TRUE(did_request_commit_); 465 } 466 467 TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { 468 // We should not crash when trying to scroll an empty layer tree. 469 EXPECT_EQ(InputHandler::ScrollIgnored, 470 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 471 } 472 473 TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { 474 scoped_ptr<TestWebGraphicsContext3D> context_owned = 475 TestWebGraphicsContext3D::Create(); 476 context_owned->set_context_lost(true); 477 478 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d( 479 context_owned.Pass())); 480 481 // Initialization will fail. 482 EXPECT_FALSE(CreateHostImpl(DefaultSettings(), 483 output_surface.PassAs<OutputSurface>())); 484 485 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 486 487 // We should not crash when trying to scroll after the renderer initialization 488 // fails. 489 EXPECT_EQ(InputHandler::ScrollIgnored, 490 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 491 } 492 493 TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { 494 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 495 host_impl_->SetViewportSize(gfx::Size(50, 50)); 496 DrawFrame(); 497 498 // We should not crash if the tree is replaced while we are scrolling. 499 EXPECT_EQ(InputHandler::ScrollStarted, 500 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 501 host_impl_->active_tree()->DetachLayerTree(); 502 503 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 504 505 // We should still be scrolling, because the scrolled layer also exists in the 506 // new tree. 507 gfx::Vector2d scroll_delta(0, 10); 508 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 509 host_impl_->ScrollEnd(); 510 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 511 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta); 512 } 513 514 TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) { 515 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 516 host_impl_->SetViewportSize(gfx::Size(50, 50)); 517 DrawFrame(); 518 519 // We should be able to scroll even if the root layer loses its render surface 520 // after the most recent render. 521 host_impl_->active_tree()->root_layer()->ClearRenderSurface(); 522 host_impl_->active_tree()->set_needs_update_draw_properties(); 523 524 EXPECT_EQ(InputHandler::ScrollStarted, 525 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 526 } 527 528 TEST_F(LayerTreeHostImplTest, WheelEventHandlers) { 529 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 530 host_impl_->SetViewportSize(gfx::Size(50, 50)); 531 DrawFrame(); 532 LayerImpl* root = host_impl_->active_tree()->root_layer(); 533 534 root->SetHaveWheelEventHandlers(true); 535 536 // With registered event handlers, wheel scrolls have to go to the main 537 // thread. 538 EXPECT_EQ(InputHandler::ScrollOnMainThread, 539 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 540 541 // But gesture scrolls can still be handled. 542 EXPECT_EQ(InputHandler::ScrollStarted, 543 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 544 } 545 546 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { 547 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 548 host_impl_->SetViewportSize(gfx::Size(50, 50)); 549 DrawFrame(); 550 551 // Ignore the fling since no layer is being scrolled 552 EXPECT_EQ(InputHandler::ScrollIgnored, 553 host_impl_->FlingScrollBegin()); 554 555 // Start scrolling a layer 556 EXPECT_EQ(InputHandler::ScrollStarted, 557 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 558 559 // Now the fling should go ahead since we've started scrolling a layer 560 EXPECT_EQ(InputHandler::ScrollStarted, 561 host_impl_->FlingScrollBegin()); 562 } 563 564 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) { 565 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 566 host_impl_->SetViewportSize(gfx::Size(50, 50)); 567 DrawFrame(); 568 569 // Ignore the fling since no layer is being scrolled 570 EXPECT_EQ(InputHandler::ScrollIgnored, 571 host_impl_->FlingScrollBegin()); 572 573 // Start scrolling a layer 574 EXPECT_EQ(InputHandler::ScrollStarted, 575 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 576 577 // Now the fling should go ahead since we've started scrolling a layer 578 EXPECT_EQ(InputHandler::ScrollStarted, 579 host_impl_->FlingScrollBegin()); 580 } 581 582 TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) { 583 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 584 host_impl_->SetViewportSize(gfx::Size(50, 50)); 585 DrawFrame(); 586 LayerImpl* root = host_impl_->active_tree()->root_layer(); 587 588 root->SetShouldScrollOnMainThread(true); 589 590 // Start scrolling a layer 591 EXPECT_EQ(InputHandler::ScrollOnMainThread, 592 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 593 594 // The fling should be ignored since there's no layer being scrolled impl-side 595 EXPECT_EQ(InputHandler::ScrollIgnored, 596 host_impl_->FlingScrollBegin()); 597 } 598 599 TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { 600 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 601 host_impl_->SetViewportSize(gfx::Size(50, 50)); 602 DrawFrame(); 603 LayerImpl* root = host_impl_->active_tree()->root_layer(); 604 605 root->SetShouldScrollOnMainThread(true); 606 607 EXPECT_EQ(InputHandler::ScrollOnMainThread, 608 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 609 EXPECT_EQ(InputHandler::ScrollOnMainThread, 610 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 611 } 612 613 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { 614 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 615 host_impl_->SetViewportSize(gfx::Size(100, 100)); 616 617 LayerImpl* root = host_impl_->active_tree()->root_layer(); 618 root->SetContentsScale(2.f, 2.f); 619 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); 620 621 DrawFrame(); 622 623 // All scroll types inside the non-fast scrollable region should fail. 624 EXPECT_EQ(InputHandler::ScrollOnMainThread, 625 host_impl_->ScrollBegin(gfx::Point(25, 25), 626 InputHandler::Wheel)); 627 EXPECT_EQ(InputHandler::ScrollOnMainThread, 628 host_impl_->ScrollBegin(gfx::Point(25, 25), 629 InputHandler::Gesture)); 630 631 // All scroll types outside this region should succeed. 632 EXPECT_EQ(InputHandler::ScrollStarted, 633 host_impl_->ScrollBegin(gfx::Point(75, 75), 634 InputHandler::Wheel)); 635 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 636 host_impl_->ScrollEnd(); 637 EXPECT_EQ(InputHandler::ScrollStarted, 638 host_impl_->ScrollBegin(gfx::Point(75, 75), 639 InputHandler::Gesture)); 640 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 641 host_impl_->ScrollEnd(); 642 } 643 644 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { 645 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 646 host_impl_->SetViewportSize(gfx::Size(100, 100)); 647 648 LayerImpl* root = host_impl_->active_tree()->root_layer(); 649 root->SetContentsScale(2.f, 2.f); 650 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); 651 root->SetPosition(gfx::PointF(-25.f, 0.f)); 652 653 DrawFrame(); 654 655 // This point would fall into the non-fast scrollable region except that we've 656 // moved the layer down by 25 pixels. 657 EXPECT_EQ(InputHandler::ScrollStarted, 658 host_impl_->ScrollBegin(gfx::Point(40, 10), 659 InputHandler::Wheel)); 660 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1)); 661 host_impl_->ScrollEnd(); 662 663 // This point is still inside the non-fast region. 664 EXPECT_EQ(InputHandler::ScrollOnMainThread, 665 host_impl_->ScrollBegin(gfx::Point(10, 10), 666 InputHandler::Wheel)); 667 } 668 669 TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { 670 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 671 host_impl_->SetViewportSize(gfx::Size(100, 100)); 672 673 DrawFrame(); 674 675 EXPECT_EQ(InputHandler::ScrollStarted, 676 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 677 678 // Trying to scroll to the left/top will not succeed. 679 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 680 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); 681 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); 682 683 // Scrolling to the right/bottom will succeed. 684 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0))); 685 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10))); 686 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10))); 687 688 // Scrolling to left/top will now succeed. 689 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 690 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); 691 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); 692 693 // Scrolling diagonally against an edge will succeed. 694 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10))); 695 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 696 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10))); 697 698 // Trying to scroll more than the available space will also succeed. 699 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000))); 700 } 701 702 TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { 703 SetupScrollAndContentsLayers(gfx::Size(200, 2000)); 704 host_impl_->SetViewportSize(gfx::Size(100, 1000)); 705 706 DrawFrame(); 707 708 EXPECT_EQ(InputHandler::ScrollStarted, 709 host_impl_->ScrollBegin(gfx::Point(), 710 InputHandler::Wheel)); 711 712 // Trying to scroll without a vertical scrollbar will fail. 713 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( 714 gfx::Point(), SCROLL_FORWARD)); 715 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( 716 gfx::Point(), SCROLL_BACKWARD)); 717 718 scoped_ptr<cc::PaintedScrollbarLayerImpl> vertical_scrollbar( 719 cc::PaintedScrollbarLayerImpl::Create( 720 host_impl_->active_tree(), 721 20, 722 VERTICAL)); 723 vertical_scrollbar->SetBounds(gfx::Size(15, 1000)); 724 host_impl_->RootScrollLayer()->SetVerticalScrollbarLayer( 725 vertical_scrollbar.get()); 726 727 // Trying to scroll with a vertical scrollbar will succeed. 728 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage( 729 gfx::Point(), SCROLL_FORWARD)); 730 EXPECT_FLOAT_EQ(875.f, host_impl_->RootScrollLayer()->ScrollDelta().y()); 731 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage( 732 gfx::Point(), SCROLL_BACKWARD)); 733 } 734 735 // The user-scrollability breaks for zoomed-in pages. So disable this. 736 // http://crbug.com/322223 737 TEST_F(LayerTreeHostImplTest, DISABLED_ScrollWithUserUnscrollableLayers) { 738 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); 739 host_impl_->SetViewportSize(gfx::Size(100, 100)); 740 741 gfx::Size overflow_size(400, 400); 742 ASSERT_EQ(1u, scroll_layer->children().size()); 743 LayerImpl* overflow = scroll_layer->children()[0]; 744 overflow->SetBounds(overflow_size); 745 overflow->SetContentBounds(overflow_size); 746 overflow->SetScrollable(true); 747 overflow->SetMaxScrollOffset(gfx::Vector2d(overflow_size.width(), 748 overflow_size.height())); 749 overflow->SetScrollOffset(gfx::Vector2d()); 750 overflow->SetPosition(gfx::PointF()); 751 overflow->SetAnchorPoint(gfx::PointF()); 752 753 DrawFrame(); 754 gfx::Point scroll_position(10, 10); 755 756 EXPECT_EQ(InputHandler::ScrollStarted, 757 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 758 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 759 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset()); 760 761 gfx::Vector2dF scroll_delta(10, 10); 762 host_impl_->ScrollBy(scroll_position, scroll_delta); 763 host_impl_->ScrollEnd(); 764 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 765 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); 766 767 overflow->set_user_scrollable_horizontal(false); 768 769 EXPECT_EQ(InputHandler::ScrollStarted, 770 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 771 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 772 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); 773 774 host_impl_->ScrollBy(scroll_position, scroll_delta); 775 host_impl_->ScrollEnd(); 776 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); 777 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 778 779 overflow->set_user_scrollable_vertical(false); 780 781 EXPECT_EQ(InputHandler::ScrollStarted, 782 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 783 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); 784 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 785 786 host_impl_->ScrollBy(scroll_position, scroll_delta); 787 host_impl_->ScrollEnd(); 788 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset()); 789 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 790 } 791 792 TEST_F(LayerTreeHostImplTest, 793 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) { 794 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 795 host_impl_->SetViewportSize(gfx::Size(50, 50)); 796 DrawFrame(); 797 798 // We should be able to hit test for touch event handlers even if the root 799 // layer loses its render surface after the most recent render. 800 host_impl_->active_tree()->root_layer()->ClearRenderSurface(); 801 host_impl_->active_tree()->set_needs_update_draw_properties(); 802 803 EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false); 804 } 805 806 TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { 807 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 808 host_impl_->SetViewportSize(gfx::Size(50, 50)); 809 DrawFrame(); 810 811 EXPECT_EQ(scroll_layer, host_impl_->RootScrollLayer()); 812 813 float min_page_scale = 1.f, max_page_scale = 4.f; 814 815 // The impl-based pinch zoom should adjust the max scroll position. 816 { 817 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 818 min_page_scale, 819 max_page_scale); 820 host_impl_->active_tree()->SetPageScaleDelta(1.f); 821 scroll_layer->SetScrollDelta(gfx::Vector2d()); 822 823 float page_scale_delta = 2.f; 824 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 825 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 826 host_impl_->PinchGestureEnd(); 827 host_impl_->ScrollEnd(); 828 EXPECT_TRUE(did_request_redraw_); 829 EXPECT_TRUE(did_request_commit_); 830 831 scoped_ptr<ScrollAndScaleSet> scroll_info = 832 host_impl_->ProcessScrollDeltas(); 833 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 834 835 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(), 836 scroll_layer->max_scroll_offset().ToString()); 837 } 838 839 // Scrolling after a pinch gesture should always be in local space. The 840 // scroll deltas do not have the page scale factor applied. 841 { 842 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 843 min_page_scale, 844 max_page_scale); 845 host_impl_->active_tree()->SetPageScaleDelta(1.f); 846 scroll_layer->SetScrollDelta(gfx::Vector2d()); 847 848 float page_scale_delta = 2.f; 849 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 850 host_impl_->PinchGestureBegin(); 851 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); 852 host_impl_->PinchGestureEnd(); 853 host_impl_->ScrollEnd(); 854 855 gfx::Vector2d scroll_delta(0, 10); 856 EXPECT_EQ(InputHandler::ScrollStarted, 857 host_impl_->ScrollBegin(gfx::Point(5, 5), 858 InputHandler::Wheel)); 859 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 860 host_impl_->ScrollEnd(); 861 862 scoped_ptr<ScrollAndScaleSet> scroll_info = 863 host_impl_->ProcessScrollDeltas(); 864 ExpectContains(*scroll_info.get(), 865 scroll_layer->id(), 866 scroll_delta); 867 } 868 } 869 870 TEST_F(LayerTreeHostImplTest, PinchGesture) { 871 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 872 host_impl_->SetViewportSize(gfx::Size(50, 50)); 873 DrawFrame(); 874 875 LayerImpl* scroll_layer = host_impl_->RootScrollLayer(); 876 DCHECK(scroll_layer); 877 878 float min_page_scale = 1.f; 879 float max_page_scale = 4.f; 880 881 // Basic pinch zoom in gesture 882 { 883 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 884 min_page_scale, 885 max_page_scale); 886 scroll_layer->SetScrollDelta(gfx::Vector2d()); 887 888 float page_scale_delta = 2.f; 889 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 890 host_impl_->PinchGestureBegin(); 891 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 892 host_impl_->PinchGestureEnd(); 893 host_impl_->ScrollEnd(); 894 EXPECT_TRUE(did_request_redraw_); 895 EXPECT_TRUE(did_request_commit_); 896 897 scoped_ptr<ScrollAndScaleSet> scroll_info = 898 host_impl_->ProcessScrollDeltas(); 899 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 900 } 901 902 // Zoom-in clamping 903 { 904 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 905 min_page_scale, 906 max_page_scale); 907 scroll_layer->SetScrollDelta(gfx::Vector2d()); 908 float page_scale_delta = 10.f; 909 910 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 911 host_impl_->PinchGestureBegin(); 912 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 913 host_impl_->PinchGestureEnd(); 914 host_impl_->ScrollEnd(); 915 916 scoped_ptr<ScrollAndScaleSet> scroll_info = 917 host_impl_->ProcessScrollDeltas(); 918 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale); 919 } 920 921 // Zoom-out clamping 922 { 923 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 924 min_page_scale, 925 max_page_scale); 926 scroll_layer->SetScrollDelta(gfx::Vector2d()); 927 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 928 929 float page_scale_delta = 0.1f; 930 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 931 host_impl_->PinchGestureBegin(); 932 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); 933 host_impl_->PinchGestureEnd(); 934 host_impl_->ScrollEnd(); 935 936 scoped_ptr<ScrollAndScaleSet> scroll_info = 937 host_impl_->ProcessScrollDeltas(); 938 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); 939 940 EXPECT_TRUE(scroll_info->scrolls.empty()); 941 } 942 943 // Two-finger panning should not happen based on pinch events only 944 { 945 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 946 min_page_scale, 947 max_page_scale); 948 scroll_layer->SetScrollDelta(gfx::Vector2d()); 949 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); 950 951 float page_scale_delta = 1.f; 952 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); 953 host_impl_->PinchGestureBegin(); 954 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); 955 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); 956 host_impl_->PinchGestureEnd(); 957 host_impl_->ScrollEnd(); 958 959 scoped_ptr<ScrollAndScaleSet> scroll_info = 960 host_impl_->ProcessScrollDeltas(); 961 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 962 EXPECT_TRUE(scroll_info->scrolls.empty()); 963 } 964 965 // Two-finger panning should work with interleaved scroll events 966 { 967 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 968 min_page_scale, 969 max_page_scale); 970 scroll_layer->SetScrollDelta(gfx::Vector2d()); 971 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); 972 973 float page_scale_delta = 1.f; 974 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); 975 host_impl_->PinchGestureBegin(); 976 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); 977 host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10)); 978 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); 979 host_impl_->PinchGestureEnd(); 980 host_impl_->ScrollEnd(); 981 982 scoped_ptr<ScrollAndScaleSet> scroll_info = 983 host_impl_->ProcessScrollDeltas(); 984 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 985 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10)); 986 } 987 988 // Two-finger panning should work when starting fully zoomed out. 989 { 990 host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f, 991 0.5f, 992 4.f); 993 scroll_layer->SetScrollDelta(gfx::Vector2d()); 994 scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0)); 995 host_impl_->active_tree()->UpdateMaxScrollOffset(); 996 997 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture); 998 host_impl_->PinchGestureBegin(); 999 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0)); 1000 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0)); 1001 host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10)); 1002 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10)); 1003 host_impl_->PinchGestureEnd(); 1004 host_impl_->ScrollEnd(); 1005 1006 scoped_ptr<ScrollAndScaleSet> scroll_info = 1007 host_impl_->ProcessScrollDeltas(); 1008 EXPECT_EQ(scroll_info->page_scale_delta, 2.f); 1009 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20)); 1010 } 1011 } 1012 1013 TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { 1014 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1015 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1016 DrawFrame(); 1017 1018 LayerImpl* scroll_layer = host_impl_->RootScrollLayer(); 1019 DCHECK(scroll_layer); 1020 1021 float min_page_scale = 0.5f; 1022 float max_page_scale = 4.f; 1023 base::TimeTicks start_time = base::TimeTicks() + 1024 base::TimeDelta::FromSeconds(1); 1025 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); 1026 base::TimeTicks halfway_through_animation = start_time + duration / 2; 1027 base::TimeTicks end_time = start_time + duration; 1028 1029 // Non-anchor zoom-in 1030 { 1031 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1032 min_page_scale, 1033 max_page_scale); 1034 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1035 1036 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f, duration); 1037 did_request_redraw_ = false; 1038 host_impl_->Animate(start_time, base::Time()); 1039 EXPECT_TRUE(did_request_redraw_); 1040 1041 did_request_redraw_ = false; 1042 host_impl_->Animate(halfway_through_animation, base::Time()); 1043 EXPECT_TRUE(did_request_redraw_); 1044 1045 did_request_redraw_ = false; 1046 did_request_commit_ = false; 1047 host_impl_->Animate(end_time, base::Time()); 1048 EXPECT_TRUE(did_request_commit_); 1049 1050 scoped_ptr<ScrollAndScaleSet> scroll_info = 1051 host_impl_->ProcessScrollDeltas(); 1052 EXPECT_EQ(scroll_info->page_scale_delta, 2); 1053 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); 1054 } 1055 1056 // Anchor zoom-out 1057 { 1058 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1059 min_page_scale, 1060 max_page_scale); 1061 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1062 1063 host_impl_->StartPageScaleAnimation( 1064 gfx::Vector2d(25, 25), true, min_page_scale, duration); 1065 did_request_redraw_ = false; 1066 host_impl_->Animate(start_time, base::Time()); 1067 EXPECT_TRUE(did_request_redraw_); 1068 1069 did_request_redraw_ = false; 1070 did_request_commit_ = false; 1071 host_impl_->Animate(end_time, base::Time()); 1072 EXPECT_TRUE(did_request_redraw_); 1073 EXPECT_TRUE(did_request_commit_); 1074 1075 scoped_ptr<ScrollAndScaleSet> scroll_info = 1076 host_impl_->ProcessScrollDeltas(); 1077 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); 1078 // Pushed to (0,0) via clamping against contents layer size. 1079 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); 1080 } 1081 } 1082 1083 TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { 1084 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1085 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1086 DrawFrame(); 1087 1088 LayerImpl* scroll_layer = host_impl_->RootScrollLayer(); 1089 DCHECK(scroll_layer); 1090 1091 float min_page_scale = 0.5f; 1092 float max_page_scale = 4.f; 1093 base::TimeTicks start_time = base::TimeTicks() + 1094 base::TimeDelta::FromSeconds(1); 1095 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); 1096 base::TimeTicks halfway_through_animation = start_time + duration / 2; 1097 base::TimeTicks end_time = start_time + duration; 1098 1099 // Anchor zoom with unchanged page scale should not change scroll or scale. 1100 { 1101 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1102 min_page_scale, 1103 max_page_scale); 1104 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1105 1106 host_impl_->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f, duration); 1107 host_impl_->Animate(start_time, base::Time()); 1108 host_impl_->Animate(halfway_through_animation, base::Time()); 1109 EXPECT_TRUE(did_request_redraw_); 1110 host_impl_->Animate(end_time, base::Time()); 1111 EXPECT_TRUE(did_request_commit_); 1112 1113 scoped_ptr<ScrollAndScaleSet> scroll_info = 1114 host_impl_->ProcessScrollDeltas(); 1115 EXPECT_EQ(scroll_info->page_scale_delta, 1); 1116 ExpectNone(*scroll_info, scroll_layer->id()); 1117 } 1118 } 1119 1120 class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { 1121 public: 1122 LayerTreeHostImplOverridePhysicalTime( 1123 const LayerTreeSettings& settings, 1124 LayerTreeHostImplClient* client, 1125 Proxy* proxy, 1126 RenderingStatsInstrumentation* rendering_stats_instrumentation) 1127 : LayerTreeHostImpl(settings, 1128 client, 1129 proxy, 1130 rendering_stats_instrumentation, 1131 NULL, 1132 0) {} 1133 1134 virtual base::TimeTicks CurrentPhysicalTimeTicks() const OVERRIDE { 1135 return fake_current_physical_time_; 1136 } 1137 1138 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) { 1139 fake_current_physical_time_ = fake_now; 1140 } 1141 1142 private: 1143 base::TimeTicks fake_current_physical_time_; 1144 }; 1145 1146 TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) { 1147 LayerTreeSettings settings; 1148 settings.scrollbar_animator = LayerTreeSettings::LinearFade; 1149 settings.scrollbar_linear_fade_delay_ms = 20; 1150 settings.scrollbar_linear_fade_length_ms = 20; 1151 1152 gfx::Size viewport_size(10, 10); 1153 gfx::Size content_size(100, 100); 1154 1155 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = 1156 new LayerTreeHostImplOverridePhysicalTime( 1157 settings, this, &proxy_, &stats_instrumentation_); 1158 host_impl_ = make_scoped_ptr(host_impl_override_time); 1159 host_impl_->InitializeRenderer(CreateOutputSurface()); 1160 host_impl_->SetViewportSize(viewport_size); 1161 1162 scoped_ptr<LayerImpl> root = 1163 LayerImpl::Create(host_impl_->active_tree(), 1); 1164 root->SetBounds(viewport_size); 1165 1166 scoped_ptr<LayerImpl> scroll = 1167 LayerImpl::Create(host_impl_->active_tree(), 2); 1168 scroll->SetScrollable(true); 1169 scroll->SetScrollOffset(gfx::Vector2d()); 1170 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(), 1171 content_size.height())); 1172 scroll->SetBounds(content_size); 1173 scroll->SetContentBounds(content_size); 1174 1175 scoped_ptr<LayerImpl> contents = 1176 LayerImpl::Create(host_impl_->active_tree(), 3); 1177 contents->SetDrawsContent(true); 1178 contents->SetBounds(content_size); 1179 contents->SetContentBounds(content_size); 1180 1181 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar = 1182 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 4, VERTICAL); 1183 scroll->SetVerticalScrollbarLayer(scrollbar.get()); 1184 1185 scroll->AddChild(contents.Pass()); 1186 root->AddChild(scroll.Pass()); 1187 root->AddChild(scrollbar.PassAs<LayerImpl>()); 1188 1189 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1190 host_impl_->active_tree()->DidBecomeActive(); 1191 DrawFrame(); 1192 1193 base::TimeTicks fake_now = gfx::FrameTime::Now(); 1194 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now); 1195 1196 // If no scroll happened recently, StartScrollbarAnimation should have no 1197 // effect. 1198 host_impl_->StartScrollbarAnimation(); 1199 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1200 EXPECT_FALSE(did_request_redraw_); 1201 1202 // If no scroll happened during a scroll gesture, StartScrollbarAnimation 1203 // should have no effect. 1204 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1205 host_impl_->ScrollEnd(); 1206 host_impl_->StartScrollbarAnimation(); 1207 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1208 EXPECT_FALSE(did_request_redraw_); 1209 1210 // After a scroll, a fade animation should be scheduled about 20ms from now. 1211 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1212 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); 1213 host_impl_->ScrollEnd(); 1214 did_request_redraw_ = false; 1215 host_impl_->StartScrollbarAnimation(); 1216 EXPECT_LT(base::TimeDelta::FromMilliseconds(19), 1217 requested_scrollbar_animation_delay_); 1218 EXPECT_FALSE(did_request_redraw_); 1219 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1220 1221 // After the fade begins, we should start getting redraws instead of a 1222 // scheduled animation. 1223 fake_now += base::TimeDelta::FromMilliseconds(25); 1224 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now); 1225 host_impl_->StartScrollbarAnimation(); 1226 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1227 EXPECT_TRUE(did_request_redraw_); 1228 did_request_redraw_ = false; 1229 1230 // If no scroll happened recently, StartScrollbarAnimation should have no 1231 // effect. 1232 fake_now += base::TimeDelta::FromMilliseconds(25); 1233 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now); 1234 host_impl_->StartScrollbarAnimation(); 1235 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1236 EXPECT_FALSE(did_request_redraw_); 1237 1238 // Setting the scroll offset outside a scroll should also cause the scrollbar 1239 // to appear and to schedule a fade. 1240 host_impl_->RootScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5)); 1241 host_impl_->StartScrollbarAnimation(); 1242 EXPECT_LT(base::TimeDelta::FromMilliseconds(19), 1243 requested_scrollbar_animation_delay_); 1244 EXPECT_FALSE(did_request_redraw_); 1245 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1246 1247 // None of the above should have called CurrentFrameTimeTicks, so if we call 1248 // it now we should get the current time. 1249 fake_now += base::TimeDelta::FromMilliseconds(10); 1250 host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now); 1251 EXPECT_EQ(fake_now, host_impl_->CurrentFrameTimeTicks()); 1252 } 1253 1254 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( 1255 float device_scale_factor) { 1256 LayerTreeSettings settings; 1257 settings.scrollbar_animator = LayerTreeSettings::Thinning; 1258 1259 gfx::Size viewport_size(300, 200); 1260 gfx::Size device_viewport_size = gfx::ToFlooredSize( 1261 gfx::ScaleSize(viewport_size, device_scale_factor)); 1262 gfx::Size content_size(1000, 1000); 1263 1264 CreateHostImpl(settings, CreateOutputSurface()); 1265 host_impl_->SetDeviceScaleFactor(device_scale_factor); 1266 host_impl_->SetViewportSize(device_viewport_size); 1267 1268 scoped_ptr<LayerImpl> root = 1269 LayerImpl::Create(host_impl_->active_tree(), 1); 1270 root->SetBounds(viewport_size); 1271 1272 scoped_ptr<LayerImpl> scroll = 1273 LayerImpl::Create(host_impl_->active_tree(), 2); 1274 scroll->SetScrollable(true); 1275 scroll->SetScrollOffset(gfx::Vector2d()); 1276 scroll->SetMaxScrollOffset(gfx::Vector2d(content_size.width(), 1277 content_size.height())); 1278 scroll->SetBounds(content_size); 1279 scroll->SetContentBounds(content_size); 1280 1281 scoped_ptr<LayerImpl> contents = 1282 LayerImpl::Create(host_impl_->active_tree(), 3); 1283 contents->SetDrawsContent(true); 1284 contents->SetBounds(content_size); 1285 contents->SetContentBounds(content_size); 1286 1287 // The scrollbar is on the right side. 1288 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar = 1289 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL); 1290 scrollbar->SetDrawsContent(true); 1291 scrollbar->SetBounds(gfx::Size(15, viewport_size.height())); 1292 scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height())); 1293 scrollbar->SetPosition(gfx::Point(285, 0)); 1294 scroll->SetVerticalScrollbarLayer(scrollbar.get()); 1295 1296 scroll->AddChild(contents.Pass()); 1297 root->AddChild(scroll.Pass()); 1298 root->AddChild(scrollbar.PassAs<LayerImpl>()); 1299 1300 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1301 host_impl_->active_tree()->DidBecomeActive(); 1302 DrawFrame(); 1303 1304 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer(); 1305 ASSERT_TRUE(root_scroll->scrollbar_animation_controller()); 1306 ScrollbarAnimationControllerThinning* scrollbar_animation_controller = 1307 static_cast<ScrollbarAnimationControllerThinning*>( 1308 root_scroll->scrollbar_animation_controller()); 1309 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f); 1310 1311 host_impl_->MouseMoveAt(gfx::Point(1, 1)); 1312 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1313 1314 host_impl_->MouseMoveAt(gfx::Point(200, 50)); 1315 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1316 1317 host_impl_->MouseMoveAt(gfx::Point(184, 100)); 1318 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1319 1320 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f); 1321 host_impl_->MouseMoveAt(gfx::Point(184, 100)); 1322 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1323 1324 did_request_redraw_ = false; 1325 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1326 host_impl_->MouseMoveAt(gfx::Point(290, 100)); 1327 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1328 host_impl_->MouseMoveAt(gfx::Point(290, 120)); 1329 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1330 host_impl_->MouseMoveAt(gfx::Point(150, 120)); 1331 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1332 } 1333 1334 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) { 1335 SetupMouseMoveAtWithDeviceScale(1.f); 1336 } 1337 1338 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { 1339 SetupMouseMoveAtWithDeviceScale(2.f); 1340 } 1341 1342 TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { 1343 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1344 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1345 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 1346 DrawFrame(); 1347 { 1348 CompositorFrameMetadata metadata = 1349 host_impl_->MakeCompositorFrameMetadata(); 1350 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset); 1351 EXPECT_EQ(1.f, metadata.page_scale_factor); 1352 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.viewport_size); 1353 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1354 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1355 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1356 } 1357 1358 // Scrolling should update metadata immediately. 1359 EXPECT_EQ(InputHandler::ScrollStarted, 1360 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 1361 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 1362 { 1363 CompositorFrameMetadata metadata = 1364 host_impl_->MakeCompositorFrameMetadata(); 1365 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1366 } 1367 host_impl_->ScrollEnd(); 1368 { 1369 CompositorFrameMetadata metadata = 1370 host_impl_->MakeCompositorFrameMetadata(); 1371 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1372 } 1373 1374 // Page scale should update metadata correctly (shrinking only the viewport). 1375 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 1376 host_impl_->PinchGestureBegin(); 1377 host_impl_->PinchGestureUpdate(2.f, gfx::Point()); 1378 host_impl_->PinchGestureEnd(); 1379 host_impl_->ScrollEnd(); 1380 { 1381 CompositorFrameMetadata metadata = 1382 host_impl_->MakeCompositorFrameMetadata(); 1383 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1384 EXPECT_EQ(2.f, metadata.page_scale_factor); 1385 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.viewport_size); 1386 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1387 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1388 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1389 } 1390 1391 // Likewise if set from the main thread. 1392 host_impl_->ProcessScrollDeltas(); 1393 host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f); 1394 host_impl_->active_tree()->SetPageScaleDelta(1.f); 1395 { 1396 CompositorFrameMetadata metadata = 1397 host_impl_->MakeCompositorFrameMetadata(); 1398 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1399 EXPECT_EQ(4.f, metadata.page_scale_factor); 1400 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.viewport_size); 1401 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1402 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1403 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1404 } 1405 } 1406 1407 class DidDrawCheckLayer : public TiledLayerImpl { 1408 public: 1409 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 1410 return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id)); 1411 } 1412 1413 virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) 1414 OVERRIDE { 1415 will_draw_called_ = true; 1416 if (will_draw_returns_false_) 1417 return false; 1418 return TiledLayerImpl::WillDraw(draw_mode, provider); 1419 } 1420 1421 virtual void AppendQuads(QuadSink* quad_sink, 1422 AppendQuadsData* append_quads_data) OVERRIDE { 1423 append_quads_called_ = true; 1424 TiledLayerImpl::AppendQuads(quad_sink, append_quads_data); 1425 } 1426 1427 virtual void DidDraw(ResourceProvider* provider) OVERRIDE { 1428 did_draw_called_ = true; 1429 TiledLayerImpl::DidDraw(provider); 1430 } 1431 1432 bool will_draw_called() const { return will_draw_called_; } 1433 bool append_quads_called() const { return append_quads_called_; } 1434 bool did_draw_called() const { return did_draw_called_; } 1435 1436 void set_will_draw_returns_false() { will_draw_returns_false_ = true; } 1437 1438 void ClearDidDrawCheck() { 1439 will_draw_called_ = false; 1440 append_quads_called_ = false; 1441 did_draw_called_ = false; 1442 } 1443 1444 protected: 1445 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id) 1446 : TiledLayerImpl(tree_impl, id), 1447 will_draw_returns_false_(false), 1448 will_draw_called_(false), 1449 append_quads_called_(false), 1450 did_draw_called_(false) { 1451 SetAnchorPoint(gfx::PointF()); 1452 SetBounds(gfx::Size(10, 10)); 1453 SetContentBounds(gfx::Size(10, 10)); 1454 SetDrawsContent(true); 1455 set_skips_draw(false); 1456 draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10); 1457 1458 scoped_ptr<LayerTilingData> tiler = 1459 LayerTilingData::Create(gfx::Size(100, 100), 1460 LayerTilingData::HAS_BORDER_TEXELS); 1461 tiler->SetBounds(content_bounds()); 1462 SetTilingData(*tiler.get()); 1463 } 1464 1465 private: 1466 bool will_draw_returns_false_; 1467 bool will_draw_called_; 1468 bool append_quads_called_; 1469 bool did_draw_called_; 1470 }; 1471 1472 TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { 1473 // The root layer is always drawn, so run this test on a child layer that 1474 // will be masked out by the root layer's bounds. 1475 host_impl_->active_tree()->SetRootLayer( 1476 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1477 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( 1478 host_impl_->active_tree()->root_layer()); 1479 1480 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1481 DidDrawCheckLayer* layer = 1482 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1483 1484 { 1485 LayerTreeHostImpl::FrameData frame; 1486 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10))); 1487 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1488 host_impl_->DidDrawAllLayers(frame); 1489 1490 EXPECT_TRUE(layer->will_draw_called()); 1491 EXPECT_TRUE(layer->append_quads_called()); 1492 EXPECT_TRUE(layer->did_draw_called()); 1493 } 1494 1495 { 1496 LayerTreeHostImpl::FrameData frame; 1497 1498 layer->set_will_draw_returns_false(); 1499 layer->ClearDidDrawCheck(); 1500 1501 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect(10, 10))); 1502 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1503 host_impl_->DidDrawAllLayers(frame); 1504 1505 EXPECT_TRUE(layer->will_draw_called()); 1506 EXPECT_FALSE(layer->append_quads_called()); 1507 EXPECT_FALSE(layer->did_draw_called()); 1508 } 1509 } 1510 1511 TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { 1512 // The root layer is always drawn, so run this test on a child layer that 1513 // will be masked out by the root layer's bounds. 1514 host_impl_->active_tree()->SetRootLayer( 1515 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1516 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( 1517 host_impl_->active_tree()->root_layer()); 1518 root->SetMasksToBounds(true); 1519 1520 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1521 DidDrawCheckLayer* layer = 1522 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1523 // Ensure visible_content_rect for layer is empty. 1524 layer->SetPosition(gfx::PointF(100.f, 100.f)); 1525 layer->SetBounds(gfx::Size(10, 10)); 1526 layer->SetContentBounds(gfx::Size(10, 10)); 1527 1528 LayerTreeHostImpl::FrameData frame; 1529 1530 EXPECT_FALSE(layer->will_draw_called()); 1531 EXPECT_FALSE(layer->did_draw_called()); 1532 1533 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1534 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1535 host_impl_->DidDrawAllLayers(frame); 1536 1537 EXPECT_FALSE(layer->will_draw_called()); 1538 EXPECT_FALSE(layer->did_draw_called()); 1539 1540 EXPECT_TRUE(layer->visible_content_rect().IsEmpty()); 1541 1542 // Ensure visible_content_rect for layer is not empty 1543 layer->SetPosition(gfx::PointF()); 1544 1545 EXPECT_FALSE(layer->will_draw_called()); 1546 EXPECT_FALSE(layer->did_draw_called()); 1547 1548 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1549 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1550 host_impl_->DidDrawAllLayers(frame); 1551 1552 EXPECT_TRUE(layer->will_draw_called()); 1553 EXPECT_TRUE(layer->did_draw_called()); 1554 1555 EXPECT_FALSE(layer->visible_content_rect().IsEmpty()); 1556 } 1557 1558 TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { 1559 gfx::Size big_size(1000, 1000); 1560 host_impl_->SetViewportSize(big_size); 1561 1562 host_impl_->active_tree()->SetRootLayer( 1563 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1564 DidDrawCheckLayer* root = 1565 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1566 1567 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1568 DidDrawCheckLayer* occluded_layer = 1569 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1570 1571 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 1572 DidDrawCheckLayer* top_layer = 1573 static_cast<DidDrawCheckLayer*>(root->children()[1]); 1574 // This layer covers the occluded_layer above. Make this layer large so it can 1575 // occlude. 1576 top_layer->SetBounds(big_size); 1577 top_layer->SetContentBounds(big_size); 1578 top_layer->SetContentsOpaque(true); 1579 1580 LayerTreeHostImpl::FrameData frame; 1581 1582 EXPECT_FALSE(occluded_layer->will_draw_called()); 1583 EXPECT_FALSE(occluded_layer->did_draw_called()); 1584 EXPECT_FALSE(top_layer->will_draw_called()); 1585 EXPECT_FALSE(top_layer->did_draw_called()); 1586 1587 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1588 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1589 host_impl_->DidDrawAllLayers(frame); 1590 1591 EXPECT_FALSE(occluded_layer->will_draw_called()); 1592 EXPECT_FALSE(occluded_layer->did_draw_called()); 1593 EXPECT_TRUE(top_layer->will_draw_called()); 1594 EXPECT_TRUE(top_layer->did_draw_called()); 1595 } 1596 1597 TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { 1598 host_impl_->active_tree()->SetRootLayer( 1599 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1600 DidDrawCheckLayer* root = 1601 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1602 1603 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1604 DidDrawCheckLayer* layer1 = 1605 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1606 1607 layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 1608 DidDrawCheckLayer* layer2 = 1609 static_cast<DidDrawCheckLayer*>(layer1->children()[0]); 1610 1611 layer1->SetOpacity(0.3f); 1612 layer1->SetPreserves3d(false); 1613 1614 EXPECT_FALSE(root->did_draw_called()); 1615 EXPECT_FALSE(layer1->did_draw_called()); 1616 EXPECT_FALSE(layer2->did_draw_called()); 1617 1618 LayerTreeHostImpl::FrameData frame; 1619 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1620 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1621 host_impl_->DidDrawAllLayers(frame); 1622 1623 EXPECT_TRUE(root->did_draw_called()); 1624 EXPECT_TRUE(layer1->did_draw_called()); 1625 EXPECT_TRUE(layer2->did_draw_called()); 1626 1627 EXPECT_NE(root->render_surface(), layer1->render_surface()); 1628 EXPECT_TRUE(!!layer1->render_surface()); 1629 } 1630 1631 class MissingTextureAnimatingLayer : public DidDrawCheckLayer { 1632 public: 1633 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, 1634 int id, 1635 bool tile_missing, 1636 bool skips_draw, 1637 bool animating, 1638 ResourceProvider* resource_provider) { 1639 return scoped_ptr<LayerImpl>(new MissingTextureAnimatingLayer( 1640 tree_impl, 1641 id, 1642 tile_missing, 1643 skips_draw, 1644 animating, 1645 resource_provider)); 1646 } 1647 1648 private: 1649 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl, 1650 int id, 1651 bool tile_missing, 1652 bool skips_draw, 1653 bool animating, 1654 ResourceProvider* resource_provider) 1655 : DidDrawCheckLayer(tree_impl, id) { 1656 scoped_ptr<LayerTilingData> tiling_data = 1657 LayerTilingData::Create(gfx::Size(10, 10), 1658 LayerTilingData::NO_BORDER_TEXELS); 1659 tiling_data->SetBounds(bounds()); 1660 SetTilingData(*tiling_data.get()); 1661 set_skips_draw(skips_draw); 1662 if (!tile_missing) { 1663 ResourceProvider::ResourceId resource = 1664 resource_provider->CreateResource(gfx::Size(1, 1), 1665 GL_CLAMP_TO_EDGE, 1666 ResourceProvider::TextureUsageAny, 1667 RGBA_8888); 1668 resource_provider->AllocateForTesting(resource); 1669 PushTileProperties(0, 0, resource, gfx::Rect(), false); 1670 } 1671 if (animating) 1672 AddAnimatedTransformToLayer(this, 10.0, 3, 0); 1673 } 1674 }; 1675 1676 TEST_F(LayerTreeHostImplTest, PrepareToDrawFailsWhenAnimationUsesCheckerboard) { 1677 // When the texture is not missing, we draw as usual. 1678 host_impl_->active_tree()->SetRootLayer( 1679 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1680 DidDrawCheckLayer* root = 1681 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1682 root->AddChild( 1683 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 1684 2, 1685 false, 1686 false, 1687 true, 1688 host_impl_->resource_provider())); 1689 1690 LayerTreeHostImpl::FrameData frame; 1691 1692 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1693 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1694 host_impl_->DidDrawAllLayers(frame); 1695 1696 // When a texture is missing and we're not animating, we draw as usual with 1697 // checkerboarding. 1698 host_impl_->active_tree()->SetRootLayer( 1699 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 1700 root = 1701 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1702 root->AddChild( 1703 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 1704 4, 1705 true, 1706 false, 1707 false, 1708 host_impl_->resource_provider())); 1709 1710 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1711 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1712 host_impl_->DidDrawAllLayers(frame); 1713 1714 // When a texture is missing and we're animating, we don't want to draw 1715 // anything. 1716 host_impl_->active_tree()->SetRootLayer( 1717 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5)); 1718 root = 1719 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1720 root->AddChild( 1721 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 1722 6, 1723 true, 1724 false, 1725 true, 1726 host_impl_->resource_provider())); 1727 1728 EXPECT_FALSE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1729 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1730 host_impl_->DidDrawAllLayers(frame); 1731 1732 // When the layer skips draw and we're animating, we still draw the frame. 1733 host_impl_->active_tree()->SetRootLayer( 1734 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); 1735 root = 1736 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1737 root->AddChild( 1738 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 1739 8, 1740 false, 1741 true, 1742 true, 1743 host_impl_->resource_provider())); 1744 1745 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 1746 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1747 host_impl_->DidDrawAllLayers(frame); 1748 } 1749 1750 TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { 1751 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1752 root->SetScrollable(false); 1753 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1754 DrawFrame(); 1755 1756 // Scroll event is ignored because layer is not scrollable. 1757 EXPECT_EQ(InputHandler::ScrollIgnored, 1758 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 1759 EXPECT_FALSE(did_request_redraw_); 1760 EXPECT_FALSE(did_request_commit_); 1761 } 1762 1763 TEST_F(LayerTreeHostImplTest, ScrollNonScrollableRootWithTopControls) { 1764 LayerTreeSettings settings; 1765 settings.calculate_top_controls_position = true; 1766 settings.top_controls_height = 50; 1767 1768 CreateHostImpl(settings, CreateOutputSurface()); 1769 1770 gfx::Size layer_size(5, 5); 1771 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1772 root->SetScrollable(true); 1773 root->SetMaxScrollOffset(gfx::Vector2d(layer_size.width(), 1774 layer_size.height())); 1775 root->SetBounds(layer_size); 1776 root->SetContentBounds(layer_size); 1777 root->SetPosition(gfx::PointF()); 1778 root->SetAnchorPoint(gfx::PointF()); 1779 root->SetDrawsContent(false); 1780 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1781 host_impl_->active_tree()->FindRootScrollLayer(); 1782 DrawFrame(); 1783 1784 EXPECT_EQ(InputHandler::ScrollIgnored, 1785 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 1786 1787 host_impl_->top_controls_manager()->ScrollBegin(); 1788 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); 1789 host_impl_->top_controls_manager()->ScrollEnd(); 1790 EXPECT_EQ(host_impl_->top_controls_manager()->content_top_offset(), 0.f); 1791 1792 EXPECT_EQ(InputHandler::ScrollStarted, 1793 host_impl_->ScrollBegin(gfx::Point(), 1794 InputHandler::Gesture)); 1795 } 1796 1797 TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { 1798 // Test the configuration where a non-composited root layer is embedded in a 1799 // scrollable outer layer. 1800 gfx::Size surface_size(10, 10); 1801 1802 scoped_ptr<LayerImpl> content_layer = 1803 LayerImpl::Create(host_impl_->active_tree(), 1); 1804 content_layer->SetDrawsContent(true); 1805 content_layer->SetPosition(gfx::PointF()); 1806 content_layer->SetAnchorPoint(gfx::PointF()); 1807 content_layer->SetBounds(surface_size); 1808 content_layer->SetContentBounds(gfx::Size(surface_size.width() * 2, 1809 surface_size.height() * 2)); 1810 content_layer->SetContentsScale(2.f, 2.f); 1811 1812 scoped_ptr<LayerImpl> scroll_layer = 1813 LayerImpl::Create(host_impl_->active_tree(), 2); 1814 scroll_layer->SetScrollable(true); 1815 scroll_layer->SetMaxScrollOffset(gfx::Vector2d(surface_size.width(), 1816 surface_size.height())); 1817 scroll_layer->SetBounds(surface_size); 1818 scroll_layer->SetContentBounds(surface_size); 1819 scroll_layer->SetPosition(gfx::PointF()); 1820 scroll_layer->SetAnchorPoint(gfx::PointF()); 1821 scroll_layer->AddChild(content_layer.Pass()); 1822 1823 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass()); 1824 host_impl_->SetViewportSize(surface_size); 1825 DrawFrame(); 1826 1827 EXPECT_EQ(InputHandler::ScrollStarted, 1828 host_impl_->ScrollBegin(gfx::Point(5, 5), 1829 InputHandler::Wheel)); 1830 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 1831 host_impl_->ScrollEnd(); 1832 EXPECT_TRUE(did_request_redraw_); 1833 EXPECT_TRUE(did_request_commit_); 1834 } 1835 1836 TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { 1837 gfx::Size surface_size(10, 10); 1838 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1839 root->SetBounds(surface_size); 1840 root->SetContentBounds(surface_size); 1841 root->AddChild(CreateScrollableLayer(2, surface_size)); 1842 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1843 host_impl_->SetViewportSize(surface_size); 1844 DrawFrame(); 1845 1846 EXPECT_EQ(InputHandler::ScrollStarted, 1847 host_impl_->ScrollBegin(gfx::Point(5, 5), 1848 InputHandler::Wheel)); 1849 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 1850 host_impl_->ScrollEnd(); 1851 EXPECT_TRUE(did_request_redraw_); 1852 EXPECT_TRUE(did_request_commit_); 1853 } 1854 1855 TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { 1856 gfx::Size surface_size(10, 10); 1857 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1858 root->AddChild(CreateScrollableLayer(2, surface_size)); 1859 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1860 host_impl_->SetViewportSize(surface_size); 1861 DrawFrame(); 1862 1863 // Scroll event is ignored because the input coordinate is outside the layer 1864 // boundaries. 1865 EXPECT_EQ(InputHandler::ScrollIgnored, 1866 host_impl_->ScrollBegin(gfx::Point(15, 5), 1867 InputHandler::Wheel)); 1868 EXPECT_FALSE(did_request_redraw_); 1869 EXPECT_FALSE(did_request_commit_); 1870 } 1871 1872 TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { 1873 gfx::Size surface_size(10, 10); 1874 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1875 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); 1876 host_impl_->SetViewportSize(surface_size); 1877 1878 gfx::Transform matrix; 1879 matrix.RotateAboutXAxis(180.0); 1880 child->SetTransform(matrix); 1881 child->SetDoubleSided(false); 1882 1883 root->AddChild(child.Pass()); 1884 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1885 DrawFrame(); 1886 1887 // Scroll event is ignored because the scrollable layer is not facing the 1888 // viewer and there is nothing scrollable behind it. 1889 EXPECT_EQ(InputHandler::ScrollIgnored, 1890 host_impl_->ScrollBegin(gfx::Point(5, 5), 1891 InputHandler::Wheel)); 1892 EXPECT_FALSE(did_request_redraw_); 1893 EXPECT_FALSE(did_request_commit_); 1894 } 1895 1896 TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { 1897 gfx::Size surface_size(10, 10); 1898 scoped_ptr<LayerImpl> content_layer = CreateScrollableLayer(1, surface_size); 1899 content_layer->SetShouldScrollOnMainThread(true); 1900 content_layer->SetScrollable(false); 1901 1902 scoped_ptr<LayerImpl> scroll_layer = CreateScrollableLayer(2, surface_size); 1903 scroll_layer->AddChild(content_layer.Pass()); 1904 1905 host_impl_->active_tree()->SetRootLayer(scroll_layer.Pass()); 1906 host_impl_->SetViewportSize(surface_size); 1907 DrawFrame(); 1908 1909 // Scrolling fails because the content layer is asking to be scrolled on the 1910 // main thread. 1911 EXPECT_EQ(InputHandler::ScrollOnMainThread, 1912 host_impl_->ScrollBegin(gfx::Point(5, 5), 1913 InputHandler::Wheel)); 1914 } 1915 1916 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { 1917 gfx::Size surface_size(10, 10); 1918 float page_scale = 2.f; 1919 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1920 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size); 1921 root->AddChild(root_scrolling.Pass()); 1922 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1923 host_impl_->active_tree()->DidBecomeActive(); 1924 host_impl_->SetViewportSize(surface_size); 1925 DrawFrame(); 1926 1927 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer(); 1928 1929 gfx::Vector2d scroll_delta(0, 10); 1930 gfx::Vector2d expected_scroll_delta = scroll_delta; 1931 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset(); 1932 EXPECT_EQ(InputHandler::ScrollStarted, 1933 host_impl_->ScrollBegin(gfx::Point(5, 5), 1934 InputHandler::Wheel)); 1935 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 1936 host_impl_->ScrollEnd(); 1937 1938 // Set new page scale from main thread. 1939 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1940 page_scale, 1941 page_scale); 1942 1943 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 1944 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta); 1945 1946 // The scroll range should also have been updated. 1947 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset()); 1948 1949 // The page scale delta remains constant because the impl thread did not 1950 // scale. 1951 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta()); 1952 } 1953 1954 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { 1955 gfx::Size surface_size(10, 10); 1956 float page_scale = 2.f; 1957 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 1958 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size); 1959 root->AddChild(root_scrolling.Pass()); 1960 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1961 host_impl_->active_tree()->DidBecomeActive(); 1962 host_impl_->SetViewportSize(surface_size); 1963 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale); 1964 DrawFrame(); 1965 1966 LayerImpl* root_scroll = host_impl_->active_tree()->RootScrollLayer(); 1967 1968 gfx::Vector2d scroll_delta(0, 10); 1969 gfx::Vector2d expected_scroll_delta = scroll_delta; 1970 gfx::Vector2d expected_max_scroll = root_scroll->max_scroll_offset(); 1971 EXPECT_EQ(InputHandler::ScrollStarted, 1972 host_impl_->ScrollBegin(gfx::Point(5, 5), 1973 InputHandler::Wheel)); 1974 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 1975 host_impl_->ScrollEnd(); 1976 1977 // Set new page scale on impl thread by pinching. 1978 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 1979 host_impl_->PinchGestureBegin(); 1980 host_impl_->PinchGestureUpdate(page_scale, gfx::Point()); 1981 host_impl_->PinchGestureEnd(); 1982 host_impl_->ScrollEnd(); 1983 DrawOneFrame(); 1984 1985 // The scroll delta is not scaled because the main thread did not scale. 1986 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 1987 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta); 1988 1989 // The scroll range should also have been updated. 1990 EXPECT_EQ(expected_max_scroll, root_scroll->max_scroll_offset()); 1991 1992 // The page scale delta should match the new scale on the impl side. 1993 EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor()); 1994 } 1995 1996 TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { 1997 gfx::Size surface_size(10, 10); 1998 float default_page_scale = 1.f; 1999 gfx::Transform default_page_scale_matrix; 2000 default_page_scale_matrix.Scale(default_page_scale, default_page_scale); 2001 2002 float new_page_scale = 2.f; 2003 gfx::Transform new_page_scale_matrix; 2004 new_page_scale_matrix.Scale(new_page_scale, new_page_scale); 2005 2006 // Create a normal scrollable root layer and another scrollable child layer. 2007 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size); 2008 LayerImpl* root = host_impl_->active_tree()->root_layer(); 2009 LayerImpl* child = scroll->children()[0]; 2010 2011 scoped_ptr<LayerImpl> scrollable_child = 2012 CreateScrollableLayer(4, surface_size); 2013 child->AddChild(scrollable_child.Pass()); 2014 LayerImpl* grand_child = child->children()[0]; 2015 2016 // Set new page scale on impl thread by pinching. 2017 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 2018 host_impl_->PinchGestureBegin(); 2019 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point()); 2020 host_impl_->PinchGestureEnd(); 2021 host_impl_->ScrollEnd(); 2022 DrawOneFrame(); 2023 2024 EXPECT_EQ(1.f, root->contents_scale_x()); 2025 EXPECT_EQ(1.f, root->contents_scale_y()); 2026 EXPECT_EQ(1.f, scroll->contents_scale_x()); 2027 EXPECT_EQ(1.f, scroll->contents_scale_y()); 2028 EXPECT_EQ(1.f, child->contents_scale_x()); 2029 EXPECT_EQ(1.f, child->contents_scale_y()); 2030 EXPECT_EQ(1.f, grand_child->contents_scale_x()); 2031 EXPECT_EQ(1.f, grand_child->contents_scale_y()); 2032 2033 // Make sure all the layers are drawn with the page scale delta applied, i.e., 2034 // the page scale delta on the root layer is applied hierarchically. 2035 LayerTreeHostImpl::FrameData frame; 2036 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2037 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2038 host_impl_->DidDrawAllLayers(frame); 2039 2040 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0)); 2041 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1)); 2042 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0)); 2043 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1)); 2044 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0)); 2045 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1)); 2046 EXPECT_EQ(new_page_scale, 2047 grand_child->draw_transform().matrix().getDouble(0, 0)); 2048 EXPECT_EQ(new_page_scale, 2049 grand_child->draw_transform().matrix().getDouble(1, 1)); 2050 } 2051 2052 TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { 2053 gfx::Size surface_size(10, 10); 2054 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2055 scoped_ptr<LayerImpl> root_scrolling = 2056 LayerImpl::Create(host_impl_->active_tree(), 2); 2057 root_scrolling->SetBounds(surface_size); 2058 root_scrolling->SetContentBounds(surface_size); 2059 root_scrolling->SetScrollable(true); 2060 root->AddChild(root_scrolling.Pass()); 2061 int child_scroll_layer_id = 3; 2062 scoped_ptr<LayerImpl> child_scrolling = 2063 CreateScrollableLayer(child_scroll_layer_id, surface_size); 2064 LayerImpl* child = child_scrolling.get(); 2065 root->AddChild(child_scrolling.Pass()); 2066 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2067 host_impl_->active_tree()->DidBecomeActive(); 2068 host_impl_->SetViewportSize(surface_size); 2069 DrawFrame(); 2070 2071 gfx::Vector2d scroll_delta(0, 10); 2072 gfx::Vector2d expected_scroll_delta(scroll_delta); 2073 gfx::Vector2d expected_max_scroll(child->max_scroll_offset()); 2074 EXPECT_EQ(InputHandler::ScrollStarted, 2075 host_impl_->ScrollBegin(gfx::Point(5, 5), 2076 InputHandler::Wheel)); 2077 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2078 host_impl_->ScrollEnd(); 2079 2080 float page_scale = 2.f; 2081 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 2082 1.f, 2083 page_scale); 2084 2085 DrawOneFrame(); 2086 2087 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2088 ExpectContains( 2089 *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta); 2090 2091 // The scroll range should not have changed. 2092 EXPECT_EQ(child->max_scroll_offset(), expected_max_scroll); 2093 2094 // The page scale delta remains constant because the impl thread did not 2095 // scale. 2096 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta()); 2097 } 2098 2099 TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { 2100 // Scroll a child layer beyond its maximum scroll range and make sure the 2101 // parent layer is scrolled on the axis on which the child was unable to 2102 // scroll. 2103 gfx::Size surface_size(10, 10); 2104 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size); 2105 2106 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size); 2107 grand_child->SetScrollOffset(gfx::Vector2d(0, 5)); 2108 2109 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); 2110 child->SetScrollOffset(gfx::Vector2d(3, 0)); 2111 child->AddChild(grand_child.Pass()); 2112 2113 root->AddChild(child.Pass()); 2114 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2115 host_impl_->active_tree()->DidBecomeActive(); 2116 host_impl_->SetViewportSize(surface_size); 2117 DrawFrame(); 2118 { 2119 gfx::Vector2d scroll_delta(-8, -7); 2120 EXPECT_EQ(InputHandler::ScrollStarted, 2121 host_impl_->ScrollBegin(gfx::Point(), 2122 InputHandler::Wheel)); 2123 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2124 host_impl_->ScrollEnd(); 2125 2126 scoped_ptr<ScrollAndScaleSet> scroll_info = 2127 host_impl_->ProcessScrollDeltas(); 2128 2129 // The grand child should have scrolled up to its limit. 2130 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; 2131 LayerImpl* grand_child = child->children()[0]; 2132 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5)); 2133 2134 // The child should have only scrolled on the other axis. 2135 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0)); 2136 } 2137 } 2138 2139 TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { 2140 // Scroll a child layer beyond its maximum scroll range and make sure the 2141 // the scroll doesn't bubble up to the parent layer. 2142 gfx::Size surface_size(10, 10); 2143 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2144 scoped_ptr<LayerImpl> root_scrolling = CreateScrollableLayer(2, surface_size); 2145 2146 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(4, surface_size); 2147 grand_child->SetScrollOffset(gfx::Vector2d(0, 2)); 2148 2149 scoped_ptr<LayerImpl> child = CreateScrollableLayer(3, surface_size); 2150 child->SetScrollOffset(gfx::Vector2d(0, 3)); 2151 child->AddChild(grand_child.Pass()); 2152 2153 root_scrolling->AddChild(child.Pass()); 2154 root->AddChild(root_scrolling.Pass()); 2155 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2156 host_impl_->active_tree()->DidBecomeActive(); 2157 host_impl_->SetViewportSize(surface_size); 2158 DrawFrame(); 2159 { 2160 gfx::Vector2d scroll_delta(0, -10); 2161 EXPECT_EQ(InputHandler::ScrollStarted, 2162 host_impl_->ScrollBegin(gfx::Point(), 2163 InputHandler::NonBubblingGesture)); 2164 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2165 host_impl_->ScrollEnd(); 2166 2167 scoped_ptr<ScrollAndScaleSet> scroll_info = 2168 host_impl_->ProcessScrollDeltas(); 2169 2170 // The grand child should have scrolled up to its limit. 2171 LayerImpl* child = 2172 host_impl_->active_tree()->root_layer()->children()[0]->children()[0]; 2173 LayerImpl* grand_child = child->children()[0]; 2174 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2)); 2175 2176 // The child should not have scrolled. 2177 ExpectNone(*scroll_info.get(), child->id()); 2178 2179 // The next time we scroll we should only scroll the parent. 2180 scroll_delta = gfx::Vector2d(0, -3); 2181 EXPECT_EQ(InputHandler::ScrollStarted, 2182 host_impl_->ScrollBegin(gfx::Point(5, 5), 2183 InputHandler::NonBubblingGesture)); 2184 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2185 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2186 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); 2187 host_impl_->ScrollEnd(); 2188 2189 scroll_info = host_impl_->ProcessScrollDeltas(); 2190 2191 // The child should have scrolled up to its limit. 2192 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3)); 2193 2194 // The grand child should not have scrolled. 2195 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2)); 2196 2197 // After scrolling the parent, another scroll on the opposite direction 2198 // should still scroll the child. 2199 scroll_delta = gfx::Vector2d(0, 7); 2200 EXPECT_EQ(InputHandler::ScrollStarted, 2201 host_impl_->ScrollBegin(gfx::Point(5, 5), 2202 InputHandler::NonBubblingGesture)); 2203 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2204 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2205 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2206 host_impl_->ScrollEnd(); 2207 2208 scroll_info = host_impl_->ProcessScrollDeltas(); 2209 2210 // The grand child should have scrolled. 2211 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5)); 2212 2213 // The child should not have scrolled. 2214 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3)); 2215 2216 2217 // Scrolling should be adjusted from viewport space. 2218 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f); 2219 host_impl_->active_tree()->SetPageScaleDelta(1.f); 2220 2221 scroll_delta = gfx::Vector2d(0, -2); 2222 EXPECT_EQ(InputHandler::ScrollStarted, 2223 host_impl_->ScrollBegin(gfx::Point(1, 1), 2224 InputHandler::NonBubblingGesture)); 2225 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer()); 2226 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2227 host_impl_->ScrollEnd(); 2228 2229 scroll_info = host_impl_->ProcessScrollDeltas(); 2230 2231 // Should have scrolled by half the amount in layer space (5 - 2/2) 2232 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4)); 2233 } 2234 } 2235 2236 TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { 2237 // When we try to scroll a non-scrollable child layer, the scroll delta 2238 // should be applied to one of its ancestors if possible. 2239 gfx::Size surface_size(10, 10); 2240 gfx::Size content_size(20, 20); 2241 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size); 2242 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); 2243 2244 child->SetScrollable(false); 2245 root->AddChild(child.Pass()); 2246 2247 host_impl_->SetViewportSize(surface_size); 2248 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2249 host_impl_->active_tree()->DidBecomeActive(); 2250 DrawFrame(); 2251 { 2252 gfx::Vector2d scroll_delta(0, 4); 2253 EXPECT_EQ(InputHandler::ScrollStarted, 2254 host_impl_->ScrollBegin(gfx::Point(5, 5), 2255 InputHandler::Wheel)); 2256 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2257 host_impl_->ScrollEnd(); 2258 2259 scoped_ptr<ScrollAndScaleSet> scroll_info = 2260 host_impl_->ProcessScrollDeltas(); 2261 2262 // Only the root should have scrolled. 2263 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 2264 ExpectContains(*scroll_info.get(), 2265 host_impl_->active_tree()->root_layer()->id(), 2266 scroll_delta); 2267 } 2268 } 2269 2270 TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { 2271 gfx::Size surface_size(10, 10); 2272 host_impl_->active_tree()->SetRootLayer( 2273 CreateScrollableLayer(1, surface_size)); 2274 host_impl_->active_tree()->DidBecomeActive(); 2275 host_impl_->SetViewportSize(surface_size); 2276 2277 // Draw one frame and then immediately rebuild the layer tree to mimic a tree 2278 // synchronization. 2279 DrawFrame(); 2280 host_impl_->active_tree()->DetachLayerTree(); 2281 host_impl_->active_tree()->SetRootLayer( 2282 CreateScrollableLayer(2, surface_size)); 2283 host_impl_->active_tree()->DidBecomeActive(); 2284 2285 // Scrolling should still work even though we did not draw yet. 2286 EXPECT_EQ(InputHandler::ScrollStarted, 2287 host_impl_->ScrollBegin(gfx::Point(5, 5), 2288 InputHandler::Wheel)); 2289 } 2290 2291 TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { 2292 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 2293 2294 // Rotate the root layer 90 degrees counter-clockwise about its center. 2295 gfx::Transform rotate_transform; 2296 rotate_transform.Rotate(-90.0); 2297 host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform); 2298 2299 gfx::Size surface_size(50, 50); 2300 host_impl_->SetViewportSize(surface_size); 2301 DrawFrame(); 2302 2303 // Scroll to the right in screen coordinates with a gesture. 2304 gfx::Vector2d gesture_scroll_delta(10, 0); 2305 EXPECT_EQ(InputHandler::ScrollStarted, 2306 host_impl_->ScrollBegin(gfx::Point(), 2307 InputHandler::Gesture)); 2308 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 2309 host_impl_->ScrollEnd(); 2310 2311 // The layer should have scrolled down in its local coordinates. 2312 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2313 ExpectContains(*scroll_info.get(), 2314 scroll_layer->id(), 2315 gfx::Vector2d(0, gesture_scroll_delta.x())); 2316 2317 // Reset and scroll down with the wheel. 2318 scroll_layer->SetScrollDelta(gfx::Vector2dF()); 2319 gfx::Vector2d wheel_scroll_delta(0, 10); 2320 EXPECT_EQ(InputHandler::ScrollStarted, 2321 host_impl_->ScrollBegin(gfx::Point(), 2322 InputHandler::Wheel)); 2323 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta); 2324 host_impl_->ScrollEnd(); 2325 2326 // The layer should have scrolled down in its local coordinates. 2327 scroll_info = host_impl_->ProcessScrollDeltas(); 2328 ExpectContains(*scroll_info.get(), 2329 scroll_layer->id(), 2330 wheel_scroll_delta); 2331 } 2332 2333 TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { 2334 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 2335 int child_layer_id = 4; 2336 float child_layer_angle = -20.f; 2337 2338 // Create a child layer that is rotated to a non-axis-aligned angle. 2339 scoped_ptr<LayerImpl> child = CreateScrollableLayer( 2340 child_layer_id, 2341 scroll_layer->content_bounds()); 2342 gfx::Transform rotate_transform; 2343 rotate_transform.Translate(-50.0, -50.0); 2344 rotate_transform.Rotate(child_layer_angle); 2345 rotate_transform.Translate(50.0, 50.0); 2346 child->SetTransform(rotate_transform); 2347 2348 // Only allow vertical scrolling. 2349 child->SetMaxScrollOffset(gfx::Vector2d(0, child->content_bounds().height())); 2350 scroll_layer->AddChild(child.Pass()); 2351 2352 gfx::Size surface_size(50, 50); 2353 host_impl_->SetViewportSize(surface_size); 2354 DrawFrame(); 2355 { 2356 // Scroll down in screen coordinates with a gesture. 2357 gfx::Vector2d gesture_scroll_delta(0, 10); 2358 EXPECT_EQ(InputHandler::ScrollStarted, 2359 host_impl_->ScrollBegin(gfx::Point(1, 1), 2360 InputHandler::Gesture)); 2361 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 2362 host_impl_->ScrollEnd(); 2363 2364 // The child layer should have scrolled down in its local coordinates an 2365 // amount proportional to the angle between it and the input scroll delta. 2366 gfx::Vector2d expected_scroll_delta( 2367 0, 2368 gesture_scroll_delta.y() * 2369 std::cos(MathUtil::Deg2Rad(child_layer_angle))); 2370 scoped_ptr<ScrollAndScaleSet> scroll_info = 2371 host_impl_->ProcessScrollDeltas(); 2372 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); 2373 2374 // The root scroll layer should not have scrolled, because the input delta 2375 // was close to the layer's axis of movement. 2376 EXPECT_EQ(scroll_info->scrolls.size(), 1u); 2377 } 2378 { 2379 // Now reset and scroll the same amount horizontally. 2380 scroll_layer->children()[1]->SetScrollDelta( 2381 gfx::Vector2dF()); 2382 gfx::Vector2d gesture_scroll_delta(10, 0); 2383 EXPECT_EQ(InputHandler::ScrollStarted, 2384 host_impl_->ScrollBegin(gfx::Point(1, 1), 2385 InputHandler::Gesture)); 2386 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 2387 host_impl_->ScrollEnd(); 2388 2389 // The child layer should have scrolled down in its local coordinates an 2390 // amount proportional to the angle between it and the input scroll delta. 2391 gfx::Vector2d expected_scroll_delta( 2392 0, 2393 -gesture_scroll_delta.x() * 2394 std::sin(MathUtil::Deg2Rad(child_layer_angle))); 2395 scoped_ptr<ScrollAndScaleSet> scroll_info = 2396 host_impl_->ProcessScrollDeltas(); 2397 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); 2398 2399 // The root scroll layer should have scrolled more, since the input scroll 2400 // delta was mostly orthogonal to the child layer's vertical scroll axis. 2401 gfx::Vector2d expected_root_scroll_delta( 2402 gesture_scroll_delta.x() * 2403 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2), 2404 0); 2405 ExpectContains(*scroll_info.get(), 2406 scroll_layer->id(), 2407 expected_root_scroll_delta); 2408 } 2409 } 2410 2411 TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { 2412 LayerImpl* scroll_layer = 2413 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 2414 2415 // Scale the layer to twice its normal size. 2416 int scale = 2; 2417 gfx::Transform scale_transform; 2418 scale_transform.Scale(scale, scale); 2419 scroll_layer->SetTransform(scale_transform); 2420 2421 gfx::Size surface_size(50, 50); 2422 host_impl_->SetViewportSize(surface_size); 2423 DrawFrame(); 2424 2425 // Scroll down in screen coordinates with a gesture. 2426 gfx::Vector2d scroll_delta(0, 10); 2427 EXPECT_EQ(InputHandler::ScrollStarted, 2428 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2429 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2430 host_impl_->ScrollEnd(); 2431 2432 // The layer should have scrolled down in its local coordinates, but half the 2433 // amount. 2434 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2435 ExpectContains(*scroll_info.get(), 2436 scroll_layer->id(), 2437 gfx::Vector2d(0, scroll_delta.y() / scale)); 2438 2439 // Reset and scroll down with the wheel. 2440 scroll_layer->SetScrollDelta(gfx::Vector2dF()); 2441 gfx::Vector2d wheel_scroll_delta(0, 10); 2442 EXPECT_EQ(InputHandler::ScrollStarted, 2443 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 2444 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta); 2445 host_impl_->ScrollEnd(); 2446 2447 // The scale should not have been applied to the scroll delta. 2448 scroll_info = host_impl_->ProcessScrollDeltas(); 2449 ExpectContains(*scroll_info.get(), 2450 scroll_layer->id(), 2451 wheel_scroll_delta); 2452 } 2453 2454 class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { 2455 public: 2456 TestScrollOffsetDelegate() : page_scale_factor_(0.f) {} 2457 2458 virtual ~TestScrollOffsetDelegate() {} 2459 2460 virtual void SetMaxScrollOffset(gfx::Vector2dF max_scroll_offset) OVERRIDE { 2461 max_scroll_offset_ = max_scroll_offset; 2462 } 2463 2464 virtual void SetTotalScrollOffset(gfx::Vector2dF new_value) OVERRIDE { 2465 last_set_scroll_offset_ = new_value; 2466 } 2467 2468 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE { 2469 return getter_return_value_; 2470 } 2471 2472 virtual bool IsExternalFlingActive() const OVERRIDE { return false; } 2473 2474 virtual void SetTotalPageScaleFactor(float page_scale_factor) OVERRIDE { 2475 page_scale_factor_ = page_scale_factor; 2476 } 2477 2478 virtual void SetScrollableSize(gfx::SizeF scrollable_size) OVERRIDE { 2479 scrollable_size_ = scrollable_size; 2480 } 2481 2482 gfx::Vector2dF last_set_scroll_offset() { 2483 return last_set_scroll_offset_; 2484 } 2485 2486 void set_getter_return_value(gfx::Vector2dF value) { 2487 getter_return_value_ = value; 2488 } 2489 2490 gfx::Vector2dF max_scroll_offset() const { 2491 return max_scroll_offset_; 2492 } 2493 2494 gfx::SizeF scrollable_size() const { 2495 return scrollable_size_; 2496 } 2497 2498 float page_scale_factor() const { 2499 return page_scale_factor_; 2500 } 2501 2502 private: 2503 gfx::Vector2dF last_set_scroll_offset_; 2504 gfx::Vector2dF getter_return_value_; 2505 gfx::Vector2dF max_scroll_offset_; 2506 gfx::SizeF scrollable_size_; 2507 float page_scale_factor_; 2508 }; 2509 2510 TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { 2511 TestScrollOffsetDelegate scroll_delegate; 2512 host_impl_->SetViewportSize(gfx::Size(10, 20)); 2513 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 2514 2515 // Setting the delegate results in the current scroll offset being set. 2516 gfx::Vector2dF initial_scroll_delta(10.f, 10.f); 2517 scroll_layer->SetScrollOffset(gfx::Vector2d()); 2518 scroll_layer->SetScrollDelta(initial_scroll_delta); 2519 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate); 2520 EXPECT_EQ(initial_scroll_delta.ToString(), 2521 scroll_delegate.last_set_scroll_offset().ToString()); 2522 2523 // Setting the delegate results in the scrollable_size, max_scroll_offset and 2524 // page_scale being set. 2525 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size()); 2526 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate.max_scroll_offset()); 2527 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor()); 2528 2529 // Updating page scale immediately updates the delegate. 2530 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f); 2531 EXPECT_EQ(2.f, scroll_delegate.page_scale_factor()); 2532 host_impl_->active_tree()->SetPageScaleDelta(1.5f); 2533 EXPECT_EQ(3.f, scroll_delegate.page_scale_factor()); 2534 host_impl_->active_tree()->SetPageScaleDelta(1.f); 2535 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 2536 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor()); 2537 2538 // Scrolling should be relative to the offset as returned by the delegate. 2539 gfx::Vector2dF scroll_delta(0.f, 10.f); 2540 gfx::Vector2dF current_offset(7.f, 8.f); 2541 2542 scroll_delegate.set_getter_return_value(current_offset); 2543 EXPECT_EQ(InputHandler::ScrollStarted, 2544 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2545 2546 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2547 EXPECT_EQ(current_offset + scroll_delta, 2548 scroll_delegate.last_set_scroll_offset()); 2549 2550 current_offset = gfx::Vector2dF(42.f, 41.f); 2551 scroll_delegate.set_getter_return_value(current_offset); 2552 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2553 EXPECT_EQ(current_offset + scroll_delta, 2554 scroll_delegate.last_set_scroll_offset()); 2555 host_impl_->ScrollEnd(); 2556 2557 // Forces a full tree synchronization and ensures that the scroll delegate 2558 // sees the correct size of the new tree. 2559 gfx::Size new_size(42, 24); 2560 host_impl_->CreatePendingTree(); 2561 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size); 2562 host_impl_->ActivatePendingTree(); 2563 EXPECT_EQ(new_size, scroll_delegate.scrollable_size()); 2564 2565 // Un-setting the delegate should propagate the delegate's current offset to 2566 // the root scrollable layer. 2567 current_offset = gfx::Vector2dF(13.f, 12.f); 2568 scroll_delegate.set_getter_return_value(current_offset); 2569 host_impl_->SetRootLayerScrollOffsetDelegate(NULL); 2570 2571 EXPECT_EQ(current_offset.ToString(), 2572 scroll_layer->TotalScrollOffset().ToString()); 2573 } 2574 2575 TEST_F(LayerTreeHostImplTest, OverscrollRoot) { 2576 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 2577 host_impl_->SetViewportSize(gfx::Size(50, 50)); 2578 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 2579 DrawFrame(); 2580 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2581 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2582 2583 // In-bounds scrolling does not affect overscroll. 2584 EXPECT_EQ(InputHandler::ScrollStarted, 2585 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 2586 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 2587 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2588 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2589 2590 // Overscroll events are reflected immediately. 2591 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50)); 2592 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll()); 2593 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2594 2595 // In-bounds scrolling resets accumulated overscroll for the scrolled axes. 2596 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50)); 2597 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); 2598 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)); 2599 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 2600 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)); 2601 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 2602 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0)); 2603 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll()); 2604 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60)); 2605 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll()); 2606 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60)); 2607 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 2608 2609 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long 2610 // as no scroll occurs. 2611 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 2612 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll()); 2613 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 2614 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll()); 2615 // Overscroll resets on valid scroll. 2616 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 2617 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); 2618 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 2619 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 2620 host_impl_->ScrollEnd(); 2621 2622 EXPECT_EQ(InputHandler::ScrollStarted, 2623 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 2624 // Fling velocity is reflected immediately. 2625 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0)); 2626 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity()); 2627 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 2628 EXPECT_EQ(gfx::Vector2dF(0, -20), host_impl_->accumulated_root_overscroll()); 2629 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity()); 2630 } 2631 2632 2633 TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { 2634 // Scroll child layers beyond their maximum scroll range and make sure root 2635 // overscroll does not accumulate. 2636 gfx::Size surface_size(10, 10); 2637 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, surface_size); 2638 2639 scoped_ptr<LayerImpl> grand_child = CreateScrollableLayer(3, surface_size); 2640 grand_child->SetScrollOffset(gfx::Vector2d(0, 2)); 2641 2642 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); 2643 child->SetScrollOffset(gfx::Vector2d(0, 3)); 2644 child->AddChild(grand_child.Pass()); 2645 2646 root->AddChild(child.Pass()); 2647 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2648 host_impl_->active_tree()->DidBecomeActive(); 2649 host_impl_->SetViewportSize(surface_size); 2650 DrawFrame(); 2651 { 2652 gfx::Vector2d scroll_delta(0, -10); 2653 EXPECT_EQ(InputHandler::ScrollStarted, 2654 host_impl_->ScrollBegin(gfx::Point(), 2655 InputHandler::NonBubblingGesture)); 2656 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2657 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2658 host_impl_->ScrollEnd(); 2659 2660 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; 2661 LayerImpl* grand_child = child->children()[0]; 2662 2663 // The next time we scroll we should only scroll the parent, but overscroll 2664 // should still not reach the root layer. 2665 scroll_delta = gfx::Vector2d(0, -30); 2666 EXPECT_EQ(InputHandler::ScrollStarted, 2667 host_impl_->ScrollBegin(gfx::Point(5, 5), 2668 InputHandler::NonBubblingGesture)); 2669 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2670 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2671 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2672 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); 2673 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2674 host_impl_->ScrollEnd(); 2675 2676 // After scrolling the parent, another scroll on the opposite direction 2677 // should scroll the child, resetting the fling velocity. 2678 scroll_delta = gfx::Vector2d(0, 70); 2679 host_impl_->NotifyCurrentFlingVelocity(gfx::Vector2dF(10, 0)); 2680 EXPECT_EQ(gfx::Vector2dF(10, 0), host_impl_->current_fling_velocity()); 2681 EXPECT_EQ(InputHandler::ScrollStarted, 2682 host_impl_->ScrollBegin(gfx::Point(5, 5), 2683 InputHandler::NonBubblingGesture)); 2684 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2685 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2686 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2687 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2688 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2689 host_impl_->ScrollEnd(); 2690 } 2691 } 2692 2693 TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { 2694 // When we try to scroll a non-scrollable child layer, the scroll delta 2695 // should be applied to one of its ancestors if possible. Overscroll should 2696 // be reflected only when it has bubbled up to the root scrolling layer. 2697 gfx::Size surface_size(10, 10); 2698 gfx::Size content_size(20, 20); 2699 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size); 2700 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); 2701 2702 child->SetScrollable(false); 2703 root->AddChild(child.Pass()); 2704 2705 host_impl_->SetViewportSize(surface_size); 2706 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2707 host_impl_->active_tree()->DidBecomeActive(); 2708 DrawFrame(); 2709 { 2710 gfx::Vector2d scroll_delta(0, 8); 2711 EXPECT_EQ(InputHandler::ScrollStarted, 2712 host_impl_->ScrollBegin(gfx::Point(5, 5), 2713 InputHandler::Wheel)); 2714 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2715 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2716 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2717 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll()); 2718 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2719 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll()); 2720 host_impl_->ScrollEnd(); 2721 } 2722 } 2723 2724 TEST_F(LayerTreeHostImplTest, OverscrollAlways) { 2725 LayerTreeSettings settings; 2726 settings.always_overscroll = true; 2727 CreateHostImpl(settings, CreateOutputSurface()); 2728 2729 SetupScrollAndContentsLayers(gfx::Size(50, 50)); 2730 host_impl_->SetViewportSize(gfx::Size(50, 50)); 2731 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 2732 DrawFrame(); 2733 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 2734 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2735 2736 // Even though the layer can't scroll the overscroll still happens. 2737 EXPECT_EQ(InputHandler::ScrollStarted, 2738 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 2739 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 2740 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll()); 2741 EXPECT_EQ(gfx::Vector2dF(), host_impl_->current_fling_velocity()); 2742 } 2743 2744 class BlendStateCheckLayer : public LayerImpl { 2745 public: 2746 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, 2747 int id, 2748 ResourceProvider* resource_provider) { 2749 return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl, 2750 id, 2751 resource_provider)); 2752 } 2753 2754 virtual void AppendQuads(QuadSink* quad_sink, 2755 AppendQuadsData* append_quads_data) OVERRIDE { 2756 quads_appended_ = true; 2757 2758 gfx::Rect opaque_rect; 2759 if (contents_opaque()) 2760 opaque_rect = quad_rect_; 2761 else 2762 opaque_rect = opaque_content_rect_; 2763 2764 SharedQuadState* shared_quad_state = 2765 quad_sink->UseSharedQuadState(CreateSharedQuadState()); 2766 scoped_ptr<TileDrawQuad> test_blending_draw_quad = TileDrawQuad::Create(); 2767 test_blending_draw_quad->SetNew(shared_quad_state, 2768 quad_rect_, 2769 opaque_rect, 2770 resource_id_, 2771 gfx::RectF(0.f, 0.f, 1.f, 1.f), 2772 gfx::Size(1, 1), 2773 false); 2774 test_blending_draw_quad->visible_rect = quad_visible_rect_; 2775 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending()); 2776 EXPECT_EQ(has_render_surface_, !!render_surface()); 2777 quad_sink->Append(test_blending_draw_quad.PassAs<DrawQuad>(), 2778 append_quads_data); 2779 } 2780 2781 void SetExpectation(bool blend, bool has_render_surface) { 2782 blend_ = blend; 2783 has_render_surface_ = has_render_surface; 2784 quads_appended_ = false; 2785 } 2786 2787 bool quads_appended() const { return quads_appended_; } 2788 2789 void SetQuadRect(gfx::Rect rect) { quad_rect_ = rect; } 2790 void SetQuadVisibleRect(gfx::Rect rect) { quad_visible_rect_ = rect; } 2791 void SetOpaqueContentRect(gfx::Rect rect) { opaque_content_rect_ = rect; } 2792 2793 private: 2794 BlendStateCheckLayer(LayerTreeImpl* tree_impl, 2795 int id, 2796 ResourceProvider* resource_provider) 2797 : LayerImpl(tree_impl, id), 2798 blend_(false), 2799 has_render_surface_(false), 2800 quads_appended_(false), 2801 quad_rect_(5, 5, 5, 5), 2802 quad_visible_rect_(5, 5, 5, 5), 2803 resource_id_(resource_provider->CreateResource( 2804 gfx::Size(1, 1), 2805 GL_CLAMP_TO_EDGE, 2806 ResourceProvider::TextureUsageAny, 2807 RGBA_8888)) { 2808 resource_provider->AllocateForTesting(resource_id_); 2809 SetAnchorPoint(gfx::PointF()); 2810 SetBounds(gfx::Size(10, 10)); 2811 SetContentBounds(gfx::Size(10, 10)); 2812 SetDrawsContent(true); 2813 } 2814 2815 bool blend_; 2816 bool has_render_surface_; 2817 bool quads_appended_; 2818 gfx::Rect quad_rect_; 2819 gfx::Rect opaque_content_rect_; 2820 gfx::Rect quad_visible_rect_; 2821 ResourceProvider::ResourceId resource_id_; 2822 }; 2823 2824 TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { 2825 { 2826 scoped_ptr<LayerImpl> root = 2827 LayerImpl::Create(host_impl_->active_tree(), 1); 2828 root->SetAnchorPoint(gfx::PointF()); 2829 root->SetBounds(gfx::Size(10, 10)); 2830 root->SetContentBounds(root->bounds()); 2831 root->SetDrawsContent(false); 2832 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2833 } 2834 LayerImpl* root = host_impl_->active_tree()->root_layer(); 2835 2836 root->AddChild( 2837 BlendStateCheckLayer::Create(host_impl_->active_tree(), 2838 2, 2839 host_impl_->resource_provider())); 2840 BlendStateCheckLayer* layer1 = 2841 static_cast<BlendStateCheckLayer*>(root->children()[0]); 2842 layer1->SetPosition(gfx::PointF(2.f, 2.f)); 2843 2844 LayerTreeHostImpl::FrameData frame; 2845 2846 // Opaque layer, drawn without blending. 2847 layer1->SetContentsOpaque(true); 2848 layer1->SetExpectation(false, false); 2849 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2850 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2851 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2852 EXPECT_TRUE(layer1->quads_appended()); 2853 host_impl_->DidDrawAllLayers(frame); 2854 2855 // Layer with translucent content and painting, so drawn with blending. 2856 layer1->SetContentsOpaque(false); 2857 layer1->SetExpectation(true, false); 2858 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2859 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2860 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2861 EXPECT_TRUE(layer1->quads_appended()); 2862 host_impl_->DidDrawAllLayers(frame); 2863 2864 // Layer with translucent opacity, drawn with blending. 2865 layer1->SetContentsOpaque(true); 2866 layer1->SetOpacity(0.5f); 2867 layer1->SetExpectation(true, false); 2868 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2869 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2870 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2871 EXPECT_TRUE(layer1->quads_appended()); 2872 host_impl_->DidDrawAllLayers(frame); 2873 2874 // Layer with translucent opacity and painting, drawn with blending. 2875 layer1->SetContentsOpaque(true); 2876 layer1->SetOpacity(0.5f); 2877 layer1->SetExpectation(true, false); 2878 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2879 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2880 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2881 EXPECT_TRUE(layer1->quads_appended()); 2882 host_impl_->DidDrawAllLayers(frame); 2883 2884 layer1->AddChild( 2885 BlendStateCheckLayer::Create(host_impl_->active_tree(), 2886 3, 2887 host_impl_->resource_provider())); 2888 BlendStateCheckLayer* layer2 = 2889 static_cast<BlendStateCheckLayer*>(layer1->children()[0]); 2890 layer2->SetPosition(gfx::PointF(4.f, 4.f)); 2891 2892 // 2 opaque layers, drawn without blending. 2893 layer1->SetContentsOpaque(true); 2894 layer1->SetOpacity(1.f); 2895 layer1->SetExpectation(false, false); 2896 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2897 layer2->SetContentsOpaque(true); 2898 layer2->SetOpacity(1.f); 2899 layer2->SetExpectation(false, false); 2900 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2901 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2902 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2903 EXPECT_TRUE(layer1->quads_appended()); 2904 EXPECT_TRUE(layer2->quads_appended()); 2905 host_impl_->DidDrawAllLayers(frame); 2906 2907 // Parent layer with translucent content, drawn with blending. 2908 // Child layer with opaque content, drawn without blending. 2909 layer1->SetContentsOpaque(false); 2910 layer1->SetExpectation(true, false); 2911 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2912 layer2->SetExpectation(false, false); 2913 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2914 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2915 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2916 EXPECT_TRUE(layer1->quads_appended()); 2917 EXPECT_TRUE(layer2->quads_appended()); 2918 host_impl_->DidDrawAllLayers(frame); 2919 2920 // Parent layer with translucent content but opaque painting, drawn without 2921 // blending. 2922 // Child layer with opaque content, drawn without blending. 2923 layer1->SetContentsOpaque(true); 2924 layer1->SetExpectation(false, false); 2925 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2926 layer2->SetExpectation(false, false); 2927 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2928 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2929 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2930 EXPECT_TRUE(layer1->quads_appended()); 2931 EXPECT_TRUE(layer2->quads_appended()); 2932 host_impl_->DidDrawAllLayers(frame); 2933 2934 // Parent layer with translucent opacity and opaque content. Since it has a 2935 // drawing child, it's drawn to a render surface which carries the opacity, 2936 // so it's itself drawn without blending. 2937 // Child layer with opaque content, drawn without blending (parent surface 2938 // carries the inherited opacity). 2939 layer1->SetContentsOpaque(true); 2940 layer1->SetOpacity(0.5f); 2941 layer1->SetExpectation(false, true); 2942 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2943 layer2->SetExpectation(false, false); 2944 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2945 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2946 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2947 EXPECT_TRUE(layer1->quads_appended()); 2948 EXPECT_TRUE(layer2->quads_appended()); 2949 host_impl_->DidDrawAllLayers(frame); 2950 2951 // Draw again, but with child non-opaque, to make sure 2952 // layer1 not culled. 2953 layer1->SetContentsOpaque(true); 2954 layer1->SetOpacity(1.f); 2955 layer1->SetExpectation(false, false); 2956 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2957 layer2->SetContentsOpaque(true); 2958 layer2->SetOpacity(0.5f); 2959 layer2->SetExpectation(true, false); 2960 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2961 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2962 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2963 EXPECT_TRUE(layer1->quads_appended()); 2964 EXPECT_TRUE(layer2->quads_appended()); 2965 host_impl_->DidDrawAllLayers(frame); 2966 2967 // A second way of making the child non-opaque. 2968 layer1->SetContentsOpaque(true); 2969 layer1->SetOpacity(1.f); 2970 layer1->SetExpectation(false, false); 2971 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2972 layer2->SetContentsOpaque(false); 2973 layer2->SetOpacity(1.f); 2974 layer2->SetExpectation(true, false); 2975 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2976 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2977 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2978 EXPECT_TRUE(layer1->quads_appended()); 2979 EXPECT_TRUE(layer2->quads_appended()); 2980 host_impl_->DidDrawAllLayers(frame); 2981 2982 // And when the layer says its not opaque but is painted opaque, it is not 2983 // blended. 2984 layer1->SetContentsOpaque(true); 2985 layer1->SetOpacity(1.f); 2986 layer1->SetExpectation(false, false); 2987 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 2988 layer2->SetContentsOpaque(true); 2989 layer2->SetOpacity(1.f); 2990 layer2->SetExpectation(false, false); 2991 layer2->set_update_rect(gfx::RectF(layer1->content_bounds())); 2992 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 2993 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2994 EXPECT_TRUE(layer1->quads_appended()); 2995 EXPECT_TRUE(layer2->quads_appended()); 2996 host_impl_->DidDrawAllLayers(frame); 2997 2998 // Layer with partially opaque contents, drawn with blending. 2999 layer1->SetContentsOpaque(false); 3000 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 3001 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5)); 3002 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 3003 layer1->SetExpectation(true, false); 3004 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 3005 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3006 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3007 EXPECT_TRUE(layer1->quads_appended()); 3008 host_impl_->DidDrawAllLayers(frame); 3009 3010 // Layer with partially opaque contents partially culled, drawn with blending. 3011 layer1->SetContentsOpaque(false); 3012 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 3013 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2)); 3014 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 3015 layer1->SetExpectation(true, false); 3016 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 3017 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3018 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3019 EXPECT_TRUE(layer1->quads_appended()); 3020 host_impl_->DidDrawAllLayers(frame); 3021 3022 // Layer with partially opaque contents culled, drawn with blending. 3023 layer1->SetContentsOpaque(false); 3024 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 3025 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5)); 3026 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 3027 layer1->SetExpectation(true, false); 3028 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 3029 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3030 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3031 EXPECT_TRUE(layer1->quads_appended()); 3032 host_impl_->DidDrawAllLayers(frame); 3033 3034 // Layer with partially opaque contents and translucent contents culled, drawn 3035 // without blending. 3036 layer1->SetContentsOpaque(false); 3037 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 3038 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5)); 3039 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 3040 layer1->SetExpectation(false, false); 3041 layer1->set_update_rect(gfx::RectF(layer1->content_bounds())); 3042 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3043 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3044 EXPECT_TRUE(layer1->quads_appended()); 3045 host_impl_->DidDrawAllLayers(frame); 3046 } 3047 3048 class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { 3049 protected: 3050 LayerTreeHostImplViewportCoveredTest() : 3051 gutter_quad_material_(DrawQuad::SOLID_COLOR), 3052 child_(NULL), 3053 did_activate_pending_tree_(false) {} 3054 3055 scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool always_draw) { 3056 if (always_draw) { 3057 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d() 3058 .PassAs<OutputSurface>(); 3059 } 3060 return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); 3061 } 3062 3063 void SetupActiveTreeLayers() { 3064 host_impl_->active_tree()->set_background_color(SK_ColorGRAY); 3065 host_impl_->active_tree()->SetRootLayer( 3066 LayerImpl::Create(host_impl_->active_tree(), 1)); 3067 host_impl_->active_tree()->root_layer()->AddChild( 3068 BlendStateCheckLayer::Create(host_impl_->active_tree(), 3069 2, 3070 host_impl_->resource_provider())); 3071 child_ = static_cast<BlendStateCheckLayer*>( 3072 host_impl_->active_tree()->root_layer()->children()[0]); 3073 child_->SetExpectation(false, false); 3074 child_->SetContentsOpaque(true); 3075 } 3076 3077 // Expect no gutter rects. 3078 void TestLayerCoversFullViewport() { 3079 gfx::Rect layer_rect(viewport_size_); 3080 child_->SetPosition(layer_rect.origin()); 3081 child_->SetBounds(layer_rect.size()); 3082 child_->SetContentBounds(layer_rect.size()); 3083 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 3084 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 3085 3086 LayerTreeHostImpl::FrameData frame; 3087 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3088 ASSERT_EQ(1u, frame.render_passes.size()); 3089 3090 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list)); 3091 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 3092 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 3093 3094 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 3095 host_impl_->DidDrawAllLayers(frame); 3096 } 3097 3098 // Expect fullscreen gutter rect. 3099 void TestEmptyLayer() { 3100 gfx::Rect layer_rect(0, 0, 0, 0); 3101 child_->SetPosition(layer_rect.origin()); 3102 child_->SetBounds(layer_rect.size()); 3103 child_->SetContentBounds(layer_rect.size()); 3104 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 3105 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 3106 3107 LayerTreeHostImpl::FrameData frame; 3108 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3109 ASSERT_EQ(1u, frame.render_passes.size()); 3110 3111 EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list)); 3112 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 3113 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 3114 3115 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 3116 host_impl_->DidDrawAllLayers(frame); 3117 } 3118 3119 // Expect four surrounding gutter rects. 3120 void TestLayerInMiddleOfViewport() { 3121 gfx::Rect layer_rect(500, 500, 200, 200); 3122 child_->SetPosition(layer_rect.origin()); 3123 child_->SetBounds(layer_rect.size()); 3124 child_->SetContentBounds(layer_rect.size()); 3125 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 3126 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 3127 3128 LayerTreeHostImpl::FrameData frame; 3129 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3130 ASSERT_EQ(1u, frame.render_passes.size()); 3131 3132 EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list)); 3133 EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size()); 3134 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 3135 3136 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 3137 host_impl_->DidDrawAllLayers(frame); 3138 } 3139 3140 // Expect no gutter rects. 3141 void TestLayerIsLargerThanViewport() { 3142 gfx::Rect layer_rect(viewport_size_.width() + 10, 3143 viewport_size_.height() + 10); 3144 child_->SetPosition(layer_rect.origin()); 3145 child_->SetBounds(layer_rect.size()); 3146 child_->SetContentBounds(layer_rect.size()); 3147 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 3148 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 3149 3150 LayerTreeHostImpl::FrameData frame; 3151 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3152 ASSERT_EQ(1u, frame.render_passes.size()); 3153 3154 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list)); 3155 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 3156 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 3157 3158 host_impl_->DidDrawAllLayers(frame); 3159 } 3160 3161 virtual void DidActivatePendingTree() OVERRIDE { 3162 did_activate_pending_tree_ = true; 3163 } 3164 3165 void set_gutter_quad_material(DrawQuad::Material material) { 3166 gutter_quad_material_ = material; 3167 } 3168 void set_gutter_texture_size(gfx::Size gutter_texture_size) { 3169 gutter_texture_size_ = gutter_texture_size; 3170 } 3171 3172 protected: 3173 size_t CountGutterQuads(const QuadList& quad_list) { 3174 size_t num_gutter_quads = 0; 3175 for (size_t i = 0; i < quad_list.size(); ++i) { 3176 num_gutter_quads += (quad_list[i]->material == 3177 gutter_quad_material_) ? 1 : 0; 3178 } 3179 return num_gutter_quads; 3180 } 3181 3182 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) { 3183 LayerTestCommon::VerifyQuadsExactlyCoverRect( 3184 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_))); 3185 } 3186 3187 // Make sure that the texture coordinates match their expectations. 3188 void ValidateTextureDrawQuads(const QuadList& quad_list) { 3189 for (size_t i = 0; i < quad_list.size(); ++i) { 3190 if (quad_list[i]->material != DrawQuad::TEXTURE_CONTENT) 3191 continue; 3192 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(quad_list[i]); 3193 gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize( 3194 gutter_texture_size_, host_impl_->device_scale_factor()); 3195 EXPECT_EQ(quad->uv_top_left.x(), 3196 quad->rect.x() / gutter_texture_size_pixels.width()); 3197 EXPECT_EQ(quad->uv_top_left.y(), 3198 quad->rect.y() / gutter_texture_size_pixels.height()); 3199 EXPECT_EQ(quad->uv_bottom_right.x(), 3200 quad->rect.right() / gutter_texture_size_pixels.width()); 3201 EXPECT_EQ(quad->uv_bottom_right.y(), 3202 quad->rect.bottom() / gutter_texture_size_pixels.height()); 3203 } 3204 } 3205 3206 gfx::Size DipSizeToPixelSize(gfx::Size size) { 3207 return gfx::ToRoundedSize( 3208 gfx::ScaleSize(size, host_impl_->device_scale_factor())); 3209 } 3210 3211 DrawQuad::Material gutter_quad_material_; 3212 gfx::Size gutter_texture_size_; 3213 gfx::Size viewport_size_; 3214 BlendStateCheckLayer* child_; 3215 bool did_activate_pending_tree_; 3216 }; 3217 3218 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { 3219 viewport_size_ = gfx::Size(1000, 1000); 3220 3221 bool always_draw = false; 3222 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 3223 3224 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3225 SetupActiveTreeLayers(); 3226 TestLayerCoversFullViewport(); 3227 TestEmptyLayer(); 3228 TestLayerInMiddleOfViewport(); 3229 TestLayerIsLargerThanViewport(); 3230 } 3231 3232 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { 3233 viewport_size_ = gfx::Size(1000, 1000); 3234 3235 bool always_draw = false; 3236 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 3237 3238 host_impl_->SetDeviceScaleFactor(2.f); 3239 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3240 SetupActiveTreeLayers(); 3241 TestLayerCoversFullViewport(); 3242 TestEmptyLayer(); 3243 TestLayerInMiddleOfViewport(); 3244 TestLayerIsLargerThanViewport(); 3245 } 3246 3247 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) { 3248 viewport_size_ = gfx::Size(1000, 1000); 3249 3250 bool always_draw = false; 3251 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 3252 3253 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3254 SetupActiveTreeLayers(); 3255 3256 SkBitmap skbitmap; 3257 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 3258 skbitmap.allocPixels(); 3259 skbitmap.setImmutable(); 3260 3261 // Specify an overhang bitmap to use. 3262 UIResourceBitmap ui_resource_bitmap(skbitmap); 3263 ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT); 3264 UIResourceId ui_resource_id = 12345; 3265 host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap); 3266 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32)); 3267 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT); 3268 set_gutter_texture_size(gfx::Size(32, 32)); 3269 3270 TestLayerCoversFullViewport(); 3271 TestEmptyLayer(); 3272 TestLayerInMiddleOfViewport(); 3273 TestLayerIsLargerThanViewport(); 3274 3275 // Change the resource size. 3276 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16)); 3277 set_gutter_texture_size(gfx::Size(128, 16)); 3278 3279 TestLayerCoversFullViewport(); 3280 TestEmptyLayer(); 3281 TestLayerInMiddleOfViewport(); 3282 TestLayerIsLargerThanViewport(); 3283 3284 // Change the device scale factor 3285 host_impl_->SetDeviceScaleFactor(2.f); 3286 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3287 3288 TestLayerCoversFullViewport(); 3289 TestEmptyLayer(); 3290 TestLayerInMiddleOfViewport(); 3291 TestLayerIsLargerThanViewport(); 3292 } 3293 3294 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { 3295 viewport_size_ = gfx::Size(1000, 1000); 3296 3297 bool always_draw = true; 3298 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 3299 3300 // Pending tree to force active_tree size invalid. Not used otherwise. 3301 host_impl_->CreatePendingTree(); 3302 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3303 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 3304 3305 SetupActiveTreeLayers(); 3306 TestEmptyLayer(); 3307 TestLayerInMiddleOfViewport(); 3308 TestLayerIsLargerThanViewport(); 3309 } 3310 3311 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { 3312 viewport_size_ = gfx::Size(1000, 1000); 3313 3314 bool always_draw = true; 3315 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 3316 3317 // Set larger viewport and activate it to active tree. 3318 host_impl_->CreatePendingTree(); 3319 gfx::Size larger_viewport(viewport_size_.width() + 100, 3320 viewport_size_.height() + 100); 3321 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport)); 3322 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 3323 host_impl_->ActivatePendingTree(); 3324 EXPECT_TRUE(did_activate_pending_tree_); 3325 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid()); 3326 3327 // Shrink pending tree viewport without activating. 3328 host_impl_->CreatePendingTree(); 3329 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 3330 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 3331 3332 SetupActiveTreeLayers(); 3333 TestEmptyLayer(); 3334 TestLayerInMiddleOfViewport(); 3335 TestLayerIsLargerThanViewport(); 3336 } 3337 3338 class FakeDrawableLayerImpl: public LayerImpl { 3339 public: 3340 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 3341 return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id)); 3342 } 3343 protected: 3344 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id) 3345 : LayerImpl(tree_impl, id) {} 3346 }; 3347 3348 // Only reshape when we know we are going to draw. Otherwise, the reshape 3349 // can leave the window at the wrong size if we never draw and the proper 3350 // viewport size is never set. 3351 TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) { 3352 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); 3353 scoped_ptr<OutputSurface> output_surface( 3354 FakeOutputSurface::Create3d(provider)); 3355 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 3356 3357 scoped_ptr<LayerImpl> root = 3358 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); 3359 root->SetAnchorPoint(gfx::PointF()); 3360 root->SetBounds(gfx::Size(10, 10)); 3361 root->SetContentBounds(gfx::Size(10, 10)); 3362 root->SetDrawsContent(true); 3363 host_impl_->active_tree()->SetRootLayer(root.Pass()); 3364 EXPECT_FALSE(provider->TestContext3d()->reshape_called()); 3365 provider->TestContext3d()->clear_reshape_called(); 3366 3367 LayerTreeHostImpl::FrameData frame; 3368 host_impl_->SetViewportSize(gfx::Size(10, 10)); 3369 host_impl_->SetDeviceScaleFactor(1.f); 3370 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3371 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3372 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 3373 EXPECT_EQ(provider->TestContext3d()->width(), 10); 3374 EXPECT_EQ(provider->TestContext3d()->height(), 10); 3375 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f); 3376 host_impl_->DidDrawAllLayers(frame); 3377 provider->TestContext3d()->clear_reshape_called(); 3378 3379 host_impl_->SetViewportSize(gfx::Size(20, 30)); 3380 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3381 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3382 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 3383 EXPECT_EQ(provider->TestContext3d()->width(), 20); 3384 EXPECT_EQ(provider->TestContext3d()->height(), 30); 3385 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f); 3386 host_impl_->DidDrawAllLayers(frame); 3387 provider->TestContext3d()->clear_reshape_called(); 3388 3389 host_impl_->SetDeviceScaleFactor(2.f); 3390 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3391 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3392 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 3393 EXPECT_EQ(provider->TestContext3d()->width(), 20); 3394 EXPECT_EQ(provider->TestContext3d()->height(), 30); 3395 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 2.f); 3396 host_impl_->DidDrawAllLayers(frame); 3397 provider->TestContext3d()->clear_reshape_called(); 3398 } 3399 3400 // Make sure damage tracking propagates all the way to the graphics context, 3401 // where it should request to swap only the sub-buffer that is damaged. 3402 TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { 3403 scoped_refptr<TestContextProvider> context_provider( 3404 TestContextProvider::Create()); 3405 context_provider->BindToCurrentThread(); 3406 context_provider->TestContext3d()->set_have_post_sub_buffer(true); 3407 3408 scoped_ptr<OutputSurface> output_surface( 3409 FakeOutputSurface::Create3d(context_provider)); 3410 3411 // This test creates its own LayerTreeHostImpl, so 3412 // that we can force partial swap enabled. 3413 LayerTreeSettings settings; 3414 settings.partial_swap_enabled = true; 3415 scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl = 3416 LayerTreeHostImpl::Create( 3417 settings, this, &proxy_, &stats_instrumentation_, NULL, 0); 3418 layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); 3419 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); 3420 3421 scoped_ptr<LayerImpl> root = 3422 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); 3423 scoped_ptr<LayerImpl> child = 3424 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); 3425 child->SetPosition(gfx::PointF(12.f, 13.f)); 3426 child->SetAnchorPoint(gfx::PointF()); 3427 child->SetBounds(gfx::Size(14, 15)); 3428 child->SetContentBounds(gfx::Size(14, 15)); 3429 child->SetDrawsContent(true); 3430 root->SetAnchorPoint(gfx::PointF()); 3431 root->SetBounds(gfx::Size(500, 500)); 3432 root->SetContentBounds(gfx::Size(500, 500)); 3433 root->SetDrawsContent(true); 3434 root->AddChild(child.Pass()); 3435 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass()); 3436 3437 LayerTreeHostImpl::FrameData frame; 3438 3439 // First frame, the entire screen should get swapped. 3440 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect())); 3441 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 3442 layer_tree_host_impl->DidDrawAllLayers(frame); 3443 layer_tree_host_impl->SwapBuffers(frame); 3444 EXPECT_EQ(TestContextSupport::SWAP, 3445 context_provider->support()->last_swap_type()); 3446 3447 // Second frame, only the damaged area should get swapped. Damage should be 3448 // the union of old and new child rects. 3449 // expected damage rect: gfx::Rect(26, 28); 3450 // expected swap rect: vertically flipped, with origin at bottom left corner. 3451 layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition( 3452 gfx::PointF()); 3453 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect())); 3454 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 3455 host_impl_->DidDrawAllLayers(frame); 3456 layer_tree_host_impl->SwapBuffers(frame); 3457 3458 // Make sure that partial swap is constrained to the viewport dimensions 3459 // expected damage rect: gfx::Rect(500, 500); 3460 // expected swap rect: flipped damage rect, but also clamped to viewport 3461 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP, 3462 context_provider->support()->last_swap_type()); 3463 gfx::Rect expected_swap_rect(0, 500-28, 26, 28); 3464 EXPECT_EQ(expected_swap_rect.ToString(), 3465 context_provider->support()-> 3466 last_partial_swap_rect().ToString()); 3467 3468 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10)); 3469 // This will damage everything. 3470 layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor( 3471 SK_ColorBLACK); 3472 EXPECT_TRUE(layer_tree_host_impl->PrepareToDraw(&frame, gfx::Rect())); 3473 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 3474 host_impl_->DidDrawAllLayers(frame); 3475 layer_tree_host_impl->SwapBuffers(frame); 3476 3477 EXPECT_EQ(TestContextSupport::SWAP, 3478 context_provider->support()->last_swap_type()); 3479 } 3480 3481 TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { 3482 scoped_ptr<LayerImpl> root = 3483 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); 3484 scoped_ptr<LayerImpl> child = 3485 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2); 3486 child->SetAnchorPoint(gfx::PointF()); 3487 child->SetBounds(gfx::Size(10, 10)); 3488 child->SetContentBounds(gfx::Size(10, 10)); 3489 child->SetDrawsContent(true); 3490 root->SetAnchorPoint(gfx::PointF()); 3491 root->SetBounds(gfx::Size(10, 10)); 3492 root->SetContentBounds(gfx::Size(10, 10)); 3493 root->SetDrawsContent(true); 3494 root->SetForceRenderSurface(true); 3495 root->AddChild(child.Pass()); 3496 3497 host_impl_->active_tree()->SetRootLayer(root.Pass()); 3498 3499 LayerTreeHostImpl::FrameData frame; 3500 3501 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3502 EXPECT_EQ(1u, frame.render_surface_layer_list->size()); 3503 EXPECT_EQ(1u, frame.render_passes.size()); 3504 host_impl_->DidDrawAllLayers(frame); 3505 } 3506 3507 class FakeLayerWithQuads : public LayerImpl { 3508 public: 3509 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 3510 return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id)); 3511 } 3512 3513 virtual void AppendQuads(QuadSink* quad_sink, 3514 AppendQuadsData* append_quads_data) OVERRIDE { 3515 SharedQuadState* shared_quad_state = 3516 quad_sink->UseSharedQuadState(CreateSharedQuadState()); 3517 3518 SkColor gray = SkColorSetRGB(100, 100, 100); 3519 gfx::Rect quad_rect(content_bounds()); 3520 scoped_ptr<SolidColorDrawQuad> my_quad = SolidColorDrawQuad::Create(); 3521 my_quad->SetNew(shared_quad_state, quad_rect, gray, false); 3522 quad_sink->Append(my_quad.PassAs<DrawQuad>(), append_quads_data); 3523 } 3524 3525 private: 3526 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id) 3527 : LayerImpl(tree_impl, id) {} 3528 }; 3529 3530 class MockContext : public TestWebGraphicsContext3D { 3531 public: 3532 MOCK_METHOD1(useProgram, void(blink::WebGLId program)); 3533 MOCK_METHOD5(uniform4f, void(blink::WGC3Dint location, 3534 blink::WGC3Dfloat x, 3535 blink::WGC3Dfloat y, 3536 blink::WGC3Dfloat z, 3537 blink::WGC3Dfloat w)); 3538 MOCK_METHOD4(uniformMatrix4fv, void(blink::WGC3Dint location, 3539 blink::WGC3Dsizei count, 3540 blink::WGC3Dboolean transpose, 3541 const blink::WGC3Dfloat* value)); 3542 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode, 3543 blink::WGC3Dsizei count, 3544 blink::WGC3Denum type, 3545 blink::WGC3Dintptr offset)); 3546 MOCK_METHOD0(getRequestableExtensionsCHROMIUM, blink::WebString()); 3547 MOCK_METHOD1(enable, void(blink::WGC3Denum cap)); 3548 MOCK_METHOD1(disable, void(blink::WGC3Denum cap)); 3549 MOCK_METHOD4(scissor, void(blink::WGC3Dint x, 3550 blink::WGC3Dint y, 3551 blink::WGC3Dsizei width, 3552 blink::WGC3Dsizei height)); 3553 }; 3554 3555 class MockContextHarness { 3556 private: 3557 MockContext* context_; 3558 3559 public: 3560 explicit MockContextHarness(MockContext* context) 3561 : context_(context) { 3562 context_->set_have_post_sub_buffer(true); 3563 3564 // Catch "uninteresting" calls 3565 EXPECT_CALL(*context_, useProgram(_)) 3566 .Times(0); 3567 3568 EXPECT_CALL(*context_, drawElements(_, _, _, _)) 3569 .Times(0); 3570 3571 // These are not asserted 3572 EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _)) 3573 .WillRepeatedly(Return()); 3574 3575 EXPECT_CALL(*context_, uniform4f(_, _, _, _, _)) 3576 .WillRepeatedly(Return()); 3577 3578 // Any un-sanctioned calls to enable() are OK 3579 EXPECT_CALL(*context_, enable(_)) 3580 .WillRepeatedly(Return()); 3581 3582 // Any un-sanctioned calls to disable() are OK 3583 EXPECT_CALL(*context_, disable(_)) 3584 .WillRepeatedly(Return()); 3585 } 3586 3587 void MustDrawSolidQuad() { 3588 EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0)) 3589 .WillOnce(Return()) 3590 .RetiresOnSaturation(); 3591 3592 EXPECT_CALL(*context_, useProgram(_)) 3593 .WillOnce(Return()) 3594 .RetiresOnSaturation(); 3595 } 3596 3597 void MustSetScissor(int x, int y, int width, int height) { 3598 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST)) 3599 .WillRepeatedly(Return()); 3600 3601 EXPECT_CALL(*context_, scissor(x, y, width, height)) 3602 .Times(AtLeast(1)) 3603 .WillRepeatedly(Return()); 3604 } 3605 3606 void MustSetNoScissor() { 3607 EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST)) 3608 .WillRepeatedly(Return()); 3609 3610 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST)) 3611 .Times(0); 3612 3613 EXPECT_CALL(*context_, scissor(_, _, _, _)) 3614 .Times(0); 3615 } 3616 }; 3617 3618 TEST_F(LayerTreeHostImplTest, NoPartialSwap) { 3619 scoped_ptr<MockContext> mock_context_owned(new MockContext); 3620 MockContext* mock_context = mock_context_owned.get(); 3621 3622 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 3623 mock_context_owned.PassAs<TestWebGraphicsContext3D>())); 3624 MockContextHarness harness(mock_context); 3625 3626 // Run test case 3627 LayerTreeSettings settings = DefaultSettings(); 3628 settings.partial_swap_enabled = false; 3629 CreateHostImpl(settings, output_surface.Pass()); 3630 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 3631 3632 // Without partial swap, and no clipping, no scissor is set. 3633 harness.MustDrawSolidQuad(); 3634 harness.MustSetNoScissor(); 3635 { 3636 LayerTreeHostImpl::FrameData frame; 3637 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3638 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3639 host_impl_->DidDrawAllLayers(frame); 3640 } 3641 Mock::VerifyAndClearExpectations(&mock_context); 3642 3643 // Without partial swap, but a layer does clip its subtree, one scissor is 3644 // set. 3645 host_impl_->active_tree()->root_layer()->SetMasksToBounds(true); 3646 harness.MustDrawSolidQuad(); 3647 harness.MustSetScissor(0, 0, 10, 10); 3648 { 3649 LayerTreeHostImpl::FrameData frame; 3650 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3651 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3652 host_impl_->DidDrawAllLayers(frame); 3653 } 3654 Mock::VerifyAndClearExpectations(&mock_context); 3655 } 3656 3657 TEST_F(LayerTreeHostImplTest, PartialSwap) { 3658 scoped_ptr<MockContext> context_owned(new MockContext); 3659 MockContext* mock_context = context_owned.get(); 3660 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 3661 context_owned.PassAs<TestWebGraphicsContext3D>())); 3662 MockContextHarness harness(mock_context); 3663 3664 LayerTreeSettings settings = DefaultSettings(); 3665 settings.partial_swap_enabled = true; 3666 CreateHostImpl(settings, output_surface.Pass()); 3667 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 3668 3669 // The first frame is not a partially-swapped one. 3670 harness.MustSetScissor(0, 0, 10, 10); 3671 harness.MustDrawSolidQuad(); 3672 { 3673 LayerTreeHostImpl::FrameData frame; 3674 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3675 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3676 host_impl_->DidDrawAllLayers(frame); 3677 } 3678 Mock::VerifyAndClearExpectations(&mock_context); 3679 3680 // Damage a portion of the frame. 3681 host_impl_->active_tree()->root_layer()->set_update_rect( 3682 gfx::Rect(0, 0, 2, 3)); 3683 3684 // The second frame will be partially-swapped (the y coordinates are flipped). 3685 harness.MustSetScissor(0, 7, 2, 3); 3686 harness.MustDrawSolidQuad(); 3687 { 3688 LayerTreeHostImpl::FrameData frame; 3689 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3690 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3691 host_impl_->DidDrawAllLayers(frame); 3692 } 3693 Mock::VerifyAndClearExpectations(&mock_context); 3694 } 3695 3696 static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( 3697 bool partial_swap, 3698 LayerTreeHostImplClient* client, 3699 Proxy* proxy, 3700 RenderingStatsInstrumentation* stats_instrumentation) { 3701 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); 3702 scoped_ptr<OutputSurface> output_surface( 3703 FakeOutputSurface::Create3d(provider)); 3704 provider->BindToCurrentThread(); 3705 provider->TestContext3d()->set_have_post_sub_buffer(true); 3706 3707 LayerTreeSettings settings; 3708 settings.partial_swap_enabled = partial_swap; 3709 scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( 3710 settings, client, proxy, stats_instrumentation, NULL, 0); 3711 my_host_impl->InitializeRenderer(output_surface.Pass()); 3712 my_host_impl->SetViewportSize(gfx::Size(100, 100)); 3713 3714 /* 3715 Layers are created as follows: 3716 3717 +--------------------+ 3718 | 1 | 3719 | +-----------+ | 3720 | | 2 | | 3721 | | +-------------------+ 3722 | | | 3 | 3723 | | +-------------------+ 3724 | | | | 3725 | +-----------+ | 3726 | | 3727 | | 3728 +--------------------+ 3729 3730 Layers 1, 2 have render surfaces 3731 */ 3732 scoped_ptr<LayerImpl> root = 3733 LayerImpl::Create(my_host_impl->active_tree(), 1); 3734 scoped_ptr<LayerImpl> child = 3735 LayerImpl::Create(my_host_impl->active_tree(), 2); 3736 scoped_ptr<LayerImpl> grand_child = 3737 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3); 3738 3739 gfx::Rect root_rect(0, 0, 100, 100); 3740 gfx::Rect child_rect(10, 10, 50, 50); 3741 gfx::Rect grand_child_rect(5, 5, 150, 150); 3742 3743 root->CreateRenderSurface(); 3744 root->SetAnchorPoint(gfx::PointF()); 3745 root->SetPosition(root_rect.origin()); 3746 root->SetBounds(root_rect.size()); 3747 root->SetContentBounds(root->bounds()); 3748 root->draw_properties().visible_content_rect = root_rect; 3749 root->SetDrawsContent(false); 3750 root->render_surface()->SetContentRect(gfx::Rect(root_rect.size())); 3751 3752 child->SetAnchorPoint(gfx::PointF()); 3753 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y())); 3754 child->SetOpacity(0.5f); 3755 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); 3756 child->SetContentBounds(child->bounds()); 3757 child->draw_properties().visible_content_rect = child_rect; 3758 child->SetDrawsContent(false); 3759 child->SetForceRenderSurface(true); 3760 3761 grand_child->SetAnchorPoint(gfx::PointF()); 3762 grand_child->SetPosition(grand_child_rect.origin()); 3763 grand_child->SetBounds(grand_child_rect.size()); 3764 grand_child->SetContentBounds(grand_child->bounds()); 3765 grand_child->draw_properties().visible_content_rect = grand_child_rect; 3766 grand_child->SetDrawsContent(true); 3767 3768 child->AddChild(grand_child.Pass()); 3769 root->AddChild(child.Pass()); 3770 3771 my_host_impl->active_tree()->SetRootLayer(root.Pass()); 3772 return my_host_impl.Pass(); 3773 } 3774 3775 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { 3776 scoped_ptr<LayerTreeHostImpl> my_host_impl = 3777 SetupLayersForOpacity(true, this, &proxy_, &stats_instrumentation_); 3778 { 3779 LayerTreeHostImpl::FrameData frame; 3780 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); 3781 3782 // Verify all quads have been computed 3783 ASSERT_EQ(2U, frame.render_passes.size()); 3784 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); 3785 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); 3786 EXPECT_EQ(DrawQuad::SOLID_COLOR, 3787 frame.render_passes[0]->quad_list[0]->material); 3788 EXPECT_EQ(DrawQuad::RENDER_PASS, 3789 frame.render_passes[1]->quad_list[0]->material); 3790 3791 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 3792 my_host_impl->DidDrawAllLayers(frame); 3793 } 3794 } 3795 3796 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { 3797 scoped_ptr<LayerTreeHostImpl> my_host_impl = 3798 SetupLayersForOpacity(false, this, &proxy_, &stats_instrumentation_); 3799 { 3800 LayerTreeHostImpl::FrameData frame; 3801 EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); 3802 3803 // Verify all quads have been computed 3804 ASSERT_EQ(2U, frame.render_passes.size()); 3805 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); 3806 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); 3807 EXPECT_EQ(DrawQuad::SOLID_COLOR, 3808 frame.render_passes[0]->quad_list[0]->material); 3809 EXPECT_EQ(DrawQuad::RENDER_PASS, 3810 frame.render_passes[1]->quad_list[0]->material); 3811 3812 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 3813 my_host_impl->DidDrawAllLayers(frame); 3814 } 3815 } 3816 3817 TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { 3818 scoped_ptr<TestWebGraphicsContext3D> context = 3819 TestWebGraphicsContext3D::Create(); 3820 TestWebGraphicsContext3D* context3d = context.get(); 3821 scoped_ptr<OutputSurface> output_surface( 3822 FakeOutputSurface::Create3d(context.Pass())); 3823 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 3824 3825 scoped_ptr<LayerImpl> root_layer = 3826 LayerImpl::Create(host_impl_->active_tree(), 1); 3827 root_layer->SetBounds(gfx::Size(10, 10)); 3828 root_layer->SetAnchorPoint(gfx::PointF()); 3829 3830 scoped_refptr<VideoFrame> softwareFrame = 3831 media::VideoFrame::CreateColorFrame( 3832 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); 3833 FakeVideoFrameProvider provider; 3834 provider.set_frame(softwareFrame); 3835 scoped_ptr<VideoLayerImpl> video_layer = 3836 VideoLayerImpl::Create(host_impl_->active_tree(), 4, &provider); 3837 video_layer->SetBounds(gfx::Size(10, 10)); 3838 video_layer->SetAnchorPoint(gfx::PointF()); 3839 video_layer->SetContentBounds(gfx::Size(10, 10)); 3840 video_layer->SetDrawsContent(true); 3841 root_layer->AddChild(video_layer.PassAs<LayerImpl>()); 3842 3843 scoped_ptr<IOSurfaceLayerImpl> io_surface_layer = 3844 IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5); 3845 io_surface_layer->SetBounds(gfx::Size(10, 10)); 3846 io_surface_layer->SetAnchorPoint(gfx::PointF()); 3847 io_surface_layer->SetContentBounds(gfx::Size(10, 10)); 3848 io_surface_layer->SetDrawsContent(true); 3849 io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10)); 3850 root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>()); 3851 3852 host_impl_->active_tree()->SetRootLayer(root_layer.Pass()); 3853 3854 EXPECT_EQ(0u, context3d->NumTextures()); 3855 3856 LayerTreeHostImpl::FrameData frame; 3857 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3858 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3859 host_impl_->DidDrawAllLayers(frame); 3860 host_impl_->SwapBuffers(frame); 3861 3862 EXPECT_GT(context3d->NumTextures(), 0u); 3863 3864 // Kill the layer tree. 3865 host_impl_->active_tree()->SetRootLayer( 3866 LayerImpl::Create(host_impl_->active_tree(), 100)); 3867 // There should be no textures left in use after. 3868 EXPECT_EQ(0u, context3d->NumTextures()); 3869 } 3870 3871 class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D { 3872 public: 3873 MOCK_METHOD1(useProgram, void(blink::WebGLId program)); 3874 MOCK_METHOD4(drawElements, void(blink::WGC3Denum mode, 3875 blink::WGC3Dsizei count, 3876 blink::WGC3Denum type, 3877 blink::WGC3Dintptr offset)); 3878 }; 3879 3880 TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { 3881 scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned( 3882 new MockDrawQuadsToFillScreenContext); 3883 MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get(); 3884 3885 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 3886 mock_context_owned.PassAs<TestWebGraphicsContext3D>())); 3887 3888 // Run test case 3889 LayerTreeSettings settings = DefaultSettings(); 3890 settings.partial_swap_enabled = false; 3891 CreateHostImpl(settings, output_surface.Pass()); 3892 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); 3893 host_impl_->active_tree()->set_background_color(SK_ColorWHITE); 3894 3895 // Verify one quad is drawn when transparent background set is not set. 3896 host_impl_->active_tree()->set_has_transparent_background(false); 3897 EXPECT_CALL(*mock_context, useProgram(_)) 3898 .Times(1); 3899 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)) 3900 .Times(1); 3901 LayerTreeHostImpl::FrameData frame; 3902 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3903 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3904 host_impl_->DidDrawAllLayers(frame); 3905 Mock::VerifyAndClearExpectations(&mock_context); 3906 3907 // Verify no quads are drawn when transparent background is set. 3908 host_impl_->active_tree()->set_has_transparent_background(true); 3909 host_impl_->SetFullRootLayerDamage(); 3910 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3911 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3912 host_impl_->DidDrawAllLayers(frame); 3913 Mock::VerifyAndClearExpectations(&mock_context); 3914 } 3915 3916 TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { 3917 set_reduce_memory_result(false); 3918 3919 // If changing the memory limit wouldn't result in changing what was 3920 // committed, then no commit should be requested. 3921 set_reduce_memory_result(false); 3922 host_impl_->set_max_memory_needed_bytes( 3923 host_impl_->memory_allocation_limit_bytes() - 1); 3924 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 3925 host_impl_->memory_allocation_limit_bytes() - 1)); 3926 EXPECT_FALSE(did_request_commit_); 3927 did_request_commit_ = false; 3928 3929 // If changing the memory limit would result in changing what was 3930 // committed, then a commit should be requested, even though nothing was 3931 // evicted. 3932 set_reduce_memory_result(false); 3933 host_impl_->set_max_memory_needed_bytes( 3934 host_impl_->memory_allocation_limit_bytes()); 3935 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 3936 host_impl_->memory_allocation_limit_bytes() - 1)); 3937 EXPECT_TRUE(did_request_commit_); 3938 did_request_commit_ = false; 3939 3940 // Especially if changing the memory limit caused evictions, we need 3941 // to re-commit. 3942 set_reduce_memory_result(true); 3943 host_impl_->set_max_memory_needed_bytes(1); 3944 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 3945 host_impl_->memory_allocation_limit_bytes() - 1)); 3946 EXPECT_TRUE(did_request_commit_); 3947 did_request_commit_ = false; 3948 3949 // But if we set it to the same value that it was before, we shouldn't 3950 // re-commit. 3951 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 3952 host_impl_->memory_allocation_limit_bytes())); 3953 EXPECT_FALSE(did_request_commit_); 3954 } 3955 3956 class LayerTreeHostImplTestWithDelegatingRenderer 3957 : public LayerTreeHostImplTest { 3958 protected: 3959 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE { 3960 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>(); 3961 } 3962 3963 void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) { 3964 bool expect_to_draw = !expected_damage.IsEmpty(); 3965 3966 LayerTreeHostImpl::FrameData frame; 3967 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 3968 3969 if (!expect_to_draw) { 3970 // With no damage, we don't draw, and no quads are created. 3971 ASSERT_EQ(0u, frame.render_passes.size()); 3972 } else { 3973 ASSERT_EQ(1u, frame.render_passes.size()); 3974 3975 // Verify the damage rect for the root render pass. 3976 const RenderPass* root_render_pass = frame.render_passes.back(); 3977 EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect); 3978 3979 // Verify the root and child layers' quads are generated and not being 3980 // culled. 3981 ASSERT_EQ(2u, root_render_pass->quad_list.size()); 3982 3983 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; 3984 gfx::RectF expected_child_visible_rect(child->content_bounds()); 3985 EXPECT_RECT_EQ(expected_child_visible_rect, 3986 root_render_pass->quad_list[0]->visible_rect); 3987 3988 LayerImpl* root = host_impl_->active_tree()->root_layer(); 3989 gfx::RectF expected_root_visible_rect(root->content_bounds()); 3990 EXPECT_RECT_EQ(expected_root_visible_rect, 3991 root_render_pass->quad_list[1]->visible_rect); 3992 } 3993 3994 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3995 host_impl_->DidDrawAllLayers(frame); 3996 EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame)); 3997 } 3998 }; 3999 4000 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { 4001 scoped_ptr<SolidColorLayerImpl> root = 4002 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 4003 root->SetAnchorPoint(gfx::PointF()); 4004 root->SetPosition(gfx::PointF()); 4005 root->SetBounds(gfx::Size(10, 10)); 4006 root->SetContentBounds(gfx::Size(10, 10)); 4007 root->SetDrawsContent(true); 4008 4009 // Child layer is in the bottom right corner. 4010 scoped_ptr<SolidColorLayerImpl> child = 4011 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2); 4012 child->SetAnchorPoint(gfx::PointF(0.f, 0.f)); 4013 child->SetPosition(gfx::PointF(9.f, 9.f)); 4014 child->SetBounds(gfx::Size(1, 1)); 4015 child->SetContentBounds(gfx::Size(1, 1)); 4016 child->SetDrawsContent(true); 4017 root->AddChild(child.PassAs<LayerImpl>()); 4018 4019 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); 4020 4021 // Draw a frame. In the first frame, the entire viewport should be damaged. 4022 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); 4023 DrawFrameAndTestDamage(full_frame_damage); 4024 4025 // The second frame has damage that doesn't touch the child layer. Its quads 4026 // should still be generated. 4027 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1); 4028 host_impl_->active_tree()->root_layer()->set_update_rect(small_damage); 4029 DrawFrameAndTestDamage(small_damage); 4030 4031 // The third frame should have no damage, so no quads should be generated. 4032 gfx::Rect no_damage; 4033 DrawFrameAndTestDamage(no_damage); 4034 } 4035 4036 class FakeMaskLayerImpl : public LayerImpl { 4037 public: 4038 static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl, 4039 int id) { 4040 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id)); 4041 } 4042 4043 virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE { 4044 return 0; 4045 } 4046 4047 private: 4048 FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id) 4049 : LayerImpl(tree_impl, id) {} 4050 }; 4051 4052 TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { 4053 LayerTreeSettings settings; 4054 settings.layer_transforms_should_scale_layer_contents = true; 4055 CreateHostImpl(settings, CreateOutputSurface()); 4056 4057 // Root 4058 // | 4059 // +-- Scaling Layer (adds a 2x scale) 4060 // | 4061 // +-- Content Layer 4062 // +--Mask 4063 scoped_ptr<LayerImpl> scoped_root = 4064 LayerImpl::Create(host_impl_->active_tree(), 1); 4065 LayerImpl* root = scoped_root.get(); 4066 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 4067 4068 scoped_ptr<LayerImpl> scoped_scaling_layer = 4069 LayerImpl::Create(host_impl_->active_tree(), 2); 4070 LayerImpl* scaling_layer = scoped_scaling_layer.get(); 4071 root->AddChild(scoped_scaling_layer.Pass()); 4072 4073 scoped_ptr<LayerImpl> scoped_content_layer = 4074 LayerImpl::Create(host_impl_->active_tree(), 3); 4075 LayerImpl* content_layer = scoped_content_layer.get(); 4076 scaling_layer->AddChild(scoped_content_layer.Pass()); 4077 4078 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 4079 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 4080 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 4081 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 4082 4083 gfx::Size root_size(100, 100); 4084 root->SetBounds(root_size); 4085 root->SetContentBounds(root_size); 4086 root->SetPosition(gfx::PointF()); 4087 root->SetAnchorPoint(gfx::PointF()); 4088 4089 gfx::Size scaling_layer_size(50, 50); 4090 scaling_layer->SetBounds(scaling_layer_size); 4091 scaling_layer->SetContentBounds(scaling_layer_size); 4092 scaling_layer->SetPosition(gfx::PointF()); 4093 scaling_layer->SetAnchorPoint(gfx::PointF()); 4094 gfx::Transform scale; 4095 scale.Scale(2.f, 2.f); 4096 scaling_layer->SetTransform(scale); 4097 4098 content_layer->SetBounds(scaling_layer_size); 4099 content_layer->SetContentBounds(scaling_layer_size); 4100 content_layer->SetPosition(gfx::PointF()); 4101 content_layer->SetAnchorPoint(gfx::PointF()); 4102 content_layer->SetDrawsContent(true); 4103 4104 mask_layer->SetBounds(scaling_layer_size); 4105 mask_layer->SetContentBounds(scaling_layer_size); 4106 mask_layer->SetPosition(gfx::PointF()); 4107 mask_layer->SetAnchorPoint(gfx::PointF()); 4108 mask_layer->SetDrawsContent(true); 4109 4110 4111 // Check that the tree scaling is correctly taken into account for the mask, 4112 // that should fully map onto the quad. 4113 float device_scale_factor = 1.f; 4114 host_impl_->SetViewportSize(root_size); 4115 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4116 { 4117 LayerTreeHostImpl::FrameData frame; 4118 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4119 4120 ASSERT_EQ(1u, frame.render_passes.size()); 4121 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4122 ASSERT_EQ(DrawQuad::RENDER_PASS, 4123 frame.render_passes[0]->quad_list[0]->material); 4124 const RenderPassDrawQuad* render_pass_quad = 4125 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4126 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4127 render_pass_quad->rect.ToString()); 4128 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4129 render_pass_quad->mask_uv_rect.ToString()); 4130 4131 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4132 host_impl_->DidDrawAllLayers(frame); 4133 } 4134 4135 4136 // Applying a DSF should change the render surface size, but won't affect 4137 // which part of the mask is used. 4138 device_scale_factor = 2.f; 4139 gfx::Size device_viewport = 4140 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 4141 host_impl_->SetViewportSize(device_viewport); 4142 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4143 host_impl_->active_tree()->set_needs_update_draw_properties(); 4144 { 4145 LayerTreeHostImpl::FrameData frame; 4146 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4147 4148 ASSERT_EQ(1u, frame.render_passes.size()); 4149 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4150 ASSERT_EQ(DrawQuad::RENDER_PASS, 4151 frame.render_passes[0]->quad_list[0]->material); 4152 const RenderPassDrawQuad* render_pass_quad = 4153 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4154 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), 4155 render_pass_quad->rect.ToString()); 4156 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4157 render_pass_quad->mask_uv_rect.ToString()); 4158 4159 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4160 host_impl_->DidDrawAllLayers(frame); 4161 } 4162 4163 4164 // Applying an equivalent content scale on the content layer and the mask 4165 // should still result in the same part of the mask being used. 4166 gfx::Size content_bounds = 4167 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size, 4168 device_scale_factor)); 4169 content_layer->SetContentBounds(content_bounds); 4170 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4171 mask_layer->SetContentBounds(content_bounds); 4172 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4173 host_impl_->active_tree()->set_needs_update_draw_properties(); 4174 { 4175 LayerTreeHostImpl::FrameData frame; 4176 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4177 4178 ASSERT_EQ(1u, frame.render_passes.size()); 4179 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4180 ASSERT_EQ(DrawQuad::RENDER_PASS, 4181 frame.render_passes[0]->quad_list[0]->material); 4182 const RenderPassDrawQuad* render_pass_quad = 4183 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4184 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), 4185 render_pass_quad->rect.ToString()); 4186 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4187 render_pass_quad->mask_uv_rect.ToString()); 4188 4189 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4190 host_impl_->DidDrawAllLayers(frame); 4191 } 4192 } 4193 4194 TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { 4195 // The mask layer has bounds 100x100 but is attached to a layer with bounds 4196 // 50x50. 4197 4198 scoped_ptr<LayerImpl> scoped_root = 4199 LayerImpl::Create(host_impl_->active_tree(), 1); 4200 LayerImpl* root = scoped_root.get(); 4201 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 4202 4203 scoped_ptr<LayerImpl> scoped_content_layer = 4204 LayerImpl::Create(host_impl_->active_tree(), 3); 4205 LayerImpl* content_layer = scoped_content_layer.get(); 4206 root->AddChild(scoped_content_layer.Pass()); 4207 4208 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 4209 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 4210 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 4211 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 4212 4213 gfx::Size root_size(100, 100); 4214 root->SetBounds(root_size); 4215 root->SetContentBounds(root_size); 4216 root->SetPosition(gfx::PointF()); 4217 root->SetAnchorPoint(gfx::PointF()); 4218 4219 gfx::Size layer_size(50, 50); 4220 content_layer->SetBounds(layer_size); 4221 content_layer->SetContentBounds(layer_size); 4222 content_layer->SetPosition(gfx::PointF()); 4223 content_layer->SetAnchorPoint(gfx::PointF()); 4224 content_layer->SetDrawsContent(true); 4225 4226 gfx::Size mask_size(100, 100); 4227 mask_layer->SetBounds(mask_size); 4228 mask_layer->SetContentBounds(mask_size); 4229 mask_layer->SetPosition(gfx::PointF()); 4230 mask_layer->SetAnchorPoint(gfx::PointF()); 4231 mask_layer->SetDrawsContent(true); 4232 4233 // Check that the mask fills the surface. 4234 float device_scale_factor = 1.f; 4235 host_impl_->SetViewportSize(root_size); 4236 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4237 { 4238 LayerTreeHostImpl::FrameData frame; 4239 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4240 4241 ASSERT_EQ(1u, frame.render_passes.size()); 4242 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4243 ASSERT_EQ(DrawQuad::RENDER_PASS, 4244 frame.render_passes[0]->quad_list[0]->material); 4245 const RenderPassDrawQuad* render_pass_quad = 4246 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4247 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 4248 render_pass_quad->rect.ToString()); 4249 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4250 render_pass_quad->mask_uv_rect.ToString()); 4251 4252 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4253 host_impl_->DidDrawAllLayers(frame); 4254 } 4255 4256 // Applying a DSF should change the render surface size, but won't affect 4257 // which part of the mask is used. 4258 device_scale_factor = 2.f; 4259 gfx::Size device_viewport = 4260 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 4261 host_impl_->SetViewportSize(device_viewport); 4262 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4263 host_impl_->active_tree()->set_needs_update_draw_properties(); 4264 { 4265 LayerTreeHostImpl::FrameData frame; 4266 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4267 4268 ASSERT_EQ(1u, frame.render_passes.size()); 4269 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4270 ASSERT_EQ(DrawQuad::RENDER_PASS, 4271 frame.render_passes[0]->quad_list[0]->material); 4272 const RenderPassDrawQuad* render_pass_quad = 4273 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4274 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4275 render_pass_quad->rect.ToString()); 4276 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4277 render_pass_quad->mask_uv_rect.ToString()); 4278 4279 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4280 host_impl_->DidDrawAllLayers(frame); 4281 } 4282 4283 // Applying an equivalent content scale on the content layer and the mask 4284 // should still result in the same part of the mask being used. 4285 gfx::Size layer_size_large = 4286 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); 4287 content_layer->SetContentBounds(layer_size_large); 4288 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4289 gfx::Size mask_size_large = 4290 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); 4291 mask_layer->SetContentBounds(mask_size_large); 4292 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4293 host_impl_->active_tree()->set_needs_update_draw_properties(); 4294 { 4295 LayerTreeHostImpl::FrameData frame; 4296 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4297 4298 ASSERT_EQ(1u, frame.render_passes.size()); 4299 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4300 ASSERT_EQ(DrawQuad::RENDER_PASS, 4301 frame.render_passes[0]->quad_list[0]->material); 4302 const RenderPassDrawQuad* render_pass_quad = 4303 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4304 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4305 render_pass_quad->rect.ToString()); 4306 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4307 render_pass_quad->mask_uv_rect.ToString()); 4308 4309 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4310 host_impl_->DidDrawAllLayers(frame); 4311 } 4312 4313 // Applying a different contents scale to the mask layer means it will have 4314 // a larger texture, but it should use the same tex coords to cover the 4315 // layer it masks. 4316 mask_layer->SetContentBounds(mask_size); 4317 mask_layer->SetContentsScale(1.f, 1.f); 4318 host_impl_->active_tree()->set_needs_update_draw_properties(); 4319 { 4320 LayerTreeHostImpl::FrameData frame; 4321 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4322 4323 ASSERT_EQ(1u, frame.render_passes.size()); 4324 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4325 ASSERT_EQ(DrawQuad::RENDER_PASS, 4326 frame.render_passes[0]->quad_list[0]->material); 4327 const RenderPassDrawQuad* render_pass_quad = 4328 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4329 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4330 render_pass_quad->rect.ToString()); 4331 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4332 render_pass_quad->mask_uv_rect.ToString()); 4333 4334 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4335 host_impl_->DidDrawAllLayers(frame); 4336 } 4337 } 4338 4339 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { 4340 // The replica's mask layer has bounds 100x100 but the replica is of a 4341 // layer with bounds 50x50. 4342 4343 scoped_ptr<LayerImpl> scoped_root = 4344 LayerImpl::Create(host_impl_->active_tree(), 1); 4345 LayerImpl* root = scoped_root.get(); 4346 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 4347 4348 scoped_ptr<LayerImpl> scoped_content_layer = 4349 LayerImpl::Create(host_impl_->active_tree(), 3); 4350 LayerImpl* content_layer = scoped_content_layer.get(); 4351 root->AddChild(scoped_content_layer.Pass()); 4352 4353 scoped_ptr<LayerImpl> scoped_replica_layer = 4354 LayerImpl::Create(host_impl_->active_tree(), 2); 4355 LayerImpl* replica_layer = scoped_replica_layer.get(); 4356 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); 4357 4358 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 4359 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 4360 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 4361 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 4362 4363 gfx::Size root_size(100, 100); 4364 root->SetBounds(root_size); 4365 root->SetContentBounds(root_size); 4366 root->SetPosition(gfx::PointF()); 4367 root->SetAnchorPoint(gfx::PointF()); 4368 4369 gfx::Size layer_size(50, 50); 4370 content_layer->SetBounds(layer_size); 4371 content_layer->SetContentBounds(layer_size); 4372 content_layer->SetPosition(gfx::PointF()); 4373 content_layer->SetAnchorPoint(gfx::PointF()); 4374 content_layer->SetDrawsContent(true); 4375 4376 gfx::Size mask_size(100, 100); 4377 mask_layer->SetBounds(mask_size); 4378 mask_layer->SetContentBounds(mask_size); 4379 mask_layer->SetPosition(gfx::PointF()); 4380 mask_layer->SetAnchorPoint(gfx::PointF()); 4381 mask_layer->SetDrawsContent(true); 4382 4383 // Check that the mask fills the surface. 4384 float device_scale_factor = 1.f; 4385 host_impl_->SetViewportSize(root_size); 4386 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4387 { 4388 LayerTreeHostImpl::FrameData frame; 4389 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4390 4391 ASSERT_EQ(1u, frame.render_passes.size()); 4392 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4393 ASSERT_EQ(DrawQuad::RENDER_PASS, 4394 frame.render_passes[0]->quad_list[1]->material); 4395 const RenderPassDrawQuad* replica_quad = 4396 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4397 EXPECT_TRUE(replica_quad->is_replica); 4398 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 4399 replica_quad->rect.ToString()); 4400 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4401 replica_quad->mask_uv_rect.ToString()); 4402 4403 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4404 host_impl_->DidDrawAllLayers(frame); 4405 } 4406 4407 // Applying a DSF should change the render surface size, but won't affect 4408 // which part of the mask is used. 4409 device_scale_factor = 2.f; 4410 gfx::Size device_viewport = 4411 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 4412 host_impl_->SetViewportSize(device_viewport); 4413 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4414 host_impl_->active_tree()->set_needs_update_draw_properties(); 4415 { 4416 LayerTreeHostImpl::FrameData frame; 4417 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4418 4419 ASSERT_EQ(1u, frame.render_passes.size()); 4420 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4421 ASSERT_EQ(DrawQuad::RENDER_PASS, 4422 frame.render_passes[0]->quad_list[1]->material); 4423 const RenderPassDrawQuad* replica_quad = 4424 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4425 EXPECT_TRUE(replica_quad->is_replica); 4426 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4427 replica_quad->rect.ToString()); 4428 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4429 replica_quad->mask_uv_rect.ToString()); 4430 4431 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4432 host_impl_->DidDrawAllLayers(frame); 4433 } 4434 4435 // Applying an equivalent content scale on the content layer and the mask 4436 // should still result in the same part of the mask being used. 4437 gfx::Size layer_size_large = 4438 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); 4439 content_layer->SetContentBounds(layer_size_large); 4440 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4441 gfx::Size mask_size_large = 4442 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); 4443 mask_layer->SetContentBounds(mask_size_large); 4444 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 4445 host_impl_->active_tree()->set_needs_update_draw_properties(); 4446 { 4447 LayerTreeHostImpl::FrameData frame; 4448 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4449 4450 ASSERT_EQ(1u, frame.render_passes.size()); 4451 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4452 ASSERT_EQ(DrawQuad::RENDER_PASS, 4453 frame.render_passes[0]->quad_list[1]->material); 4454 const RenderPassDrawQuad* replica_quad = 4455 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4456 EXPECT_TRUE(replica_quad->is_replica); 4457 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4458 replica_quad->rect.ToString()); 4459 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4460 replica_quad->mask_uv_rect.ToString()); 4461 4462 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4463 host_impl_->DidDrawAllLayers(frame); 4464 } 4465 4466 // Applying a different contents scale to the mask layer means it will have 4467 // a larger texture, but it should use the same tex coords to cover the 4468 // layer it masks. 4469 mask_layer->SetContentBounds(mask_size); 4470 mask_layer->SetContentsScale(1.f, 1.f); 4471 host_impl_->active_tree()->set_needs_update_draw_properties(); 4472 { 4473 LayerTreeHostImpl::FrameData frame; 4474 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4475 4476 ASSERT_EQ(1u, frame.render_passes.size()); 4477 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4478 ASSERT_EQ(DrawQuad::RENDER_PASS, 4479 frame.render_passes[0]->quad_list[1]->material); 4480 const RenderPassDrawQuad* replica_quad = 4481 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4482 EXPECT_TRUE(replica_quad->is_replica); 4483 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 4484 replica_quad->rect.ToString()); 4485 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 4486 replica_quad->mask_uv_rect.ToString()); 4487 4488 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4489 host_impl_->DidDrawAllLayers(frame); 4490 } 4491 } 4492 4493 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { 4494 // The replica is of a layer with bounds 50x50, but it has a child that causes 4495 // the surface bounds to be larger. 4496 4497 scoped_ptr<LayerImpl> scoped_root = 4498 LayerImpl::Create(host_impl_->active_tree(), 1); 4499 LayerImpl* root = scoped_root.get(); 4500 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 4501 4502 scoped_ptr<LayerImpl> scoped_content_layer = 4503 LayerImpl::Create(host_impl_->active_tree(), 2); 4504 LayerImpl* content_layer = scoped_content_layer.get(); 4505 root->AddChild(scoped_content_layer.Pass()); 4506 4507 scoped_ptr<LayerImpl> scoped_content_child_layer = 4508 LayerImpl::Create(host_impl_->active_tree(), 3); 4509 LayerImpl* content_child_layer = scoped_content_child_layer.get(); 4510 content_layer->AddChild(scoped_content_child_layer.Pass()); 4511 4512 scoped_ptr<LayerImpl> scoped_replica_layer = 4513 LayerImpl::Create(host_impl_->active_tree(), 4); 4514 LayerImpl* replica_layer = scoped_replica_layer.get(); 4515 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); 4516 4517 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 4518 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5); 4519 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 4520 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 4521 4522 gfx::Size root_size(100, 100); 4523 root->SetBounds(root_size); 4524 root->SetContentBounds(root_size); 4525 root->SetPosition(gfx::PointF()); 4526 root->SetAnchorPoint(gfx::PointF()); 4527 4528 gfx::Size layer_size(50, 50); 4529 content_layer->SetBounds(layer_size); 4530 content_layer->SetContentBounds(layer_size); 4531 content_layer->SetPosition(gfx::PointF()); 4532 content_layer->SetAnchorPoint(gfx::PointF()); 4533 content_layer->SetDrawsContent(true); 4534 4535 gfx::Size child_size(50, 50); 4536 content_child_layer->SetBounds(child_size); 4537 content_child_layer->SetContentBounds(child_size); 4538 content_child_layer->SetPosition(gfx::Point(50, 0)); 4539 content_child_layer->SetAnchorPoint(gfx::PointF()); 4540 content_child_layer->SetDrawsContent(true); 4541 4542 gfx::Size mask_size(50, 50); 4543 mask_layer->SetBounds(mask_size); 4544 mask_layer->SetContentBounds(mask_size); 4545 mask_layer->SetPosition(gfx::PointF()); 4546 mask_layer->SetAnchorPoint(gfx::PointF()); 4547 mask_layer->SetDrawsContent(true); 4548 4549 float device_scale_factor = 1.f; 4550 host_impl_->SetViewportSize(root_size); 4551 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4552 { 4553 LayerTreeHostImpl::FrameData frame; 4554 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4555 4556 ASSERT_EQ(1u, frame.render_passes.size()); 4557 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4558 4559 // The surface is 100x50. 4560 ASSERT_EQ(DrawQuad::RENDER_PASS, 4561 frame.render_passes[0]->quad_list[0]->material); 4562 const RenderPassDrawQuad* render_pass_quad = 4563 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4564 EXPECT_FALSE(render_pass_quad->is_replica); 4565 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 4566 render_pass_quad->rect.ToString()); 4567 4568 // The mask covers the owning layer only. 4569 ASSERT_EQ(DrawQuad::RENDER_PASS, 4570 frame.render_passes[0]->quad_list[1]->material); 4571 const RenderPassDrawQuad* replica_quad = 4572 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4573 EXPECT_TRUE(replica_quad->is_replica); 4574 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 4575 replica_quad->rect.ToString()); 4576 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(), 4577 replica_quad->mask_uv_rect.ToString()); 4578 4579 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4580 host_impl_->DidDrawAllLayers(frame); 4581 } 4582 4583 // Move the child to (-50, 0) instead. Now the mask should be moved to still 4584 // cover the layer being replicated. 4585 content_child_layer->SetPosition(gfx::Point(-50, 0)); 4586 { 4587 LayerTreeHostImpl::FrameData frame; 4588 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4589 4590 ASSERT_EQ(1u, frame.render_passes.size()); 4591 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 4592 4593 // The surface is 100x50 with its origin at (-50, 0). 4594 ASSERT_EQ(DrawQuad::RENDER_PASS, 4595 frame.render_passes[0]->quad_list[0]->material); 4596 const RenderPassDrawQuad* render_pass_quad = 4597 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4598 EXPECT_FALSE(render_pass_quad->is_replica); 4599 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), 4600 render_pass_quad->rect.ToString()); 4601 4602 // The mask covers the owning layer only. 4603 ASSERT_EQ(DrawQuad::RENDER_PASS, 4604 frame.render_passes[0]->quad_list[1]->material); 4605 const RenderPassDrawQuad* replica_quad = 4606 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[1]); 4607 EXPECT_TRUE(replica_quad->is_replica); 4608 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), 4609 replica_quad->rect.ToString()); 4610 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(), 4611 replica_quad->mask_uv_rect.ToString()); 4612 4613 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4614 host_impl_->DidDrawAllLayers(frame); 4615 } 4616 } 4617 4618 TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { 4619 // The masked layer has bounds 50x50, but it has a child that causes 4620 // the surface bounds to be larger. It also has a parent that clips the 4621 // masked layer and its surface. 4622 4623 scoped_ptr<LayerImpl> scoped_root = 4624 LayerImpl::Create(host_impl_->active_tree(), 1); 4625 LayerImpl* root = scoped_root.get(); 4626 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 4627 4628 scoped_ptr<LayerImpl> scoped_clipping_layer = 4629 LayerImpl::Create(host_impl_->active_tree(), 2); 4630 LayerImpl* clipping_layer = scoped_clipping_layer.get(); 4631 root->AddChild(scoped_clipping_layer.Pass()); 4632 4633 scoped_ptr<LayerImpl> scoped_content_layer = 4634 LayerImpl::Create(host_impl_->active_tree(), 3); 4635 LayerImpl* content_layer = scoped_content_layer.get(); 4636 clipping_layer->AddChild(scoped_content_layer.Pass()); 4637 4638 scoped_ptr<LayerImpl> scoped_content_child_layer = 4639 LayerImpl::Create(host_impl_->active_tree(), 4); 4640 LayerImpl* content_child_layer = scoped_content_child_layer.get(); 4641 content_layer->AddChild(scoped_content_child_layer.Pass()); 4642 4643 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 4644 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6); 4645 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 4646 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 4647 4648 gfx::Size root_size(100, 100); 4649 root->SetBounds(root_size); 4650 root->SetContentBounds(root_size); 4651 root->SetPosition(gfx::PointF()); 4652 root->SetAnchorPoint(gfx::PointF()); 4653 4654 gfx::Rect clipping_rect(20, 10, 10, 20); 4655 clipping_layer->SetBounds(clipping_rect.size()); 4656 clipping_layer->SetContentBounds(clipping_rect.size()); 4657 clipping_layer->SetPosition(clipping_rect.origin()); 4658 clipping_layer->SetAnchorPoint(gfx::PointF()); 4659 clipping_layer->SetMasksToBounds(true); 4660 4661 gfx::Size layer_size(50, 50); 4662 content_layer->SetBounds(layer_size); 4663 content_layer->SetContentBounds(layer_size); 4664 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin()); 4665 content_layer->SetAnchorPoint(gfx::PointF()); 4666 content_layer->SetDrawsContent(true); 4667 4668 gfx::Size child_size(50, 50); 4669 content_child_layer->SetBounds(child_size); 4670 content_child_layer->SetContentBounds(child_size); 4671 content_child_layer->SetPosition(gfx::Point(50, 0)); 4672 content_child_layer->SetAnchorPoint(gfx::PointF()); 4673 content_child_layer->SetDrawsContent(true); 4674 4675 gfx::Size mask_size(100, 100); 4676 mask_layer->SetBounds(mask_size); 4677 mask_layer->SetContentBounds(mask_size); 4678 mask_layer->SetPosition(gfx::PointF()); 4679 mask_layer->SetAnchorPoint(gfx::PointF()); 4680 mask_layer->SetDrawsContent(true); 4681 4682 float device_scale_factor = 1.f; 4683 host_impl_->SetViewportSize(root_size); 4684 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4685 { 4686 LayerTreeHostImpl::FrameData frame; 4687 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4688 4689 ASSERT_EQ(1u, frame.render_passes.size()); 4690 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4691 4692 // The surface is clipped to 10x20. 4693 ASSERT_EQ(DrawQuad::RENDER_PASS, 4694 frame.render_passes[0]->quad_list[0]->material); 4695 const RenderPassDrawQuad* render_pass_quad = 4696 RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); 4697 EXPECT_FALSE(render_pass_quad->is_replica); 4698 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), 4699 render_pass_quad->rect.ToString()); 4700 4701 // The masked layer is 50x50, but the surface size is 10x20. So the texture 4702 // coords in the mask are scaled by 10/50 and 20/50. 4703 // The surface is clipped to (20,10) so the mask texture coords are offset 4704 // by 20/50 and 10/50 4705 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 4706 1.f / 50.f).ToString(), 4707 render_pass_quad->mask_uv_rect.ToString()); 4708 4709 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4710 host_impl_->DidDrawAllLayers(frame); 4711 } 4712 } 4713 4714 class GLRendererWithSetupQuadForAntialiasing : public GLRenderer { 4715 public: 4716 using GLRenderer::SetupQuadForAntialiasing; 4717 }; 4718 4719 TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { 4720 // Due to precision issues (especially on Android), sometimes far 4721 // away quads can end up thinking they need AA. 4722 float device_scale_factor = 4.f / 3.f; 4723 host_impl_->SetDeviceScaleFactor(device_scale_factor); 4724 gfx::Size root_size(2000, 1000); 4725 gfx::Size device_viewport_size = 4726 gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor)); 4727 host_impl_->SetViewportSize(device_viewport_size); 4728 4729 host_impl_->CreatePendingTree(); 4730 host_impl_->pending_tree() 4731 ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f); 4732 4733 scoped_ptr<LayerImpl> scoped_root = 4734 LayerImpl::Create(host_impl_->pending_tree(), 1); 4735 LayerImpl* root = scoped_root.get(); 4736 4737 host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass()); 4738 4739 scoped_ptr<LayerImpl> scoped_scrolling_layer = 4740 LayerImpl::Create(host_impl_->pending_tree(), 2); 4741 LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); 4742 root->AddChild(scoped_scrolling_layer.Pass()); 4743 4744 gfx::Size content_layer_bounds(100000, 100); 4745 gfx::Size pile_tile_size(3000, 3000); 4746 scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile( 4747 pile_tile_size, content_layer_bounds)); 4748 4749 scoped_ptr<FakePictureLayerImpl> scoped_content_layer = 4750 FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile); 4751 LayerImpl* content_layer = scoped_content_layer.get(); 4752 scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>()); 4753 content_layer->SetBounds(content_layer_bounds); 4754 content_layer->SetDrawsContent(true); 4755 4756 root->SetBounds(root_size); 4757 4758 gfx::Vector2d scroll_offset(100000, 0); 4759 scrolling_layer->SetScrollable(true); 4760 scrolling_layer->SetMaxScrollOffset(scroll_offset); 4761 scrolling_layer->SetScrollOffset(scroll_offset); 4762 4763 host_impl_->ActivatePendingTree(); 4764 4765 host_impl_->active_tree()->UpdateDrawProperties(); 4766 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size()); 4767 4768 LayerTreeHostImpl::FrameData frame; 4769 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4770 4771 ASSERT_EQ(1u, frame.render_passes.size()); 4772 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size()); 4773 const DrawQuad* quad = frame.render_passes[0]->quad_list[0]; 4774 4775 float edge[24]; 4776 gfx::QuadF device_layer_quad; 4777 bool antialiased = 4778 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing( 4779 quad->quadTransform(), quad, &device_layer_quad, edge); 4780 EXPECT_FALSE(antialiased); 4781 4782 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4783 host_impl_->DidDrawAllLayers(frame); 4784 } 4785 4786 4787 class CompositorFrameMetadataTest : public LayerTreeHostImplTest { 4788 public: 4789 CompositorFrameMetadataTest() 4790 : swap_buffers_complete_(0) {} 4791 4792 virtual void OnSwapBuffersCompleteOnImplThread() OVERRIDE { 4793 swap_buffers_complete_++; 4794 } 4795 4796 int swap_buffers_complete_; 4797 }; 4798 4799 TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { 4800 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 4801 { 4802 LayerTreeHostImpl::FrameData frame; 4803 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4804 host_impl_->DrawLayers(&frame, base::TimeTicks()); 4805 host_impl_->DidDrawAllLayers(frame); 4806 } 4807 CompositorFrameAck ack; 4808 host_impl_->ReclaimResources(&ack); 4809 host_impl_->OnSwapBuffersComplete(); 4810 EXPECT_EQ(swap_buffers_complete_, 1); 4811 } 4812 4813 class CountingSoftwareDevice : public SoftwareOutputDevice { 4814 public: 4815 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {} 4816 4817 virtual SkCanvas* BeginPaint(gfx::Rect damage_rect) OVERRIDE { 4818 ++frames_began_; 4819 return SoftwareOutputDevice::BeginPaint(damage_rect); 4820 } 4821 virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE { 4822 ++frames_ended_; 4823 SoftwareOutputDevice::EndPaint(frame_data); 4824 } 4825 4826 int frames_began_, frames_ended_; 4827 }; 4828 4829 TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { 4830 // No main thread evictions in resourceless software mode. 4831 set_reduce_memory_result(false); 4832 CountingSoftwareDevice* software_device = new CountingSoftwareDevice(); 4833 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL( 4834 scoped_ptr<SoftwareOutputDevice>(software_device)).release(); 4835 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 4836 scoped_ptr<OutputSurface>(output_surface))); 4837 host_impl_->SetViewportSize(gfx::Size(50, 50)); 4838 4839 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 4840 4841 output_surface->set_forced_draw_to_software_device(true); 4842 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice()); 4843 4844 EXPECT_EQ(0, software_device->frames_began_); 4845 EXPECT_EQ(0, software_device->frames_ended_); 4846 4847 DrawFrame(); 4848 4849 EXPECT_EQ(1, software_device->frames_began_); 4850 EXPECT_EQ(1, software_device->frames_ended_); 4851 4852 // Call other API methods that are likely to hit NULL pointer in this mode. 4853 EXPECT_TRUE(host_impl_->AsValue()); 4854 EXPECT_TRUE(host_impl_->ActivationStateAsValue()); 4855 } 4856 4857 TEST_F(LayerTreeHostImplTest, 4858 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) { 4859 set_reduce_memory_result(false); 4860 FakeOutputSurface* output_surface = FakeOutputSurface::CreateDeferredGL( 4861 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice())).release(); 4862 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 4863 scoped_ptr<OutputSurface>(output_surface))); 4864 4865 output_surface->set_forced_draw_to_software_device(true); 4866 EXPECT_TRUE(output_surface->ForcedDrawToSoftwareDevice()); 4867 4868 // SolidColorLayerImpl will be drawn. 4869 scoped_ptr<SolidColorLayerImpl> root_layer = 4870 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 4871 4872 // VideoLayerImpl will not be drawn. 4873 FakeVideoFrameProvider provider; 4874 scoped_ptr<VideoLayerImpl> video_layer = 4875 VideoLayerImpl::Create(host_impl_->active_tree(), 2, &provider); 4876 video_layer->SetBounds(gfx::Size(10, 10)); 4877 video_layer->SetContentBounds(gfx::Size(10, 10)); 4878 video_layer->SetDrawsContent(true); 4879 root_layer->AddChild(video_layer.PassAs<LayerImpl>()); 4880 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); 4881 4882 LayerTreeHostImpl::FrameData frame; 4883 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 4884 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4885 host_impl_->DidDrawAllLayers(frame); 4886 4887 EXPECT_EQ(1u, frame.will_draw_layers.size()); 4888 EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]); 4889 } 4890 4891 class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest { 4892 protected: 4893 virtual void SetUp() OVERRIDE { 4894 LayerTreeHostImplTest::SetUp(); 4895 4896 set_reduce_memory_result(false); 4897 4898 scoped_ptr<FakeOutputSurface> output_surface( 4899 FakeOutputSurface::CreateDeferredGL( 4900 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice()))); 4901 output_surface_ = output_surface.get(); 4902 4903 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 4904 output_surface.PassAs<OutputSurface>())); 4905 4906 scoped_ptr<SolidColorLayerImpl> root_layer = 4907 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 4908 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); 4909 4910 onscreen_context_provider_ = TestContextProvider::Create(); 4911 offscreen_context_provider_ = TestContextProvider::Create(); 4912 } 4913 4914 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE { 4915 did_update_renderer_capabilities_ = true; 4916 } 4917 4918 FakeOutputSurface* output_surface_; 4919 scoped_refptr<TestContextProvider> onscreen_context_provider_; 4920 scoped_refptr<TestContextProvider> offscreen_context_provider_; 4921 bool did_update_renderer_capabilities_; 4922 }; 4923 4924 4925 TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) { 4926 // Software draw. 4927 DrawFrame(); 4928 4929 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4930 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4931 4932 // DeferredInitialize and hardware draw. 4933 did_update_renderer_capabilities_ = false; 4934 EXPECT_TRUE(output_surface_->InitializeAndSetContext3d( 4935 onscreen_context_provider_, offscreen_context_provider_)); 4936 EXPECT_EQ(onscreen_context_provider_, 4937 host_impl_->output_surface()->context_provider()); 4938 EXPECT_EQ(offscreen_context_provider_, 4939 host_impl_->offscreen_context_provider()); 4940 EXPECT_TRUE(did_update_renderer_capabilities_); 4941 4942 // Defer intialized GL draw. 4943 DrawFrame(); 4944 4945 // Revert back to software. 4946 did_update_renderer_capabilities_ = false; 4947 output_surface_->ReleaseGL(); 4948 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4949 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4950 EXPECT_TRUE(did_update_renderer_capabilities_); 4951 4952 // Software draw again. 4953 DrawFrame(); 4954 } 4955 4956 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_0) { 4957 // Software draw. 4958 DrawFrame(); 4959 4960 // Fail initialization of the onscreen context before the OutputSurface binds 4961 // it to the thread. 4962 onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true); 4963 4964 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4965 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4966 4967 // DeferredInitialize fails. 4968 did_update_renderer_capabilities_ = false; 4969 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d( 4970 onscreen_context_provider_, offscreen_context_provider_)); 4971 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4972 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4973 EXPECT_FALSE(did_update_renderer_capabilities_); 4974 4975 // Software draw again. 4976 DrawFrame(); 4977 } 4978 4979 // TODO(boliu): After r239415, fails_OnscreenContext_1 and 2 are exactly the 4980 // same as 0. They were supposed to test makeCurrent failing in the 4981 // OutputSurface, LayerTreeHostImpl, and GLRenderer respectively. 4982 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_1) { 4983 // Software draw. 4984 DrawFrame(); 4985 4986 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4987 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4988 4989 onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true); 4990 4991 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4992 // DeferredInitialize fails. 4993 did_update_renderer_capabilities_ = false; 4994 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d( 4995 onscreen_context_provider_, offscreen_context_provider_)); 4996 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 4997 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 4998 EXPECT_FALSE(did_update_renderer_capabilities_); 4999 } 5000 5001 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OnscreenContext_2) { 5002 // Software draw. 5003 DrawFrame(); 5004 5005 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5006 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 5007 5008 onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true); 5009 5010 // DeferredInitialize fails. 5011 did_update_renderer_capabilities_ = false; 5012 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d( 5013 onscreen_context_provider_, offscreen_context_provider_)); 5014 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5015 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 5016 EXPECT_FALSE(did_update_renderer_capabilities_); 5017 } 5018 5019 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails_OffscreenContext) { 5020 // Software draw. 5021 DrawFrame(); 5022 5023 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5024 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 5025 5026 // Fail initialization of the offscreen context. 5027 onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true); 5028 5029 // DeferredInitialize fails. 5030 did_update_renderer_capabilities_ = false; 5031 EXPECT_FALSE(output_surface_->InitializeAndSetContext3d( 5032 onscreen_context_provider_, offscreen_context_provider_)); 5033 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5034 EXPECT_FALSE(host_impl_->offscreen_context_provider()); 5035 EXPECT_FALSE(did_update_renderer_capabilities_); 5036 } 5037 5038 // Checks that we have a non-0 default allocation if we pass a context that 5039 // doesn't support memory management extensions. 5040 TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { 5041 LayerTreeSettings settings; 5042 host_impl_ = LayerTreeHostImpl::Create( 5043 settings, this, &proxy_, &stats_instrumentation_, NULL, 0); 5044 5045 scoped_ptr<OutputSurface> output_surface( 5046 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create())); 5047 host_impl_->InitializeRenderer(output_surface.Pass()); 5048 EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes()); 5049 } 5050 5051 TEST_F(LayerTreeHostImplTest, MemoryPolicy) { 5052 ManagedMemoryPolicy policy1( 5053 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000); 5054 int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( 5055 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING); 5056 int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( 5057 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING); 5058 5059 host_impl_->SetVisible(true); 5060 host_impl_->SetMemoryPolicy(policy1); 5061 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); 5062 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_); 5063 5064 host_impl_->SetVisible(false); 5065 EXPECT_EQ(0u, current_limit_bytes_); 5066 EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_); 5067 5068 host_impl_->SetVisible(true); 5069 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); 5070 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_); 5071 } 5072 5073 class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest { 5074 public: 5075 virtual void SetUp() OVERRIDE { 5076 LayerTreeSettings settings; 5077 settings.impl_side_painting = true; 5078 5079 fake_host_impl_ = new FakeLayerTreeHostImpl(settings, &proxy_); 5080 host_impl_.reset(fake_host_impl_); 5081 host_impl_->InitializeRenderer(CreateOutputSurface()); 5082 host_impl_->SetViewportSize(gfx::Size(10, 10)); 5083 } 5084 5085 FakeLayerTreeHostImpl* fake_host_impl_; 5086 }; 5087 5088 TEST_F(LayerTreeHostImplTestManageTiles, ManageTilesWhenInvisible) { 5089 fake_host_impl_->DidModifyTilePriorities(); 5090 EXPECT_TRUE(fake_host_impl_->manage_tiles_needed()); 5091 fake_host_impl_->SetVisible(false); 5092 EXPECT_FALSE(fake_host_impl_->manage_tiles_needed()); 5093 } 5094 5095 TEST_F(LayerTreeHostImplTest, UIResourceManagement) { 5096 scoped_ptr<TestWebGraphicsContext3D> context = 5097 TestWebGraphicsContext3D::Create(); 5098 TestWebGraphicsContext3D* context3d = context.get(); 5099 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface(); 5100 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 5101 5102 EXPECT_EQ(0u, context3d->NumTextures()); 5103 5104 SkBitmap skbitmap; 5105 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 5106 skbitmap.allocPixels(); 5107 skbitmap.setImmutable(); 5108 5109 UIResourceId ui_resource_id = 1; 5110 UIResourceBitmap bitmap(skbitmap); 5111 host_impl_->CreateUIResource(ui_resource_id, bitmap); 5112 EXPECT_EQ(1u, context3d->NumTextures()); 5113 ResourceProvider::ResourceId id1 = 5114 host_impl_->ResourceIdForUIResource(ui_resource_id); 5115 EXPECT_NE(0u, id1); 5116 5117 // Multiple requests with the same id is allowed. The previous texture is 5118 // deleted. 5119 host_impl_->CreateUIResource(ui_resource_id, bitmap); 5120 EXPECT_EQ(1u, context3d->NumTextures()); 5121 ResourceProvider::ResourceId id2 = 5122 host_impl_->ResourceIdForUIResource(ui_resource_id); 5123 EXPECT_NE(0u, id2); 5124 EXPECT_NE(id1, id2); 5125 5126 // Deleting invalid UIResourceId is allowed and does not change state. 5127 host_impl_->DeleteUIResource(-1); 5128 EXPECT_EQ(1u, context3d->NumTextures()); 5129 5130 // Should return zero for invalid UIResourceId. Number of textures should 5131 // not change. 5132 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1)); 5133 EXPECT_EQ(1u, context3d->NumTextures()); 5134 5135 host_impl_->DeleteUIResource(ui_resource_id); 5136 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id)); 5137 EXPECT_EQ(0u, context3d->NumTextures()); 5138 5139 // Should not change state for multiple deletion on one UIResourceId 5140 host_impl_->DeleteUIResource(ui_resource_id); 5141 EXPECT_EQ(0u, context3d->NumTextures()); 5142 } 5143 5144 TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { 5145 scoped_ptr<TestWebGraphicsContext3D> context = 5146 TestWebGraphicsContext3D::Create(); 5147 TestWebGraphicsContext3D* context3d = context.get(); 5148 scoped_ptr<OutputSurface> output_surface = CreateFakeOutputSurface(); 5149 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 5150 5151 EXPECT_EQ(0u, context3d->NumTextures()); 5152 5153 scoped_ptr<uint8_t[]> pixels(new uint8_t[8]); 5154 skia::RefPtr<ETC1PixelRef> etc1_pixel_ref = 5155 skia::AdoptRef(new ETC1PixelRef(pixels.Pass())); 5156 UIResourceBitmap bitmap(etc1_pixel_ref, gfx::Size(4, 4)); 5157 5158 UIResourceId ui_resource_id = 1; 5159 host_impl_->CreateUIResource(ui_resource_id, bitmap); 5160 EXPECT_EQ(1u, context3d->NumTextures()); 5161 ResourceProvider::ResourceId id1 = 5162 host_impl_->ResourceIdForUIResource(ui_resource_id); 5163 EXPECT_NE(0u, id1); 5164 } 5165 5166 void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) { 5167 } 5168 5169 TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { 5170 scoped_refptr<TestContextProvider> context_provider = 5171 TestContextProvider::Create(); 5172 5173 CreateHostImpl( 5174 DefaultSettings(), 5175 FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>()); 5176 5177 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); 5178 5179 ScopedPtrVector<CopyOutputRequest> requests; 5180 requests.push_back(CopyOutputRequest::CreateRequest( 5181 base::Bind(&ShutdownReleasesContext_Callback))); 5182 5183 host_impl_->active_tree()->root_layer()->PassCopyRequests(&requests); 5184 5185 LayerTreeHostImpl::FrameData frame; 5186 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 5187 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5188 host_impl_->DidDrawAllLayers(frame); 5189 5190 // The CopyOutputResult's callback has a ref on the ContextProvider and a 5191 // texture in a texture mailbox. 5192 EXPECT_FALSE(context_provider->HasOneRef()); 5193 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); 5194 5195 host_impl_.reset(); 5196 5197 // The CopyOutputResult's callback was cancelled, the CopyOutputResult 5198 // released, and the texture deleted. 5199 EXPECT_TRUE(context_provider->HasOneRef()); 5200 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures()); 5201 } 5202 5203 TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { 5204 // When flinging via touch, only the child should scroll (we should not 5205 // bubble). 5206 gfx::Size surface_size(10, 10); 5207 gfx::Size content_size(20, 20); 5208 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size); 5209 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); 5210 5211 root->AddChild(child.Pass()); 5212 5213 host_impl_->SetViewportSize(surface_size); 5214 host_impl_->active_tree()->SetRootLayer(root.Pass()); 5215 host_impl_->active_tree()->DidBecomeActive(); 5216 DrawFrame(); 5217 { 5218 EXPECT_EQ(InputHandler::ScrollStarted, 5219 host_impl_->ScrollBegin(gfx::Point(), 5220 InputHandler::Gesture)); 5221 5222 EXPECT_EQ(InputHandler::ScrollStarted, 5223 host_impl_->FlingScrollBegin()); 5224 5225 gfx::Vector2d scroll_delta(0, 100); 5226 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 5227 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 5228 5229 host_impl_->ScrollEnd(); 5230 5231 scoped_ptr<ScrollAndScaleSet> scroll_info = 5232 host_impl_->ProcessScrollDeltas(); 5233 5234 // Only the child should have scrolled. 5235 ASSERT_EQ(1u, scroll_info->scrolls.size()); 5236 ExpectNone(*scroll_info.get(), 5237 host_impl_->active_tree()->root_layer()->id()); 5238 } 5239 } 5240 5241 TEST_F(LayerTreeHostImplTest, TouchFlingShouldBubbleIfPrecedingScrollBubbled) { 5242 // When flinging via touch, bubble scrolls if the touch scroll 5243 // immediately preceding the fling bubbled. 5244 gfx::Size surface_size(10, 10); 5245 gfx::Size root_content_size(10, 20); 5246 gfx::Size child_content_size(40, 40); 5247 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, root_content_size); 5248 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, child_content_size); 5249 5250 root->AddChild(child.Pass()); 5251 5252 host_impl_->SetViewportSize(surface_size); 5253 host_impl_->active_tree()->SetRootLayer(root.Pass()); 5254 host_impl_->active_tree()->DidBecomeActive(); 5255 DrawFrame(); 5256 { 5257 EXPECT_EQ(InputHandler::ScrollStarted, 5258 host_impl_->ScrollBegin(gfx::Point(), 5259 InputHandler::Gesture)); 5260 5261 // Touch scroll before starting the fling. The second scroll should bubble. 5262 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 100))); 5263 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5))); 5264 5265 scoped_ptr<ScrollAndScaleSet> scroll_info = 5266 host_impl_->ProcessScrollDeltas(); 5267 5268 // The root should have (partially) scrolled. 5269 EXPECT_EQ(2u, scroll_info->scrolls.size()); 5270 ExpectContains(*scroll_info.get(), 5271 host_impl_->active_tree()->root_layer()->id(), 5272 gfx::Vector2d(0, 5)); 5273 5274 EXPECT_EQ(InputHandler::ScrollStarted, 5275 host_impl_->FlingScrollBegin()); 5276 5277 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 5))); 5278 host_impl_->ScrollEnd(); 5279 5280 // The root should have (fully) scrolled from the fling. 5281 scroll_info = host_impl_->ProcessScrollDeltas(); 5282 EXPECT_EQ(2u, scroll_info->scrolls.size()); 5283 ExpectContains(*scroll_info.get(), 5284 host_impl_->active_tree()->root_layer()->id(), 5285 gfx::Vector2d(0, 10)); 5286 } 5287 } 5288 5289 TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) { 5290 // When flinging via wheel, the root should eventually scroll (we should 5291 // bubble). 5292 gfx::Size surface_size(10, 10); 5293 gfx::Size content_size(20, 20); 5294 scoped_ptr<LayerImpl> root = CreateScrollableLayer(1, content_size); 5295 scoped_ptr<LayerImpl> child = CreateScrollableLayer(2, content_size); 5296 5297 root->AddChild(child.Pass()); 5298 5299 host_impl_->SetViewportSize(surface_size); 5300 host_impl_->active_tree()->SetRootLayer(root.Pass()); 5301 host_impl_->active_tree()->DidBecomeActive(); 5302 DrawFrame(); 5303 { 5304 EXPECT_EQ(InputHandler::ScrollStarted, 5305 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 5306 5307 EXPECT_EQ(InputHandler::ScrollStarted, 5308 host_impl_->FlingScrollBegin()); 5309 5310 gfx::Vector2d scroll_delta(0, 100); 5311 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 5312 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 5313 5314 host_impl_->ScrollEnd(); 5315 5316 scoped_ptr<ScrollAndScaleSet> scroll_info = 5317 host_impl_->ProcessScrollDeltas(); 5318 5319 // The root should have scrolled. 5320 ASSERT_EQ(2u, scroll_info->scrolls.size()); 5321 ExpectContains(*scroll_info.get(), 5322 host_impl_->active_tree()->root_layer()->id(), 5323 gfx::Vector2d(0, 10)); 5324 } 5325 } 5326 5327 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed 5328 // to CompositorFrameMetadata after SwapBuffers(); 5329 TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { 5330 scoped_ptr<SolidColorLayerImpl> root = 5331 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 5332 root->SetAnchorPoint(gfx::PointF()); 5333 root->SetPosition(gfx::PointF()); 5334 root->SetBounds(gfx::Size(10, 10)); 5335 root->SetContentBounds(gfx::Size(10, 10)); 5336 root->SetDrawsContent(true); 5337 5338 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); 5339 5340 FakeOutputSurface* fake_output_surface = 5341 static_cast<FakeOutputSurface*>(host_impl_->output_surface()); 5342 5343 const ui::LatencyInfo& metadata_latency_before = 5344 fake_output_surface->last_sent_frame().metadata.latency_info; 5345 EXPECT_FALSE(metadata_latency_before.FindLatency( 5346 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL)); 5347 5348 ui::LatencyInfo latency_info; 5349 latency_info.AddLatencyNumber( 5350 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0); 5351 scoped_ptr<SwapPromise> swap_promise( 5352 new LatencyInfoSwapPromise(latency_info)); 5353 host_impl_->active_tree()->QueueSwapPromise(swap_promise.Pass()); 5354 host_impl_->SetNeedsRedraw(); 5355 5356 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); 5357 LayerTreeHostImpl::FrameData frame; 5358 EXPECT_TRUE(host_impl_->PrepareToDraw(&frame, gfx::Rect())); 5359 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5360 host_impl_->DidDrawAllLayers(frame); 5361 EXPECT_TRUE(host_impl_->SwapBuffers(frame)); 5362 5363 const ui::LatencyInfo& metadata_latency_after = 5364 fake_output_surface->last_sent_frame().metadata.latency_info; 5365 EXPECT_TRUE(metadata_latency_after.FindLatency( 5366 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL)); 5367 } 5368 5369 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { 5370 public: 5371 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, 5372 LayerTreeHostImpl* layer_tree_host_impl, 5373 int* set_needs_commit_count, 5374 int* set_needs_redraw_count) 5375 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), 5376 set_needs_commit_count_(set_needs_commit_count), 5377 set_needs_redraw_count_(set_needs_redraw_count) {} 5378 5379 virtual ~SimpleSwapPromiseMonitor() {} 5380 5381 virtual void OnSetNeedsCommitOnMain() OVERRIDE { 5382 (*set_needs_commit_count_)++; 5383 } 5384 5385 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE { 5386 (*set_needs_redraw_count_)++; 5387 } 5388 5389 private: 5390 int* set_needs_commit_count_; 5391 int* set_needs_redraw_count_; 5392 }; 5393 5394 TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { 5395 int set_needs_commit_count = 0; 5396 int set_needs_redraw_count = 0; 5397 5398 { 5399 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 5400 new SimpleSwapPromiseMonitor(NULL, 5401 host_impl_.get(), 5402 &set_needs_commit_count, 5403 &set_needs_redraw_count)); 5404 host_impl_->SetNeedsRedraw(); 5405 EXPECT_EQ(0, set_needs_commit_count); 5406 EXPECT_EQ(1, set_needs_redraw_count); 5407 } 5408 5409 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being 5410 // monitored. 5411 host_impl_->SetNeedsRedraw(); 5412 EXPECT_EQ(0, set_needs_commit_count); 5413 EXPECT_EQ(1, set_needs_redraw_count); 5414 5415 { 5416 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 5417 new SimpleSwapPromiseMonitor(NULL, 5418 host_impl_.get(), 5419 &set_needs_commit_count, 5420 &set_needs_redraw_count)); 5421 host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10)); 5422 EXPECT_EQ(0, set_needs_commit_count); 5423 EXPECT_EQ(2, set_needs_redraw_count); 5424 } 5425 5426 { 5427 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 5428 new SimpleSwapPromiseMonitor(NULL, 5429 host_impl_.get(), 5430 &set_needs_commit_count, 5431 &set_needs_redraw_count)); 5432 // Empty damage rect won't signal the monitor. 5433 host_impl_->SetNeedsRedrawRect(gfx::Rect()); 5434 EXPECT_EQ(0, set_needs_commit_count); 5435 EXPECT_EQ(2, set_needs_redraw_count); 5436 } 5437 } 5438 5439 } // namespace 5440 } // namespace cc 5441