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