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/page_scale_animation.h" 17 #include "cc/input/top_controls_manager.h" 18 #include "cc/layers/append_quads_data.h" 19 #include "cc/layers/delegated_renderer_layer_impl.h" 20 #include "cc/layers/heads_up_display_layer_impl.h" 21 #include "cc/layers/io_surface_layer_impl.h" 22 #include "cc/layers/layer_impl.h" 23 #include "cc/layers/painted_scrollbar_layer_impl.h" 24 #include "cc/layers/render_surface_impl.h" 25 #include "cc/layers/solid_color_layer_impl.h" 26 #include "cc/layers/solid_color_scrollbar_layer_impl.h" 27 #include "cc/layers/texture_layer_impl.h" 28 #include "cc/layers/tiled_layer_impl.h" 29 #include "cc/layers/video_layer_impl.h" 30 #include "cc/output/begin_frame_args.h" 31 #include "cc/output/compositor_frame_ack.h" 32 #include "cc/output/compositor_frame_metadata.h" 33 #include "cc/output/copy_output_request.h" 34 #include "cc/output/copy_output_result.h" 35 #include "cc/output/gl_renderer.h" 36 #include "cc/quads/render_pass_draw_quad.h" 37 #include "cc/quads/solid_color_draw_quad.h" 38 #include "cc/quads/texture_draw_quad.h" 39 #include "cc/quads/tile_draw_quad.h" 40 #include "cc/resources/layer_tiling_data.h" 41 #include "cc/test/animation_test_common.h" 42 #include "cc/test/begin_frame_args_test.h" 43 #include "cc/test/fake_layer_tree_host_impl.h" 44 #include "cc/test/fake_output_surface.h" 45 #include "cc/test/fake_output_surface_client.h" 46 #include "cc/test/fake_picture_layer_impl.h" 47 #include "cc/test/fake_picture_pile_impl.h" 48 #include "cc/test/fake_proxy.h" 49 #include "cc/test/fake_rendering_stats_instrumentation.h" 50 #include "cc/test/fake_video_frame_provider.h" 51 #include "cc/test/geometry_test_utils.h" 52 #include "cc/test/layer_test_common.h" 53 #include "cc/test/render_pass_test_common.h" 54 #include "cc/test/test_shared_bitmap_manager.h" 55 #include "cc/test/test_web_graphics_context_3d.h" 56 #include "cc/trees/layer_tree_impl.h" 57 #include "cc/trees/single_thread_proxy.h" 58 #include "media/base/media.h" 59 #include "testing/gmock/include/gmock/gmock.h" 60 #include "testing/gtest/include/gtest/gtest.h" 61 #include "third_party/skia/include/core/SkMallocPixelRef.h" 62 #include "ui/gfx/frame_time.h" 63 #include "ui/gfx/rect_conversions.h" 64 #include "ui/gfx/size_conversions.h" 65 #include "ui/gfx/vector2d_conversions.h" 66 67 using ::testing::Mock; 68 using ::testing::Return; 69 using ::testing::AnyNumber; 70 using ::testing::AtLeast; 71 using ::testing::_; 72 using media::VideoFrame; 73 74 namespace cc { 75 namespace { 76 77 class LayerTreeHostImplTest : public testing::Test, 78 public LayerTreeHostImplClient { 79 public: 80 LayerTreeHostImplTest() 81 : proxy_(base::MessageLoopProxy::current(), 82 base::MessageLoopProxy::current()), 83 always_impl_thread_(&proxy_), 84 always_main_thread_blocked_(&proxy_), 85 shared_bitmap_manager_(new TestSharedBitmapManager()), 86 on_can_draw_state_changed_called_(false), 87 did_notify_ready_to_activate_(false), 88 did_request_commit_(false), 89 did_request_redraw_(false), 90 did_request_animate_(false), 91 did_request_manage_tiles_(false), 92 did_upload_visible_tile_(false), 93 reduce_memory_result_(true), 94 current_limit_bytes_(0), 95 current_priority_cutoff_value_(0) { 96 media::InitializeMediaLibraryForTesting(); 97 } 98 99 LayerTreeSettings DefaultSettings() { 100 LayerTreeSettings settings; 101 settings.minimum_occlusion_tracking_size = gfx::Size(); 102 settings.impl_side_painting = true; 103 settings.texture_id_allocation_chunk_size = 1; 104 settings.report_overscroll_only_for_scrollable_axes = true; 105 return settings; 106 } 107 108 virtual void SetUp() OVERRIDE { 109 CreateHostImpl(DefaultSettings(), CreateOutputSurface()); 110 } 111 112 virtual void TearDown() OVERRIDE {} 113 114 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE {} 115 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE {} 116 virtual void CommitVSyncParameters(base::TimeTicks timebase, 117 base::TimeDelta interval) OVERRIDE {} 118 virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time) OVERRIDE {} 119 virtual void SetMaxSwapsPendingOnImplThread(int max) OVERRIDE {} 120 virtual void DidSwapBuffersOnImplThread() OVERRIDE {} 121 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE {} 122 virtual void BeginFrame(const BeginFrameArgs& args) OVERRIDE {} 123 virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE { 124 on_can_draw_state_changed_called_ = true; 125 } 126 virtual void NotifyReadyToActivate() OVERRIDE { 127 did_notify_ready_to_activate_ = true; 128 host_impl_->ActivateSyncTree(); 129 } 130 virtual void SetNeedsRedrawOnImplThread() OVERRIDE { 131 did_request_redraw_ = true; 132 } 133 virtual void SetNeedsRedrawRectOnImplThread( 134 const gfx::Rect& damage_rect) OVERRIDE { 135 did_request_redraw_ = true; 136 } 137 virtual void SetNeedsAnimateOnImplThread() OVERRIDE { 138 did_request_animate_ = true; 139 } 140 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE { 141 did_request_manage_tiles_ = true; 142 } 143 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE { 144 did_upload_visible_tile_ = true; 145 } 146 virtual void SetNeedsCommitOnImplThread() OVERRIDE { 147 did_request_commit_ = true; 148 } 149 virtual void PostAnimationEventsToMainThreadOnImplThread( 150 scoped_ptr<AnimationEventsVector> events) OVERRIDE {} 151 virtual bool ReduceContentsTextureMemoryOnImplThread( 152 size_t limit_bytes, int priority_cutoff) OVERRIDE { 153 current_limit_bytes_ = limit_bytes; 154 current_priority_cutoff_value_ = priority_cutoff; 155 return reduce_memory_result_; 156 } 157 virtual bool IsInsideDraw() OVERRIDE { return false; } 158 virtual void RenewTreePriority() OVERRIDE {} 159 virtual void PostDelayedScrollbarFadeOnImplThread( 160 const base::Closure& start_fade, 161 base::TimeDelta delay) OVERRIDE { 162 scrollbar_fade_start_ = start_fade; 163 requested_scrollbar_animation_delay_ = delay; 164 } 165 virtual void DidActivateSyncTree() OVERRIDE {} 166 virtual void DidManageTiles() OVERRIDE {} 167 168 void set_reduce_memory_result(bool reduce_memory_result) { 169 reduce_memory_result_ = reduce_memory_result; 170 } 171 172 bool CreateHostImpl(const LayerTreeSettings& settings, 173 scoped_ptr<OutputSurface> output_surface) { 174 host_impl_ = LayerTreeHostImpl::Create(settings, 175 this, 176 &proxy_, 177 &stats_instrumentation_, 178 shared_bitmap_manager_.get(), 179 0); 180 bool init = host_impl_->InitializeRenderer(output_surface.Pass()); 181 host_impl_->SetViewportSize(gfx::Size(10, 10)); 182 return init; 183 } 184 185 void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) { 186 root->SetPosition(gfx::PointF()); 187 root->SetBounds(gfx::Size(10, 10)); 188 root->SetContentBounds(gfx::Size(10, 10)); 189 root->SetDrawsContent(true); 190 root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10); 191 host_impl_->active_tree()->SetRootLayer(root.Pass()); 192 } 193 194 static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) { 195 ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d()); 196 for (size_t i = 0; i < layer->children().size(); ++i) 197 ExpectClearedScrollDeltasRecursive(layer->children()[i]); 198 } 199 200 static void ExpectContains(const ScrollAndScaleSet& scroll_info, 201 int id, 202 const gfx::Vector2d& scroll_delta) { 203 int times_encountered = 0; 204 205 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { 206 if (scroll_info.scrolls[i].layer_id != id) 207 continue; 208 EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta); 209 times_encountered++; 210 } 211 212 ASSERT_EQ(1, times_encountered); 213 } 214 215 static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) { 216 int times_encountered = 0; 217 218 for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { 219 if (scroll_info.scrolls[i].layer_id != id) 220 continue; 221 times_encountered++; 222 } 223 224 ASSERT_EQ(0, times_encountered); 225 } 226 227 LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl, 228 const gfx::Size& content_size) { 229 const int kInnerViewportScrollLayerId = 2; 230 const int kInnerViewportClipLayerId = 4; 231 const int kPageScaleLayerId = 5; 232 scoped_ptr<LayerImpl> root = 233 LayerImpl::Create(layer_tree_impl, 1); 234 root->SetBounds(content_size); 235 root->SetContentBounds(content_size); 236 root->SetPosition(gfx::PointF()); 237 238 scoped_ptr<LayerImpl> scroll = 239 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); 240 LayerImpl* scroll_layer = scroll.get(); 241 scroll->SetIsContainerForFixedPositionLayers(true); 242 scroll->SetScrollOffset(gfx::Vector2d()); 243 244 scoped_ptr<LayerImpl> clip = 245 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); 246 clip->SetBounds( 247 gfx::Size(content_size.width() / 2, content_size.height() / 2)); 248 249 scoped_ptr<LayerImpl> page_scale = 250 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); 251 252 scroll->SetScrollClipLayer(clip->id()); 253 scroll->SetBounds(content_size); 254 scroll->SetContentBounds(content_size); 255 scroll->SetPosition(gfx::PointF()); 256 scroll->SetIsContainerForFixedPositionLayers(true); 257 258 scoped_ptr<LayerImpl> contents = 259 LayerImpl::Create(layer_tree_impl, 3); 260 contents->SetDrawsContent(true); 261 contents->SetBounds(content_size); 262 contents->SetContentBounds(content_size); 263 contents->SetPosition(gfx::PointF()); 264 265 scroll->AddChild(contents.Pass()); 266 page_scale->AddChild(scroll.Pass()); 267 clip->AddChild(page_scale.Pass()); 268 root->AddChild(clip.Pass()); 269 270 layer_tree_impl->SetRootLayer(root.Pass()); 271 layer_tree_impl->SetViewportLayersFromIds( 272 kPageScaleLayerId, kInnerViewportScrollLayerId, Layer::INVALID_ID); 273 274 return scroll_layer; 275 } 276 277 LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) { 278 LayerImpl* scroll_layer = CreateScrollAndContentsLayers( 279 host_impl_->active_tree(), content_size); 280 host_impl_->active_tree()->DidBecomeActive(); 281 return scroll_layer; 282 } 283 284 // TODO(wjmaclean) Add clip-layer pointer to parameters. 285 scoped_ptr<LayerImpl> CreateScrollableLayer(int id, 286 const gfx::Size& size, 287 LayerImpl* clip_layer) { 288 DCHECK(clip_layer); 289 DCHECK(id != clip_layer->id()); 290 scoped_ptr<LayerImpl> layer = 291 LayerImpl::Create(host_impl_->active_tree(), id); 292 layer->SetScrollClipLayer(clip_layer->id()); 293 layer->SetDrawsContent(true); 294 layer->SetBounds(size); 295 layer->SetContentBounds(size); 296 clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2)); 297 return layer.Pass(); 298 } 299 300 void DrawFrame() { 301 LayerTreeHostImpl::FrameData frame; 302 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 303 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 304 host_impl_->DidDrawAllLayers(frame); 305 } 306 307 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor); 308 void pinch_zoom_pan_viewport_test(float device_scale_factor); 309 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor); 310 void pinch_zoom_pan_viewport_and_scroll_boundary_test( 311 float device_scale_factor); 312 313 void CheckNotifyCalledIfCanDrawChanged(bool always_draw) { 314 // Note: It is not possible to disable the renderer once it has been set, 315 // so we do not need to test that disabling the renderer notifies us 316 // that can_draw changed. 317 EXPECT_FALSE(host_impl_->CanDraw()); 318 on_can_draw_state_changed_called_ = false; 319 320 // Set up the root layer, which allows us to draw. 321 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 322 EXPECT_TRUE(host_impl_->CanDraw()); 323 EXPECT_TRUE(on_can_draw_state_changed_called_); 324 on_can_draw_state_changed_called_ = false; 325 326 // Toggle the root layer to make sure it toggles can_draw 327 host_impl_->active_tree()->SetRootLayer(scoped_ptr<LayerImpl>()); 328 EXPECT_FALSE(host_impl_->CanDraw()); 329 EXPECT_TRUE(on_can_draw_state_changed_called_); 330 on_can_draw_state_changed_called_ = false; 331 332 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 333 EXPECT_TRUE(host_impl_->CanDraw()); 334 EXPECT_TRUE(on_can_draw_state_changed_called_); 335 on_can_draw_state_changed_called_ = false; 336 337 // Toggle the device viewport size to make sure it toggles can_draw. 338 host_impl_->SetViewportSize(gfx::Size()); 339 if (always_draw) { 340 EXPECT_TRUE(host_impl_->CanDraw()); 341 } else { 342 EXPECT_FALSE(host_impl_->CanDraw()); 343 } 344 EXPECT_TRUE(on_can_draw_state_changed_called_); 345 on_can_draw_state_changed_called_ = false; 346 347 host_impl_->SetViewportSize(gfx::Size(100, 100)); 348 EXPECT_TRUE(host_impl_->CanDraw()); 349 EXPECT_TRUE(on_can_draw_state_changed_called_); 350 on_can_draw_state_changed_called_ = false; 351 352 // Toggle contents textures purged without causing any evictions, 353 // and make sure that it does not change can_draw. 354 set_reduce_memory_result(false); 355 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 356 host_impl_->memory_allocation_limit_bytes() - 1)); 357 EXPECT_TRUE(host_impl_->CanDraw()); 358 EXPECT_FALSE(on_can_draw_state_changed_called_); 359 on_can_draw_state_changed_called_ = false; 360 361 // Toggle contents textures purged to make sure it toggles can_draw. 362 set_reduce_memory_result(true); 363 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 364 host_impl_->memory_allocation_limit_bytes() - 1)); 365 if (always_draw) { 366 EXPECT_TRUE(host_impl_->CanDraw()); 367 } else { 368 EXPECT_FALSE(host_impl_->CanDraw()); 369 } 370 EXPECT_TRUE(on_can_draw_state_changed_called_); 371 on_can_draw_state_changed_called_ = false; 372 373 host_impl_->active_tree()->ResetContentsTexturesPurged(); 374 EXPECT_TRUE(host_impl_->CanDraw()); 375 EXPECT_TRUE(on_can_draw_state_changed_called_); 376 on_can_draw_state_changed_called_ = false; 377 } 378 379 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor); 380 381 protected: 382 virtual scoped_ptr<OutputSurface> CreateOutputSurface() { 383 return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); 384 } 385 386 void DrawOneFrame() { 387 LayerTreeHostImpl::FrameData frame_data; 388 host_impl_->PrepareToDraw(&frame_data); 389 host_impl_->DidDrawAllLayers(frame_data); 390 } 391 392 FakeProxy proxy_; 393 DebugScopedSetImplThread always_impl_thread_; 394 DebugScopedSetMainThreadBlocked always_main_thread_blocked_; 395 396 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 397 scoped_ptr<LayerTreeHostImpl> host_impl_; 398 FakeRenderingStatsInstrumentation stats_instrumentation_; 399 bool on_can_draw_state_changed_called_; 400 bool did_notify_ready_to_activate_; 401 bool did_request_commit_; 402 bool did_request_redraw_; 403 bool did_request_animate_; 404 bool did_request_manage_tiles_; 405 bool did_upload_visible_tile_; 406 bool reduce_memory_result_; 407 base::Closure scrollbar_fade_start_; 408 base::TimeDelta requested_scrollbar_animation_delay_; 409 size_t current_limit_bytes_; 410 int current_priority_cutoff_value_; 411 }; 412 413 TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { 414 bool always_draw = false; 415 CheckNotifyCalledIfCanDrawChanged(always_draw); 416 } 417 418 TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) { 419 scoped_ptr<FakeOutputSurface> output_surface( 420 FakeOutputSurface::CreateAlwaysDrawAndSwap3d()); 421 CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); 422 423 bool always_draw = true; 424 CheckNotifyCalledIfCanDrawChanged(always_draw); 425 } 426 427 TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { 428 ASSERT_FALSE(host_impl_->active_tree()->root_layer()); 429 430 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 431 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 432 } 433 434 TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { 435 { 436 scoped_ptr<LayerImpl> root = 437 LayerImpl::Create(host_impl_->active_tree(), 1); 438 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2)); 439 root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3)); 440 root->children()[1]->AddChild( 441 LayerImpl::Create(host_impl_->active_tree(), 4)); 442 root->children()[1]->AddChild( 443 LayerImpl::Create(host_impl_->active_tree(), 5)); 444 root->children()[1]->children()[0]->AddChild( 445 LayerImpl::Create(host_impl_->active_tree(), 6)); 446 host_impl_->active_tree()->SetRootLayer(root.Pass()); 447 } 448 LayerImpl* root = host_impl_->active_tree()->root_layer(); 449 450 ExpectClearedScrollDeltasRecursive(root); 451 452 scoped_ptr<ScrollAndScaleSet> scroll_info; 453 454 scroll_info = host_impl_->ProcessScrollDeltas(); 455 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 456 ExpectClearedScrollDeltasRecursive(root); 457 458 scroll_info = host_impl_->ProcessScrollDeltas(); 459 ASSERT_EQ(scroll_info->scrolls.size(), 0u); 460 ExpectClearedScrollDeltasRecursive(root); 461 } 462 463 TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { 464 gfx::Vector2d scroll_offset(20, 30); 465 gfx::Vector2d scroll_delta(11, -15); 466 { 467 scoped_ptr<LayerImpl> root_clip = 468 LayerImpl::Create(host_impl_->active_tree(), 2); 469 scoped_ptr<LayerImpl> root = 470 LayerImpl::Create(host_impl_->active_tree(), 1); 471 root_clip->SetBounds(gfx::Size(10, 10)); 472 LayerImpl* root_layer = root.get(); 473 root_clip->AddChild(root.Pass()); 474 root_layer->SetBounds(gfx::Size(110, 110)); 475 root_layer->SetScrollClipLayer(root_clip->id()); 476 root_layer->SetScrollOffset(scroll_offset); 477 root_layer->ScrollBy(scroll_delta); 478 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 479 } 480 LayerImpl* root = host_impl_->active_tree()->root_layer()->children()[0]; 481 482 scoped_ptr<ScrollAndScaleSet> scroll_info; 483 484 scroll_info = host_impl_->ProcessScrollDeltas(); 485 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 486 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta); 487 ExpectContains(*scroll_info, root->id(), scroll_delta); 488 489 gfx::Vector2d scroll_delta2(-5, 27); 490 root->ScrollBy(scroll_delta2); 491 scroll_info = host_impl_->ProcessScrollDeltas(); 492 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 493 EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2); 494 ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2); 495 496 root->ScrollBy(gfx::Vector2d()); 497 scroll_info = host_impl_->ProcessScrollDeltas(); 498 EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2); 499 } 500 501 TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { 502 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 503 host_impl_->SetViewportSize(gfx::Size(50, 50)); 504 DrawFrame(); 505 506 EXPECT_EQ(InputHandler::ScrollStarted, 507 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 508 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(), 509 InputHandler::Wheel)); 510 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 511 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10), 512 InputHandler::Wheel)); 513 host_impl_->ScrollEnd(); 514 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(), 515 InputHandler::Wheel)); 516 EXPECT_TRUE(did_request_redraw_); 517 EXPECT_TRUE(did_request_commit_); 518 } 519 520 TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { 521 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 522 host_impl_->SetViewportSize(gfx::Size(50, 50)); 523 DrawFrame(); 524 525 EXPECT_EQ(InputHandler::ScrollStarted, 526 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 527 EXPECT_FALSE(host_impl_->IsActivelyScrolling()); 528 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 529 EXPECT_TRUE(host_impl_->IsActivelyScrolling()); 530 host_impl_->ScrollEnd(); 531 EXPECT_FALSE(host_impl_->IsActivelyScrolling()); 532 } 533 534 TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) { 535 // We should not crash when trying to scroll an empty layer tree. 536 EXPECT_EQ(InputHandler::ScrollIgnored, 537 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 538 } 539 540 TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { 541 scoped_ptr<TestWebGraphicsContext3D> context_owned = 542 TestWebGraphicsContext3D::Create(); 543 context_owned->set_context_lost(true); 544 545 scoped_ptr<FakeOutputSurface> output_surface(FakeOutputSurface::Create3d( 546 context_owned.Pass())); 547 548 // Initialization will fail. 549 EXPECT_FALSE(CreateHostImpl(DefaultSettings(), 550 output_surface.PassAs<OutputSurface>())); 551 552 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 553 554 // We should not crash when trying to scroll after the renderer initialization 555 // fails. 556 EXPECT_EQ(InputHandler::ScrollStarted, 557 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 558 } 559 560 TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { 561 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 562 host_impl_->SetViewportSize(gfx::Size(50, 50)); 563 DrawFrame(); 564 565 // We should not crash if the tree is replaced while we are scrolling. 566 EXPECT_EQ(InputHandler::ScrollStarted, 567 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 568 host_impl_->active_tree()->DetachLayerTree(); 569 570 scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 571 572 // We should still be scrolling, because the scrolled layer also exists in the 573 // new tree. 574 gfx::Vector2d scroll_delta(0, 10); 575 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 576 host_impl_->ScrollEnd(); 577 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 578 ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta); 579 } 580 581 TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) { 582 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 583 host_impl_->SetViewportSize(gfx::Size(50, 50)); 584 DrawFrame(); 585 586 // We should be able to scroll even if the root layer loses its render surface 587 // after the most recent render. 588 host_impl_->active_tree()->root_layer()->ClearRenderSurface(); 589 host_impl_->active_tree()->set_needs_update_draw_properties(); 590 591 EXPECT_EQ(InputHandler::ScrollStarted, 592 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 593 } 594 595 TEST_F(LayerTreeHostImplTest, WheelEventHandlers) { 596 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 597 host_impl_->SetViewportSize(gfx::Size(50, 50)); 598 DrawFrame(); 599 LayerImpl* root = host_impl_->active_tree()->root_layer(); 600 601 root->SetHaveWheelEventHandlers(true); 602 603 // With registered event handlers, wheel scrolls have to go to the main 604 // thread. 605 EXPECT_EQ(InputHandler::ScrollOnMainThread, 606 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 607 608 // But gesture scrolls can still be handled. 609 EXPECT_EQ(InputHandler::ScrollStarted, 610 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 611 } 612 613 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) { 614 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 615 host_impl_->SetViewportSize(gfx::Size(50, 50)); 616 DrawFrame(); 617 618 // Ignore the fling since no layer is being scrolled 619 EXPECT_EQ(InputHandler::ScrollIgnored, 620 host_impl_->FlingScrollBegin()); 621 622 // Start scrolling a layer 623 EXPECT_EQ(InputHandler::ScrollStarted, 624 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 625 626 // Now the fling should go ahead since we've started scrolling a layer 627 EXPECT_EQ(InputHandler::ScrollStarted, 628 host_impl_->FlingScrollBegin()); 629 } 630 631 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) { 632 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 633 host_impl_->SetViewportSize(gfx::Size(50, 50)); 634 DrawFrame(); 635 636 // Ignore the fling since no layer is being scrolled 637 EXPECT_EQ(InputHandler::ScrollIgnored, 638 host_impl_->FlingScrollBegin()); 639 640 // Start scrolling a layer 641 EXPECT_EQ(InputHandler::ScrollStarted, 642 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 643 644 // Now the fling should go ahead since we've started scrolling a layer 645 EXPECT_EQ(InputHandler::ScrollStarted, 646 host_impl_->FlingScrollBegin()); 647 } 648 649 TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) { 650 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 651 host_impl_->SetViewportSize(gfx::Size(50, 50)); 652 DrawFrame(); 653 LayerImpl* root = host_impl_->active_tree()->root_layer(); 654 655 root->SetShouldScrollOnMainThread(true); 656 657 // Start scrolling a layer 658 EXPECT_EQ(InputHandler::ScrollOnMainThread, 659 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 660 661 // The fling should be ignored since there's no layer being scrolled impl-side 662 EXPECT_EQ(InputHandler::ScrollIgnored, 663 host_impl_->FlingScrollBegin()); 664 } 665 666 TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { 667 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 668 host_impl_->SetViewportSize(gfx::Size(50, 50)); 669 DrawFrame(); 670 LayerImpl* root = host_impl_->active_tree()->root_layer(); 671 672 root->SetShouldScrollOnMainThread(true); 673 674 EXPECT_EQ(InputHandler::ScrollOnMainThread, 675 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 676 EXPECT_EQ(InputHandler::ScrollOnMainThread, 677 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 678 } 679 680 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { 681 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 682 host_impl_->SetViewportSize(gfx::Size(100, 100)); 683 684 LayerImpl* root = host_impl_->active_tree()->root_layer(); 685 root->SetContentsScale(2.f, 2.f); 686 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); 687 688 DrawFrame(); 689 690 // All scroll types inside the non-fast scrollable region should fail. 691 EXPECT_EQ(InputHandler::ScrollOnMainThread, 692 host_impl_->ScrollBegin(gfx::Point(25, 25), 693 InputHandler::Wheel)); 694 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25), 695 InputHandler::Wheel)); 696 EXPECT_EQ(InputHandler::ScrollOnMainThread, 697 host_impl_->ScrollBegin(gfx::Point(25, 25), 698 InputHandler::Gesture)); 699 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25), 700 InputHandler::Gesture)); 701 702 // All scroll types outside this region should succeed. 703 EXPECT_EQ(InputHandler::ScrollStarted, 704 host_impl_->ScrollBegin(gfx::Point(75, 75), 705 InputHandler::Wheel)); 706 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), 707 InputHandler::Gesture)); 708 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 709 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25), 710 InputHandler::Gesture)); 711 host_impl_->ScrollEnd(); 712 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), 713 InputHandler::Gesture)); 714 EXPECT_EQ(InputHandler::ScrollStarted, 715 host_impl_->ScrollBegin(gfx::Point(75, 75), 716 InputHandler::Gesture)); 717 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), 718 InputHandler::Gesture)); 719 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 720 host_impl_->ScrollEnd(); 721 EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75), 722 InputHandler::Gesture)); 723 } 724 725 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { 726 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 727 host_impl_->SetViewportSize(gfx::Size(100, 100)); 728 729 LayerImpl* root = host_impl_->active_tree()->root_layer(); 730 root->SetContentsScale(2.f, 2.f); 731 root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); 732 root->SetPosition(gfx::PointF(-25.f, 0.f)); 733 734 DrawFrame(); 735 736 // This point would fall into the non-fast scrollable region except that we've 737 // moved the layer down by 25 pixels. 738 EXPECT_EQ(InputHandler::ScrollStarted, 739 host_impl_->ScrollBegin(gfx::Point(40, 10), 740 InputHandler::Wheel)); 741 EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10), 742 InputHandler::Wheel)); 743 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1)); 744 host_impl_->ScrollEnd(); 745 746 // This point is still inside the non-fast region. 747 EXPECT_EQ(InputHandler::ScrollOnMainThread, 748 host_impl_->ScrollBegin(gfx::Point(10, 10), 749 InputHandler::Wheel)); 750 } 751 752 TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { 753 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); 754 EXPECT_FALSE(scroll_layer->have_scroll_event_handlers()); 755 host_impl_->SetViewportSize(gfx::Size(50, 50)); 756 DrawFrame(); 757 758 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); 759 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 760 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); 761 host_impl_->ScrollEnd(); 762 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); 763 } 764 765 TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { 766 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); 767 scroll_layer->SetHaveScrollEventHandlers(true); 768 host_impl_->SetViewportSize(gfx::Size(50, 50)); 769 DrawFrame(); 770 771 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); 772 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 773 EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler()); 774 host_impl_->ScrollEnd(); 775 EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); 776 } 777 778 TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { 779 SetupScrollAndContentsLayers(gfx::Size(200, 200)); 780 host_impl_->SetViewportSize(gfx::Size(100, 100)); 781 782 DrawFrame(); 783 784 EXPECT_EQ(InputHandler::ScrollStarted, 785 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 786 787 // Trying to scroll to the left/top will not succeed. 788 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 789 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); 790 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); 791 792 // Scrolling to the right/bottom will succeed. 793 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0))); 794 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10))); 795 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10))); 796 797 // Scrolling to left/top will now succeed. 798 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 799 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10))); 800 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10))); 801 802 // Scrolling diagonally against an edge will succeed. 803 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10))); 804 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0))); 805 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10))); 806 807 // Trying to scroll more than the available space will also succeed. 808 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000))); 809 } 810 811 TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) { 812 SetupScrollAndContentsLayers(gfx::Size(200, 2000)); 813 host_impl_->SetViewportSize(gfx::Size(100, 1000)); 814 815 DrawFrame(); 816 817 EXPECT_EQ(InputHandler::ScrollStarted, 818 host_impl_->ScrollBegin(gfx::Point(), 819 InputHandler::Wheel)); 820 821 // Trying to scroll without a vertical scrollbar will fail. 822 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( 823 gfx::Point(), SCROLL_FORWARD)); 824 EXPECT_FALSE(host_impl_->ScrollVerticallyByPage( 825 gfx::Point(), SCROLL_BACKWARD)); 826 827 scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar( 828 PaintedScrollbarLayerImpl::Create( 829 host_impl_->active_tree(), 830 20, 831 VERTICAL)); 832 vertical_scrollbar->SetBounds(gfx::Size(15, 1000)); 833 host_impl_->InnerViewportScrollLayer()->AddScrollbar( 834 vertical_scrollbar.get()); 835 836 // Trying to scroll with a vertical scrollbar will succeed. 837 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage( 838 gfx::Point(), SCROLL_FORWARD)); 839 EXPECT_FLOAT_EQ(875.f, 840 host_impl_->InnerViewportScrollLayer()->ScrollDelta().y()); 841 EXPECT_TRUE(host_impl_->ScrollVerticallyByPage( 842 gfx::Point(), SCROLL_BACKWARD)); 843 } 844 845 // The user-scrollability breaks for zoomed-in pages. So disable this. 846 // http://crbug.com/322223 847 TEST_F(LayerTreeHostImplTest, DISABLED_ScrollWithUserUnscrollableLayers) { 848 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200)); 849 host_impl_->SetViewportSize(gfx::Size(100, 100)); 850 851 gfx::Size overflow_size(400, 400); 852 ASSERT_EQ(1u, scroll_layer->children().size()); 853 LayerImpl* overflow = scroll_layer->children()[0]; 854 overflow->SetBounds(overflow_size); 855 overflow->SetContentBounds(overflow_size); 856 overflow->SetScrollClipLayer(scroll_layer->parent()->id()); 857 overflow->SetScrollOffset(gfx::Vector2d()); 858 overflow->SetPosition(gfx::PointF()); 859 860 DrawFrame(); 861 gfx::Point scroll_position(10, 10); 862 863 EXPECT_EQ(InputHandler::ScrollStarted, 864 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 865 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 866 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset()); 867 868 gfx::Vector2dF scroll_delta(10, 10); 869 host_impl_->ScrollBy(scroll_position, scroll_delta); 870 host_impl_->ScrollEnd(); 871 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 872 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); 873 874 overflow->set_user_scrollable_horizontal(false); 875 876 EXPECT_EQ(InputHandler::ScrollStarted, 877 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 878 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset()); 879 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset()); 880 881 host_impl_->ScrollBy(scroll_position, scroll_delta); 882 host_impl_->ScrollEnd(); 883 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); 884 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 885 886 overflow->set_user_scrollable_vertical(false); 887 888 EXPECT_EQ(InputHandler::ScrollStarted, 889 host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel)); 890 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset()); 891 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 892 893 host_impl_->ScrollBy(scroll_position, scroll_delta); 894 host_impl_->ScrollEnd(); 895 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset()); 896 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset()); 897 } 898 899 TEST_F(LayerTreeHostImplTest, 900 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) { 901 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 902 host_impl_->SetViewportSize(gfx::Size(50, 50)); 903 DrawFrame(); 904 905 // We should be able to hit test for touch event handlers even if the root 906 // layer loses its render surface after the most recent render. 907 host_impl_->active_tree()->root_layer()->ClearRenderSurface(); 908 host_impl_->active_tree()->set_needs_update_draw_properties(); 909 910 EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false); 911 } 912 913 TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { 914 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 915 host_impl_->SetViewportSize(gfx::Size(50, 50)); 916 DrawFrame(); 917 918 EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); 919 LayerImpl* container_layer = scroll_layer->scroll_clip_layer(); 920 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); 921 922 float min_page_scale = 1.f, max_page_scale = 4.f; 923 float page_scale_factor = 1.f; 924 925 // The impl-based pinch zoom should adjust the max scroll position. 926 { 927 host_impl_->active_tree()->SetPageScaleFactorAndLimits( 928 page_scale_factor, min_page_scale, max_page_scale); 929 host_impl_->active_tree()->SetPageScaleDelta(1.f); 930 scroll_layer->SetScrollDelta(gfx::Vector2d()); 931 932 float page_scale_delta = 2.f; 933 gfx::Vector2dF expected_container_size_delta( 934 container_layer->bounds().width(), container_layer->bounds().height()); 935 expected_container_size_delta.Scale((1.f - page_scale_delta) / 936 (page_scale_factor * page_scale_delta)); 937 938 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 939 host_impl_->PinchGestureBegin(); 940 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 941 // While the gesture is still active, the scroll layer should have a 942 // container size delta = container->bounds() * ((1.f - 943 // page_scale_delta)/()) 944 EXPECT_EQ(expected_container_size_delta, 945 scroll_layer->FixedContainerSizeDelta()); 946 host_impl_->PinchGestureEnd(); 947 host_impl_->ScrollEnd(); 948 EXPECT_FALSE(did_request_animate_); 949 EXPECT_TRUE(did_request_redraw_); 950 EXPECT_TRUE(did_request_commit_); 951 EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); 952 953 scoped_ptr<ScrollAndScaleSet> scroll_info = 954 host_impl_->ProcessScrollDeltas(); 955 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 956 957 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(), 958 scroll_layer->MaxScrollOffset().ToString()); 959 } 960 961 // Scrolling after a pinch gesture should always be in local space. The 962 // scroll deltas do not have the page scale factor applied. 963 { 964 host_impl_->active_tree()->SetPageScaleFactorAndLimits( 965 page_scale_factor, min_page_scale, max_page_scale); 966 host_impl_->active_tree()->SetPageScaleDelta(1.f); 967 scroll_layer->SetScrollDelta(gfx::Vector2d()); 968 969 float page_scale_delta = 2.f; 970 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 971 host_impl_->PinchGestureBegin(); 972 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); 973 host_impl_->PinchGestureEnd(); 974 host_impl_->ScrollEnd(); 975 976 gfx::Vector2d scroll_delta(0, 10); 977 EXPECT_EQ(InputHandler::ScrollStarted, 978 host_impl_->ScrollBegin(gfx::Point(5, 5), 979 InputHandler::Wheel)); 980 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 981 host_impl_->ScrollEnd(); 982 983 scoped_ptr<ScrollAndScaleSet> scroll_info = 984 host_impl_->ProcessScrollDeltas(); 985 ExpectContains(*scroll_info.get(), 986 scroll_layer->id(), 987 scroll_delta); 988 } 989 } 990 991 TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { 992 ui::LatencyInfo latency_info; 993 latency_info.trace_id = 1234; 994 scoped_ptr<SwapPromise> swap_promise( 995 new LatencyInfoSwapPromise(latency_info)); 996 997 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 998 EXPECT_EQ(InputHandler::ScrollStarted, 999 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 1000 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 1001 host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise.Pass()); 1002 host_impl_->ScrollEnd(); 1003 1004 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 1005 EXPECT_EQ(1u, scroll_info->swap_promises.size()); 1006 EXPECT_EQ(latency_info.trace_id, scroll_info->swap_promises[0]->TraceId()); 1007 } 1008 1009 TEST_F(LayerTreeHostImplTest, PinchGesture) { 1010 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1011 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1012 DrawFrame(); 1013 1014 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); 1015 DCHECK(scroll_layer); 1016 1017 float min_page_scale = 1.f; 1018 float max_page_scale = 4.f; 1019 1020 // Basic pinch zoom in gesture 1021 { 1022 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1023 min_page_scale, 1024 max_page_scale); 1025 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1026 1027 float page_scale_delta = 2.f; 1028 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 1029 host_impl_->PinchGestureBegin(); 1030 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 1031 host_impl_->PinchGestureEnd(); 1032 host_impl_->ScrollEnd(); 1033 EXPECT_FALSE(did_request_animate_); 1034 EXPECT_TRUE(did_request_redraw_); 1035 EXPECT_TRUE(did_request_commit_); 1036 1037 scoped_ptr<ScrollAndScaleSet> scroll_info = 1038 host_impl_->ProcessScrollDeltas(); 1039 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 1040 } 1041 1042 // Zoom-in clamping 1043 { 1044 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1045 min_page_scale, 1046 max_page_scale); 1047 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1048 float page_scale_delta = 10.f; 1049 1050 host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture); 1051 host_impl_->PinchGestureBegin(); 1052 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50)); 1053 host_impl_->PinchGestureEnd(); 1054 host_impl_->ScrollEnd(); 1055 1056 scoped_ptr<ScrollAndScaleSet> scroll_info = 1057 host_impl_->ProcessScrollDeltas(); 1058 EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale); 1059 } 1060 1061 // Zoom-out clamping 1062 { 1063 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1064 min_page_scale, 1065 max_page_scale); 1066 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1067 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1068 1069 float page_scale_delta = 0.1f; 1070 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 1071 host_impl_->PinchGestureBegin(); 1072 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point()); 1073 host_impl_->PinchGestureEnd(); 1074 host_impl_->ScrollEnd(); 1075 1076 scoped_ptr<ScrollAndScaleSet> scroll_info = 1077 host_impl_->ProcessScrollDeltas(); 1078 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); 1079 1080 EXPECT_TRUE(scroll_info->scrolls.empty()); 1081 } 1082 1083 // Two-finger panning should not happen based on pinch events only 1084 { 1085 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1086 min_page_scale, 1087 max_page_scale); 1088 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1089 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); 1090 1091 float page_scale_delta = 1.f; 1092 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); 1093 host_impl_->PinchGestureBegin(); 1094 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); 1095 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); 1096 host_impl_->PinchGestureEnd(); 1097 host_impl_->ScrollEnd(); 1098 1099 scoped_ptr<ScrollAndScaleSet> scroll_info = 1100 host_impl_->ProcessScrollDeltas(); 1101 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 1102 EXPECT_TRUE(scroll_info->scrolls.empty()); 1103 } 1104 1105 // Two-finger panning should work with interleaved scroll events 1106 { 1107 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1108 min_page_scale, 1109 max_page_scale); 1110 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1111 scroll_layer->SetScrollOffset(gfx::Vector2d(20, 20)); 1112 1113 float page_scale_delta = 1.f; 1114 host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture); 1115 host_impl_->PinchGestureBegin(); 1116 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10)); 1117 host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10)); 1118 host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20)); 1119 host_impl_->PinchGestureEnd(); 1120 host_impl_->ScrollEnd(); 1121 1122 scoped_ptr<ScrollAndScaleSet> scroll_info = 1123 host_impl_->ProcessScrollDeltas(); 1124 EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); 1125 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10)); 1126 } 1127 1128 // Two-finger panning should work when starting fully zoomed out. 1129 { 1130 host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f, 1131 0.5f, 1132 4.f); 1133 scroll_layer->SetScrollDelta(gfx::Vector2d()); 1134 scroll_layer->SetScrollOffset(gfx::Vector2d(0, 0)); 1135 1136 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture); 1137 host_impl_->PinchGestureBegin(); 1138 host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0)); 1139 host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0)); 1140 host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10)); 1141 host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10)); 1142 host_impl_->PinchGestureEnd(); 1143 host_impl_->ScrollEnd(); 1144 1145 scoped_ptr<ScrollAndScaleSet> scroll_info = 1146 host_impl_->ProcessScrollDeltas(); 1147 EXPECT_EQ(scroll_info->page_scale_delta, 2.f); 1148 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20)); 1149 } 1150 } 1151 1152 TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { 1153 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1154 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1155 DrawFrame(); 1156 1157 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); 1158 DCHECK(scroll_layer); 1159 1160 float min_page_scale = 0.5f; 1161 float max_page_scale = 4.f; 1162 base::TimeTicks start_time = base::TimeTicks() + 1163 base::TimeDelta::FromSeconds(1); 1164 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); 1165 base::TimeTicks halfway_through_animation = start_time + duration / 2; 1166 base::TimeTicks end_time = start_time + duration; 1167 1168 // Non-anchor zoom-in 1169 { 1170 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1171 min_page_scale, 1172 max_page_scale); 1173 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1174 1175 did_request_redraw_ = false; 1176 did_request_animate_ = false; 1177 host_impl_->active_tree()->SetPageScaleAnimation( 1178 gfx::Vector2d(), false, 2.f, duration); 1179 host_impl_->ActivateSyncTree(); 1180 EXPECT_FALSE(did_request_redraw_); 1181 EXPECT_TRUE(did_request_animate_); 1182 1183 did_request_redraw_ = false; 1184 did_request_animate_ = false; 1185 host_impl_->Animate(start_time); 1186 EXPECT_TRUE(did_request_redraw_); 1187 EXPECT_TRUE(did_request_animate_); 1188 1189 did_request_redraw_ = false; 1190 did_request_animate_ = false; 1191 host_impl_->Animate(halfway_through_animation); 1192 EXPECT_TRUE(did_request_redraw_); 1193 EXPECT_TRUE(did_request_animate_); 1194 1195 did_request_redraw_ = false; 1196 did_request_animate_ = false; 1197 did_request_commit_ = false; 1198 host_impl_->Animate(end_time); 1199 EXPECT_TRUE(did_request_commit_); 1200 EXPECT_FALSE(did_request_animate_); 1201 1202 scoped_ptr<ScrollAndScaleSet> scroll_info = 1203 host_impl_->ProcessScrollDeltas(); 1204 EXPECT_EQ(scroll_info->page_scale_delta, 2); 1205 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); 1206 } 1207 1208 // Anchor zoom-out 1209 { 1210 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1211 min_page_scale, 1212 max_page_scale); 1213 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1214 1215 did_request_redraw_ = false; 1216 did_request_animate_ = false; 1217 host_impl_->active_tree()->SetPageScaleAnimation( 1218 gfx::Vector2d(25, 25), true, min_page_scale, duration); 1219 host_impl_->ActivateSyncTree(); 1220 EXPECT_FALSE(did_request_redraw_); 1221 EXPECT_TRUE(did_request_animate_); 1222 1223 did_request_redraw_ = false; 1224 did_request_animate_ = false; 1225 host_impl_->Animate(start_time); 1226 EXPECT_TRUE(did_request_redraw_); 1227 EXPECT_TRUE(did_request_animate_); 1228 1229 did_request_redraw_ = false; 1230 did_request_commit_ = false; 1231 did_request_animate_ = false; 1232 host_impl_->Animate(end_time); 1233 EXPECT_TRUE(did_request_redraw_); 1234 EXPECT_FALSE(did_request_animate_); 1235 EXPECT_TRUE(did_request_commit_); 1236 1237 scoped_ptr<ScrollAndScaleSet> scroll_info = 1238 host_impl_->ProcessScrollDeltas(); 1239 EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); 1240 // Pushed to (0,0) via clamping against contents layer size. 1241 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); 1242 } 1243 } 1244 1245 TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { 1246 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1247 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1248 DrawFrame(); 1249 1250 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); 1251 DCHECK(scroll_layer); 1252 1253 float min_page_scale = 0.5f; 1254 float max_page_scale = 4.f; 1255 base::TimeTicks start_time = base::TimeTicks() + 1256 base::TimeDelta::FromSeconds(1); 1257 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); 1258 base::TimeTicks halfway_through_animation = start_time + duration / 2; 1259 base::TimeTicks end_time = start_time + duration; 1260 1261 // Anchor zoom with unchanged page scale should not change scroll or scale. 1262 { 1263 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1264 min_page_scale, 1265 max_page_scale); 1266 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1267 1268 host_impl_->active_tree()->SetPageScaleAnimation( 1269 gfx::Vector2d(), true, 1.f, duration); 1270 host_impl_->ActivateSyncTree(); 1271 host_impl_->Animate(start_time); 1272 host_impl_->Animate(halfway_through_animation); 1273 EXPECT_TRUE(did_request_redraw_); 1274 host_impl_->Animate(end_time); 1275 EXPECT_TRUE(did_request_commit_); 1276 1277 scoped_ptr<ScrollAndScaleSet> scroll_info = 1278 host_impl_->ProcessScrollDeltas(); 1279 EXPECT_EQ(scroll_info->page_scale_delta, 1); 1280 ExpectNone(*scroll_info, scroll_layer->id()); 1281 } 1282 } 1283 1284 TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { 1285 host_impl_->CreatePendingTree(); 1286 CreateScrollAndContentsLayers(host_impl_->pending_tree(), 1287 gfx::Size(100, 100)); 1288 host_impl_->ActivateSyncTree(); 1289 DrawFrame(); 1290 1291 LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); 1292 DCHECK(scroll_layer); 1293 1294 float min_page_scale = 0.5f; 1295 float max_page_scale = 4.f; 1296 host_impl_->sync_tree()->SetPageScaleFactorAndLimits( 1297 1.f, min_page_scale, max_page_scale); 1298 host_impl_->ActivateSyncTree(); 1299 1300 base::TimeTicks start_time = 1301 base::TimeTicks() + base::TimeDelta::FromSeconds(1); 1302 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100); 1303 base::TimeTicks third_through_animation = start_time + duration / 3; 1304 base::TimeTicks halfway_through_animation = start_time + duration / 2; 1305 base::TimeTicks end_time = start_time + duration; 1306 float target_scale = 2.f; 1307 1308 scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50)); 1309 1310 // Make sure TakePageScaleAnimation works properly. 1311 host_impl_->sync_tree()->SetPageScaleAnimation( 1312 gfx::Vector2d(), false, target_scale, duration); 1313 scoped_ptr<PageScaleAnimation> psa = 1314 host_impl_->sync_tree()->TakePageScaleAnimation(); 1315 EXPECT_EQ(target_scale, psa->target_page_scale_factor()); 1316 EXPECT_EQ(duration, psa->duration()); 1317 EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation()); 1318 1319 // Recreate the PSA. Nothing should happen here since the tree containing the 1320 // PSA hasn't been activated yet. 1321 did_request_redraw_ = false; 1322 did_request_animate_ = false; 1323 host_impl_->sync_tree()->SetPageScaleAnimation( 1324 gfx::Vector2d(), false, target_scale, duration); 1325 host_impl_->Animate(halfway_through_animation); 1326 EXPECT_FALSE(did_request_animate_); 1327 EXPECT_FALSE(did_request_redraw_); 1328 1329 // Activate the sync tree. This should cause the animation to become enabled. 1330 // It should also clear the pointer on the sync tree. 1331 host_impl_->ActivateSyncTree(); 1332 EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation().get()); 1333 EXPECT_FALSE(did_request_redraw_); 1334 EXPECT_TRUE(did_request_animate_); 1335 1336 // From here on, make sure the animation runs as normal. 1337 did_request_redraw_ = false; 1338 did_request_animate_ = false; 1339 host_impl_->Animate(start_time); 1340 EXPECT_TRUE(did_request_redraw_); 1341 EXPECT_TRUE(did_request_animate_); 1342 1343 did_request_redraw_ = false; 1344 did_request_animate_ = false; 1345 host_impl_->Animate(third_through_animation); 1346 EXPECT_TRUE(did_request_redraw_); 1347 EXPECT_TRUE(did_request_animate_); 1348 1349 // Another activation shouldn't have any effect on the animation. 1350 host_impl_->ActivateSyncTree(); 1351 1352 did_request_redraw_ = false; 1353 did_request_animate_ = false; 1354 host_impl_->Animate(halfway_through_animation); 1355 EXPECT_TRUE(did_request_redraw_); 1356 EXPECT_TRUE(did_request_animate_); 1357 1358 did_request_redraw_ = false; 1359 did_request_animate_ = false; 1360 did_request_commit_ = false; 1361 host_impl_->Animate(end_time); 1362 EXPECT_TRUE(did_request_commit_); 1363 EXPECT_FALSE(did_request_animate_); 1364 1365 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 1366 EXPECT_EQ(scroll_info->page_scale_delta, target_scale); 1367 ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50)); 1368 } 1369 1370 class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { 1371 public: 1372 LayerTreeHostImplOverridePhysicalTime( 1373 const LayerTreeSettings& settings, 1374 LayerTreeHostImplClient* client, 1375 Proxy* proxy, 1376 SharedBitmapManager* manager, 1377 RenderingStatsInstrumentation* rendering_stats_instrumentation) 1378 : LayerTreeHostImpl(settings, 1379 client, 1380 proxy, 1381 rendering_stats_instrumentation, 1382 manager, 1383 0) {} 1384 1385 virtual BeginFrameArgs CurrentBeginFrameArgs() const OVERRIDE { 1386 return CreateBeginFrameArgsForTesting(fake_current_physical_time_); 1387 } 1388 1389 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) { 1390 fake_current_physical_time_ = fake_now; 1391 } 1392 1393 private: 1394 base::TimeTicks fake_current_physical_time_; 1395 }; 1396 1397 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \ 1398 gfx::Size viewport_size(10, 10); \ 1399 gfx::Size content_size(100, 100); \ 1400 \ 1401 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \ 1402 new LayerTreeHostImplOverridePhysicalTime(settings, \ 1403 this, \ 1404 &proxy_, \ 1405 shared_bitmap_manager_.get(), \ 1406 &stats_instrumentation_); \ 1407 host_impl_ = make_scoped_ptr(host_impl_override_time); \ 1408 host_impl_->InitializeRenderer(CreateOutputSurface()); \ 1409 host_impl_->SetViewportSize(viewport_size); \ 1410 \ 1411 scoped_ptr<LayerImpl> root = \ 1412 LayerImpl::Create(host_impl_->active_tree(), 1); \ 1413 root->SetBounds(viewport_size); \ 1414 \ 1415 scoped_ptr<LayerImpl> scroll = \ 1416 LayerImpl::Create(host_impl_->active_tree(), 2); \ 1417 scroll->SetScrollClipLayer(root->id()); \ 1418 scroll->SetScrollOffset(gfx::Vector2d()); \ 1419 root->SetBounds(viewport_size); \ 1420 scroll->SetBounds(content_size); \ 1421 scroll->SetContentBounds(content_size); \ 1422 scroll->SetIsContainerForFixedPositionLayers(true); \ 1423 \ 1424 scoped_ptr<LayerImpl> contents = \ 1425 LayerImpl::Create(host_impl_->active_tree(), 3); \ 1426 contents->SetDrawsContent(true); \ 1427 contents->SetBounds(content_size); \ 1428 contents->SetContentBounds(content_size); \ 1429 \ 1430 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \ 1431 SolidColorScrollbarLayerImpl::Create( \ 1432 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \ 1433 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \ 1434 \ 1435 scroll->AddChild(contents.Pass()); \ 1436 root->AddChild(scroll.Pass()); \ 1437 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \ 1438 root->AddChild(scrollbar.PassAs<LayerImpl>()); \ 1439 \ 1440 host_impl_->active_tree()->SetRootLayer(root.Pass()); \ 1441 host_impl_->active_tree()->SetViewportLayersFromIds( \ 1442 1, 2, Layer::INVALID_ID); \ 1443 host_impl_->active_tree()->DidBecomeActive(); \ 1444 DrawFrame(); 1445 1446 TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) { 1447 LayerTreeSettings settings; 1448 settings.scrollbar_animator = LayerTreeSettings::LinearFade; 1449 settings.scrollbar_fade_delay_ms = 20; 1450 settings.scrollbar_fade_duration_ms = 20; 1451 1452 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST(); 1453 1454 base::TimeTicks fake_now = gfx::FrameTime::Now(); 1455 1456 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1457 EXPECT_FALSE(did_request_redraw_); 1458 1459 // If no scroll happened during a scroll gesture, it should have no effect. 1460 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1461 host_impl_->ScrollEnd(); 1462 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1463 EXPECT_FALSE(did_request_redraw_); 1464 EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure())); 1465 1466 // After a scroll, a fade animation should be scheduled about 20ms from now. 1467 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1468 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5)); 1469 host_impl_->ScrollEnd(); 1470 did_request_redraw_ = false; 1471 did_request_animate_ = false; 1472 EXPECT_LT(base::TimeDelta::FromMilliseconds(19), 1473 requested_scrollbar_animation_delay_); 1474 EXPECT_FALSE(did_request_redraw_); 1475 EXPECT_FALSE(did_request_animate_); 1476 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1477 scrollbar_fade_start_.Run(); 1478 host_impl_->Animate(fake_now); 1479 1480 // After the fade begins, we should start getting redraws instead of a 1481 // scheduled animation. 1482 fake_now += base::TimeDelta::FromMilliseconds(25); 1483 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1484 EXPECT_TRUE(did_request_animate_); 1485 did_request_animate_ = false; 1486 1487 // Setting the scroll offset outside a scroll should also cause the scrollbar 1488 // to appear and to schedule a fade. 1489 host_impl_->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5)); 1490 EXPECT_LT(base::TimeDelta::FromMilliseconds(19), 1491 requested_scrollbar_animation_delay_); 1492 EXPECT_FALSE(did_request_redraw_); 1493 EXPECT_FALSE(did_request_animate_); 1494 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1495 1496 // Unnecessarily Fade animation of solid color scrollbar is not triggered. 1497 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1498 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); 1499 host_impl_->ScrollEnd(); 1500 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1501 } 1502 1503 TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) { 1504 LayerTreeSettings settings; 1505 settings.scrollbar_animator = LayerTreeSettings::LinearFade; 1506 settings.scrollbar_fade_delay_ms = 20; 1507 settings.scrollbar_fade_duration_ms = 20; 1508 settings.use_pinch_zoom_scrollbars = true; 1509 1510 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST(); 1511 1512 base::TimeTicks fake_now = gfx::FrameTime::Now(); 1513 1514 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); 1515 1516 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1517 EXPECT_FALSE(did_request_animate_); 1518 1519 // If no scroll happened during a scroll gesture, it should have no effect. 1520 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1521 host_impl_->ScrollEnd(); 1522 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1523 EXPECT_FALSE(did_request_animate_); 1524 EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure())); 1525 1526 // After a scroll, no fade animation should be scheduled. 1527 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1528 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); 1529 host_impl_->ScrollEnd(); 1530 did_request_redraw_ = false; 1531 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1532 EXPECT_FALSE(did_request_animate_); 1533 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1534 1535 // We should not see any draw requests. 1536 fake_now += base::TimeDelta::FromMilliseconds(25); 1537 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_); 1538 EXPECT_FALSE(did_request_animate_); 1539 1540 // Make page scale > min so that subsequent scrolls will trigger fades. 1541 host_impl_->active_tree()->SetPageScaleDelta(1.1f); 1542 1543 // After a scroll, a fade animation should be scheduled about 20ms from now. 1544 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel); 1545 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0)); 1546 host_impl_->ScrollEnd(); 1547 did_request_redraw_ = false; 1548 EXPECT_LT(base::TimeDelta::FromMilliseconds(19), 1549 requested_scrollbar_animation_delay_); 1550 EXPECT_FALSE(did_request_animate_); 1551 requested_scrollbar_animation_delay_ = base::TimeDelta(); 1552 scrollbar_fade_start_.Run(); 1553 1554 // After the fade begins, we should start getting redraws instead of a 1555 // scheduled animation. 1556 fake_now += base::TimeDelta::FromMilliseconds(25); 1557 host_impl_->Animate(fake_now); 1558 EXPECT_TRUE(did_request_animate_); 1559 } 1560 1561 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( 1562 float device_scale_factor) { 1563 LayerTreeSettings settings; 1564 settings.scrollbar_fade_delay_ms = 500; 1565 settings.scrollbar_fade_duration_ms = 300; 1566 settings.scrollbar_animator = LayerTreeSettings::Thinning; 1567 1568 gfx::Size viewport_size(300, 200); 1569 gfx::Size device_viewport_size = gfx::ToFlooredSize( 1570 gfx::ScaleSize(viewport_size, device_scale_factor)); 1571 gfx::Size content_size(1000, 1000); 1572 1573 CreateHostImpl(settings, CreateOutputSurface()); 1574 host_impl_->SetDeviceScaleFactor(device_scale_factor); 1575 host_impl_->SetViewportSize(device_viewport_size); 1576 1577 scoped_ptr<LayerImpl> root = 1578 LayerImpl::Create(host_impl_->active_tree(), 1); 1579 root->SetBounds(viewport_size); 1580 1581 scoped_ptr<LayerImpl> scroll = 1582 LayerImpl::Create(host_impl_->active_tree(), 2); 1583 scroll->SetScrollClipLayer(root->id()); 1584 scroll->SetScrollOffset(gfx::Vector2d()); 1585 scroll->SetBounds(content_size); 1586 scroll->SetContentBounds(content_size); 1587 scroll->SetIsContainerForFixedPositionLayers(true); 1588 1589 scoped_ptr<LayerImpl> contents = 1590 LayerImpl::Create(host_impl_->active_tree(), 3); 1591 contents->SetDrawsContent(true); 1592 contents->SetBounds(content_size); 1593 contents->SetContentBounds(content_size); 1594 1595 // The scrollbar is on the right side. 1596 scoped_ptr<PaintedScrollbarLayerImpl> scrollbar = 1597 PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL); 1598 scrollbar->SetDrawsContent(true); 1599 scrollbar->SetBounds(gfx::Size(15, viewport_size.height())); 1600 scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height())); 1601 scrollbar->SetPosition(gfx::Point(285, 0)); 1602 1603 scroll->AddChild(contents.Pass()); 1604 root->AddChild(scroll.Pass()); 1605 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); 1606 root->AddChild(scrollbar.PassAs<LayerImpl>()); 1607 1608 host_impl_->active_tree()->SetRootLayer(root.Pass()); 1609 host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID); 1610 host_impl_->active_tree()->DidBecomeActive(); 1611 DrawFrame(); 1612 1613 LayerImpl* root_scroll = 1614 host_impl_->active_tree()->InnerViewportScrollLayer(); 1615 ASSERT_TRUE(root_scroll->scrollbar_animation_controller()); 1616 ScrollbarAnimationControllerThinning* scrollbar_animation_controller = 1617 static_cast<ScrollbarAnimationControllerThinning*>( 1618 root_scroll->scrollbar_animation_controller()); 1619 scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f); 1620 1621 host_impl_->MouseMoveAt(gfx::Point(1, 1)); 1622 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1623 1624 host_impl_->MouseMoveAt(gfx::Point(200, 50)); 1625 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1626 1627 host_impl_->MouseMoveAt(gfx::Point(184, 100)); 1628 EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1629 1630 scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f); 1631 host_impl_->MouseMoveAt(gfx::Point(184, 100)); 1632 EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); 1633 1634 did_request_redraw_ = false; 1635 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1636 host_impl_->MouseMoveAt(gfx::Point(290, 100)); 1637 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1638 host_impl_->MouseMoveAt(gfx::Point(290, 120)); 1639 EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1640 host_impl_->MouseMoveAt(gfx::Point(150, 120)); 1641 EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); 1642 } 1643 1644 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) { 1645 SetupMouseMoveAtWithDeviceScale(1.f); 1646 } 1647 1648 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { 1649 SetupMouseMoveAtWithDeviceScale(2.f); 1650 } 1651 1652 TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { 1653 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 1654 host_impl_->SetViewportSize(gfx::Size(50, 50)); 1655 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 1656 DrawFrame(); 1657 { 1658 CompositorFrameMetadata metadata = 1659 host_impl_->MakeCompositorFrameMetadata(); 1660 EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset); 1661 EXPECT_EQ(1.f, metadata.page_scale_factor); 1662 EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size); 1663 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1664 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1665 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1666 } 1667 1668 // Scrolling should update metadata immediately. 1669 EXPECT_EQ(InputHandler::ScrollStarted, 1670 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 1671 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 1672 { 1673 CompositorFrameMetadata metadata = 1674 host_impl_->MakeCompositorFrameMetadata(); 1675 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1676 } 1677 host_impl_->ScrollEnd(); 1678 { 1679 CompositorFrameMetadata metadata = 1680 host_impl_->MakeCompositorFrameMetadata(); 1681 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1682 } 1683 1684 // Page scale should update metadata correctly (shrinking only the viewport). 1685 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 1686 host_impl_->PinchGestureBegin(); 1687 host_impl_->PinchGestureUpdate(2.f, gfx::Point()); 1688 host_impl_->PinchGestureEnd(); 1689 host_impl_->ScrollEnd(); 1690 { 1691 CompositorFrameMetadata metadata = 1692 host_impl_->MakeCompositorFrameMetadata(); 1693 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1694 EXPECT_EQ(2.f, metadata.page_scale_factor); 1695 EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size); 1696 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1697 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1698 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1699 } 1700 1701 // Likewise if set from the main thread. 1702 host_impl_->ProcessScrollDeltas(); 1703 host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f); 1704 host_impl_->active_tree()->SetPageScaleDelta(1.f); 1705 { 1706 CompositorFrameMetadata metadata = 1707 host_impl_->MakeCompositorFrameMetadata(); 1708 EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset); 1709 EXPECT_EQ(4.f, metadata.page_scale_factor); 1710 EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size); 1711 EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size); 1712 EXPECT_EQ(0.5f, metadata.min_page_scale_factor); 1713 EXPECT_EQ(4.f, metadata.max_page_scale_factor); 1714 } 1715 } 1716 1717 class DidDrawCheckLayer : public LayerImpl { 1718 public: 1719 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 1720 return scoped_ptr<LayerImpl>(new DidDrawCheckLayer(tree_impl, id)); 1721 } 1722 1723 virtual bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) 1724 OVERRIDE { 1725 will_draw_called_ = true; 1726 if (will_draw_returns_false_) 1727 return false; 1728 return LayerImpl::WillDraw(draw_mode, provider); 1729 } 1730 1731 virtual void AppendQuads(RenderPass* render_pass, 1732 const OcclusionTracker<LayerImpl>& occlusion_tracker, 1733 AppendQuadsData* append_quads_data) OVERRIDE { 1734 append_quads_called_ = true; 1735 LayerImpl::AppendQuads(render_pass, occlusion_tracker, append_quads_data); 1736 } 1737 1738 virtual void DidDraw(ResourceProvider* provider) OVERRIDE { 1739 did_draw_called_ = true; 1740 LayerImpl::DidDraw(provider); 1741 } 1742 1743 bool will_draw_called() const { return will_draw_called_; } 1744 bool append_quads_called() const { return append_quads_called_; } 1745 bool did_draw_called() const { return did_draw_called_; } 1746 1747 void set_will_draw_returns_false() { will_draw_returns_false_ = true; } 1748 1749 void ClearDidDrawCheck() { 1750 will_draw_called_ = false; 1751 append_quads_called_ = false; 1752 did_draw_called_ = false; 1753 } 1754 1755 protected: 1756 DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id) 1757 : LayerImpl(tree_impl, id), 1758 will_draw_returns_false_(false), 1759 will_draw_called_(false), 1760 append_quads_called_(false), 1761 did_draw_called_(false) { 1762 SetBounds(gfx::Size(10, 10)); 1763 SetContentBounds(gfx::Size(10, 10)); 1764 SetDrawsContent(true); 1765 draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10); 1766 } 1767 1768 private: 1769 bool will_draw_returns_false_; 1770 bool will_draw_called_; 1771 bool append_quads_called_; 1772 bool did_draw_called_; 1773 }; 1774 1775 TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { 1776 // The root layer is always drawn, so run this test on a child layer that 1777 // will be masked out by the root layer's bounds. 1778 host_impl_->active_tree()->SetRootLayer( 1779 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1780 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( 1781 host_impl_->active_tree()->root_layer()); 1782 1783 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1784 DidDrawCheckLayer* layer = 1785 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1786 1787 { 1788 LayerTreeHostImpl::FrameData frame; 1789 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1790 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1791 host_impl_->DidDrawAllLayers(frame); 1792 1793 EXPECT_TRUE(layer->will_draw_called()); 1794 EXPECT_TRUE(layer->append_quads_called()); 1795 EXPECT_TRUE(layer->did_draw_called()); 1796 } 1797 1798 host_impl_->SetViewportDamage(gfx::Rect(10, 10)); 1799 1800 { 1801 LayerTreeHostImpl::FrameData frame; 1802 1803 layer->set_will_draw_returns_false(); 1804 layer->ClearDidDrawCheck(); 1805 1806 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1807 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1808 host_impl_->DidDrawAllLayers(frame); 1809 1810 EXPECT_TRUE(layer->will_draw_called()); 1811 EXPECT_FALSE(layer->append_quads_called()); 1812 EXPECT_FALSE(layer->did_draw_called()); 1813 } 1814 } 1815 1816 TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { 1817 // The root layer is always drawn, so run this test on a child layer that 1818 // will be masked out by the root layer's bounds. 1819 host_impl_->active_tree()->SetRootLayer( 1820 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1821 DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>( 1822 host_impl_->active_tree()->root_layer()); 1823 root->SetMasksToBounds(true); 1824 1825 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1826 DidDrawCheckLayer* layer = 1827 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1828 // Ensure visible_content_rect for layer is empty. 1829 layer->SetPosition(gfx::PointF(100.f, 100.f)); 1830 layer->SetBounds(gfx::Size(10, 10)); 1831 layer->SetContentBounds(gfx::Size(10, 10)); 1832 1833 LayerTreeHostImpl::FrameData frame; 1834 1835 EXPECT_FALSE(layer->will_draw_called()); 1836 EXPECT_FALSE(layer->did_draw_called()); 1837 1838 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1839 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1840 host_impl_->DidDrawAllLayers(frame); 1841 1842 EXPECT_FALSE(layer->will_draw_called()); 1843 EXPECT_FALSE(layer->did_draw_called()); 1844 1845 EXPECT_TRUE(layer->visible_content_rect().IsEmpty()); 1846 1847 // Ensure visible_content_rect for layer is not empty 1848 layer->SetPosition(gfx::PointF()); 1849 1850 EXPECT_FALSE(layer->will_draw_called()); 1851 EXPECT_FALSE(layer->did_draw_called()); 1852 1853 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1854 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1855 host_impl_->DidDrawAllLayers(frame); 1856 1857 EXPECT_TRUE(layer->will_draw_called()); 1858 EXPECT_TRUE(layer->did_draw_called()); 1859 1860 EXPECT_FALSE(layer->visible_content_rect().IsEmpty()); 1861 } 1862 1863 TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { 1864 gfx::Size big_size(1000, 1000); 1865 host_impl_->SetViewportSize(big_size); 1866 1867 host_impl_->active_tree()->SetRootLayer( 1868 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1869 DidDrawCheckLayer* root = 1870 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1871 1872 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1873 DidDrawCheckLayer* occluded_layer = 1874 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1875 1876 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 1877 DidDrawCheckLayer* top_layer = 1878 static_cast<DidDrawCheckLayer*>(root->children()[1]); 1879 // This layer covers the occluded_layer above. Make this layer large so it can 1880 // occlude. 1881 top_layer->SetBounds(big_size); 1882 top_layer->SetContentBounds(big_size); 1883 top_layer->SetContentsOpaque(true); 1884 1885 LayerTreeHostImpl::FrameData frame; 1886 1887 EXPECT_FALSE(occluded_layer->will_draw_called()); 1888 EXPECT_FALSE(occluded_layer->did_draw_called()); 1889 EXPECT_FALSE(top_layer->will_draw_called()); 1890 EXPECT_FALSE(top_layer->did_draw_called()); 1891 1892 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1893 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1894 host_impl_->DidDrawAllLayers(frame); 1895 1896 EXPECT_FALSE(occluded_layer->will_draw_called()); 1897 EXPECT_FALSE(occluded_layer->did_draw_called()); 1898 EXPECT_TRUE(top_layer->will_draw_called()); 1899 EXPECT_TRUE(top_layer->did_draw_called()); 1900 } 1901 1902 TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { 1903 host_impl_->active_tree()->SetRootLayer( 1904 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1905 DidDrawCheckLayer* root = 1906 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1907 1908 root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); 1909 DidDrawCheckLayer* layer1 = 1910 static_cast<DidDrawCheckLayer*>(root->children()[0]); 1911 1912 layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 1913 DidDrawCheckLayer* layer2 = 1914 static_cast<DidDrawCheckLayer*>(layer1->children()[0]); 1915 1916 layer1->SetOpacity(0.3f); 1917 layer1->SetShouldFlattenTransform(true); 1918 1919 EXPECT_FALSE(root->did_draw_called()); 1920 EXPECT_FALSE(layer1->did_draw_called()); 1921 EXPECT_FALSE(layer2->did_draw_called()); 1922 1923 LayerTreeHostImpl::FrameData frame; 1924 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren( 1925 host_impl_->active_tree()->root_layer()); 1926 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 1927 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 1928 host_impl_->DidDrawAllLayers(frame); 1929 1930 EXPECT_TRUE(root->did_draw_called()); 1931 EXPECT_TRUE(layer1->did_draw_called()); 1932 EXPECT_TRUE(layer2->did_draw_called()); 1933 1934 EXPECT_NE(root->render_surface(), layer1->render_surface()); 1935 EXPECT_TRUE(!!layer1->render_surface()); 1936 } 1937 1938 class MissingTextureAnimatingLayer : public DidDrawCheckLayer { 1939 public: 1940 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, 1941 int id, 1942 bool tile_missing, 1943 bool had_incomplete_tile, 1944 bool animating, 1945 ResourceProvider* resource_provider) { 1946 return scoped_ptr<LayerImpl>( 1947 new MissingTextureAnimatingLayer(tree_impl, 1948 id, 1949 tile_missing, 1950 had_incomplete_tile, 1951 animating, 1952 resource_provider)); 1953 } 1954 1955 virtual void AppendQuads(RenderPass* render_pass, 1956 const OcclusionTracker<LayerImpl>& occlusion_tracker, 1957 AppendQuadsData* append_quads_data) OVERRIDE { 1958 LayerImpl::AppendQuads(render_pass, occlusion_tracker, append_quads_data); 1959 if (had_incomplete_tile_) 1960 append_quads_data->num_incomplete_tiles++; 1961 if (tile_missing_) 1962 append_quads_data->num_missing_tiles++; 1963 } 1964 1965 private: 1966 MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl, 1967 int id, 1968 bool tile_missing, 1969 bool had_incomplete_tile, 1970 bool animating, 1971 ResourceProvider* resource_provider) 1972 : DidDrawCheckLayer(tree_impl, id), 1973 tile_missing_(tile_missing), 1974 had_incomplete_tile_(had_incomplete_tile) { 1975 if (animating) 1976 AddAnimatedTransformToLayer(this, 10.0, 3, 0); 1977 } 1978 1979 bool tile_missing_; 1980 bool had_incomplete_tile_; 1981 }; 1982 1983 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsOnDefault) { 1984 host_impl_->active_tree()->SetRootLayer( 1985 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 1986 DidDrawCheckLayer* root = 1987 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 1988 1989 bool tile_missing = false; 1990 bool had_incomplete_tile = false; 1991 bool is_animating = false; 1992 root->AddChild( 1993 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 1994 2, 1995 tile_missing, 1996 had_incomplete_tile, 1997 is_animating, 1998 host_impl_->resource_provider())); 1999 2000 LayerTreeHostImpl::FrameData frame; 2001 2002 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2003 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2004 host_impl_->DidDrawAllLayers(frame); 2005 } 2006 2007 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithAnimatedLayer) { 2008 host_impl_->active_tree()->SetRootLayer( 2009 DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); 2010 DidDrawCheckLayer* root = 2011 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2012 bool tile_missing = false; 2013 bool had_incomplete_tile = false; 2014 bool is_animating = true; 2015 root->AddChild( 2016 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2017 2, 2018 tile_missing, 2019 had_incomplete_tile, 2020 is_animating, 2021 host_impl_->resource_provider())); 2022 2023 LayerTreeHostImpl::FrameData frame; 2024 2025 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2026 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2027 host_impl_->DidDrawAllLayers(frame); 2028 } 2029 2030 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithMissingTiles) { 2031 host_impl_->active_tree()->SetRootLayer( 2032 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 2033 DidDrawCheckLayer* root = 2034 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2035 2036 LayerTreeHostImpl::FrameData frame; 2037 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2038 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2039 host_impl_->DidDrawAllLayers(frame); 2040 host_impl_->SwapBuffers(frame); 2041 2042 bool tile_missing = true; 2043 bool had_incomplete_tile = false; 2044 bool is_animating = false; 2045 root->AddChild( 2046 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2047 4, 2048 tile_missing, 2049 had_incomplete_tile, 2050 is_animating, 2051 host_impl_->resource_provider())); 2052 LayerTreeHostImpl::FrameData frame2; 2053 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); 2054 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2055 host_impl_->DidDrawAllLayers(frame2); 2056 } 2057 2058 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithIncompleteTile) { 2059 host_impl_->active_tree()->SetRootLayer( 2060 DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); 2061 DidDrawCheckLayer* root = 2062 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2063 2064 LayerTreeHostImpl::FrameData frame; 2065 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2066 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2067 host_impl_->DidDrawAllLayers(frame); 2068 host_impl_->SwapBuffers(frame); 2069 2070 bool tile_missing = false; 2071 bool had_incomplete_tile = true; 2072 bool is_animating = false; 2073 root->AddChild( 2074 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2075 4, 2076 tile_missing, 2077 had_incomplete_tile, 2078 is_animating, 2079 host_impl_->resource_provider())); 2080 LayerTreeHostImpl::FrameData frame2; 2081 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); 2082 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2083 host_impl_->DidDrawAllLayers(frame2); 2084 } 2085 2086 TEST_F(LayerTreeHostImplTest, 2087 PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard) { 2088 host_impl_->active_tree()->SetRootLayer( 2089 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5)); 2090 DidDrawCheckLayer* root = 2091 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2092 2093 LayerTreeHostImpl::FrameData frame; 2094 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2095 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2096 host_impl_->DidDrawAllLayers(frame); 2097 host_impl_->SwapBuffers(frame); 2098 2099 bool tile_missing = true; 2100 bool had_incomplete_tile = false; 2101 bool is_animating = true; 2102 root->AddChild( 2103 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2104 6, 2105 tile_missing, 2106 had_incomplete_tile, 2107 is_animating, 2108 host_impl_->resource_provider())); 2109 LayerTreeHostImpl::FrameData frame2; 2110 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS, 2111 host_impl_->PrepareToDraw(&frame2)); 2112 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2113 host_impl_->DidDrawAllLayers(frame2); 2114 } 2115 2116 TEST_F(LayerTreeHostImplTest, 2117 PrepareToDrawSucceedsWithAnimationAndIncompleteTiles) { 2118 host_impl_->active_tree()->SetRootLayer( 2119 DidDrawCheckLayer::Create(host_impl_->active_tree(), 5)); 2120 DidDrawCheckLayer* root = 2121 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2122 2123 LayerTreeHostImpl::FrameData frame; 2124 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2125 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2126 host_impl_->DidDrawAllLayers(frame); 2127 host_impl_->SwapBuffers(frame); 2128 2129 bool tile_missing = false; 2130 bool had_incomplete_tile = true; 2131 bool is_animating = true; 2132 root->AddChild( 2133 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2134 6, 2135 tile_missing, 2136 had_incomplete_tile, 2137 is_animating, 2138 host_impl_->resource_provider())); 2139 LayerTreeHostImpl::FrameData frame2; 2140 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); 2141 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2142 host_impl_->DidDrawAllLayers(frame2); 2143 } 2144 2145 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWhenHighResRequired) { 2146 host_impl_->active_tree()->SetRootLayer( 2147 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); 2148 DidDrawCheckLayer* root = 2149 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2150 2151 LayerTreeHostImpl::FrameData frame; 2152 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2153 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2154 host_impl_->DidDrawAllLayers(frame); 2155 host_impl_->SwapBuffers(frame); 2156 2157 bool tile_missing = false; 2158 bool had_incomplete_tile = false; 2159 bool is_animating = false; 2160 root->AddChild( 2161 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2162 8, 2163 tile_missing, 2164 had_incomplete_tile, 2165 is_animating, 2166 host_impl_->resource_provider())); 2167 host_impl_->active_tree()->SetRequiresHighResToDraw(); 2168 LayerTreeHostImpl::FrameData frame2; 2169 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); 2170 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2171 host_impl_->DidDrawAllLayers(frame2); 2172 } 2173 2174 TEST_F(LayerTreeHostImplTest, 2175 PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles) { 2176 host_impl_->active_tree()->SetRootLayer( 2177 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); 2178 DidDrawCheckLayer* root = 2179 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2180 2181 LayerTreeHostImpl::FrameData frame; 2182 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2183 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2184 host_impl_->DidDrawAllLayers(frame); 2185 host_impl_->SwapBuffers(frame); 2186 2187 bool tile_missing = false; 2188 bool had_incomplete_tile = true; 2189 bool is_animating = false; 2190 root->AddChild( 2191 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2192 8, 2193 tile_missing, 2194 had_incomplete_tile, 2195 is_animating, 2196 host_impl_->resource_provider())); 2197 host_impl_->active_tree()->SetRequiresHighResToDraw(); 2198 LayerTreeHostImpl::FrameData frame2; 2199 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT, 2200 host_impl_->PrepareToDraw(&frame2)); 2201 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2202 host_impl_->DidDrawAllLayers(frame2); 2203 } 2204 2205 TEST_F(LayerTreeHostImplTest, 2206 PrepareToDrawFailsWhenHighResRequiredAndMissingTile) { 2207 host_impl_->active_tree()->SetRootLayer( 2208 DidDrawCheckLayer::Create(host_impl_->active_tree(), 7)); 2209 DidDrawCheckLayer* root = 2210 static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer()); 2211 2212 LayerTreeHostImpl::FrameData frame; 2213 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2214 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2215 host_impl_->DidDrawAllLayers(frame); 2216 host_impl_->SwapBuffers(frame); 2217 2218 bool tile_missing = true; 2219 bool had_incomplete_tile = false; 2220 bool is_animating = false; 2221 root->AddChild( 2222 MissingTextureAnimatingLayer::Create(host_impl_->active_tree(), 2223 8, 2224 tile_missing, 2225 had_incomplete_tile, 2226 is_animating, 2227 host_impl_->resource_provider())); 2228 host_impl_->active_tree()->SetRequiresHighResToDraw(); 2229 LayerTreeHostImpl::FrameData frame2; 2230 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT, 2231 host_impl_->PrepareToDraw(&frame2)); 2232 host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now()); 2233 host_impl_->DidDrawAllLayers(frame2); 2234 } 2235 2236 TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { 2237 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2238 root->SetScrollClipLayer(Layer::INVALID_ID); 2239 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2240 DrawFrame(); 2241 2242 // Scroll event is ignored because layer is not scrollable. 2243 EXPECT_EQ(InputHandler::ScrollIgnored, 2244 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 2245 EXPECT_FALSE(did_request_redraw_); 2246 EXPECT_FALSE(did_request_commit_); 2247 } 2248 2249 class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { 2250 public: 2251 LayerTreeHostImplTopControlsTest() 2252 // Make the clip size the same as the layer (content) size so the layer is 2253 // non-scrollable. 2254 : layer_size_(10, 10), 2255 clip_size_(layer_size_) { 2256 settings_.calculate_top_controls_position = true; 2257 settings_.top_controls_height = 50; 2258 2259 viewport_size_ = 2260 gfx::Size(clip_size_.width(), 2261 clip_size_.height() + settings_.top_controls_height); 2262 } 2263 2264 void SetupTopControlsAndScrollLayer() { 2265 scoped_ptr<LayerImpl> root = 2266 LayerImpl::Create(host_impl_->active_tree(), 1); 2267 scoped_ptr<LayerImpl> root_clip = 2268 LayerImpl::Create(host_impl_->active_tree(), 2); 2269 root_clip->SetBounds(clip_size_); 2270 root->SetScrollClipLayer(root_clip->id()); 2271 root->SetBounds(layer_size_); 2272 root->SetContentBounds(layer_size_); 2273 root->SetPosition(gfx::PointF()); 2274 root->SetDrawsContent(false); 2275 root->SetIsContainerForFixedPositionLayers(true); 2276 int inner_viewport_scroll_layer_id = root->id(); 2277 int page_scale_layer_id = root_clip->id(); 2278 root_clip->AddChild(root.Pass()); 2279 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 2280 host_impl_->active_tree()->SetViewportLayersFromIds( 2281 page_scale_layer_id, inner_viewport_scroll_layer_id, Layer::INVALID_ID); 2282 // Set a viewport size that is large enough to contain both the top controls 2283 // and some content. 2284 host_impl_->SetViewportSize(viewport_size_); 2285 host_impl_->SetTopControlsLayoutHeight( 2286 settings_.top_controls_height); 2287 2288 host_impl_->CreatePendingTree(); 2289 root = 2290 LayerImpl::Create(host_impl_->sync_tree(), 1); 2291 root_clip = 2292 LayerImpl::Create(host_impl_->sync_tree(), 2); 2293 root_clip->SetBounds(clip_size_); 2294 root->SetScrollClipLayer(root_clip->id()); 2295 root->SetBounds(layer_size_); 2296 root->SetContentBounds(layer_size_); 2297 root->SetPosition(gfx::PointF()); 2298 root->SetDrawsContent(false); 2299 root->SetIsContainerForFixedPositionLayers(true); 2300 inner_viewport_scroll_layer_id = root->id(); 2301 page_scale_layer_id = root_clip->id(); 2302 root_clip->AddChild(root.Pass()); 2303 host_impl_->sync_tree()->SetRootLayer(root_clip.Pass()); 2304 host_impl_->sync_tree()->SetViewportLayersFromIds( 2305 page_scale_layer_id, inner_viewport_scroll_layer_id, Layer::INVALID_ID); 2306 // Set a viewport size that is large enough to contain both the top controls 2307 // and some content. 2308 host_impl_->SetViewportSize(viewport_size_); 2309 host_impl_->sync_tree()->set_top_controls_layout_height( 2310 settings_.top_controls_height); 2311 } 2312 2313 protected: 2314 gfx::Size layer_size_; 2315 gfx::Size clip_size_; 2316 gfx::Size viewport_size_; 2317 2318 LayerTreeSettings settings_; 2319 }; // class LayerTreeHostImplTopControlsTest 2320 2321 TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { 2322 CreateHostImpl(settings_, CreateOutputSurface()); 2323 SetupTopControlsAndScrollLayer(); 2324 DrawFrame(); 2325 2326 EXPECT_EQ(InputHandler::ScrollStarted, 2327 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2328 2329 // Make the test scroll delta a fractional amount, to verify that the 2330 // fixed container size delta is (1) non-zero, and (2) fractional, and 2331 // (3) matches the movement of the top controls. 2332 gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f); 2333 host_impl_->top_controls_manager()->ScrollBegin(); 2334 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); 2335 host_impl_->top_controls_manager()->ScrollEnd(); 2336 2337 LayerImpl* inner_viewport_scroll_layer = 2338 host_impl_->active_tree()->InnerViewportScrollLayer(); 2339 DCHECK(inner_viewport_scroll_layer); 2340 host_impl_->ScrollEnd(); 2341 EXPECT_EQ(top_controls_scroll_delta, 2342 inner_viewport_scroll_layer->FixedContainerSizeDelta()); 2343 } 2344 2345 TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsWithPageScale) { 2346 CreateHostImpl(settings_, CreateOutputSurface()); 2347 SetupTopControlsAndScrollLayer(); 2348 DrawFrame(); 2349 2350 EXPECT_EQ(InputHandler::ScrollStarted, 2351 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2352 2353 float page_scale = 1.5f; 2354 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f); 2355 2356 gfx::Vector2dF top_controls_scroll_delta(0.f, 5.f); 2357 gfx::Vector2dF expected_container_size_delta = 2358 ScaleVector2d(top_controls_scroll_delta, 1.f / page_scale); 2359 host_impl_->top_controls_manager()->ScrollBegin(); 2360 host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); 2361 host_impl_->top_controls_manager()->ScrollEnd(); 2362 2363 LayerImpl* inner_viewport_scroll_layer = 2364 host_impl_->active_tree()->InnerViewportScrollLayer(); 2365 DCHECK(inner_viewport_scroll_layer); 2366 host_impl_->ScrollEnd(); 2367 2368 // Use a tolerance that requires the container size delta to be within 0.01 2369 // pixels. 2370 double tolerance = 0.0001; 2371 EXPECT_LT( 2372 (expected_container_size_delta - 2373 inner_viewport_scroll_layer->FixedContainerSizeDelta()).LengthSquared(), 2374 tolerance); 2375 } 2376 2377 // Ensure setting the top controls position explicitly using the setters on the 2378 // TreeImpl correctly affects the top controls manager and viewport bounds. 2379 TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) { 2380 CreateHostImpl(settings_, CreateOutputSurface()); 2381 SetupTopControlsAndScrollLayer(); 2382 DrawFrame(); 2383 2384 host_impl_->active_tree()->set_top_controls_delta(0.f); 2385 host_impl_->active_tree()->set_top_controls_content_offset(30.f); 2386 EXPECT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2387 EXPECT_EQ(-20.f, host_impl_->top_controls_manager()->ControlsTopOffset()); 2388 2389 host_impl_->active_tree()->set_top_controls_delta(-30.f); 2390 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2391 EXPECT_EQ(-50.f, host_impl_->top_controls_manager()->ControlsTopOffset()); 2392 2393 host_impl_->DidChangeTopControlsPosition(); 2394 2395 // Now that top controls have moved, expect the clip to resize. 2396 LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); 2397 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2398 } 2399 2400 // Test that the top_controls delta and sent delta are appropriately 2401 // applied on sync tree activation. The total top controls offset shouldn't 2402 // change after the activation. 2403 TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) { 2404 CreateHostImpl(settings_, CreateOutputSurface()); 2405 SetupTopControlsAndScrollLayer(); 2406 DrawFrame(); 2407 2408 host_impl_->sync_tree()->set_top_controls_content_offset(15.f); 2409 2410 host_impl_->active_tree()->set_top_controls_content_offset(20.f); 2411 host_impl_->active_tree()->set_top_controls_delta(-20.f); 2412 host_impl_->active_tree()->set_sent_top_controls_delta(-5.f); 2413 2414 host_impl_->DidChangeTopControlsPosition(); 2415 LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); 2416 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2417 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2418 EXPECT_EQ(0.f, 2419 host_impl_->active_tree()->total_top_controls_content_offset()); 2420 2421 host_impl_->ActivateSyncTree(); 2422 2423 root_clip_ptr = host_impl_->active_tree()->root_layer(); 2424 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2425 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2426 2427 EXPECT_EQ(0.f, host_impl_->active_tree()->sent_top_controls_delta()); 2428 EXPECT_EQ(-15.f, host_impl_->active_tree()->top_controls_delta()); 2429 EXPECT_EQ(15.f, host_impl_->active_tree()->top_controls_content_offset()); 2430 EXPECT_EQ(0.f, 2431 host_impl_->active_tree()->total_top_controls_content_offset()); 2432 } 2433 2434 // Test that changing the top controls layout height is correctly applied to 2435 // the inner viewport container bounds. That is, the top controls layout 2436 // height is the amount that the inner viewport container was shrunk outside 2437 // the compositor to accommodate the top controls. 2438 TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) { 2439 CreateHostImpl(settings_, CreateOutputSurface()); 2440 SetupTopControlsAndScrollLayer(); 2441 DrawFrame(); 2442 2443 host_impl_->sync_tree()->set_top_controls_content_offset(15.f); 2444 host_impl_->sync_tree()->set_top_controls_layout_height(15.f); 2445 2446 host_impl_->active_tree()->set_top_controls_content_offset(20.f); 2447 host_impl_->active_tree()->set_top_controls_delta(-20.f); 2448 host_impl_->active_tree()->set_sent_top_controls_delta(-5.f); 2449 2450 host_impl_->DidChangeTopControlsPosition(); 2451 LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); 2452 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2453 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2454 2455 host_impl_->sync_tree()->root_layer()->SetBounds( 2456 gfx::Size(root_clip_ptr->bounds().width(), 2457 root_clip_ptr->bounds().height() - 15.f)); 2458 2459 host_impl_->ActivateSyncTree(); 2460 2461 root_clip_ptr = host_impl_->active_tree()->root_layer(); 2462 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2463 2464 // The total bounds should remain unchanged since the bounds delta should 2465 // account for the difference between the layout height and the current 2466 // top controls offset. 2467 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2468 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 15.f), root_clip_ptr->bounds_delta()); 2469 2470 host_impl_->active_tree()->set_top_controls_delta(0.f); 2471 host_impl_->DidChangeTopControlsPosition(); 2472 2473 EXPECT_EQ(15.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2474 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), root_clip_ptr->bounds_delta()); 2475 EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height()-15.f), 2476 root_clip_ptr->bounds()); 2477 } 2478 2479 TEST_F(LayerTreeHostImplTopControlsTest, 2480 ScrollNonScrollableRootWithTopControls) { 2481 CreateHostImpl(settings_, CreateOutputSurface()); 2482 SetupTopControlsAndScrollLayer(); 2483 DrawFrame(); 2484 2485 EXPECT_EQ(InputHandler::ScrollStarted, 2486 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2487 2488 host_impl_->top_controls_manager()->ScrollBegin(); 2489 host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); 2490 host_impl_->top_controls_manager()->ScrollEnd(); 2491 EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); 2492 // Now that top controls have moved, expect the clip to resize. 2493 LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer(); 2494 EXPECT_EQ(viewport_size_, root_clip_ptr->bounds()); 2495 2496 host_impl_->ScrollEnd(); 2497 2498 EXPECT_EQ(InputHandler::ScrollStarted, 2499 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2500 2501 float scroll_increment_y = -25.f; 2502 host_impl_->top_controls_manager()->ScrollBegin(); 2503 host_impl_->top_controls_manager()->ScrollBy( 2504 gfx::Vector2dF(0.f, scroll_increment_y)); 2505 EXPECT_EQ(-scroll_increment_y, 2506 host_impl_->top_controls_manager()->ContentTopOffset()); 2507 // Now that top controls have moved, expect the clip to resize. 2508 EXPECT_EQ(gfx::Size(viewport_size_.width(), 2509 viewport_size_.height() + scroll_increment_y), 2510 root_clip_ptr->bounds()); 2511 2512 host_impl_->top_controls_manager()->ScrollBy( 2513 gfx::Vector2dF(0.f, scroll_increment_y)); 2514 host_impl_->top_controls_manager()->ScrollEnd(); 2515 EXPECT_EQ(-2 * scroll_increment_y, 2516 host_impl_->top_controls_manager()->ContentTopOffset()); 2517 // Now that top controls have moved, expect the clip to resize. 2518 EXPECT_EQ(clip_size_, root_clip_ptr->bounds()); 2519 2520 host_impl_->ScrollEnd(); 2521 2522 // Verify the layer is once-again non-scrollable. 2523 EXPECT_EQ( 2524 gfx::Vector2d(), 2525 host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset()); 2526 2527 EXPECT_EQ(InputHandler::ScrollStarted, 2528 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 2529 } 2530 2531 TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { 2532 // Test the configuration where a non-composited root layer is embedded in a 2533 // scrollable outer layer. 2534 gfx::Size surface_size(10, 10); 2535 gfx::Size contents_size(20, 20); 2536 2537 scoped_ptr<LayerImpl> content_layer = 2538 LayerImpl::Create(host_impl_->active_tree(), 1); 2539 content_layer->SetDrawsContent(true); 2540 content_layer->SetPosition(gfx::PointF()); 2541 content_layer->SetBounds(contents_size); 2542 content_layer->SetContentBounds(contents_size); 2543 content_layer->SetContentsScale(2.f, 2.f); 2544 2545 scoped_ptr<LayerImpl> scroll_clip_layer = 2546 LayerImpl::Create(host_impl_->active_tree(), 3); 2547 scroll_clip_layer->SetBounds(surface_size); 2548 2549 scoped_ptr<LayerImpl> scroll_layer = 2550 LayerImpl::Create(host_impl_->active_tree(), 2); 2551 scroll_layer->SetScrollClipLayer(3); 2552 scroll_layer->SetBounds(contents_size); 2553 scroll_layer->SetContentBounds(contents_size); 2554 scroll_layer->SetPosition(gfx::PointF()); 2555 scroll_layer->AddChild(content_layer.Pass()); 2556 scroll_clip_layer->AddChild(scroll_layer.Pass()); 2557 2558 host_impl_->active_tree()->SetRootLayer(scroll_clip_layer.Pass()); 2559 host_impl_->SetViewportSize(surface_size); 2560 DrawFrame(); 2561 2562 EXPECT_EQ(InputHandler::ScrollStarted, 2563 host_impl_->ScrollBegin(gfx::Point(5, 5), 2564 InputHandler::Wheel)); 2565 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 2566 host_impl_->ScrollEnd(); 2567 EXPECT_TRUE(did_request_redraw_); 2568 EXPECT_TRUE(did_request_commit_); 2569 } 2570 2571 TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { 2572 gfx::Size surface_size(10, 10); 2573 gfx::Size contents_size(20, 20); 2574 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2575 root->SetBounds(surface_size); 2576 root->SetContentBounds(contents_size); 2577 root->AddChild(CreateScrollableLayer(2, contents_size, root.get())); 2578 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2579 host_impl_->SetViewportSize(surface_size); 2580 DrawFrame(); 2581 2582 EXPECT_EQ(InputHandler::ScrollStarted, 2583 host_impl_->ScrollBegin(gfx::Point(5, 5), 2584 InputHandler::Wheel)); 2585 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 2586 host_impl_->ScrollEnd(); 2587 EXPECT_TRUE(did_request_redraw_); 2588 EXPECT_TRUE(did_request_commit_); 2589 } 2590 2591 TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { 2592 gfx::Size surface_size(10, 10); 2593 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2594 root->AddChild(CreateScrollableLayer(2, surface_size, root.get())); 2595 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2596 host_impl_->SetViewportSize(surface_size); 2597 DrawFrame(); 2598 2599 // Scroll event is ignored because the input coordinate is outside the layer 2600 // boundaries. 2601 EXPECT_EQ(InputHandler::ScrollIgnored, 2602 host_impl_->ScrollBegin(gfx::Point(15, 5), 2603 InputHandler::Wheel)); 2604 EXPECT_FALSE(did_request_redraw_); 2605 EXPECT_FALSE(did_request_commit_); 2606 } 2607 2608 TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { 2609 gfx::Size surface_size(10, 10); 2610 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2611 scoped_ptr<LayerImpl> child = 2612 CreateScrollableLayer(2, surface_size, root.get()); 2613 host_impl_->SetViewportSize(surface_size); 2614 2615 gfx::Transform matrix; 2616 matrix.RotateAboutXAxis(180.0); 2617 child->SetTransform(matrix); 2618 child->SetDoubleSided(false); 2619 2620 root->AddChild(child.Pass()); 2621 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2622 DrawFrame(); 2623 2624 // Scroll event is ignored because the scrollable layer is not facing the 2625 // viewer and there is nothing scrollable behind it. 2626 EXPECT_EQ(InputHandler::ScrollIgnored, 2627 host_impl_->ScrollBegin(gfx::Point(5, 5), 2628 InputHandler::Wheel)); 2629 EXPECT_FALSE(did_request_redraw_); 2630 EXPECT_FALSE(did_request_commit_); 2631 } 2632 2633 TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { 2634 gfx::Size surface_size(10, 10); 2635 scoped_ptr<LayerImpl> clip_layer = 2636 LayerImpl::Create(host_impl_->active_tree(), 3); 2637 scoped_ptr<LayerImpl> content_layer = 2638 CreateScrollableLayer(1, surface_size, clip_layer.get()); 2639 content_layer->SetShouldScrollOnMainThread(true); 2640 content_layer->SetScrollClipLayer(Layer::INVALID_ID); 2641 2642 // Note: we can use the same clip layer for both since both calls to 2643 // CreateScrollableLayer() use the same surface size. 2644 scoped_ptr<LayerImpl> scroll_layer = 2645 CreateScrollableLayer(2, surface_size, clip_layer.get()); 2646 scroll_layer->AddChild(content_layer.Pass()); 2647 clip_layer->AddChild(scroll_layer.Pass()); 2648 2649 host_impl_->active_tree()->SetRootLayer(clip_layer.Pass()); 2650 host_impl_->SetViewportSize(surface_size); 2651 DrawFrame(); 2652 2653 // Scrolling fails because the content layer is asking to be scrolled on the 2654 // main thread. 2655 EXPECT_EQ(InputHandler::ScrollOnMainThread, 2656 host_impl_->ScrollBegin(gfx::Point(5, 5), 2657 InputHandler::Wheel)); 2658 } 2659 2660 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { 2661 gfx::Size surface_size(20, 20); 2662 gfx::Size viewport_size(10, 10); 2663 float page_scale = 2.f; 2664 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2665 scoped_ptr<LayerImpl> root_clip = 2666 LayerImpl::Create(host_impl_->active_tree(), 2); 2667 scoped_ptr<LayerImpl> root_scrolling = 2668 CreateScrollableLayer(3, surface_size, root_clip.get()); 2669 EXPECT_EQ(viewport_size, root_clip->bounds()); 2670 root_scrolling->SetIsContainerForFixedPositionLayers(true); 2671 root_clip->AddChild(root_scrolling.Pass()); 2672 root->AddChild(root_clip.Pass()); 2673 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2674 // The behaviour in this test assumes the page scale is applied at a layer 2675 // above the clip layer. 2676 host_impl_->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID); 2677 host_impl_->active_tree()->DidBecomeActive(); 2678 host_impl_->SetViewportSize(viewport_size); 2679 DrawFrame(); 2680 2681 LayerImpl* root_scroll = 2682 host_impl_->active_tree()->InnerViewportScrollLayer(); 2683 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); 2684 2685 gfx::Vector2d scroll_delta(0, 10); 2686 gfx::Vector2d expected_scroll_delta = scroll_delta; 2687 gfx::Vector2d expected_max_scroll = root_scroll->MaxScrollOffset(); 2688 EXPECT_EQ(InputHandler::ScrollStarted, 2689 host_impl_->ScrollBegin(gfx::Point(5, 5), 2690 InputHandler::Wheel)); 2691 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2692 host_impl_->ScrollEnd(); 2693 2694 // Set new page scale from main thread. 2695 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 2696 page_scale, 2697 page_scale); 2698 2699 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2700 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta); 2701 2702 // The scroll range should also have been updated. 2703 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); 2704 2705 // The page scale delta remains constant because the impl thread did not 2706 // scale. 2707 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta()); 2708 } 2709 2710 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { 2711 gfx::Size surface_size(20, 20); 2712 gfx::Size viewport_size(10, 10); 2713 float page_scale = 2.f; 2714 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2715 scoped_ptr<LayerImpl> root_clip = 2716 LayerImpl::Create(host_impl_->active_tree(), 2); 2717 scoped_ptr<LayerImpl> root_scrolling = 2718 CreateScrollableLayer(3, surface_size, root_clip.get()); 2719 EXPECT_EQ(viewport_size, root_clip->bounds()); 2720 root_scrolling->SetIsContainerForFixedPositionLayers(true); 2721 root_clip->AddChild(root_scrolling.Pass()); 2722 root->AddChild(root_clip.Pass()); 2723 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2724 // The behaviour in this test assumes the page scale is applied at a layer 2725 // above the clip layer. 2726 host_impl_->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID); 2727 host_impl_->active_tree()->DidBecomeActive(); 2728 host_impl_->SetViewportSize(viewport_size); 2729 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale); 2730 DrawFrame(); 2731 2732 LayerImpl* root_scroll = 2733 host_impl_->active_tree()->InnerViewportScrollLayer(); 2734 EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds()); 2735 2736 gfx::Vector2d scroll_delta(0, 10); 2737 gfx::Vector2d expected_scroll_delta = scroll_delta; 2738 gfx::Vector2d expected_max_scroll = root_scroll->MaxScrollOffset(); 2739 EXPECT_EQ(InputHandler::ScrollStarted, 2740 host_impl_->ScrollBegin(gfx::Point(5, 5), 2741 InputHandler::Wheel)); 2742 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2743 host_impl_->ScrollEnd(); 2744 2745 // Set new page scale on impl thread by pinching. 2746 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 2747 host_impl_->PinchGestureBegin(); 2748 host_impl_->PinchGestureUpdate(page_scale, gfx::Point()); 2749 host_impl_->PinchGestureEnd(); 2750 host_impl_->ScrollEnd(); 2751 DrawOneFrame(); 2752 2753 // The scroll delta is not scaled because the main thread did not scale. 2754 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2755 ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta); 2756 2757 // The scroll range should also have been updated. 2758 EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); 2759 2760 // The page scale delta should match the new scale on the impl side. 2761 EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor()); 2762 } 2763 2764 TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { 2765 gfx::Size surface_size(10, 10); 2766 float default_page_scale = 1.f; 2767 gfx::Transform default_page_scale_matrix; 2768 default_page_scale_matrix.Scale(default_page_scale, default_page_scale); 2769 2770 float new_page_scale = 2.f; 2771 gfx::Transform new_page_scale_matrix; 2772 new_page_scale_matrix.Scale(new_page_scale, new_page_scale); 2773 2774 // Create a normal scrollable root layer and another scrollable child layer. 2775 LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size); 2776 LayerImpl* root = host_impl_->active_tree()->root_layer(); 2777 LayerImpl* child = scroll->children()[0]; 2778 2779 scoped_ptr<LayerImpl> scrollable_child_clip = 2780 LayerImpl::Create(host_impl_->active_tree(), 6); 2781 scoped_ptr<LayerImpl> scrollable_child = 2782 CreateScrollableLayer(7, surface_size, scrollable_child_clip.get()); 2783 scrollable_child_clip->AddChild(scrollable_child.Pass()); 2784 child->AddChild(scrollable_child_clip.Pass()); 2785 LayerImpl* grand_child = child->children()[0]; 2786 2787 // Set new page scale on impl thread by pinching. 2788 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 2789 host_impl_->PinchGestureBegin(); 2790 host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point()); 2791 host_impl_->PinchGestureEnd(); 2792 host_impl_->ScrollEnd(); 2793 DrawOneFrame(); 2794 2795 EXPECT_EQ(1.f, root->contents_scale_x()); 2796 EXPECT_EQ(1.f, root->contents_scale_y()); 2797 EXPECT_EQ(1.f, scroll->contents_scale_x()); 2798 EXPECT_EQ(1.f, scroll->contents_scale_y()); 2799 EXPECT_EQ(1.f, child->contents_scale_x()); 2800 EXPECT_EQ(1.f, child->contents_scale_y()); 2801 EXPECT_EQ(1.f, grand_child->contents_scale_x()); 2802 EXPECT_EQ(1.f, grand_child->contents_scale_y()); 2803 2804 // Make sure all the layers are drawn with the page scale delta applied, i.e., 2805 // the page scale delta on the root layer is applied hierarchically. 2806 LayerTreeHostImpl::FrameData frame; 2807 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 2808 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 2809 host_impl_->DidDrawAllLayers(frame); 2810 2811 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0)); 2812 EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1)); 2813 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0)); 2814 EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1)); 2815 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0)); 2816 EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1)); 2817 EXPECT_EQ(new_page_scale, 2818 grand_child->draw_transform().matrix().getDouble(0, 0)); 2819 EXPECT_EQ(new_page_scale, 2820 grand_child->draw_transform().matrix().getDouble(1, 1)); 2821 } 2822 2823 TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { 2824 gfx::Size surface_size(30, 30); 2825 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2826 root->SetBounds(gfx::Size(5, 5)); 2827 scoped_ptr<LayerImpl> root_scrolling = 2828 LayerImpl::Create(host_impl_->active_tree(), 2); 2829 root_scrolling->SetBounds(surface_size); 2830 root_scrolling->SetContentBounds(surface_size); 2831 root_scrolling->SetScrollClipLayer(root->id()); 2832 root_scrolling->SetIsContainerForFixedPositionLayers(true); 2833 LayerImpl* root_scrolling_ptr = root_scrolling.get(); 2834 root->AddChild(root_scrolling.Pass()); 2835 int child_scroll_layer_id = 3; 2836 scoped_ptr<LayerImpl> child_scrolling = CreateScrollableLayer( 2837 child_scroll_layer_id, surface_size, root_scrolling_ptr); 2838 LayerImpl* child = child_scrolling.get(); 2839 root_scrolling_ptr->AddChild(child_scrolling.Pass()); 2840 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2841 host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID); 2842 host_impl_->active_tree()->DidBecomeActive(); 2843 host_impl_->SetViewportSize(surface_size); 2844 DrawFrame(); 2845 2846 gfx::Vector2d scroll_delta(0, 10); 2847 gfx::Vector2d expected_scroll_delta(scroll_delta); 2848 gfx::Vector2d expected_max_scroll(child->MaxScrollOffset()); 2849 EXPECT_EQ(InputHandler::ScrollStarted, 2850 host_impl_->ScrollBegin(gfx::Point(5, 5), 2851 InputHandler::Wheel)); 2852 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2853 host_impl_->ScrollEnd(); 2854 2855 float page_scale = 2.f; 2856 host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 2857 1.f, 2858 page_scale); 2859 2860 DrawOneFrame(); 2861 2862 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 2863 ExpectContains( 2864 *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta); 2865 2866 // The scroll range should not have changed. 2867 EXPECT_EQ(child->MaxScrollOffset(), expected_max_scroll); 2868 2869 // The page scale delta remains constant because the impl thread did not 2870 // scale. 2871 EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta()); 2872 } 2873 2874 TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { 2875 // Scroll a child layer beyond its maximum scroll range and make sure the 2876 // parent layer is scrolled on the axis on which the child was unable to 2877 // scroll. 2878 gfx::Size surface_size(10, 10); 2879 gfx::Size content_size(20, 20); 2880 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2881 root->SetBounds(surface_size); 2882 2883 scoped_ptr<LayerImpl> grand_child = 2884 CreateScrollableLayer(3, content_size, root.get()); 2885 2886 scoped_ptr<LayerImpl> child = 2887 CreateScrollableLayer(2, content_size, root.get()); 2888 LayerImpl* grand_child_layer = grand_child.get(); 2889 child->AddChild(grand_child.Pass()); 2890 2891 LayerImpl* child_layer = child.get(); 2892 root->AddChild(child.Pass()); 2893 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2894 host_impl_->active_tree()->DidBecomeActive(); 2895 host_impl_->SetViewportSize(surface_size); 2896 grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 5)); 2897 child_layer->SetScrollOffset(gfx::Vector2d(3, 0)); 2898 2899 DrawFrame(); 2900 { 2901 gfx::Vector2d scroll_delta(-8, -7); 2902 EXPECT_EQ(InputHandler::ScrollStarted, 2903 host_impl_->ScrollBegin(gfx::Point(), 2904 InputHandler::Wheel)); 2905 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2906 host_impl_->ScrollEnd(); 2907 2908 scoped_ptr<ScrollAndScaleSet> scroll_info = 2909 host_impl_->ProcessScrollDeltas(); 2910 2911 // The grand child should have scrolled up to its limit. 2912 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; 2913 LayerImpl* grand_child = child->children()[0]; 2914 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5)); 2915 2916 // The child should have only scrolled on the other axis. 2917 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0)); 2918 } 2919 } 2920 2921 TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { 2922 // Scroll a child layer beyond its maximum scroll range and make sure the 2923 // the scroll doesn't bubble up to the parent layer. 2924 gfx::Size surface_size(20, 20); 2925 gfx::Size viewport_size(10, 10); 2926 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 2927 scoped_ptr<LayerImpl> root_scrolling = 2928 CreateScrollableLayer(2, surface_size, root.get()); 2929 root_scrolling->SetIsContainerForFixedPositionLayers(true); 2930 2931 scoped_ptr<LayerImpl> grand_child = 2932 CreateScrollableLayer(4, surface_size, root.get()); 2933 2934 scoped_ptr<LayerImpl> child = 2935 CreateScrollableLayer(3, surface_size, root.get()); 2936 LayerImpl* grand_child_layer = grand_child.get(); 2937 child->AddChild(grand_child.Pass()); 2938 2939 LayerImpl* child_layer = child.get(); 2940 root_scrolling->AddChild(child.Pass()); 2941 root->AddChild(root_scrolling.Pass()); 2942 EXPECT_EQ(viewport_size, root->bounds()); 2943 host_impl_->active_tree()->SetRootLayer(root.Pass()); 2944 host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID); 2945 host_impl_->active_tree()->DidBecomeActive(); 2946 host_impl_->SetViewportSize(viewport_size); 2947 2948 grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 2)); 2949 child_layer->SetScrollOffset(gfx::Vector2d(0, 3)); 2950 2951 DrawFrame(); 2952 { 2953 gfx::Vector2d scroll_delta(0, -10); 2954 EXPECT_EQ(InputHandler::ScrollStarted, 2955 host_impl_->ScrollBegin(gfx::Point(), 2956 InputHandler::NonBubblingGesture)); 2957 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2958 host_impl_->ScrollEnd(); 2959 2960 scoped_ptr<ScrollAndScaleSet> scroll_info = 2961 host_impl_->ProcessScrollDeltas(); 2962 2963 // The grand child should have scrolled up to its limit. 2964 LayerImpl* child = 2965 host_impl_->active_tree()->root_layer()->children()[0]->children()[0]; 2966 LayerImpl* grand_child = child->children()[0]; 2967 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2)); 2968 2969 // The child should not have scrolled. 2970 ExpectNone(*scroll_info.get(), child->id()); 2971 2972 // The next time we scroll we should only scroll the parent. 2973 scroll_delta = gfx::Vector2d(0, -3); 2974 EXPECT_EQ(InputHandler::ScrollStarted, 2975 host_impl_->ScrollBegin(gfx::Point(5, 5), 2976 InputHandler::NonBubblingGesture)); 2977 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2978 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2979 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); 2980 host_impl_->ScrollEnd(); 2981 2982 scroll_info = host_impl_->ProcessScrollDeltas(); 2983 2984 // The child should have scrolled up to its limit. 2985 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3)); 2986 2987 // The grand child should not have scrolled. 2988 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2)); 2989 2990 // After scrolling the parent, another scroll on the opposite direction 2991 // should still scroll the child. 2992 scroll_delta = gfx::Vector2d(0, 7); 2993 EXPECT_EQ(InputHandler::ScrollStarted, 2994 host_impl_->ScrollBegin(gfx::Point(5, 5), 2995 InputHandler::NonBubblingGesture)); 2996 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2997 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 2998 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 2999 host_impl_->ScrollEnd(); 3000 3001 scroll_info = host_impl_->ProcessScrollDeltas(); 3002 3003 // The grand child should have scrolled. 3004 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5)); 3005 3006 // The child should not have scrolled. 3007 ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3)); 3008 3009 3010 // Scrolling should be adjusted from viewport space. 3011 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f); 3012 host_impl_->active_tree()->SetPageScaleDelta(1.f); 3013 3014 scroll_delta = gfx::Vector2d(0, -2); 3015 EXPECT_EQ(InputHandler::ScrollStarted, 3016 host_impl_->ScrollBegin(gfx::Point(1, 1), 3017 InputHandler::NonBubblingGesture)); 3018 EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer()); 3019 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3020 host_impl_->ScrollEnd(); 3021 3022 scroll_info = host_impl_->ProcessScrollDeltas(); 3023 3024 // Should have scrolled by half the amount in layer space (5 - 2/2) 3025 ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4)); 3026 } 3027 } 3028 TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { 3029 // When we try to scroll a non-scrollable child layer, the scroll delta 3030 // should be applied to one of its ancestors if possible. 3031 gfx::Size surface_size(10, 10); 3032 gfx::Size content_size(20, 20); 3033 scoped_ptr<LayerImpl> root_clip = 3034 LayerImpl::Create(host_impl_->active_tree(), 3); 3035 scoped_ptr<LayerImpl> root = 3036 CreateScrollableLayer(1, content_size, root_clip.get()); 3037 // Make 'root' the clip layer for child: since they have the same sizes the 3038 // child will have zero max_scroll_offset and scrolls will bubble. 3039 scoped_ptr<LayerImpl> child = 3040 CreateScrollableLayer(2, content_size, root.get()); 3041 child->SetIsContainerForFixedPositionLayers(true); 3042 root->SetBounds(content_size); 3043 3044 int root_scroll_id = root->id(); 3045 root->AddChild(child.Pass()); 3046 root_clip->AddChild(root.Pass()); 3047 3048 host_impl_->SetViewportSize(surface_size); 3049 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3050 host_impl_->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID); 3051 host_impl_->active_tree()->DidBecomeActive(); 3052 DrawFrame(); 3053 { 3054 gfx::Vector2d scroll_delta(0, 4); 3055 EXPECT_EQ(InputHandler::ScrollStarted, 3056 host_impl_->ScrollBegin(gfx::Point(5, 5), 3057 InputHandler::Wheel)); 3058 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3059 host_impl_->ScrollEnd(); 3060 3061 scoped_ptr<ScrollAndScaleSet> scroll_info = 3062 host_impl_->ProcessScrollDeltas(); 3063 3064 // Only the root scroll should have scrolled. 3065 ASSERT_EQ(scroll_info->scrolls.size(), 1u); 3066 ExpectContains(*scroll_info.get(), root_scroll_id, scroll_delta); 3067 } 3068 } 3069 3070 TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { 3071 gfx::Size surface_size(10, 10); 3072 scoped_ptr<LayerImpl> root_clip = 3073 LayerImpl::Create(host_impl_->active_tree(), 1); 3074 scoped_ptr<LayerImpl> root_scroll = 3075 CreateScrollableLayer(2, surface_size, root_clip.get()); 3076 root_scroll->SetIsContainerForFixedPositionLayers(true); 3077 root_clip->AddChild(root_scroll.Pass()); 3078 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3079 host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID); 3080 host_impl_->active_tree()->DidBecomeActive(); 3081 host_impl_->SetViewportSize(surface_size); 3082 3083 // Draw one frame and then immediately rebuild the layer tree to mimic a tree 3084 // synchronization. 3085 DrawFrame(); 3086 host_impl_->active_tree()->DetachLayerTree(); 3087 scoped_ptr<LayerImpl> root_clip2 = 3088 LayerImpl::Create(host_impl_->active_tree(), 3); 3089 scoped_ptr<LayerImpl> root_scroll2 = 3090 CreateScrollableLayer(4, surface_size, root_clip2.get()); 3091 root_scroll2->SetIsContainerForFixedPositionLayers(true); 3092 root_clip2->AddChild(root_scroll2.Pass()); 3093 host_impl_->active_tree()->SetRootLayer(root_clip2.Pass()); 3094 host_impl_->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID); 3095 host_impl_->active_tree()->DidBecomeActive(); 3096 3097 // Scrolling should still work even though we did not draw yet. 3098 EXPECT_EQ(InputHandler::ScrollStarted, 3099 host_impl_->ScrollBegin(gfx::Point(5, 5), 3100 InputHandler::Wheel)); 3101 } 3102 3103 TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { 3104 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3105 3106 // Rotate the root layer 90 degrees counter-clockwise about its center. 3107 gfx::Transform rotate_transform; 3108 rotate_transform.Rotate(-90.0); 3109 host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform); 3110 3111 gfx::Size surface_size(50, 50); 3112 host_impl_->SetViewportSize(surface_size); 3113 DrawFrame(); 3114 3115 // Scroll to the right in screen coordinates with a gesture. 3116 gfx::Vector2d gesture_scroll_delta(10, 0); 3117 EXPECT_EQ(InputHandler::ScrollStarted, 3118 host_impl_->ScrollBegin(gfx::Point(), 3119 InputHandler::Gesture)); 3120 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 3121 host_impl_->ScrollEnd(); 3122 3123 // The layer should have scrolled down in its local coordinates. 3124 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 3125 ExpectContains(*scroll_info.get(), 3126 scroll_layer->id(), 3127 gfx::Vector2d(0, gesture_scroll_delta.x())); 3128 3129 // Reset and scroll down with the wheel. 3130 scroll_layer->SetScrollDelta(gfx::Vector2dF()); 3131 gfx::Vector2d wheel_scroll_delta(0, 10); 3132 EXPECT_EQ(InputHandler::ScrollStarted, 3133 host_impl_->ScrollBegin(gfx::Point(), 3134 InputHandler::Wheel)); 3135 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta); 3136 host_impl_->ScrollEnd(); 3137 3138 // The layer should have scrolled down in its local coordinates. 3139 scroll_info = host_impl_->ProcessScrollDeltas(); 3140 ExpectContains(*scroll_info.get(), 3141 scroll_layer->id(), 3142 wheel_scroll_delta); 3143 } 3144 3145 TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { 3146 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3147 int child_clip_layer_id = 6; 3148 int child_layer_id = 7; 3149 float child_layer_angle = -20.f; 3150 3151 // Create a child layer that is rotated to a non-axis-aligned angle. 3152 scoped_ptr<LayerImpl> clip_layer = 3153 LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); 3154 scoped_ptr<LayerImpl> child = CreateScrollableLayer( 3155 child_layer_id, scroll_layer->content_bounds(), clip_layer.get()); 3156 gfx::Transform rotate_transform; 3157 rotate_transform.Translate(-50.0, -50.0); 3158 rotate_transform.Rotate(child_layer_angle); 3159 rotate_transform.Translate(50.0, 50.0); 3160 clip_layer->SetTransform(rotate_transform); 3161 3162 // Only allow vertical scrolling. 3163 clip_layer->SetBounds( 3164 gfx::Size(child->bounds().width(), child->bounds().height() / 2)); 3165 // The rotation depends on the layer's transform origin, and the child layer 3166 // is a different size than the clip, so make sure the clip layer's origin 3167 // lines up over the child. 3168 clip_layer->SetTransformOrigin(gfx::Point3F( 3169 clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f)); 3170 LayerImpl* child_ptr = child.get(); 3171 clip_layer->AddChild(child.Pass()); 3172 scroll_layer->AddChild(clip_layer.Pass()); 3173 3174 gfx::Size surface_size(50, 50); 3175 host_impl_->SetViewportSize(surface_size); 3176 DrawFrame(); 3177 { 3178 // Scroll down in screen coordinates with a gesture. 3179 gfx::Vector2d gesture_scroll_delta(0, 10); 3180 EXPECT_EQ(InputHandler::ScrollStarted, 3181 host_impl_->ScrollBegin(gfx::Point(1, 1), 3182 InputHandler::Gesture)); 3183 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 3184 host_impl_->ScrollEnd(); 3185 3186 // The child layer should have scrolled down in its local coordinates an 3187 // amount proportional to the angle between it and the input scroll delta. 3188 gfx::Vector2d expected_scroll_delta( 3189 0, 3190 gesture_scroll_delta.y() * 3191 std::cos(MathUtil::Deg2Rad(child_layer_angle))); 3192 scoped_ptr<ScrollAndScaleSet> scroll_info = 3193 host_impl_->ProcessScrollDeltas(); 3194 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); 3195 3196 // The root scroll layer should not have scrolled, because the input delta 3197 // was close to the layer's axis of movement. 3198 EXPECT_EQ(scroll_info->scrolls.size(), 1u); 3199 } 3200 { 3201 // Now reset and scroll the same amount horizontally. 3202 child_ptr->SetScrollDelta(gfx::Vector2dF()); 3203 gfx::Vector2d gesture_scroll_delta(10, 0); 3204 EXPECT_EQ(InputHandler::ScrollStarted, 3205 host_impl_->ScrollBegin(gfx::Point(1, 1), 3206 InputHandler::Gesture)); 3207 host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta); 3208 host_impl_->ScrollEnd(); 3209 3210 // The child layer should have scrolled down in its local coordinates an 3211 // amount proportional to the angle between it and the input scroll delta. 3212 gfx::Vector2d expected_scroll_delta( 3213 0, 3214 -gesture_scroll_delta.x() * 3215 std::sin(MathUtil::Deg2Rad(child_layer_angle))); 3216 scoped_ptr<ScrollAndScaleSet> scroll_info = 3217 host_impl_->ProcessScrollDeltas(); 3218 ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta); 3219 3220 // The root scroll layer should have scrolled more, since the input scroll 3221 // delta was mostly orthogonal to the child layer's vertical scroll axis. 3222 gfx::Vector2d expected_root_scroll_delta( 3223 gesture_scroll_delta.x() * 3224 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2), 3225 0); 3226 ExpectContains(*scroll_info.get(), 3227 scroll_layer->id(), 3228 expected_root_scroll_delta); 3229 } 3230 } 3231 3232 TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { 3233 LayerImpl* scroll_layer = 3234 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3235 3236 // Scale the layer to twice its normal size. 3237 int scale = 2; 3238 gfx::Transform scale_transform; 3239 scale_transform.Scale(scale, scale); 3240 scroll_layer->SetTransform(scale_transform); 3241 3242 gfx::Size surface_size(50, 50); 3243 host_impl_->SetViewportSize(surface_size); 3244 DrawFrame(); 3245 3246 // Scroll down in screen coordinates with a gesture. 3247 gfx::Vector2d scroll_delta(0, 10); 3248 EXPECT_EQ(InputHandler::ScrollStarted, 3249 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 3250 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3251 host_impl_->ScrollEnd(); 3252 3253 // The layer should have scrolled down in its local coordinates, but half the 3254 // amount. 3255 scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); 3256 ExpectContains(*scroll_info.get(), 3257 scroll_layer->id(), 3258 gfx::Vector2d(0, scroll_delta.y() / scale)); 3259 3260 // Reset and scroll down with the wheel. 3261 scroll_layer->SetScrollDelta(gfx::Vector2dF()); 3262 gfx::Vector2d wheel_scroll_delta(0, 10); 3263 EXPECT_EQ(InputHandler::ScrollStarted, 3264 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 3265 host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta); 3266 host_impl_->ScrollEnd(); 3267 3268 // The scale should not have been applied to the scroll delta. 3269 scroll_info = host_impl_->ProcessScrollDeltas(); 3270 ExpectContains(*scroll_info.get(), 3271 scroll_layer->id(), 3272 wheel_scroll_delta); 3273 } 3274 3275 TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { 3276 int width = 332; 3277 int height = 20; 3278 int scale = 3; 3279 SetupScrollAndContentsLayers(gfx::Size(width, height)); 3280 host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( 3281 gfx::Size(width * scale - 1, height * scale)); 3282 host_impl_->SetDeviceScaleFactor(scale); 3283 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 3284 3285 LayerImpl* inner_viewport_scroll_layer = 3286 host_impl_->active_tree()->InnerViewportScrollLayer(); 3287 EXPECT_EQ(gfx::Vector2d(0, 0), 3288 inner_viewport_scroll_layer->MaxScrollOffset()); 3289 } 3290 3291 class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate { 3292 public: 3293 TestScrollOffsetDelegate() 3294 : page_scale_factor_(0.f), 3295 min_page_scale_factor_(-1.f), 3296 max_page_scale_factor_(-1.f) {} 3297 3298 virtual ~TestScrollOffsetDelegate() {} 3299 3300 virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE { 3301 return getter_return_value_; 3302 } 3303 3304 virtual bool IsExternalFlingActive() const OVERRIDE { return false; } 3305 3306 virtual void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset, 3307 const gfx::Vector2dF& max_scroll_offset, 3308 const gfx::SizeF& scrollable_size, 3309 float page_scale_factor, 3310 float min_page_scale_factor, 3311 float max_page_scale_factor) OVERRIDE { 3312 DCHECK(total_scroll_offset.x() <= max_scroll_offset.x()); 3313 DCHECK(total_scroll_offset.y() <= max_scroll_offset.y()); 3314 last_set_scroll_offset_ = total_scroll_offset; 3315 max_scroll_offset_ = max_scroll_offset; 3316 scrollable_size_ = scrollable_size; 3317 page_scale_factor_ = page_scale_factor; 3318 min_page_scale_factor_ = min_page_scale_factor; 3319 max_page_scale_factor_ = max_page_scale_factor; 3320 } 3321 3322 gfx::Vector2dF last_set_scroll_offset() { 3323 return last_set_scroll_offset_; 3324 } 3325 3326 void set_getter_return_value(const gfx::Vector2dF& value) { 3327 getter_return_value_ = value; 3328 } 3329 3330 gfx::Vector2dF max_scroll_offset() const { 3331 return max_scroll_offset_; 3332 } 3333 3334 gfx::SizeF scrollable_size() const { 3335 return scrollable_size_; 3336 } 3337 3338 float page_scale_factor() const { 3339 return page_scale_factor_; 3340 } 3341 3342 float min_page_scale_factor() const { 3343 return min_page_scale_factor_; 3344 } 3345 3346 float max_page_scale_factor() const { 3347 return max_page_scale_factor_; 3348 } 3349 3350 private: 3351 gfx::Vector2dF last_set_scroll_offset_; 3352 gfx::Vector2dF getter_return_value_; 3353 gfx::Vector2dF max_scroll_offset_; 3354 gfx::SizeF scrollable_size_; 3355 float page_scale_factor_; 3356 float min_page_scale_factor_; 3357 float max_page_scale_factor_; 3358 }; 3359 3360 TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { 3361 TestScrollOffsetDelegate scroll_delegate; 3362 host_impl_->SetViewportSize(gfx::Size(10, 20)); 3363 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3364 LayerImpl* clip_layer = scroll_layer->parent()->parent(); 3365 clip_layer->SetBounds(gfx::Size(10, 20)); 3366 3367 // Setting the delegate results in the current scroll offset being set. 3368 gfx::Vector2dF initial_scroll_delta(10.f, 10.f); 3369 scroll_layer->SetScrollOffset(gfx::Vector2d()); 3370 scroll_layer->SetScrollDelta(initial_scroll_delta); 3371 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate); 3372 EXPECT_EQ(initial_scroll_delta.ToString(), 3373 scroll_delegate.last_set_scroll_offset().ToString()); 3374 3375 // Setting the delegate results in the scrollable_size, max_scroll_offset, 3376 // page_scale_factor and {min|max}_page_scale_factor being set. 3377 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size()); 3378 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate.max_scroll_offset()); 3379 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor()); 3380 EXPECT_EQ(0.f, scroll_delegate.min_page_scale_factor()); 3381 EXPECT_EQ(0.f, scroll_delegate.max_page_scale_factor()); 3382 3383 // Updating page scale immediately updates the delegate. 3384 host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f); 3385 EXPECT_EQ(2.f, scroll_delegate.page_scale_factor()); 3386 EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor()); 3387 EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor()); 3388 host_impl_->active_tree()->SetPageScaleDelta(1.5f); 3389 EXPECT_EQ(3.f, scroll_delegate.page_scale_factor()); 3390 EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor()); 3391 EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor()); 3392 host_impl_->active_tree()->SetPageScaleDelta(1.f); 3393 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 3394 EXPECT_EQ(1.f, scroll_delegate.page_scale_factor()); 3395 EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor()); 3396 EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor()); 3397 3398 // The pinch gesture doesn't put the delegate into a state where the scroll 3399 // offset is outside of the scroll range. (this is verified by DCHECKs in the 3400 // delegate). 3401 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture); 3402 host_impl_->PinchGestureBegin(); 3403 host_impl_->PinchGestureUpdate(2.f, gfx::Point()); 3404 host_impl_->PinchGestureUpdate(.5f, gfx::Point()); 3405 host_impl_->PinchGestureEnd(); 3406 host_impl_->ScrollEnd(); 3407 3408 // Scrolling should be relative to the offset as returned by the delegate. 3409 gfx::Vector2dF scroll_delta(0.f, 10.f); 3410 gfx::Vector2dF current_offset(7.f, 8.f); 3411 3412 scroll_delegate.set_getter_return_value(current_offset); 3413 EXPECT_EQ(InputHandler::ScrollStarted, 3414 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 3415 3416 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3417 EXPECT_EQ(current_offset + scroll_delta, 3418 scroll_delegate.last_set_scroll_offset()); 3419 3420 current_offset = gfx::Vector2dF(42.f, 41.f); 3421 scroll_delegate.set_getter_return_value(current_offset); 3422 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3423 EXPECT_EQ(current_offset + scroll_delta, 3424 scroll_delegate.last_set_scroll_offset()); 3425 host_impl_->ScrollEnd(); 3426 scroll_delegate.set_getter_return_value(gfx::Vector2dF()); 3427 3428 // Forces a full tree synchronization and ensures that the scroll delegate 3429 // sees the correct size of the new tree. 3430 gfx::Size new_size(42, 24); 3431 host_impl_->CreatePendingTree(); 3432 CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size); 3433 host_impl_->ActivateSyncTree(); 3434 EXPECT_EQ(new_size, scroll_delegate.scrollable_size()); 3435 3436 // Un-setting the delegate should propagate the delegate's current offset to 3437 // the root scrollable layer. 3438 current_offset = gfx::Vector2dF(13.f, 12.f); 3439 scroll_delegate.set_getter_return_value(current_offset); 3440 host_impl_->SetRootLayerScrollOffsetDelegate(NULL); 3441 3442 EXPECT_EQ(current_offset.ToString(), 3443 scroll_layer->TotalScrollOffset().ToString()); 3444 } 3445 3446 void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) { 3447 const gfx::Transform target_space_transform = 3448 layer->draw_properties().target_space_transform; 3449 EXPECT_TRUE(target_space_transform.IsScaleOrTranslation()); 3450 gfx::Point translated_point; 3451 target_space_transform.TransformPoint(&translated_point); 3452 gfx::Point expected_point = gfx::Point() - ToRoundedVector2d(scroll_delta); 3453 EXPECT_EQ(expected_point.ToString(), translated_point.ToString()); 3454 } 3455 3456 TEST_F(LayerTreeHostImplTest, 3457 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) { 3458 TestScrollOffsetDelegate scroll_delegate; 3459 host_impl_->SetViewportSize(gfx::Size(10, 20)); 3460 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3461 LayerImpl* clip_layer = scroll_layer->parent()->parent(); 3462 clip_layer->SetBounds(gfx::Size(10, 20)); 3463 host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate); 3464 3465 // Draw first frame to clear any pending draws and check scroll. 3466 DrawFrame(); 3467 CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f)); 3468 EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); 3469 3470 // Set external scroll delta on delegate and notify LayerTreeHost. 3471 gfx::Vector2dF scroll_delta(10.f, 10.f); 3472 scroll_delegate.set_getter_return_value(scroll_delta); 3473 host_impl_->OnRootLayerDelegatedScrollOffsetChanged(); 3474 3475 // Check scroll delta reflected in layer. 3476 DrawFrame(); 3477 CheckLayerScrollDelta(scroll_layer, scroll_delta); 3478 3479 host_impl_->SetRootLayerScrollOffsetDelegate(NULL); 3480 } 3481 3482 TEST_F(LayerTreeHostImplTest, OverscrollRoot) { 3483 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 3484 host_impl_->SetViewportSize(gfx::Size(50, 50)); 3485 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 3486 DrawFrame(); 3487 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3488 3489 // In-bounds scrolling does not affect overscroll. 3490 EXPECT_EQ(InputHandler::ScrollStarted, 3491 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 3492 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 3493 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3494 3495 // Overscroll events are reflected immediately. 3496 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50)); 3497 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll()); 3498 3499 // In-bounds scrolling resets accumulated overscroll for the scrolled axes. 3500 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50)); 3501 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); 3502 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)); 3503 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 3504 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)); 3505 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 3506 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0)); 3507 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll()); 3508 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60)); 3509 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll()); 3510 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60)); 3511 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 3512 3513 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long 3514 // as no scroll occurs. 3515 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 3516 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll()); 3517 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 3518 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll()); 3519 // Overscroll resets on valid scroll. 3520 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 3521 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll()); 3522 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20)); 3523 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll()); 3524 host_impl_->ScrollEnd(); 3525 } 3526 3527 3528 TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { 3529 // Scroll child layers beyond their maximum scroll range and make sure root 3530 // overscroll does not accumulate. 3531 gfx::Size surface_size(10, 10); 3532 scoped_ptr<LayerImpl> root_clip = 3533 LayerImpl::Create(host_impl_->active_tree(), 4); 3534 scoped_ptr<LayerImpl> root = 3535 CreateScrollableLayer(1, surface_size, root_clip.get()); 3536 3537 scoped_ptr<LayerImpl> grand_child = 3538 CreateScrollableLayer(3, surface_size, root_clip.get()); 3539 3540 scoped_ptr<LayerImpl> child = 3541 CreateScrollableLayer(2, surface_size, root_clip.get()); 3542 LayerImpl* grand_child_layer = grand_child.get(); 3543 child->AddChild(grand_child.Pass()); 3544 3545 LayerImpl* child_layer = child.get(); 3546 root->AddChild(child.Pass()); 3547 root_clip->AddChild(root.Pass()); 3548 child_layer->SetScrollOffset(gfx::Vector2d(0, 3)); 3549 grand_child_layer->SetScrollOffset(gfx::Vector2d(0, 2)); 3550 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3551 host_impl_->active_tree()->DidBecomeActive(); 3552 host_impl_->SetViewportSize(surface_size); 3553 DrawFrame(); 3554 { 3555 gfx::Vector2d scroll_delta(0, -10); 3556 EXPECT_EQ(InputHandler::ScrollStarted, 3557 host_impl_->ScrollBegin(gfx::Point(), 3558 InputHandler::NonBubblingGesture)); 3559 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3560 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3561 host_impl_->ScrollEnd(); 3562 3563 // The next time we scroll we should only scroll the parent, but overscroll 3564 // should still not reach the root layer. 3565 scroll_delta = gfx::Vector2d(0, -30); 3566 EXPECT_EQ(InputHandler::ScrollStarted, 3567 host_impl_->ScrollBegin(gfx::Point(5, 5), 3568 InputHandler::NonBubblingGesture)); 3569 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); 3570 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3571 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3572 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer); 3573 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3574 host_impl_->ScrollEnd(); 3575 3576 // After scrolling the parent, another scroll on the opposite direction 3577 // should scroll the child. 3578 scroll_delta = gfx::Vector2d(0, 70); 3579 EXPECT_EQ(InputHandler::ScrollStarted, 3580 host_impl_->ScrollBegin(gfx::Point(5, 5), 3581 InputHandler::NonBubblingGesture)); 3582 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); 3583 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3584 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); 3585 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3586 host_impl_->ScrollEnd(); 3587 } 3588 } 3589 3590 TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { 3591 // When we try to scroll a non-scrollable child layer, the scroll delta 3592 // should be applied to one of its ancestors if possible. Overscroll should 3593 // be reflected only when it has bubbled up to the root scrolling layer. 3594 gfx::Size surface_size(10, 10); 3595 gfx::Size content_size(20, 20); 3596 scoped_ptr<LayerImpl> root_clip = 3597 LayerImpl::Create(host_impl_->active_tree(), 3); 3598 scoped_ptr<LayerImpl> root = 3599 CreateScrollableLayer(1, content_size, root_clip.get()); 3600 root->SetIsContainerForFixedPositionLayers(true); 3601 scoped_ptr<LayerImpl> child = 3602 CreateScrollableLayer(2, content_size, root_clip.get()); 3603 3604 child->SetScrollClipLayer(Layer::INVALID_ID); 3605 root->AddChild(child.Pass()); 3606 root_clip->AddChild(root.Pass()); 3607 3608 host_impl_->SetViewportSize(surface_size); 3609 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3610 host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID); 3611 host_impl_->active_tree()->DidBecomeActive(); 3612 DrawFrame(); 3613 { 3614 gfx::Vector2d scroll_delta(0, 8); 3615 EXPECT_EQ(InputHandler::ScrollStarted, 3616 host_impl_->ScrollBegin(gfx::Point(5, 5), 3617 InputHandler::Wheel)); 3618 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3619 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3620 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3621 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll()); 3622 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 3623 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll()); 3624 host_impl_->ScrollEnd(); 3625 } 3626 } 3627 3628 TEST_F(LayerTreeHostImplTest, OverscrollAlways) { 3629 LayerTreeSettings settings; 3630 CreateHostImpl(settings, CreateOutputSurface()); 3631 3632 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50)); 3633 LayerImpl* clip_layer = scroll_layer->parent()->parent(); 3634 clip_layer->SetBounds(gfx::Size(50, 50)); 3635 host_impl_->SetViewportSize(gfx::Size(50, 50)); 3636 host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f); 3637 DrawFrame(); 3638 EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); 3639 3640 // Even though the layer can't scroll the overscroll still happens. 3641 EXPECT_EQ(InputHandler::ScrollStarted, 3642 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 3643 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)); 3644 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll()); 3645 } 3646 3647 TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) { 3648 gfx::Size surface_size(980, 1439); 3649 gfx::Size content_size(980, 1438); 3650 float device_scale_factor = 1.5f; 3651 scoped_ptr<LayerImpl> root_clip = 3652 LayerImpl::Create(host_impl_->active_tree(), 3); 3653 scoped_ptr<LayerImpl> root = 3654 CreateScrollableLayer(1, content_size, root_clip.get()); 3655 root->SetIsContainerForFixedPositionLayers(true); 3656 scoped_ptr<LayerImpl> child = 3657 CreateScrollableLayer(2, content_size, root_clip.get()); 3658 root->scroll_clip_layer()->SetBounds(gfx::Size(320, 469)); 3659 host_impl_->active_tree()->SetPageScaleFactorAndLimits( 3660 0.326531f, 0.326531f, 5.f); 3661 host_impl_->active_tree()->SetPageScaleDelta(1.f); 3662 child->SetScrollClipLayer(Layer::INVALID_ID); 3663 root->AddChild(child.Pass()); 3664 root_clip->AddChild(root.Pass()); 3665 3666 host_impl_->SetViewportSize(surface_size); 3667 host_impl_->SetDeviceScaleFactor(device_scale_factor); 3668 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3669 host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID); 3670 host_impl_->active_tree()->DidBecomeActive(); 3671 DrawFrame(); 3672 { 3673 // Horizontal & Vertical GlowEffect should not be applied when 3674 // content size is less then view port size. For Example Horizontal & 3675 // vertical GlowEffect should not be applied in about:blank page. 3676 EXPECT_EQ(InputHandler::ScrollStarted, 3677 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel)); 3678 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1)); 3679 EXPECT_EQ(gfx::Vector2dF().ToString(), 3680 host_impl_->accumulated_root_overscroll().ToString()); 3681 3682 host_impl_->ScrollEnd(); 3683 } 3684 } 3685 3686 TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { 3687 gfx::Size surface_size(100, 100); 3688 gfx::Size content_size(200, 200); 3689 scoped_ptr<LayerImpl> root_clip = 3690 LayerImpl::Create(host_impl_->active_tree(), 3); 3691 scoped_ptr<LayerImpl> root = 3692 CreateScrollableLayer(1, content_size, root_clip.get()); 3693 root->SetIsContainerForFixedPositionLayers(true); 3694 scoped_ptr<LayerImpl> child = 3695 CreateScrollableLayer(2, content_size, root_clip.get()); 3696 3697 child->SetScrollClipLayer(Layer::INVALID_ID); 3698 root->AddChild(child.Pass()); 3699 root_clip->AddChild(root.Pass()); 3700 3701 host_impl_->SetViewportSize(surface_size); 3702 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 3703 host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID); 3704 host_impl_->active_tree()->DidBecomeActive(); 3705 DrawFrame(); 3706 { 3707 // Edge glow effect should be applicable only upon reaching Edges 3708 // of the content. unnecessary glow effect calls shouldn't be 3709 // called while scrolling up without reaching the edge of the content. 3710 EXPECT_EQ(InputHandler::ScrollStarted, 3711 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel)); 3712 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100)); 3713 EXPECT_EQ(gfx::Vector2dF().ToString(), 3714 host_impl_->accumulated_root_overscroll().ToString()); 3715 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f)); 3716 EXPECT_EQ(gfx::Vector2dF().ToString(), 3717 host_impl_->accumulated_root_overscroll().ToString()); 3718 host_impl_->ScrollEnd(); 3719 // unusedrootDelta should be subtracted from applied delta so that 3720 // unwanted glow effect calls are not called. 3721 EXPECT_EQ(InputHandler::ScrollStarted, 3722 host_impl_->ScrollBegin(gfx::Point(0, 0), 3723 InputHandler::NonBubblingGesture)); 3724 EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); 3725 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20)); 3726 EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(), 3727 host_impl_->accumulated_root_overscroll().ToString()); 3728 3729 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f)); 3730 EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(), 3731 host_impl_->accumulated_root_overscroll().ToString()); 3732 host_impl_->ScrollEnd(); 3733 // TestCase to check kEpsilon, which prevents minute values to trigger 3734 // gloweffect without reaching edge. 3735 EXPECT_EQ(InputHandler::ScrollStarted, 3736 host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel)); 3737 host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f)); 3738 EXPECT_EQ(gfx::Vector2dF().ToString(), 3739 host_impl_->accumulated_root_overscroll().ToString()); 3740 host_impl_->ScrollEnd(); 3741 } 3742 } 3743 3744 class BlendStateCheckLayer : public LayerImpl { 3745 public: 3746 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, 3747 int id, 3748 ResourceProvider* resource_provider) { 3749 return scoped_ptr<LayerImpl>(new BlendStateCheckLayer(tree_impl, 3750 id, 3751 resource_provider)); 3752 } 3753 3754 virtual void AppendQuads(RenderPass* render_pass, 3755 const OcclusionTracker<LayerImpl>& occlusion_tracker, 3756 AppendQuadsData* append_quads_data) OVERRIDE { 3757 quads_appended_ = true; 3758 3759 gfx::Rect opaque_rect; 3760 if (contents_opaque()) 3761 opaque_rect = quad_rect_; 3762 else 3763 opaque_rect = opaque_content_rect_; 3764 gfx::Rect visible_quad_rect = quad_rect_; 3765 3766 SharedQuadState* shared_quad_state = 3767 render_pass->CreateAndAppendSharedQuadState(); 3768 PopulateSharedQuadState(shared_quad_state); 3769 3770 TileDrawQuad* test_blending_draw_quad = 3771 render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); 3772 test_blending_draw_quad->SetNew(shared_quad_state, 3773 quad_rect_, 3774 opaque_rect, 3775 visible_quad_rect, 3776 resource_id_, 3777 gfx::RectF(0.f, 0.f, 1.f, 1.f), 3778 gfx::Size(1, 1), 3779 false); 3780 test_blending_draw_quad->visible_rect = quad_visible_rect_; 3781 EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending()); 3782 EXPECT_EQ(has_render_surface_, !!render_surface()); 3783 } 3784 3785 void SetExpectation(bool blend, bool has_render_surface) { 3786 blend_ = blend; 3787 has_render_surface_ = has_render_surface; 3788 quads_appended_ = false; 3789 } 3790 3791 bool quads_appended() const { return quads_appended_; } 3792 3793 void SetQuadRect(const gfx::Rect& rect) { quad_rect_ = rect; } 3794 void SetQuadVisibleRect(const gfx::Rect& rect) { quad_visible_rect_ = rect; } 3795 void SetOpaqueContentRect(const gfx::Rect& rect) { 3796 opaque_content_rect_ = rect; 3797 } 3798 3799 private: 3800 BlendStateCheckLayer(LayerTreeImpl* tree_impl, 3801 int id, 3802 ResourceProvider* resource_provider) 3803 : LayerImpl(tree_impl, id), 3804 blend_(false), 3805 has_render_surface_(false), 3806 quads_appended_(false), 3807 quad_rect_(5, 5, 5, 5), 3808 quad_visible_rect_(5, 5, 5, 5), 3809 resource_id_(resource_provider->CreateResource( 3810 gfx::Size(1, 1), 3811 GL_CLAMP_TO_EDGE, 3812 ResourceProvider::TextureHintImmutable, 3813 RGBA_8888)) { 3814 resource_provider->AllocateForTesting(resource_id_); 3815 SetBounds(gfx::Size(10, 10)); 3816 SetContentBounds(gfx::Size(10, 10)); 3817 SetDrawsContent(true); 3818 } 3819 3820 bool blend_; 3821 bool has_render_surface_; 3822 bool quads_appended_; 3823 gfx::Rect quad_rect_; 3824 gfx::Rect opaque_content_rect_; 3825 gfx::Rect quad_visible_rect_; 3826 ResourceProvider::ResourceId resource_id_; 3827 }; 3828 3829 TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { 3830 { 3831 scoped_ptr<LayerImpl> root = 3832 LayerImpl::Create(host_impl_->active_tree(), 1); 3833 root->SetBounds(gfx::Size(10, 10)); 3834 root->SetContentBounds(root->bounds()); 3835 root->SetDrawsContent(false); 3836 host_impl_->active_tree()->SetRootLayer(root.Pass()); 3837 } 3838 LayerImpl* root = host_impl_->active_tree()->root_layer(); 3839 3840 root->AddChild( 3841 BlendStateCheckLayer::Create(host_impl_->active_tree(), 3842 2, 3843 host_impl_->resource_provider())); 3844 BlendStateCheckLayer* layer1 = 3845 static_cast<BlendStateCheckLayer*>(root->children()[0]); 3846 layer1->SetPosition(gfx::PointF(2.f, 2.f)); 3847 3848 LayerTreeHostImpl::FrameData frame; 3849 3850 // Opaque layer, drawn without blending. 3851 layer1->SetContentsOpaque(true); 3852 layer1->SetExpectation(false, false); 3853 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3854 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3855 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3856 EXPECT_TRUE(layer1->quads_appended()); 3857 host_impl_->DidDrawAllLayers(frame); 3858 3859 // Layer with translucent content and painting, so drawn with blending. 3860 layer1->SetContentsOpaque(false); 3861 layer1->SetExpectation(true, false); 3862 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3863 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3864 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3865 EXPECT_TRUE(layer1->quads_appended()); 3866 host_impl_->DidDrawAllLayers(frame); 3867 3868 // Layer with translucent opacity, drawn with blending. 3869 layer1->SetContentsOpaque(true); 3870 layer1->SetOpacity(0.5f); 3871 layer1->SetExpectation(true, false); 3872 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3873 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3874 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3875 EXPECT_TRUE(layer1->quads_appended()); 3876 host_impl_->DidDrawAllLayers(frame); 3877 3878 // Layer with translucent opacity and painting, drawn with blending. 3879 layer1->SetContentsOpaque(true); 3880 layer1->SetOpacity(0.5f); 3881 layer1->SetExpectation(true, false); 3882 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3883 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3884 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3885 EXPECT_TRUE(layer1->quads_appended()); 3886 host_impl_->DidDrawAllLayers(frame); 3887 3888 layer1->AddChild( 3889 BlendStateCheckLayer::Create(host_impl_->active_tree(), 3890 3, 3891 host_impl_->resource_provider())); 3892 BlendStateCheckLayer* layer2 = 3893 static_cast<BlendStateCheckLayer*>(layer1->children()[0]); 3894 layer2->SetPosition(gfx::PointF(4.f, 4.f)); 3895 3896 // 2 opaque layers, drawn without blending. 3897 layer1->SetContentsOpaque(true); 3898 layer1->SetOpacity(1.f); 3899 layer1->SetExpectation(false, false); 3900 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3901 layer2->SetContentsOpaque(true); 3902 layer2->SetOpacity(1.f); 3903 layer2->SetExpectation(false, false); 3904 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3905 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3906 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3907 EXPECT_TRUE(layer1->quads_appended()); 3908 EXPECT_TRUE(layer2->quads_appended()); 3909 host_impl_->DidDrawAllLayers(frame); 3910 3911 // Parent layer with translucent content, drawn with blending. 3912 // Child layer with opaque content, drawn without blending. 3913 layer1->SetContentsOpaque(false); 3914 layer1->SetExpectation(true, false); 3915 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3916 layer2->SetExpectation(false, false); 3917 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3918 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3919 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3920 EXPECT_TRUE(layer1->quads_appended()); 3921 EXPECT_TRUE(layer2->quads_appended()); 3922 host_impl_->DidDrawAllLayers(frame); 3923 3924 // Parent layer with translucent content but opaque painting, drawn without 3925 // blending. 3926 // Child layer with opaque content, drawn without blending. 3927 layer1->SetContentsOpaque(true); 3928 layer1->SetExpectation(false, false); 3929 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3930 layer2->SetExpectation(false, false); 3931 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3932 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3933 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3934 EXPECT_TRUE(layer1->quads_appended()); 3935 EXPECT_TRUE(layer2->quads_appended()); 3936 host_impl_->DidDrawAllLayers(frame); 3937 3938 // Parent layer with translucent opacity and opaque content. Since it has a 3939 // drawing child, it's drawn to a render surface which carries the opacity, 3940 // so it's itself drawn without blending. 3941 // Child layer with opaque content, drawn without blending (parent surface 3942 // carries the inherited opacity). 3943 layer1->SetContentsOpaque(true); 3944 layer1->SetOpacity(0.5f); 3945 layer1->SetExpectation(false, true); 3946 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3947 layer2->SetExpectation(false, false); 3948 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3949 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren( 3950 host_impl_->active_tree()->root_layer()); 3951 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3952 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3953 EXPECT_TRUE(layer1->quads_appended()); 3954 EXPECT_TRUE(layer2->quads_appended()); 3955 host_impl_->DidDrawAllLayers(frame); 3956 3957 // Draw again, but with child non-opaque, to make sure 3958 // layer1 not culled. 3959 layer1->SetContentsOpaque(true); 3960 layer1->SetOpacity(1.f); 3961 layer1->SetExpectation(false, false); 3962 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3963 layer2->SetContentsOpaque(true); 3964 layer2->SetOpacity(0.5f); 3965 layer2->SetExpectation(true, false); 3966 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3967 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3968 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3969 EXPECT_TRUE(layer1->quads_appended()); 3970 EXPECT_TRUE(layer2->quads_appended()); 3971 host_impl_->DidDrawAllLayers(frame); 3972 3973 // A second way of making the child non-opaque. 3974 layer1->SetContentsOpaque(true); 3975 layer1->SetOpacity(1.f); 3976 layer1->SetExpectation(false, false); 3977 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3978 layer2->SetContentsOpaque(false); 3979 layer2->SetOpacity(1.f); 3980 layer2->SetExpectation(true, false); 3981 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3982 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3983 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 3984 EXPECT_TRUE(layer1->quads_appended()); 3985 EXPECT_TRUE(layer2->quads_appended()); 3986 host_impl_->DidDrawAllLayers(frame); 3987 3988 // And when the layer says its not opaque but is painted opaque, it is not 3989 // blended. 3990 layer1->SetContentsOpaque(true); 3991 layer1->SetOpacity(1.f); 3992 layer1->SetExpectation(false, false); 3993 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3994 layer2->SetContentsOpaque(true); 3995 layer2->SetOpacity(1.f); 3996 layer2->SetExpectation(false, false); 3997 layer2->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 3998 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 3999 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4000 EXPECT_TRUE(layer1->quads_appended()); 4001 EXPECT_TRUE(layer2->quads_appended()); 4002 host_impl_->DidDrawAllLayers(frame); 4003 4004 // Layer with partially opaque contents, drawn with blending. 4005 layer1->SetContentsOpaque(false); 4006 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 4007 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5)); 4008 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 4009 layer1->SetExpectation(true, false); 4010 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 4011 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4012 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4013 EXPECT_TRUE(layer1->quads_appended()); 4014 host_impl_->DidDrawAllLayers(frame); 4015 4016 // Layer with partially opaque contents partially culled, drawn with blending. 4017 layer1->SetContentsOpaque(false); 4018 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 4019 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2)); 4020 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 4021 layer1->SetExpectation(true, false); 4022 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 4023 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4024 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4025 EXPECT_TRUE(layer1->quads_appended()); 4026 host_impl_->DidDrawAllLayers(frame); 4027 4028 // Layer with partially opaque contents culled, drawn with blending. 4029 layer1->SetContentsOpaque(false); 4030 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 4031 layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5)); 4032 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 4033 layer1->SetExpectation(true, false); 4034 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 4035 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4036 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4037 EXPECT_TRUE(layer1->quads_appended()); 4038 host_impl_->DidDrawAllLayers(frame); 4039 4040 // Layer with partially opaque contents and translucent contents culled, drawn 4041 // without blending. 4042 layer1->SetContentsOpaque(false); 4043 layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5)); 4044 layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5)); 4045 layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); 4046 layer1->SetExpectation(false, false); 4047 layer1->SetUpdateRect(gfx::RectF(layer1->content_bounds())); 4048 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4049 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4050 EXPECT_TRUE(layer1->quads_appended()); 4051 host_impl_->DidDrawAllLayers(frame); 4052 } 4053 4054 class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { 4055 protected: 4056 LayerTreeHostImplViewportCoveredTest() : 4057 gutter_quad_material_(DrawQuad::SOLID_COLOR), 4058 child_(NULL), 4059 did_activate_pending_tree_(false) {} 4060 4061 scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool always_draw) { 4062 if (always_draw) { 4063 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d() 4064 .PassAs<OutputSurface>(); 4065 } 4066 return FakeOutputSurface::Create3d().PassAs<OutputSurface>(); 4067 } 4068 4069 void SetupActiveTreeLayers() { 4070 host_impl_->active_tree()->set_background_color(SK_ColorGRAY); 4071 host_impl_->active_tree()->SetRootLayer( 4072 LayerImpl::Create(host_impl_->active_tree(), 1)); 4073 host_impl_->active_tree()->root_layer()->AddChild( 4074 BlendStateCheckLayer::Create(host_impl_->active_tree(), 4075 2, 4076 host_impl_->resource_provider())); 4077 child_ = static_cast<BlendStateCheckLayer*>( 4078 host_impl_->active_tree()->root_layer()->children()[0]); 4079 child_->SetExpectation(false, false); 4080 child_->SetContentsOpaque(true); 4081 } 4082 4083 // Expect no gutter rects. 4084 void TestLayerCoversFullViewport() { 4085 gfx::Rect layer_rect(viewport_size_); 4086 child_->SetPosition(layer_rect.origin()); 4087 child_->SetBounds(layer_rect.size()); 4088 child_->SetContentBounds(layer_rect.size()); 4089 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 4090 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 4091 4092 LayerTreeHostImpl::FrameData frame; 4093 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4094 ASSERT_EQ(1u, frame.render_passes.size()); 4095 4096 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list)); 4097 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4098 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 4099 4100 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 4101 host_impl_->DidDrawAllLayers(frame); 4102 } 4103 4104 // Expect fullscreen gutter rect. 4105 void TestEmptyLayer() { 4106 gfx::Rect layer_rect(0, 0, 0, 0); 4107 child_->SetPosition(layer_rect.origin()); 4108 child_->SetBounds(layer_rect.size()); 4109 child_->SetContentBounds(layer_rect.size()); 4110 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 4111 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 4112 4113 LayerTreeHostImpl::FrameData frame; 4114 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4115 ASSERT_EQ(1u, frame.render_passes.size()); 4116 4117 EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list)); 4118 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4119 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 4120 4121 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 4122 host_impl_->DidDrawAllLayers(frame); 4123 } 4124 4125 // Expect four surrounding gutter rects. 4126 void TestLayerInMiddleOfViewport() { 4127 gfx::Rect layer_rect(500, 500, 200, 200); 4128 child_->SetPosition(layer_rect.origin()); 4129 child_->SetBounds(layer_rect.size()); 4130 child_->SetContentBounds(layer_rect.size()); 4131 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 4132 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 4133 4134 LayerTreeHostImpl::FrameData frame; 4135 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4136 ASSERT_EQ(1u, frame.render_passes.size()); 4137 4138 EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list)); 4139 EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size()); 4140 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 4141 4142 VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list); 4143 host_impl_->DidDrawAllLayers(frame); 4144 } 4145 4146 // Expect no gutter rects. 4147 void TestLayerIsLargerThanViewport() { 4148 gfx::Rect layer_rect(viewport_size_.width() + 10, 4149 viewport_size_.height() + 10); 4150 child_->SetPosition(layer_rect.origin()); 4151 child_->SetBounds(layer_rect.size()); 4152 child_->SetContentBounds(layer_rect.size()); 4153 child_->SetQuadRect(gfx::Rect(layer_rect.size())); 4154 child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); 4155 4156 LayerTreeHostImpl::FrameData frame; 4157 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4158 ASSERT_EQ(1u, frame.render_passes.size()); 4159 4160 EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list)); 4161 EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size()); 4162 ValidateTextureDrawQuads(frame.render_passes[0]->quad_list); 4163 4164 host_impl_->DidDrawAllLayers(frame); 4165 } 4166 4167 virtual void DidActivateSyncTree() OVERRIDE { 4168 did_activate_pending_tree_ = true; 4169 } 4170 4171 void set_gutter_quad_material(DrawQuad::Material material) { 4172 gutter_quad_material_ = material; 4173 } 4174 void set_gutter_texture_size(const gfx::Size& gutter_texture_size) { 4175 gutter_texture_size_ = gutter_texture_size; 4176 } 4177 4178 protected: 4179 size_t CountGutterQuads(const QuadList& quad_list) { 4180 size_t num_gutter_quads = 0; 4181 for (QuadList::ConstIterator iter = quad_list.begin(); 4182 iter != quad_list.end(); 4183 ++iter) { 4184 num_gutter_quads += (iter->material == gutter_quad_material_) ? 1 : 0; 4185 } 4186 return num_gutter_quads; 4187 } 4188 4189 void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) { 4190 LayerTestCommon::VerifyQuadsExactlyCoverRect( 4191 quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_))); 4192 } 4193 4194 // Make sure that the texture coordinates match their expectations. 4195 void ValidateTextureDrawQuads(const QuadList& quad_list) { 4196 for (QuadList::ConstIterator iter = quad_list.begin(); 4197 iter != quad_list.end(); 4198 ++iter) { 4199 if (iter->material != DrawQuad::TEXTURE_CONTENT) 4200 continue; 4201 const TextureDrawQuad* quad = TextureDrawQuad::MaterialCast(&*iter); 4202 gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize( 4203 gutter_texture_size_, host_impl_->device_scale_factor()); 4204 EXPECT_EQ(quad->uv_top_left.x(), 4205 quad->rect.x() / gutter_texture_size_pixels.width()); 4206 EXPECT_EQ(quad->uv_top_left.y(), 4207 quad->rect.y() / gutter_texture_size_pixels.height()); 4208 EXPECT_EQ(quad->uv_bottom_right.x(), 4209 quad->rect.right() / gutter_texture_size_pixels.width()); 4210 EXPECT_EQ(quad->uv_bottom_right.y(), 4211 quad->rect.bottom() / gutter_texture_size_pixels.height()); 4212 } 4213 } 4214 4215 gfx::Size DipSizeToPixelSize(const gfx::Size& size) { 4216 return gfx::ToRoundedSize( 4217 gfx::ScaleSize(size, host_impl_->device_scale_factor())); 4218 } 4219 4220 DrawQuad::Material gutter_quad_material_; 4221 gfx::Size gutter_texture_size_; 4222 gfx::Size viewport_size_; 4223 BlendStateCheckLayer* child_; 4224 bool did_activate_pending_tree_; 4225 }; 4226 4227 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { 4228 viewport_size_ = gfx::Size(1000, 1000); 4229 4230 bool always_draw = false; 4231 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 4232 4233 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4234 SetupActiveTreeLayers(); 4235 TestLayerCoversFullViewport(); 4236 TestEmptyLayer(); 4237 TestLayerInMiddleOfViewport(); 4238 TestLayerIsLargerThanViewport(); 4239 } 4240 4241 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { 4242 viewport_size_ = gfx::Size(1000, 1000); 4243 4244 bool always_draw = false; 4245 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 4246 4247 host_impl_->SetDeviceScaleFactor(2.f); 4248 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4249 SetupActiveTreeLayers(); 4250 TestLayerCoversFullViewport(); 4251 TestEmptyLayer(); 4252 TestLayerInMiddleOfViewport(); 4253 TestLayerIsLargerThanViewport(); 4254 } 4255 4256 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) { 4257 viewport_size_ = gfx::Size(1000, 1000); 4258 4259 bool always_draw = false; 4260 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 4261 4262 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4263 SetupActiveTreeLayers(); 4264 4265 // Specify an overhang bitmap to use. 4266 bool is_opaque = false; 4267 UIResourceBitmap ui_resource_bitmap(gfx::Size(2, 2), is_opaque); 4268 ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT); 4269 UIResourceId ui_resource_id = 12345; 4270 host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap); 4271 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32)); 4272 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT); 4273 set_gutter_texture_size(gfx::Size(32, 32)); 4274 4275 TestLayerCoversFullViewport(); 4276 TestEmptyLayer(); 4277 TestLayerInMiddleOfViewport(); 4278 TestLayerIsLargerThanViewport(); 4279 4280 // Change the resource size. 4281 host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16)); 4282 set_gutter_texture_size(gfx::Size(128, 16)); 4283 4284 TestLayerCoversFullViewport(); 4285 TestEmptyLayer(); 4286 TestLayerInMiddleOfViewport(); 4287 TestLayerIsLargerThanViewport(); 4288 4289 // Change the device scale factor 4290 host_impl_->SetDeviceScaleFactor(2.f); 4291 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4292 4293 TestLayerCoversFullViewport(); 4294 TestEmptyLayer(); 4295 TestLayerInMiddleOfViewport(); 4296 TestLayerIsLargerThanViewport(); 4297 } 4298 4299 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { 4300 viewport_size_ = gfx::Size(1000, 1000); 4301 4302 bool always_draw = true; 4303 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 4304 4305 // Pending tree to force active_tree size invalid. Not used otherwise. 4306 host_impl_->CreatePendingTree(); 4307 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4308 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 4309 4310 SetupActiveTreeLayers(); 4311 TestEmptyLayer(); 4312 TestLayerInMiddleOfViewport(); 4313 TestLayerIsLargerThanViewport(); 4314 } 4315 4316 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) { 4317 viewport_size_ = gfx::Size(1000, 1000); 4318 4319 bool always_draw = true; 4320 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw)); 4321 4322 // Set larger viewport and activate it to active tree. 4323 host_impl_->CreatePendingTree(); 4324 gfx::Size larger_viewport(viewport_size_.width() + 100, 4325 viewport_size_.height() + 100); 4326 host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport)); 4327 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 4328 host_impl_->ActivateSyncTree(); 4329 EXPECT_TRUE(did_activate_pending_tree_); 4330 EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid()); 4331 4332 // Shrink pending tree viewport without activating. 4333 host_impl_->CreatePendingTree(); 4334 host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_)); 4335 EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid()); 4336 4337 SetupActiveTreeLayers(); 4338 TestEmptyLayer(); 4339 TestLayerInMiddleOfViewport(); 4340 TestLayerIsLargerThanViewport(); 4341 } 4342 4343 class FakeDrawableLayerImpl: public LayerImpl { 4344 public: 4345 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 4346 return scoped_ptr<LayerImpl>(new FakeDrawableLayerImpl(tree_impl, id)); 4347 } 4348 protected: 4349 FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id) 4350 : LayerImpl(tree_impl, id) {} 4351 }; 4352 4353 // Only reshape when we know we are going to draw. Otherwise, the reshape 4354 // can leave the window at the wrong size if we never draw and the proper 4355 // viewport size is never set. 4356 TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) { 4357 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); 4358 scoped_ptr<OutputSurface> output_surface( 4359 FakeOutputSurface::Create3d(provider)); 4360 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 4361 4362 scoped_ptr<LayerImpl> root = 4363 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); 4364 root->SetBounds(gfx::Size(10, 10)); 4365 root->SetContentBounds(gfx::Size(10, 10)); 4366 root->SetDrawsContent(true); 4367 host_impl_->active_tree()->SetRootLayer(root.Pass()); 4368 EXPECT_FALSE(provider->TestContext3d()->reshape_called()); 4369 provider->TestContext3d()->clear_reshape_called(); 4370 4371 LayerTreeHostImpl::FrameData frame; 4372 host_impl_->SetViewportSize(gfx::Size(10, 10)); 4373 host_impl_->SetDeviceScaleFactor(1.f); 4374 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4375 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4376 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 4377 EXPECT_EQ(provider->TestContext3d()->width(), 10); 4378 EXPECT_EQ(provider->TestContext3d()->height(), 10); 4379 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f); 4380 host_impl_->DidDrawAllLayers(frame); 4381 provider->TestContext3d()->clear_reshape_called(); 4382 4383 host_impl_->SetViewportSize(gfx::Size(20, 30)); 4384 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4385 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4386 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 4387 EXPECT_EQ(provider->TestContext3d()->width(), 20); 4388 EXPECT_EQ(provider->TestContext3d()->height(), 30); 4389 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f); 4390 host_impl_->DidDrawAllLayers(frame); 4391 provider->TestContext3d()->clear_reshape_called(); 4392 4393 host_impl_->SetDeviceScaleFactor(2.f); 4394 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4395 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4396 EXPECT_TRUE(provider->TestContext3d()->reshape_called()); 4397 EXPECT_EQ(provider->TestContext3d()->width(), 20); 4398 EXPECT_EQ(provider->TestContext3d()->height(), 30); 4399 EXPECT_EQ(provider->TestContext3d()->scale_factor(), 2.f); 4400 host_impl_->DidDrawAllLayers(frame); 4401 provider->TestContext3d()->clear_reshape_called(); 4402 } 4403 4404 // Make sure damage tracking propagates all the way to the graphics context, 4405 // where it should request to swap only the sub-buffer that is damaged. 4406 TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { 4407 scoped_refptr<TestContextProvider> context_provider( 4408 TestContextProvider::Create()); 4409 context_provider->BindToCurrentThread(); 4410 context_provider->TestContext3d()->set_have_post_sub_buffer(true); 4411 4412 scoped_ptr<OutputSurface> output_surface( 4413 FakeOutputSurface::Create3d(context_provider)); 4414 4415 // This test creates its own LayerTreeHostImpl, so 4416 // that we can force partial swap enabled. 4417 LayerTreeSettings settings; 4418 settings.partial_swap_enabled = true; 4419 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 4420 new TestSharedBitmapManager()); 4421 scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl = 4422 LayerTreeHostImpl::Create(settings, 4423 this, 4424 &proxy_, 4425 &stats_instrumentation_, 4426 shared_bitmap_manager.get(), 4427 0); 4428 layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); 4429 layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500)); 4430 4431 scoped_ptr<LayerImpl> root = 4432 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); 4433 scoped_ptr<LayerImpl> child = 4434 FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); 4435 child->SetPosition(gfx::PointF(12.f, 13.f)); 4436 child->SetBounds(gfx::Size(14, 15)); 4437 child->SetContentBounds(gfx::Size(14, 15)); 4438 child->SetDrawsContent(true); 4439 root->SetBounds(gfx::Size(500, 500)); 4440 root->SetContentBounds(gfx::Size(500, 500)); 4441 root->SetDrawsContent(true); 4442 root->AddChild(child.Pass()); 4443 layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass()); 4444 4445 LayerTreeHostImpl::FrameData frame; 4446 4447 // First frame, the entire screen should get swapped. 4448 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); 4449 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 4450 layer_tree_host_impl->DidDrawAllLayers(frame); 4451 layer_tree_host_impl->SwapBuffers(frame); 4452 EXPECT_EQ(TestContextSupport::SWAP, 4453 context_provider->support()->last_swap_type()); 4454 4455 // Second frame, only the damaged area should get swapped. Damage should be 4456 // the union of old and new child rects. 4457 // expected damage rect: gfx::Rect(26, 28); 4458 // expected swap rect: vertically flipped, with origin at bottom left corner. 4459 layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition( 4460 gfx::PointF()); 4461 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); 4462 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 4463 host_impl_->DidDrawAllLayers(frame); 4464 layer_tree_host_impl->SwapBuffers(frame); 4465 4466 // Make sure that partial swap is constrained to the viewport dimensions 4467 // expected damage rect: gfx::Rect(500, 500); 4468 // expected swap rect: flipped damage rect, but also clamped to viewport 4469 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP, 4470 context_provider->support()->last_swap_type()); 4471 gfx::Rect expected_swap_rect(0, 500-28, 26, 28); 4472 EXPECT_EQ(expected_swap_rect.ToString(), 4473 context_provider->support()-> 4474 last_partial_swap_rect().ToString()); 4475 4476 layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10)); 4477 // This will damage everything. 4478 layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor( 4479 SK_ColorBLACK); 4480 EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); 4481 layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 4482 host_impl_->DidDrawAllLayers(frame); 4483 layer_tree_host_impl->SwapBuffers(frame); 4484 4485 EXPECT_EQ(TestContextSupport::SWAP, 4486 context_provider->support()->last_swap_type()); 4487 } 4488 4489 TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { 4490 scoped_ptr<LayerImpl> root = 4491 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); 4492 scoped_ptr<LayerImpl> child = 4493 FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2); 4494 child->SetBounds(gfx::Size(10, 10)); 4495 child->SetContentBounds(gfx::Size(10, 10)); 4496 child->SetDrawsContent(true); 4497 root->SetBounds(gfx::Size(10, 10)); 4498 root->SetContentBounds(gfx::Size(10, 10)); 4499 root->SetDrawsContent(true); 4500 root->SetForceRenderSurface(true); 4501 root->AddChild(child.Pass()); 4502 4503 host_impl_->active_tree()->SetRootLayer(root.Pass()); 4504 4505 LayerTreeHostImpl::FrameData frame; 4506 4507 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4508 EXPECT_EQ(1u, frame.render_surface_layer_list->size()); 4509 EXPECT_EQ(1u, frame.render_passes.size()); 4510 host_impl_->DidDrawAllLayers(frame); 4511 } 4512 4513 class FakeLayerWithQuads : public LayerImpl { 4514 public: 4515 static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { 4516 return scoped_ptr<LayerImpl>(new FakeLayerWithQuads(tree_impl, id)); 4517 } 4518 4519 virtual void AppendQuads(RenderPass* render_pass, 4520 const OcclusionTracker<LayerImpl>& occlusion_tracker, 4521 AppendQuadsData* append_quads_data) OVERRIDE { 4522 SharedQuadState* shared_quad_state = 4523 render_pass->CreateAndAppendSharedQuadState(); 4524 PopulateSharedQuadState(shared_quad_state); 4525 4526 SkColor gray = SkColorSetRGB(100, 100, 100); 4527 gfx::Rect quad_rect(content_bounds()); 4528 gfx::Rect visible_quad_rect(quad_rect); 4529 SolidColorDrawQuad* my_quad = 4530 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); 4531 my_quad->SetNew( 4532 shared_quad_state, quad_rect, visible_quad_rect, gray, false); 4533 } 4534 4535 private: 4536 FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id) 4537 : LayerImpl(tree_impl, id) {} 4538 }; 4539 4540 class MockContext : public TestWebGraphicsContext3D { 4541 public: 4542 MOCK_METHOD1(useProgram, void(GLuint program)); 4543 MOCK_METHOD5(uniform4f, void(GLint location, 4544 GLfloat x, 4545 GLfloat y, 4546 GLfloat z, 4547 GLfloat w)); 4548 MOCK_METHOD4(uniformMatrix4fv, void(GLint location, 4549 GLsizei count, 4550 GLboolean transpose, 4551 const GLfloat* value)); 4552 MOCK_METHOD4(drawElements, void(GLenum mode, 4553 GLsizei count, 4554 GLenum type, 4555 GLintptr offset)); 4556 MOCK_METHOD1(enable, void(GLenum cap)); 4557 MOCK_METHOD1(disable, void(GLenum cap)); 4558 MOCK_METHOD4(scissor, void(GLint x, 4559 GLint y, 4560 GLsizei width, 4561 GLsizei height)); 4562 }; 4563 4564 class MockContextHarness { 4565 private: 4566 MockContext* context_; 4567 4568 public: 4569 explicit MockContextHarness(MockContext* context) 4570 : context_(context) { 4571 context_->set_have_post_sub_buffer(true); 4572 4573 // Catch "uninteresting" calls 4574 EXPECT_CALL(*context_, useProgram(_)) 4575 .Times(0); 4576 4577 EXPECT_CALL(*context_, drawElements(_, _, _, _)) 4578 .Times(0); 4579 4580 // These are not asserted 4581 EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _)) 4582 .WillRepeatedly(Return()); 4583 4584 EXPECT_CALL(*context_, uniform4f(_, _, _, _, _)) 4585 .WillRepeatedly(Return()); 4586 4587 // Any un-sanctioned calls to enable() are OK 4588 EXPECT_CALL(*context_, enable(_)) 4589 .WillRepeatedly(Return()); 4590 4591 // Any un-sanctioned calls to disable() are OK 4592 EXPECT_CALL(*context_, disable(_)) 4593 .WillRepeatedly(Return()); 4594 } 4595 4596 void MustDrawSolidQuad() { 4597 EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0)) 4598 .WillOnce(Return()) 4599 .RetiresOnSaturation(); 4600 4601 EXPECT_CALL(*context_, useProgram(_)) 4602 .WillOnce(Return()) 4603 .RetiresOnSaturation(); 4604 } 4605 4606 void MustSetScissor(int x, int y, int width, int height) { 4607 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST)) 4608 .WillRepeatedly(Return()); 4609 4610 EXPECT_CALL(*context_, scissor(x, y, width, height)) 4611 .Times(AtLeast(1)) 4612 .WillRepeatedly(Return()); 4613 } 4614 4615 void MustSetNoScissor() { 4616 EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST)) 4617 .WillRepeatedly(Return()); 4618 4619 EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST)) 4620 .Times(0); 4621 4622 EXPECT_CALL(*context_, scissor(_, _, _, _)) 4623 .Times(0); 4624 } 4625 }; 4626 4627 TEST_F(LayerTreeHostImplTest, NoPartialSwap) { 4628 scoped_ptr<MockContext> mock_context_owned(new MockContext); 4629 MockContext* mock_context = mock_context_owned.get(); 4630 4631 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 4632 mock_context_owned.PassAs<TestWebGraphicsContext3D>())); 4633 MockContextHarness harness(mock_context); 4634 4635 // Run test case 4636 LayerTreeSettings settings = DefaultSettings(); 4637 settings.partial_swap_enabled = false; 4638 CreateHostImpl(settings, output_surface.Pass()); 4639 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 4640 4641 // Without partial swap, and no clipping, no scissor is set. 4642 harness.MustDrawSolidQuad(); 4643 harness.MustSetNoScissor(); 4644 { 4645 LayerTreeHostImpl::FrameData frame; 4646 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4647 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4648 host_impl_->DidDrawAllLayers(frame); 4649 } 4650 Mock::VerifyAndClearExpectations(&mock_context); 4651 4652 // Without partial swap, but a layer does clip its subtree, one scissor is 4653 // set. 4654 host_impl_->active_tree()->root_layer()->SetMasksToBounds(true); 4655 harness.MustDrawSolidQuad(); 4656 harness.MustSetScissor(0, 0, 10, 10); 4657 { 4658 LayerTreeHostImpl::FrameData frame; 4659 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4660 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4661 host_impl_->DidDrawAllLayers(frame); 4662 } 4663 Mock::VerifyAndClearExpectations(&mock_context); 4664 } 4665 4666 TEST_F(LayerTreeHostImplTest, PartialSwap) { 4667 scoped_ptr<MockContext> context_owned(new MockContext); 4668 MockContext* mock_context = context_owned.get(); 4669 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 4670 context_owned.PassAs<TestWebGraphicsContext3D>())); 4671 MockContextHarness harness(mock_context); 4672 4673 LayerTreeSettings settings = DefaultSettings(); 4674 settings.partial_swap_enabled = true; 4675 CreateHostImpl(settings, output_surface.Pass()); 4676 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 4677 4678 // The first frame is not a partially-swapped one. 4679 harness.MustSetScissor(0, 0, 10, 10); 4680 harness.MustDrawSolidQuad(); 4681 { 4682 LayerTreeHostImpl::FrameData frame; 4683 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4684 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4685 host_impl_->DidDrawAllLayers(frame); 4686 } 4687 Mock::VerifyAndClearExpectations(&mock_context); 4688 4689 // Damage a portion of the frame. 4690 host_impl_->active_tree()->root_layer()->SetUpdateRect( 4691 gfx::Rect(0, 0, 2, 3)); 4692 4693 // The second frame will be partially-swapped (the y coordinates are flipped). 4694 harness.MustSetScissor(0, 7, 2, 3); 4695 harness.MustDrawSolidQuad(); 4696 { 4697 LayerTreeHostImpl::FrameData frame; 4698 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4699 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4700 host_impl_->DidDrawAllLayers(frame); 4701 } 4702 Mock::VerifyAndClearExpectations(&mock_context); 4703 } 4704 4705 static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity( 4706 bool partial_swap, 4707 LayerTreeHostImplClient* client, 4708 Proxy* proxy, 4709 SharedBitmapManager* manager, 4710 RenderingStatsInstrumentation* stats_instrumentation) { 4711 scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); 4712 scoped_ptr<OutputSurface> output_surface( 4713 FakeOutputSurface::Create3d(provider)); 4714 provider->BindToCurrentThread(); 4715 provider->TestContext3d()->set_have_post_sub_buffer(true); 4716 4717 LayerTreeSettings settings; 4718 settings.partial_swap_enabled = partial_swap; 4719 scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( 4720 settings, client, proxy, stats_instrumentation, manager, 0); 4721 my_host_impl->InitializeRenderer(output_surface.Pass()); 4722 my_host_impl->SetViewportSize(gfx::Size(100, 100)); 4723 4724 /* 4725 Layers are created as follows: 4726 4727 +--------------------+ 4728 | 1 | 4729 | +-----------+ | 4730 | | 2 | | 4731 | | +-------------------+ 4732 | | | 3 | 4733 | | +-------------------+ 4734 | | | | 4735 | +-----------+ | 4736 | | 4737 | | 4738 +--------------------+ 4739 4740 Layers 1, 2 have render surfaces 4741 */ 4742 scoped_ptr<LayerImpl> root = 4743 LayerImpl::Create(my_host_impl->active_tree(), 1); 4744 scoped_ptr<LayerImpl> child = 4745 LayerImpl::Create(my_host_impl->active_tree(), 2); 4746 scoped_ptr<LayerImpl> grand_child = 4747 FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3); 4748 4749 gfx::Rect root_rect(0, 0, 100, 100); 4750 gfx::Rect child_rect(10, 10, 50, 50); 4751 gfx::Rect grand_child_rect(5, 5, 150, 150); 4752 4753 root->CreateRenderSurface(); 4754 root->SetPosition(root_rect.origin()); 4755 root->SetBounds(root_rect.size()); 4756 root->SetContentBounds(root->bounds()); 4757 root->draw_properties().visible_content_rect = root_rect; 4758 root->SetDrawsContent(false); 4759 root->render_surface()->SetContentRect(gfx::Rect(root_rect.size())); 4760 4761 child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y())); 4762 child->SetOpacity(0.5f); 4763 child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); 4764 child->SetContentBounds(child->bounds()); 4765 child->draw_properties().visible_content_rect = child_rect; 4766 child->SetDrawsContent(false); 4767 child->SetForceRenderSurface(true); 4768 4769 grand_child->SetPosition(grand_child_rect.origin()); 4770 grand_child->SetBounds(grand_child_rect.size()); 4771 grand_child->SetContentBounds(grand_child->bounds()); 4772 grand_child->draw_properties().visible_content_rect = grand_child_rect; 4773 grand_child->SetDrawsContent(true); 4774 4775 child->AddChild(grand_child.Pass()); 4776 root->AddChild(child.Pass()); 4777 4778 my_host_impl->active_tree()->SetRootLayer(root.Pass()); 4779 return my_host_impl.Pass(); 4780 } 4781 4782 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { 4783 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 4784 new TestSharedBitmapManager()); 4785 scoped_ptr<LayerTreeHostImpl> my_host_impl = 4786 SetupLayersForOpacity(true, 4787 this, 4788 &proxy_, 4789 shared_bitmap_manager.get(), 4790 &stats_instrumentation_); 4791 { 4792 LayerTreeHostImpl::FrameData frame; 4793 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); 4794 4795 // Verify all quads have been computed 4796 ASSERT_EQ(2U, frame.render_passes.size()); 4797 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); 4798 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); 4799 EXPECT_EQ(DrawQuad::SOLID_COLOR, 4800 frame.render_passes[0]->quad_list.front()->material); 4801 EXPECT_EQ(DrawQuad::RENDER_PASS, 4802 frame.render_passes[1]->quad_list.front()->material); 4803 4804 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 4805 my_host_impl->DidDrawAllLayers(frame); 4806 } 4807 } 4808 4809 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { 4810 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 4811 new TestSharedBitmapManager()); 4812 scoped_ptr<LayerTreeHostImpl> my_host_impl = 4813 SetupLayersForOpacity(false, 4814 this, 4815 &proxy_, 4816 shared_bitmap_manager.get(), 4817 &stats_instrumentation_); 4818 { 4819 LayerTreeHostImpl::FrameData frame; 4820 EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); 4821 4822 // Verify all quads have been computed 4823 ASSERT_EQ(2U, frame.render_passes.size()); 4824 ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size()); 4825 ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size()); 4826 EXPECT_EQ(DrawQuad::SOLID_COLOR, 4827 frame.render_passes[0]->quad_list.front()->material); 4828 EXPECT_EQ(DrawQuad::RENDER_PASS, 4829 frame.render_passes[1]->quad_list.front()->material); 4830 4831 my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now()); 4832 my_host_impl->DidDrawAllLayers(frame); 4833 } 4834 } 4835 4836 TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { 4837 scoped_ptr<TestWebGraphicsContext3D> context = 4838 TestWebGraphicsContext3D::Create(); 4839 TestWebGraphicsContext3D* context3d = context.get(); 4840 scoped_ptr<OutputSurface> output_surface( 4841 FakeOutputSurface::Create3d(context.Pass())); 4842 CreateHostImpl(DefaultSettings(), output_surface.Pass()); 4843 4844 scoped_ptr<LayerImpl> root_layer = 4845 LayerImpl::Create(host_impl_->active_tree(), 1); 4846 root_layer->SetBounds(gfx::Size(10, 10)); 4847 4848 scoped_refptr<VideoFrame> softwareFrame = 4849 media::VideoFrame::CreateColorFrame( 4850 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); 4851 FakeVideoFrameProvider provider; 4852 provider.set_frame(softwareFrame); 4853 scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( 4854 host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0); 4855 video_layer->SetBounds(gfx::Size(10, 10)); 4856 video_layer->SetContentBounds(gfx::Size(10, 10)); 4857 video_layer->SetDrawsContent(true); 4858 root_layer->AddChild(video_layer.PassAs<LayerImpl>()); 4859 4860 scoped_ptr<IOSurfaceLayerImpl> io_surface_layer = 4861 IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5); 4862 io_surface_layer->SetBounds(gfx::Size(10, 10)); 4863 io_surface_layer->SetContentBounds(gfx::Size(10, 10)); 4864 io_surface_layer->SetDrawsContent(true); 4865 io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10)); 4866 root_layer->AddChild(io_surface_layer.PassAs<LayerImpl>()); 4867 4868 host_impl_->active_tree()->SetRootLayer(root_layer.Pass()); 4869 4870 EXPECT_EQ(0u, context3d->NumTextures()); 4871 4872 LayerTreeHostImpl::FrameData frame; 4873 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4874 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4875 host_impl_->DidDrawAllLayers(frame); 4876 host_impl_->SwapBuffers(frame); 4877 4878 EXPECT_GT(context3d->NumTextures(), 0u); 4879 4880 // Kill the layer tree. 4881 host_impl_->active_tree()->SetRootLayer( 4882 LayerImpl::Create(host_impl_->active_tree(), 100)); 4883 // There should be no textures left in use after. 4884 EXPECT_EQ(0u, context3d->NumTextures()); 4885 } 4886 4887 class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D { 4888 public: 4889 MOCK_METHOD1(useProgram, void(GLuint program)); 4890 MOCK_METHOD4(drawElements, void(GLenum mode, 4891 GLsizei count, 4892 GLenum type, 4893 GLintptr offset)); 4894 }; 4895 4896 TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { 4897 scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned( 4898 new MockDrawQuadsToFillScreenContext); 4899 MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get(); 4900 4901 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 4902 mock_context_owned.PassAs<TestWebGraphicsContext3D>())); 4903 4904 // Run test case 4905 LayerTreeSettings settings = DefaultSettings(); 4906 settings.partial_swap_enabled = false; 4907 CreateHostImpl(settings, output_surface.Pass()); 4908 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); 4909 host_impl_->active_tree()->set_background_color(SK_ColorWHITE); 4910 4911 // Verify one quad is drawn when transparent background set is not set. 4912 host_impl_->active_tree()->set_has_transparent_background(false); 4913 EXPECT_CALL(*mock_context, useProgram(_)) 4914 .Times(1); 4915 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)) 4916 .Times(1); 4917 LayerTreeHostImpl::FrameData frame; 4918 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4919 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4920 host_impl_->DidDrawAllLayers(frame); 4921 Mock::VerifyAndClearExpectations(&mock_context); 4922 4923 // Verify no quads are drawn when transparent background is set. 4924 host_impl_->active_tree()->set_has_transparent_background(true); 4925 host_impl_->SetFullRootLayerDamage(); 4926 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4927 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 4928 host_impl_->DidDrawAllLayers(frame); 4929 Mock::VerifyAndClearExpectations(&mock_context); 4930 } 4931 4932 TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { 4933 set_reduce_memory_result(false); 4934 4935 // If changing the memory limit wouldn't result in changing what was 4936 // committed, then no commit should be requested. 4937 set_reduce_memory_result(false); 4938 host_impl_->set_max_memory_needed_bytes( 4939 host_impl_->memory_allocation_limit_bytes() - 1); 4940 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 4941 host_impl_->memory_allocation_limit_bytes() - 1)); 4942 EXPECT_FALSE(did_request_commit_); 4943 did_request_commit_ = false; 4944 4945 // If changing the memory limit would result in changing what was 4946 // committed, then a commit should be requested, even though nothing was 4947 // evicted. 4948 set_reduce_memory_result(false); 4949 host_impl_->set_max_memory_needed_bytes( 4950 host_impl_->memory_allocation_limit_bytes()); 4951 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 4952 host_impl_->memory_allocation_limit_bytes() - 1)); 4953 EXPECT_TRUE(did_request_commit_); 4954 did_request_commit_ = false; 4955 4956 // Especially if changing the memory limit caused evictions, we need 4957 // to re-commit. 4958 set_reduce_memory_result(true); 4959 host_impl_->set_max_memory_needed_bytes(1); 4960 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 4961 host_impl_->memory_allocation_limit_bytes() - 1)); 4962 EXPECT_TRUE(did_request_commit_); 4963 did_request_commit_ = false; 4964 4965 // But if we set it to the same value that it was before, we shouldn't 4966 // re-commit. 4967 host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( 4968 host_impl_->memory_allocation_limit_bytes())); 4969 EXPECT_FALSE(did_request_commit_); 4970 } 4971 4972 class LayerTreeHostImplTestWithDelegatingRenderer 4973 : public LayerTreeHostImplTest { 4974 protected: 4975 virtual scoped_ptr<OutputSurface> CreateOutputSurface() OVERRIDE { 4976 return FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>(); 4977 } 4978 4979 void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) { 4980 bool expect_to_draw = !expected_damage.IsEmpty(); 4981 4982 LayerTreeHostImpl::FrameData frame; 4983 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 4984 4985 if (!expect_to_draw) { 4986 // With no damage, we don't draw, and no quads are created. 4987 ASSERT_EQ(0u, frame.render_passes.size()); 4988 } else { 4989 ASSERT_EQ(1u, frame.render_passes.size()); 4990 4991 // Verify the damage rect for the root render pass. 4992 const RenderPass* root_render_pass = frame.render_passes.back(); 4993 EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect); 4994 4995 // Verify the root and child layers' quads are generated and not being 4996 // culled. 4997 ASSERT_EQ(2u, root_render_pass->quad_list.size()); 4998 4999 LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0]; 5000 gfx::RectF expected_child_visible_rect(child->content_bounds()); 5001 EXPECT_RECT_EQ(expected_child_visible_rect, 5002 root_render_pass->quad_list.front()->visible_rect); 5003 5004 LayerImpl* root = host_impl_->active_tree()->root_layer(); 5005 gfx::RectF expected_root_visible_rect(root->content_bounds()); 5006 EXPECT_RECT_EQ(expected_root_visible_rect, 5007 root_render_pass->quad_list.ElementAt(1)->visible_rect); 5008 } 5009 5010 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5011 host_impl_->DidDrawAllLayers(frame); 5012 EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame)); 5013 } 5014 }; 5015 5016 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) { 5017 scoped_ptr<SolidColorLayerImpl> root = 5018 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 5019 root->SetPosition(gfx::PointF()); 5020 root->SetBounds(gfx::Size(10, 10)); 5021 root->SetContentBounds(gfx::Size(10, 10)); 5022 root->SetDrawsContent(true); 5023 5024 // Child layer is in the bottom right corner. 5025 scoped_ptr<SolidColorLayerImpl> child = 5026 SolidColorLayerImpl::Create(host_impl_->active_tree(), 2); 5027 child->SetPosition(gfx::PointF(9.f, 9.f)); 5028 child->SetBounds(gfx::Size(1, 1)); 5029 child->SetContentBounds(gfx::Size(1, 1)); 5030 child->SetDrawsContent(true); 5031 root->AddChild(child.PassAs<LayerImpl>()); 5032 5033 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); 5034 5035 // Draw a frame. In the first frame, the entire viewport should be damaged. 5036 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); 5037 DrawFrameAndTestDamage(full_frame_damage); 5038 5039 // The second frame has damage that doesn't touch the child layer. Its quads 5040 // should still be generated. 5041 gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1); 5042 host_impl_->active_tree()->root_layer()->SetUpdateRect(small_damage); 5043 DrawFrameAndTestDamage(small_damage); 5044 5045 // The third frame should have no damage, so no quads should be generated. 5046 gfx::Rect no_damage; 5047 DrawFrameAndTestDamage(no_damage); 5048 } 5049 5050 // TODO(reveman): Remove this test and the ability to prevent on demand raster 5051 // when delegating renderer supports PictureDrawQuads. crbug.com/342121 5052 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, PreventRasterizeOnDemand) { 5053 LayerTreeSettings settings; 5054 CreateHostImpl(settings, CreateOutputSurface()); 5055 EXPECT_FALSE(host_impl_->GetRendererCapabilities().allow_rasterize_on_demand); 5056 } 5057 5058 class FakeMaskLayerImpl : public LayerImpl { 5059 public: 5060 static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl, 5061 int id) { 5062 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id)); 5063 } 5064 5065 virtual ResourceProvider::ResourceId ContentsResourceId() const OVERRIDE { 5066 return 0; 5067 } 5068 5069 private: 5070 FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id) 5071 : LayerImpl(tree_impl, id) {} 5072 }; 5073 5074 TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) { 5075 LayerTreeSettings settings; 5076 settings.layer_transforms_should_scale_layer_contents = true; 5077 CreateHostImpl(settings, CreateOutputSurface()); 5078 5079 // Root 5080 // | 5081 // +-- Scaling Layer (adds a 2x scale) 5082 // | 5083 // +-- Content Layer 5084 // +--Mask 5085 scoped_ptr<LayerImpl> scoped_root = 5086 LayerImpl::Create(host_impl_->active_tree(), 1); 5087 LayerImpl* root = scoped_root.get(); 5088 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 5089 5090 scoped_ptr<LayerImpl> scoped_scaling_layer = 5091 LayerImpl::Create(host_impl_->active_tree(), 2); 5092 LayerImpl* scaling_layer = scoped_scaling_layer.get(); 5093 root->AddChild(scoped_scaling_layer.Pass()); 5094 5095 scoped_ptr<LayerImpl> scoped_content_layer = 5096 LayerImpl::Create(host_impl_->active_tree(), 3); 5097 LayerImpl* content_layer = scoped_content_layer.get(); 5098 scaling_layer->AddChild(scoped_content_layer.Pass()); 5099 5100 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 5101 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 5102 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 5103 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 5104 5105 gfx::Size root_size(100, 100); 5106 root->SetBounds(root_size); 5107 root->SetContentBounds(root_size); 5108 root->SetPosition(gfx::PointF()); 5109 5110 gfx::Size scaling_layer_size(50, 50); 5111 scaling_layer->SetBounds(scaling_layer_size); 5112 scaling_layer->SetContentBounds(scaling_layer_size); 5113 scaling_layer->SetPosition(gfx::PointF()); 5114 gfx::Transform scale; 5115 scale.Scale(2.f, 2.f); 5116 scaling_layer->SetTransform(scale); 5117 5118 content_layer->SetBounds(scaling_layer_size); 5119 content_layer->SetContentBounds(scaling_layer_size); 5120 content_layer->SetPosition(gfx::PointF()); 5121 content_layer->SetDrawsContent(true); 5122 5123 mask_layer->SetBounds(scaling_layer_size); 5124 mask_layer->SetContentBounds(scaling_layer_size); 5125 mask_layer->SetPosition(gfx::PointF()); 5126 mask_layer->SetDrawsContent(true); 5127 5128 5129 // Check that the tree scaling is correctly taken into account for the mask, 5130 // that should fully map onto the quad. 5131 float device_scale_factor = 1.f; 5132 host_impl_->SetViewportSize(root_size); 5133 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5134 { 5135 LayerTreeHostImpl::FrameData frame; 5136 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5137 5138 ASSERT_EQ(1u, frame.render_passes.size()); 5139 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5140 ASSERT_EQ(DrawQuad::RENDER_PASS, 5141 frame.render_passes[0]->quad_list.front()->material); 5142 const RenderPassDrawQuad* render_pass_quad = 5143 RenderPassDrawQuad::MaterialCast( 5144 frame.render_passes[0]->quad_list.front()); 5145 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5146 render_pass_quad->rect.ToString()); 5147 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5148 render_pass_quad->mask_uv_rect.ToString()); 5149 5150 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5151 host_impl_->DidDrawAllLayers(frame); 5152 } 5153 5154 5155 // Applying a DSF should change the render surface size, but won't affect 5156 // which part of the mask is used. 5157 device_scale_factor = 2.f; 5158 gfx::Size device_viewport = 5159 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 5160 host_impl_->SetViewportSize(device_viewport); 5161 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5162 host_impl_->active_tree()->set_needs_update_draw_properties(); 5163 { 5164 LayerTreeHostImpl::FrameData frame; 5165 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5166 5167 ASSERT_EQ(1u, frame.render_passes.size()); 5168 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5169 ASSERT_EQ(DrawQuad::RENDER_PASS, 5170 frame.render_passes[0]->quad_list.front()->material); 5171 const RenderPassDrawQuad* render_pass_quad = 5172 RenderPassDrawQuad::MaterialCast( 5173 frame.render_passes[0]->quad_list.front()); 5174 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), 5175 render_pass_quad->rect.ToString()); 5176 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5177 render_pass_quad->mask_uv_rect.ToString()); 5178 5179 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5180 host_impl_->DidDrawAllLayers(frame); 5181 } 5182 5183 5184 // Applying an equivalent content scale on the content layer and the mask 5185 // should still result in the same part of the mask being used. 5186 gfx::Size content_bounds = 5187 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size, 5188 device_scale_factor)); 5189 content_layer->SetContentBounds(content_bounds); 5190 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5191 mask_layer->SetContentBounds(content_bounds); 5192 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5193 host_impl_->active_tree()->set_needs_update_draw_properties(); 5194 { 5195 LayerTreeHostImpl::FrameData frame; 5196 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5197 5198 ASSERT_EQ(1u, frame.render_passes.size()); 5199 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5200 ASSERT_EQ(DrawQuad::RENDER_PASS, 5201 frame.render_passes[0]->quad_list.front()->material); 5202 const RenderPassDrawQuad* render_pass_quad = 5203 RenderPassDrawQuad::MaterialCast( 5204 frame.render_passes[0]->quad_list.front()); 5205 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), 5206 render_pass_quad->rect.ToString()); 5207 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5208 render_pass_quad->mask_uv_rect.ToString()); 5209 5210 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5211 host_impl_->DidDrawAllLayers(frame); 5212 } 5213 } 5214 5215 TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) { 5216 // The mask layer has bounds 100x100 but is attached to a layer with bounds 5217 // 50x50. 5218 5219 scoped_ptr<LayerImpl> scoped_root = 5220 LayerImpl::Create(host_impl_->active_tree(), 1); 5221 LayerImpl* root = scoped_root.get(); 5222 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 5223 5224 scoped_ptr<LayerImpl> scoped_content_layer = 5225 LayerImpl::Create(host_impl_->active_tree(), 3); 5226 LayerImpl* content_layer = scoped_content_layer.get(); 5227 root->AddChild(scoped_content_layer.Pass()); 5228 5229 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 5230 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 5231 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 5232 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 5233 5234 gfx::Size root_size(100, 100); 5235 root->SetBounds(root_size); 5236 root->SetContentBounds(root_size); 5237 root->SetPosition(gfx::PointF()); 5238 5239 gfx::Size layer_size(50, 50); 5240 content_layer->SetBounds(layer_size); 5241 content_layer->SetContentBounds(layer_size); 5242 content_layer->SetPosition(gfx::PointF()); 5243 content_layer->SetDrawsContent(true); 5244 5245 gfx::Size mask_size(100, 100); 5246 mask_layer->SetBounds(mask_size); 5247 mask_layer->SetContentBounds(mask_size); 5248 mask_layer->SetPosition(gfx::PointF()); 5249 mask_layer->SetDrawsContent(true); 5250 5251 // Check that the mask fills the surface. 5252 float device_scale_factor = 1.f; 5253 host_impl_->SetViewportSize(root_size); 5254 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5255 { 5256 LayerTreeHostImpl::FrameData frame; 5257 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5258 5259 ASSERT_EQ(1u, frame.render_passes.size()); 5260 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5261 ASSERT_EQ(DrawQuad::RENDER_PASS, 5262 frame.render_passes[0]->quad_list.front()->material); 5263 const RenderPassDrawQuad* render_pass_quad = 5264 RenderPassDrawQuad::MaterialCast( 5265 frame.render_passes[0]->quad_list.front()); 5266 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 5267 render_pass_quad->rect.ToString()); 5268 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5269 render_pass_quad->mask_uv_rect.ToString()); 5270 5271 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5272 host_impl_->DidDrawAllLayers(frame); 5273 } 5274 5275 // Applying a DSF should change the render surface size, but won't affect 5276 // which part of the mask is used. 5277 device_scale_factor = 2.f; 5278 gfx::Size device_viewport = 5279 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 5280 host_impl_->SetViewportSize(device_viewport); 5281 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5282 host_impl_->active_tree()->set_needs_update_draw_properties(); 5283 { 5284 LayerTreeHostImpl::FrameData frame; 5285 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5286 5287 ASSERT_EQ(1u, frame.render_passes.size()); 5288 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5289 ASSERT_EQ(DrawQuad::RENDER_PASS, 5290 frame.render_passes[0]->quad_list.front()->material); 5291 const RenderPassDrawQuad* render_pass_quad = 5292 RenderPassDrawQuad::MaterialCast( 5293 frame.render_passes[0]->quad_list.front()); 5294 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5295 render_pass_quad->rect.ToString()); 5296 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5297 render_pass_quad->mask_uv_rect.ToString()); 5298 5299 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5300 host_impl_->DidDrawAllLayers(frame); 5301 } 5302 5303 // Applying an equivalent content scale on the content layer and the mask 5304 // should still result in the same part of the mask being used. 5305 gfx::Size layer_size_large = 5306 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); 5307 content_layer->SetContentBounds(layer_size_large); 5308 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5309 gfx::Size mask_size_large = 5310 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); 5311 mask_layer->SetContentBounds(mask_size_large); 5312 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5313 host_impl_->active_tree()->set_needs_update_draw_properties(); 5314 { 5315 LayerTreeHostImpl::FrameData frame; 5316 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5317 5318 ASSERT_EQ(1u, frame.render_passes.size()); 5319 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5320 ASSERT_EQ(DrawQuad::RENDER_PASS, 5321 frame.render_passes[0]->quad_list.front()->material); 5322 const RenderPassDrawQuad* render_pass_quad = 5323 RenderPassDrawQuad::MaterialCast( 5324 frame.render_passes[0]->quad_list.front()); 5325 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5326 render_pass_quad->rect.ToString()); 5327 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5328 render_pass_quad->mask_uv_rect.ToString()); 5329 5330 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5331 host_impl_->DidDrawAllLayers(frame); 5332 } 5333 5334 // Applying a different contents scale to the mask layer means it will have 5335 // a larger texture, but it should use the same tex coords to cover the 5336 // layer it masks. 5337 mask_layer->SetContentBounds(mask_size); 5338 mask_layer->SetContentsScale(1.f, 1.f); 5339 host_impl_->active_tree()->set_needs_update_draw_properties(); 5340 { 5341 LayerTreeHostImpl::FrameData frame; 5342 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5343 5344 ASSERT_EQ(1u, frame.render_passes.size()); 5345 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5346 ASSERT_EQ(DrawQuad::RENDER_PASS, 5347 frame.render_passes[0]->quad_list.front()->material); 5348 const RenderPassDrawQuad* render_pass_quad = 5349 RenderPassDrawQuad::MaterialCast( 5350 frame.render_passes[0]->quad_list.front()); 5351 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5352 render_pass_quad->rect.ToString()); 5353 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5354 render_pass_quad->mask_uv_rect.ToString()); 5355 5356 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5357 host_impl_->DidDrawAllLayers(frame); 5358 } 5359 } 5360 5361 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) { 5362 // The replica's mask layer has bounds 100x100 but the replica is of a 5363 // layer with bounds 50x50. 5364 5365 scoped_ptr<LayerImpl> scoped_root = 5366 LayerImpl::Create(host_impl_->active_tree(), 1); 5367 LayerImpl* root = scoped_root.get(); 5368 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 5369 5370 scoped_ptr<LayerImpl> scoped_content_layer = 5371 LayerImpl::Create(host_impl_->active_tree(), 3); 5372 LayerImpl* content_layer = scoped_content_layer.get(); 5373 root->AddChild(scoped_content_layer.Pass()); 5374 5375 scoped_ptr<LayerImpl> scoped_replica_layer = 5376 LayerImpl::Create(host_impl_->active_tree(), 2); 5377 LayerImpl* replica_layer = scoped_replica_layer.get(); 5378 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); 5379 5380 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 5381 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4); 5382 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 5383 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 5384 5385 gfx::Size root_size(100, 100); 5386 root->SetBounds(root_size); 5387 root->SetContentBounds(root_size); 5388 root->SetPosition(gfx::PointF()); 5389 5390 gfx::Size layer_size(50, 50); 5391 content_layer->SetBounds(layer_size); 5392 content_layer->SetContentBounds(layer_size); 5393 content_layer->SetPosition(gfx::PointF()); 5394 content_layer->SetDrawsContent(true); 5395 5396 gfx::Size mask_size(100, 100); 5397 mask_layer->SetBounds(mask_size); 5398 mask_layer->SetContentBounds(mask_size); 5399 mask_layer->SetPosition(gfx::PointF()); 5400 mask_layer->SetDrawsContent(true); 5401 5402 // Check that the mask fills the surface. 5403 float device_scale_factor = 1.f; 5404 host_impl_->SetViewportSize(root_size); 5405 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5406 { 5407 LayerTreeHostImpl::FrameData frame; 5408 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5409 5410 ASSERT_EQ(1u, frame.render_passes.size()); 5411 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5412 ASSERT_EQ(DrawQuad::RENDER_PASS, 5413 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5414 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5415 frame.render_passes[0]->quad_list.ElementAt(1)); 5416 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), 5417 replica_quad->rect.ToString()); 5418 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5419 replica_quad->mask_uv_rect.ToString()); 5420 5421 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5422 host_impl_->DidDrawAllLayers(frame); 5423 } 5424 5425 // Applying a DSF should change the render surface size, but won't affect 5426 // which part of the mask is used. 5427 device_scale_factor = 2.f; 5428 gfx::Size device_viewport = 5429 gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor)); 5430 host_impl_->SetViewportSize(device_viewport); 5431 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5432 host_impl_->active_tree()->set_needs_update_draw_properties(); 5433 { 5434 LayerTreeHostImpl::FrameData frame; 5435 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5436 5437 ASSERT_EQ(1u, frame.render_passes.size()); 5438 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5439 ASSERT_EQ(DrawQuad::RENDER_PASS, 5440 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5441 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5442 frame.render_passes[0]->quad_list.ElementAt(1)); 5443 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5444 replica_quad->rect.ToString()); 5445 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5446 replica_quad->mask_uv_rect.ToString()); 5447 5448 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5449 host_impl_->DidDrawAllLayers(frame); 5450 } 5451 5452 // Applying an equivalent content scale on the content layer and the mask 5453 // should still result in the same part of the mask being used. 5454 gfx::Size layer_size_large = 5455 gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor)); 5456 content_layer->SetContentBounds(layer_size_large); 5457 content_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5458 gfx::Size mask_size_large = 5459 gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor)); 5460 mask_layer->SetContentBounds(mask_size_large); 5461 mask_layer->SetContentsScale(device_scale_factor, device_scale_factor); 5462 host_impl_->active_tree()->set_needs_update_draw_properties(); 5463 { 5464 LayerTreeHostImpl::FrameData frame; 5465 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5466 5467 ASSERT_EQ(1u, frame.render_passes.size()); 5468 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5469 ASSERT_EQ(DrawQuad::RENDER_PASS, 5470 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5471 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5472 frame.render_passes[0]->quad_list.ElementAt(1)); 5473 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5474 replica_quad->rect.ToString()); 5475 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5476 replica_quad->mask_uv_rect.ToString()); 5477 5478 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5479 host_impl_->DidDrawAllLayers(frame); 5480 } 5481 5482 // Applying a different contents scale to the mask layer means it will have 5483 // a larger texture, but it should use the same tex coords to cover the 5484 // layer it masks. 5485 mask_layer->SetContentBounds(mask_size); 5486 mask_layer->SetContentsScale(1.f, 1.f); 5487 host_impl_->active_tree()->set_needs_update_draw_properties(); 5488 { 5489 LayerTreeHostImpl::FrameData frame; 5490 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5491 5492 ASSERT_EQ(1u, frame.render_passes.size()); 5493 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5494 ASSERT_EQ(DrawQuad::RENDER_PASS, 5495 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5496 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5497 frame.render_passes[0]->quad_list.ElementAt(1)); 5498 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), 5499 replica_quad->rect.ToString()); 5500 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), 5501 replica_quad->mask_uv_rect.ToString()); 5502 5503 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5504 host_impl_->DidDrawAllLayers(frame); 5505 } 5506 } 5507 5508 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) { 5509 // The replica is of a layer with bounds 50x50, but it has a child that causes 5510 // the surface bounds to be larger. 5511 5512 scoped_ptr<LayerImpl> scoped_root = 5513 LayerImpl::Create(host_impl_->active_tree(), 1); 5514 LayerImpl* root = scoped_root.get(); 5515 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 5516 5517 scoped_ptr<LayerImpl> scoped_content_layer = 5518 LayerImpl::Create(host_impl_->active_tree(), 2); 5519 LayerImpl* content_layer = scoped_content_layer.get(); 5520 root->AddChild(scoped_content_layer.Pass()); 5521 5522 scoped_ptr<LayerImpl> scoped_content_child_layer = 5523 LayerImpl::Create(host_impl_->active_tree(), 3); 5524 LayerImpl* content_child_layer = scoped_content_child_layer.get(); 5525 content_layer->AddChild(scoped_content_child_layer.Pass()); 5526 5527 scoped_ptr<LayerImpl> scoped_replica_layer = 5528 LayerImpl::Create(host_impl_->active_tree(), 4); 5529 LayerImpl* replica_layer = scoped_replica_layer.get(); 5530 content_layer->SetReplicaLayer(scoped_replica_layer.Pass()); 5531 5532 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 5533 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5); 5534 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 5535 replica_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 5536 5537 gfx::Size root_size(100, 100); 5538 root->SetBounds(root_size); 5539 root->SetContentBounds(root_size); 5540 root->SetPosition(gfx::PointF()); 5541 5542 gfx::Size layer_size(50, 50); 5543 content_layer->SetBounds(layer_size); 5544 content_layer->SetContentBounds(layer_size); 5545 content_layer->SetPosition(gfx::PointF()); 5546 content_layer->SetDrawsContent(true); 5547 5548 gfx::Size child_size(50, 50); 5549 content_child_layer->SetBounds(child_size); 5550 content_child_layer->SetContentBounds(child_size); 5551 content_child_layer->SetPosition(gfx::Point(50, 0)); 5552 content_child_layer->SetDrawsContent(true); 5553 5554 gfx::Size mask_size(50, 50); 5555 mask_layer->SetBounds(mask_size); 5556 mask_layer->SetContentBounds(mask_size); 5557 mask_layer->SetPosition(gfx::PointF()); 5558 mask_layer->SetDrawsContent(true); 5559 5560 float device_scale_factor = 1.f; 5561 host_impl_->SetViewportSize(root_size); 5562 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5563 { 5564 LayerTreeHostImpl::FrameData frame; 5565 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5566 5567 ASSERT_EQ(1u, frame.render_passes.size()); 5568 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5569 5570 // The surface is 100x50. 5571 ASSERT_EQ(DrawQuad::RENDER_PASS, 5572 frame.render_passes[0]->quad_list.front()->material); 5573 const RenderPassDrawQuad* render_pass_quad = 5574 RenderPassDrawQuad::MaterialCast( 5575 frame.render_passes[0]->quad_list.front()); 5576 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 5577 render_pass_quad->rect.ToString()); 5578 5579 // The mask covers the owning layer only. 5580 ASSERT_EQ(DrawQuad::RENDER_PASS, 5581 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5582 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5583 frame.render_passes[0]->quad_list.ElementAt(1)); 5584 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), 5585 replica_quad->rect.ToString()); 5586 EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(), 5587 replica_quad->mask_uv_rect.ToString()); 5588 5589 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5590 host_impl_->DidDrawAllLayers(frame); 5591 } 5592 5593 // Move the child to (-50, 0) instead. Now the mask should be moved to still 5594 // cover the layer being replicated. 5595 content_child_layer->SetPosition(gfx::Point(-50, 0)); 5596 { 5597 LayerTreeHostImpl::FrameData frame; 5598 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5599 5600 ASSERT_EQ(1u, frame.render_passes.size()); 5601 ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size()); 5602 5603 // The surface is 100x50 with its origin at (-50, 0). 5604 ASSERT_EQ(DrawQuad::RENDER_PASS, 5605 frame.render_passes[0]->quad_list.front()->material); 5606 const RenderPassDrawQuad* render_pass_quad = 5607 RenderPassDrawQuad::MaterialCast( 5608 frame.render_passes[0]->quad_list.front()); 5609 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), 5610 render_pass_quad->rect.ToString()); 5611 5612 // The mask covers the owning layer only. 5613 ASSERT_EQ(DrawQuad::RENDER_PASS, 5614 frame.render_passes[0]->quad_list.ElementAt(1)->material); 5615 const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast( 5616 frame.render_passes[0]->quad_list.ElementAt(1)); 5617 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(), 5618 replica_quad->rect.ToString()); 5619 EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(), 5620 replica_quad->mask_uv_rect.ToString()); 5621 5622 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5623 host_impl_->DidDrawAllLayers(frame); 5624 } 5625 } 5626 5627 TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) { 5628 // The masked layer has bounds 50x50, but it has a child that causes 5629 // the surface bounds to be larger. It also has a parent that clips the 5630 // masked layer and its surface. 5631 5632 scoped_ptr<LayerImpl> scoped_root = 5633 LayerImpl::Create(host_impl_->active_tree(), 1); 5634 LayerImpl* root = scoped_root.get(); 5635 host_impl_->active_tree()->SetRootLayer(scoped_root.Pass()); 5636 5637 scoped_ptr<LayerImpl> scoped_clipping_layer = 5638 LayerImpl::Create(host_impl_->active_tree(), 2); 5639 LayerImpl* clipping_layer = scoped_clipping_layer.get(); 5640 root->AddChild(scoped_clipping_layer.Pass()); 5641 5642 scoped_ptr<LayerImpl> scoped_content_layer = 5643 LayerImpl::Create(host_impl_->active_tree(), 3); 5644 LayerImpl* content_layer = scoped_content_layer.get(); 5645 clipping_layer->AddChild(scoped_content_layer.Pass()); 5646 5647 scoped_ptr<LayerImpl> scoped_content_child_layer = 5648 LayerImpl::Create(host_impl_->active_tree(), 4); 5649 LayerImpl* content_child_layer = scoped_content_child_layer.get(); 5650 content_layer->AddChild(scoped_content_child_layer.Pass()); 5651 5652 scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer = 5653 FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6); 5654 FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get(); 5655 content_layer->SetMaskLayer(scoped_mask_layer.PassAs<LayerImpl>()); 5656 5657 gfx::Size root_size(100, 100); 5658 root->SetBounds(root_size); 5659 root->SetContentBounds(root_size); 5660 root->SetPosition(gfx::PointF()); 5661 5662 gfx::Rect clipping_rect(20, 10, 10, 20); 5663 clipping_layer->SetBounds(clipping_rect.size()); 5664 clipping_layer->SetContentBounds(clipping_rect.size()); 5665 clipping_layer->SetPosition(clipping_rect.origin()); 5666 clipping_layer->SetMasksToBounds(true); 5667 5668 gfx::Size layer_size(50, 50); 5669 content_layer->SetBounds(layer_size); 5670 content_layer->SetContentBounds(layer_size); 5671 content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin()); 5672 content_layer->SetDrawsContent(true); 5673 5674 gfx::Size child_size(50, 50); 5675 content_child_layer->SetBounds(child_size); 5676 content_child_layer->SetContentBounds(child_size); 5677 content_child_layer->SetPosition(gfx::Point(50, 0)); 5678 content_child_layer->SetDrawsContent(true); 5679 5680 gfx::Size mask_size(100, 100); 5681 mask_layer->SetBounds(mask_size); 5682 mask_layer->SetContentBounds(mask_size); 5683 mask_layer->SetPosition(gfx::PointF()); 5684 mask_layer->SetDrawsContent(true); 5685 5686 float device_scale_factor = 1.f; 5687 host_impl_->SetViewportSize(root_size); 5688 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5689 { 5690 LayerTreeHostImpl::FrameData frame; 5691 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5692 5693 ASSERT_EQ(1u, frame.render_passes.size()); 5694 ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size()); 5695 5696 // The surface is clipped to 10x20. 5697 ASSERT_EQ(DrawQuad::RENDER_PASS, 5698 frame.render_passes[0]->quad_list.front()->material); 5699 const RenderPassDrawQuad* render_pass_quad = 5700 RenderPassDrawQuad::MaterialCast( 5701 frame.render_passes[0]->quad_list.front()); 5702 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), 5703 render_pass_quad->rect.ToString()); 5704 5705 // The masked layer is 50x50, but the surface size is 10x20. So the texture 5706 // coords in the mask are scaled by 10/50 and 20/50. 5707 // The surface is clipped to (20,10) so the mask texture coords are offset 5708 // by 20/50 and 10/50 5709 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 5710 1.f / 50.f).ToString(), 5711 render_pass_quad->mask_uv_rect.ToString()); 5712 5713 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5714 host_impl_->DidDrawAllLayers(frame); 5715 } 5716 } 5717 5718 class GLRendererWithSetupQuadForAntialiasing : public GLRenderer { 5719 public: 5720 using GLRenderer::SetupQuadForAntialiasing; 5721 }; 5722 5723 TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { 5724 // Due to precision issues (especially on Android), sometimes far 5725 // away quads can end up thinking they need AA. 5726 float device_scale_factor = 4.f / 3.f; 5727 host_impl_->SetDeviceScaleFactor(device_scale_factor); 5728 gfx::Size root_size(2000, 1000); 5729 gfx::Size device_viewport_size = 5730 gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor)); 5731 host_impl_->SetViewportSize(device_viewport_size); 5732 5733 host_impl_->CreatePendingTree(); 5734 host_impl_->pending_tree() 5735 ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f); 5736 5737 scoped_ptr<LayerImpl> scoped_root = 5738 LayerImpl::Create(host_impl_->pending_tree(), 1); 5739 LayerImpl* root = scoped_root.get(); 5740 5741 host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass()); 5742 5743 scoped_ptr<LayerImpl> scoped_scrolling_layer = 5744 LayerImpl::Create(host_impl_->pending_tree(), 2); 5745 LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); 5746 root->AddChild(scoped_scrolling_layer.Pass()); 5747 5748 gfx::Size content_layer_bounds(100000, 100); 5749 gfx::Size pile_tile_size(3000, 3000); 5750 scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile( 5751 pile_tile_size, content_layer_bounds)); 5752 5753 scoped_ptr<FakePictureLayerImpl> scoped_content_layer = 5754 FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile); 5755 LayerImpl* content_layer = scoped_content_layer.get(); 5756 scrolling_layer->AddChild(scoped_content_layer.PassAs<LayerImpl>()); 5757 content_layer->SetBounds(content_layer_bounds); 5758 content_layer->SetDrawsContent(true); 5759 5760 root->SetBounds(root_size); 5761 5762 gfx::Vector2d scroll_offset(100000, 0); 5763 scrolling_layer->SetScrollClipLayer(root->id()); 5764 scrolling_layer->SetScrollOffset(scroll_offset); 5765 5766 host_impl_->ActivateSyncTree(); 5767 5768 host_impl_->active_tree()->UpdateDrawProperties(); 5769 ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size()); 5770 5771 LayerTreeHostImpl::FrameData frame; 5772 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5773 5774 ASSERT_EQ(1u, frame.render_passes.size()); 5775 ASSERT_LE(1u, frame.render_passes[0]->quad_list.size()); 5776 const DrawQuad* quad = frame.render_passes[0]->quad_list.front(); 5777 5778 float edge[24]; 5779 gfx::QuadF device_layer_quad; 5780 bool antialiased = 5781 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing( 5782 quad->quadTransform(), quad, &device_layer_quad, edge); 5783 EXPECT_FALSE(antialiased); 5784 5785 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5786 host_impl_->DidDrawAllLayers(frame); 5787 } 5788 5789 5790 class CompositorFrameMetadataTest : public LayerTreeHostImplTest { 5791 public: 5792 CompositorFrameMetadataTest() 5793 : swap_buffers_complete_(0) {} 5794 5795 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE { 5796 swap_buffers_complete_++; 5797 } 5798 5799 int swap_buffers_complete_; 5800 }; 5801 5802 TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { 5803 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); 5804 { 5805 LayerTreeHostImpl::FrameData frame; 5806 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5807 host_impl_->DrawLayers(&frame, base::TimeTicks()); 5808 host_impl_->DidDrawAllLayers(frame); 5809 } 5810 CompositorFrameAck ack; 5811 host_impl_->ReclaimResources(&ack); 5812 host_impl_->DidSwapBuffersComplete(); 5813 EXPECT_EQ(swap_buffers_complete_, 1); 5814 } 5815 5816 class CountingSoftwareDevice : public SoftwareOutputDevice { 5817 public: 5818 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {} 5819 5820 virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect) OVERRIDE { 5821 ++frames_began_; 5822 return SoftwareOutputDevice::BeginPaint(damage_rect); 5823 } 5824 virtual void EndPaint(SoftwareFrameData* frame_data) OVERRIDE { 5825 ++frames_ended_; 5826 SoftwareOutputDevice::EndPaint(frame_data); 5827 } 5828 5829 int frames_began_, frames_ended_; 5830 }; 5831 5832 TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) { 5833 // No main thread evictions in resourceless software mode. 5834 set_reduce_memory_result(false); 5835 CountingSoftwareDevice* software_device = new CountingSoftwareDevice(); 5836 bool delegated_rendering = false; 5837 FakeOutputSurface* output_surface = 5838 FakeOutputSurface::CreateDeferredGL( 5839 scoped_ptr<SoftwareOutputDevice>(software_device), 5840 delegated_rendering).release(); 5841 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 5842 scoped_ptr<OutputSurface>(output_surface))); 5843 host_impl_->SetViewportSize(gfx::Size(50, 50)); 5844 5845 SetupScrollAndContentsLayers(gfx::Size(100, 100)); 5846 5847 const gfx::Transform external_transform; 5848 const gfx::Rect external_viewport; 5849 const gfx::Rect external_clip; 5850 const bool resourceless_software_draw = true; 5851 host_impl_->SetExternalDrawConstraints(external_transform, 5852 external_viewport, 5853 external_clip, 5854 external_viewport, 5855 external_transform, 5856 resourceless_software_draw); 5857 5858 EXPECT_EQ(0, software_device->frames_began_); 5859 EXPECT_EQ(0, software_device->frames_ended_); 5860 5861 DrawFrame(); 5862 5863 EXPECT_EQ(1, software_device->frames_began_); 5864 EXPECT_EQ(1, software_device->frames_ended_); 5865 5866 // Call other API methods that are likely to hit NULL pointer in this mode. 5867 EXPECT_TRUE(host_impl_->AsValue().get()); 5868 EXPECT_TRUE(host_impl_->ActivationStateAsValue().get()); 5869 } 5870 5871 TEST_F(LayerTreeHostImplTest, 5872 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) { 5873 set_reduce_memory_result(false); 5874 bool delegated_rendering = false; 5875 FakeOutputSurface* output_surface = 5876 FakeOutputSurface::CreateDeferredGL( 5877 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice()), 5878 delegated_rendering).release(); 5879 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 5880 scoped_ptr<OutputSurface>(output_surface))); 5881 5882 const gfx::Transform external_transform; 5883 const gfx::Rect external_viewport; 5884 const gfx::Rect external_clip; 5885 const bool resourceless_software_draw = true; 5886 host_impl_->SetExternalDrawConstraints(external_transform, 5887 external_viewport, 5888 external_clip, 5889 external_viewport, 5890 external_transform, 5891 resourceless_software_draw); 5892 5893 // SolidColorLayerImpl will be drawn. 5894 scoped_ptr<SolidColorLayerImpl> root_layer = 5895 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 5896 5897 // VideoLayerImpl will not be drawn. 5898 FakeVideoFrameProvider provider; 5899 scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( 5900 host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0); 5901 video_layer->SetBounds(gfx::Size(10, 10)); 5902 video_layer->SetContentBounds(gfx::Size(10, 10)); 5903 video_layer->SetDrawsContent(true); 5904 root_layer->AddChild(video_layer.PassAs<LayerImpl>()); 5905 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); 5906 5907 LayerTreeHostImpl::FrameData frame; 5908 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 5909 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 5910 host_impl_->DidDrawAllLayers(frame); 5911 5912 EXPECT_EQ(1u, frame.will_draw_layers.size()); 5913 EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]); 5914 } 5915 5916 class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest { 5917 protected: 5918 virtual void SetUp() OVERRIDE { 5919 LayerTreeHostImplTest::SetUp(); 5920 5921 set_reduce_memory_result(false); 5922 5923 bool delegated_rendering = false; 5924 scoped_ptr<FakeOutputSurface> output_surface( 5925 FakeOutputSurface::CreateDeferredGL( 5926 scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice()), 5927 delegated_rendering)); 5928 output_surface_ = output_surface.get(); 5929 5930 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), 5931 output_surface.PassAs<OutputSurface>())); 5932 5933 scoped_ptr<SolidColorLayerImpl> root_layer = 5934 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 5935 SetupRootLayerImpl(root_layer.PassAs<LayerImpl>()); 5936 5937 onscreen_context_provider_ = TestContextProvider::Create(); 5938 } 5939 5940 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE { 5941 did_update_renderer_capabilities_ = true; 5942 } 5943 5944 FakeOutputSurface* output_surface_; 5945 scoped_refptr<TestContextProvider> onscreen_context_provider_; 5946 bool did_update_renderer_capabilities_; 5947 }; 5948 5949 5950 TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) { 5951 // Software draw. 5952 DrawFrame(); 5953 5954 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5955 5956 // DeferredInitialize and hardware draw. 5957 did_update_renderer_capabilities_ = false; 5958 EXPECT_TRUE( 5959 output_surface_->InitializeAndSetContext3d(onscreen_context_provider_)); 5960 EXPECT_EQ(onscreen_context_provider_.get(), 5961 host_impl_->output_surface()->context_provider()); 5962 EXPECT_TRUE(did_update_renderer_capabilities_); 5963 5964 // Defer intialized GL draw. 5965 DrawFrame(); 5966 5967 // Revert back to software. 5968 did_update_renderer_capabilities_ = false; 5969 output_surface_->ReleaseGL(); 5970 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5971 EXPECT_TRUE(did_update_renderer_capabilities_); 5972 5973 // Software draw again. 5974 DrawFrame(); 5975 } 5976 5977 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails) { 5978 // Software draw. 5979 DrawFrame(); 5980 5981 // Fail initialization of the onscreen context before the OutputSurface binds 5982 // it to the thread. 5983 onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true); 5984 5985 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5986 5987 // DeferredInitialize fails. 5988 did_update_renderer_capabilities_ = false; 5989 EXPECT_FALSE( 5990 output_surface_->InitializeAndSetContext3d(onscreen_context_provider_)); 5991 EXPECT_FALSE(host_impl_->output_surface()->context_provider()); 5992 EXPECT_FALSE(did_update_renderer_capabilities_); 5993 5994 // Software draw again. 5995 DrawFrame(); 5996 } 5997 5998 // Checks that we have a non-0 default allocation if we pass a context that 5999 // doesn't support memory management extensions. 6000 TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { 6001 LayerTreeSettings settings; 6002 host_impl_ = LayerTreeHostImpl::Create(settings, 6003 this, 6004 &proxy_, 6005 &stats_instrumentation_, 6006 shared_bitmap_manager_.get(), 6007 0); 6008 6009 scoped_ptr<OutputSurface> output_surface( 6010 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create())); 6011 host_impl_->InitializeRenderer(output_surface.Pass()); 6012 EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes()); 6013 } 6014 6015 TEST_F(LayerTreeHostImplTest, MemoryPolicy) { 6016 ManagedMemoryPolicy policy1( 6017 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000); 6018 int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( 6019 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING); 6020 int allow_nice_to_have_cutoff_value = 6021 ManagedMemoryPolicy::PriorityCutoffToValue( 6022 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE); 6023 int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( 6024 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING); 6025 6026 // GPU rasterization should be disabled by default on the tree(s) 6027 EXPECT_FALSE(host_impl_->active_tree()->use_gpu_rasterization()); 6028 EXPECT_TRUE(host_impl_->pending_tree() == NULL); 6029 6030 host_impl_->SetVisible(true); 6031 host_impl_->SetMemoryPolicy(policy1); 6032 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); 6033 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_); 6034 6035 host_impl_->SetVisible(false); 6036 EXPECT_EQ(0u, current_limit_bytes_); 6037 EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_); 6038 6039 host_impl_->SetVisible(true); 6040 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); 6041 EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_); 6042 6043 // Now enable GPU rasterization and test if we get nice to have cutoff, 6044 // when visible. 6045 LayerTreeSettings settings; 6046 settings.gpu_rasterization_enabled = true; 6047 host_impl_ = LayerTreeHostImpl::Create( 6048 settings, this, &proxy_, &stats_instrumentation_, NULL, 0); 6049 host_impl_->SetUseGpuRasterization(true); 6050 host_impl_->SetVisible(true); 6051 host_impl_->SetMemoryPolicy(policy1); 6052 EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); 6053 EXPECT_EQ(allow_nice_to_have_cutoff_value, current_priority_cutoff_value_); 6054 6055 host_impl_->SetVisible(false); 6056 EXPECT_EQ(0u, current_limit_bytes_); 6057 EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_); 6058 } 6059 6060 TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) { 6061 ASSERT_TRUE(host_impl_->active_tree()); 6062 6063 // RequiresHighResToDraw is set when new output surface is used. 6064 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6065 6066 host_impl_->active_tree()->ResetRequiresHighResToDraw(); 6067 6068 host_impl_->SetVisible(false); 6069 EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); 6070 host_impl_->SetVisible(true); 6071 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6072 host_impl_->SetVisible(false); 6073 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6074 6075 host_impl_->active_tree()->ResetRequiresHighResToDraw(); 6076 6077 EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); 6078 host_impl_->SetVisible(true); 6079 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6080 } 6081 6082 TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { 6083 ASSERT_TRUE(host_impl_->active_tree()); 6084 EXPECT_FALSE(host_impl_->use_gpu_rasterization()); 6085 6086 // RequiresHighResToDraw is set when new output surface is used. 6087 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6088 6089 host_impl_->active_tree()->ResetRequiresHighResToDraw(); 6090 6091 host_impl_->SetUseGpuRasterization(false); 6092 EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); 6093 host_impl_->SetUseGpuRasterization(true); 6094 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6095 host_impl_->SetUseGpuRasterization(false); 6096 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6097 6098 host_impl_->active_tree()->ResetRequiresHighResToDraw(); 6099 6100 EXPECT_FALSE(host_impl_->active_tree()->RequiresHighResToDraw()); 6101 host_impl_->SetUseGpuRasterization(true); 6102 EXPECT_TRUE(host_impl_->active_tree()->RequiresHighResToDraw()); 6103 } 6104 6105 class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest { 6106 public: 6107 virtual void SetUp() OVERRIDE { 6108 LayerTreeSettings settings; 6109 settings.impl_side_painting = true; 6110 6111 fake_host_impl_ = new FakeLayerTreeHostImpl( 6112 settings, &proxy_, shared_bitmap_manager_.get()); 6113 host_impl_.reset(fake_host_impl_); 6114 host_impl_->InitializeRenderer(CreateOutputSurface()); 6115 host_impl_->SetViewportSize(gfx::Size(10, 10)); 6116 } 6117 6118 FakeLayerTreeHostImpl* fake_host_impl_; 6119 }; 6120 6121 TEST_F(LayerTreeHostImplTestManageTiles, ManageTilesWhenInvisible) { 6122 fake_host_impl_->DidModifyTilePriorities(); 6123 EXPECT_TRUE(fake_host_impl_->manage_tiles_needed()); 6124 fake_host_impl_->SetVisible(false); 6125 EXPECT_FALSE(fake_host_impl_->manage_tiles_needed()); 6126 } 6127 6128 TEST_F(LayerTreeHostImplTest, UIResourceManagement) { 6129 scoped_ptr<TestWebGraphicsContext3D> context = 6130 TestWebGraphicsContext3D::Create(); 6131 TestWebGraphicsContext3D* context3d = context.get(); 6132 scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); 6133 CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); 6134 6135 EXPECT_EQ(0u, context3d->NumTextures()); 6136 6137 UIResourceId ui_resource_id = 1; 6138 bool is_opaque = false; 6139 UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque); 6140 host_impl_->CreateUIResource(ui_resource_id, bitmap); 6141 EXPECT_EQ(1u, context3d->NumTextures()); 6142 ResourceProvider::ResourceId id1 = 6143 host_impl_->ResourceIdForUIResource(ui_resource_id); 6144 EXPECT_NE(0u, id1); 6145 6146 // Multiple requests with the same id is allowed. The previous texture is 6147 // deleted. 6148 host_impl_->CreateUIResource(ui_resource_id, bitmap); 6149 EXPECT_EQ(1u, context3d->NumTextures()); 6150 ResourceProvider::ResourceId id2 = 6151 host_impl_->ResourceIdForUIResource(ui_resource_id); 6152 EXPECT_NE(0u, id2); 6153 EXPECT_NE(id1, id2); 6154 6155 // Deleting invalid UIResourceId is allowed and does not change state. 6156 host_impl_->DeleteUIResource(-1); 6157 EXPECT_EQ(1u, context3d->NumTextures()); 6158 6159 // Should return zero for invalid UIResourceId. Number of textures should 6160 // not change. 6161 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1)); 6162 EXPECT_EQ(1u, context3d->NumTextures()); 6163 6164 host_impl_->DeleteUIResource(ui_resource_id); 6165 EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id)); 6166 EXPECT_EQ(0u, context3d->NumTextures()); 6167 6168 // Should not change state for multiple deletion on one UIResourceId 6169 host_impl_->DeleteUIResource(ui_resource_id); 6170 EXPECT_EQ(0u, context3d->NumTextures()); 6171 } 6172 6173 TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { 6174 scoped_ptr<TestWebGraphicsContext3D> context = 6175 TestWebGraphicsContext3D::Create(); 6176 TestWebGraphicsContext3D* context3d = context.get(); 6177 scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d(); 6178 CreateHostImpl(DefaultSettings(), output_surface.PassAs<OutputSurface>()); 6179 6180 EXPECT_EQ(0u, context3d->NumTextures()); 6181 6182 gfx::Size size(4, 4); 6183 // SkImageInfo has no support for ETC1. The |info| below contains the right 6184 // total pixel size for the bitmap but not the right height and width. The 6185 // correct width/height are passed directly to UIResourceBitmap. 6186 SkImageInfo info = 6187 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType); 6188 skia::RefPtr<SkPixelRef> pixel_ref = 6189 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info, 0, 0)); 6190 pixel_ref->setImmutable(); 6191 UIResourceBitmap bitmap(pixel_ref, size); 6192 UIResourceId ui_resource_id = 1; 6193 host_impl_->CreateUIResource(ui_resource_id, bitmap); 6194 EXPECT_EQ(1u, context3d->NumTextures()); 6195 ResourceProvider::ResourceId id1 = 6196 host_impl_->ResourceIdForUIResource(ui_resource_id); 6197 EXPECT_NE(0u, id1); 6198 } 6199 6200 void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) { 6201 } 6202 6203 TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { 6204 scoped_refptr<TestContextProvider> context_provider = 6205 TestContextProvider::Create(); 6206 6207 CreateHostImpl( 6208 DefaultSettings(), 6209 FakeOutputSurface::Create3d(context_provider).PassAs<OutputSurface>()); 6210 6211 SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); 6212 6213 ScopedPtrVector<CopyOutputRequest> requests; 6214 requests.push_back(CopyOutputRequest::CreateRequest( 6215 base::Bind(&ShutdownReleasesContext_Callback))); 6216 6217 host_impl_->active_tree()->root_layer()->PassCopyRequests(&requests); 6218 6219 LayerTreeHostImpl::FrameData frame; 6220 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 6221 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 6222 host_impl_->DidDrawAllLayers(frame); 6223 6224 // The CopyOutputResult's callback has a ref on the ContextProvider and a 6225 // texture in a texture mailbox. 6226 EXPECT_FALSE(context_provider->HasOneRef()); 6227 EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); 6228 6229 host_impl_.reset(); 6230 6231 // The CopyOutputResult's callback was cancelled, the CopyOutputResult 6232 // released, and the texture deleted. 6233 EXPECT_TRUE(context_provider->HasOneRef()); 6234 EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures()); 6235 } 6236 6237 TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) { 6238 // When flinging via touch, only the child should scroll (we should not 6239 // bubble). 6240 gfx::Size surface_size(10, 10); 6241 gfx::Size content_size(20, 20); 6242 scoped_ptr<LayerImpl> root_clip = 6243 LayerImpl::Create(host_impl_->active_tree(), 3); 6244 scoped_ptr<LayerImpl> root = 6245 CreateScrollableLayer(1, content_size, root_clip.get()); 6246 root->SetIsContainerForFixedPositionLayers(true); 6247 scoped_ptr<LayerImpl> child = 6248 CreateScrollableLayer(2, content_size, root_clip.get()); 6249 6250 root->AddChild(child.Pass()); 6251 int root_id = root->id(); 6252 root_clip->AddChild(root.Pass()); 6253 6254 host_impl_->SetViewportSize(surface_size); 6255 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 6256 host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID); 6257 host_impl_->active_tree()->DidBecomeActive(); 6258 DrawFrame(); 6259 { 6260 EXPECT_EQ(InputHandler::ScrollStarted, 6261 host_impl_->ScrollBegin(gfx::Point(), 6262 InputHandler::Gesture)); 6263 6264 EXPECT_EQ(InputHandler::ScrollStarted, 6265 host_impl_->FlingScrollBegin()); 6266 6267 gfx::Vector2d scroll_delta(0, 100); 6268 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 6269 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 6270 6271 host_impl_->ScrollEnd(); 6272 6273 scoped_ptr<ScrollAndScaleSet> scroll_info = 6274 host_impl_->ProcessScrollDeltas(); 6275 6276 // Only the child should have scrolled. 6277 ASSERT_EQ(1u, scroll_info->scrolls.size()); 6278 ExpectNone(*scroll_info.get(), root_id); 6279 } 6280 } 6281 6282 TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) { 6283 // Scroll a child layer beyond its maximum scroll range and make sure the 6284 // the scroll doesn't bubble up to the parent layer. 6285 gfx::Size surface_size(10, 10); 6286 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1); 6287 scoped_ptr<LayerImpl> root_scrolling = 6288 CreateScrollableLayer(2, surface_size, root.get()); 6289 6290 scoped_ptr<LayerImpl> grand_child = 6291 CreateScrollableLayer(4, surface_size, root.get()); 6292 grand_child->SetScrollOffset(gfx::Vector2d(0, 2)); 6293 6294 scoped_ptr<LayerImpl> child = 6295 CreateScrollableLayer(3, surface_size, root.get()); 6296 child->SetScrollOffset(gfx::Vector2d(0, 4)); 6297 child->AddChild(grand_child.Pass()); 6298 6299 root_scrolling->AddChild(child.Pass()); 6300 root->AddChild(root_scrolling.Pass()); 6301 host_impl_->active_tree()->SetRootLayer(root.Pass()); 6302 host_impl_->active_tree()->DidBecomeActive(); 6303 host_impl_->SetViewportSize(surface_size); 6304 DrawFrame(); 6305 { 6306 scoped_ptr<ScrollAndScaleSet> scroll_info; 6307 LayerImpl* child = 6308 host_impl_->active_tree()->root_layer()->children()[0]->children()[0]; 6309 LayerImpl* grand_child = child->children()[0]; 6310 6311 gfx::Vector2d scroll_delta(0, -2); 6312 EXPECT_EQ(InputHandler::ScrollStarted, 6313 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6314 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); 6315 6316 // The grand child should have scrolled up to its limit. 6317 scroll_info = host_impl_->ProcessScrollDeltas(); 6318 ASSERT_EQ(1u, scroll_info->scrolls.size()); 6319 ExpectContains(*scroll_info, grand_child->id(), scroll_delta); 6320 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 6321 6322 // The child should have received the bubbled delta, but the locked 6323 // scrolling layer should remain set as the grand child. 6324 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); 6325 scroll_info = host_impl_->ProcessScrollDeltas(); 6326 ASSERT_EQ(2u, scroll_info->scrolls.size()); 6327 ExpectContains(*scroll_info, grand_child->id(), scroll_delta); 6328 ExpectContains(*scroll_info, child->id(), scroll_delta); 6329 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child); 6330 6331 // The first |ScrollBy| after the fling should re-lock the scrolling 6332 // layer to the first layer that scrolled, which is the child. 6333 EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); 6334 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); 6335 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); 6336 6337 // The child should have scrolled up to its limit. 6338 scroll_info = host_impl_->ProcessScrollDeltas(); 6339 ASSERT_EQ(2u, scroll_info->scrolls.size()); 6340 ExpectContains(*scroll_info, grand_child->id(), scroll_delta); 6341 ExpectContains(*scroll_info, child->id(), scroll_delta + scroll_delta); 6342 6343 // As the locked layer is at it's limit, no further scrolling can occur. 6344 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta)); 6345 EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child); 6346 host_impl_->ScrollEnd(); 6347 } 6348 } 6349 6350 TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) { 6351 // When flinging via wheel, the root should eventually scroll (we should 6352 // bubble). 6353 gfx::Size surface_size(10, 10); 6354 gfx::Size content_size(20, 20); 6355 scoped_ptr<LayerImpl> root_clip = 6356 LayerImpl::Create(host_impl_->active_tree(), 3); 6357 scoped_ptr<LayerImpl> root_scroll = 6358 CreateScrollableLayer(1, content_size, root_clip.get()); 6359 int root_scroll_id = root_scroll->id(); 6360 scoped_ptr<LayerImpl> child = 6361 CreateScrollableLayer(2, content_size, root_clip.get()); 6362 6363 root_scroll->AddChild(child.Pass()); 6364 root_clip->AddChild(root_scroll.Pass()); 6365 6366 host_impl_->SetViewportSize(surface_size); 6367 host_impl_->active_tree()->SetRootLayer(root_clip.Pass()); 6368 host_impl_->active_tree()->DidBecomeActive(); 6369 DrawFrame(); 6370 { 6371 EXPECT_EQ(InputHandler::ScrollStarted, 6372 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 6373 6374 EXPECT_EQ(InputHandler::ScrollStarted, 6375 host_impl_->FlingScrollBegin()); 6376 6377 gfx::Vector2d scroll_delta(0, 100); 6378 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 6379 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 6380 6381 host_impl_->ScrollEnd(); 6382 6383 scoped_ptr<ScrollAndScaleSet> scroll_info = 6384 host_impl_->ProcessScrollDeltas(); 6385 6386 // The root should have scrolled. 6387 ASSERT_EQ(2u, scroll_info->scrolls.size()); 6388 ExpectContains(*scroll_info.get(), root_scroll_id, gfx::Vector2d(0, 10)); 6389 } 6390 } 6391 6392 TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) { 6393 // If we ray cast a scroller that is not on the first layer's ancestor chain, 6394 // we should return ScrollUnknown. 6395 gfx::Size content_size(100, 100); 6396 SetupScrollAndContentsLayers(content_size); 6397 6398 int scroll_layer_id = 2; 6399 LayerImpl* scroll_layer = 6400 host_impl_->active_tree()->LayerById(scroll_layer_id); 6401 scroll_layer->SetDrawsContent(true); 6402 6403 int page_scale_layer_id = 5; 6404 LayerImpl* page_scale_layer = 6405 host_impl_->active_tree()->LayerById(page_scale_layer_id); 6406 6407 int occluder_layer_id = 6; 6408 scoped_ptr<LayerImpl> occluder_layer = 6409 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); 6410 occluder_layer->SetDrawsContent(true); 6411 occluder_layer->SetBounds(content_size); 6412 occluder_layer->SetContentBounds(content_size); 6413 occluder_layer->SetPosition(gfx::PointF()); 6414 6415 // The parent of the occluder is *above* the scroller. 6416 page_scale_layer->AddChild(occluder_layer.Pass()); 6417 6418 DrawFrame(); 6419 6420 EXPECT_EQ(InputHandler::ScrollUnknown, 6421 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 6422 } 6423 6424 TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { 6425 // If we ray cast a scroller this is on the first layer's ancestor chain, but 6426 // is not the first scroller we encounter when walking up from the layer, we 6427 // should also return ScrollUnknown. 6428 gfx::Size content_size(100, 100); 6429 SetupScrollAndContentsLayers(content_size); 6430 6431 int scroll_layer_id = 2; 6432 LayerImpl* scroll_layer = 6433 host_impl_->active_tree()->LayerById(scroll_layer_id); 6434 scroll_layer->SetDrawsContent(true); 6435 6436 int occluder_layer_id = 6; 6437 scoped_ptr<LayerImpl> occluder_layer = 6438 LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); 6439 occluder_layer->SetDrawsContent(true); 6440 occluder_layer->SetBounds(content_size); 6441 occluder_layer->SetContentBounds(content_size); 6442 occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f)); 6443 6444 int child_scroll_clip_layer_id = 7; 6445 scoped_ptr<LayerImpl> child_scroll_clip = 6446 LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); 6447 6448 int child_scroll_layer_id = 8; 6449 scoped_ptr<LayerImpl> child_scroll = CreateScrollableLayer( 6450 child_scroll_layer_id, content_size, child_scroll_clip.get()); 6451 6452 child_scroll->SetPosition(gfx::PointF(10.f, 10.f)); 6453 6454 child_scroll->AddChild(occluder_layer.Pass()); 6455 scroll_layer->AddChild(child_scroll.Pass()); 6456 6457 DrawFrame(); 6458 6459 EXPECT_EQ(InputHandler::ScrollUnknown, 6460 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 6461 } 6462 6463 TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { 6464 gfx::Size content_size(100, 100); 6465 SetupScrollAndContentsLayers(content_size); 6466 6467 LayerImpl* root = host_impl_->active_tree()->LayerById(1); 6468 6469 int scroll_layer_id = 2; 6470 LayerImpl* scroll_layer = 6471 host_impl_->active_tree()->LayerById(scroll_layer_id); 6472 6473 int child_scroll_layer_id = 7; 6474 scoped_ptr<LayerImpl> child_scroll = 6475 CreateScrollableLayer(child_scroll_layer_id, content_size, root); 6476 child_scroll->SetDrawsContent(false); 6477 6478 scroll_layer->AddChild(child_scroll.Pass()); 6479 6480 DrawFrame(); 6481 6482 // We should not have scrolled |child_scroll| even though we technically "hit" 6483 // it. The reason for this is that if the scrolling the scroll would not move 6484 // any layer that is a drawn RSLL member, then we can ignore the hit. 6485 // 6486 // Why ScrollStarted? In this case, it's because we've bubbled out and started 6487 // overscrolling the inner viewport. 6488 EXPECT_EQ(InputHandler::ScrollStarted, 6489 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 6490 6491 EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id()); 6492 } 6493 6494 TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { 6495 // This test case is very similar to the one above with one key difference: 6496 // the invisible scroller has a scroll child that is indeed draw contents. 6497 // If we attempt to initiate a gesture scroll off of the visible scroll child 6498 // we should still start the scroll child. 6499 gfx::Size content_size(100, 100); 6500 SetupScrollAndContentsLayers(content_size); 6501 6502 LayerImpl* root = host_impl_->active_tree()->LayerById(1); 6503 6504 int scroll_layer_id = 2; 6505 LayerImpl* scroll_layer = 6506 host_impl_->active_tree()->LayerById(scroll_layer_id); 6507 6508 int scroll_child_id = 6; 6509 scoped_ptr<LayerImpl> scroll_child = 6510 LayerImpl::Create(host_impl_->active_tree(), scroll_child_id); 6511 scroll_child->SetDrawsContent(true); 6512 scroll_child->SetBounds(content_size); 6513 scroll_child->SetContentBounds(content_size); 6514 // Move the scroll child so it's not hit by our test point. 6515 scroll_child->SetPosition(gfx::PointF(10.f, 10.f)); 6516 6517 int invisible_scroll_layer_id = 7; 6518 scoped_ptr<LayerImpl> invisible_scroll = 6519 CreateScrollableLayer(invisible_scroll_layer_id, content_size, root); 6520 invisible_scroll->SetDrawsContent(false); 6521 6522 int container_id = 8; 6523 scoped_ptr<LayerImpl> container = 6524 LayerImpl::Create(host_impl_->active_tree(), container_id); 6525 6526 scoped_ptr<std::set<LayerImpl*> > scroll_children(new std::set<LayerImpl*>()); 6527 scroll_children->insert(scroll_child.get()); 6528 invisible_scroll->SetScrollChildren(scroll_children.release()); 6529 6530 scroll_child->SetScrollParent(invisible_scroll.get()); 6531 6532 container->AddChild(invisible_scroll.Pass()); 6533 container->AddChild(scroll_child.Pass()); 6534 6535 scroll_layer->AddChild(container.Pass()); 6536 6537 DrawFrame(); 6538 6539 // We should not have scrolled |child_scroll| even though we technically "hit" 6540 // it. The reason for this is that if the scrolling the scroll would not move 6541 // any layer that is a drawn RSLL member, then we can ignore the hit. 6542 // 6543 // Why ScrollStarted? In this case, it's because we've bubbled out and started 6544 // overscrolling the inner viewport. 6545 EXPECT_EQ(InputHandler::ScrollStarted, 6546 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel)); 6547 6548 EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id()); 6549 } 6550 6551 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed 6552 // to CompositorFrameMetadata after SwapBuffers(); 6553 TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { 6554 scoped_ptr<SolidColorLayerImpl> root = 6555 SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); 6556 root->SetPosition(gfx::PointF()); 6557 root->SetBounds(gfx::Size(10, 10)); 6558 root->SetContentBounds(gfx::Size(10, 10)); 6559 root->SetDrawsContent(true); 6560 6561 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); 6562 6563 FakeOutputSurface* fake_output_surface = 6564 static_cast<FakeOutputSurface*>(host_impl_->output_surface()); 6565 6566 const std::vector<ui::LatencyInfo>& metadata_latency_before = 6567 fake_output_surface->last_sent_frame().metadata.latency_info; 6568 EXPECT_TRUE(metadata_latency_before.empty()); 6569 6570 ui::LatencyInfo latency_info; 6571 latency_info.AddLatencyNumber( 6572 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0); 6573 scoped_ptr<SwapPromise> swap_promise( 6574 new LatencyInfoSwapPromise(latency_info)); 6575 host_impl_->active_tree()->QueueSwapPromise(swap_promise.Pass()); 6576 host_impl_->SetNeedsRedraw(); 6577 6578 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); 6579 LayerTreeHostImpl::FrameData frame; 6580 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 6581 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 6582 host_impl_->DidDrawAllLayers(frame); 6583 EXPECT_TRUE(host_impl_->SwapBuffers(frame)); 6584 6585 const std::vector<ui::LatencyInfo>& metadata_latency_after = 6586 fake_output_surface->last_sent_frame().metadata.latency_info; 6587 EXPECT_EQ(1u, metadata_latency_after.size()); 6588 EXPECT_TRUE(metadata_latency_after[0].FindLatency( 6589 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL)); 6590 } 6591 6592 TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { 6593 int root_layer_id = 1; 6594 scoped_ptr<SolidColorLayerImpl> root = 6595 SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); 6596 root->SetPosition(gfx::PointF()); 6597 root->SetBounds(gfx::Size(10, 10)); 6598 root->SetContentBounds(gfx::Size(10, 10)); 6599 root->SetDrawsContent(true); 6600 6601 host_impl_->active_tree()->SetRootLayer(root.PassAs<LayerImpl>()); 6602 6603 // Ensure the default frame selection bounds are empty. 6604 FakeOutputSurface* fake_output_surface = 6605 static_cast<FakeOutputSurface*>(host_impl_->output_surface()); 6606 const ViewportSelectionBound& selection_start_before = 6607 fake_output_surface->last_sent_frame().metadata.selection_start; 6608 const ViewportSelectionBound& selection_end_before = 6609 fake_output_surface->last_sent_frame().metadata.selection_end; 6610 EXPECT_EQ(ViewportSelectionBound(), selection_start_before); 6611 EXPECT_EQ(ViewportSelectionBound(), selection_end_before); 6612 6613 // Plumb the layer-local selection bounds. 6614 gfx::PointF selection_top(5, 0); 6615 gfx::PointF selection_bottom(5, 5); 6616 LayerSelectionBound start, end; 6617 start.type = SELECTION_BOUND_CENTER; 6618 start.layer_id = root_layer_id; 6619 start.edge_bottom = selection_bottom; 6620 start.edge_top = selection_top; 6621 end = start; 6622 host_impl_->active_tree()->RegisterSelection(start, end); 6623 6624 // Trigger a draw-swap sequence. 6625 host_impl_->SetNeedsRedraw(); 6626 6627 gfx::Rect full_frame_damage(host_impl_->DrawViewportSize()); 6628 LayerTreeHostImpl::FrameData frame; 6629 EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); 6630 host_impl_->DrawLayers(&frame, gfx::FrameTime::Now()); 6631 host_impl_->DidDrawAllLayers(frame); 6632 EXPECT_TRUE(host_impl_->SwapBuffers(frame)); 6633 6634 // Ensure the selection bounds have propagated to the frame metadata. 6635 const ViewportSelectionBound& selection_start_after = 6636 fake_output_surface->last_sent_frame().metadata.selection_start; 6637 const ViewportSelectionBound& selection_end_after = 6638 fake_output_surface->last_sent_frame().metadata.selection_end; 6639 EXPECT_EQ(start.type, selection_start_after.type); 6640 EXPECT_EQ(end.type, selection_end_after.type); 6641 EXPECT_EQ(selection_bottom, selection_start_after.edge_bottom); 6642 EXPECT_EQ(selection_top, selection_start_after.edge_top); 6643 EXPECT_TRUE(selection_start_after.visible); 6644 EXPECT_TRUE(selection_start_after.visible); 6645 } 6646 6647 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { 6648 public: 6649 SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, 6650 LayerTreeHostImpl* layer_tree_host_impl, 6651 int* set_needs_commit_count, 6652 int* set_needs_redraw_count, 6653 int* forward_to_main_count) 6654 : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl), 6655 set_needs_commit_count_(set_needs_commit_count), 6656 set_needs_redraw_count_(set_needs_redraw_count), 6657 forward_to_main_count_(forward_to_main_count) {} 6658 6659 virtual ~SimpleSwapPromiseMonitor() {} 6660 6661 virtual void OnSetNeedsCommitOnMain() OVERRIDE { 6662 (*set_needs_commit_count_)++; 6663 } 6664 6665 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE { 6666 (*set_needs_redraw_count_)++; 6667 } 6668 6669 virtual void OnForwardScrollUpdateToMainThreadOnImpl() OVERRIDE { 6670 (*forward_to_main_count_)++; 6671 } 6672 6673 private: 6674 int* set_needs_commit_count_; 6675 int* set_needs_redraw_count_; 6676 int* forward_to_main_count_; 6677 }; 6678 6679 TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { 6680 int set_needs_commit_count = 0; 6681 int set_needs_redraw_count = 0; 6682 int forward_to_main_count = 0; 6683 6684 { 6685 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 6686 new SimpleSwapPromiseMonitor(NULL, 6687 host_impl_.get(), 6688 &set_needs_commit_count, 6689 &set_needs_redraw_count, 6690 &forward_to_main_count)); 6691 host_impl_->SetNeedsRedraw(); 6692 EXPECT_EQ(0, set_needs_commit_count); 6693 EXPECT_EQ(1, set_needs_redraw_count); 6694 EXPECT_EQ(0, forward_to_main_count); 6695 } 6696 6697 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being 6698 // monitored. 6699 host_impl_->SetNeedsRedraw(); 6700 EXPECT_EQ(0, set_needs_commit_count); 6701 EXPECT_EQ(1, set_needs_redraw_count); 6702 EXPECT_EQ(0, forward_to_main_count); 6703 6704 { 6705 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 6706 new SimpleSwapPromiseMonitor(NULL, 6707 host_impl_.get(), 6708 &set_needs_commit_count, 6709 &set_needs_redraw_count, 6710 &forward_to_main_count)); 6711 host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10)); 6712 EXPECT_EQ(0, set_needs_commit_count); 6713 EXPECT_EQ(2, set_needs_redraw_count); 6714 EXPECT_EQ(0, forward_to_main_count); 6715 } 6716 6717 { 6718 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 6719 new SimpleSwapPromiseMonitor(NULL, 6720 host_impl_.get(), 6721 &set_needs_commit_count, 6722 &set_needs_redraw_count, 6723 &forward_to_main_count)); 6724 // Empty damage rect won't signal the monitor. 6725 host_impl_->SetNeedsRedrawRect(gfx::Rect()); 6726 EXPECT_EQ(0, set_needs_commit_count); 6727 EXPECT_EQ(2, set_needs_redraw_count); 6728 EXPECT_EQ(0, forward_to_main_count); 6729 } 6730 6731 { 6732 set_needs_commit_count = 0; 6733 set_needs_redraw_count = 0; 6734 forward_to_main_count = 0; 6735 scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( 6736 new SimpleSwapPromiseMonitor(NULL, 6737 host_impl_.get(), 6738 &set_needs_commit_count, 6739 &set_needs_redraw_count, 6740 &forward_to_main_count)); 6741 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); 6742 6743 // Scrolling normally should not trigger any forwarding. 6744 EXPECT_EQ(InputHandler::ScrollStarted, 6745 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6746 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10))); 6747 host_impl_->ScrollEnd(); 6748 6749 EXPECT_EQ(0, set_needs_commit_count); 6750 EXPECT_EQ(1, set_needs_redraw_count); 6751 EXPECT_EQ(0, forward_to_main_count); 6752 6753 // Scrolling with a scroll handler should defer the swap to the main 6754 // thread. 6755 scroll_layer->SetHaveScrollEventHandlers(true); 6756 EXPECT_EQ(InputHandler::ScrollStarted, 6757 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6758 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10))); 6759 host_impl_->ScrollEnd(); 6760 6761 EXPECT_EQ(0, set_needs_commit_count); 6762 EXPECT_EQ(2, set_needs_redraw_count); 6763 EXPECT_EQ(1, forward_to_main_count); 6764 } 6765 } 6766 6767 class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest { 6768 public: 6769 virtual void SetUp() OVERRIDE { 6770 LayerTreeSettings settings = DefaultSettings(); 6771 settings.calculate_top_controls_position = true; 6772 settings.top_controls_height = top_controls_height_; 6773 CreateHostImpl(settings, CreateOutputSurface()); 6774 } 6775 6776 protected: 6777 static const int top_controls_height_; 6778 }; 6779 6780 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50; 6781 6782 TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) { 6783 SetupScrollAndContentsLayers(gfx::Size(100, 100)) 6784 ->SetScrollOffset(gfx::Vector2d(0, 10)); 6785 host_impl_->Animate(base::TimeTicks()); 6786 EXPECT_FALSE(did_request_redraw_); 6787 } 6788 6789 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) { 6790 SetupScrollAndContentsLayers(gfx::Size(100, 100)) 6791 ->SetScrollOffset(gfx::Vector2d(0, 10)); 6792 host_impl_->DidChangeTopControlsPosition(); 6793 EXPECT_TRUE(did_request_animate_); 6794 EXPECT_TRUE(did_request_redraw_); 6795 } 6796 6797 TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { 6798 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); 6799 host_impl_->SetViewportSize(gfx::Size(100, 100)); 6800 host_impl_->top_controls_manager()->UpdateTopControlsState( 6801 BOTH, SHOWN, false); 6802 DrawFrame(); 6803 6804 EXPECT_EQ(InputHandler::ScrollStarted, 6805 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6806 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); 6807 EXPECT_EQ(gfx::Vector2dF().ToString(), 6808 scroll_layer->TotalScrollOffset().ToString()); 6809 6810 // Scroll just the top controls and verify that the scroll succeeds. 6811 const float residue = 10; 6812 float offset = top_controls_height_ - residue; 6813 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6814 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); 6815 EXPECT_EQ(gfx::Vector2dF().ToString(), 6816 scroll_layer->TotalScrollOffset().ToString()); 6817 6818 // Scroll across the boundary 6819 const float content_scroll = 20; 6820 offset = residue + content_scroll; 6821 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6822 EXPECT_EQ(-top_controls_height_, 6823 host_impl_->top_controls_manager()->ControlsTopOffset()); 6824 EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(), 6825 scroll_layer->TotalScrollOffset().ToString()); 6826 6827 // Now scroll back to the top of the content 6828 offset = -content_scroll; 6829 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6830 EXPECT_EQ(-top_controls_height_, 6831 host_impl_->top_controls_manager()->ControlsTopOffset()); 6832 EXPECT_EQ(gfx::Vector2dF().ToString(), 6833 scroll_layer->TotalScrollOffset().ToString()); 6834 6835 // And scroll the top controls completely into view 6836 offset = -top_controls_height_; 6837 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6838 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); 6839 EXPECT_EQ(gfx::Vector2dF().ToString(), 6840 scroll_layer->TotalScrollOffset().ToString()); 6841 6842 // And attempt to scroll past the end 6843 EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6844 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); 6845 EXPECT_EQ(gfx::Vector2dF().ToString(), 6846 scroll_layer->TotalScrollOffset().ToString()); 6847 6848 host_impl_->ScrollEnd(); 6849 } 6850 6851 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { 6852 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); 6853 host_impl_->SetViewportSize(gfx::Size(100, 200)); 6854 host_impl_->top_controls_manager()->UpdateTopControlsState( 6855 BOTH, SHOWN, false); 6856 DrawFrame(); 6857 6858 EXPECT_EQ(InputHandler::ScrollStarted, 6859 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6860 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); 6861 EXPECT_EQ(gfx::Vector2dF().ToString(), 6862 scroll_layer->TotalScrollOffset().ToString()); 6863 6864 // Scroll the top controls partially. 6865 const float residue = 35; 6866 float offset = top_controls_height_ - residue; 6867 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6868 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); 6869 EXPECT_EQ(gfx::Vector2dF().ToString(), 6870 scroll_layer->TotalScrollOffset().ToString()); 6871 6872 did_request_redraw_ = false; 6873 did_request_animate_ = false; 6874 did_request_commit_ = false; 6875 6876 // End the scroll while the controls are still offset from their limit. 6877 host_impl_->ScrollEnd(); 6878 ASSERT_TRUE(host_impl_->top_controls_manager()->animation()); 6879 EXPECT_TRUE(did_request_animate_); 6880 EXPECT_TRUE(did_request_redraw_); 6881 EXPECT_FALSE(did_request_commit_); 6882 6883 // The top controls should properly animate until finished, despite the scroll 6884 // offset being at the origin. 6885 base::TimeTicks animation_time = gfx::FrameTime::Now(); 6886 while (did_request_animate_) { 6887 did_request_redraw_ = false; 6888 did_request_animate_ = false; 6889 did_request_commit_ = false; 6890 6891 float old_offset = 6892 host_impl_->top_controls_manager()->ControlsTopOffset(); 6893 6894 animation_time += base::TimeDelta::FromMilliseconds(5); 6895 host_impl_->Animate(animation_time); 6896 EXPECT_EQ(gfx::Vector2dF().ToString(), 6897 scroll_layer->TotalScrollOffset().ToString()); 6898 6899 float new_offset = 6900 host_impl_->top_controls_manager()->ControlsTopOffset(); 6901 6902 // No commit is needed as the controls are animating the content offset, 6903 // not the scroll offset. 6904 EXPECT_FALSE(did_request_commit_); 6905 6906 if (new_offset != old_offset) 6907 EXPECT_TRUE(did_request_redraw_); 6908 6909 if (new_offset != 0) { 6910 EXPECT_TRUE(host_impl_->top_controls_manager()->animation()); 6911 EXPECT_TRUE(did_request_animate_); 6912 } 6913 } 6914 EXPECT_FALSE(host_impl_->top_controls_manager()->animation()); 6915 } 6916 6917 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { 6918 LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); 6919 host_impl_->SetViewportSize(gfx::Size(100, 100)); 6920 host_impl_->top_controls_manager()->UpdateTopControlsState( 6921 BOTH, SHOWN, false); 6922 float initial_scroll_offset = 50; 6923 scroll_layer->SetScrollOffset(gfx::Vector2d(0, initial_scroll_offset)); 6924 DrawFrame(); 6925 6926 EXPECT_EQ(InputHandler::ScrollStarted, 6927 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 6928 EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); 6929 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), 6930 scroll_layer->TotalScrollOffset().ToString()); 6931 6932 // Scroll the top controls partially. 6933 const float residue = 15; 6934 float offset = top_controls_height_ - residue; 6935 EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset))); 6936 EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); 6937 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), 6938 scroll_layer->TotalScrollOffset().ToString()); 6939 6940 did_request_redraw_ = false; 6941 did_request_animate_ = false; 6942 did_request_commit_ = false; 6943 6944 // End the scroll while the controls are still offset from the limit. 6945 host_impl_->ScrollEnd(); 6946 ASSERT_TRUE(host_impl_->top_controls_manager()->animation()); 6947 EXPECT_TRUE(did_request_animate_); 6948 EXPECT_TRUE(did_request_redraw_); 6949 EXPECT_FALSE(did_request_commit_); 6950 6951 // Animate the top controls to the limit. 6952 base::TimeTicks animation_time = gfx::FrameTime::Now(); 6953 while (did_request_animate_) { 6954 did_request_redraw_ = false; 6955 did_request_animate_ = false; 6956 did_request_commit_ = false; 6957 6958 float old_offset = 6959 host_impl_->top_controls_manager()->ControlsTopOffset(); 6960 6961 animation_time += base::TimeDelta::FromMilliseconds(5); 6962 host_impl_->Animate(animation_time); 6963 6964 float new_offset = 6965 host_impl_->top_controls_manager()->ControlsTopOffset(); 6966 6967 if (new_offset != old_offset) { 6968 EXPECT_TRUE(did_request_redraw_); 6969 EXPECT_TRUE(did_request_commit_); 6970 } 6971 } 6972 EXPECT_FALSE(host_impl_->top_controls_manager()->animation()); 6973 } 6974 6975 class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { 6976 public: 6977 void SetupVirtualViewportLayers(const gfx::Size& content_size, 6978 const gfx::Size& outer_viewport, 6979 const gfx::Size& inner_viewport) { 6980 LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); 6981 const int kOuterViewportClipLayerId = 6; 6982 const int kOuterViewportScrollLayerId = 7; 6983 const int kInnerViewportScrollLayerId = 2; 6984 const int kInnerViewportClipLayerId = 4; 6985 const int kPageScaleLayerId = 5; 6986 6987 scoped_ptr<LayerImpl> inner_scroll = 6988 LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); 6989 inner_scroll->SetIsContainerForFixedPositionLayers(true); 6990 inner_scroll->SetScrollOffset(gfx::Vector2d()); 6991 6992 scoped_ptr<LayerImpl> inner_clip = 6993 LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); 6994 inner_clip->SetBounds(inner_viewport); 6995 6996 scoped_ptr<LayerImpl> page_scale = 6997 LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); 6998 6999 inner_scroll->SetScrollClipLayer(inner_clip->id()); 7000 inner_scroll->SetBounds(outer_viewport); 7001 inner_scroll->SetContentBounds(outer_viewport); 7002 inner_scroll->SetPosition(gfx::PointF()); 7003 7004 scoped_ptr<LayerImpl> outer_clip = 7005 LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); 7006 outer_clip->SetBounds(outer_viewport); 7007 outer_clip->SetIsContainerForFixedPositionLayers(true); 7008 7009 scoped_ptr<LayerImpl> outer_scroll = 7010 LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); 7011 outer_scroll->SetScrollClipLayer(outer_clip->id()); 7012 outer_scroll->SetScrollOffset(gfx::Vector2d()); 7013 outer_scroll->SetBounds(content_size); 7014 outer_scroll->SetContentBounds(content_size); 7015 outer_scroll->SetPosition(gfx::PointF()); 7016 7017 scoped_ptr<LayerImpl> contents = 7018 LayerImpl::Create(layer_tree_impl, 8); 7019 contents->SetDrawsContent(true); 7020 contents->SetBounds(content_size); 7021 contents->SetContentBounds(content_size); 7022 contents->SetPosition(gfx::PointF()); 7023 7024 outer_scroll->AddChild(contents.Pass()); 7025 outer_clip->AddChild(outer_scroll.Pass()); 7026 inner_scroll->AddChild(outer_clip.Pass()); 7027 page_scale->AddChild(inner_scroll.Pass()); 7028 inner_clip->AddChild(page_scale.Pass()); 7029 7030 layer_tree_impl->SetRootLayer(inner_clip.Pass()); 7031 layer_tree_impl->SetViewportLayersFromIds(kPageScaleLayerId, 7032 kInnerViewportScrollLayerId, kOuterViewportScrollLayerId); 7033 7034 host_impl_->active_tree()->DidBecomeActive(); 7035 } 7036 }; 7037 7038 TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { 7039 gfx::Size content_size = gfx::Size(100, 160); 7040 gfx::Size outer_viewport = gfx::Size(50, 80); 7041 gfx::Size inner_viewport = gfx::Size(25, 40); 7042 7043 SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); 7044 7045 LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); 7046 LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); 7047 DrawFrame(); 7048 { 7049 gfx::Vector2dF inner_expected; 7050 gfx::Vector2dF outer_expected; 7051 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); 7052 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); 7053 7054 // Make sure the fling goes to the outer viewport first 7055 EXPECT_EQ(InputHandler::ScrollStarted, 7056 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 7057 EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); 7058 7059 gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height()); 7060 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 7061 outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); 7062 7063 host_impl_->ScrollEnd(); 7064 7065 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); 7066 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); 7067 7068 // Fling past the outer viewport boundry, make sure inner viewport scrolls. 7069 EXPECT_EQ(InputHandler::ScrollStarted, 7070 host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture)); 7071 EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin()); 7072 7073 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 7074 outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); 7075 7076 host_impl_->ScrollBy(gfx::Point(), scroll_delta); 7077 inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); 7078 7079 host_impl_->ScrollEnd(); 7080 7081 EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset()); 7082 EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset()); 7083 } 7084 } 7085 7086 class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest { 7087 public: 7088 virtual void SetUp() OVERRIDE { 7089 LayerTreeSettings settings = DefaultSettings(); 7090 settings.max_memory_for_prepaint_percentage = 50; 7091 CreateHostImpl(settings, CreateOutputSurface()); 7092 } 7093 }; 7094 7095 TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) { 7096 // Set up a memory policy and percentages which could cause 7097 // 32-bit integer overflows. 7098 ManagedMemoryPolicy mem_policy(300 * 1024 * 1024); // 300MB 7099 7100 // Verify implicit limits are calculated correctly with no overflows 7101 host_impl_->SetMemoryPolicy(mem_policy); 7102 EXPECT_EQ(host_impl_->global_tile_state().hard_memory_limit_in_bytes, 7103 300u * 1024u * 1024u); 7104 EXPECT_EQ(host_impl_->global_tile_state().soft_memory_limit_in_bytes, 7105 150u * 1024u * 1024u); 7106 } 7107 7108 TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { 7109 const gfx::Size layer_size(100, 100); 7110 gfx::Transform external_transform; 7111 const gfx::Rect external_viewport(layer_size); 7112 const gfx::Rect external_clip(layer_size); 7113 const bool resourceless_software_draw = false; 7114 LayerImpl* layer = SetupScrollAndContentsLayers(layer_size); 7115 7116 host_impl_->SetExternalDrawConstraints(external_transform, 7117 external_viewport, 7118 external_clip, 7119 external_viewport, 7120 external_transform, 7121 resourceless_software_draw); 7122 DrawFrame(); 7123 EXPECT_TRANSFORMATION_MATRIX_EQ( 7124 external_transform, layer->draw_properties().target_space_transform); 7125 7126 external_transform.Translate(20, 20); 7127 host_impl_->SetExternalDrawConstraints(external_transform, 7128 external_viewport, 7129 external_clip, 7130 external_viewport, 7131 external_transform, 7132 resourceless_software_draw); 7133 DrawFrame(); 7134 EXPECT_TRANSFORMATION_MATRIX_EQ( 7135 external_transform, layer->draw_properties().target_space_transform); 7136 } 7137 7138 TEST_F(LayerTreeHostImplTest, ScrollAnimated) { 7139 SetupScrollAndContentsLayers(gfx::Size(100, 200)); 7140 DrawFrame(); 7141 7142 base::TimeTicks start_time = 7143 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); 7144 7145 EXPECT_EQ(InputHandler::ScrollStarted, 7146 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); 7147 7148 LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer(); 7149 7150 host_impl_->Animate(start_time); 7151 host_impl_->UpdateAnimationState(true); 7152 7153 EXPECT_EQ(gfx::Vector2dF(), scrolling_layer->TotalScrollOffset()); 7154 7155 host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(50)); 7156 host_impl_->UpdateAnimationState(true); 7157 7158 float y = scrolling_layer->TotalScrollOffset().y(); 7159 EXPECT_TRUE(y > 1 && y < 49); 7160 7161 // Update target. 7162 EXPECT_EQ(InputHandler::ScrollStarted, 7163 host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50))); 7164 7165 host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(200)); 7166 host_impl_->UpdateAnimationState(true); 7167 7168 y = scrolling_layer->TotalScrollOffset().y(); 7169 EXPECT_TRUE(y > 50 && y < 100); 7170 EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer()); 7171 7172 host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(250)); 7173 host_impl_->UpdateAnimationState(true); 7174 7175 EXPECT_EQ(gfx::Vector2dF(0, 100), scrolling_layer->TotalScrollOffset()); 7176 EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer()); 7177 } 7178 7179 TEST_F(LayerTreeHostImplTest, GetPictureLayerImplPairs) { 7180 host_impl_->CreatePendingTree(); 7181 host_impl_->ActivateSyncTree(); 7182 host_impl_->CreatePendingTree(); 7183 7184 LayerTreeImpl* active_tree = host_impl_->active_tree(); 7185 LayerTreeImpl* pending_tree = host_impl_->pending_tree(); 7186 EXPECT_NE(active_tree, pending_tree); 7187 7188 scoped_ptr<FakePictureLayerImpl> active_layer = 7189 FakePictureLayerImpl::Create(active_tree, 10); 7190 scoped_ptr<FakePictureLayerImpl> pending_layer = 7191 FakePictureLayerImpl::Create(pending_tree, 10); 7192 7193 std::vector<PictureLayerImpl::Pair> layer_pairs; 7194 host_impl_->GetPictureLayerImplPairs(&layer_pairs); 7195 7196 EXPECT_EQ(2u, layer_pairs.size()); 7197 if (layer_pairs[0].active) { 7198 EXPECT_EQ(active_layer.get(), layer_pairs[0].active); 7199 EXPECT_EQ(NULL, layer_pairs[0].pending); 7200 } else { 7201 EXPECT_EQ(pending_layer.get(), layer_pairs[0].pending); 7202 EXPECT_EQ(NULL, layer_pairs[0].active); 7203 } 7204 7205 if (layer_pairs[1].active) { 7206 EXPECT_EQ(active_layer.get(), layer_pairs[1].active); 7207 EXPECT_EQ(NULL, layer_pairs[1].pending); 7208 } else { 7209 EXPECT_EQ(pending_layer.get(), layer_pairs[1].pending); 7210 EXPECT_EQ(NULL, layer_pairs[1].active); 7211 } 7212 7213 active_layer->set_twin_layer(pending_layer.get()); 7214 pending_layer->set_twin_layer(active_layer.get()); 7215 7216 layer_pairs.clear(); 7217 host_impl_->GetPictureLayerImplPairs(&layer_pairs); 7218 EXPECT_EQ(1u, layer_pairs.size()); 7219 7220 EXPECT_EQ(active_layer.get(), layer_pairs[0].active); 7221 EXPECT_EQ(pending_layer.get(), layer_pairs[0].pending); 7222 } 7223 7224 TEST_F(LayerTreeHostImplTest, DidBecomeActive) { 7225 host_impl_->CreatePendingTree(); 7226 host_impl_->ActivateSyncTree(); 7227 host_impl_->CreatePendingTree(); 7228 7229 LayerTreeImpl* pending_tree = host_impl_->pending_tree(); 7230 7231 scoped_ptr<FakePictureLayerImpl> pending_layer = 7232 FakePictureLayerImpl::Create(pending_tree, 10); 7233 pending_layer->DoPostCommitInitializationIfNeeded(); 7234 FakePictureLayerImpl* raw_pending_layer = pending_layer.get(); 7235 pending_tree->SetRootLayer(pending_layer.PassAs<LayerImpl>()); 7236 ASSERT_EQ(raw_pending_layer, pending_tree->root_layer()); 7237 7238 EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count()); 7239 pending_tree->DidBecomeActive(); 7240 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); 7241 7242 scoped_ptr<FakePictureLayerImpl> mask_layer = 7243 FakePictureLayerImpl::Create(pending_tree, 11); 7244 mask_layer->DoPostCommitInitializationIfNeeded(); 7245 FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); 7246 raw_pending_layer->SetMaskLayer(mask_layer.PassAs<LayerImpl>()); 7247 ASSERT_EQ(raw_mask_layer, raw_pending_layer->mask_layer()); 7248 7249 EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); 7250 EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count()); 7251 pending_tree->DidBecomeActive(); 7252 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); 7253 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); 7254 7255 scoped_ptr<FakePictureLayerImpl> replica_layer = 7256 FakePictureLayerImpl::Create(pending_tree, 12); 7257 scoped_ptr<FakePictureLayerImpl> replica_mask_layer = 7258 FakePictureLayerImpl::Create(pending_tree, 13); 7259 replica_mask_layer->DoPostCommitInitializationIfNeeded(); 7260 FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get(); 7261 replica_layer->SetMaskLayer(replica_mask_layer.PassAs<LayerImpl>()); 7262 raw_pending_layer->SetReplicaLayer(replica_layer.PassAs<LayerImpl>()); 7263 ASSERT_EQ(raw_replica_mask_layer, 7264 raw_pending_layer->replica_layer()->mask_layer()); 7265 7266 EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); 7267 EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); 7268 EXPECT_EQ(0u, raw_replica_mask_layer->did_become_active_call_count()); 7269 pending_tree->DidBecomeActive(); 7270 EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count()); 7271 EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count()); 7272 EXPECT_EQ(1u, raw_replica_mask_layer->did_become_active_call_count()); 7273 } 7274 7275 class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest { 7276 public: 7277 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {} 7278 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE { 7279 num_lost_surfaces_++; 7280 } 7281 7282 protected: 7283 int num_lost_surfaces_; 7284 }; 7285 7286 TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) { 7287 // Really we just need at least one client notification each time 7288 // we go from having a valid output surface to not having a valid output 7289 // surface. 7290 EXPECT_EQ(0, num_lost_surfaces_); 7291 host_impl_->DidLoseOutputSurface(); 7292 EXPECT_EQ(1, num_lost_surfaces_); 7293 host_impl_->DidLoseOutputSurface(); 7294 EXPECT_LE(1, num_lost_surfaces_); 7295 } 7296 7297 } // namespace 7298 } // namespace cc 7299