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.
5 #include "cc/trees/layer_tree_host_impl.h"
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/containers/scoped_ptr_hash_map.h"
14 #include "cc/animation/scrollbar_animation_controller_thinning.h"
15 #include "cc/base/latency_info_swap_promise.h"
16 #include "cc/base/math_util.h"
17 #include "cc/input/page_scale_animation.h"
18 #include "cc/input/top_controls_manager.h"
19 #include "cc/layers/append_quads_data.h"
20 #include "cc/layers/delegated_renderer_layer_impl.h"
21 #include "cc/layers/heads_up_display_layer_impl.h"
22 #include "cc/layers/io_surface_layer_impl.h"
23 #include "cc/layers/layer_impl.h"
24 #include "cc/layers/painted_scrollbar_layer_impl.h"
25 #include "cc/layers/render_surface_impl.h"
26 #include "cc/layers/solid_color_layer_impl.h"
27 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
28 #include "cc/layers/texture_layer_impl.h"
29 #include "cc/layers/tiled_layer_impl.h"
30 #include "cc/layers/video_layer_impl.h"
31 #include "cc/output/begin_frame_args.h"
32 #include "cc/output/compositor_frame_ack.h"
33 #include "cc/output/compositor_frame_metadata.h"
34 #include "cc/output/copy_output_request.h"
35 #include "cc/output/copy_output_result.h"
36 #include "cc/output/gl_renderer.h"
37 #include "cc/quads/render_pass_draw_quad.h"
38 #include "cc/quads/solid_color_draw_quad.h"
39 #include "cc/quads/texture_draw_quad.h"
40 #include "cc/quads/tile_draw_quad.h"
41 #include "cc/resources/layer_tiling_data.h"
42 #include "cc/test/animation_test_common.h"
43 #include "cc/test/begin_frame_args_test.h"
44 #include "cc/test/fake_layer_tree_host_impl.h"
45 #include "cc/test/fake_output_surface.h"
46 #include "cc/test/fake_output_surface_client.h"
47 #include "cc/test/fake_picture_layer_impl.h"
48 #include "cc/test/fake_picture_pile_impl.h"
49 #include "cc/test/fake_proxy.h"
50 #include "cc/test/fake_video_frame_provider.h"
51 #include "cc/test/geometry_test_utils.h"
52 #include "cc/test/layer_test_common.h"
53 #include "cc/test/render_pass_test_common.h"
54 #include "cc/test/test_gpu_memory_buffer_manager.h"
55 #include "cc/test/test_shared_bitmap_manager.h"
56 #include "cc/test/test_web_graphics_context_3d.h"
57 #include "cc/trees/layer_tree_impl.h"
58 #include "cc/trees/single_thread_proxy.h"
59 #include "media/base/media.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "third_party/skia/include/core/SkMallocPixelRef.h"
63 #include "ui/gfx/frame_time.h"
64 #include "ui/gfx/geometry/rect_conversions.h"
65 #include "ui/gfx/geometry/size_conversions.h"
66 #include "ui/gfx/geometry/vector2d_conversions.h"
68 using ::testing::Mock
;
69 using ::testing::Return
;
70 using ::testing::AnyNumber
;
71 using ::testing::AtLeast
;
73 using media::VideoFrame
;
78 class LayerTreeHostImplTest
: public testing::Test
,
79 public LayerTreeHostImplClient
{
81 LayerTreeHostImplTest()
82 : proxy_(base::MessageLoopProxy::current(),
83 base::MessageLoopProxy::current()),
84 always_impl_thread_(&proxy_
),
85 always_main_thread_blocked_(&proxy_
),
86 shared_bitmap_manager_(new TestSharedBitmapManager
),
87 gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager
),
88 on_can_draw_state_changed_called_(false),
89 did_notify_ready_to_activate_(false),
90 did_request_commit_(false),
91 did_request_redraw_(false),
92 did_request_animate_(false),
93 did_request_manage_tiles_(false),
94 did_upload_visible_tile_(false),
95 reduce_memory_result_(true),
96 current_limit_bytes_(0),
97 current_priority_cutoff_value_(0) {
98 media::InitializeMediaLibraryForTesting();
101 LayerTreeSettings
DefaultSettings() {
102 LayerTreeSettings settings
;
103 settings
.minimum_occlusion_tracking_size
= gfx::Size();
104 settings
.impl_side_painting
= true;
105 settings
.texture_id_allocation_chunk_size
= 1;
106 settings
.report_overscroll_only_for_scrollable_axes
= true;
107 settings
.use_pinch_virtual_viewport
= true;
111 virtual void SetUp() override
{
112 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
115 virtual void TearDown() override
{}
117 void UpdateRendererCapabilitiesOnImplThread() override
{}
118 void DidLoseOutputSurfaceOnImplThread() override
{}
119 void CommitVSyncParameters(base::TimeTicks timebase
,
120 base::TimeDelta interval
) override
{}
121 void SetEstimatedParentDrawTime(base::TimeDelta draw_time
) override
{}
122 void SetMaxSwapsPendingOnImplThread(int max
) override
{}
123 void DidSwapBuffersOnImplThread() override
{}
124 void DidSwapBuffersCompleteOnImplThread() override
{}
125 void OnCanDrawStateChanged(bool can_draw
) override
{
126 on_can_draw_state_changed_called_
= true;
128 void NotifyReadyToActivate() override
{
129 did_notify_ready_to_activate_
= true;
130 host_impl_
->ActivateSyncTree();
132 void SetNeedsRedrawOnImplThread() override
{ did_request_redraw_
= true; }
133 void SetNeedsRedrawRectOnImplThread(const gfx::Rect
& damage_rect
) override
{
134 did_request_redraw_
= true;
136 void SetNeedsAnimateOnImplThread() override
{ did_request_animate_
= true; }
137 void SetNeedsManageTilesOnImplThread() override
{
138 did_request_manage_tiles_
= true;
140 void DidInitializeVisibleTileOnImplThread() override
{
141 did_upload_visible_tile_
= true;
143 void SetNeedsCommitOnImplThread() override
{ did_request_commit_
= true; }
144 void PostAnimationEventsToMainThreadOnImplThread(
145 scoped_ptr
<AnimationEventsVector
> events
) override
{}
146 bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes
,
147 int priority_cutoff
) override
{
148 current_limit_bytes_
= limit_bytes
;
149 current_priority_cutoff_value_
= priority_cutoff
;
150 return reduce_memory_result_
;
152 bool IsInsideDraw() override
{ return false; }
153 void RenewTreePriority() override
{}
154 void PostDelayedScrollbarFadeOnImplThread(const base::Closure
& start_fade
,
155 base::TimeDelta delay
) override
{
156 scrollbar_fade_start_
= start_fade
;
157 requested_scrollbar_animation_delay_
= delay
;
159 void DidActivateSyncTree() override
{}
160 void DidManageTiles() override
{}
162 void set_reduce_memory_result(bool reduce_memory_result
) {
163 reduce_memory_result_
= reduce_memory_result
;
166 bool CreateHostImpl(const LayerTreeSettings
& settings
,
167 scoped_ptr
<OutputSurface
> output_surface
) {
168 host_impl_
= LayerTreeHostImpl::Create(settings
,
171 &stats_instrumentation_
,
172 shared_bitmap_manager_
.get(),
173 gpu_memory_buffer_manager_
.get(),
175 bool init
= host_impl_
->InitializeRenderer(output_surface
.Pass());
176 host_impl_
->SetViewportSize(gfx::Size(10, 10));
180 void SetupRootLayerImpl(scoped_ptr
<LayerImpl
> root
) {
181 root
->SetPosition(gfx::PointF());
182 root
->SetBounds(gfx::Size(10, 10));
183 root
->SetContentBounds(gfx::Size(10, 10));
184 root
->SetDrawsContent(true);
185 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
186 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
189 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
190 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
191 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
192 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
195 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
197 const gfx::Vector2d
& scroll_delta
) {
198 int times_encountered
= 0;
200 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
201 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
203 EXPECT_VECTOR_EQ(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
);
207 ASSERT_EQ(1, times_encountered
);
210 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
211 int times_encountered
= 0;
213 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
214 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
219 ASSERT_EQ(0, times_encountered
);
222 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
223 const gfx::Size
& content_size
) {
224 const int kInnerViewportScrollLayerId
= 2;
225 const int kInnerViewportClipLayerId
= 4;
226 const int kPageScaleLayerId
= 5;
227 scoped_ptr
<LayerImpl
> root
=
228 LayerImpl::Create(layer_tree_impl
, 1);
229 root
->SetBounds(content_size
);
230 root
->SetContentBounds(content_size
);
231 root
->SetPosition(gfx::PointF());
233 scoped_ptr
<LayerImpl
> scroll
=
234 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
235 LayerImpl
* scroll_layer
= scroll
.get();
236 scroll
->SetIsContainerForFixedPositionLayers(true);
237 scroll
->SetScrollOffset(gfx::ScrollOffset());
239 scoped_ptr
<LayerImpl
> clip
=
240 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
242 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
244 scoped_ptr
<LayerImpl
> page_scale
=
245 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
247 scroll
->SetScrollClipLayer(clip
->id());
248 scroll
->SetBounds(content_size
);
249 scroll
->SetContentBounds(content_size
);
250 scroll
->SetPosition(gfx::PointF());
251 scroll
->SetIsContainerForFixedPositionLayers(true);
253 scoped_ptr
<LayerImpl
> contents
=
254 LayerImpl::Create(layer_tree_impl
, 3);
255 contents
->SetDrawsContent(true);
256 contents
->SetBounds(content_size
);
257 contents
->SetContentBounds(content_size
);
258 contents
->SetPosition(gfx::PointF());
260 scroll
->AddChild(contents
.Pass());
261 page_scale
->AddChild(scroll
.Pass());
262 clip
->AddChild(page_scale
.Pass());
263 root
->AddChild(clip
.Pass());
265 layer_tree_impl
->SetRootLayer(root
.Pass());
266 layer_tree_impl
->SetViewportLayersFromIds(
267 kPageScaleLayerId
, kInnerViewportScrollLayerId
, Layer::INVALID_ID
);
272 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
273 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
274 host_impl_
->active_tree(), content_size
);
275 host_impl_
->active_tree()->DidBecomeActive();
279 // TODO(wjmaclean) Add clip-layer pointer to parameters.
280 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
281 const gfx::Size
& size
,
282 LayerImpl
* clip_layer
) {
284 DCHECK(id
!= clip_layer
->id());
285 scoped_ptr
<LayerImpl
> layer
=
286 LayerImpl::Create(host_impl_
->active_tree(), id
);
287 layer
->SetScrollClipLayer(clip_layer
->id());
288 layer
->SetDrawsContent(true);
289 layer
->SetBounds(size
);
290 layer
->SetContentBounds(size
);
291 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
296 LayerTreeHostImpl::FrameData frame
;
297 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
298 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
299 host_impl_
->DidDrawAllLayers(frame
);
302 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
303 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
304 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
305 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
306 float device_scale_factor
);
308 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
309 // Note: It is not possible to disable the renderer once it has been set,
310 // so we do not need to test that disabling the renderer notifies us
311 // that can_draw changed.
312 EXPECT_FALSE(host_impl_
->CanDraw());
313 on_can_draw_state_changed_called_
= false;
315 // Set up the root layer, which allows us to draw.
316 SetupScrollAndContentsLayers(gfx::Size(100, 100));
317 EXPECT_TRUE(host_impl_
->CanDraw());
318 EXPECT_TRUE(on_can_draw_state_changed_called_
);
319 on_can_draw_state_changed_called_
= false;
321 // Toggle the root layer to make sure it toggles can_draw
322 host_impl_
->active_tree()->SetRootLayer(nullptr);
323 EXPECT_FALSE(host_impl_
->CanDraw());
324 EXPECT_TRUE(on_can_draw_state_changed_called_
);
325 on_can_draw_state_changed_called_
= false;
327 SetupScrollAndContentsLayers(gfx::Size(100, 100));
328 EXPECT_TRUE(host_impl_
->CanDraw());
329 EXPECT_TRUE(on_can_draw_state_changed_called_
);
330 on_can_draw_state_changed_called_
= false;
332 // Toggle the device viewport size to make sure it toggles can_draw.
333 host_impl_
->SetViewportSize(gfx::Size());
335 EXPECT_TRUE(host_impl_
->CanDraw());
337 EXPECT_FALSE(host_impl_
->CanDraw());
339 EXPECT_TRUE(on_can_draw_state_changed_called_
);
340 on_can_draw_state_changed_called_
= false;
342 host_impl_
->SetViewportSize(gfx::Size(100, 100));
343 EXPECT_TRUE(host_impl_
->CanDraw());
344 EXPECT_TRUE(on_can_draw_state_changed_called_
);
345 on_can_draw_state_changed_called_
= false;
347 // Toggle contents textures purged without causing any evictions,
348 // and make sure that it does not change can_draw.
349 set_reduce_memory_result(false);
350 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
351 host_impl_
->memory_allocation_limit_bytes() - 1));
352 EXPECT_TRUE(host_impl_
->CanDraw());
353 EXPECT_FALSE(on_can_draw_state_changed_called_
);
354 on_can_draw_state_changed_called_
= false;
356 // Toggle contents textures purged to make sure it toggles can_draw.
357 set_reduce_memory_result(true);
358 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
359 host_impl_
->memory_allocation_limit_bytes() - 1));
361 EXPECT_TRUE(host_impl_
->CanDraw());
363 EXPECT_FALSE(host_impl_
->CanDraw());
365 EXPECT_TRUE(on_can_draw_state_changed_called_
);
366 on_can_draw_state_changed_called_
= false;
368 host_impl_
->active_tree()->ResetContentsTexturesPurged();
369 EXPECT_TRUE(host_impl_
->CanDraw());
370 EXPECT_TRUE(on_can_draw_state_changed_called_
);
371 on_can_draw_state_changed_called_
= false;
374 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
377 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
378 return FakeOutputSurface::Create3d();
381 void DrawOneFrame() {
382 LayerTreeHostImpl::FrameData frame_data
;
383 host_impl_
->PrepareToDraw(&frame_data
);
384 host_impl_
->DidDrawAllLayers(frame_data
);
388 DebugScopedSetImplThread always_impl_thread_
;
389 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
391 scoped_ptr
<TestSharedBitmapManager
> shared_bitmap_manager_
;
392 scoped_ptr
<TestGpuMemoryBufferManager
> gpu_memory_buffer_manager_
;
393 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
394 FakeRenderingStatsInstrumentation stats_instrumentation_
;
395 bool on_can_draw_state_changed_called_
;
396 bool did_notify_ready_to_activate_
;
397 bool did_request_commit_
;
398 bool did_request_redraw_
;
399 bool did_request_animate_
;
400 bool did_request_manage_tiles_
;
401 bool did_upload_visible_tile_
;
402 bool reduce_memory_result_
;
403 base::Closure scrollbar_fade_start_
;
404 base::TimeDelta requested_scrollbar_animation_delay_
;
405 size_t current_limit_bytes_
;
406 int current_priority_cutoff_value_
;
409 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
410 bool always_draw
= false;
411 CheckNotifyCalledIfCanDrawChanged(always_draw
);
414 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
415 CreateHostImpl(DefaultSettings(),
416 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
418 bool always_draw
= true;
419 CheckNotifyCalledIfCanDrawChanged(always_draw
);
422 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
423 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
425 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
426 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
429 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
431 scoped_ptr
<LayerImpl
> root
=
432 LayerImpl::Create(host_impl_
->active_tree(), 1);
433 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
434 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
435 root
->children()[1]->AddChild(
436 LayerImpl::Create(host_impl_
->active_tree(), 4));
437 root
->children()[1]->AddChild(
438 LayerImpl::Create(host_impl_
->active_tree(), 5));
439 root
->children()[1]->children()[0]->AddChild(
440 LayerImpl::Create(host_impl_
->active_tree(), 6));
441 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
443 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
445 ExpectClearedScrollDeltasRecursive(root
);
447 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
449 scroll_info
= host_impl_
->ProcessScrollDeltas();
450 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
451 ExpectClearedScrollDeltasRecursive(root
);
453 scroll_info
= host_impl_
->ProcessScrollDeltas();
454 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
455 ExpectClearedScrollDeltasRecursive(root
);
458 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
459 gfx::ScrollOffset
scroll_offset(20, 30);
460 gfx::Vector2d
scroll_delta(11, -15);
462 scoped_ptr
<LayerImpl
> root_clip
=
463 LayerImpl::Create(host_impl_
->active_tree(), 2);
464 scoped_ptr
<LayerImpl
> root
=
465 LayerImpl::Create(host_impl_
->active_tree(), 1);
466 root_clip
->SetBounds(gfx::Size(10, 10));
467 LayerImpl
* root_layer
= root
.get();
468 root_clip
->AddChild(root
.Pass());
469 root_layer
->SetBounds(gfx::Size(110, 110));
470 root_layer
->SetScrollClipLayer(root_clip
->id());
471 root_layer
->SetScrollOffset(scroll_offset
);
472 root_layer
->ScrollBy(scroll_delta
);
473 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
475 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
477 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
479 scroll_info
= host_impl_
->ProcessScrollDeltas();
480 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
481 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
);
482 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
484 gfx::Vector2d
scroll_delta2(-5, 27);
485 root
->ScrollBy(scroll_delta2
);
486 scroll_info
= host_impl_
->ProcessScrollDeltas();
487 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
488 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
489 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
491 root
->ScrollBy(gfx::Vector2d());
492 scroll_info
= host_impl_
->ProcessScrollDeltas();
493 EXPECT_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
496 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
497 SetupScrollAndContentsLayers(gfx::Size(100, 100));
498 host_impl_
->SetViewportSize(gfx::Size(50, 50));
501 EXPECT_EQ(InputHandler::ScrollStarted
,
502 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
503 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
504 InputHandler::Wheel
));
505 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
506 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
507 InputHandler::Wheel
));
508 host_impl_
->ScrollEnd();
509 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
510 InputHandler::Wheel
));
511 EXPECT_TRUE(did_request_redraw_
);
512 EXPECT_TRUE(did_request_commit_
);
515 TEST_F(LayerTreeHostImplTest
, ScrollActiveOnlyAfterScrollMovement
) {
516 SetupScrollAndContentsLayers(gfx::Size(100, 100));
517 host_impl_
->SetViewportSize(gfx::Size(50, 50));
520 EXPECT_EQ(InputHandler::ScrollStarted
,
521 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
522 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
523 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
524 EXPECT_TRUE(host_impl_
->IsActivelyScrolling());
525 host_impl_
->ScrollEnd();
526 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
529 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
530 // We should not crash when trying to scroll an empty layer tree.
531 EXPECT_EQ(InputHandler::ScrollIgnored
,
532 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
535 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
536 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
537 TestWebGraphicsContext3D::Create();
538 context_owned
->set_context_lost(true);
540 // Initialization will fail.
541 EXPECT_FALSE(CreateHostImpl(
542 DefaultSettings(), FakeOutputSurface::Create3d(context_owned
.Pass())));
544 SetupScrollAndContentsLayers(gfx::Size(100, 100));
546 // We should not crash when trying to scroll after the renderer initialization
548 EXPECT_EQ(InputHandler::ScrollStarted
,
549 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
552 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
553 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
554 host_impl_
->SetViewportSize(gfx::Size(50, 50));
557 // We should not crash if the tree is replaced while we are scrolling.
558 EXPECT_EQ(InputHandler::ScrollStarted
,
559 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
560 host_impl_
->active_tree()->DetachLayerTree();
562 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
564 // We should still be scrolling, because the scrolled layer also exists in the
566 gfx::Vector2d
scroll_delta(0, 10);
567 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
568 host_impl_
->ScrollEnd();
569 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
570 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
573 TEST_F(LayerTreeHostImplTest
, ClearRootRenderSurfaceAndScroll
) {
574 SetupScrollAndContentsLayers(gfx::Size(100, 100));
575 host_impl_
->SetViewportSize(gfx::Size(50, 50));
578 // We should be able to scroll even if the root layer loses its render surface
579 // after the most recent render.
580 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
581 host_impl_
->active_tree()->set_needs_update_draw_properties();
583 EXPECT_EQ(InputHandler::ScrollStarted
,
584 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
587 TEST_F(LayerTreeHostImplTest
, WheelEventHandlers
) {
588 SetupScrollAndContentsLayers(gfx::Size(100, 100));
589 host_impl_
->SetViewportSize(gfx::Size(50, 50));
591 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
593 root
->SetHaveWheelEventHandlers(true);
595 // With registered event handlers, wheel scrolls have to go to the main
597 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
598 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
600 // But gesture scrolls can still be handled.
601 EXPECT_EQ(InputHandler::ScrollStarted
,
602 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
605 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
606 SetupScrollAndContentsLayers(gfx::Size(100, 100));
607 host_impl_
->SetViewportSize(gfx::Size(50, 50));
610 // Ignore the fling since no layer is being scrolled
611 EXPECT_EQ(InputHandler::ScrollIgnored
,
612 host_impl_
->FlingScrollBegin());
614 // Start scrolling a layer
615 EXPECT_EQ(InputHandler::ScrollStarted
,
616 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
618 // Now the fling should go ahead since we've started scrolling a layer
619 EXPECT_EQ(InputHandler::ScrollStarted
,
620 host_impl_
->FlingScrollBegin());
623 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
624 SetupScrollAndContentsLayers(gfx::Size(100, 100));
625 host_impl_
->SetViewportSize(gfx::Size(50, 50));
628 // Ignore the fling since no layer is being scrolled
629 EXPECT_EQ(InputHandler::ScrollIgnored
,
630 host_impl_
->FlingScrollBegin());
632 // Start scrolling a layer
633 EXPECT_EQ(InputHandler::ScrollStarted
,
634 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
636 // Now the fling should go ahead since we've started scrolling a layer
637 EXPECT_EQ(InputHandler::ScrollStarted
,
638 host_impl_
->FlingScrollBegin());
641 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
642 SetupScrollAndContentsLayers(gfx::Size(100, 100));
643 host_impl_
->SetViewportSize(gfx::Size(50, 50));
645 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
647 root
->SetShouldScrollOnMainThread(true);
649 // Start scrolling a layer
650 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
651 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
653 // The fling should be ignored since there's no layer being scrolled impl-side
654 EXPECT_EQ(InputHandler::ScrollIgnored
,
655 host_impl_
->FlingScrollBegin());
658 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
659 SetupScrollAndContentsLayers(gfx::Size(100, 100));
660 host_impl_
->SetViewportSize(gfx::Size(50, 50));
662 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
664 root
->SetShouldScrollOnMainThread(true);
666 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
667 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
668 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
669 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
672 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
673 SetupScrollAndContentsLayers(gfx::Size(200, 200));
674 host_impl_
->SetViewportSize(gfx::Size(100, 100));
676 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
677 root
->SetContentsScale(2.f
, 2.f
);
678 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
682 // All scroll types inside the non-fast scrollable region should fail.
683 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
684 host_impl_
->ScrollBegin(gfx::Point(25, 25),
685 InputHandler::Wheel
));
686 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
687 InputHandler::Wheel
));
688 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
689 host_impl_
->ScrollBegin(gfx::Point(25, 25),
690 InputHandler::Gesture
));
691 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
692 InputHandler::Gesture
));
694 // All scroll types outside this region should succeed.
695 EXPECT_EQ(InputHandler::ScrollStarted
,
696 host_impl_
->ScrollBegin(gfx::Point(75, 75),
697 InputHandler::Wheel
));
698 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
699 InputHandler::Gesture
));
700 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
701 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
702 InputHandler::Gesture
));
703 host_impl_
->ScrollEnd();
704 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
705 InputHandler::Gesture
));
706 EXPECT_EQ(InputHandler::ScrollStarted
,
707 host_impl_
->ScrollBegin(gfx::Point(75, 75),
708 InputHandler::Gesture
));
709 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
710 InputHandler::Gesture
));
711 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
712 host_impl_
->ScrollEnd();
713 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
714 InputHandler::Gesture
));
717 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
718 SetupScrollAndContentsLayers(gfx::Size(200, 200));
719 host_impl_
->SetViewportSize(gfx::Size(100, 100));
721 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
722 root
->SetContentsScale(2.f
, 2.f
);
723 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
724 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
728 // This point would fall into the non-fast scrollable region except that we've
729 // moved the layer down by 25 pixels.
730 EXPECT_EQ(InputHandler::ScrollStarted
,
731 host_impl_
->ScrollBegin(gfx::Point(40, 10),
732 InputHandler::Wheel
));
733 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
734 InputHandler::Wheel
));
735 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
736 host_impl_
->ScrollEnd();
738 // This point is still inside the non-fast region.
739 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
740 host_impl_
->ScrollBegin(gfx::Point(10, 10),
741 InputHandler::Wheel
));
744 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
745 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
746 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
747 host_impl_
->SetViewportSize(gfx::Size(50, 50));
750 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
751 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
752 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
753 host_impl_
->ScrollEnd();
754 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
757 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
758 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
759 scroll_layer
->SetHaveScrollEventHandlers(true);
760 host_impl_
->SetViewportSize(gfx::Size(50, 50));
763 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
764 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
765 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
766 host_impl_
->ScrollEnd();
767 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
770 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
771 SetupScrollAndContentsLayers(gfx::Size(200, 200));
772 host_impl_
->SetViewportSize(gfx::Size(100, 100));
776 EXPECT_EQ(InputHandler::ScrollStarted
,
777 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
779 // Trying to scroll to the left/top will not succeed.
780 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
781 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
782 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
784 // Scrolling to the right/bottom will succeed.
785 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
786 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
787 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
789 // Scrolling to left/top will now succeed.
790 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
791 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
792 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
794 // Scrolling diagonally against an edge will succeed.
795 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
796 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
797 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
799 // Trying to scroll more than the available space will also succeed.
800 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
803 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
804 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
805 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
809 EXPECT_EQ(InputHandler::ScrollStarted
,
810 host_impl_
->ScrollBegin(gfx::Point(),
811 InputHandler::Wheel
));
813 // Trying to scroll without a vertical scrollbar will fail.
814 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
815 gfx::Point(), SCROLL_FORWARD
));
816 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
817 gfx::Point(), SCROLL_BACKWARD
));
819 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
820 PaintedScrollbarLayerImpl::Create(
821 host_impl_
->active_tree(),
824 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
825 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
826 vertical_scrollbar
.get());
828 // Trying to scroll with a vertical scrollbar will succeed.
829 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
830 gfx::Point(), SCROLL_FORWARD
));
831 EXPECT_FLOAT_EQ(875.f
,
832 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
833 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
834 gfx::Point(), SCROLL_BACKWARD
));
837 TEST_F(LayerTreeHostImplTest
, ScrollWithUserUnscrollableLayers
) {
838 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
839 host_impl_
->SetViewportSize(gfx::Size(100, 100));
841 gfx::Size
overflow_size(400, 400);
842 ASSERT_EQ(1u, scroll_layer
->children().size());
843 LayerImpl
* overflow
= scroll_layer
->children()[0];
844 overflow
->SetBounds(overflow_size
);
845 overflow
->SetContentBounds(overflow_size
);
846 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
847 overflow
->SetScrollOffset(gfx::ScrollOffset());
848 overflow
->SetPosition(gfx::PointF());
851 gfx::Point
scroll_position(10, 10);
853 EXPECT_EQ(InputHandler::ScrollStarted
,
854 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
855 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
856 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->TotalScrollOffset());
858 gfx::Vector2dF
scroll_delta(10, 10);
859 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
860 host_impl_
->ScrollEnd();
861 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
862 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
864 overflow
->set_user_scrollable_horizontal(false);
866 EXPECT_EQ(InputHandler::ScrollStarted
,
867 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
868 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
869 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
871 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
872 host_impl_
->ScrollEnd();
873 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
874 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
876 overflow
->set_user_scrollable_vertical(false);
878 EXPECT_EQ(InputHandler::ScrollStarted
,
879 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
880 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
881 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
883 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
884 host_impl_
->ScrollEnd();
885 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->TotalScrollOffset());
886 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
889 TEST_F(LayerTreeHostImplTest
,
890 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion
) {
891 SetupScrollAndContentsLayers(gfx::Size(100, 100));
892 host_impl_
->SetViewportSize(gfx::Size(50, 50));
895 // We should be able to hit test for touch event handlers even if the root
896 // layer loses its render surface after the most recent render.
897 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
898 host_impl_
->active_tree()->set_needs_update_draw_properties();
900 EXPECT_EQ(host_impl_
->HaveTouchEventHandlersAt(gfx::Point()), false);
903 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
904 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
905 host_impl_
->SetViewportSize(gfx::Size(50, 50));
908 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
909 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
910 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
912 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
913 float page_scale_factor
= 1.f
;
915 // The impl-based pinch zoom should adjust the max scroll position.
917 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
918 page_scale_factor
, min_page_scale
, max_page_scale
);
919 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
920 scroll_layer
->SetScrollDelta(gfx::Vector2d());
922 float page_scale_delta
= 2.f
;
924 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
925 host_impl_
->PinchGestureBegin();
926 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
927 host_impl_
->PinchGestureEnd();
928 host_impl_
->ScrollEnd();
929 EXPECT_FALSE(did_request_animate_
);
930 EXPECT_TRUE(did_request_redraw_
);
931 EXPECT_TRUE(did_request_commit_
);
932 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
934 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
935 host_impl_
->ProcessScrollDeltas();
936 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
938 EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
939 scroll_layer
->MaxScrollOffset().ToString());
942 // Scrolling after a pinch gesture should always be in local space. The
943 // scroll deltas do not have the page scale factor applied.
945 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
946 page_scale_factor
, min_page_scale
, max_page_scale
);
947 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
948 scroll_layer
->SetScrollDelta(gfx::Vector2d());
950 float page_scale_delta
= 2.f
;
951 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
952 host_impl_
->PinchGestureBegin();
953 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
954 host_impl_
->PinchGestureEnd();
955 host_impl_
->ScrollEnd();
957 gfx::Vector2d
scroll_delta(0, 10);
958 EXPECT_EQ(InputHandler::ScrollStarted
,
959 host_impl_
->ScrollBegin(gfx::Point(5, 5),
960 InputHandler::Wheel
));
961 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
962 host_impl_
->ScrollEnd();
964 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
965 host_impl_
->ProcessScrollDeltas();
966 ExpectContains(*scroll_info
.get(),
972 TEST_F(LayerTreeHostImplTest
, ScrollWithSwapPromises
) {
973 ui::LatencyInfo latency_info
;
974 latency_info
.trace_id
= 1234;
975 scoped_ptr
<SwapPromise
> swap_promise(
976 new LatencyInfoSwapPromise(latency_info
));
978 SetupScrollAndContentsLayers(gfx::Size(100, 100));
979 EXPECT_EQ(InputHandler::ScrollStarted
,
980 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
981 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
982 host_impl_
->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise
.Pass());
983 host_impl_
->ScrollEnd();
985 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
986 EXPECT_EQ(1u, scroll_info
->swap_promises
.size());
987 EXPECT_EQ(latency_info
.trace_id
, scroll_info
->swap_promises
[0]->TraceId());
990 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
991 SetupScrollAndContentsLayers(gfx::Size(100, 100));
992 host_impl_
->SetViewportSize(gfx::Size(50, 50));
995 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
996 DCHECK(scroll_layer
);
998 float min_page_scale
= 1.f
;
999 float max_page_scale
= 4.f
;
1001 // Basic pinch zoom in gesture
1003 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1006 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1008 float page_scale_delta
= 2.f
;
1009 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1010 host_impl_
->PinchGestureBegin();
1011 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1012 host_impl_
->PinchGestureEnd();
1013 host_impl_
->ScrollEnd();
1014 EXPECT_FALSE(did_request_animate_
);
1015 EXPECT_TRUE(did_request_redraw_
);
1016 EXPECT_TRUE(did_request_commit_
);
1018 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1019 host_impl_
->ProcessScrollDeltas();
1020 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1025 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1028 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1029 float page_scale_delta
= 10.f
;
1031 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1032 host_impl_
->PinchGestureBegin();
1033 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1034 host_impl_
->PinchGestureEnd();
1035 host_impl_
->ScrollEnd();
1037 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1038 host_impl_
->ProcessScrollDeltas();
1039 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1042 // Zoom-out clamping
1044 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1047 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1048 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1050 float page_scale_delta
= 0.1f
;
1051 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1052 host_impl_
->PinchGestureBegin();
1053 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1054 host_impl_
->PinchGestureEnd();
1055 host_impl_
->ScrollEnd();
1057 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1058 host_impl_
->ProcessScrollDeltas();
1059 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1061 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1064 // Two-finger panning should not happen based on pinch events only
1066 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1069 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1070 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(20, 20));
1072 float page_scale_delta
= 1.f
;
1073 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1074 host_impl_
->PinchGestureBegin();
1075 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1076 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1077 host_impl_
->PinchGestureEnd();
1078 host_impl_
->ScrollEnd();
1080 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1081 host_impl_
->ProcessScrollDeltas();
1082 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1083 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1086 // Two-finger panning should work with interleaved scroll events
1088 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1091 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1092 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(20, 20));
1094 float page_scale_delta
= 1.f
;
1095 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1096 host_impl_
->PinchGestureBegin();
1097 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1098 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1099 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1100 host_impl_
->PinchGestureEnd();
1101 host_impl_
->ScrollEnd();
1103 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1104 host_impl_
->ProcessScrollDeltas();
1105 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1106 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1109 // Two-finger panning should work when starting fully zoomed out.
1111 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(0.5f
,
1114 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1115 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(0, 0));
1117 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1118 host_impl_
->PinchGestureBegin();
1119 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1120 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1121 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1122 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1123 host_impl_
->PinchGestureEnd();
1124 host_impl_
->ScrollEnd();
1126 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1127 host_impl_
->ProcessScrollDeltas();
1128 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1129 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1133 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1134 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1135 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1138 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1139 DCHECK(scroll_layer
);
1141 float min_page_scale
= 0.5f
;
1142 float max_page_scale
= 4.f
;
1143 base::TimeTicks start_time
= base::TimeTicks() +
1144 base::TimeDelta::FromSeconds(1);
1145 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1146 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1147 base::TimeTicks end_time
= start_time
+ duration
;
1149 // Non-anchor zoom-in
1151 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1154 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1156 did_request_redraw_
= false;
1157 did_request_animate_
= false;
1158 host_impl_
->active_tree()->SetPageScaleAnimation(
1163 host_impl_
->ActivateSyncTree();
1164 EXPECT_FALSE(did_request_redraw_
);
1165 EXPECT_TRUE(did_request_animate_
);
1167 did_request_redraw_
= false;
1168 did_request_animate_
= false;
1169 host_impl_
->Animate(start_time
);
1170 EXPECT_TRUE(did_request_redraw_
);
1171 EXPECT_TRUE(did_request_animate_
);
1173 did_request_redraw_
= false;
1174 did_request_animate_
= false;
1175 host_impl_
->Animate(halfway_through_animation
);
1176 EXPECT_TRUE(did_request_redraw_
);
1177 EXPECT_TRUE(did_request_animate_
);
1179 did_request_redraw_
= false;
1180 did_request_animate_
= false;
1181 did_request_commit_
= false;
1182 host_impl_
->Animate(end_time
);
1183 EXPECT_TRUE(did_request_commit_
);
1184 EXPECT_FALSE(did_request_animate_
);
1186 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1187 host_impl_
->ProcessScrollDeltas();
1188 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1189 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1194 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1197 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1199 did_request_redraw_
= false;
1200 did_request_animate_
= false;
1201 host_impl_
->active_tree()->SetPageScaleAnimation(
1202 gfx::Vector2d(25, 25), true, min_page_scale
, duration
);
1203 host_impl_
->ActivateSyncTree();
1204 EXPECT_FALSE(did_request_redraw_
);
1205 EXPECT_TRUE(did_request_animate_
);
1207 did_request_redraw_
= false;
1208 did_request_animate_
= false;
1209 host_impl_
->Animate(start_time
);
1210 EXPECT_TRUE(did_request_redraw_
);
1211 EXPECT_TRUE(did_request_animate_
);
1213 did_request_redraw_
= false;
1214 did_request_commit_
= false;
1215 did_request_animate_
= false;
1216 host_impl_
->Animate(end_time
);
1217 EXPECT_TRUE(did_request_redraw_
);
1218 EXPECT_FALSE(did_request_animate_
);
1219 EXPECT_TRUE(did_request_commit_
);
1221 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1222 host_impl_
->ProcessScrollDeltas();
1223 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1224 // Pushed to (0,0) via clamping against contents layer size.
1225 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1229 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1230 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1231 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1234 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1235 DCHECK(scroll_layer
);
1237 float min_page_scale
= 0.5f
;
1238 float max_page_scale
= 4.f
;
1239 base::TimeTicks start_time
= base::TimeTicks() +
1240 base::TimeDelta::FromSeconds(1);
1241 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1242 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1243 base::TimeTicks end_time
= start_time
+ duration
;
1245 // Anchor zoom with unchanged page scale should not change scroll or scale.
1247 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1250 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1252 host_impl_
->active_tree()->SetPageScaleAnimation(
1257 host_impl_
->ActivateSyncTree();
1258 host_impl_
->Animate(start_time
);
1259 host_impl_
->Animate(halfway_through_animation
);
1260 EXPECT_TRUE(did_request_redraw_
);
1261 host_impl_
->Animate(end_time
);
1262 EXPECT_TRUE(did_request_commit_
);
1264 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1265 host_impl_
->ProcessScrollDeltas();
1266 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1267 ExpectNone(*scroll_info
, scroll_layer
->id());
1271 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationTransferedOnSyncTreeActivate
) {
1272 host_impl_
->CreatePendingTree();
1273 CreateScrollAndContentsLayers(
1274 host_impl_
->pending_tree(),
1275 gfx::Size(100, 100));
1276 host_impl_
->ActivateSyncTree();
1279 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1280 DCHECK(scroll_layer
);
1282 float min_page_scale
= 0.5f
;
1283 float max_page_scale
= 4.f
;
1284 host_impl_
->sync_tree()->SetPageScaleFactorAndLimits(1.f
,
1287 host_impl_
->ActivateSyncTree();
1289 base::TimeTicks start_time
= base::TimeTicks() +
1290 base::TimeDelta::FromSeconds(1);
1291 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1292 base::TimeTicks third_through_animation
= start_time
+ duration
/ 3;
1293 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1294 base::TimeTicks end_time
= start_time
+ duration
;
1295 float target_scale
= 2.f
;
1297 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1299 // Make sure TakePageScaleAnimation works properly.
1300 host_impl_
->sync_tree()->SetPageScaleAnimation(
1305 scoped_ptr
<PageScaleAnimation
> psa
=
1306 host_impl_
->sync_tree()->TakePageScaleAnimation();
1307 EXPECT_EQ(target_scale
, psa
->target_page_scale_factor());
1308 EXPECT_EQ(duration
, psa
->duration());
1309 EXPECT_EQ(nullptr, host_impl_
->sync_tree()->TakePageScaleAnimation());
1311 // Recreate the PSA. Nothing should happen here since the tree containing the
1312 // PSA hasn't been activated yet.
1313 did_request_redraw_
= false;
1314 did_request_animate_
= false;
1315 host_impl_
->sync_tree()->SetPageScaleAnimation(
1320 host_impl_
->Animate(halfway_through_animation
);
1321 EXPECT_FALSE(did_request_animate_
);
1322 EXPECT_FALSE(did_request_redraw_
);
1324 // Activate the sync tree. This should cause the animation to become enabled.
1325 // It should also clear the pointer on the sync tree.
1326 host_impl_
->ActivateSyncTree();
1327 EXPECT_EQ(nullptr, host_impl_
->sync_tree()->TakePageScaleAnimation().get());
1328 EXPECT_FALSE(did_request_redraw_
);
1329 EXPECT_TRUE(did_request_animate_
);
1331 // From here on, make sure the animation runs as normal.
1332 did_request_redraw_
= false;
1333 did_request_animate_
= false;
1334 host_impl_
->Animate(start_time
);
1335 EXPECT_TRUE(did_request_redraw_
);
1336 EXPECT_TRUE(did_request_animate_
);
1338 did_request_redraw_
= false;
1339 did_request_animate_
= false;
1340 host_impl_
->Animate(third_through_animation
);
1341 EXPECT_TRUE(did_request_redraw_
);
1342 EXPECT_TRUE(did_request_animate_
);
1344 // Another activation shouldn't have any effect on the animation.
1345 host_impl_
->ActivateSyncTree();
1347 did_request_redraw_
= false;
1348 did_request_animate_
= false;
1349 host_impl_
->Animate(halfway_through_animation
);
1350 EXPECT_TRUE(did_request_redraw_
);
1351 EXPECT_TRUE(did_request_animate_
);
1353 did_request_redraw_
= false;
1354 did_request_animate_
= false;
1355 did_request_commit_
= false;
1356 host_impl_
->Animate(end_time
);
1357 EXPECT_TRUE(did_request_commit_
);
1358 EXPECT_FALSE(did_request_animate_
);
1360 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1361 host_impl_
->ProcessScrollDeltas();
1362 EXPECT_EQ(scroll_info
->page_scale_delta
, target_scale
);
1363 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1366 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1368 LayerTreeHostImplOverridePhysicalTime(
1369 const LayerTreeSettings
& settings
,
1370 LayerTreeHostImplClient
* client
,
1372 SharedBitmapManager
* manager
,
1373 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1374 : LayerTreeHostImpl(settings
,
1377 rendering_stats_instrumentation
,
1382 BeginFrameArgs
CurrentBeginFrameArgs() const override
{
1383 return CreateBeginFrameArgsForTesting(fake_current_physical_time_
);
1386 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1387 fake_current_physical_time_
= fake_now
;
1391 base::TimeTicks fake_current_physical_time_
;
1394 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1395 gfx::Size viewport_size(10, 10); \
1396 gfx::Size content_size(100, 100); \
1398 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1399 new LayerTreeHostImplOverridePhysicalTime(settings, \
1402 shared_bitmap_manager_.get(), \
1403 &stats_instrumentation_); \
1404 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1405 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1406 host_impl_->SetViewportSize(viewport_size); \
1408 scoped_ptr<LayerImpl> root = \
1409 LayerImpl::Create(host_impl_->active_tree(), 1); \
1410 root->SetBounds(viewport_size); \
1412 scoped_ptr<LayerImpl> scroll = \
1413 LayerImpl::Create(host_impl_->active_tree(), 2); \
1414 scroll->SetScrollClipLayer(root->id()); \
1415 scroll->SetScrollOffset(gfx::ScrollOffset()); \
1416 root->SetBounds(viewport_size); \
1417 scroll->SetBounds(content_size); \
1418 scroll->SetContentBounds(content_size); \
1419 scroll->SetIsContainerForFixedPositionLayers(true); \
1421 scoped_ptr<LayerImpl> contents = \
1422 LayerImpl::Create(host_impl_->active_tree(), 3); \
1423 contents->SetDrawsContent(true); \
1424 contents->SetBounds(content_size); \
1425 contents->SetContentBounds(content_size); \
1427 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1428 SolidColorScrollbarLayerImpl::Create( \
1429 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \
1430 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1432 scroll->AddChild(contents.Pass()); \
1433 root->AddChild(scroll.Pass()); \
1434 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \
1435 root->AddChild(scrollbar.Pass()); \
1437 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1438 host_impl_->active_tree()->SetViewportLayersFromIds( \
1439 1, 2, Layer::INVALID_ID); \
1440 host_impl_->active_tree()->DidBecomeActive(); \
1443 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1444 LayerTreeSettings settings
;
1445 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1446 settings
.scrollbar_fade_delay_ms
= 20;
1447 settings
.scrollbar_fade_duration_ms
= 20;
1449 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1451 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1453 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1454 EXPECT_FALSE(did_request_redraw_
);
1456 // If no scroll happened during a scroll gesture, it should have no effect.
1457 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1458 host_impl_
->ScrollEnd();
1459 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1460 EXPECT_FALSE(did_request_redraw_
);
1461 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1463 // After a scroll, a fade animation should be scheduled about 20ms from now.
1464 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1465 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5));
1466 host_impl_
->ScrollEnd();
1467 did_request_redraw_
= false;
1468 did_request_animate_
= false;
1469 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1470 requested_scrollbar_animation_delay_
);
1471 EXPECT_FALSE(did_request_redraw_
);
1472 EXPECT_FALSE(did_request_animate_
);
1473 requested_scrollbar_animation_delay_
= base::TimeDelta();
1474 scrollbar_fade_start_
.Run();
1475 host_impl_
->Animate(fake_now
);
1477 // After the fade begins, we should start getting redraws instead of a
1478 // scheduled animation.
1479 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1480 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1481 EXPECT_TRUE(did_request_animate_
);
1482 did_request_animate_
= false;
1484 // Setting the scroll offset outside a scroll should also cause the scrollbar
1485 // to appear and to schedule a fade.
1486 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(
1487 gfx::ScrollOffset(5, 5));
1488 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1489 requested_scrollbar_animation_delay_
);
1490 EXPECT_FALSE(did_request_redraw_
);
1491 EXPECT_FALSE(did_request_animate_
);
1492 requested_scrollbar_animation_delay_
= base::TimeDelta();
1494 // Unnecessarily Fade animation of solid color scrollbar is not triggered.
1495 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1496 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1497 host_impl_
->ScrollEnd();
1498 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1501 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1502 LayerTreeSettings settings
;
1503 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1504 settings
.scrollbar_fade_delay_ms
= 20;
1505 settings
.scrollbar_fade_duration_ms
= 20;
1506 settings
.use_pinch_zoom_scrollbars
= true;
1508 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1510 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1512 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, 4.f
);
1514 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1515 EXPECT_FALSE(did_request_animate_
);
1517 // If no scroll happened during a scroll gesture, it should have no effect.
1518 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1519 host_impl_
->ScrollEnd();
1520 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1521 EXPECT_FALSE(did_request_animate_
);
1522 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1524 // After a scroll, no fade animation should be scheduled.
1525 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1526 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1527 host_impl_
->ScrollEnd();
1528 did_request_redraw_
= false;
1529 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1530 EXPECT_FALSE(did_request_animate_
);
1531 requested_scrollbar_animation_delay_
= base::TimeDelta();
1533 // We should not see any draw requests.
1534 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1535 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1536 EXPECT_FALSE(did_request_animate_
);
1538 // Make page scale > min so that subsequent scrolls will trigger fades.
1539 host_impl_
->active_tree()->SetPageScaleDelta(1.1f
);
1541 // After a scroll, a fade animation should be scheduled about 20ms from now.
1542 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1543 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1544 host_impl_
->ScrollEnd();
1545 did_request_redraw_
= false;
1546 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1547 requested_scrollbar_animation_delay_
);
1548 EXPECT_FALSE(did_request_animate_
);
1549 requested_scrollbar_animation_delay_
= base::TimeDelta();
1550 scrollbar_fade_start_
.Run();
1552 // After the fade begins, we should start getting redraws instead of a
1553 // scheduled animation.
1554 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1555 host_impl_
->Animate(fake_now
);
1556 EXPECT_TRUE(did_request_animate_
);
1559 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1560 float device_scale_factor
) {
1561 LayerTreeSettings settings
;
1562 settings
.scrollbar_fade_delay_ms
= 500;
1563 settings
.scrollbar_fade_duration_ms
= 300;
1564 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1566 gfx::Size
viewport_size(300, 200);
1567 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1568 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1569 gfx::Size
content_size(1000, 1000);
1571 CreateHostImpl(settings
, CreateOutputSurface());
1572 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1573 host_impl_
->SetViewportSize(device_viewport_size
);
1575 scoped_ptr
<LayerImpl
> root
=
1576 LayerImpl::Create(host_impl_
->active_tree(), 1);
1577 root
->SetBounds(viewport_size
);
1579 scoped_ptr
<LayerImpl
> scroll
=
1580 LayerImpl::Create(host_impl_
->active_tree(), 2);
1581 scroll
->SetScrollClipLayer(root
->id());
1582 scroll
->SetScrollOffset(gfx::ScrollOffset());
1583 scroll
->SetBounds(content_size
);
1584 scroll
->SetContentBounds(content_size
);
1585 scroll
->SetIsContainerForFixedPositionLayers(true);
1587 scoped_ptr
<LayerImpl
> contents
=
1588 LayerImpl::Create(host_impl_
->active_tree(), 3);
1589 contents
->SetDrawsContent(true);
1590 contents
->SetBounds(content_size
);
1591 contents
->SetContentBounds(content_size
);
1593 // The scrollbar is on the right side.
1594 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1595 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1596 scrollbar
->SetDrawsContent(true);
1597 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1598 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1599 scrollbar
->SetPosition(gfx::Point(285, 0));
1601 scroll
->AddChild(contents
.Pass());
1602 root
->AddChild(scroll
.Pass());
1603 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1604 root
->AddChild(scrollbar
.Pass());
1606 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1607 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
1608 host_impl_
->active_tree()->DidBecomeActive();
1611 LayerImpl
* root_scroll
=
1612 host_impl_
->active_tree()->InnerViewportScrollLayer();
1613 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1614 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1615 static_cast<ScrollbarAnimationControllerThinning
*>(
1616 root_scroll
->scrollbar_animation_controller());
1617 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1619 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1620 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1622 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1623 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1625 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1626 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1628 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1629 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1630 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1632 did_request_redraw_
= false;
1633 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1634 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1635 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1636 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1637 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1638 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1639 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1642 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1643 SetupMouseMoveAtWithDeviceScale(1.f
);
1646 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1647 SetupMouseMoveAtWithDeviceScale(2.f
);
1650 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1651 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1652 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1653 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
1656 CompositorFrameMetadata metadata
=
1657 host_impl_
->MakeCompositorFrameMetadata();
1658 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1659 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1660 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.scrollable_viewport_size
);
1661 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1662 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1663 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1666 // Scrolling should update metadata immediately.
1667 EXPECT_EQ(InputHandler::ScrollStarted
,
1668 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1669 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1671 CompositorFrameMetadata metadata
=
1672 host_impl_
->MakeCompositorFrameMetadata();
1673 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1675 host_impl_
->ScrollEnd();
1677 CompositorFrameMetadata metadata
=
1678 host_impl_
->MakeCompositorFrameMetadata();
1679 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1682 // Page scale should update metadata correctly (shrinking only the viewport).
1683 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1684 host_impl_
->PinchGestureBegin();
1685 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1686 host_impl_
->PinchGestureEnd();
1687 host_impl_
->ScrollEnd();
1689 CompositorFrameMetadata metadata
=
1690 host_impl_
->MakeCompositorFrameMetadata();
1691 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1692 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1693 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.scrollable_viewport_size
);
1694 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1695 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1696 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1699 // Likewise if set from the main thread.
1700 host_impl_
->ProcessScrollDeltas();
1701 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(4.f
, 0.5f
, 4.f
);
1702 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
1704 CompositorFrameMetadata metadata
=
1705 host_impl_
->MakeCompositorFrameMetadata();
1706 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1707 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1708 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.scrollable_viewport_size
);
1709 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1710 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1711 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1715 class DidDrawCheckLayer
: public LayerImpl
{
1717 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1718 return make_scoped_ptr(new DidDrawCheckLayer(tree_impl
, id
));
1721 bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
) override
{
1722 will_draw_called_
= true;
1723 if (will_draw_returns_false_
)
1725 return LayerImpl::WillDraw(draw_mode
, provider
);
1728 void AppendQuads(RenderPass
* render_pass
,
1729 const Occlusion
& occlusion_in_content_space
,
1730 AppendQuadsData
* append_quads_data
) override
{
1731 append_quads_called_
= true;
1732 LayerImpl::AppendQuads(
1733 render_pass
, occlusion_in_content_space
, append_quads_data
);
1736 void DidDraw(ResourceProvider
* provider
) override
{
1737 did_draw_called_
= true;
1738 LayerImpl::DidDraw(provider
);
1741 bool will_draw_called() const { return will_draw_called_
; }
1742 bool append_quads_called() const { return append_quads_called_
; }
1743 bool did_draw_called() const { return did_draw_called_
; }
1745 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1747 void ClearDidDrawCheck() {
1748 will_draw_called_
= false;
1749 append_quads_called_
= false;
1750 did_draw_called_
= false;
1754 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1755 : LayerImpl(tree_impl
, id
),
1756 will_draw_returns_false_(false),
1757 will_draw_called_(false),
1758 append_quads_called_(false),
1759 did_draw_called_(false) {
1760 SetBounds(gfx::Size(10, 10));
1761 SetContentBounds(gfx::Size(10, 10));
1762 SetDrawsContent(true);
1763 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1767 bool will_draw_returns_false_
;
1768 bool will_draw_called_
;
1769 bool append_quads_called_
;
1770 bool did_draw_called_
;
1773 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1774 // The root layer is always drawn, so run this test on a child layer that
1775 // will be masked out by the root layer's bounds.
1776 host_impl_
->active_tree()->SetRootLayer(
1777 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1778 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1779 host_impl_
->active_tree()->root_layer());
1781 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1782 DidDrawCheckLayer
* layer
=
1783 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1786 LayerTreeHostImpl::FrameData frame
;
1787 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1788 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1789 host_impl_
->DidDrawAllLayers(frame
);
1791 EXPECT_TRUE(layer
->will_draw_called());
1792 EXPECT_TRUE(layer
->append_quads_called());
1793 EXPECT_TRUE(layer
->did_draw_called());
1796 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1799 LayerTreeHostImpl::FrameData frame
;
1801 layer
->set_will_draw_returns_false();
1802 layer
->ClearDidDrawCheck();
1804 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1805 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1806 host_impl_
->DidDrawAllLayers(frame
);
1808 EXPECT_TRUE(layer
->will_draw_called());
1809 EXPECT_FALSE(layer
->append_quads_called());
1810 EXPECT_FALSE(layer
->did_draw_called());
1814 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1815 // The root layer is always drawn, so run this test on a child layer that
1816 // will be masked out by the root layer's bounds.
1817 host_impl_
->active_tree()->SetRootLayer(
1818 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1819 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1820 host_impl_
->active_tree()->root_layer());
1821 root
->SetMasksToBounds(true);
1823 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1824 DidDrawCheckLayer
* layer
=
1825 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1826 // Ensure visible_content_rect for layer is empty.
1827 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1828 layer
->SetBounds(gfx::Size(10, 10));
1829 layer
->SetContentBounds(gfx::Size(10, 10));
1831 LayerTreeHostImpl::FrameData frame
;
1833 EXPECT_FALSE(layer
->will_draw_called());
1834 EXPECT_FALSE(layer
->did_draw_called());
1836 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1837 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1838 host_impl_
->DidDrawAllLayers(frame
);
1840 EXPECT_FALSE(layer
->will_draw_called());
1841 EXPECT_FALSE(layer
->did_draw_called());
1843 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1845 // Ensure visible_content_rect for layer is not empty
1846 layer
->SetPosition(gfx::PointF());
1848 EXPECT_FALSE(layer
->will_draw_called());
1849 EXPECT_FALSE(layer
->did_draw_called());
1851 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1852 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1853 host_impl_
->DidDrawAllLayers(frame
);
1855 EXPECT_TRUE(layer
->will_draw_called());
1856 EXPECT_TRUE(layer
->did_draw_called());
1858 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1861 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1862 gfx::Size
big_size(1000, 1000);
1863 host_impl_
->SetViewportSize(big_size
);
1865 host_impl_
->active_tree()->SetRootLayer(
1866 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1867 DidDrawCheckLayer
* root
=
1868 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1870 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1871 DidDrawCheckLayer
* occluded_layer
=
1872 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1874 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1875 DidDrawCheckLayer
* top_layer
=
1876 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1877 // This layer covers the occluded_layer above. Make this layer large so it can
1879 top_layer
->SetBounds(big_size
);
1880 top_layer
->SetContentBounds(big_size
);
1881 top_layer
->SetContentsOpaque(true);
1883 LayerTreeHostImpl::FrameData frame
;
1885 EXPECT_FALSE(occluded_layer
->will_draw_called());
1886 EXPECT_FALSE(occluded_layer
->did_draw_called());
1887 EXPECT_FALSE(top_layer
->will_draw_called());
1888 EXPECT_FALSE(top_layer
->did_draw_called());
1890 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1891 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1892 host_impl_
->DidDrawAllLayers(frame
);
1894 EXPECT_FALSE(occluded_layer
->will_draw_called());
1895 EXPECT_FALSE(occluded_layer
->did_draw_called());
1896 EXPECT_TRUE(top_layer
->will_draw_called());
1897 EXPECT_TRUE(top_layer
->did_draw_called());
1900 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1901 host_impl_
->active_tree()->SetRootLayer(
1902 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1903 DidDrawCheckLayer
* root
=
1904 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1906 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1907 DidDrawCheckLayer
* layer1
=
1908 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1910 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1911 DidDrawCheckLayer
* layer2
=
1912 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1914 layer1
->SetOpacity(0.3f
);
1915 layer1
->SetShouldFlattenTransform(true);
1917 EXPECT_FALSE(root
->did_draw_called());
1918 EXPECT_FALSE(layer1
->did_draw_called());
1919 EXPECT_FALSE(layer2
->did_draw_called());
1921 LayerTreeHostImpl::FrameData frame
;
1922 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
1923 host_impl_
->active_tree()->root_layer());
1924 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1925 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1926 host_impl_
->DidDrawAllLayers(frame
);
1928 EXPECT_TRUE(root
->did_draw_called());
1929 EXPECT_TRUE(layer1
->did_draw_called());
1930 EXPECT_TRUE(layer2
->did_draw_called());
1932 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1933 EXPECT_TRUE(!!layer1
->render_surface());
1936 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1938 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1941 bool had_incomplete_tile
,
1943 ResourceProvider
* resource_provider
) {
1944 return make_scoped_ptr(new MissingTextureAnimatingLayer(tree_impl
,
1947 had_incomplete_tile
,
1949 resource_provider
));
1952 void AppendQuads(RenderPass
* render_pass
,
1953 const Occlusion
& occlusion_in_content_space
,
1954 AppendQuadsData
* append_quads_data
) override
{
1955 LayerImpl::AppendQuads(
1956 render_pass
, occlusion_in_content_space
, append_quads_data
);
1957 if (had_incomplete_tile_
)
1958 append_quads_data
->num_incomplete_tiles
++;
1960 append_quads_data
->num_missing_tiles
++;
1964 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1967 bool had_incomplete_tile
,
1969 ResourceProvider
* resource_provider
)
1970 : DidDrawCheckLayer(tree_impl
, id
),
1971 tile_missing_(tile_missing
),
1972 had_incomplete_tile_(had_incomplete_tile
) {
1974 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1978 bool had_incomplete_tile_
;
1981 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsOnDefault
) {
1982 host_impl_
->active_tree()->SetRootLayer(
1983 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1984 DidDrawCheckLayer
* root
=
1985 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1987 bool tile_missing
= false;
1988 bool had_incomplete_tile
= false;
1989 bool is_animating
= false;
1991 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1994 had_incomplete_tile
,
1996 host_impl_
->resource_provider()));
1998 LayerTreeHostImpl::FrameData frame
;
2000 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2001 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2002 host_impl_
->DidDrawAllLayers(frame
);
2005 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
2006 host_impl_
->active_tree()->SetRootLayer(
2007 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2008 DidDrawCheckLayer
* root
=
2009 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2010 bool tile_missing
= false;
2011 bool had_incomplete_tile
= false;
2012 bool is_animating
= true;
2014 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2017 had_incomplete_tile
,
2019 host_impl_
->resource_provider()));
2021 LayerTreeHostImpl::FrameData frame
;
2023 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2024 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2025 host_impl_
->DidDrawAllLayers(frame
);
2028 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithMissingTiles
) {
2029 host_impl_
->active_tree()->SetRootLayer(
2030 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2031 DidDrawCheckLayer
* root
=
2032 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2034 LayerTreeHostImpl::FrameData frame
;
2035 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2036 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2037 host_impl_
->DidDrawAllLayers(frame
);
2038 host_impl_
->SwapBuffers(frame
);
2040 bool tile_missing
= true;
2041 bool had_incomplete_tile
= false;
2042 bool is_animating
= false;
2044 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2047 had_incomplete_tile
,
2049 host_impl_
->resource_provider()));
2050 LayerTreeHostImpl::FrameData frame2
;
2051 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2052 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2053 host_impl_
->DidDrawAllLayers(frame2
);
2056 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithIncompleteTile
) {
2057 host_impl_
->active_tree()->SetRootLayer(
2058 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2059 DidDrawCheckLayer
* root
=
2060 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2062 LayerTreeHostImpl::FrameData frame
;
2063 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2064 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2065 host_impl_
->DidDrawAllLayers(frame
);
2066 host_impl_
->SwapBuffers(frame
);
2068 bool tile_missing
= false;
2069 bool had_incomplete_tile
= true;
2070 bool is_animating
= false;
2072 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2075 had_incomplete_tile
,
2077 host_impl_
->resource_provider()));
2078 LayerTreeHostImpl::FrameData frame2
;
2079 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2080 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2081 host_impl_
->DidDrawAllLayers(frame2
);
2084 TEST_F(LayerTreeHostImplTest
,
2085 PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard
) {
2086 host_impl_
->active_tree()->SetRootLayer(
2087 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2088 DidDrawCheckLayer
* root
=
2089 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2091 LayerTreeHostImpl::FrameData frame
;
2092 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2093 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2094 host_impl_
->DidDrawAllLayers(frame
);
2095 host_impl_
->SwapBuffers(frame
);
2097 bool tile_missing
= true;
2098 bool had_incomplete_tile
= false;
2099 bool is_animating
= true;
2101 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2104 had_incomplete_tile
,
2106 host_impl_
->resource_provider()));
2107 LayerTreeHostImpl::FrameData frame2
;
2108 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2109 host_impl_
->PrepareToDraw(&frame2
));
2110 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2111 host_impl_
->DidDrawAllLayers(frame2
);
2114 TEST_F(LayerTreeHostImplTest
,
2115 PrepareToDrawSucceedsWithAnimationAndIncompleteTiles
) {
2116 host_impl_
->active_tree()->SetRootLayer(
2117 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2118 DidDrawCheckLayer
* root
=
2119 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2121 LayerTreeHostImpl::FrameData frame
;
2122 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2123 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2124 host_impl_
->DidDrawAllLayers(frame
);
2125 host_impl_
->SwapBuffers(frame
);
2127 bool tile_missing
= false;
2128 bool had_incomplete_tile
= true;
2129 bool is_animating
= true;
2131 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2134 had_incomplete_tile
,
2136 host_impl_
->resource_provider()));
2137 LayerTreeHostImpl::FrameData frame2
;
2138 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2139 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2140 host_impl_
->DidDrawAllLayers(frame2
);
2143 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenHighResRequired
) {
2144 host_impl_
->active_tree()->SetRootLayer(
2145 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2146 DidDrawCheckLayer
* root
=
2147 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2149 LayerTreeHostImpl::FrameData frame
;
2150 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2151 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2152 host_impl_
->DidDrawAllLayers(frame
);
2153 host_impl_
->SwapBuffers(frame
);
2155 bool tile_missing
= false;
2156 bool had_incomplete_tile
= false;
2157 bool is_animating
= false;
2159 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2162 had_incomplete_tile
,
2164 host_impl_
->resource_provider()));
2165 host_impl_
->SetRequiresHighResToDraw();
2166 LayerTreeHostImpl::FrameData frame2
;
2167 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2168 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2169 host_impl_
->DidDrawAllLayers(frame2
);
2172 TEST_F(LayerTreeHostImplTest
,
2173 PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles
) {
2174 host_impl_
->active_tree()->SetRootLayer(
2175 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2176 DidDrawCheckLayer
* root
=
2177 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2179 LayerTreeHostImpl::FrameData frame
;
2180 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2181 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2182 host_impl_
->DidDrawAllLayers(frame
);
2183 host_impl_
->SwapBuffers(frame
);
2185 bool tile_missing
= false;
2186 bool had_incomplete_tile
= true;
2187 bool is_animating
= false;
2189 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2192 had_incomplete_tile
,
2194 host_impl_
->resource_provider()));
2195 host_impl_
->SetRequiresHighResToDraw();
2196 LayerTreeHostImpl::FrameData frame2
;
2197 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2198 host_impl_
->PrepareToDraw(&frame2
));
2199 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2200 host_impl_
->DidDrawAllLayers(frame2
);
2203 TEST_F(LayerTreeHostImplTest
,
2204 PrepareToDrawFailsWhenHighResRequiredAndMissingTile
) {
2205 host_impl_
->active_tree()->SetRootLayer(
2206 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2207 DidDrawCheckLayer
* root
=
2208 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2210 LayerTreeHostImpl::FrameData frame
;
2211 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2212 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2213 host_impl_
->DidDrawAllLayers(frame
);
2214 host_impl_
->SwapBuffers(frame
);
2216 bool tile_missing
= true;
2217 bool had_incomplete_tile
= false;
2218 bool is_animating
= false;
2220 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2223 had_incomplete_tile
,
2225 host_impl_
->resource_provider()));
2226 host_impl_
->SetRequiresHighResToDraw();
2227 LayerTreeHostImpl::FrameData frame2
;
2228 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2229 host_impl_
->PrepareToDraw(&frame2
));
2230 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2231 host_impl_
->DidDrawAllLayers(frame2
);
2234 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2235 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2236 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2237 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2240 // Scroll event is ignored because layer is not scrollable.
2241 EXPECT_EQ(InputHandler::ScrollIgnored
,
2242 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2243 EXPECT_FALSE(did_request_redraw_
);
2244 EXPECT_FALSE(did_request_commit_
);
2247 // TODO(bokan): Convert these tests to create inner and outer viewports.
2248 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2250 LayerTreeHostImplTopControlsTest()
2251 // Make the clip size the same as the layer (content) size so the layer is
2253 : layer_size_(10, 10),
2254 clip_size_(layer_size_
) {
2255 settings_
.calculate_top_controls_position
= true;
2256 settings_
.top_controls_height
= 50;
2257 settings_
.use_pinch_virtual_viewport
= true;
2260 gfx::Size(clip_size_
.width(),
2261 clip_size_
.height() + settings_
.top_controls_height
);
2264 void SetupTopControlsAndScrollLayer() {
2265 scoped_ptr
<LayerImpl
> root
=
2266 LayerImpl::Create(host_impl_
->active_tree(), 1);
2267 scoped_ptr
<LayerImpl
> root_clip
=
2268 LayerImpl::Create(host_impl_
->active_tree(), 2);
2269 root_clip
->SetBounds(clip_size_
);
2270 root
->SetScrollClipLayer(root_clip
->id());
2271 root
->SetBounds(layer_size_
);
2272 root
->SetContentBounds(layer_size_
);
2273 root
->SetPosition(gfx::PointF());
2274 root
->SetDrawsContent(false);
2275 root
->SetIsContainerForFixedPositionLayers(true);
2276 int inner_viewport_scroll_layer_id
= root
->id();
2277 int page_scale_layer_id
= root_clip
->id();
2278 root_clip
->AddChild(root
.Pass());
2279 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2280 host_impl_
->active_tree()->SetViewportLayersFromIds(
2281 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2282 // Set a viewport size that is large enough to contain both the top controls
2283 // and some content.
2284 host_impl_
->SetViewportSize(viewport_size_
);
2285 host_impl_
->SetTopControlsLayoutHeight(
2286 settings_
.top_controls_height
);
2288 host_impl_
->CreatePendingTree();
2290 LayerImpl::Create(host_impl_
->sync_tree(), 1);
2292 LayerImpl::Create(host_impl_
->sync_tree(), 2);
2293 root_clip
->SetBounds(clip_size_
);
2294 root
->SetScrollClipLayer(root_clip
->id());
2295 root
->SetBounds(layer_size_
);
2296 root
->SetContentBounds(layer_size_
);
2297 root
->SetPosition(gfx::PointF());
2298 root
->SetDrawsContent(false);
2299 root
->SetIsContainerForFixedPositionLayers(true);
2300 inner_viewport_scroll_layer_id
= root
->id();
2301 page_scale_layer_id
= root_clip
->id();
2302 root_clip
->AddChild(root
.Pass());
2303 host_impl_
->sync_tree()->SetRootLayer(root_clip
.Pass());
2304 host_impl_
->sync_tree()->SetViewportLayersFromIds(
2305 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2306 // Set a viewport size that is large enough to contain both the top controls
2307 // and some content.
2308 host_impl_
->SetViewportSize(viewport_size_
);
2309 host_impl_
->sync_tree()->set_top_controls_layout_height(
2310 settings_
.top_controls_height
);
2313 void SetupTopControlsAndScrollLayerWithVirtualViewport(
2314 const gfx::Size
& inner_viewport_size
,
2315 const gfx::Size
& outer_viewport_size
,
2316 const gfx::Size
& scroll_layer_size
) {
2317 CreateHostImpl(settings_
, CreateOutputSurface());
2319 scoped_ptr
<LayerImpl
> root
=
2320 LayerImpl::Create(host_impl_
->active_tree(), 1);
2321 scoped_ptr
<LayerImpl
> root_clip
=
2322 LayerImpl::Create(host_impl_
->active_tree(), 2);
2323 scoped_ptr
<LayerImpl
> page_scale
=
2324 LayerImpl::Create(host_impl_
->active_tree(), 3);
2326 scoped_ptr
<LayerImpl
> outer_scroll
=
2327 LayerImpl::Create(host_impl_
->active_tree(), 4);
2328 scoped_ptr
<LayerImpl
> outer_clip
=
2329 LayerImpl::Create(host_impl_
->active_tree(), 5);
2331 root_clip
->SetBounds(inner_viewport_size
);
2332 root
->SetScrollClipLayer(root_clip
->id());
2333 root
->SetBounds(outer_viewport_size
);
2334 root
->SetContentBounds(outer_viewport_size
);
2335 root
->SetPosition(gfx::PointF());
2336 root
->SetDrawsContent(false);
2337 root
->SetIsContainerForFixedPositionLayers(true);
2339 outer_clip
->SetBounds(outer_viewport_size
);
2340 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
2341 outer_scroll
->SetBounds(scroll_layer_size
);
2342 outer_scroll
->SetContentBounds(scroll_layer_size
);
2343 outer_scroll
->SetPosition(gfx::PointF());
2344 outer_scroll
->SetDrawsContent(false);
2345 outer_scroll
->SetIsContainerForFixedPositionLayers(true);
2347 int inner_viewport_scroll_layer_id
= root
->id();
2348 int outer_viewport_scroll_layer_id
= outer_scroll
->id();
2349 int page_scale_layer_id
= page_scale
->id();
2351 outer_clip
->AddChild(outer_scroll
.Pass());
2352 root
->AddChild(outer_clip
.Pass());
2353 page_scale
->AddChild(root
.Pass());
2354 root_clip
->AddChild(page_scale
.Pass());
2356 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2357 host_impl_
->active_tree()->SetViewportLayersFromIds(
2358 page_scale_layer_id
,
2359 inner_viewport_scroll_layer_id
,
2360 outer_viewport_scroll_layer_id
);
2362 host_impl_
->SetViewportSize(inner_viewport_size
);
2363 host_impl_
->SetTopControlsLayoutHeight(
2364 settings_
.top_controls_height
);
2365 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2366 EXPECT_EQ(inner_viewport_size
, root_clip_ptr
->bounds());
2370 gfx::Size layer_size_
;
2371 gfx::Size clip_size_
;
2372 gfx::Size viewport_size_
;
2374 LayerTreeSettings settings_
;
2375 }; // class LayerTreeHostImplTopControlsTest
2377 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2378 SetupTopControlsAndScrollLayerWithVirtualViewport(
2379 gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
2382 EXPECT_EQ(InputHandler::ScrollStarted
,
2383 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2385 // Make the test scroll delta a fractional amount, to verify that the
2386 // fixed container size delta is (1) non-zero, and (2) fractional, and
2387 // (3) matches the movement of the top controls.
2388 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2389 host_impl_
->top_controls_manager()->ScrollBegin();
2390 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2391 host_impl_
->top_controls_manager()->ScrollEnd();
2393 LayerImpl
* inner_viewport_scroll_layer
=
2394 host_impl_
->active_tree()->InnerViewportScrollLayer();
2395 DCHECK(inner_viewport_scroll_layer
);
2396 host_impl_
->ScrollEnd();
2397 EXPECT_EQ(top_controls_scroll_delta
,
2398 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2401 // Test that the fixed position container delta is appropriately adjusted
2402 // by the top controls showing/hiding and page scale doesn't affect it.
2403 TEST_F(LayerTreeHostImplTopControlsTest
, FixedContainerDelta
) {
2404 SetupTopControlsAndScrollLayerWithVirtualViewport(
2405 gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
2408 float page_scale
= 1.5f
;
2409 float top_controls_height
= settings_
.top_controls_height
;
2410 LayerImpl
* outer_viewport_scroll_layer
=
2411 host_impl_
->active_tree()->OuterViewportScrollLayer();
2413 // Zoom in, since the fixed container is the outer viewport, the delta should
2415 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
, 1.f
, 2.f
);
2417 EXPECT_EQ(InputHandler::ScrollStarted
,
2418 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2420 // Scroll down, the top controls hiding should expand the viewport size so
2421 // the delta should be equal to the scroll distance.
2422 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 20.f
);
2423 host_impl_
->top_controls_manager()->ScrollBegin();
2424 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2425 EXPECT_EQ(top_controls_height
- top_controls_scroll_delta
.y(),
2426 host_impl_
->top_controls_manager()->ContentTopOffset());
2427 EXPECT_VECTOR_EQ(top_controls_scroll_delta
,
2428 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2429 host_impl_
->ScrollEnd();
2431 // Scroll past the maximum extent. The delta shouldn't be greater than the
2432 // top controls height.
2433 host_impl_
->top_controls_manager()->ScrollBegin();
2434 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2435 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2436 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2437 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2438 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height
),
2439 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2440 host_impl_
->ScrollEnd();
2442 // Scroll in the direction to make the top controls show.
2443 host_impl_
->top_controls_manager()->ScrollBegin();
2444 host_impl_
->top_controls_manager()->ScrollBy(-top_controls_scroll_delta
);
2445 EXPECT_EQ(top_controls_scroll_delta
.y(),
2446 host_impl_
->top_controls_manager()->ContentTopOffset());
2448 gfx::Vector2dF(0, top_controls_height
- top_controls_scroll_delta
.y()),
2449 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2450 host_impl_
->top_controls_manager()->ScrollEnd();
2453 // Ensure setting the top controls position explicitly using the setters on the
2454 // TreeImpl correctly affects the top controls manager and viewport bounds.
2455 TEST_F(LayerTreeHostImplTopControlsTest
, PositionTopControlsExplicitly
) {
2456 CreateHostImpl(settings_
, CreateOutputSurface());
2457 SetupTopControlsAndScrollLayer();
2460 host_impl_
->active_tree()->set_top_controls_delta(0.f
);
2461 host_impl_
->active_tree()->set_top_controls_content_offset(30.f
);
2462 EXPECT_EQ(30.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2463 EXPECT_EQ(-20.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
2465 host_impl_
->active_tree()->set_top_controls_delta(-30.f
);
2466 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2467 EXPECT_EQ(-50.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
2469 host_impl_
->DidChangeTopControlsPosition();
2471 // Now that top controls have moved, expect the clip to resize.
2472 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2473 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2476 // Test that the top_controls delta and sent delta are appropriately
2477 // applied on sync tree activation. The total top controls offset shouldn't
2478 // change after the activation.
2479 TEST_F(LayerTreeHostImplTopControlsTest
, ApplyDeltaOnTreeActivation
) {
2480 CreateHostImpl(settings_
, CreateOutputSurface());
2481 SetupTopControlsAndScrollLayer();
2484 host_impl_
->sync_tree()->set_top_controls_content_offset(15.f
);
2486 host_impl_
->active_tree()->set_top_controls_content_offset(20.f
);
2487 host_impl_
->active_tree()->set_top_controls_delta(-20.f
);
2488 host_impl_
->active_tree()->set_sent_top_controls_delta(-5.f
);
2490 host_impl_
->DidChangeTopControlsPosition();
2491 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2492 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2493 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2495 host_impl_
->active_tree()->total_top_controls_content_offset());
2497 host_impl_
->ActivateSyncTree();
2499 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2500 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2501 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2503 EXPECT_EQ(0.f
, host_impl_
->active_tree()->sent_top_controls_delta());
2504 EXPECT_EQ(-15.f
, host_impl_
->active_tree()->top_controls_delta());
2505 EXPECT_EQ(15.f
, host_impl_
->active_tree()->top_controls_content_offset());
2507 host_impl_
->active_tree()->total_top_controls_content_offset());
2510 // Test that changing the top controls layout height is correctly applied to
2511 // the inner viewport container bounds. That is, the top controls layout
2512 // height is the amount that the inner viewport container was shrunk outside
2513 // the compositor to accommodate the top controls.
2514 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsLayoutHeightChanged
) {
2515 CreateHostImpl(settings_
, CreateOutputSurface());
2516 SetupTopControlsAndScrollLayer();
2519 host_impl_
->sync_tree()->set_top_controls_content_offset(15.f
);
2520 host_impl_
->sync_tree()->set_top_controls_layout_height(15.f
);
2522 host_impl_
->active_tree()->set_top_controls_content_offset(20.f
);
2523 host_impl_
->active_tree()->set_top_controls_delta(-20.f
);
2524 host_impl_
->active_tree()->set_sent_top_controls_delta(-5.f
);
2526 host_impl_
->DidChangeTopControlsPosition();
2527 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2528 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2529 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2531 host_impl_
->sync_tree()->root_layer()->SetBounds(
2532 gfx::Size(root_clip_ptr
->bounds().width(),
2533 root_clip_ptr
->bounds().height() - 15.f
));
2535 host_impl_
->ActivateSyncTree();
2537 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2538 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2540 // The total bounds should remain unchanged since the bounds delta should
2541 // account for the difference between the layout height and the current
2542 // top controls offset.
2543 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2544 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 15.f
), root_clip_ptr
->bounds_delta());
2546 host_impl_
->active_tree()->set_top_controls_delta(0.f
);
2547 host_impl_
->DidChangeTopControlsPosition();
2549 EXPECT_EQ(15.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2550 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 0.f
), root_clip_ptr
->bounds_delta());
2551 EXPECT_EQ(gfx::Size(viewport_size_
.width(), viewport_size_
.height()-15.f
),
2552 root_clip_ptr
->bounds());
2555 // Test that showing/hiding the top controls when the viewport is fully scrolled
2556 // doesn't incorrectly change the viewport offset due to clamping from changing
2558 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsViewportOffsetClamping
) {
2559 SetupTopControlsAndScrollLayerWithVirtualViewport(
2560 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2563 EXPECT_EQ(settings_
.top_controls_height
,
2564 host_impl_
->active_tree()->total_top_controls_content_offset());
2566 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
2567 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
2569 // Scroll the viewports to max scroll offset.
2570 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2571 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2573 gfx::ScrollOffset viewport_offset
=
2574 host_impl_
->active_tree()->TotalScrollOffset();
2575 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(), viewport_offset
);
2577 // Hide the top controls by 25px.
2578 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2579 EXPECT_EQ(InputHandler::ScrollStarted
,
2580 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2581 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2582 host_impl_
->ScrollEnd();
2584 EXPECT_EQ(scroll_delta
.y(),
2585 settings_
.top_controls_height
-
2586 host_impl_
->active_tree()->total_top_controls_content_offset());
2588 inner_scroll
->ClampScrollToMaxScrollOffset();
2589 outer_scroll
->ClampScrollToMaxScrollOffset();
2591 // We should still be fully scrolled.
2592 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2593 host_impl_
->active_tree()->TotalScrollOffset());
2595 viewport_offset
= host_impl_
->active_tree()->TotalScrollOffset();
2597 // Bring the top controls down by 25px.
2598 scroll_delta
= gfx::Vector2dF(0.f
, -25.f
);
2599 EXPECT_EQ(InputHandler::ScrollStarted
,
2600 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2601 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2602 host_impl_
->ScrollEnd();
2604 // The viewport offset shouldn't have changed.
2605 EXPECT_EQ(viewport_offset
,
2606 host_impl_
->active_tree()->TotalScrollOffset());
2608 // Scroll the viewports to max scroll offset.
2609 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2610 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2611 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2612 host_impl_
->active_tree()->TotalScrollOffset());
2615 // Test that the top controls coming in and out maintains the same aspect ratio
2616 // between the inner and outer viewports.
2617 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsAspectRatio
) {
2618 SetupTopControlsAndScrollLayerWithVirtualViewport(
2619 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2622 EXPECT_EQ(settings_
.top_controls_height
,
2623 host_impl_
->active_tree()->total_top_controls_content_offset());
2625 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2626 EXPECT_EQ(InputHandler::ScrollStarted
,
2627 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2628 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2629 host_impl_
->ScrollEnd();
2631 EXPECT_EQ(scroll_delta
.y(),
2632 settings_
.top_controls_height
-
2633 host_impl_
->active_tree()->total_top_controls_content_offset());
2635 // Top controls were hidden by 25px so the inner viewport should have expanded
2637 LayerImpl
* outer_container
=
2638 host_impl_
->active_tree()->OuterViewportContainerLayer();
2639 LayerImpl
* inner_container
=
2640 host_impl_
->active_tree()->InnerViewportContainerLayer();
2641 EXPECT_EQ(gfx::Size(100, 100+25), inner_container
->BoundsForScrolling());
2643 // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
2644 float aspect_ratio
= inner_container
->BoundsForScrolling().width() /
2645 inner_container
->BoundsForScrolling().height();
2646 gfx::Size expected
= gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio
));
2647 EXPECT_EQ(expected
, outer_container
->BoundsForScrolling());
2649 host_impl_
->InnerViewportScrollLayer()->BoundsForScrolling());
2652 // Test that scrolling the outer viewport affects the top controls.
2653 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsScrollOuterViewport
) {
2654 SetupTopControlsAndScrollLayerWithVirtualViewport(
2655 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2658 EXPECT_EQ(settings_
.top_controls_height
,
2659 host_impl_
->active_tree()->total_top_controls_content_offset());
2661 // Send a gesture scroll that will scroll the outer viewport, make sure the
2662 // top controls get scrolled.
2663 gfx::Vector2dF
scroll_delta(0.f
, 15.f
);
2664 EXPECT_EQ(InputHandler::ScrollStarted
,
2665 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2666 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2667 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
2668 host_impl_
->CurrentlyScrollingLayer());
2669 host_impl_
->ScrollEnd();
2671 EXPECT_EQ(scroll_delta
.y(),
2672 settings_
.top_controls_height
-
2673 host_impl_
->active_tree()->total_top_controls_content_offset());
2675 scroll_delta
= gfx::Vector2dF(0.f
, 50.f
);
2676 EXPECT_EQ(InputHandler::ScrollStarted
,
2677 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2678 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2680 EXPECT_EQ(0, host_impl_
->active_tree()->total_top_controls_content_offset());
2681 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
2682 host_impl_
->CurrentlyScrollingLayer());
2684 host_impl_
->ScrollEnd();
2686 // Position the viewports such that the inner viewport will be scrolled.
2687 gfx::Vector2dF
inner_viewport_offset(0.f
, 25.f
);
2688 host_impl_
->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2dF());
2689 host_impl_
->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset
);
2691 scroll_delta
= gfx::Vector2dF(0.f
, -65.f
);
2692 EXPECT_EQ(InputHandler::ScrollStarted
,
2693 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2694 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2696 EXPECT_EQ(settings_
.top_controls_height
,
2697 host_impl_
->active_tree()->total_top_controls_content_offset());
2698 EXPECT_EQ(inner_viewport_offset
.y() +
2699 (scroll_delta
.y() + settings_
.top_controls_height
),
2700 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
2702 host_impl_
->ScrollEnd();
2705 TEST_F(LayerTreeHostImplTopControlsTest
,
2706 ScrollNonScrollableRootWithTopControls
) {
2707 CreateHostImpl(settings_
, CreateOutputSurface());
2708 SetupTopControlsAndScrollLayer();
2711 EXPECT_EQ(InputHandler::ScrollStarted
,
2712 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2714 host_impl_
->top_controls_manager()->ScrollBegin();
2715 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2716 host_impl_
->top_controls_manager()->ScrollEnd();
2717 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2718 // Now that top controls have moved, expect the clip to resize.
2719 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2720 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2722 host_impl_
->ScrollEnd();
2724 EXPECT_EQ(InputHandler::ScrollStarted
,
2725 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2727 float scroll_increment_y
= -25.f
;
2728 host_impl_
->top_controls_manager()->ScrollBegin();
2729 host_impl_
->top_controls_manager()->ScrollBy(
2730 gfx::Vector2dF(0.f
, scroll_increment_y
));
2731 EXPECT_EQ(-scroll_increment_y
,
2732 host_impl_
->top_controls_manager()->ContentTopOffset());
2733 // Now that top controls have moved, expect the clip to resize.
2734 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2735 viewport_size_
.height() + scroll_increment_y
),
2736 root_clip_ptr
->bounds());
2738 host_impl_
->top_controls_manager()->ScrollBy(
2739 gfx::Vector2dF(0.f
, scroll_increment_y
));
2740 host_impl_
->top_controls_manager()->ScrollEnd();
2741 EXPECT_EQ(-2 * scroll_increment_y
,
2742 host_impl_
->top_controls_manager()->ContentTopOffset());
2743 // Now that top controls have moved, expect the clip to resize.
2744 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2746 host_impl_
->ScrollEnd();
2748 // Verify the layer is once-again non-scrollable.
2750 gfx::ScrollOffset(),
2751 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2753 EXPECT_EQ(InputHandler::ScrollStarted
,
2754 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2757 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2758 // Test the configuration where a non-composited root layer is embedded in a
2759 // scrollable outer layer.
2760 gfx::Size
surface_size(10, 10);
2761 gfx::Size
contents_size(20, 20);
2763 scoped_ptr
<LayerImpl
> content_layer
=
2764 LayerImpl::Create(host_impl_
->active_tree(), 1);
2765 content_layer
->SetDrawsContent(true);
2766 content_layer
->SetPosition(gfx::PointF());
2767 content_layer
->SetBounds(contents_size
);
2768 content_layer
->SetContentBounds(contents_size
);
2769 content_layer
->SetContentsScale(2.f
, 2.f
);
2771 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2772 LayerImpl::Create(host_impl_
->active_tree(), 3);
2773 scroll_clip_layer
->SetBounds(surface_size
);
2775 scoped_ptr
<LayerImpl
> scroll_layer
=
2776 LayerImpl::Create(host_impl_
->active_tree(), 2);
2777 scroll_layer
->SetScrollClipLayer(3);
2778 scroll_layer
->SetBounds(contents_size
);
2779 scroll_layer
->SetContentBounds(contents_size
);
2780 scroll_layer
->SetPosition(gfx::PointF());
2781 scroll_layer
->AddChild(content_layer
.Pass());
2782 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2784 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2785 host_impl_
->SetViewportSize(surface_size
);
2788 EXPECT_EQ(InputHandler::ScrollStarted
,
2789 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2790 InputHandler::Wheel
));
2791 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2792 host_impl_
->ScrollEnd();
2793 EXPECT_TRUE(did_request_redraw_
);
2794 EXPECT_TRUE(did_request_commit_
);
2797 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2798 gfx::Size
surface_size(10, 10);
2799 gfx::Size
contents_size(20, 20);
2800 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2801 root
->SetBounds(surface_size
);
2802 root
->SetContentBounds(contents_size
);
2803 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2804 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2805 host_impl_
->SetViewportSize(surface_size
);
2808 EXPECT_EQ(InputHandler::ScrollStarted
,
2809 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2810 InputHandler::Wheel
));
2811 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2812 host_impl_
->ScrollEnd();
2813 EXPECT_TRUE(did_request_redraw_
);
2814 EXPECT_TRUE(did_request_commit_
);
2817 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2818 gfx::Size
surface_size(10, 10);
2819 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2820 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2821 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2822 host_impl_
->SetViewportSize(surface_size
);
2825 // Scroll event is ignored because the input coordinate is outside the layer
2827 EXPECT_EQ(InputHandler::ScrollIgnored
,
2828 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2829 InputHandler::Wheel
));
2830 EXPECT_FALSE(did_request_redraw_
);
2831 EXPECT_FALSE(did_request_commit_
);
2834 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2835 gfx::Size
surface_size(10, 10);
2836 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2837 scoped_ptr
<LayerImpl
> child
=
2838 CreateScrollableLayer(2, surface_size
, root
.get());
2839 host_impl_
->SetViewportSize(surface_size
);
2841 gfx::Transform matrix
;
2842 matrix
.RotateAboutXAxis(180.0);
2843 child
->SetTransform(matrix
);
2844 child
->SetDoubleSided(false);
2846 root
->AddChild(child
.Pass());
2847 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2850 // Scroll event is ignored because the scrollable layer is not facing the
2851 // viewer and there is nothing scrollable behind it.
2852 EXPECT_EQ(InputHandler::ScrollIgnored
,
2853 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2854 InputHandler::Wheel
));
2855 EXPECT_FALSE(did_request_redraw_
);
2856 EXPECT_FALSE(did_request_commit_
);
2859 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2860 gfx::Size
surface_size(10, 10);
2861 scoped_ptr
<LayerImpl
> clip_layer
=
2862 LayerImpl::Create(host_impl_
->active_tree(), 3);
2863 scoped_ptr
<LayerImpl
> content_layer
=
2864 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2865 content_layer
->SetShouldScrollOnMainThread(true);
2866 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2868 // Note: we can use the same clip layer for both since both calls to
2869 // CreateScrollableLayer() use the same surface size.
2870 scoped_ptr
<LayerImpl
> scroll_layer
=
2871 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2872 scroll_layer
->AddChild(content_layer
.Pass());
2873 clip_layer
->AddChild(scroll_layer
.Pass());
2875 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2876 host_impl_
->SetViewportSize(surface_size
);
2879 // Scrolling fails because the content layer is asking to be scrolled on the
2881 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2882 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2883 InputHandler::Wheel
));
2886 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2887 gfx::Size
surface_size(20, 20);
2888 gfx::Size
viewport_size(10, 10);
2889 float page_scale
= 2.f
;
2890 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2891 scoped_ptr
<LayerImpl
> root_clip
=
2892 LayerImpl::Create(host_impl_
->active_tree(), 2);
2893 scoped_ptr
<LayerImpl
> root_scrolling
=
2894 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2895 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2896 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2897 root_clip
->AddChild(root_scrolling
.Pass());
2898 root
->AddChild(root_clip
.Pass());
2899 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2900 // The behaviour in this test assumes the page scale is applied at a layer
2901 // above the clip layer.
2902 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2903 host_impl_
->active_tree()->DidBecomeActive();
2904 host_impl_
->SetViewportSize(viewport_size
);
2907 LayerImpl
* root_scroll
=
2908 host_impl_
->active_tree()->InnerViewportScrollLayer();
2909 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2911 gfx::Vector2d
scroll_delta(0, 10);
2912 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2913 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
2914 EXPECT_EQ(InputHandler::ScrollStarted
,
2915 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2916 InputHandler::Wheel
));
2917 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2918 host_impl_
->ScrollEnd();
2920 // Set new page scale from main thread.
2921 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2925 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2926 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2928 // The scroll range should also have been updated.
2929 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2931 // The page scale delta remains constant because the impl thread did not
2933 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2936 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
2937 gfx::Size
surface_size(20, 20);
2938 gfx::Size
viewport_size(10, 10);
2939 float page_scale
= 2.f
;
2940 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2941 scoped_ptr
<LayerImpl
> root_clip
=
2942 LayerImpl::Create(host_impl_
->active_tree(), 2);
2943 scoped_ptr
<LayerImpl
> root_scrolling
=
2944 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2945 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2946 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2947 root_clip
->AddChild(root_scrolling
.Pass());
2948 root
->AddChild(root_clip
.Pass());
2949 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2950 // The behaviour in this test assumes the page scale is applied at a layer
2951 // above the clip layer.
2952 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2953 host_impl_
->active_tree()->DidBecomeActive();
2954 host_impl_
->SetViewportSize(viewport_size
);
2955 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, page_scale
);
2958 LayerImpl
* root_scroll
=
2959 host_impl_
->active_tree()->InnerViewportScrollLayer();
2960 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2962 gfx::Vector2d
scroll_delta(0, 10);
2963 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2964 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
2965 EXPECT_EQ(InputHandler::ScrollStarted
,
2966 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2967 InputHandler::Wheel
));
2968 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2969 host_impl_
->ScrollEnd();
2971 // Set new page scale on impl thread by pinching.
2972 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2973 host_impl_
->PinchGestureBegin();
2974 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
2975 host_impl_
->PinchGestureEnd();
2976 host_impl_
->ScrollEnd();
2979 // The scroll delta is not scaled because the main thread did not scale.
2980 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2981 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2983 // The scroll range should also have been updated.
2984 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2986 // The page scale delta should match the new scale on the impl side.
2987 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->total_page_scale_factor());
2990 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
2991 gfx::Size
surface_size(10, 10);
2992 float default_page_scale
= 1.f
;
2993 gfx::Transform default_page_scale_matrix
;
2994 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
2996 float new_page_scale
= 2.f
;
2997 gfx::Transform new_page_scale_matrix
;
2998 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
3000 // Create a normal scrollable root layer and another scrollable child layer.
3001 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
3002 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3003 LayerImpl
* child
= scroll
->children()[0];
3005 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
3006 LayerImpl::Create(host_impl_
->active_tree(), 6);
3007 scoped_ptr
<LayerImpl
> scrollable_child
=
3008 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
3009 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
3010 child
->AddChild(scrollable_child_clip
.Pass());
3011 LayerImpl
* grand_child
= child
->children()[0];
3013 // Set new page scale on impl thread by pinching.
3014 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3015 host_impl_
->PinchGestureBegin();
3016 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
3017 host_impl_
->PinchGestureEnd();
3018 host_impl_
->ScrollEnd();
3021 EXPECT_EQ(1.f
, root
->contents_scale_x());
3022 EXPECT_EQ(1.f
, root
->contents_scale_y());
3023 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
3024 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
3025 EXPECT_EQ(1.f
, child
->contents_scale_x());
3026 EXPECT_EQ(1.f
, child
->contents_scale_y());
3027 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
3028 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
3030 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
3031 // the page scale delta on the root layer is applied hierarchically.
3032 LayerTreeHostImpl::FrameData frame
;
3033 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3034 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3035 host_impl_
->DidDrawAllLayers(frame
);
3037 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
3038 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
3039 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
3040 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
3041 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
3042 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
3043 EXPECT_EQ(new_page_scale
,
3044 grand_child
->draw_transform().matrix().getDouble(0, 0));
3045 EXPECT_EQ(new_page_scale
,
3046 grand_child
->draw_transform().matrix().getDouble(1, 1));
3049 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
3050 gfx::Size
surface_size(30, 30);
3051 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3052 root
->SetBounds(gfx::Size(5, 5));
3053 scoped_ptr
<LayerImpl
> root_scrolling
=
3054 LayerImpl::Create(host_impl_
->active_tree(), 2);
3055 root_scrolling
->SetBounds(surface_size
);
3056 root_scrolling
->SetContentBounds(surface_size
);
3057 root_scrolling
->SetScrollClipLayer(root
->id());
3058 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3059 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
3060 root
->AddChild(root_scrolling
.Pass());
3061 int child_scroll_layer_id
= 3;
3062 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
3063 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
3064 LayerImpl
* child
= child_scrolling
.get();
3065 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
3066 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3067 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
3068 host_impl_
->active_tree()->DidBecomeActive();
3069 host_impl_
->SetViewportSize(surface_size
);
3072 gfx::Vector2d
scroll_delta(0, 10);
3073 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
3074 gfx::ScrollOffset
expected_max_scroll(child
->MaxScrollOffset());
3075 EXPECT_EQ(InputHandler::ScrollStarted
,
3076 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3077 InputHandler::Wheel
));
3078 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3079 host_impl_
->ScrollEnd();
3081 float page_scale
= 2.f
;
3082 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
3088 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3090 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
3092 // The scroll range should not have changed.
3093 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
3095 // The page scale delta remains constant because the impl thread did not
3097 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
3100 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
3101 // Scroll a child layer beyond its maximum scroll range and make sure the
3102 // parent layer is scrolled on the axis on which the child was unable to
3104 gfx::Size
surface_size(10, 10);
3105 gfx::Size
content_size(20, 20);
3106 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3107 root
->SetBounds(surface_size
);
3109 scoped_ptr
<LayerImpl
> grand_child
=
3110 CreateScrollableLayer(3, content_size
, root
.get());
3112 scoped_ptr
<LayerImpl
> child
=
3113 CreateScrollableLayer(2, content_size
, root
.get());
3114 LayerImpl
* grand_child_layer
= grand_child
.get();
3115 child
->AddChild(grand_child
.Pass());
3117 LayerImpl
* child_layer
= child
.get();
3118 root
->AddChild(child
.Pass());
3119 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3120 host_impl_
->active_tree()->DidBecomeActive();
3121 host_impl_
->SetViewportSize(surface_size
);
3122 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 5));
3123 child_layer
->SetScrollOffset(gfx::ScrollOffset(3, 0));
3127 gfx::Vector2d
scroll_delta(-8, -7);
3128 EXPECT_EQ(InputHandler::ScrollStarted
,
3129 host_impl_
->ScrollBegin(gfx::Point(),
3130 InputHandler::Wheel
));
3131 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3132 host_impl_
->ScrollEnd();
3134 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3135 host_impl_
->ProcessScrollDeltas();
3137 // The grand child should have scrolled up to its limit.
3138 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
3139 LayerImpl
* grand_child
= child
->children()[0];
3140 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
3142 // The child should have only scrolled on the other axis.
3143 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
3147 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
3148 // Scroll a child layer beyond its maximum scroll range and make sure the
3149 // the scroll doesn't bubble up to the parent layer.
3150 gfx::Size
surface_size(20, 20);
3151 gfx::Size
viewport_size(10, 10);
3152 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3153 scoped_ptr
<LayerImpl
> root_scrolling
=
3154 CreateScrollableLayer(2, surface_size
, root
.get());
3155 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3157 scoped_ptr
<LayerImpl
> grand_child
=
3158 CreateScrollableLayer(4, surface_size
, root
.get());
3160 scoped_ptr
<LayerImpl
> child
=
3161 CreateScrollableLayer(3, surface_size
, root
.get());
3162 LayerImpl
* grand_child_layer
= grand_child
.get();
3163 child
->AddChild(grand_child
.Pass());
3165 LayerImpl
* child_layer
= child
.get();
3166 root_scrolling
->AddChild(child
.Pass());
3167 root
->AddChild(root_scrolling
.Pass());
3168 EXPECT_EQ(viewport_size
, root
->bounds());
3169 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3170 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
3171 host_impl_
->active_tree()->DidBecomeActive();
3172 host_impl_
->SetViewportSize(viewport_size
);
3174 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 2));
3175 child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 3));
3179 gfx::Vector2d
scroll_delta(0, -10);
3180 EXPECT_EQ(InputHandler::ScrollStarted
,
3181 host_impl_
->ScrollBegin(gfx::Point(),
3182 InputHandler::NonBubblingGesture
));
3183 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3184 host_impl_
->ScrollEnd();
3186 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3187 host_impl_
->ProcessScrollDeltas();
3189 // The grand child should have scrolled up to its limit.
3191 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
3192 LayerImpl
* grand_child
= child
->children()[0];
3193 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3195 // The child should not have scrolled.
3196 ExpectNone(*scroll_info
.get(), child
->id());
3198 // The next time we scroll we should only scroll the parent.
3199 scroll_delta
= gfx::Vector2d(0, -3);
3200 EXPECT_EQ(InputHandler::ScrollStarted
,
3201 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3202 InputHandler::NonBubblingGesture
));
3203 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3204 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3205 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
3206 host_impl_
->ScrollEnd();
3208 scroll_info
= host_impl_
->ProcessScrollDeltas();
3210 // The child should have scrolled up to its limit.
3211 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3213 // The grand child should not have scrolled.
3214 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3216 // After scrolling the parent, another scroll on the opposite direction
3217 // should still scroll the child.
3218 scroll_delta
= gfx::Vector2d(0, 7);
3219 EXPECT_EQ(InputHandler::ScrollStarted
,
3220 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3221 InputHandler::NonBubblingGesture
));
3222 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3223 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3224 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3225 host_impl_
->ScrollEnd();
3227 scroll_info
= host_impl_
->ProcessScrollDeltas();
3229 // The grand child should have scrolled.
3230 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
3232 // The child should not have scrolled.
3233 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3236 // Scrolling should be adjusted from viewport space.
3237 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 2.f
, 2.f
);
3238 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3240 scroll_delta
= gfx::Vector2d(0, -2);
3241 EXPECT_EQ(InputHandler::ScrollStarted
,
3242 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3243 InputHandler::NonBubblingGesture
));
3244 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
3245 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3246 host_impl_
->ScrollEnd();
3248 scroll_info
= host_impl_
->ProcessScrollDeltas();
3250 // Should have scrolled by half the amount in layer space (5 - 2/2)
3251 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
3254 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
3255 // When we try to scroll a non-scrollable child layer, the scroll delta
3256 // should be applied to one of its ancestors if possible.
3257 gfx::Size
surface_size(10, 10);
3258 gfx::Size
content_size(20, 20);
3259 scoped_ptr
<LayerImpl
> root_clip
=
3260 LayerImpl::Create(host_impl_
->active_tree(), 3);
3261 scoped_ptr
<LayerImpl
> root
=
3262 CreateScrollableLayer(1, content_size
, root_clip
.get());
3263 // Make 'root' the clip layer for child: since they have the same sizes the
3264 // child will have zero max_scroll_offset and scrolls will bubble.
3265 scoped_ptr
<LayerImpl
> child
=
3266 CreateScrollableLayer(2, content_size
, root
.get());
3267 child
->SetIsContainerForFixedPositionLayers(true);
3268 root
->SetBounds(content_size
);
3270 int root_scroll_id
= root
->id();
3271 root
->AddChild(child
.Pass());
3272 root_clip
->AddChild(root
.Pass());
3274 host_impl_
->SetViewportSize(surface_size
);
3275 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3276 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID
);
3277 host_impl_
->active_tree()->DidBecomeActive();
3280 gfx::Vector2d
scroll_delta(0, 4);
3281 EXPECT_EQ(InputHandler::ScrollStarted
,
3282 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3283 InputHandler::Wheel
));
3284 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3285 host_impl_
->ScrollEnd();
3287 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3288 host_impl_
->ProcessScrollDeltas();
3290 // Only the root scroll should have scrolled.
3291 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
3292 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
3296 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
3297 gfx::Size
surface_size(10, 10);
3298 scoped_ptr
<LayerImpl
> root_clip
=
3299 LayerImpl::Create(host_impl_
->active_tree(), 1);
3300 scoped_ptr
<LayerImpl
> root_scroll
=
3301 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3302 root_scroll
->SetIsContainerForFixedPositionLayers(true);
3303 root_clip
->AddChild(root_scroll
.Pass());
3304 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3305 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
3306 host_impl_
->active_tree()->DidBecomeActive();
3307 host_impl_
->SetViewportSize(surface_size
);
3309 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
3312 host_impl_
->active_tree()->DetachLayerTree();
3313 scoped_ptr
<LayerImpl
> root_clip2
=
3314 LayerImpl::Create(host_impl_
->active_tree(), 3);
3315 scoped_ptr
<LayerImpl
> root_scroll2
=
3316 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
3317 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
3318 root_clip2
->AddChild(root_scroll2
.Pass());
3319 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
3320 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID
);
3321 host_impl_
->active_tree()->DidBecomeActive();
3323 // Scrolling should still work even though we did not draw yet.
3324 EXPECT_EQ(InputHandler::ScrollStarted
,
3325 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3326 InputHandler::Wheel
));
3329 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
3330 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3332 // Rotate the root layer 90 degrees counter-clockwise about its center.
3333 gfx::Transform rotate_transform
;
3334 rotate_transform
.Rotate(-90.0);
3335 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
3337 gfx::Size
surface_size(50, 50);
3338 host_impl_
->SetViewportSize(surface_size
);
3341 // Scroll to the right in screen coordinates with a gesture.
3342 gfx::Vector2d
gesture_scroll_delta(10, 0);
3343 EXPECT_EQ(InputHandler::ScrollStarted
,
3344 host_impl_
->ScrollBegin(gfx::Point(),
3345 InputHandler::Gesture
));
3346 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3347 host_impl_
->ScrollEnd();
3349 // The layer should have scrolled down in its local coordinates.
3350 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3351 ExpectContains(*scroll_info
.get(),
3353 gfx::Vector2d(0, gesture_scroll_delta
.x()));
3355 // Reset and scroll down with the wheel.
3356 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3357 gfx::Vector2d
wheel_scroll_delta(0, 10);
3358 EXPECT_EQ(InputHandler::ScrollStarted
,
3359 host_impl_
->ScrollBegin(gfx::Point(),
3360 InputHandler::Wheel
));
3361 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3362 host_impl_
->ScrollEnd();
3364 // The layer should have scrolled down in its local coordinates.
3365 scroll_info
= host_impl_
->ProcessScrollDeltas();
3366 ExpectContains(*scroll_info
.get(),
3368 wheel_scroll_delta
);
3371 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
3372 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3373 int child_clip_layer_id
= 6;
3374 int child_layer_id
= 7;
3375 float child_layer_angle
= -20.f
;
3377 // Create a child layer that is rotated to a non-axis-aligned angle.
3378 scoped_ptr
<LayerImpl
> clip_layer
=
3379 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
3380 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
3381 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
3382 gfx::Transform rotate_transform
;
3383 rotate_transform
.Translate(-50.0, -50.0);
3384 rotate_transform
.Rotate(child_layer_angle
);
3385 rotate_transform
.Translate(50.0, 50.0);
3386 clip_layer
->SetTransform(rotate_transform
);
3388 // Only allow vertical scrolling.
3389 clip_layer
->SetBounds(
3390 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
3391 // The rotation depends on the layer's transform origin, and the child layer
3392 // is a different size than the clip, so make sure the clip layer's origin
3393 // lines up over the child.
3394 clip_layer
->SetTransformOrigin(gfx::Point3F(
3395 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
3396 LayerImpl
* child_ptr
= child
.get();
3397 clip_layer
->AddChild(child
.Pass());
3398 scroll_layer
->AddChild(clip_layer
.Pass());
3400 gfx::Size
surface_size(50, 50);
3401 host_impl_
->SetViewportSize(surface_size
);
3404 // Scroll down in screen coordinates with a gesture.
3405 gfx::Vector2d
gesture_scroll_delta(0, 10);
3406 EXPECT_EQ(InputHandler::ScrollStarted
,
3407 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3408 InputHandler::Gesture
));
3409 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3410 host_impl_
->ScrollEnd();
3412 // The child layer should have scrolled down in its local coordinates an
3413 // amount proportional to the angle between it and the input scroll delta.
3414 gfx::Vector2d
expected_scroll_delta(
3416 gesture_scroll_delta
.y() *
3417 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
3418 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3419 host_impl_
->ProcessScrollDeltas();
3420 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3422 // The root scroll layer should not have scrolled, because the input delta
3423 // was close to the layer's axis of movement.
3424 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
3427 // Now reset and scroll the same amount horizontally.
3428 child_ptr
->SetScrollDelta(gfx::Vector2dF());
3429 gfx::Vector2d
gesture_scroll_delta(10, 0);
3430 EXPECT_EQ(InputHandler::ScrollStarted
,
3431 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3432 InputHandler::Gesture
));
3433 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3434 host_impl_
->ScrollEnd();
3436 // The child layer should have scrolled down in its local coordinates an
3437 // amount proportional to the angle between it and the input scroll delta.
3438 gfx::Vector2d
expected_scroll_delta(
3440 -gesture_scroll_delta
.x() *
3441 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
3442 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3443 host_impl_
->ProcessScrollDeltas();
3444 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3446 // The root scroll layer should have scrolled more, since the input scroll
3447 // delta was mostly orthogonal to the child layer's vertical scroll axis.
3448 gfx::Vector2d
expected_root_scroll_delta(
3449 gesture_scroll_delta
.x() *
3450 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
3452 ExpectContains(*scroll_info
.get(),
3454 expected_root_scroll_delta
);
3458 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
3459 LayerImpl
* scroll_layer
=
3460 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3462 // Scale the layer to twice its normal size.
3464 gfx::Transform scale_transform
;
3465 scale_transform
.Scale(scale
, scale
);
3466 scroll_layer
->SetTransform(scale_transform
);
3468 gfx::Size
surface_size(50, 50);
3469 host_impl_
->SetViewportSize(surface_size
);
3472 // Scroll down in screen coordinates with a gesture.
3473 gfx::Vector2d
scroll_delta(0, 10);
3474 EXPECT_EQ(InputHandler::ScrollStarted
,
3475 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3476 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3477 host_impl_
->ScrollEnd();
3479 // The layer should have scrolled down in its local coordinates, but half the
3481 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3482 ExpectContains(*scroll_info
.get(),
3484 gfx::Vector2d(0, scroll_delta
.y() / scale
));
3486 // Reset and scroll down with the wheel.
3487 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3488 gfx::Vector2d
wheel_scroll_delta(0, 10);
3489 EXPECT_EQ(InputHandler::ScrollStarted
,
3490 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3491 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3492 host_impl_
->ScrollEnd();
3494 // The scale should not have been applied to the scroll delta.
3495 scroll_info
= host_impl_
->ProcessScrollDeltas();
3496 ExpectContains(*scroll_info
.get(),
3498 wheel_scroll_delta
);
3501 TEST_F(LayerTreeHostImplTest
, ScrollViewportRounding
) {
3505 SetupScrollAndContentsLayers(gfx::Size(width
, height
));
3506 host_impl_
->active_tree()->InnerViewportContainerLayer()->SetBounds(
3507 gfx::Size(width
* scale
- 1, height
* scale
));
3508 host_impl_
->SetDeviceScaleFactor(scale
);
3509 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3511 LayerImpl
* inner_viewport_scroll_layer
=
3512 host_impl_
->active_tree()->InnerViewportScrollLayer();
3513 EXPECT_EQ(gfx::ScrollOffset(0, 0),
3514 inner_viewport_scroll_layer
->MaxScrollOffset());
3517 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3519 TestScrollOffsetDelegate()
3520 : page_scale_factor_(0.f
),
3521 min_page_scale_factor_(-1.f
),
3522 max_page_scale_factor_(-1.f
) {}
3524 ~TestScrollOffsetDelegate() override
{}
3526 gfx::ScrollOffset
GetTotalScrollOffset() override
{
3527 return getter_return_value_
;
3530 bool IsExternalFlingActive() const override
{ return false; }
3532 void UpdateRootLayerState(const gfx::ScrollOffset
& total_scroll_offset
,
3533 const gfx::ScrollOffset
& max_scroll_offset
,
3534 const gfx::SizeF
& scrollable_size
,
3535 float page_scale_factor
,
3536 float min_page_scale_factor
,
3537 float max_page_scale_factor
) override
{
3538 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3539 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3540 last_set_scroll_offset_
= total_scroll_offset
;
3541 max_scroll_offset_
= max_scroll_offset
;
3542 scrollable_size_
= scrollable_size
;
3543 page_scale_factor_
= page_scale_factor
;
3544 min_page_scale_factor_
= min_page_scale_factor
;
3545 max_page_scale_factor_
= max_page_scale_factor
;
3548 gfx::ScrollOffset
last_set_scroll_offset() {
3549 return last_set_scroll_offset_
;
3552 void set_getter_return_value(const gfx::ScrollOffset
& value
) {
3553 getter_return_value_
= value
;
3556 gfx::ScrollOffset
max_scroll_offset() const {
3557 return max_scroll_offset_
;
3560 gfx::SizeF
scrollable_size() const {
3561 return scrollable_size_
;
3564 float page_scale_factor() const {
3565 return page_scale_factor_
;
3568 float min_page_scale_factor() const {
3569 return min_page_scale_factor_
;
3572 float max_page_scale_factor() const {
3573 return max_page_scale_factor_
;
3577 gfx::ScrollOffset last_set_scroll_offset_
;
3578 gfx::ScrollOffset getter_return_value_
;
3579 gfx::ScrollOffset max_scroll_offset_
;
3580 gfx::SizeF scrollable_size_
;
3581 float page_scale_factor_
;
3582 float min_page_scale_factor_
;
3583 float max_page_scale_factor_
;
3586 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3587 TestScrollOffsetDelegate scroll_delegate
;
3588 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3589 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3590 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3591 clip_layer
->SetBounds(gfx::Size(10, 20));
3593 // Setting the delegate results in the current scroll offset being set.
3594 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3595 scroll_layer
->SetScrollOffset(gfx::ScrollOffset());
3596 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3597 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3598 EXPECT_EQ(initial_scroll_delta
.ToString(),
3599 scroll_delegate
.last_set_scroll_offset().ToString());
3601 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3602 // page_scale_factor and {min|max}_page_scale_factor being set.
3603 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3604 EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate
.max_scroll_offset());
3605 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3606 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3607 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3609 // Updating page scale immediately updates the delegate.
3610 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 0.5f
, 4.f
);
3611 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3612 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3613 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3614 host_impl_
->active_tree()->SetPageScaleDelta(1.5f
);
3615 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3616 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3617 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3618 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3619 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3620 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3621 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3622 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3624 // The pinch gesture doesn't put the delegate into a state where the scroll
3625 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3627 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3628 host_impl_
->PinchGestureBegin();
3629 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3630 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3631 host_impl_
->PinchGestureEnd();
3632 host_impl_
->ScrollEnd();
3634 // Scrolling should be relative to the offset as returned by the delegate.
3635 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3636 gfx::ScrollOffset
current_offset(7.f
, 8.f
);
3638 scroll_delegate
.set_getter_return_value(current_offset
);
3639 EXPECT_EQ(InputHandler::ScrollStarted
,
3640 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3642 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3643 EXPECT_EQ(ScrollOffsetWithDelta(current_offset
, scroll_delta
),
3644 scroll_delegate
.last_set_scroll_offset());
3646 current_offset
= gfx::ScrollOffset(42.f
, 41.f
);
3647 scroll_delegate
.set_getter_return_value(current_offset
);
3648 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3649 EXPECT_EQ(current_offset
+ gfx::ScrollOffset(scroll_delta
),
3650 scroll_delegate
.last_set_scroll_offset());
3651 host_impl_
->ScrollEnd();
3652 scroll_delegate
.set_getter_return_value(gfx::ScrollOffset());
3654 // Forces a full tree synchronization and ensures that the scroll delegate
3655 // sees the correct size of the new tree.
3656 gfx::Size
new_size(42, 24);
3657 host_impl_
->CreatePendingTree();
3658 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3659 host_impl_
->ActivateSyncTree();
3660 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3662 // Un-setting the delegate should propagate the delegate's current offset to
3663 // the root scrollable layer.
3664 current_offset
= gfx::ScrollOffset(13.f
, 12.f
);
3665 scroll_delegate
.set_getter_return_value(current_offset
);
3666 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3668 EXPECT_EQ(current_offset
.ToString(),
3669 scroll_layer
->TotalScrollOffset().ToString());
3672 void CheckLayerScrollDelta(LayerImpl
* layer
, gfx::Vector2dF scroll_delta
) {
3673 const gfx::Transform target_space_transform
=
3674 layer
->draw_properties().target_space_transform
;
3675 EXPECT_TRUE(target_space_transform
.IsScaleOrTranslation());
3676 gfx::Point translated_point
;
3677 target_space_transform
.TransformPoint(&translated_point
);
3678 gfx::Point expected_point
= gfx::Point() - ToRoundedVector2d(scroll_delta
);
3679 EXPECT_EQ(expected_point
.ToString(), translated_point
.ToString());
3682 TEST_F(LayerTreeHostImplTest
,
3683 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw
) {
3684 TestScrollOffsetDelegate scroll_delegate
;
3685 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3686 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3687 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3688 clip_layer
->SetBounds(gfx::Size(10, 20));
3689 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3691 // Draw first frame to clear any pending draws and check scroll.
3693 CheckLayerScrollDelta(scroll_layer
, gfx::Vector2dF(0.f
, 0.f
));
3694 EXPECT_FALSE(host_impl_
->active_tree()->needs_update_draw_properties());
3696 // Set external scroll delta on delegate and notify LayerTreeHost.
3697 gfx::ScrollOffset
scroll_offset(10.f
, 10.f
);
3698 scroll_delegate
.set_getter_return_value(scroll_offset
);
3699 host_impl_
->OnRootLayerDelegatedScrollOffsetChanged();
3701 // Check scroll delta reflected in layer.
3702 LayerTreeHostImpl::FrameData frame
;
3703 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3704 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3705 host_impl_
->DidDrawAllLayers(frame
);
3706 EXPECT_FALSE(frame
.has_no_damage
);
3707 CheckLayerScrollDelta(scroll_layer
, ScrollOffsetToVector2dF(scroll_offset
));
3709 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3712 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3713 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3714 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3715 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3717 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3719 // In-bounds scrolling does not affect overscroll.
3720 EXPECT_EQ(InputHandler::ScrollStarted
,
3721 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3722 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3723 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3725 // Overscroll events are reflected immediately.
3726 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3727 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3729 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3730 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3731 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3732 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3733 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3734 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3735 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3736 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3737 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3738 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3739 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3740 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3741 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3743 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3744 // as no scroll occurs.
3745 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3746 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3747 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3748 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3749 // Overscroll resets on valid scroll.
3750 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3751 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3752 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3753 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3754 host_impl_
->ScrollEnd();
3758 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3759 // Scroll child layers beyond their maximum scroll range and make sure root
3760 // overscroll does not accumulate.
3761 gfx::Size
surface_size(10, 10);
3762 scoped_ptr
<LayerImpl
> root_clip
=
3763 LayerImpl::Create(host_impl_
->active_tree(), 4);
3764 scoped_ptr
<LayerImpl
> root
=
3765 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3767 scoped_ptr
<LayerImpl
> grand_child
=
3768 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3770 scoped_ptr
<LayerImpl
> child
=
3771 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3772 LayerImpl
* grand_child_layer
= grand_child
.get();
3773 child
->AddChild(grand_child
.Pass());
3775 LayerImpl
* child_layer
= child
.get();
3776 root
->AddChild(child
.Pass());
3777 root_clip
->AddChild(root
.Pass());
3778 child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 3));
3779 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 2));
3780 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3781 host_impl_
->active_tree()->DidBecomeActive();
3782 host_impl_
->SetViewportSize(surface_size
);
3785 gfx::Vector2d
scroll_delta(0, -10);
3786 EXPECT_EQ(InputHandler::ScrollStarted
,
3787 host_impl_
->ScrollBegin(gfx::Point(),
3788 InputHandler::NonBubblingGesture
));
3789 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3790 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3791 host_impl_
->ScrollEnd();
3793 // The next time we scroll we should only scroll the parent, but overscroll
3794 // should still not reach the root layer.
3795 scroll_delta
= gfx::Vector2d(0, -30);
3796 EXPECT_EQ(InputHandler::ScrollStarted
,
3797 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3798 InputHandler::NonBubblingGesture
));
3799 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3800 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3801 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3802 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3803 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3804 host_impl_
->ScrollEnd();
3806 // After scrolling the parent, another scroll on the opposite direction
3807 // should scroll the child.
3808 scroll_delta
= gfx::Vector2d(0, 70);
3809 EXPECT_EQ(InputHandler::ScrollStarted
,
3810 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3811 InputHandler::NonBubblingGesture
));
3812 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3813 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3814 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3815 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3816 host_impl_
->ScrollEnd();
3820 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3821 // When we try to scroll a non-scrollable child layer, the scroll delta
3822 // should be applied to one of its ancestors if possible. Overscroll should
3823 // be reflected only when it has bubbled up to the root scrolling layer.
3824 gfx::Size
surface_size(10, 10);
3825 gfx::Size
content_size(20, 20);
3826 scoped_ptr
<LayerImpl
> root_clip
=
3827 LayerImpl::Create(host_impl_
->active_tree(), 3);
3828 scoped_ptr
<LayerImpl
> root
=
3829 CreateScrollableLayer(1, content_size
, root_clip
.get());
3830 root
->SetIsContainerForFixedPositionLayers(true);
3831 scoped_ptr
<LayerImpl
> child
=
3832 CreateScrollableLayer(2, content_size
, root_clip
.get());
3834 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3835 root
->AddChild(child
.Pass());
3836 root_clip
->AddChild(root
.Pass());
3838 host_impl_
->SetViewportSize(surface_size
);
3839 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3840 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3841 host_impl_
->active_tree()->DidBecomeActive();
3844 gfx::Vector2d
scroll_delta(0, 8);
3845 EXPECT_EQ(InputHandler::ScrollStarted
,
3846 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3847 InputHandler::Wheel
));
3848 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3849 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3850 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3851 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
3852 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3853 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
3854 host_impl_
->ScrollEnd();
3858 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
3859 LayerTreeSettings settings
;
3860 CreateHostImpl(settings
, CreateOutputSurface());
3862 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
3863 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3864 clip_layer
->SetBounds(gfx::Size(50, 50));
3865 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3866 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3868 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3870 // Even though the layer can't scroll the overscroll still happens.
3871 EXPECT_EQ(InputHandler::ScrollStarted
,
3872 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3873 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3874 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3877 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
3878 gfx::Size
surface_size(980, 1439);
3879 gfx::Size
content_size(980, 1438);
3880 float device_scale_factor
= 1.5f
;
3881 scoped_ptr
<LayerImpl
> root_clip
=
3882 LayerImpl::Create(host_impl_
->active_tree(), 3);
3883 scoped_ptr
<LayerImpl
> root
=
3884 CreateScrollableLayer(1, content_size
, root_clip
.get());
3885 root
->SetIsContainerForFixedPositionLayers(true);
3886 scoped_ptr
<LayerImpl
> child
=
3887 CreateScrollableLayer(2, content_size
, root_clip
.get());
3888 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
3889 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
3890 0.326531f
, 0.326531f
, 5.f
);
3891 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3892 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3893 root
->AddChild(child
.Pass());
3894 root_clip
->AddChild(root
.Pass());
3896 host_impl_
->SetViewportSize(surface_size
);
3897 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
3898 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3899 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3900 host_impl_
->active_tree()->DidBecomeActive();
3903 // Horizontal & Vertical GlowEffect should not be applied when
3904 // content size is less then view port size. For Example Horizontal &
3905 // vertical GlowEffect should not be applied in about:blank page.
3906 EXPECT_EQ(InputHandler::ScrollStarted
,
3907 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3908 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
3909 EXPECT_EQ(gfx::Vector2dF().ToString(),
3910 host_impl_
->accumulated_root_overscroll().ToString());
3912 host_impl_
->ScrollEnd();
3916 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
3917 gfx::Size
surface_size(100, 100);
3918 gfx::Size
content_size(200, 200);
3919 scoped_ptr
<LayerImpl
> root_clip
=
3920 LayerImpl::Create(host_impl_
->active_tree(), 3);
3921 scoped_ptr
<LayerImpl
> root
=
3922 CreateScrollableLayer(1, content_size
, root_clip
.get());
3923 root
->SetIsContainerForFixedPositionLayers(true);
3924 scoped_ptr
<LayerImpl
> child
=
3925 CreateScrollableLayer(2, content_size
, root_clip
.get());
3927 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3928 root
->AddChild(child
.Pass());
3929 root_clip
->AddChild(root
.Pass());
3931 host_impl_
->SetViewportSize(surface_size
);
3932 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3933 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3934 host_impl_
->active_tree()->DidBecomeActive();
3937 // Edge glow effect should be applicable only upon reaching Edges
3938 // of the content. unnecessary glow effect calls shouldn't be
3939 // called while scrolling up without reaching the edge of the content.
3940 EXPECT_EQ(InputHandler::ScrollStarted
,
3941 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3942 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
3943 EXPECT_EQ(gfx::Vector2dF().ToString(),
3944 host_impl_
->accumulated_root_overscroll().ToString());
3945 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
3946 EXPECT_EQ(gfx::Vector2dF().ToString(),
3947 host_impl_
->accumulated_root_overscroll().ToString());
3948 host_impl_
->ScrollEnd();
3949 // unusedrootDelta should be subtracted from applied delta so that
3950 // unwanted glow effect calls are not called.
3951 EXPECT_EQ(InputHandler::ScrollStarted
,
3952 host_impl_
->ScrollBegin(gfx::Point(0, 0),
3953 InputHandler::NonBubblingGesture
));
3954 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
3955 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
3956 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3957 host_impl_
->accumulated_root_overscroll().ToString());
3959 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
3960 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3961 host_impl_
->accumulated_root_overscroll().ToString());
3962 host_impl_
->ScrollEnd();
3963 // TestCase to check kEpsilon, which prevents minute values to trigger
3964 // gloweffect without reaching edge.
3965 EXPECT_EQ(InputHandler::ScrollStarted
,
3966 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3967 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
3968 EXPECT_EQ(gfx::Vector2dF().ToString(),
3969 host_impl_
->accumulated_root_overscroll().ToString());
3970 host_impl_
->ScrollEnd();
3974 class BlendStateCheckLayer
: public LayerImpl
{
3976 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
3978 ResourceProvider
* resource_provider
) {
3979 return make_scoped_ptr(
3980 new BlendStateCheckLayer(tree_impl
, id
, resource_provider
));
3983 void AppendQuads(RenderPass
* render_pass
,
3984 const Occlusion
& occlusion_in_content_space
,
3985 AppendQuadsData
* append_quads_data
) override
{
3986 quads_appended_
= true;
3988 gfx::Rect opaque_rect
;
3989 if (contents_opaque())
3990 opaque_rect
= quad_rect_
;
3992 opaque_rect
= opaque_content_rect_
;
3993 gfx::Rect visible_quad_rect
= quad_rect_
;
3995 SharedQuadState
* shared_quad_state
=
3996 render_pass
->CreateAndAppendSharedQuadState();
3997 PopulateSharedQuadState(shared_quad_state
);
3999 TileDrawQuad
* test_blending_draw_quad
=
4000 render_pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
4001 test_blending_draw_quad
->SetNew(shared_quad_state
,
4006 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
4009 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
4010 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
4011 EXPECT_EQ(has_render_surface_
, !!render_surface());
4014 void SetExpectation(bool blend
, bool has_render_surface
) {
4016 has_render_surface_
= has_render_surface
;
4017 quads_appended_
= false;
4020 bool quads_appended() const { return quads_appended_
; }
4022 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
4023 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
4024 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
4025 opaque_content_rect_
= rect
;
4029 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
4031 ResourceProvider
* resource_provider
)
4032 : LayerImpl(tree_impl
, id
),
4034 has_render_surface_(false),
4035 quads_appended_(false),
4036 quad_rect_(5, 5, 5, 5),
4037 quad_visible_rect_(5, 5, 5, 5),
4038 resource_id_(resource_provider
->CreateResource(
4041 ResourceProvider::TextureHintImmutable
,
4043 resource_provider
->AllocateForTesting(resource_id_
);
4044 SetBounds(gfx::Size(10, 10));
4045 SetContentBounds(gfx::Size(10, 10));
4046 SetDrawsContent(true);
4050 bool has_render_surface_
;
4051 bool quads_appended_
;
4052 gfx::Rect quad_rect_
;
4053 gfx::Rect opaque_content_rect_
;
4054 gfx::Rect quad_visible_rect_
;
4055 ResourceProvider::ResourceId resource_id_
;
4058 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
4060 scoped_ptr
<LayerImpl
> root
=
4061 LayerImpl::Create(host_impl_
->active_tree(), 1);
4062 root
->SetBounds(gfx::Size(10, 10));
4063 root
->SetContentBounds(root
->bounds());
4064 root
->SetDrawsContent(false);
4065 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4067 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4070 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4072 host_impl_
->resource_provider()));
4073 BlendStateCheckLayer
* layer1
=
4074 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
4075 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
4077 LayerTreeHostImpl::FrameData frame
;
4079 // Opaque layer, drawn without blending.
4080 layer1
->SetContentsOpaque(true);
4081 layer1
->SetExpectation(false, false);
4082 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4083 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4084 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4085 EXPECT_TRUE(layer1
->quads_appended());
4086 host_impl_
->DidDrawAllLayers(frame
);
4088 // Layer with translucent content and painting, so drawn with blending.
4089 layer1
->SetContentsOpaque(false);
4090 layer1
->SetExpectation(true, false);
4091 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4092 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4093 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4094 EXPECT_TRUE(layer1
->quads_appended());
4095 host_impl_
->DidDrawAllLayers(frame
);
4097 // Layer with translucent opacity, drawn with blending.
4098 layer1
->SetContentsOpaque(true);
4099 layer1
->SetOpacity(0.5f
);
4100 layer1
->SetExpectation(true, false);
4101 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4102 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4103 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4104 EXPECT_TRUE(layer1
->quads_appended());
4105 host_impl_
->DidDrawAllLayers(frame
);
4107 // Layer with translucent opacity and painting, drawn with blending.
4108 layer1
->SetContentsOpaque(true);
4109 layer1
->SetOpacity(0.5f
);
4110 layer1
->SetExpectation(true, false);
4111 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4112 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4113 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4114 EXPECT_TRUE(layer1
->quads_appended());
4115 host_impl_
->DidDrawAllLayers(frame
);
4118 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4120 host_impl_
->resource_provider()));
4121 BlendStateCheckLayer
* layer2
=
4122 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
4123 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
4125 // 2 opaque layers, drawn without blending.
4126 layer1
->SetContentsOpaque(true);
4127 layer1
->SetOpacity(1.f
);
4128 layer1
->SetExpectation(false, false);
4129 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4130 layer2
->SetContentsOpaque(true);
4131 layer2
->SetOpacity(1.f
);
4132 layer2
->SetExpectation(false, false);
4133 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4134 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4135 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4136 EXPECT_TRUE(layer1
->quads_appended());
4137 EXPECT_TRUE(layer2
->quads_appended());
4138 host_impl_
->DidDrawAllLayers(frame
);
4140 // Parent layer with translucent content, drawn with blending.
4141 // Child layer with opaque content, drawn without blending.
4142 layer1
->SetContentsOpaque(false);
4143 layer1
->SetExpectation(true, false);
4144 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4145 layer2
->SetExpectation(false, false);
4146 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4147 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4148 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4149 EXPECT_TRUE(layer1
->quads_appended());
4150 EXPECT_TRUE(layer2
->quads_appended());
4151 host_impl_
->DidDrawAllLayers(frame
);
4153 // Parent layer with translucent content but opaque painting, drawn without
4155 // Child layer with opaque content, drawn without blending.
4156 layer1
->SetContentsOpaque(true);
4157 layer1
->SetExpectation(false, false);
4158 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4159 layer2
->SetExpectation(false, false);
4160 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4161 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4162 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4163 EXPECT_TRUE(layer1
->quads_appended());
4164 EXPECT_TRUE(layer2
->quads_appended());
4165 host_impl_
->DidDrawAllLayers(frame
);
4167 // Parent layer with translucent opacity and opaque content. Since it has a
4168 // drawing child, it's drawn to a render surface which carries the opacity,
4169 // so it's itself drawn without blending.
4170 // Child layer with opaque content, drawn without blending (parent surface
4171 // carries the inherited opacity).
4172 layer1
->SetContentsOpaque(true);
4173 layer1
->SetOpacity(0.5f
);
4174 layer1
->SetExpectation(false, true);
4175 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4176 layer2
->SetExpectation(false, false);
4177 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4178 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
4179 host_impl_
->active_tree()->root_layer());
4180 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4181 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4182 EXPECT_TRUE(layer1
->quads_appended());
4183 EXPECT_TRUE(layer2
->quads_appended());
4184 host_impl_
->DidDrawAllLayers(frame
);
4186 // Draw again, but with child non-opaque, to make sure
4187 // layer1 not culled.
4188 layer1
->SetContentsOpaque(true);
4189 layer1
->SetOpacity(1.f
);
4190 layer1
->SetExpectation(false, false);
4191 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4192 layer2
->SetContentsOpaque(true);
4193 layer2
->SetOpacity(0.5f
);
4194 layer2
->SetExpectation(true, false);
4195 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4196 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4197 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4198 EXPECT_TRUE(layer1
->quads_appended());
4199 EXPECT_TRUE(layer2
->quads_appended());
4200 host_impl_
->DidDrawAllLayers(frame
);
4202 // A second way of making the child non-opaque.
4203 layer1
->SetContentsOpaque(true);
4204 layer1
->SetOpacity(1.f
);
4205 layer1
->SetExpectation(false, false);
4206 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4207 layer2
->SetContentsOpaque(false);
4208 layer2
->SetOpacity(1.f
);
4209 layer2
->SetExpectation(true, false);
4210 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4211 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4212 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4213 EXPECT_TRUE(layer1
->quads_appended());
4214 EXPECT_TRUE(layer2
->quads_appended());
4215 host_impl_
->DidDrawAllLayers(frame
);
4217 // And when the layer says its not opaque but is painted opaque, it is not
4219 layer1
->SetContentsOpaque(true);
4220 layer1
->SetOpacity(1.f
);
4221 layer1
->SetExpectation(false, false);
4222 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4223 layer2
->SetContentsOpaque(true);
4224 layer2
->SetOpacity(1.f
);
4225 layer2
->SetExpectation(false, false);
4226 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4227 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4228 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4229 EXPECT_TRUE(layer1
->quads_appended());
4230 EXPECT_TRUE(layer2
->quads_appended());
4231 host_impl_
->DidDrawAllLayers(frame
);
4233 // Layer with partially opaque contents, drawn with blending.
4234 layer1
->SetContentsOpaque(false);
4235 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4236 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
4237 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4238 layer1
->SetExpectation(true, false);
4239 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4240 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4241 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4242 EXPECT_TRUE(layer1
->quads_appended());
4243 host_impl_
->DidDrawAllLayers(frame
);
4245 // Layer with partially opaque contents partially culled, drawn with blending.
4246 layer1
->SetContentsOpaque(false);
4247 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4248 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
4249 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4250 layer1
->SetExpectation(true, false);
4251 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4252 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4253 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4254 EXPECT_TRUE(layer1
->quads_appended());
4255 host_impl_
->DidDrawAllLayers(frame
);
4257 // Layer with partially opaque contents culled, drawn with blending.
4258 layer1
->SetContentsOpaque(false);
4259 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4260 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
4261 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4262 layer1
->SetExpectation(true, false);
4263 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4264 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4265 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4266 EXPECT_TRUE(layer1
->quads_appended());
4267 host_impl_
->DidDrawAllLayers(frame
);
4269 // Layer with partially opaque contents and translucent contents culled, drawn
4270 // without blending.
4271 layer1
->SetContentsOpaque(false);
4272 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4273 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
4274 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4275 layer1
->SetExpectation(false, false);
4276 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4277 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4278 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4279 EXPECT_TRUE(layer1
->quads_appended());
4280 host_impl_
->DidDrawAllLayers(frame
);
4283 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
4285 LayerTreeHostImplViewportCoveredTest() :
4286 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
4288 did_activate_pending_tree_(false) {}
4290 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
4292 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d();
4294 return FakeOutputSurface::Create3d();
4297 void SetupActiveTreeLayers() {
4298 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
4299 host_impl_
->active_tree()->SetRootLayer(
4300 LayerImpl::Create(host_impl_
->active_tree(), 1));
4301 host_impl_
->active_tree()->root_layer()->AddChild(
4302 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4304 host_impl_
->resource_provider()));
4305 child_
= static_cast<BlendStateCheckLayer
*>(
4306 host_impl_
->active_tree()->root_layer()->children()[0]);
4307 child_
->SetExpectation(false, false);
4308 child_
->SetContentsOpaque(true);
4311 // Expect no gutter rects.
4312 void TestLayerCoversFullViewport() {
4313 gfx::Rect
layer_rect(viewport_size_
);
4314 child_
->SetPosition(layer_rect
.origin());
4315 child_
->SetBounds(layer_rect
.size());
4316 child_
->SetContentBounds(layer_rect
.size());
4317 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4318 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4320 LayerTreeHostImpl::FrameData frame
;
4321 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4322 ASSERT_EQ(1u, frame
.render_passes
.size());
4324 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4325 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4326 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4328 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4329 host_impl_
->DidDrawAllLayers(frame
);
4332 // Expect fullscreen gutter rect.
4333 void TestEmptyLayer() {
4334 gfx::Rect
layer_rect(0, 0, 0, 0);
4335 child_
->SetPosition(layer_rect
.origin());
4336 child_
->SetBounds(layer_rect
.size());
4337 child_
->SetContentBounds(layer_rect
.size());
4338 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4339 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4341 LayerTreeHostImpl::FrameData frame
;
4342 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4343 ASSERT_EQ(1u, frame
.render_passes
.size());
4345 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4346 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4347 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4349 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4350 host_impl_
->DidDrawAllLayers(frame
);
4353 // Expect four surrounding gutter rects.
4354 void TestLayerInMiddleOfViewport() {
4355 gfx::Rect
layer_rect(500, 500, 200, 200);
4356 child_
->SetPosition(layer_rect
.origin());
4357 child_
->SetBounds(layer_rect
.size());
4358 child_
->SetContentBounds(layer_rect
.size());
4359 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4360 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4362 LayerTreeHostImpl::FrameData frame
;
4363 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4364 ASSERT_EQ(1u, frame
.render_passes
.size());
4366 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4367 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
4368 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4370 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4371 host_impl_
->DidDrawAllLayers(frame
);
4374 // Expect no gutter rects.
4375 void TestLayerIsLargerThanViewport() {
4376 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
4377 viewport_size_
.height() + 10);
4378 child_
->SetPosition(layer_rect
.origin());
4379 child_
->SetBounds(layer_rect
.size());
4380 child_
->SetContentBounds(layer_rect
.size());
4381 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4382 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4384 LayerTreeHostImpl::FrameData frame
;
4385 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4386 ASSERT_EQ(1u, frame
.render_passes
.size());
4388 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4389 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4390 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4392 host_impl_
->DidDrawAllLayers(frame
);
4395 void DidActivateSyncTree() override
{ did_activate_pending_tree_
= true; }
4397 void set_gutter_quad_material(DrawQuad::Material material
) {
4398 gutter_quad_material_
= material
;
4400 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
4401 gutter_texture_size_
= gutter_texture_size
;
4405 size_t CountGutterQuads(const QuadList
& quad_list
) {
4406 size_t num_gutter_quads
= 0;
4407 for (const auto& quad
: quad_list
) {
4408 num_gutter_quads
+= (quad
->material
== gutter_quad_material_
) ? 1 : 0;
4410 return num_gutter_quads
;
4413 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
4414 LayerTestCommon::VerifyQuadsExactlyCoverRect(
4415 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
4418 // Make sure that the texture coordinates match their expectations.
4419 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
4420 for (const auto& quad
: quad_list
) {
4421 if (quad
->material
!= DrawQuad::TEXTURE_CONTENT
)
4423 const TextureDrawQuad
* texture_quad
= TextureDrawQuad::MaterialCast(quad
);
4424 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
4425 gutter_texture_size_
, host_impl_
->device_scale_factor());
4426 EXPECT_EQ(texture_quad
->uv_top_left
.x(),
4427 texture_quad
->rect
.x() / gutter_texture_size_pixels
.width());
4428 EXPECT_EQ(texture_quad
->uv_top_left
.y(),
4429 texture_quad
->rect
.y() / gutter_texture_size_pixels
.height());
4431 texture_quad
->uv_bottom_right
.x(),
4432 texture_quad
->rect
.right() / gutter_texture_size_pixels
.width());
4434 texture_quad
->uv_bottom_right
.y(),
4435 texture_quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
4439 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
4440 return gfx::ToRoundedSize(
4441 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
4444 DrawQuad::Material gutter_quad_material_
;
4445 gfx::Size gutter_texture_size_
;
4446 gfx::Size viewport_size_
;
4447 BlendStateCheckLayer
* child_
;
4448 bool did_activate_pending_tree_
;
4451 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
4452 viewport_size_
= gfx::Size(1000, 1000);
4454 bool always_draw
= false;
4455 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4457 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4458 SetupActiveTreeLayers();
4459 TestLayerCoversFullViewport();
4461 TestLayerInMiddleOfViewport();
4462 TestLayerIsLargerThanViewport();
4465 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
4466 viewport_size_
= gfx::Size(1000, 1000);
4468 bool always_draw
= false;
4469 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4471 host_impl_
->SetDeviceScaleFactor(2.f
);
4472 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4473 SetupActiveTreeLayers();
4474 TestLayerCoversFullViewport();
4476 TestLayerInMiddleOfViewport();
4477 TestLayerIsLargerThanViewport();
4480 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
4481 viewport_size_
= gfx::Size(1000, 1000);
4483 bool always_draw
= false;
4484 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4486 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4487 SetupActiveTreeLayers();
4489 // Specify an overhang bitmap to use.
4490 bool is_opaque
= false;
4491 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
4492 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
4493 UIResourceId ui_resource_id
= 12345;
4494 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
4495 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
4496 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
4497 set_gutter_texture_size(gfx::Size(32, 32));
4499 TestLayerCoversFullViewport();
4501 TestLayerInMiddleOfViewport();
4502 TestLayerIsLargerThanViewport();
4504 // Change the resource size.
4505 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
4506 set_gutter_texture_size(gfx::Size(128, 16));
4508 TestLayerCoversFullViewport();
4510 TestLayerInMiddleOfViewport();
4511 TestLayerIsLargerThanViewport();
4513 // Change the device scale factor
4514 host_impl_
->SetDeviceScaleFactor(2.f
);
4515 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4517 TestLayerCoversFullViewport();
4519 TestLayerInMiddleOfViewport();
4520 TestLayerIsLargerThanViewport();
4523 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
4524 viewport_size_
= gfx::Size(1000, 1000);
4526 bool always_draw
= true;
4527 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4529 // Pending tree to force active_tree size invalid. Not used otherwise.
4530 host_impl_
->CreatePendingTree();
4531 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4532 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4534 SetupActiveTreeLayers();
4536 TestLayerInMiddleOfViewport();
4537 TestLayerIsLargerThanViewport();
4540 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
4541 viewport_size_
= gfx::Size(1000, 1000);
4543 bool always_draw
= true;
4544 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4546 // Set larger viewport and activate it to active tree.
4547 host_impl_
->CreatePendingTree();
4548 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4549 viewport_size_
.height() + 100);
4550 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4551 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4552 host_impl_
->ActivateSyncTree();
4553 EXPECT_TRUE(did_activate_pending_tree_
);
4554 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4556 // Shrink pending tree viewport without activating.
4557 host_impl_
->CreatePendingTree();
4558 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4559 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4561 SetupActiveTreeLayers();
4563 TestLayerInMiddleOfViewport();
4564 TestLayerIsLargerThanViewport();
4567 class FakeDrawableLayerImpl
: public LayerImpl
{
4569 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4570 return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl
, id
));
4573 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4574 : LayerImpl(tree_impl
, id
) {}
4577 // Only reshape when we know we are going to draw. Otherwise, the reshape
4578 // can leave the window at the wrong size if we never draw and the proper
4579 // viewport size is never set.
4580 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4581 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4582 scoped_ptr
<OutputSurface
> output_surface(
4583 FakeOutputSurface::Create3d(provider
));
4584 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4586 scoped_ptr
<LayerImpl
> root
=
4587 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4588 root
->SetBounds(gfx::Size(10, 10));
4589 root
->SetContentBounds(gfx::Size(10, 10));
4590 root
->SetDrawsContent(true);
4591 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4592 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4593 provider
->TestContext3d()->clear_reshape_called();
4595 LayerTreeHostImpl::FrameData frame
;
4596 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4597 host_impl_
->SetDeviceScaleFactor(1.f
);
4598 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4599 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4600 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4601 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4602 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4603 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4604 host_impl_
->DidDrawAllLayers(frame
);
4605 provider
->TestContext3d()->clear_reshape_called();
4607 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4608 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4609 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4610 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4611 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4612 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4613 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4614 host_impl_
->DidDrawAllLayers(frame
);
4615 provider
->TestContext3d()->clear_reshape_called();
4617 host_impl_
->SetDeviceScaleFactor(2.f
);
4618 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4619 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4620 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4621 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4622 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4623 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4624 host_impl_
->DidDrawAllLayers(frame
);
4625 provider
->TestContext3d()->clear_reshape_called();
4628 // Make sure damage tracking propagates all the way to the graphics context,
4629 // where it should request to swap only the sub-buffer that is damaged.
4630 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4631 scoped_refptr
<TestContextProvider
> context_provider(
4632 TestContextProvider::Create());
4633 context_provider
->BindToCurrentThread();
4634 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4636 scoped_ptr
<FakeOutputSurface
> output_surface(
4637 FakeOutputSurface::Create3d(context_provider
));
4638 FakeOutputSurface
* fake_output_surface
= output_surface
.get();
4640 // This test creates its own LayerTreeHostImpl, so
4641 // that we can force partial swap enabled.
4642 LayerTreeSettings settings
;
4643 settings
.partial_swap_enabled
= true;
4644 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4645 new TestSharedBitmapManager());
4646 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4647 LayerTreeHostImpl::Create(settings
,
4650 &stats_instrumentation_
,
4651 shared_bitmap_manager
.get(),
4654 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4655 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4657 scoped_ptr
<LayerImpl
> root
=
4658 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4659 scoped_ptr
<LayerImpl
> child
=
4660 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4661 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4662 child
->SetBounds(gfx::Size(14, 15));
4663 child
->SetContentBounds(gfx::Size(14, 15));
4664 child
->SetDrawsContent(true);
4665 root
->SetBounds(gfx::Size(500, 500));
4666 root
->SetContentBounds(gfx::Size(500, 500));
4667 root
->SetDrawsContent(true);
4668 root
->AddChild(child
.Pass());
4669 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4671 LayerTreeHostImpl::FrameData frame
;
4673 // First frame, the entire screen should get swapped.
4674 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4675 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4676 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4677 layer_tree_host_impl
->SwapBuffers(frame
);
4678 gfx::Rect
expected_swap_rect(0, 0, 500, 500);
4679 EXPECT_EQ(expected_swap_rect
.ToString(),
4680 fake_output_surface
->last_swap_rect().ToString());
4682 // Second frame, only the damaged area should get swapped. Damage should be
4683 // the union of old and new child rects.
4684 // expected damage rect: gfx::Rect(26, 28);
4685 // expected swap rect: vertically flipped, with origin at bottom left corner.
4686 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4688 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4689 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4690 host_impl_
->DidDrawAllLayers(frame
);
4691 layer_tree_host_impl
->SwapBuffers(frame
);
4693 // Make sure that partial swap is constrained to the viewport dimensions
4694 // expected damage rect: gfx::Rect(500, 500);
4695 // expected swap rect: flipped damage rect, but also clamped to viewport
4696 expected_swap_rect
= gfx::Rect(0, 500-28, 26, 28);
4697 EXPECT_EQ(expected_swap_rect
.ToString(),
4698 fake_output_surface
->last_swap_rect().ToString());
4700 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4701 // This will damage everything.
4702 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4704 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4705 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4706 host_impl_
->DidDrawAllLayers(frame
);
4707 layer_tree_host_impl
->SwapBuffers(frame
);
4709 expected_swap_rect
= gfx::Rect(0, 0, 10, 10);
4710 EXPECT_EQ(expected_swap_rect
.ToString(),
4711 fake_output_surface
->last_swap_rect().ToString());
4714 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4715 scoped_ptr
<LayerImpl
> root
=
4716 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4717 scoped_ptr
<LayerImpl
> child
=
4718 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4719 child
->SetBounds(gfx::Size(10, 10));
4720 child
->SetContentBounds(gfx::Size(10, 10));
4721 child
->SetDrawsContent(true);
4722 root
->SetBounds(gfx::Size(10, 10));
4723 root
->SetContentBounds(gfx::Size(10, 10));
4724 root
->SetDrawsContent(true);
4725 root
->SetForceRenderSurface(true);
4726 root
->AddChild(child
.Pass());
4728 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4730 LayerTreeHostImpl::FrameData frame
;
4732 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4733 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4734 EXPECT_EQ(1u, frame
.render_passes
.size());
4735 host_impl_
->DidDrawAllLayers(frame
);
4738 class FakeLayerWithQuads
: public LayerImpl
{
4740 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4741 return make_scoped_ptr(new FakeLayerWithQuads(tree_impl
, id
));
4744 void AppendQuads(RenderPass
* render_pass
,
4745 const Occlusion
& occlusion_in_content_space
,
4746 AppendQuadsData
* append_quads_data
) override
{
4747 SharedQuadState
* shared_quad_state
=
4748 render_pass
->CreateAndAppendSharedQuadState();
4749 PopulateSharedQuadState(shared_quad_state
);
4751 SkColor gray
= SkColorSetRGB(100, 100, 100);
4752 gfx::Rect
quad_rect(content_bounds());
4753 gfx::Rect
visible_quad_rect(quad_rect
);
4754 SolidColorDrawQuad
* my_quad
=
4755 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
4757 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4761 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4762 : LayerImpl(tree_impl
, id
) {}
4765 class MockContext
: public TestWebGraphicsContext3D
{
4767 MOCK_METHOD1(useProgram
, void(GLuint program
));
4768 MOCK_METHOD5(uniform4f
, void(GLint location
,
4773 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4775 GLboolean transpose
,
4776 const GLfloat
* value
));
4777 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4781 MOCK_METHOD1(enable
, void(GLenum cap
));
4782 MOCK_METHOD1(disable
, void(GLenum cap
));
4783 MOCK_METHOD4(scissor
, void(GLint x
,
4789 class MockContextHarness
{
4791 MockContext
* context_
;
4794 explicit MockContextHarness(MockContext
* context
)
4795 : context_(context
) {
4796 context_
->set_have_post_sub_buffer(true);
4798 // Catch "uninteresting" calls
4799 EXPECT_CALL(*context_
, useProgram(_
))
4802 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4805 // These are not asserted
4806 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4807 .WillRepeatedly(Return());
4809 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4810 .WillRepeatedly(Return());
4812 // Any un-sanctioned calls to enable() are OK
4813 EXPECT_CALL(*context_
, enable(_
))
4814 .WillRepeatedly(Return());
4816 // Any un-sanctioned calls to disable() are OK
4817 EXPECT_CALL(*context_
, disable(_
))
4818 .WillRepeatedly(Return());
4821 void MustDrawSolidQuad() {
4822 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
4824 .RetiresOnSaturation();
4826 EXPECT_CALL(*context_
, useProgram(_
))
4828 .RetiresOnSaturation();
4831 void MustSetScissor(int x
, int y
, int width
, int height
) {
4832 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4833 .WillRepeatedly(Return());
4835 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
4837 .WillRepeatedly(Return());
4840 void MustSetNoScissor() {
4841 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
4842 .WillRepeatedly(Return());
4844 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4847 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
4852 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
4853 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
4854 MockContext
* mock_context
= mock_context_owned
.get();
4855 MockContextHarness
harness(mock_context
);
4858 LayerTreeSettings settings
= DefaultSettings();
4859 settings
.partial_swap_enabled
= false;
4860 CreateHostImpl(settings
,
4861 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
4862 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4864 // Without partial swap, and no clipping, no scissor is set.
4865 harness
.MustDrawSolidQuad();
4866 harness
.MustSetNoScissor();
4868 LayerTreeHostImpl::FrameData frame
;
4869 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4870 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4871 host_impl_
->DidDrawAllLayers(frame
);
4873 Mock::VerifyAndClearExpectations(&mock_context
);
4875 // Without partial swap, but a layer does clip its subtree, one scissor is
4877 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
4878 harness
.MustDrawSolidQuad();
4879 harness
.MustSetScissor(0, 0, 10, 10);
4881 LayerTreeHostImpl::FrameData frame
;
4882 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4883 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4884 host_impl_
->DidDrawAllLayers(frame
);
4886 Mock::VerifyAndClearExpectations(&mock_context
);
4889 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
4890 scoped_ptr
<MockContext
> context_owned(new MockContext
);
4891 MockContext
* mock_context
= context_owned
.get();
4892 MockContextHarness
harness(mock_context
);
4894 LayerTreeSettings settings
= DefaultSettings();
4895 settings
.partial_swap_enabled
= true;
4896 CreateHostImpl(settings
, FakeOutputSurface::Create3d(context_owned
.Pass()));
4897 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4899 // The first frame is not a partially-swapped one.
4900 harness
.MustSetScissor(0, 0, 10, 10);
4901 harness
.MustDrawSolidQuad();
4903 LayerTreeHostImpl::FrameData frame
;
4904 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4905 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4906 host_impl_
->DidDrawAllLayers(frame
);
4908 Mock::VerifyAndClearExpectations(&mock_context
);
4910 // Damage a portion of the frame.
4911 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
4912 gfx::Rect(0, 0, 2, 3));
4914 // The second frame will be partially-swapped (the y coordinates are flipped).
4915 harness
.MustSetScissor(0, 7, 2, 3);
4916 harness
.MustDrawSolidQuad();
4918 LayerTreeHostImpl::FrameData frame
;
4919 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4920 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4921 host_impl_
->DidDrawAllLayers(frame
);
4923 Mock::VerifyAndClearExpectations(&mock_context
);
4926 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
4928 LayerTreeHostImplClient
* client
,
4930 SharedBitmapManager
* manager
,
4931 RenderingStatsInstrumentation
* stats_instrumentation
) {
4932 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4933 scoped_ptr
<OutputSurface
> output_surface(
4934 FakeOutputSurface::Create3d(provider
));
4935 provider
->BindToCurrentThread();
4936 provider
->TestContext3d()->set_have_post_sub_buffer(true);
4938 LayerTreeSettings settings
;
4939 settings
.partial_swap_enabled
= partial_swap
;
4940 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
4941 settings
, client
, proxy
, stats_instrumentation
, manager
, NULL
, 0);
4942 my_host_impl
->InitializeRenderer(output_surface
.Pass());
4943 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
4946 Layers are created as follows:
4948 +--------------------+
4952 | | +-------------------+
4954 | | +-------------------+
4959 +--------------------+
4961 Layers 1, 2 have render surfaces
4963 scoped_ptr
<LayerImpl
> root
=
4964 LayerImpl::Create(my_host_impl
->active_tree(), 1);
4965 scoped_ptr
<LayerImpl
> child
=
4966 LayerImpl::Create(my_host_impl
->active_tree(), 2);
4967 scoped_ptr
<LayerImpl
> grand_child
=
4968 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
4970 gfx::Rect
root_rect(0, 0, 100, 100);
4971 gfx::Rect
child_rect(10, 10, 50, 50);
4972 gfx::Rect
grand_child_rect(5, 5, 150, 150);
4974 root
->CreateRenderSurface();
4975 root
->SetPosition(root_rect
.origin());
4976 root
->SetBounds(root_rect
.size());
4977 root
->SetContentBounds(root
->bounds());
4978 root
->draw_properties().visible_content_rect
= root_rect
;
4979 root
->SetDrawsContent(false);
4980 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
4982 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
4983 child
->SetOpacity(0.5f
);
4984 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
4985 child
->SetContentBounds(child
->bounds());
4986 child
->draw_properties().visible_content_rect
= child_rect
;
4987 child
->SetDrawsContent(false);
4988 child
->SetForceRenderSurface(true);
4990 grand_child
->SetPosition(grand_child_rect
.origin());
4991 grand_child
->SetBounds(grand_child_rect
.size());
4992 grand_child
->SetContentBounds(grand_child
->bounds());
4993 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
4994 grand_child
->SetDrawsContent(true);
4996 child
->AddChild(grand_child
.Pass());
4997 root
->AddChild(child
.Pass());
4999 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
5000 return my_host_impl
.Pass();
5003 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
5004 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5005 new TestSharedBitmapManager());
5006 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5007 SetupLayersForOpacity(true,
5010 shared_bitmap_manager
.get(),
5011 &stats_instrumentation_
);
5013 LayerTreeHostImpl::FrameData frame
;
5014 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5016 // Verify all quads have been computed
5017 ASSERT_EQ(2U, frame
.render_passes
.size());
5018 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5019 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5020 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5021 frame
.render_passes
[0]->quad_list
.front()->material
);
5022 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5023 frame
.render_passes
[1]->quad_list
.front()->material
);
5025 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5026 my_host_impl
->DidDrawAllLayers(frame
);
5030 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
5031 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5032 new TestSharedBitmapManager());
5033 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5034 SetupLayersForOpacity(false,
5037 shared_bitmap_manager
.get(),
5038 &stats_instrumentation_
);
5040 LayerTreeHostImpl::FrameData frame
;
5041 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5043 // Verify all quads have been computed
5044 ASSERT_EQ(2U, frame
.render_passes
.size());
5045 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5046 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5047 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5048 frame
.render_passes
[0]->quad_list
.front()->material
);
5049 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5050 frame
.render_passes
[1]->quad_list
.front()->material
);
5052 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5053 my_host_impl
->DidDrawAllLayers(frame
);
5057 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
5058 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5059 TestWebGraphicsContext3D::Create();
5060 TestWebGraphicsContext3D
* context3d
= context
.get();
5061 scoped_ptr
<OutputSurface
> output_surface(
5062 FakeOutputSurface::Create3d(context
.Pass()));
5063 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
5065 scoped_ptr
<LayerImpl
> root_layer
=
5066 LayerImpl::Create(host_impl_
->active_tree(), 1);
5067 root_layer
->SetBounds(gfx::Size(10, 10));
5069 scoped_refptr
<VideoFrame
> softwareFrame
=
5070 media::VideoFrame::CreateColorFrame(
5071 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
5072 FakeVideoFrameProvider provider
;
5073 provider
.set_frame(softwareFrame
);
5074 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
5075 host_impl_
->active_tree(), 4, &provider
, media::VIDEO_ROTATION_0
);
5076 video_layer
->SetBounds(gfx::Size(10, 10));
5077 video_layer
->SetContentBounds(gfx::Size(10, 10));
5078 video_layer
->SetDrawsContent(true);
5079 root_layer
->AddChild(video_layer
.Pass());
5081 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
5082 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
5083 io_surface_layer
->SetBounds(gfx::Size(10, 10));
5084 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
5085 io_surface_layer
->SetDrawsContent(true);
5086 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
5087 root_layer
->AddChild(io_surface_layer
.Pass());
5089 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
5091 EXPECT_EQ(0u, context3d
->NumTextures());
5093 LayerTreeHostImpl::FrameData frame
;
5094 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5095 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5096 host_impl_
->DidDrawAllLayers(frame
);
5097 host_impl_
->SwapBuffers(frame
);
5099 EXPECT_GT(context3d
->NumTextures(), 0u);
5101 // Kill the layer tree.
5102 host_impl_
->active_tree()->SetRootLayer(
5103 LayerImpl::Create(host_impl_
->active_tree(), 100));
5104 // There should be no textures left in use after.
5105 EXPECT_EQ(0u, context3d
->NumTextures());
5108 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
5110 MOCK_METHOD1(useProgram
, void(GLuint program
));
5111 MOCK_METHOD4(drawElements
, void(GLenum mode
,
5117 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
5118 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
5119 new MockDrawQuadsToFillScreenContext
);
5120 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
5123 LayerTreeSettings settings
= DefaultSettings();
5124 settings
.partial_swap_enabled
= false;
5125 CreateHostImpl(settings
,
5126 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
5127 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5128 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
5130 // Verify one quad is drawn when transparent background set is not set.
5131 host_impl_
->active_tree()->set_has_transparent_background(false);
5132 EXPECT_CALL(*mock_context
, useProgram(_
))
5134 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
5136 LayerTreeHostImpl::FrameData frame
;
5137 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5138 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5139 host_impl_
->DidDrawAllLayers(frame
);
5140 Mock::VerifyAndClearExpectations(&mock_context
);
5142 // Verify no quads are drawn when transparent background is set.
5143 host_impl_
->active_tree()->set_has_transparent_background(true);
5144 host_impl_
->SetFullRootLayerDamage();
5145 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5146 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5147 host_impl_
->DidDrawAllLayers(frame
);
5148 Mock::VerifyAndClearExpectations(&mock_context
);
5151 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
5152 set_reduce_memory_result(false);
5154 // If changing the memory limit wouldn't result in changing what was
5155 // committed, then no commit should be requested.
5156 set_reduce_memory_result(false);
5157 host_impl_
->set_max_memory_needed_bytes(
5158 host_impl_
->memory_allocation_limit_bytes() - 1);
5159 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5160 host_impl_
->memory_allocation_limit_bytes() - 1));
5161 EXPECT_FALSE(did_request_commit_
);
5162 did_request_commit_
= false;
5164 // If changing the memory limit would result in changing what was
5165 // committed, then a commit should be requested, even though nothing was
5167 set_reduce_memory_result(false);
5168 host_impl_
->set_max_memory_needed_bytes(
5169 host_impl_
->memory_allocation_limit_bytes());
5170 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5171 host_impl_
->memory_allocation_limit_bytes() - 1));
5172 EXPECT_TRUE(did_request_commit_
);
5173 did_request_commit_
= false;
5175 // Especially if changing the memory limit caused evictions, we need
5177 set_reduce_memory_result(true);
5178 host_impl_
->set_max_memory_needed_bytes(1);
5179 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5180 host_impl_
->memory_allocation_limit_bytes() - 1));
5181 EXPECT_TRUE(did_request_commit_
);
5182 did_request_commit_
= false;
5184 // But if we set it to the same value that it was before, we shouldn't
5186 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5187 host_impl_
->memory_allocation_limit_bytes()));
5188 EXPECT_FALSE(did_request_commit_
);
5191 class LayerTreeHostImplTestWithDelegatingRenderer
5192 : public LayerTreeHostImplTest
{
5194 scoped_ptr
<OutputSurface
> CreateOutputSurface() override
{
5195 return FakeOutputSurface::CreateDelegating3d();
5198 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
5199 bool expect_to_draw
= !expected_damage
.IsEmpty();
5201 LayerTreeHostImpl::FrameData frame
;
5202 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5204 if (!expect_to_draw
) {
5205 // With no damage, we don't draw, and no quads are created.
5206 ASSERT_EQ(0u, frame
.render_passes
.size());
5208 ASSERT_EQ(1u, frame
.render_passes
.size());
5210 // Verify the damage rect for the root render pass.
5211 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
5212 EXPECT_RECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
5214 // Verify the root and child layers' quads are generated and not being
5216 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
5218 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
5219 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
5220 EXPECT_RECT_EQ(expected_child_visible_rect
,
5221 root_render_pass
->quad_list
.front()->visible_rect
);
5223 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
5224 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
5225 EXPECT_RECT_EQ(expected_root_visible_rect
,
5226 root_render_pass
->quad_list
.ElementAt(1)->visible_rect
);
5229 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5230 host_impl_
->DidDrawAllLayers(frame
);
5231 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
5235 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
5236 scoped_ptr
<SolidColorLayerImpl
> root
=
5237 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5238 root
->SetPosition(gfx::PointF());
5239 root
->SetBounds(gfx::Size(10, 10));
5240 root
->SetContentBounds(gfx::Size(10, 10));
5241 root
->SetDrawsContent(true);
5243 // Child layer is in the bottom right corner.
5244 scoped_ptr
<SolidColorLayerImpl
> child
=
5245 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
5246 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
5247 child
->SetBounds(gfx::Size(1, 1));
5248 child
->SetContentBounds(gfx::Size(1, 1));
5249 child
->SetDrawsContent(true);
5250 root
->AddChild(child
.Pass());
5252 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5254 // Draw a frame. In the first frame, the entire viewport should be damaged.
5255 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
5256 DrawFrameAndTestDamage(full_frame_damage
);
5258 // The second frame has damage that doesn't touch the child layer. Its quads
5259 // should still be generated.
5260 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
5261 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
5262 DrawFrameAndTestDamage(small_damage
);
5264 // The third frame should have no damage, so no quads should be generated.
5265 gfx::Rect no_damage
;
5266 DrawFrameAndTestDamage(no_damage
);
5269 // TODO(reveman): Remove this test and the ability to prevent on demand raster
5270 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
5271 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
5272 LayerTreeSettings settings
;
5273 CreateHostImpl(settings
, CreateOutputSurface());
5274 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
5277 class FakeMaskLayerImpl
: public LayerImpl
{
5279 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
5281 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
5284 void GetContentsResourceId(ResourceProvider::ResourceId
* resource_id
,
5285 gfx::Size
* resource_size
) const override
{
5290 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
5291 : LayerImpl(tree_impl
, id
) {}
5294 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
5295 LayerTreeSettings settings
;
5296 settings
.layer_transforms_should_scale_layer_contents
= true;
5297 CreateHostImpl(settings
, CreateOutputSurface());
5301 // +-- Scaling Layer (adds a 2x scale)
5303 // +-- Content Layer
5305 scoped_ptr
<LayerImpl
> scoped_root
=
5306 LayerImpl::Create(host_impl_
->active_tree(), 1);
5307 LayerImpl
* root
= scoped_root
.get();
5308 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5310 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
5311 LayerImpl::Create(host_impl_
->active_tree(), 2);
5312 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
5313 root
->AddChild(scoped_scaling_layer
.Pass());
5315 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5316 LayerImpl::Create(host_impl_
->active_tree(), 3);
5317 LayerImpl
* content_layer
= scoped_content_layer
.get();
5318 scaling_layer
->AddChild(scoped_content_layer
.Pass());
5320 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5321 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5322 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5323 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5325 gfx::Size
root_size(100, 100);
5326 root
->SetBounds(root_size
);
5327 root
->SetContentBounds(root_size
);
5328 root
->SetPosition(gfx::PointF());
5330 gfx::Size
scaling_layer_size(50, 50);
5331 scaling_layer
->SetBounds(scaling_layer_size
);
5332 scaling_layer
->SetContentBounds(scaling_layer_size
);
5333 scaling_layer
->SetPosition(gfx::PointF());
5334 gfx::Transform scale
;
5335 scale
.Scale(2.f
, 2.f
);
5336 scaling_layer
->SetTransform(scale
);
5338 content_layer
->SetBounds(scaling_layer_size
);
5339 content_layer
->SetContentBounds(scaling_layer_size
);
5340 content_layer
->SetPosition(gfx::PointF());
5341 content_layer
->SetDrawsContent(true);
5343 mask_layer
->SetBounds(scaling_layer_size
);
5344 mask_layer
->SetContentBounds(scaling_layer_size
);
5345 mask_layer
->SetPosition(gfx::PointF());
5346 mask_layer
->SetDrawsContent(true);
5349 // Check that the tree scaling is correctly taken into account for the mask,
5350 // that should fully map onto the quad.
5351 float device_scale_factor
= 1.f
;
5352 host_impl_
->SetViewportSize(root_size
);
5353 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5355 LayerTreeHostImpl::FrameData frame
;
5356 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5358 ASSERT_EQ(1u, frame
.render_passes
.size());
5359 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5360 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5361 frame
.render_passes
[0]->quad_list
.front()->material
);
5362 const RenderPassDrawQuad
* render_pass_quad
=
5363 RenderPassDrawQuad::MaterialCast(
5364 frame
.render_passes
[0]->quad_list
.front());
5365 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5366 render_pass_quad
->rect
.ToString());
5367 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5368 render_pass_quad
->MaskUVRect().ToString());
5369 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5370 render_pass_quad
->mask_uv_scale
.ToString());
5372 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5373 host_impl_
->DidDrawAllLayers(frame
);
5377 // Applying a DSF should change the render surface size, but won't affect
5378 // which part of the mask is used.
5379 device_scale_factor
= 2.f
;
5380 gfx::Size device_viewport
=
5381 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5382 host_impl_
->SetViewportSize(device_viewport
);
5383 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5384 host_impl_
->active_tree()->set_needs_update_draw_properties();
5386 LayerTreeHostImpl::FrameData frame
;
5387 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5389 ASSERT_EQ(1u, frame
.render_passes
.size());
5390 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5391 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5392 frame
.render_passes
[0]->quad_list
.front()->material
);
5393 const RenderPassDrawQuad
* render_pass_quad
=
5394 RenderPassDrawQuad::MaterialCast(
5395 frame
.render_passes
[0]->quad_list
.front());
5396 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5397 render_pass_quad
->rect
.ToString());
5398 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5399 render_pass_quad
->MaskUVRect().ToString());
5400 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5401 render_pass_quad
->mask_uv_scale
.ToString());
5403 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5404 host_impl_
->DidDrawAllLayers(frame
);
5408 // Applying an equivalent content scale on the content layer and the mask
5409 // should still result in the same part of the mask being used.
5410 gfx::Size content_bounds
=
5411 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
5412 device_scale_factor
));
5413 content_layer
->SetContentBounds(content_bounds
);
5414 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5415 mask_layer
->SetContentBounds(content_bounds
);
5416 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5417 host_impl_
->active_tree()->set_needs_update_draw_properties();
5419 LayerTreeHostImpl::FrameData frame
;
5420 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5422 ASSERT_EQ(1u, frame
.render_passes
.size());
5423 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5424 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5425 frame
.render_passes
[0]->quad_list
.front()->material
);
5426 const RenderPassDrawQuad
* render_pass_quad
=
5427 RenderPassDrawQuad::MaterialCast(
5428 frame
.render_passes
[0]->quad_list
.front());
5429 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5430 render_pass_quad
->rect
.ToString());
5431 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5432 render_pass_quad
->MaskUVRect().ToString());
5433 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5434 render_pass_quad
->mask_uv_scale
.ToString());
5436 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5437 host_impl_
->DidDrawAllLayers(frame
);
5441 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
5442 // The mask layer has bounds 100x100 but is attached to a layer with bounds
5445 scoped_ptr
<LayerImpl
> scoped_root
=
5446 LayerImpl::Create(host_impl_
->active_tree(), 1);
5447 LayerImpl
* root
= scoped_root
.get();
5448 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5450 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5451 LayerImpl::Create(host_impl_
->active_tree(), 3);
5452 LayerImpl
* content_layer
= scoped_content_layer
.get();
5453 root
->AddChild(scoped_content_layer
.Pass());
5455 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5456 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5457 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5458 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5460 gfx::Size
root_size(100, 100);
5461 root
->SetBounds(root_size
);
5462 root
->SetContentBounds(root_size
);
5463 root
->SetPosition(gfx::PointF());
5465 gfx::Size
layer_size(50, 50);
5466 content_layer
->SetBounds(layer_size
);
5467 content_layer
->SetContentBounds(layer_size
);
5468 content_layer
->SetPosition(gfx::PointF());
5469 content_layer
->SetDrawsContent(true);
5471 gfx::Size
mask_size(100, 100);
5472 mask_layer
->SetBounds(mask_size
);
5473 mask_layer
->SetContentBounds(mask_size
);
5474 mask_layer
->SetPosition(gfx::PointF());
5475 mask_layer
->SetDrawsContent(true);
5477 // Check that the mask fills the surface.
5478 float device_scale_factor
= 1.f
;
5479 host_impl_
->SetViewportSize(root_size
);
5480 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5482 LayerTreeHostImpl::FrameData frame
;
5483 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5485 ASSERT_EQ(1u, frame
.render_passes
.size());
5486 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5487 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5488 frame
.render_passes
[0]->quad_list
.front()->material
);
5489 const RenderPassDrawQuad
* render_pass_quad
=
5490 RenderPassDrawQuad::MaterialCast(
5491 frame
.render_passes
[0]->quad_list
.front());
5492 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5493 render_pass_quad
->rect
.ToString());
5494 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5495 render_pass_quad
->MaskUVRect().ToString());
5496 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5497 render_pass_quad
->mask_uv_scale
.ToString());
5499 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5500 host_impl_
->DidDrawAllLayers(frame
);
5503 // Applying a DSF should change the render surface size, but won't affect
5504 // which part of the mask is used.
5505 device_scale_factor
= 2.f
;
5506 gfx::Size device_viewport
=
5507 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5508 host_impl_
->SetViewportSize(device_viewport
);
5509 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5510 host_impl_
->active_tree()->set_needs_update_draw_properties();
5512 LayerTreeHostImpl::FrameData frame
;
5513 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5515 ASSERT_EQ(1u, frame
.render_passes
.size());
5516 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5517 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5518 frame
.render_passes
[0]->quad_list
.front()->material
);
5519 const RenderPassDrawQuad
* render_pass_quad
=
5520 RenderPassDrawQuad::MaterialCast(
5521 frame
.render_passes
[0]->quad_list
.front());
5522 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5523 render_pass_quad
->rect
.ToString());
5524 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5525 render_pass_quad
->MaskUVRect().ToString());
5526 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5527 render_pass_quad
->mask_uv_scale
.ToString());
5529 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5530 host_impl_
->DidDrawAllLayers(frame
);
5533 // Applying an equivalent content scale on the content layer and the mask
5534 // should still result in the same part of the mask being used.
5535 gfx::Size layer_size_large
=
5536 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5537 content_layer
->SetContentBounds(layer_size_large
);
5538 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5539 gfx::Size mask_size_large
=
5540 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5541 mask_layer
->SetContentBounds(mask_size_large
);
5542 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5543 host_impl_
->active_tree()->set_needs_update_draw_properties();
5545 LayerTreeHostImpl::FrameData frame
;
5546 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5548 ASSERT_EQ(1u, frame
.render_passes
.size());
5549 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5550 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5551 frame
.render_passes
[0]->quad_list
.front()->material
);
5552 const RenderPassDrawQuad
* render_pass_quad
=
5553 RenderPassDrawQuad::MaterialCast(
5554 frame
.render_passes
[0]->quad_list
.front());
5555 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5556 render_pass_quad
->rect
.ToString());
5557 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5558 render_pass_quad
->MaskUVRect().ToString());
5559 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5560 render_pass_quad
->mask_uv_scale
.ToString());
5562 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5563 host_impl_
->DidDrawAllLayers(frame
);
5566 // Applying a different contents scale to the mask layer means it will have
5567 // a larger texture, but it should use the same tex coords to cover the
5569 mask_layer
->SetContentBounds(mask_size
);
5570 mask_layer
->SetContentsScale(1.f
, 1.f
);
5571 host_impl_
->active_tree()->set_needs_update_draw_properties();
5573 LayerTreeHostImpl::FrameData frame
;
5574 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5576 ASSERT_EQ(1u, frame
.render_passes
.size());
5577 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5578 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5579 frame
.render_passes
[0]->quad_list
.front()->material
);
5580 const RenderPassDrawQuad
* render_pass_quad
=
5581 RenderPassDrawQuad::MaterialCast(
5582 frame
.render_passes
[0]->quad_list
.front());
5583 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5584 render_pass_quad
->rect
.ToString());
5585 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5586 render_pass_quad
->MaskUVRect().ToString());
5587 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5588 render_pass_quad
->mask_uv_scale
.ToString());
5590 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5591 host_impl_
->DidDrawAllLayers(frame
);
5595 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5596 // The replica's mask layer has bounds 100x100 but the replica is of a
5597 // layer with bounds 50x50.
5599 scoped_ptr
<LayerImpl
> scoped_root
=
5600 LayerImpl::Create(host_impl_
->active_tree(), 1);
5601 LayerImpl
* root
= scoped_root
.get();
5602 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5604 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5605 LayerImpl::Create(host_impl_
->active_tree(), 3);
5606 LayerImpl
* content_layer
= scoped_content_layer
.get();
5607 root
->AddChild(scoped_content_layer
.Pass());
5609 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5610 LayerImpl::Create(host_impl_
->active_tree(), 2);
5611 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5612 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5614 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5615 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5616 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5617 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5619 gfx::Size
root_size(100, 100);
5620 root
->SetBounds(root_size
);
5621 root
->SetContentBounds(root_size
);
5622 root
->SetPosition(gfx::PointF());
5624 gfx::Size
layer_size(50, 50);
5625 content_layer
->SetBounds(layer_size
);
5626 content_layer
->SetContentBounds(layer_size
);
5627 content_layer
->SetPosition(gfx::PointF());
5628 content_layer
->SetDrawsContent(true);
5630 gfx::Size
mask_size(100, 100);
5631 mask_layer
->SetBounds(mask_size
);
5632 mask_layer
->SetContentBounds(mask_size
);
5633 mask_layer
->SetPosition(gfx::PointF());
5634 mask_layer
->SetDrawsContent(true);
5636 // Check that the mask fills the surface.
5637 float device_scale_factor
= 1.f
;
5638 host_impl_
->SetViewportSize(root_size
);
5639 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5641 LayerTreeHostImpl::FrameData frame
;
5642 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5644 ASSERT_EQ(1u, frame
.render_passes
.size());
5645 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5646 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5647 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5648 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5649 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5650 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5651 replica_quad
->rect
.ToString());
5652 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5653 replica_quad
->MaskUVRect().ToString());
5654 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5655 replica_quad
->mask_uv_scale
.ToString());
5657 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5658 host_impl_
->DidDrawAllLayers(frame
);
5661 // Applying a DSF should change the render surface size, but won't affect
5662 // which part of the mask is used.
5663 device_scale_factor
= 2.f
;
5664 gfx::Size device_viewport
=
5665 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5666 host_impl_
->SetViewportSize(device_viewport
);
5667 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5668 host_impl_
->active_tree()->set_needs_update_draw_properties();
5670 LayerTreeHostImpl::FrameData frame
;
5671 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5673 ASSERT_EQ(1u, frame
.render_passes
.size());
5674 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5675 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5676 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5677 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5678 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5679 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5680 replica_quad
->rect
.ToString());
5681 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5682 replica_quad
->MaskUVRect().ToString());
5683 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5684 replica_quad
->mask_uv_scale
.ToString());
5686 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5687 host_impl_
->DidDrawAllLayers(frame
);
5690 // Applying an equivalent content scale on the content layer and the mask
5691 // should still result in the same part of the mask being used.
5692 gfx::Size layer_size_large
=
5693 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5694 content_layer
->SetContentBounds(layer_size_large
);
5695 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5696 gfx::Size mask_size_large
=
5697 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5698 mask_layer
->SetContentBounds(mask_size_large
);
5699 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5700 host_impl_
->active_tree()->set_needs_update_draw_properties();
5702 LayerTreeHostImpl::FrameData frame
;
5703 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5705 ASSERT_EQ(1u, frame
.render_passes
.size());
5706 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5707 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5708 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5709 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5710 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5711 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5712 replica_quad
->rect
.ToString());
5713 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5714 replica_quad
->MaskUVRect().ToString());
5715 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5716 replica_quad
->mask_uv_scale
.ToString());
5718 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5719 host_impl_
->DidDrawAllLayers(frame
);
5722 // Applying a different contents scale to the mask layer means it will have
5723 // a larger texture, but it should use the same tex coords to cover the
5725 mask_layer
->SetContentBounds(mask_size
);
5726 mask_layer
->SetContentsScale(1.f
, 1.f
);
5727 host_impl_
->active_tree()->set_needs_update_draw_properties();
5729 LayerTreeHostImpl::FrameData frame
;
5730 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5732 ASSERT_EQ(1u, frame
.render_passes
.size());
5733 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5734 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5735 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5736 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5737 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5738 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5739 replica_quad
->rect
.ToString());
5740 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5741 replica_quad
->MaskUVRect().ToString());
5742 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5743 replica_quad
->mask_uv_scale
.ToString());
5745 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5746 host_impl_
->DidDrawAllLayers(frame
);
5750 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5751 // The replica is of a layer with bounds 50x50, but it has a child that causes
5752 // the surface bounds to be larger.
5754 scoped_ptr
<LayerImpl
> scoped_root
=
5755 LayerImpl::Create(host_impl_
->active_tree(), 1);
5756 LayerImpl
* root
= scoped_root
.get();
5757 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5759 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5760 LayerImpl::Create(host_impl_
->active_tree(), 2);
5761 LayerImpl
* content_layer
= scoped_content_layer
.get();
5762 root
->AddChild(scoped_content_layer
.Pass());
5764 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5765 LayerImpl::Create(host_impl_
->active_tree(), 3);
5766 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5767 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5769 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5770 LayerImpl::Create(host_impl_
->active_tree(), 4);
5771 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5772 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5774 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5775 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5776 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5777 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5779 gfx::Size
root_size(100, 100);
5780 root
->SetBounds(root_size
);
5781 root
->SetContentBounds(root_size
);
5782 root
->SetPosition(gfx::PointF());
5784 gfx::Size
layer_size(50, 50);
5785 content_layer
->SetBounds(layer_size
);
5786 content_layer
->SetContentBounds(layer_size
);
5787 content_layer
->SetPosition(gfx::PointF());
5788 content_layer
->SetDrawsContent(true);
5790 gfx::Size
child_size(50, 50);
5791 content_child_layer
->SetBounds(child_size
);
5792 content_child_layer
->SetContentBounds(child_size
);
5793 content_child_layer
->SetPosition(gfx::Point(50, 0));
5794 content_child_layer
->SetDrawsContent(true);
5796 gfx::Size
mask_size(50, 50);
5797 mask_layer
->SetBounds(mask_size
);
5798 mask_layer
->SetContentBounds(mask_size
);
5799 mask_layer
->SetPosition(gfx::PointF());
5800 mask_layer
->SetDrawsContent(true);
5802 float device_scale_factor
= 1.f
;
5803 host_impl_
->SetViewportSize(root_size
);
5804 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5806 LayerTreeHostImpl::FrameData frame
;
5807 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5809 ASSERT_EQ(1u, frame
.render_passes
.size());
5810 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5812 // The surface is 100x50.
5813 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5814 frame
.render_passes
[0]->quad_list
.front()->material
);
5815 const RenderPassDrawQuad
* render_pass_quad
=
5816 RenderPassDrawQuad::MaterialCast(
5817 frame
.render_passes
[0]->quad_list
.front());
5818 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5819 render_pass_quad
->rect
.ToString());
5821 // The mask covers the owning layer only.
5822 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5823 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5824 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5825 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5826 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5827 replica_quad
->rect
.ToString());
5828 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
5829 replica_quad
->MaskUVRect().ToString());
5830 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
5831 replica_quad
->mask_uv_scale
.ToString());
5833 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5834 host_impl_
->DidDrawAllLayers(frame
);
5837 // Move the child to (-50, 0) instead. Now the mask should be moved to still
5838 // cover the layer being replicated.
5839 content_child_layer
->SetPosition(gfx::Point(-50, 0));
5841 LayerTreeHostImpl::FrameData frame
;
5842 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5844 ASSERT_EQ(1u, frame
.render_passes
.size());
5845 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5847 // The surface is 100x50 with its origin at (-50, 0).
5848 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5849 frame
.render_passes
[0]->quad_list
.front()->material
);
5850 const RenderPassDrawQuad
* render_pass_quad
=
5851 RenderPassDrawQuad::MaterialCast(
5852 frame
.render_passes
[0]->quad_list
.front());
5853 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5854 render_pass_quad
->rect
.ToString());
5856 // The mask covers the owning layer only.
5857 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5858 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5859 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5860 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5861 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5862 replica_quad
->rect
.ToString());
5863 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
5864 replica_quad
->MaskUVRect().ToString());
5865 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
5866 replica_quad
->mask_uv_scale
.ToString());
5868 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5869 host_impl_
->DidDrawAllLayers(frame
);
5873 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
5874 // The masked layer has bounds 50x50, but it has a child that causes
5875 // the surface bounds to be larger. It also has a parent that clips the
5876 // masked layer and its surface.
5878 scoped_ptr
<LayerImpl
> scoped_root
=
5879 LayerImpl::Create(host_impl_
->active_tree(), 1);
5880 LayerImpl
* root
= scoped_root
.get();
5881 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5883 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
5884 LayerImpl::Create(host_impl_
->active_tree(), 2);
5885 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
5886 root
->AddChild(scoped_clipping_layer
.Pass());
5888 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5889 LayerImpl::Create(host_impl_
->active_tree(), 3);
5890 LayerImpl
* content_layer
= scoped_content_layer
.get();
5891 clipping_layer
->AddChild(scoped_content_layer
.Pass());
5893 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5894 LayerImpl::Create(host_impl_
->active_tree(), 4);
5895 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5896 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5898 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5899 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
5900 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5901 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5903 gfx::Size
root_size(100, 100);
5904 root
->SetBounds(root_size
);
5905 root
->SetContentBounds(root_size
);
5906 root
->SetPosition(gfx::PointF());
5908 gfx::Rect
clipping_rect(20, 10, 10, 20);
5909 clipping_layer
->SetBounds(clipping_rect
.size());
5910 clipping_layer
->SetContentBounds(clipping_rect
.size());
5911 clipping_layer
->SetPosition(clipping_rect
.origin());
5912 clipping_layer
->SetMasksToBounds(true);
5914 gfx::Size
layer_size(50, 50);
5915 content_layer
->SetBounds(layer_size
);
5916 content_layer
->SetContentBounds(layer_size
);
5917 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
5918 content_layer
->SetDrawsContent(true);
5920 gfx::Size
child_size(50, 50);
5921 content_child_layer
->SetBounds(child_size
);
5922 content_child_layer
->SetContentBounds(child_size
);
5923 content_child_layer
->SetPosition(gfx::Point(50, 0));
5924 content_child_layer
->SetDrawsContent(true);
5926 gfx::Size
mask_size(100, 100);
5927 mask_layer
->SetBounds(mask_size
);
5928 mask_layer
->SetContentBounds(mask_size
);
5929 mask_layer
->SetPosition(gfx::PointF());
5930 mask_layer
->SetDrawsContent(true);
5932 float device_scale_factor
= 1.f
;
5933 host_impl_
->SetViewportSize(root_size
);
5934 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5936 LayerTreeHostImpl::FrameData frame
;
5937 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5939 ASSERT_EQ(1u, frame
.render_passes
.size());
5940 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5942 // The surface is clipped to 10x20.
5943 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5944 frame
.render_passes
[0]->quad_list
.front()->material
);
5945 const RenderPassDrawQuad
* render_pass_quad
=
5946 RenderPassDrawQuad::MaterialCast(
5947 frame
.render_passes
[0]->quad_list
.front());
5948 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5949 render_pass_quad
->rect
.ToString());
5950 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5951 // coords in the mask are scaled by 10/50 and 20/50.
5952 // The surface is clipped to (20,10) so the mask texture coords are offset
5953 // by 20/50 and 10/50
5954 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
), 1.f
/ 50.f
)
5956 render_pass_quad
->MaskUVRect().ToString());
5957 EXPECT_EQ(gfx::Vector2dF(10.f
/ 50.f
, 20.f
/ 50.f
).ToString(),
5958 render_pass_quad
->mask_uv_scale
.ToString());
5960 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5961 host_impl_
->DidDrawAllLayers(frame
);
5965 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
5967 using GLRenderer::SetupQuadForAntialiasing
;
5970 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
5971 // Due to precision issues (especially on Android), sometimes far
5972 // away quads can end up thinking they need AA.
5973 float device_scale_factor
= 4.f
/ 3.f
;
5974 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5975 gfx::Size
root_size(2000, 1000);
5976 gfx::Size device_viewport_size
=
5977 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5978 host_impl_
->SetViewportSize(device_viewport_size
);
5980 host_impl_
->CreatePendingTree();
5981 host_impl_
->pending_tree()
5982 ->SetPageScaleFactorAndLimits(1.f
, 1.f
/ 16.f
, 16.f
);
5984 scoped_ptr
<LayerImpl
> scoped_root
=
5985 LayerImpl::Create(host_impl_
->pending_tree(), 1);
5986 LayerImpl
* root
= scoped_root
.get();
5988 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
5990 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
5991 LayerImpl::Create(host_impl_
->pending_tree(), 2);
5992 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
5993 root
->AddChild(scoped_scrolling_layer
.Pass());
5995 gfx::Size
content_layer_bounds(100000, 100);
5996 gfx::Size
pile_tile_size(3000, 3000);
5997 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
5998 pile_tile_size
, content_layer_bounds
));
6000 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
6001 FakePictureLayerImpl::CreateWithPile(host_impl_
->pending_tree(), 3, pile
);
6002 LayerImpl
* content_layer
= scoped_content_layer
.get();
6003 scrolling_layer
->AddChild(scoped_content_layer
.Pass());
6004 content_layer
->SetBounds(content_layer_bounds
);
6005 content_layer
->SetDrawsContent(true);
6007 root
->SetBounds(root_size
);
6009 gfx::ScrollOffset
scroll_offset(100000, 0);
6010 scrolling_layer
->SetScrollClipLayer(root
->id());
6011 scrolling_layer
->SetScrollOffset(scroll_offset
);
6013 host_impl_
->ActivateSyncTree();
6015 host_impl_
->active_tree()->UpdateDrawProperties();
6016 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
6018 LayerTreeHostImpl::FrameData frame
;
6019 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6021 ASSERT_EQ(1u, frame
.render_passes
.size());
6022 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
6023 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
.front();
6025 bool force_aa
= false;
6027 gfx::QuadF device_layer_quad
;
6029 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
6030 quad
->quadTransform(), quad
, force_aa
, &device_layer_quad
, edge
);
6031 EXPECT_FALSE(antialiased
);
6033 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6034 host_impl_
->DidDrawAllLayers(frame
);
6038 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
6040 CompositorFrameMetadataTest()
6041 : swap_buffers_complete_(0) {}
6043 void DidSwapBuffersCompleteOnImplThread() override
{
6044 swap_buffers_complete_
++;
6047 int swap_buffers_complete_
;
6050 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
6051 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
6053 LayerTreeHostImpl::FrameData frame
;
6054 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6055 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
6056 host_impl_
->DidDrawAllLayers(frame
);
6058 CompositorFrameAck ack
;
6059 host_impl_
->ReclaimResources(&ack
);
6060 host_impl_
->DidSwapBuffersComplete();
6061 EXPECT_EQ(swap_buffers_complete_
, 1);
6064 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
6066 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
6068 SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) override
{
6070 return SoftwareOutputDevice::BeginPaint(damage_rect
);
6072 void EndPaint(SoftwareFrameData
* frame_data
) override
{
6074 SoftwareOutputDevice::EndPaint(frame_data
);
6077 int frames_began_
, frames_ended_
;
6080 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
6081 // No main thread evictions in resourceless software mode.
6082 set_reduce_memory_result(false);
6083 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
6084 bool delegated_rendering
= false;
6085 FakeOutputSurface
* output_surface
=
6086 FakeOutputSurface::CreateDeferredGL(
6087 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
6088 delegated_rendering
).release();
6089 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6090 scoped_ptr
<OutputSurface
>(output_surface
)));
6091 host_impl_
->SetViewportSize(gfx::Size(50, 50));
6093 SetupScrollAndContentsLayers(gfx::Size(100, 100));
6095 const gfx::Transform external_transform
;
6096 const gfx::Rect external_viewport
;
6097 const gfx::Rect external_clip
;
6098 const bool resourceless_software_draw
= true;
6099 host_impl_
->SetExternalDrawConstraints(external_transform
,
6104 resourceless_software_draw
);
6106 EXPECT_EQ(0, software_device
->frames_began_
);
6107 EXPECT_EQ(0, software_device
->frames_ended_
);
6111 EXPECT_EQ(1, software_device
->frames_began_
);
6112 EXPECT_EQ(1, software_device
->frames_ended_
);
6114 // Call other API methods that are likely to hit NULL pointer in this mode.
6115 EXPECT_TRUE(host_impl_
->AsValue().get());
6116 EXPECT_TRUE(host_impl_
->ActivationStateAsValue().get());
6119 TEST_F(LayerTreeHostImplTest
,
6120 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
6121 set_reduce_memory_result(false);
6122 bool delegated_rendering
= false;
6123 FakeOutputSurface
* output_surface
=
6124 FakeOutputSurface::CreateDeferredGL(
6125 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6126 delegated_rendering
).release();
6127 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6128 scoped_ptr
<OutputSurface
>(output_surface
)));
6130 const gfx::Transform external_transform
;
6131 const gfx::Rect external_viewport
;
6132 const gfx::Rect external_clip
;
6133 const bool resourceless_software_draw
= true;
6134 host_impl_
->SetExternalDrawConstraints(external_transform
,
6139 resourceless_software_draw
);
6141 // SolidColorLayerImpl will be drawn.
6142 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6143 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6145 // VideoLayerImpl will not be drawn.
6146 FakeVideoFrameProvider provider
;
6147 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
6148 host_impl_
->active_tree(), 2, &provider
, media::VIDEO_ROTATION_0
);
6149 video_layer
->SetBounds(gfx::Size(10, 10));
6150 video_layer
->SetContentBounds(gfx::Size(10, 10));
6151 video_layer
->SetDrawsContent(true);
6152 root_layer
->AddChild(video_layer
.Pass());
6153 SetupRootLayerImpl(root_layer
.Pass());
6155 LayerTreeHostImpl::FrameData frame
;
6156 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6157 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6158 host_impl_
->DidDrawAllLayers(frame
);
6160 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
6161 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
6164 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
6166 virtual void SetUp() override
{
6167 LayerTreeHostImplTest::SetUp();
6169 set_reduce_memory_result(false);
6171 bool delegated_rendering
= false;
6172 scoped_ptr
<FakeOutputSurface
> output_surface(
6173 FakeOutputSurface::CreateDeferredGL(
6174 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6175 delegated_rendering
));
6176 output_surface_
= output_surface
.get();
6178 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), output_surface
.Pass()));
6180 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6181 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6182 SetupRootLayerImpl(root_layer
.Pass());
6184 onscreen_context_provider_
= TestContextProvider::Create();
6187 void UpdateRendererCapabilitiesOnImplThread() override
{
6188 did_update_renderer_capabilities_
= true;
6191 FakeOutputSurface
* output_surface_
;
6192 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
6193 bool did_update_renderer_capabilities_
;
6197 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
6201 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6203 // DeferredInitialize and hardware draw.
6204 did_update_renderer_capabilities_
= false;
6206 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
6207 EXPECT_EQ(onscreen_context_provider_
.get(),
6208 host_impl_
->output_surface()->context_provider());
6209 EXPECT_TRUE(did_update_renderer_capabilities_
);
6211 // Defer intialized GL draw.
6214 // Revert back to software.
6215 did_update_renderer_capabilities_
= false;
6216 output_surface_
->ReleaseGL();
6217 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6218 EXPECT_TRUE(did_update_renderer_capabilities_
);
6220 // Software draw again.
6224 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
6228 // Fail initialization of the onscreen context before the OutputSurface binds
6229 // it to the thread.
6230 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
6232 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6234 // DeferredInitialize fails.
6235 did_update_renderer_capabilities_
= false;
6237 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
6238 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6239 EXPECT_FALSE(did_update_renderer_capabilities_
);
6241 // Software draw again.
6245 // Checks that we have a non-0 default allocation if we pass a context that
6246 // doesn't support memory management extensions.
6247 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
6248 LayerTreeSettings settings
;
6249 host_impl_
= LayerTreeHostImpl::Create(settings
,
6252 &stats_instrumentation_
,
6253 shared_bitmap_manager_
.get(),
6254 gpu_memory_buffer_manager_
.get(),
6257 scoped_ptr
<OutputSurface
> output_surface(
6258 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
6259 host_impl_
->InitializeRenderer(output_surface
.Pass());
6260 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
6263 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
6264 ManagedMemoryPolicy
policy1(
6265 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
6266 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6267 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
6268 int allow_nice_to_have_cutoff_value
=
6269 ManagedMemoryPolicy::PriorityCutoffToValue(
6270 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
6271 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6272 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
6274 // GPU rasterization should be disabled by default on the tree(s)
6275 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
6276 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
6278 host_impl_
->SetVisible(true);
6279 host_impl_
->SetMemoryPolicy(policy1
);
6280 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6281 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6283 host_impl_
->SetVisible(false);
6284 EXPECT_EQ(0u, current_limit_bytes_
);
6285 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6287 host_impl_
->SetVisible(true);
6288 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6289 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6291 // Now enable GPU rasterization and test if we get nice to have cutoff,
6293 LayerTreeSettings settings
;
6294 settings
.gpu_rasterization_enabled
= true;
6295 host_impl_
= LayerTreeHostImpl::Create(
6296 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, NULL
, 0);
6297 host_impl_
->SetUseGpuRasterization(true);
6298 host_impl_
->SetVisible(true);
6299 host_impl_
->SetMemoryPolicy(policy1
);
6300 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6301 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
6303 host_impl_
->SetVisible(false);
6304 EXPECT_EQ(0u, current_limit_bytes_
);
6305 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6308 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
6309 ASSERT_TRUE(host_impl_
->active_tree());
6311 // RequiresHighResToDraw is set when new output surface is used.
6312 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6314 host_impl_
->ResetRequiresHighResToDraw();
6316 host_impl_
->SetVisible(false);
6317 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6318 host_impl_
->SetVisible(true);
6319 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6320 host_impl_
->SetVisible(false);
6321 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6323 host_impl_
->ResetRequiresHighResToDraw();
6325 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6326 host_impl_
->SetVisible(true);
6327 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6330 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
6331 ASSERT_TRUE(host_impl_
->active_tree());
6332 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
6334 // RequiresHighResToDraw is set when new output surface is used.
6335 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6337 host_impl_
->ResetRequiresHighResToDraw();
6339 host_impl_
->SetUseGpuRasterization(false);
6340 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6341 host_impl_
->SetUseGpuRasterization(true);
6342 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6343 host_impl_
->SetUseGpuRasterization(false);
6344 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6346 host_impl_
->ResetRequiresHighResToDraw();
6348 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6349 host_impl_
->SetUseGpuRasterization(true);
6350 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6353 class LayerTreeHostImplTestManageTiles
: public LayerTreeHostImplTest
{
6355 virtual void SetUp() override
{
6356 LayerTreeSettings settings
;
6357 settings
.impl_side_painting
= true;
6359 fake_host_impl_
= new FakeLayerTreeHostImpl(
6360 settings
, &proxy_
, shared_bitmap_manager_
.get());
6361 host_impl_
.reset(fake_host_impl_
);
6362 host_impl_
->InitializeRenderer(CreateOutputSurface());
6363 host_impl_
->SetViewportSize(gfx::Size(10, 10));
6366 FakeLayerTreeHostImpl
* fake_host_impl_
;
6369 TEST_F(LayerTreeHostImplTestManageTiles
, ManageTilesWhenInvisible
) {
6370 fake_host_impl_
->DidModifyTilePriorities();
6371 EXPECT_TRUE(fake_host_impl_
->manage_tiles_needed());
6372 fake_host_impl_
->SetVisible(false);
6373 EXPECT_FALSE(fake_host_impl_
->manage_tiles_needed());
6376 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
6377 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6378 TestWebGraphicsContext3D::Create();
6379 TestWebGraphicsContext3D
* context3d
= context
.get();
6380 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
6381 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
6383 EXPECT_EQ(0u, context3d
->NumTextures());
6385 UIResourceId ui_resource_id
= 1;
6386 bool is_opaque
= false;
6387 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
6388 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6389 EXPECT_EQ(1u, context3d
->NumTextures());
6390 ResourceProvider::ResourceId id1
=
6391 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6394 // Multiple requests with the same id is allowed. The previous texture is
6396 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6397 EXPECT_EQ(1u, context3d
->NumTextures());
6398 ResourceProvider::ResourceId id2
=
6399 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6401 EXPECT_NE(id1
, id2
);
6403 // Deleting invalid UIResourceId is allowed and does not change state.
6404 host_impl_
->DeleteUIResource(-1);
6405 EXPECT_EQ(1u, context3d
->NumTextures());
6407 // Should return zero for invalid UIResourceId. Number of textures should
6409 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
6410 EXPECT_EQ(1u, context3d
->NumTextures());
6412 host_impl_
->DeleteUIResource(ui_resource_id
);
6413 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
6414 EXPECT_EQ(0u, context3d
->NumTextures());
6416 // Should not change state for multiple deletion on one UIResourceId
6417 host_impl_
->DeleteUIResource(ui_resource_id
);
6418 EXPECT_EQ(0u, context3d
->NumTextures());
6421 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
6422 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6423 TestWebGraphicsContext3D::Create();
6424 TestWebGraphicsContext3D
* context3d
= context
.get();
6425 CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d());
6427 EXPECT_EQ(0u, context3d
->NumTextures());
6429 gfx::Size
size(4, 4);
6430 // SkImageInfo has no support for ETC1. The |info| below contains the right
6431 // total pixel size for the bitmap but not the right height and width. The
6432 // correct width/height are passed directly to UIResourceBitmap.
6434 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
6435 skia::RefPtr
<SkPixelRef
> pixel_ref
=
6436 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
6437 pixel_ref
->setImmutable();
6438 UIResourceBitmap
bitmap(pixel_ref
, size
);
6439 UIResourceId ui_resource_id
= 1;
6440 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6441 EXPECT_EQ(1u, context3d
->NumTextures());
6442 ResourceProvider::ResourceId id1
=
6443 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6447 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
6450 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
6451 scoped_refptr
<TestContextProvider
> context_provider
=
6452 TestContextProvider::Create();
6454 CreateHostImpl(DefaultSettings(),
6455 FakeOutputSurface::Create3d(context_provider
));
6457 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
6459 ScopedPtrVector
<CopyOutputRequest
> requests
;
6460 requests
.push_back(CopyOutputRequest::CreateRequest(
6461 base::Bind(&ShutdownReleasesContext_Callback
)));
6463 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
6465 LayerTreeHostImpl::FrameData frame
;
6466 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6467 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6468 host_impl_
->DidDrawAllLayers(frame
);
6470 // The CopyOutputResult's callback has a ref on the ContextProvider and a
6471 // texture in a texture mailbox.
6472 EXPECT_FALSE(context_provider
->HasOneRef());
6473 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
6475 host_impl_
= nullptr;
6477 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
6478 // released, and the texture deleted.
6479 EXPECT_TRUE(context_provider
->HasOneRef());
6480 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
6483 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
6484 // When flinging via touch, only the child should scroll (we should not
6486 gfx::Size
surface_size(10, 10);
6487 gfx::Size
content_size(20, 20);
6488 scoped_ptr
<LayerImpl
> root_clip
=
6489 LayerImpl::Create(host_impl_
->active_tree(), 3);
6490 scoped_ptr
<LayerImpl
> root
=
6491 CreateScrollableLayer(1, content_size
, root_clip
.get());
6492 root
->SetIsContainerForFixedPositionLayers(true);
6493 scoped_ptr
<LayerImpl
> child
=
6494 CreateScrollableLayer(2, content_size
, root_clip
.get());
6496 root
->AddChild(child
.Pass());
6497 int root_id
= root
->id();
6498 root_clip
->AddChild(root
.Pass());
6500 host_impl_
->SetViewportSize(surface_size
);
6501 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6502 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
6503 host_impl_
->active_tree()->DidBecomeActive();
6506 EXPECT_EQ(InputHandler::ScrollStarted
,
6507 host_impl_
->ScrollBegin(gfx::Point(),
6508 InputHandler::Gesture
));
6510 EXPECT_EQ(InputHandler::ScrollStarted
,
6511 host_impl_
->FlingScrollBegin());
6513 gfx::Vector2d
scroll_delta(0, 100);
6514 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6515 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6517 host_impl_
->ScrollEnd();
6519 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6520 host_impl_
->ProcessScrollDeltas();
6522 // Only the child should have scrolled.
6523 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6524 ExpectNone(*scroll_info
.get(), root_id
);
6528 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
6529 // Scroll a child layer beyond its maximum scroll range and make sure the
6530 // the scroll doesn't bubble up to the parent layer.
6531 gfx::Size
surface_size(10, 10);
6532 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
6533 scoped_ptr
<LayerImpl
> root_scrolling
=
6534 CreateScrollableLayer(2, surface_size
, root
.get());
6536 scoped_ptr
<LayerImpl
> grand_child
=
6537 CreateScrollableLayer(4, surface_size
, root
.get());
6538 grand_child
->SetScrollOffset(gfx::ScrollOffset(0, 2));
6540 scoped_ptr
<LayerImpl
> child
=
6541 CreateScrollableLayer(3, surface_size
, root
.get());
6542 child
->SetScrollOffset(gfx::ScrollOffset(0, 4));
6543 child
->AddChild(grand_child
.Pass());
6545 root_scrolling
->AddChild(child
.Pass());
6546 root
->AddChild(root_scrolling
.Pass());
6547 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6548 host_impl_
->active_tree()->DidBecomeActive();
6549 host_impl_
->SetViewportSize(surface_size
);
6552 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
6554 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
6555 LayerImpl
* grand_child
= child
->children()[0];
6557 gfx::Vector2d
scroll_delta(0, -2);
6558 EXPECT_EQ(InputHandler::ScrollStarted
,
6559 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6560 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6562 // The grand child should have scrolled up to its limit.
6563 scroll_info
= host_impl_
->ProcessScrollDeltas();
6564 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6565 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6566 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6568 // The child should have received the bubbled delta, but the locked
6569 // scrolling layer should remain set as the grand child.
6570 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6571 scroll_info
= host_impl_
->ProcessScrollDeltas();
6572 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6573 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6574 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
6575 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6577 // The first |ScrollBy| after the fling should re-lock the scrolling
6578 // layer to the first layer that scrolled, which is the child.
6579 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6580 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6581 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6583 // The child should have scrolled up to its limit.
6584 scroll_info
= host_impl_
->ProcessScrollDeltas();
6585 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6586 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6587 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
6589 // As the locked layer is at it's limit, no further scrolling can occur.
6590 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6591 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6592 host_impl_
->ScrollEnd();
6596 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
6597 // When flinging via wheel, the root should eventually scroll (we should
6599 gfx::Size
surface_size(10, 10);
6600 gfx::Size
content_size(20, 20);
6601 scoped_ptr
<LayerImpl
> root_clip
=
6602 LayerImpl::Create(host_impl_
->active_tree(), 3);
6603 scoped_ptr
<LayerImpl
> root_scroll
=
6604 CreateScrollableLayer(1, content_size
, root_clip
.get());
6605 int root_scroll_id
= root_scroll
->id();
6606 scoped_ptr
<LayerImpl
> child
=
6607 CreateScrollableLayer(2, content_size
, root_clip
.get());
6609 root_scroll
->AddChild(child
.Pass());
6610 root_clip
->AddChild(root_scroll
.Pass());
6612 host_impl_
->SetViewportSize(surface_size
);
6613 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6614 host_impl_
->active_tree()->DidBecomeActive();
6617 EXPECT_EQ(InputHandler::ScrollStarted
,
6618 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6620 EXPECT_EQ(InputHandler::ScrollStarted
,
6621 host_impl_
->FlingScrollBegin());
6623 gfx::Vector2d
scroll_delta(0, 100);
6624 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6625 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6627 host_impl_
->ScrollEnd();
6629 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6630 host_impl_
->ProcessScrollDeltas();
6632 // The root should have scrolled.
6633 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6634 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6638 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6639 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6640 // we should return ScrollUnknown.
6641 gfx::Size
content_size(100, 100);
6642 SetupScrollAndContentsLayers(content_size
);
6644 int scroll_layer_id
= 2;
6645 LayerImpl
* scroll_layer
=
6646 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6647 scroll_layer
->SetDrawsContent(true);
6649 int page_scale_layer_id
= 5;
6650 LayerImpl
* page_scale_layer
=
6651 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6653 int occluder_layer_id
= 6;
6654 scoped_ptr
<LayerImpl
> occluder_layer
=
6655 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6656 occluder_layer
->SetDrawsContent(true);
6657 occluder_layer
->SetBounds(content_size
);
6658 occluder_layer
->SetContentBounds(content_size
);
6659 occluder_layer
->SetPosition(gfx::PointF());
6661 // The parent of the occluder is *above* the scroller.
6662 page_scale_layer
->AddChild(occluder_layer
.Pass());
6666 EXPECT_EQ(InputHandler::ScrollUnknown
,
6667 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6670 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6671 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6672 // is not the first scroller we encounter when walking up from the layer, we
6673 // should also return ScrollUnknown.
6674 gfx::Size
content_size(100, 100);
6675 SetupScrollAndContentsLayers(content_size
);
6677 int scroll_layer_id
= 2;
6678 LayerImpl
* scroll_layer
=
6679 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6680 scroll_layer
->SetDrawsContent(true);
6682 int occluder_layer_id
= 6;
6683 scoped_ptr
<LayerImpl
> occluder_layer
=
6684 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6685 occluder_layer
->SetDrawsContent(true);
6686 occluder_layer
->SetBounds(content_size
);
6687 occluder_layer
->SetContentBounds(content_size
);
6688 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6690 int child_scroll_clip_layer_id
= 7;
6691 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6692 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6694 int child_scroll_layer_id
= 8;
6695 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6696 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6698 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6700 child_scroll
->AddChild(occluder_layer
.Pass());
6701 scroll_layer
->AddChild(child_scroll
.Pass());
6705 EXPECT_EQ(InputHandler::ScrollUnknown
,
6706 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6709 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6710 gfx::Size
content_size(100, 100);
6711 SetupScrollAndContentsLayers(content_size
);
6713 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6715 int scroll_layer_id
= 2;
6716 LayerImpl
* scroll_layer
=
6717 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6719 int child_scroll_layer_id
= 7;
6720 scoped_ptr
<LayerImpl
> child_scroll
=
6721 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6722 child_scroll
->SetDrawsContent(false);
6724 scroll_layer
->AddChild(child_scroll
.Pass());
6728 // We should not have scrolled |child_scroll| even though we technically "hit"
6729 // it. The reason for this is that if the scrolling the scroll would not move
6730 // any layer that is a drawn RSLL member, then we can ignore the hit.
6732 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6733 // overscrolling the inner viewport.
6734 EXPECT_EQ(InputHandler::ScrollStarted
,
6735 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6737 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6740 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6741 // This test case is very similar to the one above with one key difference:
6742 // the invisible scroller has a scroll child that is indeed draw contents.
6743 // If we attempt to initiate a gesture scroll off of the visible scroll child
6744 // we should still start the scroll child.
6745 gfx::Size
content_size(100, 100);
6746 SetupScrollAndContentsLayers(content_size
);
6748 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6750 int scroll_layer_id
= 2;
6751 LayerImpl
* scroll_layer
=
6752 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6754 int scroll_child_id
= 6;
6755 scoped_ptr
<LayerImpl
> scroll_child
=
6756 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6757 scroll_child
->SetDrawsContent(true);
6758 scroll_child
->SetBounds(content_size
);
6759 scroll_child
->SetContentBounds(content_size
);
6760 // Move the scroll child so it's not hit by our test point.
6761 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6763 int invisible_scroll_layer_id
= 7;
6764 scoped_ptr
<LayerImpl
> invisible_scroll
=
6765 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6766 invisible_scroll
->SetDrawsContent(false);
6768 int container_id
= 8;
6769 scoped_ptr
<LayerImpl
> container
=
6770 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6772 scoped_ptr
<std::set
<LayerImpl
*>> scroll_children(new std::set
<LayerImpl
*>);
6773 scroll_children
->insert(scroll_child
.get());
6774 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6776 scroll_child
->SetScrollParent(invisible_scroll
.get());
6778 container
->AddChild(invisible_scroll
.Pass());
6779 container
->AddChild(scroll_child
.Pass());
6781 scroll_layer
->AddChild(container
.Pass());
6785 // We should not have scrolled |child_scroll| even though we technically "hit"
6786 // it. The reason for this is that if the scrolling the scroll would not move
6787 // any layer that is a drawn RSLL member, then we can ignore the hit.
6789 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6790 // overscrolling the inner viewport.
6791 EXPECT_EQ(InputHandler::ScrollStarted
,
6792 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6794 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6797 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6798 // to CompositorFrameMetadata after SwapBuffers();
6799 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6800 scoped_ptr
<SolidColorLayerImpl
> root
=
6801 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6802 root
->SetPosition(gfx::PointF());
6803 root
->SetBounds(gfx::Size(10, 10));
6804 root
->SetContentBounds(gfx::Size(10, 10));
6805 root
->SetDrawsContent(true);
6807 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6809 FakeOutputSurface
* fake_output_surface
=
6810 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6812 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6813 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6814 EXPECT_TRUE(metadata_latency_before
.empty());
6816 ui::LatencyInfo latency_info
;
6817 latency_info
.AddLatencyNumber(
6818 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6819 scoped_ptr
<SwapPromise
> swap_promise(
6820 new LatencyInfoSwapPromise(latency_info
));
6821 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
6822 host_impl_
->SetNeedsRedraw();
6824 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6825 LayerTreeHostImpl::FrameData frame
;
6826 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6827 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6828 host_impl_
->DidDrawAllLayers(frame
);
6829 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6831 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
6832 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6833 EXPECT_EQ(1u, metadata_latency_after
.size());
6834 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
6835 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
6838 TEST_F(LayerTreeHostImplTest
, SelectionBoundsPassedToCompositorFrameMetadata
) {
6839 int root_layer_id
= 1;
6840 scoped_ptr
<SolidColorLayerImpl
> root
=
6841 SolidColorLayerImpl::Create(host_impl_
->active_tree(), root_layer_id
);
6842 root
->SetPosition(gfx::PointF());
6843 root
->SetBounds(gfx::Size(10, 10));
6844 root
->SetContentBounds(gfx::Size(10, 10));
6845 root
->SetDrawsContent(true);
6847 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6849 // Ensure the default frame selection bounds are empty.
6850 FakeOutputSurface
* fake_output_surface
=
6851 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6852 const ViewportSelectionBound
& selection_start_before
=
6853 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
6854 const ViewportSelectionBound
& selection_end_before
=
6855 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
6856 EXPECT_EQ(ViewportSelectionBound(), selection_start_before
);
6857 EXPECT_EQ(ViewportSelectionBound(), selection_end_before
);
6859 // Plumb the layer-local selection bounds.
6860 gfx::PointF
selection_top(5, 0);
6861 gfx::PointF
selection_bottom(5, 5);
6862 LayerSelectionBound start
, end
;
6863 start
.type
= SELECTION_BOUND_CENTER
;
6864 start
.layer_id
= root_layer_id
;
6865 start
.edge_bottom
= selection_bottom
;
6866 start
.edge_top
= selection_top
;
6868 host_impl_
->active_tree()->RegisterSelection(start
, end
);
6870 // Trigger a draw-swap sequence.
6871 host_impl_
->SetNeedsRedraw();
6873 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6874 LayerTreeHostImpl::FrameData frame
;
6875 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6876 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6877 host_impl_
->DidDrawAllLayers(frame
);
6878 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6880 // Ensure the selection bounds have propagated to the frame metadata.
6881 const ViewportSelectionBound
& selection_start_after
=
6882 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
6883 const ViewportSelectionBound
& selection_end_after
=
6884 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
6885 EXPECT_EQ(start
.type
, selection_start_after
.type
);
6886 EXPECT_EQ(end
.type
, selection_end_after
.type
);
6887 EXPECT_EQ(selection_bottom
, selection_start_after
.edge_bottom
);
6888 EXPECT_EQ(selection_top
, selection_start_after
.edge_top
);
6889 EXPECT_TRUE(selection_start_after
.visible
);
6890 EXPECT_TRUE(selection_start_after
.visible
);
6893 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
6895 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
6896 LayerTreeHostImpl
* layer_tree_host_impl
,
6897 int* set_needs_commit_count
,
6898 int* set_needs_redraw_count
,
6899 int* forward_to_main_count
)
6900 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
6901 set_needs_commit_count_(set_needs_commit_count
),
6902 set_needs_redraw_count_(set_needs_redraw_count
),
6903 forward_to_main_count_(forward_to_main_count
) {}
6905 ~SimpleSwapPromiseMonitor() override
{}
6907 void OnSetNeedsCommitOnMain() override
{ (*set_needs_commit_count_
)++; }
6909 void OnSetNeedsRedrawOnImpl() override
{ (*set_needs_redraw_count_
)++; }
6911 void OnForwardScrollUpdateToMainThreadOnImpl() override
{
6912 (*forward_to_main_count_
)++;
6916 int* set_needs_commit_count_
;
6917 int* set_needs_redraw_count_
;
6918 int* forward_to_main_count_
;
6921 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
6922 int set_needs_commit_count
= 0;
6923 int set_needs_redraw_count
= 0;
6924 int forward_to_main_count
= 0;
6927 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6928 new SimpleSwapPromiseMonitor(NULL
,
6930 &set_needs_commit_count
,
6931 &set_needs_redraw_count
,
6932 &forward_to_main_count
));
6933 host_impl_
->SetNeedsRedraw();
6934 EXPECT_EQ(0, set_needs_commit_count
);
6935 EXPECT_EQ(1, set_needs_redraw_count
);
6936 EXPECT_EQ(0, forward_to_main_count
);
6939 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
6941 host_impl_
->SetNeedsRedraw();
6942 EXPECT_EQ(0, set_needs_commit_count
);
6943 EXPECT_EQ(1, set_needs_redraw_count
);
6944 EXPECT_EQ(0, forward_to_main_count
);
6947 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6948 new SimpleSwapPromiseMonitor(NULL
,
6950 &set_needs_commit_count
,
6951 &set_needs_redraw_count
,
6952 &forward_to_main_count
));
6953 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
6954 EXPECT_EQ(0, set_needs_commit_count
);
6955 EXPECT_EQ(2, set_needs_redraw_count
);
6956 EXPECT_EQ(0, forward_to_main_count
);
6960 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6961 new SimpleSwapPromiseMonitor(NULL
,
6963 &set_needs_commit_count
,
6964 &set_needs_redraw_count
,
6965 &forward_to_main_count
));
6966 // Empty damage rect won't signal the monitor.
6967 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
6968 EXPECT_EQ(0, set_needs_commit_count
);
6969 EXPECT_EQ(2, set_needs_redraw_count
);
6970 EXPECT_EQ(0, forward_to_main_count
);
6974 set_needs_commit_count
= 0;
6975 set_needs_redraw_count
= 0;
6976 forward_to_main_count
= 0;
6977 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6978 new SimpleSwapPromiseMonitor(NULL
,
6980 &set_needs_commit_count
,
6981 &set_needs_redraw_count
,
6982 &forward_to_main_count
));
6983 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
6985 // Scrolling normally should not trigger any forwarding.
6986 EXPECT_EQ(InputHandler::ScrollStarted
,
6987 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6988 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
6989 host_impl_
->ScrollEnd();
6991 EXPECT_EQ(0, set_needs_commit_count
);
6992 EXPECT_EQ(1, set_needs_redraw_count
);
6993 EXPECT_EQ(0, forward_to_main_count
);
6995 // Scrolling with a scroll handler should defer the swap to the main
6997 scroll_layer
->SetHaveScrollEventHandlers(true);
6998 EXPECT_EQ(InputHandler::ScrollStarted
,
6999 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7000 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
7001 host_impl_
->ScrollEnd();
7003 EXPECT_EQ(0, set_needs_commit_count
);
7004 EXPECT_EQ(2, set_needs_redraw_count
);
7005 EXPECT_EQ(1, forward_to_main_count
);
7009 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
7011 virtual void SetUp() override
{
7012 LayerTreeSettings settings
= DefaultSettings();
7013 settings
.calculate_top_controls_position
= true;
7014 settings
.top_controls_height
= top_controls_height_
;
7015 CreateHostImpl(settings
, CreateOutputSurface());
7019 static const int top_controls_height_
;
7022 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
7024 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
7025 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7026 ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7027 host_impl_
->Animate(base::TimeTicks());
7028 EXPECT_FALSE(did_request_redraw_
);
7031 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
7032 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7033 ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7034 host_impl_
->DidChangeTopControlsPosition();
7035 EXPECT_TRUE(did_request_animate_
);
7036 EXPECT_TRUE(did_request_redraw_
);
7039 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
7040 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7041 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7042 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7043 BOTH
, SHOWN
, false);
7046 EXPECT_EQ(InputHandler::ScrollStarted
,
7047 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7048 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7049 EXPECT_EQ(gfx::Vector2dF().ToString(),
7050 scroll_layer
->TotalScrollOffset().ToString());
7052 // Scroll just the top controls and verify that the scroll succeeds.
7053 const float residue
= 10;
7054 float offset
= top_controls_height_
- residue
;
7055 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7056 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7057 EXPECT_EQ(gfx::Vector2dF().ToString(),
7058 scroll_layer
->TotalScrollOffset().ToString());
7060 // Scroll across the boundary
7061 const float content_scroll
= 20;
7062 offset
= residue
+ content_scroll
;
7063 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7064 EXPECT_EQ(-top_controls_height_
,
7065 host_impl_
->top_controls_manager()->ControlsTopOffset());
7066 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
7067 scroll_layer
->TotalScrollOffset().ToString());
7069 // Now scroll back to the top of the content
7070 offset
= -content_scroll
;
7071 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7072 EXPECT_EQ(-top_controls_height_
,
7073 host_impl_
->top_controls_manager()->ControlsTopOffset());
7074 EXPECT_EQ(gfx::Vector2dF().ToString(),
7075 scroll_layer
->TotalScrollOffset().ToString());
7077 // And scroll the top controls completely into view
7078 offset
= -top_controls_height_
;
7079 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7080 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7081 EXPECT_EQ(gfx::Vector2dF().ToString(),
7082 scroll_layer
->TotalScrollOffset().ToString());
7084 // And attempt to scroll past the end
7085 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7086 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7087 EXPECT_EQ(gfx::Vector2dF().ToString(),
7088 scroll_layer
->TotalScrollOffset().ToString());
7090 host_impl_
->ScrollEnd();
7093 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAtOrigin
) {
7094 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7095 host_impl_
->SetViewportSize(gfx::Size(100, 200));
7096 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7097 BOTH
, SHOWN
, false);
7100 EXPECT_EQ(InputHandler::ScrollStarted
,
7101 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7102 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7103 EXPECT_EQ(gfx::Vector2dF().ToString(),
7104 scroll_layer
->TotalScrollOffset().ToString());
7106 // Scroll the top controls partially.
7107 const float residue
= 35;
7108 float offset
= top_controls_height_
- residue
;
7109 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7110 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7111 EXPECT_EQ(gfx::Vector2dF().ToString(),
7112 scroll_layer
->TotalScrollOffset().ToString());
7114 did_request_redraw_
= false;
7115 did_request_animate_
= false;
7116 did_request_commit_
= false;
7118 // End the scroll while the controls are still offset from their limit.
7119 host_impl_
->ScrollEnd();
7120 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7121 EXPECT_TRUE(did_request_animate_
);
7122 EXPECT_TRUE(did_request_redraw_
);
7123 EXPECT_FALSE(did_request_commit_
);
7125 // The top controls should properly animate until finished, despite the scroll
7126 // offset being at the origin.
7127 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7128 while (did_request_animate_
) {
7129 did_request_redraw_
= false;
7130 did_request_animate_
= false;
7131 did_request_commit_
= false;
7134 host_impl_
->top_controls_manager()->ControlsTopOffset();
7136 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7137 host_impl_
->Animate(animation_time
);
7138 EXPECT_EQ(gfx::Vector2dF().ToString(),
7139 scroll_layer
->TotalScrollOffset().ToString());
7142 host_impl_
->top_controls_manager()->ControlsTopOffset();
7144 // No commit is needed as the controls are animating the content offset,
7145 // not the scroll offset.
7146 EXPECT_FALSE(did_request_commit_
);
7148 if (new_offset
!= old_offset
)
7149 EXPECT_TRUE(did_request_redraw_
);
7151 if (new_offset
!= 0) {
7152 EXPECT_TRUE(host_impl_
->top_controls_manager()->animation());
7153 EXPECT_TRUE(did_request_animate_
);
7156 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7159 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAfterScroll
) {
7160 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7161 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7162 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7163 BOTH
, SHOWN
, false);
7164 float initial_scroll_offset
= 50;
7165 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(0, initial_scroll_offset
));
7168 EXPECT_EQ(InputHandler::ScrollStarted
,
7169 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7170 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7171 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7172 scroll_layer
->TotalScrollOffset().ToString());
7174 // Scroll the top controls partially.
7175 const float residue
= 15;
7176 float offset
= top_controls_height_
- residue
;
7177 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
7178 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7179 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7180 scroll_layer
->TotalScrollOffset().ToString());
7182 did_request_redraw_
= false;
7183 did_request_animate_
= false;
7184 did_request_commit_
= false;
7186 // End the scroll while the controls are still offset from the limit.
7187 host_impl_
->ScrollEnd();
7188 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7189 EXPECT_TRUE(did_request_animate_
);
7190 EXPECT_TRUE(did_request_redraw_
);
7191 EXPECT_FALSE(did_request_commit_
);
7193 // Animate the top controls to the limit.
7194 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7195 while (did_request_animate_
) {
7196 did_request_redraw_
= false;
7197 did_request_animate_
= false;
7198 did_request_commit_
= false;
7201 host_impl_
->top_controls_manager()->ControlsTopOffset();
7203 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7204 host_impl_
->Animate(animation_time
);
7207 host_impl_
->top_controls_manager()->ControlsTopOffset();
7209 if (new_offset
!= old_offset
) {
7210 EXPECT_TRUE(did_request_redraw_
);
7211 EXPECT_TRUE(did_request_commit_
);
7214 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7217 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
7219 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
7220 const gfx::Size
& outer_viewport
,
7221 const gfx::Size
& inner_viewport
) {
7222 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
7223 const int kOuterViewportClipLayerId
= 6;
7224 const int kOuterViewportScrollLayerId
= 7;
7225 const int kInnerViewportScrollLayerId
= 2;
7226 const int kInnerViewportClipLayerId
= 4;
7227 const int kPageScaleLayerId
= 5;
7229 scoped_ptr
<LayerImpl
> inner_scroll
=
7230 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
7231 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
7232 inner_scroll
->SetScrollOffset(gfx::ScrollOffset());
7234 scoped_ptr
<LayerImpl
> inner_clip
=
7235 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
7236 inner_clip
->SetBounds(inner_viewport
);
7238 scoped_ptr
<LayerImpl
> page_scale
=
7239 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
7241 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
7242 inner_scroll
->SetBounds(outer_viewport
);
7243 inner_scroll
->SetContentBounds(outer_viewport
);
7244 inner_scroll
->SetPosition(gfx::PointF());
7246 scoped_ptr
<LayerImpl
> outer_clip
=
7247 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
7248 outer_clip
->SetBounds(outer_viewport
);
7249 outer_clip
->SetIsContainerForFixedPositionLayers(true);
7251 scoped_ptr
<LayerImpl
> outer_scroll
=
7252 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
7253 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
7254 outer_scroll
->SetScrollOffset(gfx::ScrollOffset());
7255 outer_scroll
->SetBounds(content_size
);
7256 outer_scroll
->SetContentBounds(content_size
);
7257 outer_scroll
->SetPosition(gfx::PointF());
7259 scoped_ptr
<LayerImpl
> contents
=
7260 LayerImpl::Create(layer_tree_impl
, 8);
7261 contents
->SetDrawsContent(true);
7262 contents
->SetBounds(content_size
);
7263 contents
->SetContentBounds(content_size
);
7264 contents
->SetPosition(gfx::PointF());
7266 outer_scroll
->AddChild(contents
.Pass());
7267 outer_clip
->AddChild(outer_scroll
.Pass());
7268 inner_scroll
->AddChild(outer_clip
.Pass());
7269 page_scale
->AddChild(inner_scroll
.Pass());
7270 inner_clip
->AddChild(page_scale
.Pass());
7272 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
7273 layer_tree_impl
->SetViewportLayersFromIds(kPageScaleLayerId
,
7274 kInnerViewportScrollLayerId
, kOuterViewportScrollLayerId
);
7276 host_impl_
->active_tree()->DidBecomeActive();
7280 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
7281 gfx::Size content_size
= gfx::Size(100, 160);
7282 gfx::Size outer_viewport
= gfx::Size(50, 80);
7283 gfx::Size inner_viewport
= gfx::Size(25, 40);
7285 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7287 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7288 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7291 gfx::Vector2dF inner_expected
;
7292 gfx::Vector2dF outer_expected
;
7293 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7294 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7296 // Make sure the fling goes to the outer viewport first
7297 EXPECT_EQ(InputHandler::ScrollStarted
,
7298 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7299 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7301 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
7302 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7303 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7305 host_impl_
->ScrollEnd();
7307 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7308 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7310 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
7311 EXPECT_EQ(InputHandler::ScrollStarted
,
7312 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7313 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7315 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7316 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7318 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7319 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7321 host_impl_
->ScrollEnd();
7323 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7324 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7328 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
7330 virtual void SetUp() override
{
7331 LayerTreeSettings settings
= DefaultSettings();
7332 settings
.max_memory_for_prepaint_percentage
= 50;
7333 CreateHostImpl(settings
, CreateOutputSurface());
7337 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
7338 // Set up a memory policy and percentages which could cause
7339 // 32-bit integer overflows.
7340 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
7342 // Verify implicit limits are calculated correctly with no overflows
7343 host_impl_
->SetMemoryPolicy(mem_policy
);
7344 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
7345 300u * 1024u * 1024u);
7346 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
7347 150u * 1024u * 1024u);
7350 TEST_F(LayerTreeHostImplTest
, ExternalTransformReflectedInNextDraw
) {
7351 const gfx::Size
layer_size(100, 100);
7352 gfx::Transform external_transform
;
7353 const gfx::Rect
external_viewport(layer_size
);
7354 const gfx::Rect
external_clip(layer_size
);
7355 const bool resourceless_software_draw
= false;
7356 LayerImpl
* layer
= SetupScrollAndContentsLayers(layer_size
);
7358 host_impl_
->SetExternalDrawConstraints(external_transform
,
7363 resourceless_software_draw
);
7365 EXPECT_TRANSFORMATION_MATRIX_EQ(
7366 external_transform
, layer
->draw_properties().target_space_transform
);
7368 external_transform
.Translate(20, 20);
7369 host_impl_
->SetExternalDrawConstraints(external_transform
,
7374 resourceless_software_draw
);
7376 EXPECT_TRANSFORMATION_MATRIX_EQ(
7377 external_transform
, layer
->draw_properties().target_space_transform
);
7380 TEST_F(LayerTreeHostImplTest
, ScrollAnimated
) {
7381 SetupScrollAndContentsLayers(gfx::Size(100, 200));
7384 base::TimeTicks start_time
=
7385 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
7387 EXPECT_EQ(InputHandler::ScrollStarted
,
7388 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7390 LayerImpl
* scrolling_layer
= host_impl_
->CurrentlyScrollingLayer();
7392 host_impl_
->Animate(start_time
);
7393 host_impl_
->UpdateAnimationState(true);
7395 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer
->TotalScrollOffset());
7397 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(50));
7398 host_impl_
->UpdateAnimationState(true);
7400 float y
= scrolling_layer
->TotalScrollOffset().y();
7401 EXPECT_TRUE(y
> 1 && y
< 49);
7404 EXPECT_EQ(InputHandler::ScrollStarted
,
7405 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7407 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(200));
7408 host_impl_
->UpdateAnimationState(true);
7410 y
= scrolling_layer
->TotalScrollOffset().y();
7411 EXPECT_TRUE(y
> 50 && y
< 100);
7412 EXPECT_EQ(scrolling_layer
, host_impl_
->CurrentlyScrollingLayer());
7414 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(250));
7415 host_impl_
->UpdateAnimationState(true);
7417 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
7418 scrolling_layer
->TotalScrollOffset());
7419 EXPECT_EQ(NULL
, host_impl_
->CurrentlyScrollingLayer());
7422 TEST_F(LayerTreeHostImplTest
, GetPictureLayerImplPairs
) {
7423 host_impl_
->CreatePendingTree();
7424 host_impl_
->pending_tree()->SetRootLayer(
7425 PictureLayerImpl::Create(host_impl_
->pending_tree(), 10));
7427 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
7428 LayerImpl
* pending_layer
= pending_tree
->root_layer();
7430 std::vector
<PictureLayerImpl::Pair
> layer_pairs
;
7431 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
);
7432 EXPECT_EQ(1u, layer_pairs
.size());
7433 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7434 EXPECT_EQ(nullptr, layer_pairs
[0].active
);
7436 host_impl_
->ActivateSyncTree();
7438 LayerTreeImpl
* active_tree
= host_impl_
->active_tree();
7439 LayerImpl
* active_layer
= active_tree
->root_layer();
7440 EXPECT_NE(active_tree
, pending_tree
);
7441 EXPECT_NE(active_layer
, pending_layer
);
7442 EXPECT_NE(nullptr, active_tree
);
7443 EXPECT_NE(nullptr, active_layer
);
7445 host_impl_
->CreatePendingTree();
7447 layer_pairs
.clear();
7448 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
);
7449 EXPECT_EQ(1u, layer_pairs
.size());
7450 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7451 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7453 // Activate, the active layer has no twin now.
7454 host_impl_
->ActivateSyncTree();
7456 layer_pairs
.clear();
7457 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
);
7458 EXPECT_EQ(1u, layer_pairs
.size());
7459 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7460 EXPECT_EQ(nullptr, layer_pairs
[0].pending
);
7462 // Create another layer in the pending tree that's not in the active tree. We
7463 // should get two pairs.
7464 host_impl_
->CreatePendingTree();
7465 host_impl_
->pending_tree()->root_layer()->AddChild(
7466 PictureLayerImpl::Create(host_impl_
->pending_tree(), 11));
7468 LayerImpl
* new_pending_layer
= pending_tree
->root_layer()->children()[0];
7470 layer_pairs
.clear();
7471 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
);
7472 EXPECT_EQ(2u, layer_pairs
.size());
7474 // The pair ordering is flaky, so make it consistent.
7475 if (layer_pairs
[0].active
!= active_layer
)
7476 std::swap(layer_pairs
[0], layer_pairs
[1]);
7478 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7479 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7480 EXPECT_EQ(new_pending_layer
, layer_pairs
[1].pending
);
7481 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
7484 TEST_F(LayerTreeHostImplTest
, DidBecomeActive
) {
7485 host_impl_
->CreatePendingTree();
7486 host_impl_
->ActivateSyncTree();
7487 host_impl_
->CreatePendingTree();
7489 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
7491 scoped_ptr
<FakePictureLayerImpl
> pending_layer
=
7492 FakePictureLayerImpl::Create(pending_tree
, 10);
7493 pending_layer
->DoPostCommitInitializationIfNeeded();
7494 FakePictureLayerImpl
* raw_pending_layer
= pending_layer
.get();
7495 pending_tree
->SetRootLayer(pending_layer
.Pass());
7496 ASSERT_EQ(raw_pending_layer
, pending_tree
->root_layer());
7498 EXPECT_EQ(0u, raw_pending_layer
->did_become_active_call_count());
7499 pending_tree
->DidBecomeActive();
7500 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
7502 scoped_ptr
<FakePictureLayerImpl
> mask_layer
=
7503 FakePictureLayerImpl::Create(pending_tree
, 11);
7504 mask_layer
->DoPostCommitInitializationIfNeeded();
7505 FakePictureLayerImpl
* raw_mask_layer
= mask_layer
.get();
7506 raw_pending_layer
->SetMaskLayer(mask_layer
.Pass());
7507 ASSERT_EQ(raw_mask_layer
, raw_pending_layer
->mask_layer());
7509 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
7510 EXPECT_EQ(0u, raw_mask_layer
->did_become_active_call_count());
7511 pending_tree
->DidBecomeActive();
7512 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
7513 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
7515 scoped_ptr
<FakePictureLayerImpl
> replica_layer
=
7516 FakePictureLayerImpl::Create(pending_tree
, 12);
7517 scoped_ptr
<FakePictureLayerImpl
> replica_mask_layer
=
7518 FakePictureLayerImpl::Create(pending_tree
, 13);
7519 replica_mask_layer
->DoPostCommitInitializationIfNeeded();
7520 FakePictureLayerImpl
* raw_replica_mask_layer
= replica_mask_layer
.get();
7521 replica_layer
->SetMaskLayer(replica_mask_layer
.Pass());
7522 raw_pending_layer
->SetReplicaLayer(replica_layer
.Pass());
7523 ASSERT_EQ(raw_replica_mask_layer
,
7524 raw_pending_layer
->replica_layer()->mask_layer());
7526 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
7527 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
7528 EXPECT_EQ(0u, raw_replica_mask_layer
->did_become_active_call_count());
7529 pending_tree
->DidBecomeActive();
7530 EXPECT_EQ(3u, raw_pending_layer
->did_become_active_call_count());
7531 EXPECT_EQ(2u, raw_mask_layer
->did_become_active_call_count());
7532 EXPECT_EQ(1u, raw_replica_mask_layer
->did_become_active_call_count());
7535 class LayerTreeHostImplCountingLostSurfaces
: public LayerTreeHostImplTest
{
7537 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
7538 void DidLoseOutputSurfaceOnImplThread() override
{ num_lost_surfaces_
++; }
7541 int num_lost_surfaces_
;
7544 TEST_F(LayerTreeHostImplCountingLostSurfaces
, TwiceLostSurface
) {
7545 // Really we just need at least one client notification each time
7546 // we go from having a valid output surface to not having a valid output
7548 EXPECT_EQ(0, num_lost_surfaces_
);
7549 host_impl_
->DidLoseOutputSurface();
7550 EXPECT_EQ(1, num_lost_surfaces_
);
7551 host_impl_
->DidLoseOutputSurface();
7552 EXPECT_LE(1, num_lost_surfaces_
);