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/math_util.h"
16 #include "cc/input/page_scale_animation.h"
17 #include "cc/input/top_controls_manager.h"
18 #include "cc/layers/append_quads_data.h"
19 #include "cc/layers/delegated_renderer_layer_impl.h"
20 #include "cc/layers/heads_up_display_layer_impl.h"
21 #include "cc/layers/io_surface_layer_impl.h"
22 #include "cc/layers/layer_impl.h"
23 #include "cc/layers/painted_scrollbar_layer_impl.h"
24 #include "cc/layers/render_surface_impl.h"
25 #include "cc/layers/solid_color_layer_impl.h"
26 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
27 #include "cc/layers/texture_layer_impl.h"
28 #include "cc/layers/tiled_layer_impl.h"
29 #include "cc/layers/video_layer_impl.h"
30 #include "cc/output/begin_frame_args.h"
31 #include "cc/output/compositor_frame_ack.h"
32 #include "cc/output/compositor_frame_metadata.h"
33 #include "cc/output/copy_output_request.h"
34 #include "cc/output/copy_output_result.h"
35 #include "cc/output/gl_renderer.h"
36 #include "cc/output/latency_info_swap_promise.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/layer_tree_test.h"
54 #include "cc/test/render_pass_test_common.h"
55 #include "cc/test/test_gpu_memory_buffer_manager.h"
56 #include "cc/test/test_shared_bitmap_manager.h"
57 #include "cc/test/test_web_graphics_context_3d.h"
58 #include "cc/trees/layer_tree_impl.h"
59 #include "cc/trees/single_thread_proxy.h"
60 #include "media/base/media.h"
61 #include "testing/gmock/include/gmock/gmock.h"
62 #include "testing/gtest/include/gtest/gtest.h"
63 #include "third_party/skia/include/core/SkMallocPixelRef.h"
64 #include "ui/gfx/frame_time.h"
65 #include "ui/gfx/geometry/rect_conversions.h"
66 #include "ui/gfx/geometry/size_conversions.h"
67 #include "ui/gfx/geometry/vector2d_conversions.h"
69 using ::testing::Mock
;
70 using ::testing::Return
;
71 using ::testing::AnyNumber
;
72 using ::testing::AtLeast
;
74 using media::VideoFrame
;
79 class LayerTreeHostImplTest
: public testing::Test
,
80 public LayerTreeHostImplClient
{
82 LayerTreeHostImplTest()
83 : proxy_(base::MessageLoopProxy::current(),
84 base::MessageLoopProxy::current()),
85 always_impl_thread_(&proxy_
),
86 always_main_thread_blocked_(&proxy_
),
87 shared_bitmap_manager_(new TestSharedBitmapManager
),
88 gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager
),
89 on_can_draw_state_changed_called_(false),
90 did_notify_ready_to_activate_(false),
91 did_request_commit_(false),
92 did_request_redraw_(false),
93 did_request_animate_(false),
94 did_request_prepare_tiles_(false),
95 did_complete_page_scale_animation_(false),
96 reduce_memory_result_(true),
97 current_limit_bytes_(0),
98 current_priority_cutoff_value_(0) {
99 media::InitializeMediaLibraryForTesting();
102 LayerTreeSettings
DefaultSettings() {
103 LayerTreeSettings settings
;
104 settings
.minimum_occlusion_tracking_size
= gfx::Size();
105 settings
.impl_side_painting
= true;
106 settings
.renderer_settings
.texture_id_allocation_chunk_size
= 1;
107 settings
.report_overscroll_only_for_scrollable_axes
= true;
108 settings
.use_pinch_virtual_viewport
= true;
112 void SetUp() override
{
113 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
116 void TearDown() override
{}
118 void UpdateRendererCapabilitiesOnImplThread() override
{}
119 void DidLoseOutputSurfaceOnImplThread() override
{}
120 void CommitVSyncParameters(base::TimeTicks timebase
,
121 base::TimeDelta interval
) override
{}
122 void SetEstimatedParentDrawTime(base::TimeDelta draw_time
) override
{}
123 void SetMaxSwapsPendingOnImplThread(int max
) override
{}
124 void DidSwapBuffersOnImplThread() override
{}
125 void DidSwapBuffersCompleteOnImplThread() override
{}
126 void OnCanDrawStateChanged(bool can_draw
) override
{
127 on_can_draw_state_changed_called_
= true;
129 void NotifyReadyToActivate() override
{
130 did_notify_ready_to_activate_
= true;
131 host_impl_
->ActivateSyncTree();
133 void NotifyReadyToDraw() override
{}
134 void SetNeedsRedrawOnImplThread() override
{ did_request_redraw_
= true; }
135 void SetNeedsRedrawRectOnImplThread(const gfx::Rect
& damage_rect
) override
{
136 did_request_redraw_
= true;
138 void SetNeedsAnimateOnImplThread() override
{ did_request_animate_
= true; }
139 void SetNeedsPrepareTilesOnImplThread() override
{
140 did_request_prepare_tiles_
= true;
142 void SetNeedsCommitOnImplThread() override
{ did_request_commit_
= true; }
143 void PostAnimationEventsToMainThreadOnImplThread(
144 scoped_ptr
<AnimationEventsVector
> events
) override
{}
145 bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes
,
146 int priority_cutoff
) override
{
147 current_limit_bytes_
= limit_bytes
;
148 current_priority_cutoff_value_
= priority_cutoff
;
149 return reduce_memory_result_
;
151 bool IsInsideDraw() override
{ return false; }
152 void RenewTreePriority() override
{}
153 void PostDelayedAnimationTaskOnImplThread(const base::Closure
& task
,
154 base::TimeDelta delay
) override
{
155 animation_task_
= task
;
156 requested_animation_delay_
= delay
;
158 void DidActivateSyncTree() override
{}
159 void DidPrepareTiles() override
{}
160 void DidCompletePageScaleAnimationOnImplThread() override
{
161 did_complete_page_scale_animation_
= true;
164 void set_reduce_memory_result(bool reduce_memory_result
) {
165 reduce_memory_result_
= reduce_memory_result
;
168 virtual bool CreateHostImpl(const LayerTreeSettings
& settings
,
169 scoped_ptr
<OutputSurface
> output_surface
) {
170 host_impl_
= LayerTreeHostImpl::Create(settings
,
173 &stats_instrumentation_
,
174 shared_bitmap_manager_
.get(),
175 gpu_memory_buffer_manager_
.get(),
177 bool init
= host_impl_
->InitializeRenderer(output_surface
.Pass());
178 host_impl_
->SetViewportSize(gfx::Size(10, 10));
182 void SetupRootLayerImpl(scoped_ptr
<LayerImpl
> root
) {
183 root
->SetPosition(gfx::PointF());
184 root
->SetBounds(gfx::Size(10, 10));
185 root
->SetContentBounds(gfx::Size(10, 10));
186 root
->SetDrawsContent(true);
187 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
188 root
->SetHasRenderSurface(true);
189 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
192 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
193 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
194 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
195 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
198 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
200 const gfx::Vector2dF
& scroll_delta
) {
201 int times_encountered
= 0;
203 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
204 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
206 EXPECT_VECTOR2DF_NEAR(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
,
211 ASSERT_EQ(1, times_encountered
);
214 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
215 int times_encountered
= 0;
217 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
218 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
223 ASSERT_EQ(0, times_encountered
);
226 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
227 const gfx::Size
& content_size
) {
228 const int kInnerViewportScrollLayerId
= 2;
229 const int kInnerViewportClipLayerId
= 4;
230 const int kPageScaleLayerId
= 5;
231 scoped_ptr
<LayerImpl
> root
=
232 LayerImpl::Create(layer_tree_impl
, 1);
233 root
->SetBounds(content_size
);
234 root
->SetContentBounds(content_size
);
235 root
->SetPosition(gfx::PointF());
236 root
->SetHasRenderSurface(true);
238 scoped_ptr
<LayerImpl
> scroll
=
239 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
240 LayerImpl
* scroll_layer
= scroll
.get();
241 scroll
->SetIsContainerForFixedPositionLayers(true);
242 scroll
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
244 scoped_ptr
<LayerImpl
> clip
=
245 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
247 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
249 scoped_ptr
<LayerImpl
> page_scale
=
250 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
252 scroll
->SetScrollClipLayer(clip
->id());
253 scroll
->SetBounds(content_size
);
254 scroll
->SetContentBounds(content_size
);
255 scroll
->SetPosition(gfx::PointF());
256 scroll
->SetIsContainerForFixedPositionLayers(true);
258 scoped_ptr
<LayerImpl
> contents
=
259 LayerImpl::Create(layer_tree_impl
, 3);
260 contents
->SetDrawsContent(true);
261 contents
->SetBounds(content_size
);
262 contents
->SetContentBounds(content_size
);
263 contents
->SetPosition(gfx::PointF());
265 scroll
->AddChild(contents
.Pass());
266 page_scale
->AddChild(scroll
.Pass());
267 clip
->AddChild(page_scale
.Pass());
268 root
->AddChild(clip
.Pass());
270 layer_tree_impl
->SetRootLayer(root
.Pass());
271 layer_tree_impl
->SetViewportLayersFromIds(
272 Layer::INVALID_ID
, kPageScaleLayerId
, kInnerViewportScrollLayerId
,
278 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
279 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
280 host_impl_
->active_tree(), content_size
);
281 host_impl_
->active_tree()->DidBecomeActive();
285 // TODO(wjmaclean) Add clip-layer pointer to parameters.
286 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
287 const gfx::Size
& size
,
288 LayerImpl
* clip_layer
) {
290 DCHECK(id
!= clip_layer
->id());
291 scoped_ptr
<LayerImpl
> layer
=
292 LayerImpl::Create(host_impl_
->active_tree(), id
);
293 layer
->SetScrollClipLayer(clip_layer
->id());
294 layer
->SetDrawsContent(true);
295 layer
->SetBounds(size
);
296 layer
->SetContentBounds(size
);
297 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
302 LayerTreeHostImpl::FrameData frame
;
303 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
304 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
305 host_impl_
->DidDrawAllLayers(frame
);
308 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
309 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
310 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
311 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
312 float device_scale_factor
);
314 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
315 // Note: It is not possible to disable the renderer once it has been set,
316 // so we do not need to test that disabling the renderer notifies us
317 // that can_draw changed.
318 EXPECT_FALSE(host_impl_
->CanDraw());
319 on_can_draw_state_changed_called_
= false;
321 // Set up the root layer, which allows us to draw.
322 SetupScrollAndContentsLayers(gfx::Size(100, 100));
323 EXPECT_TRUE(host_impl_
->CanDraw());
324 EXPECT_TRUE(on_can_draw_state_changed_called_
);
325 on_can_draw_state_changed_called_
= false;
327 // Toggle the root layer to make sure it toggles can_draw
328 host_impl_
->active_tree()->SetRootLayer(nullptr);
329 EXPECT_FALSE(host_impl_
->CanDraw());
330 EXPECT_TRUE(on_can_draw_state_changed_called_
);
331 on_can_draw_state_changed_called_
= false;
333 SetupScrollAndContentsLayers(gfx::Size(100, 100));
334 EXPECT_TRUE(host_impl_
->CanDraw());
335 EXPECT_TRUE(on_can_draw_state_changed_called_
);
336 on_can_draw_state_changed_called_
= false;
338 // Toggle the device viewport size to make sure it toggles can_draw.
339 host_impl_
->SetViewportSize(gfx::Size());
341 EXPECT_TRUE(host_impl_
->CanDraw());
343 EXPECT_FALSE(host_impl_
->CanDraw());
345 EXPECT_TRUE(on_can_draw_state_changed_called_
);
346 on_can_draw_state_changed_called_
= false;
348 host_impl_
->SetViewportSize(gfx::Size(100, 100));
349 EXPECT_TRUE(host_impl_
->CanDraw());
350 EXPECT_TRUE(on_can_draw_state_changed_called_
);
351 on_can_draw_state_changed_called_
= false;
353 // Toggle contents textures purged without causing any evictions,
354 // and make sure that it does not change can_draw.
355 set_reduce_memory_result(false);
356 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
357 host_impl_
->memory_allocation_limit_bytes() - 1));
358 EXPECT_TRUE(host_impl_
->CanDraw());
359 EXPECT_FALSE(on_can_draw_state_changed_called_
);
360 on_can_draw_state_changed_called_
= false;
362 // Toggle contents textures purged to make sure it toggles can_draw.
363 set_reduce_memory_result(true);
364 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
365 host_impl_
->memory_allocation_limit_bytes() - 1));
367 EXPECT_TRUE(host_impl_
->CanDraw());
369 EXPECT_FALSE(host_impl_
->CanDraw());
371 EXPECT_TRUE(on_can_draw_state_changed_called_
);
372 on_can_draw_state_changed_called_
= false;
374 host_impl_
->active_tree()->ResetContentsTexturesPurged();
375 EXPECT_TRUE(host_impl_
->CanDraw());
376 EXPECT_TRUE(on_can_draw_state_changed_called_
);
377 on_can_draw_state_changed_called_
= false;
380 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
383 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
384 return FakeOutputSurface::Create3d();
387 void DrawOneFrame() {
388 LayerTreeHostImpl::FrameData frame_data
;
389 host_impl_
->PrepareToDraw(&frame_data
);
390 host_impl_
->DidDrawAllLayers(frame_data
);
394 DebugScopedSetImplThread always_impl_thread_
;
395 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
397 scoped_ptr
<TestSharedBitmapManager
> shared_bitmap_manager_
;
398 scoped_ptr
<TestGpuMemoryBufferManager
> gpu_memory_buffer_manager_
;
399 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
400 FakeRenderingStatsInstrumentation stats_instrumentation_
;
401 bool on_can_draw_state_changed_called_
;
402 bool did_notify_ready_to_activate_
;
403 bool did_request_commit_
;
404 bool did_request_redraw_
;
405 bool did_request_animate_
;
406 bool did_request_prepare_tiles_
;
407 bool did_complete_page_scale_animation_
;
408 bool reduce_memory_result_
;
409 base::Closure animation_task_
;
410 base::TimeDelta requested_animation_delay_
;
411 size_t current_limit_bytes_
;
412 int current_priority_cutoff_value_
;
415 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
416 bool always_draw
= false;
417 CheckNotifyCalledIfCanDrawChanged(always_draw
);
420 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
421 CreateHostImpl(DefaultSettings(),
422 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
424 bool always_draw
= true;
425 CheckNotifyCalledIfCanDrawChanged(always_draw
);
428 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
429 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
431 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
432 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
435 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
437 scoped_ptr
<LayerImpl
> root
=
438 LayerImpl::Create(host_impl_
->active_tree(), 1);
439 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
440 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
441 root
->children()[1]->AddChild(
442 LayerImpl::Create(host_impl_
->active_tree(), 4));
443 root
->children()[1]->AddChild(
444 LayerImpl::Create(host_impl_
->active_tree(), 5));
445 root
->children()[1]->children()[0]->AddChild(
446 LayerImpl::Create(host_impl_
->active_tree(), 6));
447 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
449 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
451 ExpectClearedScrollDeltasRecursive(root
);
453 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
455 scroll_info
= host_impl_
->ProcessScrollDeltas();
456 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
457 ExpectClearedScrollDeltasRecursive(root
);
459 scroll_info
= host_impl_
->ProcessScrollDeltas();
460 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
461 ExpectClearedScrollDeltasRecursive(root
);
464 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
465 gfx::ScrollOffset
scroll_offset(20, 30);
466 gfx::Vector2d
scroll_delta(11, -15);
468 scoped_ptr
<LayerImpl
> root_clip
=
469 LayerImpl::Create(host_impl_
->active_tree(), 2);
470 scoped_ptr
<LayerImpl
> root
=
471 LayerImpl::Create(host_impl_
->active_tree(), 1);
472 root_clip
->SetBounds(gfx::Size(10, 10));
473 LayerImpl
* root_layer
= root
.get();
474 root_clip
->AddChild(root
.Pass());
475 root_layer
->SetBounds(gfx::Size(110, 110));
476 root_layer
->SetScrollClipLayer(root_clip
->id());
477 root_layer
->PushScrollOffsetFromMainThread(scroll_offset
);
478 root_layer
->ScrollBy(scroll_delta
);
479 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
481 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
483 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
485 scroll_info
= host_impl_
->ProcessScrollDeltas();
486 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
487 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
489 gfx::Vector2d
scroll_delta2(-5, 27);
490 root
->ScrollBy(scroll_delta2
);
491 scroll_info
= host_impl_
->ProcessScrollDeltas();
492 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
493 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
495 root
->ScrollBy(gfx::Vector2d());
496 scroll_info
= host_impl_
->ProcessScrollDeltas();
497 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
500 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
501 SetupScrollAndContentsLayers(gfx::Size(100, 100));
502 host_impl_
->SetViewportSize(gfx::Size(50, 50));
505 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
506 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
507 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
508 InputHandler::WHEEL
));
509 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
510 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
511 InputHandler::WHEEL
));
512 host_impl_
->ScrollEnd();
513 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
514 InputHandler::WHEEL
));
515 EXPECT_TRUE(did_request_redraw_
);
516 EXPECT_TRUE(did_request_commit_
);
519 TEST_F(LayerTreeHostImplTest
, ScrollActiveOnlyAfterScrollMovement
) {
520 SetupScrollAndContentsLayers(gfx::Size(100, 100));
521 host_impl_
->SetViewportSize(gfx::Size(50, 50));
524 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
525 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
526 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
527 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
528 EXPECT_TRUE(host_impl_
->IsActivelyScrolling());
529 host_impl_
->ScrollEnd();
530 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
533 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
534 // We should not crash when trying to scroll an empty layer tree.
535 EXPECT_EQ(InputHandler::SCROLL_IGNORED
,
536 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
539 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
540 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
541 TestWebGraphicsContext3D::Create();
542 context_owned
->set_context_lost(true);
544 // Initialization will fail.
545 EXPECT_FALSE(CreateHostImpl(
546 DefaultSettings(), FakeOutputSurface::Create3d(context_owned
.Pass())));
548 SetupScrollAndContentsLayers(gfx::Size(100, 100));
550 // We should not crash when trying to scroll after the renderer initialization
552 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
553 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
556 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
557 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
558 host_impl_
->SetViewportSize(gfx::Size(50, 50));
561 // We should not crash if the tree is replaced while we are scrolling.
562 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
563 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
564 host_impl_
->active_tree()->DetachLayerTree();
566 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
568 // We should still be scrolling, because the scrolled layer also exists in the
570 gfx::Vector2d
scroll_delta(0, 10);
571 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
572 host_impl_
->ScrollEnd();
573 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
574 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
577 TEST_F(LayerTreeHostImplTest
, ScrollBlocksOnWheelEventHandlers
) {
578 SetupScrollAndContentsLayers(gfx::Size(100, 100));
579 host_impl_
->SetViewportSize(gfx::Size(50, 50));
581 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
583 // With registered event handlers, wheel scrolls don't necessarily
584 // have to go to the main thread.
585 root
->SetHaveWheelEventHandlers(true);
586 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
587 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
588 host_impl_
->ScrollEnd();
590 // But typically the scroll-blocks-on mode will require them to.
591 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT
|
592 SCROLL_BLOCKS_ON_START_TOUCH
);
593 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
594 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
596 // But gesture scrolls can still be handled.
597 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
598 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
599 host_impl_
->ScrollEnd();
601 // And if the handlers go away, wheel scrolls can again be processed
602 // on impl (despite the scroll-blocks-on mode).
603 root
->SetHaveWheelEventHandlers(false);
604 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
605 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
606 host_impl_
->ScrollEnd();
609 TEST_F(LayerTreeHostImplTest
, ScrollBlocksOnTouchEventHandlers
) {
610 LayerImpl
* scroll
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
611 host_impl_
->SetViewportSize(gfx::Size(50, 50));
613 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
615 LayerImpl
* child
= 0;
617 scoped_ptr
<LayerImpl
> child_layer
=
618 LayerImpl::Create(host_impl_
->active_tree(), 6);
619 child
= child_layer
.get();
620 child_layer
->SetDrawsContent(true);
621 child_layer
->SetPosition(gfx::PointF(0, 20));
622 child_layer
->SetBounds(gfx::Size(50, 50));
623 child_layer
->SetContentBounds(gfx::Size(50, 50));
624 scroll
->AddChild(child_layer
.Pass());
627 // Touch handler regions determine whether touch events block scroll.
628 root
->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 100, 100));
629 EXPECT_FALSE(host_impl_
->DoTouchEventsBlockScrollAt(gfx::Point(10, 10)));
630 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_START_TOUCH
|
631 SCROLL_BLOCKS_ON_WHEEL_EVENT
);
632 EXPECT_TRUE(host_impl_
->DoTouchEventsBlockScrollAt(gfx::Point(10, 10)));
634 // But they don't influence the actual handling of the scroll gestures.
635 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
636 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
637 host_impl_
->ScrollEnd();
639 // It's the union of scroll-blocks-on mode bits across all layers in the
640 // scroll paret chain that matters.
641 EXPECT_TRUE(host_impl_
->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
642 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_NONE
);
643 EXPECT_FALSE(host_impl_
->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
644 child
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_START_TOUCH
);
645 EXPECT_TRUE(host_impl_
->DoTouchEventsBlockScrollAt(gfx::Point(10, 30)));
648 TEST_F(LayerTreeHostImplTest
, ScrollBlocksOnScrollEventHandlers
) {
649 SetupScrollAndContentsLayers(gfx::Size(100, 100));
650 host_impl_
->SetViewportSize(gfx::Size(50, 50));
652 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
654 // With registered scroll handlers, scrolls don't generally have to go
655 // to the main thread.
656 root
->SetHaveScrollEventHandlers(true);
657 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
658 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
659 host_impl_
->ScrollEnd();
661 // Even the default scroll blocks on mode doesn't require this.
662 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT
|
663 SCROLL_BLOCKS_ON_START_TOUCH
);
664 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
665 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
666 host_impl_
->ScrollEnd();
668 // But the page can opt in to blocking on scroll event handlers.
669 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT
);
670 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
671 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
673 // GESTURE and WHEEL scrolls behave identically in this regard.
674 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
675 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
677 // And if the handlers go away, scrolls can again be processed on impl
678 // (despite the scroll-blocks-on mode).
679 root
->SetHaveScrollEventHandlers(false);
680 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
681 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
682 host_impl_
->ScrollEnd();
685 TEST_F(LayerTreeHostImplTest
, ScrollBlocksOnLayerTopology
) {
686 host_impl_
->SetViewportSize(gfx::Size(50, 50));
688 // Create a normal scrollable root layer
689 LayerImpl
* root_scroll
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
690 LayerImpl
* root_child
= root_scroll
->children()[0];
691 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
694 // Create two child scrollable layers
695 LayerImpl
* child1
= 0;
697 scoped_ptr
<LayerImpl
> scrollable_child_clip_1
=
698 LayerImpl::Create(host_impl_
->active_tree(), 6);
699 scoped_ptr
<LayerImpl
> scrollable_child_1
= CreateScrollableLayer(
700 7, gfx::Size(10, 10), scrollable_child_clip_1
.get());
701 child1
= scrollable_child_1
.get();
702 scrollable_child_1
->SetPosition(gfx::Point(5, 5));
703 scrollable_child_1
->SetHaveWheelEventHandlers(true);
704 scrollable_child_1
->SetHaveScrollEventHandlers(true);
705 scrollable_child_clip_1
->AddChild(scrollable_child_1
.Pass());
706 root_child
->AddChild(scrollable_child_clip_1
.Pass());
709 LayerImpl
* child2
= 0;
711 scoped_ptr
<LayerImpl
> scrollable_child_clip_2
=
712 LayerImpl::Create(host_impl_
->active_tree(), 8);
713 scoped_ptr
<LayerImpl
> scrollable_child_2
= CreateScrollableLayer(
714 9, gfx::Size(10, 10), scrollable_child_clip_2
.get());
715 child2
= scrollable_child_2
.get();
716 scrollable_child_2
->SetPosition(gfx::Point(5, 20));
717 scrollable_child_2
->SetHaveWheelEventHandlers(true);
718 scrollable_child_2
->SetHaveScrollEventHandlers(true);
719 scrollable_child_clip_2
->AddChild(scrollable_child_2
.Pass());
720 root_child
->AddChild(scrollable_child_clip_2
.Pass());
723 // Scroll-blocks-on on a layer affects scrolls that hit that layer.
724 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
725 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::GESTURE
));
726 host_impl_
->ScrollEnd();
727 child1
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT
);
728 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
729 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::GESTURE
));
731 // But not those that hit only other layers.
732 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
733 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::GESTURE
));
734 host_impl_
->ScrollEnd();
736 // It's the union of bits set across the scroll ancestor chain that matters.
737 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
738 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::GESTURE
));
739 host_impl_
->ScrollEnd();
740 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
741 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::WHEEL
));
742 host_impl_
->ScrollEnd();
743 root
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_WHEEL_EVENT
);
744 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
745 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::GESTURE
));
746 host_impl_
->ScrollEnd();
747 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
748 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::WHEEL
));
749 child2
->SetScrollBlocksOn(SCROLL_BLOCKS_ON_SCROLL_EVENT
);
750 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
751 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::WHEEL
));
752 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
753 host_impl_
->ScrollBegin(gfx::Point(10, 25), InputHandler::GESTURE
));
756 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
757 SetupScrollAndContentsLayers(gfx::Size(100, 100));
758 host_impl_
->SetViewportSize(gfx::Size(50, 50));
761 // Ignore the fling since no layer is being scrolled
762 EXPECT_EQ(InputHandler::SCROLL_IGNORED
, host_impl_
->FlingScrollBegin());
764 // Start scrolling a layer
765 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
766 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
768 // Now the fling should go ahead since we've started scrolling a layer
769 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
772 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
773 SetupScrollAndContentsLayers(gfx::Size(100, 100));
774 host_impl_
->SetViewportSize(gfx::Size(50, 50));
777 // Ignore the fling since no layer is being scrolled
778 EXPECT_EQ(InputHandler::SCROLL_IGNORED
, host_impl_
->FlingScrollBegin());
780 // Start scrolling a layer
781 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
782 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
784 // Now the fling should go ahead since we've started scrolling a layer
785 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
788 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
789 SetupScrollAndContentsLayers(gfx::Size(100, 100));
790 host_impl_
->SetViewportSize(gfx::Size(50, 50));
792 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
794 root
->SetShouldScrollOnMainThread(true);
796 // Start scrolling a layer
797 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
798 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
800 // The fling should be ignored since there's no layer being scrolled impl-side
801 EXPECT_EQ(InputHandler::SCROLL_IGNORED
, host_impl_
->FlingScrollBegin());
804 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
805 SetupScrollAndContentsLayers(gfx::Size(100, 100));
806 host_impl_
->SetViewportSize(gfx::Size(50, 50));
808 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
810 root
->SetShouldScrollOnMainThread(true);
812 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
813 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
814 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
815 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
818 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
819 SetupScrollAndContentsLayers(gfx::Size(200, 200));
820 host_impl_
->SetViewportSize(gfx::Size(100, 100));
822 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
823 root
->SetContentsScale(2.f
, 2.f
);
824 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
828 // All scroll types inside the non-fast scrollable region should fail.
829 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
830 host_impl_
->ScrollBegin(gfx::Point(25, 25), InputHandler::WHEEL
));
831 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
832 InputHandler::WHEEL
));
833 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
834 host_impl_
->ScrollBegin(gfx::Point(25, 25), InputHandler::GESTURE
));
835 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
836 InputHandler::GESTURE
));
838 // All scroll types outside this region should succeed.
839 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
840 host_impl_
->ScrollBegin(gfx::Point(75, 75), InputHandler::WHEEL
));
841 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
842 InputHandler::GESTURE
));
843 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
844 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
845 InputHandler::GESTURE
));
846 host_impl_
->ScrollEnd();
847 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
848 InputHandler::GESTURE
));
849 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
850 host_impl_
->ScrollBegin(gfx::Point(75, 75), InputHandler::GESTURE
));
851 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
852 InputHandler::GESTURE
));
853 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
854 host_impl_
->ScrollEnd();
855 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
856 InputHandler::GESTURE
));
859 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
860 SetupScrollAndContentsLayers(gfx::Size(200, 200));
861 host_impl_
->SetViewportSize(gfx::Size(100, 100));
863 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
864 root
->SetContentsScale(2.f
, 2.f
);
865 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
866 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
870 // This point would fall into the non-fast scrollable region except that we've
871 // moved the layer down by 25 pixels.
872 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
873 host_impl_
->ScrollBegin(gfx::Point(40, 10), InputHandler::WHEEL
));
874 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
875 InputHandler::WHEEL
));
876 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
877 host_impl_
->ScrollEnd();
879 // This point is still inside the non-fast region.
880 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
881 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::WHEEL
));
884 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
885 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
886 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
887 host_impl_
->SetViewportSize(gfx::Size(50, 50));
890 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
891 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
892 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
893 host_impl_
->ScrollEnd();
894 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
897 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
898 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
899 scroll_layer
->SetHaveScrollEventHandlers(true);
900 host_impl_
->SetViewportSize(gfx::Size(50, 50));
903 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
904 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
905 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
906 host_impl_
->ScrollEnd();
907 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
910 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
911 SetupScrollAndContentsLayers(gfx::Size(200, 200));
912 host_impl_
->SetViewportSize(gfx::Size(100, 100));
916 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
917 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
919 // Trying to scroll to the left/top will not succeed.
921 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
923 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll
);
925 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll
);
927 // Scrolling to the right/bottom will succeed.
929 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)).did_scroll
);
931 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
933 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)).did_scroll
);
935 // Scrolling to left/top will now succeed.
937 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
939 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll
);
941 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll
);
943 // Scrolling diagonally against an edge will succeed.
945 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)).did_scroll
);
947 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
949 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)).did_scroll
);
951 // Trying to scroll more than the available space will also succeed.
953 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)).did_scroll
);
956 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
957 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
958 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
962 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
963 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
965 // Trying to scroll without a vertical scrollbar will fail.
966 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
967 gfx::Point(), SCROLL_FORWARD
));
968 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
969 gfx::Point(), SCROLL_BACKWARD
));
971 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
972 PaintedScrollbarLayerImpl::Create(
973 host_impl_
->active_tree(),
976 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
977 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
978 vertical_scrollbar
.get());
980 // Trying to scroll with a vertical scrollbar will succeed.
981 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
982 gfx::Point(), SCROLL_FORWARD
));
983 EXPECT_FLOAT_EQ(875.f
,
984 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
985 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
986 gfx::Point(), SCROLL_BACKWARD
));
989 TEST_F(LayerTreeHostImplTest
, ScrollWithUserUnscrollableLayers
) {
990 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
991 host_impl_
->SetViewportSize(gfx::Size(100, 100));
993 gfx::Size
overflow_size(400, 400);
994 ASSERT_EQ(1u, scroll_layer
->children().size());
995 LayerImpl
* overflow
= scroll_layer
->children()[0];
996 overflow
->SetBounds(overflow_size
);
997 overflow
->SetContentBounds(overflow_size
);
998 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
999 overflow
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
1000 overflow
->SetPosition(gfx::PointF());
1003 gfx::Point
scroll_position(10, 10);
1005 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1006 host_impl_
->ScrollBegin(scroll_position
, InputHandler::WHEEL
));
1007 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->CurrentScrollOffset());
1008 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->CurrentScrollOffset());
1010 gfx::Vector2dF
scroll_delta(10, 10);
1011 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
1012 host_impl_
->ScrollEnd();
1013 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->CurrentScrollOffset());
1014 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->CurrentScrollOffset());
1016 overflow
->set_user_scrollable_horizontal(false);
1018 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1019 host_impl_
->ScrollBegin(scroll_position
, InputHandler::WHEEL
));
1020 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->CurrentScrollOffset());
1021 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->CurrentScrollOffset());
1023 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
1024 host_impl_
->ScrollEnd();
1025 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->CurrentScrollOffset());
1026 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->CurrentScrollOffset());
1028 overflow
->set_user_scrollable_vertical(false);
1030 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1031 host_impl_
->ScrollBegin(scroll_position
, InputHandler::WHEEL
));
1032 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->CurrentScrollOffset());
1033 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->CurrentScrollOffset());
1035 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
1036 host_impl_
->ScrollEnd();
1037 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->CurrentScrollOffset());
1038 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->CurrentScrollOffset());
1041 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
1042 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
1043 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1046 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
1047 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
1048 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
1050 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
1051 float page_scale_factor
= 1.f
;
1053 // The impl-based pinch zoom should adjust the max scroll position.
1055 host_impl_
->active_tree()->PushPageScaleFromMainThread(
1056 page_scale_factor
, min_page_scale
, max_page_scale
);
1057 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
1058 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1060 float page_scale_delta
= 2.f
;
1062 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::GESTURE
);
1063 host_impl_
->PinchGestureBegin();
1064 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1065 host_impl_
->PinchGestureEnd();
1066 host_impl_
->ScrollEnd();
1067 EXPECT_FALSE(did_request_animate_
);
1068 EXPECT_TRUE(did_request_redraw_
);
1069 EXPECT_TRUE(did_request_commit_
);
1070 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
1072 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1073 host_impl_
->ProcessScrollDeltas();
1074 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1076 EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
1077 scroll_layer
->MaxScrollOffset().ToString());
1080 // Scrolling after a pinch gesture should always be in local space. The
1081 // scroll deltas have the page scale factor applied.
1083 host_impl_
->active_tree()->PushPageScaleFromMainThread(
1084 page_scale_factor
, min_page_scale
, max_page_scale
);
1085 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
1086 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1088 float page_scale_delta
= 2.f
;
1089 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
1090 host_impl_
->PinchGestureBegin();
1091 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1092 host_impl_
->PinchGestureEnd();
1093 host_impl_
->ScrollEnd();
1095 gfx::Vector2d
scroll_delta(0, 10);
1096 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1097 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
1098 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
1099 host_impl_
->ScrollEnd();
1101 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1102 host_impl_
->ProcessScrollDeltas();
1103 ExpectContains(*scroll_info
.get(), scroll_layer
->id(),
1104 gfx::Vector2d(0, scroll_delta
.y() / page_scale_delta
));
1108 TEST_F(LayerTreeHostImplTest
, ScrollWithSwapPromises
) {
1109 ui::LatencyInfo latency_info
;
1110 latency_info
.trace_id
= 1234;
1111 scoped_ptr
<SwapPromise
> swap_promise(
1112 new LatencyInfoSwapPromise(latency_info
));
1114 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1115 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1116 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
1117 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1118 host_impl_
->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise
.Pass());
1119 host_impl_
->ScrollEnd();
1121 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
1122 EXPECT_EQ(1u, scroll_info
->swap_promises
.size());
1123 EXPECT_EQ(latency_info
.trace_id
, scroll_info
->swap_promises
[0]->TraceId());
1126 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1127 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1128 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1131 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1132 DCHECK(scroll_layer
);
1134 float min_page_scale
= 1.f
;
1135 float max_page_scale
= 4.f
;
1137 // Basic pinch zoom in gesture
1139 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1141 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1143 float page_scale_delta
= 2.f
;
1144 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::GESTURE
);
1145 host_impl_
->PinchGestureBegin();
1146 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1147 host_impl_
->PinchGestureEnd();
1148 host_impl_
->ScrollEnd();
1149 EXPECT_FALSE(did_request_animate_
);
1150 EXPECT_TRUE(did_request_redraw_
);
1151 EXPECT_TRUE(did_request_commit_
);
1153 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1154 host_impl_
->ProcessScrollDeltas();
1155 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1160 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1162 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1163 float page_scale_delta
= 10.f
;
1165 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::GESTURE
);
1166 host_impl_
->PinchGestureBegin();
1167 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1168 host_impl_
->PinchGestureEnd();
1169 host_impl_
->ScrollEnd();
1171 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1172 host_impl_
->ProcessScrollDeltas();
1173 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1176 // Zoom-out clamping
1178 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1180 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1181 scroll_layer
->PullDeltaForMainThread();
1182 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1184 float page_scale_delta
= 0.1f
;
1185 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
1186 host_impl_
->PinchGestureBegin();
1187 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1188 host_impl_
->PinchGestureEnd();
1189 host_impl_
->ScrollEnd();
1191 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1192 host_impl_
->ProcessScrollDeltas();
1193 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1195 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1198 // Two-finger panning should not happen based on pinch events only
1200 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1202 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1203 scroll_layer
->PullDeltaForMainThread();
1204 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(20, 20));
1206 float page_scale_delta
= 1.f
;
1207 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::GESTURE
);
1208 host_impl_
->PinchGestureBegin();
1209 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1210 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1211 host_impl_
->PinchGestureEnd();
1212 host_impl_
->ScrollEnd();
1214 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1215 host_impl_
->ProcessScrollDeltas();
1216 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1217 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1220 // Two-finger panning should work with interleaved scroll events
1222 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1224 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1225 scroll_layer
->PullDeltaForMainThread();
1226 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(20, 20));
1228 float page_scale_delta
= 1.f
;
1229 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::GESTURE
);
1230 host_impl_
->PinchGestureBegin();
1231 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1232 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1233 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1234 host_impl_
->PinchGestureEnd();
1235 host_impl_
->ScrollEnd();
1237 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1238 host_impl_
->ProcessScrollDeltas();
1239 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1240 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1243 // Two-finger panning should work when starting fully zoomed out.
1245 host_impl_
->active_tree()->PushPageScaleFromMainThread(0.5f
, 0.5f
, 4.f
);
1246 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1247 scroll_layer
->PullDeltaForMainThread();
1248 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 0));
1250 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::GESTURE
);
1251 host_impl_
->PinchGestureBegin();
1252 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1253 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1254 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1255 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1256 host_impl_
->PinchGestureEnd();
1257 host_impl_
->ScrollEnd();
1259 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1260 host_impl_
->ProcessScrollDeltas();
1261 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1262 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1266 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1267 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1268 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1271 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1272 DCHECK(scroll_layer
);
1274 float min_page_scale
= 0.5f
;
1275 float max_page_scale
= 4.f
;
1276 base::TimeTicks start_time
= base::TimeTicks() +
1277 base::TimeDelta::FromSeconds(1);
1278 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1279 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1280 base::TimeTicks end_time
= start_time
+ duration
;
1282 // Non-anchor zoom-in
1284 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1286 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1288 did_request_redraw_
= false;
1289 did_request_animate_
= false;
1290 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1291 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1296 host_impl_
->ActivateSyncTree();
1297 EXPECT_FALSE(did_request_redraw_
);
1298 EXPECT_TRUE(did_request_animate_
);
1300 did_request_redraw_
= false;
1301 did_request_animate_
= false;
1302 host_impl_
->Animate(start_time
);
1303 EXPECT_TRUE(did_request_redraw_
);
1304 EXPECT_TRUE(did_request_animate_
);
1306 did_request_redraw_
= false;
1307 did_request_animate_
= false;
1308 host_impl_
->Animate(halfway_through_animation
);
1309 EXPECT_TRUE(did_request_redraw_
);
1310 EXPECT_TRUE(did_request_animate_
);
1312 did_request_redraw_
= false;
1313 did_request_animate_
= false;
1314 did_request_commit_
= false;
1315 host_impl_
->Animate(end_time
);
1316 EXPECT_TRUE(did_request_commit_
);
1317 EXPECT_FALSE(did_request_animate_
);
1319 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1320 host_impl_
->ProcessScrollDeltas();
1321 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1322 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1327 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1329 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1331 did_request_redraw_
= false;
1332 did_request_animate_
= false;
1333 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1334 scoped_ptr
<PendingPageScaleAnimation
> (new PendingPageScaleAnimation(
1335 gfx::Vector2d(25, 25),
1339 host_impl_
->ActivateSyncTree();
1340 EXPECT_FALSE(did_request_redraw_
);
1341 EXPECT_TRUE(did_request_animate_
);
1343 did_request_redraw_
= false;
1344 did_request_animate_
= false;
1345 host_impl_
->Animate(start_time
);
1346 EXPECT_TRUE(did_request_redraw_
);
1347 EXPECT_TRUE(did_request_animate_
);
1349 did_request_redraw_
= false;
1350 did_request_commit_
= false;
1351 did_request_animate_
= false;
1352 host_impl_
->Animate(end_time
);
1353 EXPECT_TRUE(did_request_redraw_
);
1354 EXPECT_FALSE(did_request_animate_
);
1355 EXPECT_TRUE(did_request_commit_
);
1357 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1358 host_impl_
->ProcessScrollDeltas();
1359 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1360 // Pushed to (0,0) via clamping against contents layer size.
1361 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1365 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1366 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1367 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1370 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1371 DCHECK(scroll_layer
);
1373 float min_page_scale
= 0.5f
;
1374 float max_page_scale
= 4.f
;
1375 base::TimeTicks start_time
= base::TimeTicks() +
1376 base::TimeDelta::FromSeconds(1);
1377 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1378 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1379 base::TimeTicks end_time
= start_time
+ duration
;
1381 // Anchor zoom with unchanged page scale should not change scroll or scale.
1383 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1385 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1387 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1388 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1393 host_impl_
->ActivateSyncTree();
1394 host_impl_
->Animate(start_time
);
1395 host_impl_
->Animate(halfway_through_animation
);
1396 EXPECT_TRUE(did_request_redraw_
);
1397 host_impl_
->Animate(end_time
);
1398 EXPECT_TRUE(did_request_commit_
);
1400 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1401 host_impl_
->ProcessScrollDeltas();
1402 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1403 ExpectNone(*scroll_info
, scroll_layer
->id());
1407 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationTransferedOnSyncTreeActivate
) {
1408 host_impl_
->CreatePendingTree();
1409 CreateScrollAndContentsLayers(
1410 host_impl_
->pending_tree(),
1411 gfx::Size(100, 100));
1412 host_impl_
->ActivateSyncTree();
1415 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1416 DCHECK(scroll_layer
);
1418 float min_page_scale
= 0.5f
;
1419 float max_page_scale
= 4.f
;
1420 host_impl_
->sync_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1422 host_impl_
->ActivateSyncTree();
1424 base::TimeTicks start_time
= base::TimeTicks() +
1425 base::TimeDelta::FromSeconds(1);
1426 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1427 base::TimeTicks third_through_animation
= start_time
+ duration
/ 3;
1428 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1429 base::TimeTicks end_time
= start_time
+ duration
;
1430 float target_scale
= 2.f
;
1432 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1434 // Make sure TakePageScaleAnimation works properly.
1436 host_impl_
->sync_tree()->SetPendingPageScaleAnimation(
1437 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1442 scoped_ptr
<PendingPageScaleAnimation
> psa
=
1443 host_impl_
->sync_tree()->TakePendingPageScaleAnimation();
1444 EXPECT_EQ(target_scale
, psa
->scale
);
1445 EXPECT_EQ(duration
, psa
->duration
);
1446 EXPECT_EQ(nullptr, host_impl_
->sync_tree()->TakePendingPageScaleAnimation());
1448 // Recreate the PSA. Nothing should happen here since the tree containing the
1449 // PSA hasn't been activated yet.
1450 did_request_redraw_
= false;
1451 did_request_animate_
= false;
1452 host_impl_
->sync_tree()->SetPendingPageScaleAnimation(
1453 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1458 host_impl_
->Animate(halfway_through_animation
);
1459 EXPECT_FALSE(did_request_animate_
);
1460 EXPECT_FALSE(did_request_redraw_
);
1462 // Activate the sync tree. This should cause the animation to become enabled.
1463 // It should also clear the pointer on the sync tree.
1464 host_impl_
->ActivateSyncTree();
1466 host_impl_
->sync_tree()->TakePendingPageScaleAnimation().get());
1467 EXPECT_FALSE(did_request_redraw_
);
1468 EXPECT_TRUE(did_request_animate_
);
1470 // From here on, make sure the animation runs as normal.
1471 did_request_redraw_
= false;
1472 did_request_animate_
= false;
1473 host_impl_
->Animate(start_time
);
1474 EXPECT_TRUE(did_request_redraw_
);
1475 EXPECT_TRUE(did_request_animate_
);
1477 did_request_redraw_
= false;
1478 did_request_animate_
= false;
1479 host_impl_
->Animate(third_through_animation
);
1480 EXPECT_TRUE(did_request_redraw_
);
1481 EXPECT_TRUE(did_request_animate_
);
1483 // Another activation shouldn't have any effect on the animation.
1484 host_impl_
->ActivateSyncTree();
1486 did_request_redraw_
= false;
1487 did_request_animate_
= false;
1488 host_impl_
->Animate(halfway_through_animation
);
1489 EXPECT_TRUE(did_request_redraw_
);
1490 EXPECT_TRUE(did_request_animate_
);
1492 did_request_redraw_
= false;
1493 did_request_animate_
= false;
1494 did_request_commit_
= false;
1495 host_impl_
->Animate(end_time
);
1496 EXPECT_TRUE(did_request_commit_
);
1497 EXPECT_FALSE(did_request_animate_
);
1499 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1500 host_impl_
->ProcessScrollDeltas();
1501 EXPECT_EQ(scroll_info
->page_scale_delta
, target_scale
);
1502 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1505 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationCompletedNotification
) {
1506 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1507 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1510 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1511 DCHECK(scroll_layer
);
1513 base::TimeTicks start_time
=
1514 base::TimeTicks() + base::TimeDelta::FromSeconds(1);
1515 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1516 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1517 base::TimeTicks end_time
= start_time
+ duration
;
1519 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
1520 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(50, 50));
1522 did_complete_page_scale_animation_
= false;
1523 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1524 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1525 gfx::Vector2d(), false, 2.f
, duration
)));
1526 host_impl_
->ActivateSyncTree();
1527 host_impl_
->Animate(start_time
);
1528 EXPECT_FALSE(did_complete_page_scale_animation_
);
1530 host_impl_
->Animate(halfway_through_animation
);
1531 EXPECT_FALSE(did_complete_page_scale_animation_
);
1533 host_impl_
->Animate(end_time
);
1534 EXPECT_TRUE(did_complete_page_scale_animation_
);
1537 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1539 LayerTreeHostImplOverridePhysicalTime(
1540 const LayerTreeSettings
& settings
,
1541 LayerTreeHostImplClient
* client
,
1543 SharedBitmapManager
* manager
,
1544 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1545 : LayerTreeHostImpl(settings
,
1548 rendering_stats_instrumentation
,
1553 BeginFrameArgs
CurrentBeginFrameArgs() const override
{
1554 return CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
,
1555 fake_current_physical_time_
);
1558 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1559 fake_current_physical_time_
= fake_now
;
1563 base::TimeTicks fake_current_physical_time_
;
1566 class LayerTreeHostImplTestScrollbarAnimation
: public LayerTreeHostImplTest
{
1568 void SetupLayers(LayerTreeSettings settings
) {
1569 gfx::Size
viewport_size(10, 10);
1570 gfx::Size
content_size(100, 100);
1572 LayerTreeHostImplOverridePhysicalTime
* host_impl_override_time
=
1573 new LayerTreeHostImplOverridePhysicalTime(settings
, this, &proxy_
,
1574 shared_bitmap_manager_
.get(),
1575 &stats_instrumentation_
);
1576 host_impl_
= make_scoped_ptr(host_impl_override_time
);
1577 host_impl_
->InitializeRenderer(CreateOutputSurface());
1578 host_impl_
->SetViewportSize(viewport_size
);
1580 scoped_ptr
<LayerImpl
> root
=
1581 LayerImpl::Create(host_impl_
->active_tree(), 1);
1582 root
->SetBounds(viewport_size
);
1584 scoped_ptr
<LayerImpl
> scroll
=
1585 LayerImpl::Create(host_impl_
->active_tree(), 2);
1586 scroll
->SetScrollClipLayer(root
->id());
1587 scroll
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
1588 root
->SetBounds(viewport_size
);
1589 scroll
->SetBounds(content_size
);
1590 scroll
->SetContentBounds(content_size
);
1591 scroll
->SetIsContainerForFixedPositionLayers(true);
1593 scoped_ptr
<LayerImpl
> contents
=
1594 LayerImpl::Create(host_impl_
->active_tree(), 3);
1595 contents
->SetDrawsContent(true);
1596 contents
->SetBounds(content_size
);
1597 contents
->SetContentBounds(content_size
);
1599 scoped_ptr
<SolidColorScrollbarLayerImpl
> scrollbar
=
1600 SolidColorScrollbarLayerImpl::Create(host_impl_
->active_tree(), 4,
1601 VERTICAL
, 10, 0, false, true);
1602 EXPECT_FLOAT_EQ(0.f
, scrollbar
->opacity());
1604 scroll
->AddChild(contents
.Pass());
1605 root
->AddChild(scroll
.Pass());
1606 root
->SetHasRenderSurface(true);
1607 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1608 root
->AddChild(scrollbar
.Pass());
1610 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1611 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
1613 host_impl_
->active_tree()->DidBecomeActive();
1617 void RunTest(LayerTreeSettings::ScrollbarAnimator animator
) {
1618 LayerTreeSettings settings
;
1619 settings
.scrollbar_animator
= animator
;
1620 settings
.scrollbar_fade_delay_ms
= 20;
1621 settings
.scrollbar_fade_duration_ms
= 20;
1623 SetupLayers(settings
);
1625 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1627 EXPECT_FALSE(did_request_animate_
);
1628 EXPECT_FALSE(did_request_redraw_
);
1629 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1630 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1632 // If no scroll happened during a scroll gesture, it should have no effect.
1633 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
);
1634 host_impl_
->ScrollEnd();
1635 EXPECT_FALSE(did_request_animate_
);
1636 EXPECT_FALSE(did_request_redraw_
);
1637 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1638 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1640 // After a scroll, a scrollbar animation should be scheduled about 20ms from
1642 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
);
1643 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5));
1644 EXPECT_FALSE(did_request_animate_
);
1645 EXPECT_TRUE(did_request_redraw_
);
1646 did_request_redraw_
= false;
1647 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1648 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1650 host_impl_
->ScrollEnd();
1651 EXPECT_FALSE(did_request_animate_
);
1652 EXPECT_FALSE(did_request_redraw_
);
1653 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
1654 requested_animation_delay_
);
1655 EXPECT_FALSE(animation_task_
.Equals(base::Closure()));
1657 fake_now
+= requested_animation_delay_
;
1658 requested_animation_delay_
= base::TimeDelta();
1659 animation_task_
.Run();
1660 animation_task_
= base::Closure();
1661 EXPECT_TRUE(did_request_animate_
);
1662 did_request_animate_
= false;
1663 EXPECT_FALSE(did_request_redraw_
);
1665 // After the scrollbar animation begins, we should start getting redraws.
1666 host_impl_
->Animate(fake_now
);
1667 EXPECT_TRUE(did_request_animate_
);
1668 did_request_animate_
= false;
1669 EXPECT_TRUE(did_request_redraw_
);
1670 did_request_redraw_
= false;
1671 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1672 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1674 // Setting the scroll offset outside a scroll should also cause the
1675 // scrollbar to appear and to schedule a scrollbar animation.
1676 host_impl_
->InnerViewportScrollLayer()->PushScrollOffsetFromMainThread(
1677 gfx::ScrollOffset(5, 5));
1678 EXPECT_FALSE(did_request_animate_
);
1679 EXPECT_FALSE(did_request_redraw_
);
1680 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
1681 requested_animation_delay_
);
1682 EXPECT_FALSE(animation_task_
.Equals(base::Closure()));
1683 requested_animation_delay_
= base::TimeDelta();
1684 animation_task_
= base::Closure();
1686 // Scrollbar animation is not triggered unnecessarily.
1687 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
);
1688 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1689 EXPECT_FALSE(did_request_animate_
);
1690 EXPECT_TRUE(did_request_redraw_
);
1691 did_request_redraw_
= false;
1692 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1693 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1695 host_impl_
->ScrollEnd();
1696 EXPECT_FALSE(did_request_animate_
);
1697 EXPECT_FALSE(did_request_redraw_
);
1698 EXPECT_EQ(base::TimeDelta(), requested_animation_delay_
);
1699 EXPECT_TRUE(animation_task_
.Equals(base::Closure()));
1701 // Changing page scale triggers scrollbar animation.
1702 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 1.f
, 4.f
);
1703 host_impl_
->SetPageScaleOnActiveTree(1.1f
);
1704 EXPECT_FALSE(did_request_animate_
);
1705 EXPECT_FALSE(did_request_redraw_
);
1706 EXPECT_EQ(base::TimeDelta::FromMilliseconds(20),
1707 requested_animation_delay_
);
1708 EXPECT_FALSE(animation_task_
.Equals(base::Closure()));
1709 requested_animation_delay_
= base::TimeDelta();
1710 animation_task_
= base::Closure();
1714 TEST_F(LayerTreeHostImplTestScrollbarAnimation
, LinearFade
) {
1715 RunTest(LayerTreeSettings::LINEAR_FADE
);
1718 TEST_F(LayerTreeHostImplTestScrollbarAnimation
, Thinning
) {
1719 RunTest(LayerTreeSettings::THINNING
);
1722 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1723 float device_scale_factor
) {
1724 LayerTreeSettings settings
;
1725 settings
.scrollbar_fade_delay_ms
= 500;
1726 settings
.scrollbar_fade_duration_ms
= 300;
1727 settings
.scrollbar_animator
= LayerTreeSettings::THINNING
;
1729 gfx::Size
viewport_size(300, 200);
1730 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1731 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1732 gfx::Size
content_size(1000, 1000);
1734 CreateHostImpl(settings
, CreateOutputSurface());
1735 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1736 host_impl_
->SetViewportSize(device_viewport_size
);
1738 scoped_ptr
<LayerImpl
> root
=
1739 LayerImpl::Create(host_impl_
->active_tree(), 1);
1740 root
->SetBounds(viewport_size
);
1741 root
->SetHasRenderSurface(true);
1743 scoped_ptr
<LayerImpl
> scroll
=
1744 LayerImpl::Create(host_impl_
->active_tree(), 2);
1745 scroll
->SetScrollClipLayer(root
->id());
1746 scroll
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
1747 scroll
->SetBounds(content_size
);
1748 scroll
->SetContentBounds(content_size
);
1749 scroll
->SetIsContainerForFixedPositionLayers(true);
1751 scoped_ptr
<LayerImpl
> contents
=
1752 LayerImpl::Create(host_impl_
->active_tree(), 3);
1753 contents
->SetDrawsContent(true);
1754 contents
->SetBounds(content_size
);
1755 contents
->SetContentBounds(content_size
);
1757 // The scrollbar is on the right side.
1758 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1759 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1760 scrollbar
->SetDrawsContent(true);
1761 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1762 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1763 scrollbar
->SetPosition(gfx::Point(285, 0));
1765 scroll
->AddChild(contents
.Pass());
1766 root
->AddChild(scroll
.Pass());
1767 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1768 root
->AddChild(scrollbar
.Pass());
1770 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1771 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
1773 host_impl_
->active_tree()->DidBecomeActive();
1776 LayerImpl
* root_scroll
=
1777 host_impl_
->active_tree()->InnerViewportScrollLayer();
1778 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1779 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1780 static_cast<ScrollbarAnimationControllerThinning
*>(
1781 root_scroll
->scrollbar_animation_controller());
1782 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1784 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1785 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1787 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1788 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1790 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1791 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1793 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1794 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1795 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1797 did_request_redraw_
= false;
1798 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1799 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1800 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1801 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1802 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1803 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1804 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1807 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1808 SetupMouseMoveAtWithDeviceScale(1.f
);
1811 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1812 SetupMouseMoveAtWithDeviceScale(2.f
);
1815 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1816 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1817 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1818 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
1821 CompositorFrameMetadata metadata
=
1822 host_impl_
->MakeCompositorFrameMetadata();
1823 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1824 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1825 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.scrollable_viewport_size
);
1826 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1827 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1828 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1829 EXPECT_FALSE(metadata
.root_overflow_x_hidden
);
1830 EXPECT_FALSE(metadata
.root_overflow_y_hidden
);
1833 // Scrolling should update metadata immediately.
1834 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
1835 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
1836 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1838 CompositorFrameMetadata metadata
=
1839 host_impl_
->MakeCompositorFrameMetadata();
1840 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1842 host_impl_
->ScrollEnd();
1844 CompositorFrameMetadata metadata
=
1845 host_impl_
->MakeCompositorFrameMetadata();
1846 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1849 // Root "overflow: hidden" properties should be reflected.
1851 host_impl_
->active_tree()
1852 ->InnerViewportScrollLayer()
1853 ->set_user_scrollable_horizontal(false);
1854 CompositorFrameMetadata metadata
=
1855 host_impl_
->MakeCompositorFrameMetadata();
1856 EXPECT_TRUE(metadata
.root_overflow_x_hidden
);
1857 EXPECT_FALSE(metadata
.root_overflow_y_hidden
);
1859 host_impl_
->active_tree()
1860 ->InnerViewportScrollLayer()
1861 ->set_user_scrollable_vertical(false);
1862 metadata
= host_impl_
->MakeCompositorFrameMetadata();
1863 EXPECT_TRUE(metadata
.root_overflow_x_hidden
);
1864 EXPECT_TRUE(metadata
.root_overflow_y_hidden
);
1867 // Page scale should update metadata correctly (shrinking only the viewport).
1868 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
1869 host_impl_
->PinchGestureBegin();
1870 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1871 host_impl_
->PinchGestureEnd();
1872 host_impl_
->ScrollEnd();
1874 CompositorFrameMetadata metadata
=
1875 host_impl_
->MakeCompositorFrameMetadata();
1876 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1877 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1878 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.scrollable_viewport_size
);
1879 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1880 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1881 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1884 // Likewise if set from the main thread.
1885 host_impl_
->ProcessScrollDeltas();
1886 host_impl_
->active_tree()->PushPageScaleFromMainThread(4.f
, 0.5f
, 4.f
);
1887 host_impl_
->SetPageScaleOnActiveTree(4.f
);
1889 CompositorFrameMetadata metadata
=
1890 host_impl_
->MakeCompositorFrameMetadata();
1891 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1892 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1893 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.scrollable_viewport_size
);
1894 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1895 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1896 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1900 class DidDrawCheckLayer
: public LayerImpl
{
1902 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1903 return make_scoped_ptr(new DidDrawCheckLayer(tree_impl
, id
));
1906 bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
) override
{
1907 will_draw_called_
= true;
1908 if (will_draw_returns_false_
)
1910 return LayerImpl::WillDraw(draw_mode
, provider
);
1913 void AppendQuads(RenderPass
* render_pass
,
1914 AppendQuadsData
* append_quads_data
) override
{
1915 append_quads_called_
= true;
1916 LayerImpl::AppendQuads(render_pass
, append_quads_data
);
1919 void DidDraw(ResourceProvider
* provider
) override
{
1920 did_draw_called_
= true;
1921 LayerImpl::DidDraw(provider
);
1924 bool will_draw_called() const { return will_draw_called_
; }
1925 bool append_quads_called() const { return append_quads_called_
; }
1926 bool did_draw_called() const { return did_draw_called_
; }
1928 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1930 void ClearDidDrawCheck() {
1931 will_draw_called_
= false;
1932 append_quads_called_
= false;
1933 did_draw_called_
= false;
1936 static void IgnoreResult(scoped_ptr
<CopyOutputResult
> result
) {}
1938 void AddCopyRequest() {
1939 ScopedPtrVector
<CopyOutputRequest
> requests
;
1941 CopyOutputRequest::CreateRequest(base::Bind(&IgnoreResult
)));
1942 SetHasRenderSurface(true);
1943 PassCopyRequests(&requests
);
1947 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1948 : LayerImpl(tree_impl
, id
),
1949 will_draw_returns_false_(false),
1950 will_draw_called_(false),
1951 append_quads_called_(false),
1952 did_draw_called_(false) {
1953 SetBounds(gfx::Size(10, 10));
1954 SetContentBounds(gfx::Size(10, 10));
1955 SetDrawsContent(true);
1956 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1960 bool will_draw_returns_false_
;
1961 bool will_draw_called_
;
1962 bool append_quads_called_
;
1963 bool did_draw_called_
;
1966 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1967 // The root layer is always drawn, so run this test on a child layer that
1968 // will be masked out by the root layer's bounds.
1969 host_impl_
->active_tree()->SetRootLayer(
1970 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1971 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1972 host_impl_
->active_tree()->root_layer());
1974 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1975 root
->SetHasRenderSurface(true);
1976 DidDrawCheckLayer
* layer
=
1977 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1980 LayerTreeHostImpl::FrameData frame
;
1981 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1982 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1983 host_impl_
->DidDrawAllLayers(frame
);
1985 EXPECT_TRUE(layer
->will_draw_called());
1986 EXPECT_TRUE(layer
->append_quads_called());
1987 EXPECT_TRUE(layer
->did_draw_called());
1990 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1993 LayerTreeHostImpl::FrameData frame
;
1995 layer
->set_will_draw_returns_false();
1996 layer
->ClearDidDrawCheck();
1998 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1999 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2000 host_impl_
->DidDrawAllLayers(frame
);
2002 EXPECT_TRUE(layer
->will_draw_called());
2003 EXPECT_FALSE(layer
->append_quads_called());
2004 EXPECT_FALSE(layer
->did_draw_called());
2008 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
2009 // The root layer is always drawn, so run this test on a child layer that
2010 // will be masked out by the root layer's bounds.
2011 host_impl_
->active_tree()->SetRootLayer(
2012 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2013 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
2014 host_impl_
->active_tree()->root_layer());
2015 root
->SetMasksToBounds(true);
2016 root
->SetHasRenderSurface(true);
2017 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
2018 DidDrawCheckLayer
* layer
=
2019 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
2020 // Ensure visible_content_rect for layer is empty.
2021 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
2022 layer
->SetBounds(gfx::Size(10, 10));
2023 layer
->SetContentBounds(gfx::Size(10, 10));
2025 LayerTreeHostImpl::FrameData frame
;
2027 EXPECT_FALSE(layer
->will_draw_called());
2028 EXPECT_FALSE(layer
->did_draw_called());
2030 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2031 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2032 host_impl_
->DidDrawAllLayers(frame
);
2034 EXPECT_FALSE(layer
->will_draw_called());
2035 EXPECT_FALSE(layer
->did_draw_called());
2037 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
2039 // Ensure visible_content_rect for layer is not empty
2040 layer
->SetPosition(gfx::PointF());
2042 EXPECT_FALSE(layer
->will_draw_called());
2043 EXPECT_FALSE(layer
->did_draw_called());
2045 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2046 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2047 host_impl_
->DidDrawAllLayers(frame
);
2049 EXPECT_TRUE(layer
->will_draw_called());
2050 EXPECT_TRUE(layer
->did_draw_called());
2052 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
2055 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
2056 gfx::Size
big_size(1000, 1000);
2057 host_impl_
->SetViewportSize(big_size
);
2059 host_impl_
->active_tree()->SetRootLayer(
2060 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2061 DidDrawCheckLayer
* root
=
2062 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2064 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
2065 DidDrawCheckLayer
* occluded_layer
=
2066 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
2068 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2069 root
->SetHasRenderSurface(true);
2070 DidDrawCheckLayer
* top_layer
=
2071 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
2072 // This layer covers the occluded_layer above. Make this layer large so it can
2074 top_layer
->SetBounds(big_size
);
2075 top_layer
->SetContentBounds(big_size
);
2076 top_layer
->SetContentsOpaque(true);
2078 LayerTreeHostImpl::FrameData frame
;
2080 EXPECT_FALSE(occluded_layer
->will_draw_called());
2081 EXPECT_FALSE(occluded_layer
->did_draw_called());
2082 EXPECT_FALSE(top_layer
->will_draw_called());
2083 EXPECT_FALSE(top_layer
->did_draw_called());
2085 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2086 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2087 host_impl_
->DidDrawAllLayers(frame
);
2089 EXPECT_FALSE(occluded_layer
->will_draw_called());
2090 EXPECT_FALSE(occluded_layer
->did_draw_called());
2091 EXPECT_TRUE(top_layer
->will_draw_called());
2092 EXPECT_TRUE(top_layer
->did_draw_called());
2095 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
2096 host_impl_
->active_tree()->SetRootLayer(
2097 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2098 DidDrawCheckLayer
* root
=
2099 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2101 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
2102 root
->SetHasRenderSurface(true);
2103 DidDrawCheckLayer
* layer1
=
2104 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
2106 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2107 DidDrawCheckLayer
* layer2
=
2108 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
2110 layer1
->SetHasRenderSurface(true);
2111 layer1
->SetShouldFlattenTransform(true);
2113 EXPECT_FALSE(root
->did_draw_called());
2114 EXPECT_FALSE(layer1
->did_draw_called());
2115 EXPECT_FALSE(layer2
->did_draw_called());
2117 LayerTreeHostImpl::FrameData frame
;
2118 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
2119 host_impl_
->active_tree()->root_layer());
2120 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2121 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2122 host_impl_
->DidDrawAllLayers(frame
);
2124 EXPECT_TRUE(root
->did_draw_called());
2125 EXPECT_TRUE(layer1
->did_draw_called());
2126 EXPECT_TRUE(layer2
->did_draw_called());
2128 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
2129 EXPECT_TRUE(!!layer1
->render_surface());
2132 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
2134 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
2137 bool had_incomplete_tile
,
2139 ResourceProvider
* resource_provider
) {
2140 return make_scoped_ptr(new MissingTextureAnimatingLayer(tree_impl
,
2143 had_incomplete_tile
,
2145 resource_provider
));
2148 void AppendQuads(RenderPass
* render_pass
,
2149 AppendQuadsData
* append_quads_data
) override
{
2150 LayerImpl::AppendQuads(render_pass
, append_quads_data
);
2151 if (had_incomplete_tile_
)
2152 append_quads_data
->num_incomplete_tiles
++;
2154 append_quads_data
->num_missing_tiles
++;
2158 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
2161 bool had_incomplete_tile
,
2163 ResourceProvider
* resource_provider
)
2164 : DidDrawCheckLayer(tree_impl
, id
),
2165 tile_missing_(tile_missing
),
2166 had_incomplete_tile_(had_incomplete_tile
) {
2168 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
2172 bool had_incomplete_tile_
;
2175 struct PrepareToDrawSuccessTestCase
{
2177 bool has_missing_tile
= false;
2178 bool has_incomplete_tile
= false;
2179 bool is_animating
= false;
2180 bool has_copy_request
= false;
2182 bool high_res_required
= false;
2184 State layer_between
;
2186 DrawResult expected_result
;
2188 explicit PrepareToDrawSuccessTestCase(DrawResult result
)
2189 : expected_result(result
) {}
2192 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsAndFails
) {
2193 std::vector
<PrepareToDrawSuccessTestCase
> cases
;
2196 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2197 // 1. Animated layer first.
2198 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2199 cases
.back().layer_before
.is_animating
= true;
2200 // 2. Animated layer between.
2201 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2202 cases
.back().layer_between
.is_animating
= true;
2203 // 3. Animated layer last.
2204 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2205 cases
.back().layer_after
.is_animating
= true;
2206 // 4. Missing tile first.
2207 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2208 cases
.back().layer_before
.has_missing_tile
= true;
2209 // 5. Missing tile between.
2210 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2211 cases
.back().layer_between
.has_missing_tile
= true;
2212 // 6. Missing tile last.
2213 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2214 cases
.back().layer_after
.has_missing_tile
= true;
2215 // 7. Incomplete tile first.
2216 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2217 cases
.back().layer_before
.has_incomplete_tile
= true;
2218 // 8. Incomplete tile between.
2219 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2220 cases
.back().layer_between
.has_incomplete_tile
= true;
2221 // 9. Incomplete tile last.
2222 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2223 cases
.back().layer_after
.has_incomplete_tile
= true;
2224 // 10. Animation with missing tile.
2226 PrepareToDrawSuccessTestCase(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
));
2227 cases
.back().layer_between
.has_missing_tile
= true;
2228 cases
.back().layer_between
.is_animating
= true;
2229 // 11. Animation with missing tile and copy request after. Must succeed
2230 // because the animation checkerboard means we'll get a new frame and the copy
2231 // request's layer may be destroyed.
2232 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2233 cases
.back().layer_between
.has_missing_tile
= true;
2234 cases
.back().layer_between
.is_animating
= true;
2235 cases
.back().layer_after
.has_copy_request
= true;
2236 // 12. Animation with missing tile and copy request before. Must succeed
2237 // because the animation checkerboard means we'll get a new frame and the copy
2238 // request's layer may be destroyed.
2239 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2240 cases
.back().layer_between
.has_missing_tile
= true;
2241 cases
.back().layer_between
.is_animating
= true;
2242 cases
.back().layer_before
.has_copy_request
= true;
2243 // 13. Animation with incomplete tile.
2244 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2245 cases
.back().layer_between
.has_incomplete_tile
= true;
2246 cases
.back().layer_between
.is_animating
= true;
2248 // 14. High res required.
2249 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2250 cases
.back().high_res_required
= true;
2251 // 15. High res required with incomplete tile.
2253 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2254 cases
.back().high_res_required
= true;
2255 cases
.back().layer_between
.has_incomplete_tile
= true;
2256 // 16. High res required with missing tile.
2258 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2259 cases
.back().high_res_required
= true;
2260 cases
.back().layer_between
.has_missing_tile
= true;
2262 // 17. High res required is higher priority than animating missing tiles.
2264 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2265 cases
.back().high_res_required
= true;
2266 cases
.back().layer_between
.has_missing_tile
= true;
2267 cases
.back().layer_after
.has_missing_tile
= true;
2268 cases
.back().layer_after
.is_animating
= true;
2269 // 18. High res required is higher priority than animating missing tiles.
2271 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2272 cases
.back().high_res_required
= true;
2273 cases
.back().layer_between
.has_missing_tile
= true;
2274 cases
.back().layer_before
.has_missing_tile
= true;
2275 cases
.back().layer_before
.is_animating
= true;
2277 // 19. High res required is higher priority than copy requests.
2279 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2280 cases
.back().high_res_required
= true;
2281 cases
.back().layer_between
.has_missing_tile
= true;
2282 cases
.back().layer_after
.has_copy_request
= true;
2283 // 20. High res required is higher priority than copy requests.
2285 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2286 cases
.back().high_res_required
= true;
2287 cases
.back().layer_between
.has_missing_tile
= true;
2288 cases
.back().layer_before
.has_copy_request
= true;
2289 // 21. High res required is higher priority than copy requests.
2291 PrepareToDrawSuccessTestCase(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
));
2292 cases
.back().high_res_required
= true;
2293 cases
.back().layer_between
.has_missing_tile
= true;
2294 cases
.back().layer_between
.has_copy_request
= true;
2296 host_impl_
->active_tree()->SetRootLayer(
2297 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2298 DidDrawCheckLayer
* root
=
2299 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2300 root
->SetHasRenderSurface(true);
2302 LayerTreeHostImpl::FrameData frame
;
2303 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2304 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2305 host_impl_
->DidDrawAllLayers(frame
);
2306 host_impl_
->SwapBuffers(frame
);
2308 for (size_t i
= 0; i
< cases
.size(); ++i
) {
2309 const auto& testcase
= cases
[i
];
2310 std::vector
<LayerImpl
*> to_remove
;
2311 for (auto* child
: root
->children())
2312 to_remove
.push_back(child
);
2313 for (auto* child
: to_remove
)
2314 root
->RemoveChild(child
);
2316 std::ostringstream scope
;
2317 scope
<< "Test case: " << i
;
2318 SCOPED_TRACE(scope
.str());
2320 root
->AddChild(MissingTextureAnimatingLayer::Create(
2321 host_impl_
->active_tree(), 2, testcase
.layer_before
.has_missing_tile
,
2322 testcase
.layer_before
.has_incomplete_tile
,
2323 testcase
.layer_before
.is_animating
, host_impl_
->resource_provider()));
2324 DidDrawCheckLayer
* before
=
2325 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2326 if (testcase
.layer_before
.has_copy_request
)
2327 before
->AddCopyRequest();
2329 root
->AddChild(MissingTextureAnimatingLayer::Create(
2330 host_impl_
->active_tree(), 3, testcase
.layer_between
.has_missing_tile
,
2331 testcase
.layer_between
.has_incomplete_tile
,
2332 testcase
.layer_between
.is_animating
, host_impl_
->resource_provider()));
2333 DidDrawCheckLayer
* between
=
2334 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2335 if (testcase
.layer_between
.has_copy_request
)
2336 between
->AddCopyRequest();
2338 root
->AddChild(MissingTextureAnimatingLayer::Create(
2339 host_impl_
->active_tree(), 4, testcase
.layer_after
.has_missing_tile
,
2340 testcase
.layer_after
.has_incomplete_tile
,
2341 testcase
.layer_after
.is_animating
, host_impl_
->resource_provider()));
2342 DidDrawCheckLayer
* after
=
2343 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2344 if (testcase
.layer_after
.has_copy_request
)
2345 after
->AddCopyRequest();
2347 if (testcase
.high_res_required
)
2348 host_impl_
->SetRequiresHighResToDraw();
2350 LayerTreeHostImpl::FrameData frame
;
2351 EXPECT_EQ(testcase
.expected_result
, host_impl_
->PrepareToDraw(&frame
));
2352 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2353 host_impl_
->DidDrawAllLayers(frame
);
2354 host_impl_
->SwapBuffers(frame
);
2358 TEST_F(LayerTreeHostImplTest
,
2359 PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame
) {
2360 CreateHostImpl(DefaultSettings(),
2361 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
2362 EXPECT_TRUE(host_impl_
->output_surface()
2364 .draw_and_swap_full_viewport_every_frame
);
2366 std::vector
<PrepareToDrawSuccessTestCase
> cases
;
2369 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2370 // 1. Animation with missing tile.
2371 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2372 cases
.back().layer_between
.has_missing_tile
= true;
2373 cases
.back().layer_between
.is_animating
= true;
2374 // 2. High res required with incomplete tile.
2375 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2376 cases
.back().high_res_required
= true;
2377 cases
.back().layer_between
.has_incomplete_tile
= true;
2378 // 3. High res required with missing tile.
2379 cases
.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS
));
2380 cases
.back().high_res_required
= true;
2381 cases
.back().layer_between
.has_missing_tile
= true;
2383 host_impl_
->active_tree()->SetRootLayer(
2384 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2385 DidDrawCheckLayer
* root
=
2386 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2387 root
->SetHasRenderSurface(true);
2389 LayerTreeHostImpl::FrameData frame
;
2390 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2391 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2392 host_impl_
->DidDrawAllLayers(frame
);
2393 host_impl_
->SwapBuffers(frame
);
2395 for (size_t i
= 0; i
< cases
.size(); ++i
) {
2396 const auto& testcase
= cases
[i
];
2397 std::vector
<LayerImpl
*> to_remove
;
2398 for (auto* child
: root
->children())
2399 to_remove
.push_back(child
);
2400 for (auto* child
: to_remove
)
2401 root
->RemoveChild(child
);
2403 std::ostringstream scope
;
2404 scope
<< "Test case: " << i
;
2405 SCOPED_TRACE(scope
.str());
2407 root
->AddChild(MissingTextureAnimatingLayer::Create(
2408 host_impl_
->active_tree(), 2, testcase
.layer_before
.has_missing_tile
,
2409 testcase
.layer_before
.has_incomplete_tile
,
2410 testcase
.layer_before
.is_animating
, host_impl_
->resource_provider()));
2411 DidDrawCheckLayer
* before
=
2412 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2413 if (testcase
.layer_before
.has_copy_request
)
2414 before
->AddCopyRequest();
2416 root
->AddChild(MissingTextureAnimatingLayer::Create(
2417 host_impl_
->active_tree(), 3, testcase
.layer_between
.has_missing_tile
,
2418 testcase
.layer_between
.has_incomplete_tile
,
2419 testcase
.layer_between
.is_animating
, host_impl_
->resource_provider()));
2420 DidDrawCheckLayer
* between
=
2421 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2422 if (testcase
.layer_between
.has_copy_request
)
2423 between
->AddCopyRequest();
2425 root
->AddChild(MissingTextureAnimatingLayer::Create(
2426 host_impl_
->active_tree(), 4, testcase
.layer_after
.has_missing_tile
,
2427 testcase
.layer_after
.has_incomplete_tile
,
2428 testcase
.layer_after
.is_animating
, host_impl_
->resource_provider()));
2429 DidDrawCheckLayer
* after
=
2430 static_cast<DidDrawCheckLayer
*>(root
->children().back());
2431 if (testcase
.layer_after
.has_copy_request
)
2432 after
->AddCopyRequest();
2434 if (testcase
.high_res_required
)
2435 host_impl_
->SetRequiresHighResToDraw();
2437 LayerTreeHostImpl::FrameData frame
;
2438 EXPECT_EQ(testcase
.expected_result
, host_impl_
->PrepareToDraw(&frame
));
2439 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2440 host_impl_
->DidDrawAllLayers(frame
);
2441 host_impl_
->SwapBuffers(frame
);
2445 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2446 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2447 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2448 root
->SetHasRenderSurface(true);
2449 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2452 // Scroll event is ignored because layer is not scrollable.
2453 EXPECT_EQ(InputHandler::SCROLL_IGNORED
,
2454 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
2455 EXPECT_FALSE(did_request_redraw_
);
2456 EXPECT_FALSE(did_request_commit_
);
2459 // TODO(bokan): Convert these tests to create inner and outer viewports.
2460 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2462 LayerTreeHostImplTopControlsTest()
2463 // Make the clip size the same as the layer (content) size so the layer is
2465 : layer_size_(10, 10),
2466 clip_size_(layer_size_
),
2467 top_controls_height_(50) {
2468 settings_
.use_pinch_virtual_viewport
= true;
2470 viewport_size_
= gfx::Size(clip_size_
.width(),
2471 clip_size_
.height() + top_controls_height_
);
2474 bool CreateHostImpl(const LayerTreeSettings
& settings
,
2475 scoped_ptr
<OutputSurface
> output_surface
) override
{
2477 LayerTreeHostImplTest::CreateHostImpl(settings
, output_surface
.Pass());
2479 host_impl_
->active_tree()->set_top_controls_height(top_controls_height_
);
2480 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(1.f
);
2485 void SetupTopControlsAndScrollLayer() {
2486 scoped_ptr
<LayerImpl
> root
=
2487 LayerImpl::Create(host_impl_
->active_tree(), 1);
2488 scoped_ptr
<LayerImpl
> root_clip
=
2489 LayerImpl::Create(host_impl_
->active_tree(), 2);
2490 root_clip
->SetBounds(clip_size_
);
2491 root
->SetScrollClipLayer(root_clip
->id());
2492 root
->SetBounds(layer_size_
);
2493 root
->SetContentBounds(layer_size_
);
2494 root
->SetPosition(gfx::PointF());
2495 root
->SetDrawsContent(false);
2496 root
->SetIsContainerForFixedPositionLayers(true);
2497 int inner_viewport_scroll_layer_id
= root
->id();
2498 int page_scale_layer_id
= root_clip
->id();
2499 root_clip
->SetHasRenderSurface(true);
2500 root_clip
->AddChild(root
.Pass());
2501 root_clip
->SetHasRenderSurface(true);
2502 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2503 host_impl_
->active_tree()->SetViewportLayersFromIds(
2504 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2506 // Set a viewport size that is large enough to contain both the top controls
2507 // and some content.
2508 host_impl_
->SetViewportSize(viewport_size_
);
2509 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2511 host_impl_
->DidChangeTopControlsPosition();
2513 host_impl_
->CreatePendingTree();
2514 host_impl_
->sync_tree()->set_top_controls_height(top_controls_height_
);
2516 LayerImpl::Create(host_impl_
->sync_tree(), 1);
2518 LayerImpl::Create(host_impl_
->sync_tree(), 2);
2519 root_clip
->SetBounds(clip_size_
);
2520 root
->SetScrollClipLayer(root_clip
->id());
2521 root
->SetBounds(layer_size_
);
2522 root
->SetContentBounds(layer_size_
);
2523 root
->SetPosition(gfx::PointF());
2524 root
->SetDrawsContent(false);
2525 root
->SetIsContainerForFixedPositionLayers(true);
2526 inner_viewport_scroll_layer_id
= root
->id();
2527 page_scale_layer_id
= root_clip
->id();
2528 root_clip
->AddChild(root
.Pass());
2529 host_impl_
->sync_tree()->SetRootLayer(root_clip
.Pass());
2530 host_impl_
->sync_tree()->SetViewportLayersFromIds(
2531 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2533 // Set a viewport size that is large enough to contain both the top controls
2534 // and some content.
2535 host_impl_
->SetViewportSize(viewport_size_
);
2536 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2537 host_impl_
->DidChangeTopControlsPosition();
2540 void SetupTopControlsAndScrollLayerWithVirtualViewport(
2541 const gfx::Size
& inner_viewport_size
,
2542 const gfx::Size
& outer_viewport_size
,
2543 const gfx::Size
& scroll_layer_size
) {
2544 CreateHostImpl(settings_
, CreateOutputSurface());
2545 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2546 host_impl_
->sync_tree()->set_top_controls_height(top_controls_height_
);
2547 host_impl_
->DidChangeTopControlsPosition();
2549 scoped_ptr
<LayerImpl
> root
=
2550 LayerImpl::Create(host_impl_
->active_tree(), 1);
2551 scoped_ptr
<LayerImpl
> root_clip
=
2552 LayerImpl::Create(host_impl_
->active_tree(), 2);
2553 scoped_ptr
<LayerImpl
> page_scale
=
2554 LayerImpl::Create(host_impl_
->active_tree(), 3);
2556 scoped_ptr
<LayerImpl
> outer_scroll
=
2557 LayerImpl::Create(host_impl_
->active_tree(), 4);
2558 scoped_ptr
<LayerImpl
> outer_clip
=
2559 LayerImpl::Create(host_impl_
->active_tree(), 5);
2561 root_clip
->SetBounds(inner_viewport_size
);
2562 root
->SetScrollClipLayer(root_clip
->id());
2563 root
->SetBounds(outer_viewport_size
);
2564 root
->SetContentBounds(outer_viewport_size
);
2565 root
->SetPosition(gfx::PointF());
2566 root
->SetDrawsContent(false);
2567 root
->SetIsContainerForFixedPositionLayers(true);
2568 root_clip
->SetHasRenderSurface(true);
2569 outer_clip
->SetBounds(outer_viewport_size
);
2570 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
2571 outer_scroll
->SetBounds(scroll_layer_size
);
2572 outer_scroll
->SetContentBounds(scroll_layer_size
);
2573 outer_scroll
->SetPosition(gfx::PointF());
2574 outer_scroll
->SetDrawsContent(false);
2575 outer_scroll
->SetIsContainerForFixedPositionLayers(true);
2577 int inner_viewport_scroll_layer_id
= root
->id();
2578 int outer_viewport_scroll_layer_id
= outer_scroll
->id();
2579 int page_scale_layer_id
= page_scale
->id();
2581 outer_clip
->AddChild(outer_scroll
.Pass());
2582 root
->AddChild(outer_clip
.Pass());
2583 page_scale
->AddChild(root
.Pass());
2584 root_clip
->AddChild(page_scale
.Pass());
2586 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2587 host_impl_
->active_tree()->SetViewportLayersFromIds(
2588 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2589 outer_viewport_scroll_layer_id
);
2591 host_impl_
->SetViewportSize(inner_viewport_size
);
2592 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2593 EXPECT_EQ(inner_viewport_size
, root_clip_ptr
->bounds());
2597 gfx::Size layer_size_
;
2598 gfx::Size clip_size_
;
2599 gfx::Size viewport_size_
;
2600 float top_controls_height_
;
2602 LayerTreeSettings settings_
;
2603 }; // class LayerTreeHostImplTopControlsTest
2605 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2606 SetupTopControlsAndScrollLayerWithVirtualViewport(
2607 gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
2610 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2611 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2613 // Make the test scroll delta a fractional amount, to verify that the
2614 // fixed container size delta is (1) non-zero, and (2) fractional, and
2615 // (3) matches the movement of the top controls.
2616 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2617 host_impl_
->top_controls_manager()->ScrollBegin();
2618 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2619 host_impl_
->top_controls_manager()->ScrollEnd();
2621 LayerImpl
* inner_viewport_scroll_layer
=
2622 host_impl_
->active_tree()->InnerViewportScrollLayer();
2623 DCHECK(inner_viewport_scroll_layer
);
2624 host_impl_
->ScrollEnd();
2625 EXPECT_FLOAT_EQ(top_controls_scroll_delta
.y(),
2626 inner_viewport_scroll_layer
->FixedContainerSizeDelta().y());
2629 // In this test, the outer viewport is initially unscrollable. We test that a
2630 // scroll initiated on the inner viewport, causing the top controls to show and
2631 // thus making the outer viewport scrollable, still scrolls the outer viewport.
2632 TEST_F(LayerTreeHostImplTopControlsTest
,
2633 TopControlsOuterViewportBecomesScrollable
) {
2634 SetupTopControlsAndScrollLayerWithVirtualViewport(
2635 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
2638 LayerImpl
*inner_scroll
=
2639 host_impl_
->active_tree()->InnerViewportScrollLayer();
2640 LayerImpl
*inner_container
=
2641 host_impl_
->active_tree()->InnerViewportContainerLayer();
2642 LayerImpl
*outer_scroll
=
2643 host_impl_
->active_tree()->OuterViewportScrollLayer();
2644 LayerImpl
*outer_container
=
2645 host_impl_
->active_tree()->OuterViewportContainerLayer();
2647 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
2648 outer_scroll
->SetDrawsContent(true);
2649 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 1.f
, 2.f
);
2651 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2652 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2653 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, 50.f
));
2655 // The entire scroll delta should have been used to hide the top controls.
2656 // The viewport layers should be resized back to their full sizes.
2657 EXPECT_EQ(0.f
, host_impl_
->active_tree()->CurrentTopControlsShownRatio());
2658 EXPECT_EQ(0.f
, inner_scroll
->CurrentScrollOffset().y());
2659 EXPECT_EQ(100.f
, inner_container
->BoundsForScrolling().height());
2660 EXPECT_EQ(100.f
, outer_container
->BoundsForScrolling().height());
2662 // The inner viewport should be scrollable by 50px * page_scale.
2663 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, 100.f
));
2664 EXPECT_EQ(50.f
, inner_scroll
->CurrentScrollOffset().y());
2665 EXPECT_EQ(0.f
, outer_scroll
->CurrentScrollOffset().y());
2666 EXPECT_EQ(gfx::ScrollOffset(), outer_scroll
->MaxScrollOffset());
2668 host_impl_
->ScrollEnd();
2670 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2671 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2672 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
2674 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -50.f
));
2676 // The entire scroll delta should have been used to show the top controls.
2677 // The outer viewport should be resized to accomodate and scrolled to the
2678 // bottom of the document to keep the viewport in place.
2679 EXPECT_EQ(1.f
, host_impl_
->active_tree()->CurrentTopControlsShownRatio());
2680 EXPECT_EQ(50.f
, outer_container
->BoundsForScrolling().height());
2681 EXPECT_EQ(50.f
, inner_container
->BoundsForScrolling().height());
2682 EXPECT_EQ(25.f
, outer_scroll
->CurrentScrollOffset().y());
2683 EXPECT_EQ(25.f
, inner_scroll
->CurrentScrollOffset().y());
2685 // Now when we continue scrolling, make sure the outer viewport gets scrolled
2686 // since it wasn't scrollable when the scroll began.
2687 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -20.f
));
2688 EXPECT_EQ(15.f
, outer_scroll
->CurrentScrollOffset().y());
2689 EXPECT_EQ(25.f
, inner_scroll
->CurrentScrollOffset().y());
2691 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -30.f
));
2692 EXPECT_EQ(0.f
, outer_scroll
->CurrentScrollOffset().y());
2693 EXPECT_EQ(25.f
, inner_scroll
->CurrentScrollOffset().y());
2695 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -50.f
));
2696 host_impl_
->ScrollEnd();
2698 EXPECT_EQ(0.f
, outer_scroll
->CurrentScrollOffset().y());
2699 EXPECT_EQ(0.f
, inner_scroll
->CurrentScrollOffset().y());
2702 // Test that the fixed position container delta is appropriately adjusted
2703 // by the top controls showing/hiding and page scale doesn't affect it.
2704 TEST_F(LayerTreeHostImplTopControlsTest
, FixedContainerDelta
) {
2705 SetupTopControlsAndScrollLayerWithVirtualViewport(
2706 gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
2709 float page_scale
= 1.5f
;
2710 LayerImpl
* outer_viewport_scroll_layer
=
2711 host_impl_
->active_tree()->OuterViewportScrollLayer();
2713 // Zoom in, since the fixed container is the outer viewport, the delta should
2715 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, 1.f
, 2.f
);
2717 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2718 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2720 // Scroll down, the top controls hiding should expand the viewport size so
2721 // the delta should be equal to the scroll distance.
2722 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 20.f
);
2723 host_impl_
->top_controls_manager()->ScrollBegin();
2724 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2725 EXPECT_FLOAT_EQ(top_controls_height_
- top_controls_scroll_delta
.y(),
2726 host_impl_
->top_controls_manager()->ContentTopOffset());
2727 EXPECT_VECTOR_EQ(top_controls_scroll_delta
,
2728 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2729 host_impl_
->ScrollEnd();
2731 // Scroll past the maximum extent. The delta shouldn't be greater than the
2732 // top controls height.
2733 host_impl_
->top_controls_manager()->ScrollBegin();
2734 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2735 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2736 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2737 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2738 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_
),
2739 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2740 host_impl_
->ScrollEnd();
2742 // Scroll in the direction to make the top controls show.
2743 host_impl_
->top_controls_manager()->ScrollBegin();
2744 host_impl_
->top_controls_manager()->ScrollBy(-top_controls_scroll_delta
);
2745 EXPECT_EQ(top_controls_scroll_delta
.y(),
2746 host_impl_
->top_controls_manager()->ContentTopOffset());
2748 gfx::Vector2dF(0, top_controls_height_
- top_controls_scroll_delta
.y()),
2749 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2750 host_impl_
->top_controls_manager()->ScrollEnd();
2753 // Test that if a scrollable sublayer doesn't consume the scroll,
2754 // top controls should hide when scrolling down.
2755 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsScrollableSublayer
) {
2756 gfx::Size
sub_content_size(100, 400);
2757 gfx::Size
sub_content_layer_size(100, 300);
2758 SetupTopControlsAndScrollLayerWithVirtualViewport(
2759 gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100));
2762 // Show top controls
2763 EXPECT_EQ(1.f
, host_impl_
->active_tree()->CurrentTopControlsShownRatio());
2765 LayerImpl
* outer_viewport_scroll_layer
=
2766 host_impl_
->active_tree()->OuterViewportScrollLayer();
2767 int id
= outer_viewport_scroll_layer
->id();
2769 scoped_ptr
<LayerImpl
> child
=
2770 LayerImpl::Create(host_impl_
->active_tree(), id
+ 2);
2771 scoped_ptr
<LayerImpl
> child_clip
=
2772 LayerImpl::Create(host_impl_
->active_tree(), id
+ 3);
2774 child_clip
->SetBounds(sub_content_layer_size
);
2775 child
->SetScrollClipLayer(child_clip
->id());
2776 child
->SetBounds(sub_content_size
);
2777 child
->SetContentBounds(sub_content_size
);
2778 child
->SetPosition(gfx::PointF());
2779 child
->SetDrawsContent(true);
2780 child
->SetIsContainerForFixedPositionLayers(true);
2782 // scroll child to limit
2783 child
->SetScrollDelta(gfx::Vector2dF(0, 100.f
));
2784 child_clip
->AddChild(child
.Pass());
2785 outer_viewport_scroll_layer
->AddChild(child_clip
.Pass());
2787 // Scroll 25px to hide top controls
2788 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2789 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2790 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2791 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2792 host_impl_
->ScrollEnd();
2794 // Top controls should be hidden
2795 EXPECT_EQ(scroll_delta
.y(),
2796 top_controls_height_
-
2797 host_impl_
->top_controls_manager()->ContentTopOffset());
2800 // Ensure setting the top controls position explicitly using the setters on the
2801 // TreeImpl correctly affects the top controls manager and viewport bounds.
2802 TEST_F(LayerTreeHostImplTopControlsTest
, PositionTopControlsExplicitly
) {
2803 CreateHostImpl(settings_
, CreateOutputSurface());
2804 SetupTopControlsAndScrollLayer();
2807 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(0.f
);
2808 host_impl_
->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
2809 30.f
/ top_controls_height_
);
2810 host_impl_
->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
2811 EXPECT_FLOAT_EQ(30.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2812 EXPECT_FLOAT_EQ(-20.f
,
2813 host_impl_
->top_controls_manager()->ControlsTopOffset());
2815 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(0.f
);
2816 EXPECT_FLOAT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2817 EXPECT_FLOAT_EQ(-50.f
,
2818 host_impl_
->top_controls_manager()->ControlsTopOffset());
2820 host_impl_
->DidChangeTopControlsPosition();
2822 // Now that top controls have moved, expect the clip to resize.
2823 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2824 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2827 // Test that the top_controls delta and sent delta are appropriately
2828 // applied on sync tree activation. The total top controls offset shouldn't
2829 // change after the activation.
2830 TEST_F(LayerTreeHostImplTopControlsTest
, ApplyDeltaOnTreeActivation
) {
2831 CreateHostImpl(settings_
, CreateOutputSurface());
2832 SetupTopControlsAndScrollLayer();
2835 host_impl_
->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
2836 20.f
/ top_controls_height_
);
2837 host_impl_
->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
2838 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(
2839 15.f
/ top_controls_height_
);
2840 host_impl_
->active_tree()
2841 ->top_controls_shown_ratio()
2842 ->PullDeltaForMainThread();
2843 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(0.f
);
2844 host_impl_
->sync_tree()->PushTopControlsFromMainThread(15.f
/
2845 top_controls_height_
);
2847 host_impl_
->DidChangeTopControlsPosition();
2848 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2849 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2850 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2852 host_impl_
->ActivateSyncTree();
2854 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2855 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2856 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2859 -15.f
, host_impl_
->active_tree()->top_controls_shown_ratio()->Delta() *
2860 top_controls_height_
);
2863 host_impl_
->active_tree()->top_controls_shown_ratio()->ActiveBase() *
2864 top_controls_height_
);
2867 // Test that changing the top controls layout height is correctly applied to
2868 // the inner viewport container bounds. That is, the top controls layout
2869 // height is the amount that the inner viewport container was shrunk outside
2870 // the compositor to accommodate the top controls.
2871 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsLayoutHeightChanged
) {
2872 CreateHostImpl(settings_
, CreateOutputSurface());
2873 SetupTopControlsAndScrollLayer();
2876 host_impl_
->sync_tree()->PushTopControlsFromMainThread(1.f
);
2877 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2879 host_impl_
->active_tree()->top_controls_shown_ratio()->PushFromMainThread(
2881 host_impl_
->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
2882 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(0.f
);
2884 host_impl_
->DidChangeTopControlsPosition();
2885 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2886 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2887 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2889 host_impl_
->sync_tree()->root_layer()->SetBounds(
2890 gfx::Size(root_clip_ptr
->bounds().width(),
2891 root_clip_ptr
->bounds().height() - 50.f
));
2893 host_impl_
->ActivateSyncTree();
2895 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2896 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2898 // The total bounds should remain unchanged since the bounds delta should
2899 // account for the difference between the layout height and the current
2900 // top controls offset.
2901 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2902 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 50.f
), root_clip_ptr
->bounds_delta());
2904 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(1.f
);
2905 host_impl_
->DidChangeTopControlsPosition();
2907 EXPECT_EQ(1.f
, host_impl_
->top_controls_manager()->TopControlsShownRatio());
2908 EXPECT_EQ(50.f
, host_impl_
->top_controls_manager()->TopControlsHeight());
2909 EXPECT_EQ(50.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2910 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 0.f
), root_clip_ptr
->bounds_delta());
2911 EXPECT_EQ(gfx::Size(viewport_size_
.width(), viewport_size_
.height() - 50.f
),
2912 root_clip_ptr
->bounds());
2915 // Test that showing/hiding the top controls when the viewport is fully scrolled
2916 // doesn't incorrectly change the viewport offset due to clamping from changing
2918 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsViewportOffsetClamping
) {
2919 SetupTopControlsAndScrollLayerWithVirtualViewport(
2920 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2923 EXPECT_EQ(1.f
, host_impl_
->active_tree()->CurrentTopControlsShownRatio());
2925 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
2926 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
2928 // Scroll the viewports to max scroll offset.
2929 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2930 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2932 gfx::ScrollOffset viewport_offset
=
2933 host_impl_
->active_tree()->TotalScrollOffset();
2934 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(), viewport_offset
);
2936 // Hide the top controls by 25px.
2937 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2938 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2939 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2940 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2942 // scrolling down at the max extents no longer hides the top controls
2943 EXPECT_EQ(1.f
, host_impl_
->active_tree()->CurrentTopControlsShownRatio());
2945 // forcefully hide the top controls by 25px
2946 host_impl_
->top_controls_manager()->ScrollBy(scroll_delta
);
2947 host_impl_
->ScrollEnd();
2949 EXPECT_FLOAT_EQ(scroll_delta
.y(),
2950 top_controls_height_
-
2951 host_impl_
->top_controls_manager()->ContentTopOffset());
2953 inner_scroll
->ClampScrollToMaxScrollOffset();
2954 outer_scroll
->ClampScrollToMaxScrollOffset();
2956 // We should still be fully scrolled.
2957 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2958 host_impl_
->active_tree()->TotalScrollOffset());
2960 viewport_offset
= host_impl_
->active_tree()->TotalScrollOffset();
2962 // Bring the top controls down by 25px.
2963 scroll_delta
= gfx::Vector2dF(0.f
, -25.f
);
2964 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2965 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2966 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2967 host_impl_
->ScrollEnd();
2969 // The viewport offset shouldn't have changed.
2970 EXPECT_EQ(viewport_offset
,
2971 host_impl_
->active_tree()->TotalScrollOffset());
2973 // Scroll the viewports to max scroll offset.
2974 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2975 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2976 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2977 host_impl_
->active_tree()->TotalScrollOffset());
2980 // Test that the top controls coming in and out maintains the same aspect ratio
2981 // between the inner and outer viewports.
2982 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsAspectRatio
) {
2983 SetupTopControlsAndScrollLayerWithVirtualViewport(
2984 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2987 EXPECT_FLOAT_EQ(top_controls_height_
,
2988 host_impl_
->top_controls_manager()->ContentTopOffset());
2990 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2991 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
2992 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
2993 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2994 host_impl_
->ScrollEnd();
2996 EXPECT_FLOAT_EQ(scroll_delta
.y(),
2997 top_controls_height_
-
2998 host_impl_
->top_controls_manager()->ContentTopOffset());
3000 // Top controls were hidden by 25px so the inner viewport should have expanded
3002 LayerImpl
* outer_container
=
3003 host_impl_
->active_tree()->OuterViewportContainerLayer();
3004 LayerImpl
* inner_container
=
3005 host_impl_
->active_tree()->InnerViewportContainerLayer();
3006 EXPECT_EQ(gfx::Size(100, 100+25), inner_container
->BoundsForScrolling());
3008 // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
3009 float aspect_ratio
= inner_container
->BoundsForScrolling().width() /
3010 inner_container
->BoundsForScrolling().height();
3011 gfx::Size expected
= gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio
));
3012 EXPECT_EQ(expected
, outer_container
->BoundsForScrolling());
3014 host_impl_
->InnerViewportScrollLayer()->BoundsForScrolling());
3017 // Test that scrolling the outer viewport affects the top controls.
3018 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsScrollOuterViewport
) {
3019 SetupTopControlsAndScrollLayerWithVirtualViewport(
3020 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
3023 EXPECT_EQ(top_controls_height_
,
3024 host_impl_
->top_controls_manager()->ContentTopOffset());
3026 // Send a gesture scroll that will scroll the outer viewport, make sure the
3027 // top controls get scrolled.
3028 gfx::Vector2dF
scroll_delta(0.f
, 15.f
);
3029 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3030 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3031 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3032 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
3033 host_impl_
->CurrentlyScrollingLayer());
3034 host_impl_
->ScrollEnd();
3036 EXPECT_FLOAT_EQ(scroll_delta
.y(),
3037 top_controls_height_
-
3038 host_impl_
->top_controls_manager()->ContentTopOffset());
3040 scroll_delta
= gfx::Vector2dF(0.f
, 50.f
);
3041 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3042 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3043 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3045 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ContentTopOffset());
3046 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
3047 host_impl_
->CurrentlyScrollingLayer());
3049 host_impl_
->ScrollEnd();
3051 // Position the viewports such that the inner viewport will be scrolled.
3052 gfx::Vector2dF
inner_viewport_offset(0.f
, 25.f
);
3053 host_impl_
->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2dF());
3054 host_impl_
->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset
);
3056 scroll_delta
= gfx::Vector2dF(0.f
, -65.f
);
3057 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3058 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3059 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3061 EXPECT_EQ(top_controls_height_
,
3062 host_impl_
->top_controls_manager()->ContentTopOffset());
3064 inner_viewport_offset
.y() + (scroll_delta
.y() + top_controls_height_
),
3065 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
3067 host_impl_
->ScrollEnd();
3070 TEST_F(LayerTreeHostImplTopControlsTest
,
3071 ScrollNonScrollableRootWithTopControls
) {
3072 CreateHostImpl(settings_
, CreateOutputSurface());
3073 SetupTopControlsAndScrollLayer();
3076 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3077 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3079 host_impl_
->top_controls_manager()->ScrollBegin();
3080 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
3081 host_impl_
->top_controls_manager()->ScrollEnd();
3082 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
3083 // Now that top controls have moved, expect the clip to resize.
3084 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
3085 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
3087 host_impl_
->ScrollEnd();
3089 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3090 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3092 float scroll_increment_y
= -25.f
;
3093 host_impl_
->top_controls_manager()->ScrollBegin();
3094 host_impl_
->top_controls_manager()->ScrollBy(
3095 gfx::Vector2dF(0.f
, scroll_increment_y
));
3096 EXPECT_FLOAT_EQ(-scroll_increment_y
,
3097 host_impl_
->top_controls_manager()->ContentTopOffset());
3098 // Now that top controls have moved, expect the clip to resize.
3099 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
3100 viewport_size_
.height() + scroll_increment_y
),
3101 root_clip_ptr
->bounds());
3103 host_impl_
->top_controls_manager()->ScrollBy(
3104 gfx::Vector2dF(0.f
, scroll_increment_y
));
3105 host_impl_
->top_controls_manager()->ScrollEnd();
3106 EXPECT_FLOAT_EQ(-2 * scroll_increment_y
,
3107 host_impl_
->top_controls_manager()->ContentTopOffset());
3108 // Now that top controls have moved, expect the clip to resize.
3109 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
3111 host_impl_
->ScrollEnd();
3113 // Verify the layer is once-again non-scrollable.
3115 gfx::ScrollOffset(),
3116 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
3118 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3119 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3122 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
3123 // Test the configuration where a non-composited root layer is embedded in a
3124 // scrollable outer layer.
3125 gfx::Size
surface_size(10, 10);
3126 gfx::Size
contents_size(20, 20);
3128 scoped_ptr
<LayerImpl
> content_layer
=
3129 LayerImpl::Create(host_impl_
->active_tree(), 1);
3130 content_layer
->SetDrawsContent(true);
3131 content_layer
->SetPosition(gfx::PointF());
3132 content_layer
->SetBounds(contents_size
);
3133 content_layer
->SetContentBounds(contents_size
);
3134 content_layer
->SetContentsScale(2.f
, 2.f
);
3136 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
3137 LayerImpl::Create(host_impl_
->active_tree(), 3);
3138 scroll_clip_layer
->SetBounds(surface_size
);
3140 scoped_ptr
<LayerImpl
> scroll_layer
=
3141 LayerImpl::Create(host_impl_
->active_tree(), 2);
3142 scroll_layer
->SetScrollClipLayer(3);
3143 scroll_layer
->SetBounds(contents_size
);
3144 scroll_layer
->SetContentBounds(contents_size
);
3145 scroll_layer
->SetPosition(gfx::PointF());
3146 scroll_layer
->AddChild(content_layer
.Pass());
3147 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
3149 scroll_clip_layer
->SetHasRenderSurface(true);
3150 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
3151 host_impl_
->SetViewportSize(surface_size
);
3154 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3155 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3156 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3157 host_impl_
->ScrollEnd();
3158 EXPECT_TRUE(did_request_redraw_
);
3159 EXPECT_TRUE(did_request_commit_
);
3162 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
3163 gfx::Size
surface_size(10, 10);
3164 gfx::Size
contents_size(20, 20);
3165 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3166 root
->SetBounds(surface_size
);
3167 root
->SetContentBounds(contents_size
);
3168 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
3169 root
->SetHasRenderSurface(true);
3170 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3171 host_impl_
->SetViewportSize(surface_size
);
3174 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3175 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3176 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3177 host_impl_
->ScrollEnd();
3178 EXPECT_TRUE(did_request_redraw_
);
3179 EXPECT_TRUE(did_request_commit_
);
3182 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
3183 gfx::Size
surface_size(10, 10);
3184 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3185 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
3186 root
->SetHasRenderSurface(true);
3187 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3188 host_impl_
->SetViewportSize(surface_size
);
3191 // Scroll event is ignored because the input coordinate is outside the layer
3193 EXPECT_EQ(InputHandler::SCROLL_IGNORED
,
3194 host_impl_
->ScrollBegin(gfx::Point(15, 5), InputHandler::WHEEL
));
3195 EXPECT_FALSE(did_request_redraw_
);
3196 EXPECT_FALSE(did_request_commit_
);
3199 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
3200 gfx::Size
surface_size(10, 10);
3201 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3202 root
->SetHasRenderSurface(true);
3203 scoped_ptr
<LayerImpl
> child
=
3204 CreateScrollableLayer(2, surface_size
, root
.get());
3205 host_impl_
->SetViewportSize(surface_size
);
3207 gfx::Transform matrix
;
3208 matrix
.RotateAboutXAxis(180.0);
3209 child
->SetTransform(matrix
);
3210 child
->SetDoubleSided(false);
3212 root
->AddChild(child
.Pass());
3213 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3216 // Scroll event is ignored because the scrollable layer is not facing the
3217 // viewer and there is nothing scrollable behind it.
3218 EXPECT_EQ(InputHandler::SCROLL_IGNORED
,
3219 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3220 EXPECT_FALSE(did_request_redraw_
);
3221 EXPECT_FALSE(did_request_commit_
);
3224 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
3225 gfx::Size
surface_size(10, 10);
3226 scoped_ptr
<LayerImpl
> clip_layer
=
3227 LayerImpl::Create(host_impl_
->active_tree(), 3);
3228 scoped_ptr
<LayerImpl
> content_layer
=
3229 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
3230 content_layer
->SetShouldScrollOnMainThread(true);
3231 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
3233 // Note: we can use the same clip layer for both since both calls to
3234 // CreateScrollableLayer() use the same surface size.
3235 scoped_ptr
<LayerImpl
> scroll_layer
=
3236 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
3237 scroll_layer
->AddChild(content_layer
.Pass());
3238 clip_layer
->AddChild(scroll_layer
.Pass());
3239 clip_layer
->SetHasRenderSurface(true);
3241 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
3242 host_impl_
->SetViewportSize(surface_size
);
3245 // Scrolling fails because the content layer is asking to be scrolled on the
3247 EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD
,
3248 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3251 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
3252 gfx::Size
surface_size(20, 20);
3253 gfx::Size
viewport_size(10, 10);
3254 float page_scale
= 2.f
;
3255 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3256 scoped_ptr
<LayerImpl
> root_clip
=
3257 LayerImpl::Create(host_impl_
->active_tree(), 2);
3258 scoped_ptr
<LayerImpl
> root_scrolling
=
3259 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3260 EXPECT_EQ(viewport_size
, root_clip
->bounds());
3261 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3262 root_clip
->AddChild(root_scrolling
.Pass());
3263 root
->AddChild(root_clip
.Pass());
3264 root
->SetHasRenderSurface(true);
3265 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3266 // The behaviour in this test assumes the page scale is applied at a layer
3267 // above the clip layer.
3268 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 3,
3270 host_impl_
->active_tree()->DidBecomeActive();
3271 host_impl_
->SetViewportSize(viewport_size
);
3274 LayerImpl
* root_scroll
=
3275 host_impl_
->active_tree()->InnerViewportScrollLayer();
3276 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
3278 gfx::Vector2d
scroll_delta(0, 10);
3279 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
3280 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
3281 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3282 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3283 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3284 host_impl_
->ScrollEnd();
3286 // Set new page scale from main thread.
3287 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, page_scale
,
3290 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3291 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
3293 // The scroll range should also have been updated.
3294 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
3296 // The page scale delta remains constant because the impl thread did not
3298 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
3301 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
3302 gfx::Size
surface_size(20, 20);
3303 gfx::Size
viewport_size(10, 10);
3304 float page_scale
= 2.f
;
3305 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3306 scoped_ptr
<LayerImpl
> root_clip
=
3307 LayerImpl::Create(host_impl_
->active_tree(), 2);
3308 scoped_ptr
<LayerImpl
> root_scrolling
=
3309 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3310 EXPECT_EQ(viewport_size
, root_clip
->bounds());
3311 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3312 root_clip
->AddChild(root_scrolling
.Pass());
3313 root
->AddChild(root_clip
.Pass());
3314 root
->SetHasRenderSurface(true);
3315 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3316 // The behaviour in this test assumes the page scale is applied at a layer
3317 // above the clip layer.
3318 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 3,
3320 host_impl_
->active_tree()->DidBecomeActive();
3321 host_impl_
->SetViewportSize(viewport_size
);
3322 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 1.f
, page_scale
);
3325 LayerImpl
* root_scroll
=
3326 host_impl_
->active_tree()->InnerViewportScrollLayer();
3327 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
3329 gfx::Vector2d
scroll_delta(0, 10);
3330 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
3331 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
3332 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3333 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3334 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3335 host_impl_
->ScrollEnd();
3337 // Set new page scale on impl thread by pinching.
3338 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
3339 host_impl_
->PinchGestureBegin();
3340 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
3341 host_impl_
->PinchGestureEnd();
3342 host_impl_
->ScrollEnd();
3345 // The scroll delta is not scaled because the main thread did not scale.
3346 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3347 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
3349 // The scroll range should also have been updated.
3350 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
3352 // The page scale delta should match the new scale on the impl side.
3353 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->current_page_scale_factor());
3356 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
3357 gfx::Size
surface_size(10, 10);
3358 float default_page_scale
= 1.f
;
3359 gfx::Transform default_page_scale_matrix
;
3360 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
3362 float new_page_scale
= 2.f
;
3363 gfx::Transform new_page_scale_matrix
;
3364 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
3366 // Create a normal scrollable root layer and another scrollable child layer.
3367 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
3368 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3369 LayerImpl
* child
= scroll
->children()[0];
3371 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
3372 LayerImpl::Create(host_impl_
->active_tree(), 6);
3373 scoped_ptr
<LayerImpl
> scrollable_child
=
3374 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
3375 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
3376 child
->AddChild(scrollable_child_clip
.Pass());
3377 LayerImpl
* grand_child
= child
->children()[0];
3379 // Set new page scale on impl thread by pinching.
3380 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
3381 host_impl_
->PinchGestureBegin();
3382 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
3383 host_impl_
->PinchGestureEnd();
3384 host_impl_
->ScrollEnd();
3387 EXPECT_EQ(1.f
, root
->contents_scale_x());
3388 EXPECT_EQ(1.f
, root
->contents_scale_y());
3389 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
3390 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
3391 EXPECT_EQ(1.f
, child
->contents_scale_x());
3392 EXPECT_EQ(1.f
, child
->contents_scale_y());
3393 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
3394 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
3396 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
3397 // the page scale delta on the root layer is applied hierarchically.
3398 LayerTreeHostImpl::FrameData frame
;
3399 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3400 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3401 host_impl_
->DidDrawAllLayers(frame
);
3403 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
3404 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
3405 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
3406 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
3407 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
3408 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
3409 EXPECT_EQ(new_page_scale
,
3410 grand_child
->draw_transform().matrix().getDouble(0, 0));
3411 EXPECT_EQ(new_page_scale
,
3412 grand_child
->draw_transform().matrix().getDouble(1, 1));
3415 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
3416 gfx::Size
surface_size(30, 30);
3417 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3418 root
->SetBounds(gfx::Size(5, 5));
3419 root
->SetHasRenderSurface(true);
3420 scoped_ptr
<LayerImpl
> root_scrolling
=
3421 LayerImpl::Create(host_impl_
->active_tree(), 2);
3422 root_scrolling
->SetBounds(surface_size
);
3423 root_scrolling
->SetContentBounds(surface_size
);
3424 root_scrolling
->SetScrollClipLayer(root
->id());
3425 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3426 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
3427 root
->AddChild(root_scrolling
.Pass());
3428 int child_scroll_layer_id
= 3;
3429 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
3430 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
3431 LayerImpl
* child
= child_scrolling
.get();
3432 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
3433 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3434 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3436 host_impl_
->active_tree()->DidBecomeActive();
3437 host_impl_
->SetViewportSize(surface_size
);
3440 gfx::Vector2d
scroll_delta(0, 10);
3441 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
3442 gfx::ScrollOffset
expected_max_scroll(child
->MaxScrollOffset());
3443 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3444 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3445 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3446 host_impl_
->ScrollEnd();
3448 float page_scale
= 2.f
;
3449 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, 1.f
,
3454 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3456 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
3458 // The scroll range should not have changed.
3459 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
3461 // The page scale delta remains constant because the impl thread did not
3463 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
3466 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
3467 // Scroll a child layer beyond its maximum scroll range and make sure the
3468 // parent layer is scrolled on the axis on which the child was unable to
3470 gfx::Size
surface_size(10, 10);
3471 gfx::Size
content_size(20, 20);
3472 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3473 root
->SetBounds(surface_size
);
3474 root
->SetHasRenderSurface(true);
3475 scoped_ptr
<LayerImpl
> grand_child
=
3476 CreateScrollableLayer(3, content_size
, root
.get());
3478 scoped_ptr
<LayerImpl
> child
=
3479 CreateScrollableLayer(2, content_size
, root
.get());
3480 LayerImpl
* grand_child_layer
= grand_child
.get();
3481 child
->AddChild(grand_child
.Pass());
3483 LayerImpl
* child_layer
= child
.get();
3484 root
->AddChild(child
.Pass());
3485 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3486 host_impl_
->active_tree()->DidBecomeActive();
3487 host_impl_
->SetViewportSize(surface_size
);
3488 grand_child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 5));
3489 child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(3, 0));
3493 gfx::Vector2d
scroll_delta(-8, -7);
3494 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3495 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
3496 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3497 host_impl_
->ScrollEnd();
3499 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3500 host_impl_
->ProcessScrollDeltas();
3502 // The grand child should have scrolled up to its limit.
3503 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
3504 LayerImpl
* grand_child
= child
->children()[0];
3505 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
3507 // The child should have only scrolled on the other axis.
3508 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
3512 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
3513 // Scroll a child layer beyond its maximum scroll range and make sure the
3514 // the scroll doesn't bubble up to the parent layer.
3515 gfx::Size
surface_size(20, 20);
3516 gfx::Size
viewport_size(10, 10);
3517 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3518 root
->SetHasRenderSurface(true);
3519 scoped_ptr
<LayerImpl
> root_scrolling
=
3520 CreateScrollableLayer(2, surface_size
, root
.get());
3521 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3523 scoped_ptr
<LayerImpl
> grand_child
=
3524 CreateScrollableLayer(4, surface_size
, root
.get());
3526 scoped_ptr
<LayerImpl
> child
=
3527 CreateScrollableLayer(3, surface_size
, root
.get());
3528 LayerImpl
* grand_child_layer
= grand_child
.get();
3529 child
->AddChild(grand_child
.Pass());
3531 LayerImpl
* child_layer
= child
.get();
3532 root_scrolling
->AddChild(child
.Pass());
3533 root
->AddChild(root_scrolling
.Pass());
3534 EXPECT_EQ(viewport_size
, root
->bounds());
3535 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3536 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3538 host_impl_
->active_tree()->DidBecomeActive();
3539 host_impl_
->SetViewportSize(viewport_size
);
3541 grand_child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 2));
3542 child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 3));
3546 gfx::Vector2d
scroll_delta(0, -10);
3547 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3548 host_impl_
->ScrollBegin(gfx::Point(),
3549 InputHandler::NON_BUBBLING_GESTURE
));
3550 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3551 host_impl_
->ScrollEnd();
3553 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3554 host_impl_
->ProcessScrollDeltas();
3556 // The grand child should have scrolled up to its limit.
3558 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
3559 LayerImpl
* grand_child
= child
->children()[0];
3560 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3562 // The child should not have scrolled.
3563 ExpectNone(*scroll_info
.get(), child
->id());
3565 // The next time we scroll we should only scroll the parent.
3566 scroll_delta
= gfx::Vector2d(0, -3);
3567 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3568 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3569 InputHandler::NON_BUBBLING_GESTURE
));
3570 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3571 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3572 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
3573 host_impl_
->ScrollEnd();
3575 scroll_info
= host_impl_
->ProcessScrollDeltas();
3577 // The child should have scrolled up to its limit.
3578 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3580 // The grand child should not have scrolled.
3581 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3583 // After scrolling the parent, another scroll on the opposite direction
3584 // should still scroll the child.
3585 scroll_delta
= gfx::Vector2d(0, 7);
3586 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3587 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3588 InputHandler::NON_BUBBLING_GESTURE
));
3589 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3590 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3591 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3592 host_impl_
->ScrollEnd();
3594 scroll_info
= host_impl_
->ProcessScrollDeltas();
3596 // The grand child should have scrolled.
3597 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
3599 // The child should not have scrolled.
3600 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3603 // Scrolling should be adjusted from viewport space.
3604 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 2.f
, 2.f
);
3605 host_impl_
->SetPageScaleOnActiveTree(2.f
);
3607 scroll_delta
= gfx::Vector2d(0, -2);
3608 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3609 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3610 InputHandler::NON_BUBBLING_GESTURE
));
3611 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
3612 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3613 host_impl_
->ScrollEnd();
3615 scroll_info
= host_impl_
->ProcessScrollDeltas();
3617 // Should have scrolled by half the amount in layer space (5 - 2/2)
3618 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
3621 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
3622 // When we try to scroll a non-scrollable child layer, the scroll delta
3623 // should be applied to one of its ancestors if possible.
3624 gfx::Size
surface_size(10, 10);
3625 gfx::Size
content_size(20, 20);
3626 scoped_ptr
<LayerImpl
> root_clip
=
3627 LayerImpl::Create(host_impl_
->active_tree(), 3);
3628 root_clip
->SetHasRenderSurface(true);
3629 scoped_ptr
<LayerImpl
> root
=
3630 CreateScrollableLayer(1, content_size
, root_clip
.get());
3631 // Make 'root' the clip layer for child: since they have the same sizes the
3632 // child will have zero max_scroll_offset and scrolls will bubble.
3633 scoped_ptr
<LayerImpl
> child
=
3634 CreateScrollableLayer(2, content_size
, root
.get());
3635 child
->SetIsContainerForFixedPositionLayers(true);
3636 root
->SetBounds(content_size
);
3638 int root_scroll_id
= root
->id();
3639 root
->AddChild(child
.Pass());
3640 root_clip
->AddChild(root
.Pass());
3642 host_impl_
->SetViewportSize(surface_size
);
3643 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3644 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 2,
3646 host_impl_
->active_tree()->DidBecomeActive();
3649 gfx::Vector2d
scroll_delta(0, 4);
3650 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3651 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3652 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3653 host_impl_
->ScrollEnd();
3655 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3656 host_impl_
->ProcessScrollDeltas();
3658 // Only the root scroll should have scrolled.
3659 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
3660 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
3664 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
3665 gfx::Size
surface_size(10, 10);
3666 scoped_ptr
<LayerImpl
> root_clip
=
3667 LayerImpl::Create(host_impl_
->active_tree(), 1);
3668 scoped_ptr
<LayerImpl
> root_scroll
=
3669 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3670 root_scroll
->SetIsContainerForFixedPositionLayers(true);
3671 root_clip
->SetHasRenderSurface(true);
3672 root_clip
->AddChild(root_scroll
.Pass());
3673 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3674 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3676 host_impl_
->active_tree()->DidBecomeActive();
3677 host_impl_
->SetViewportSize(surface_size
);
3679 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
3682 host_impl_
->active_tree()->DetachLayerTree();
3683 scoped_ptr
<LayerImpl
> root_clip2
=
3684 LayerImpl::Create(host_impl_
->active_tree(), 3);
3685 scoped_ptr
<LayerImpl
> root_scroll2
=
3686 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
3687 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
3688 root_clip2
->AddChild(root_scroll2
.Pass());
3689 root_clip2
->SetHasRenderSurface(true);
3690 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
3691 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 4,
3693 host_impl_
->active_tree()->DidBecomeActive();
3695 // Scrolling should still work even though we did not draw yet.
3696 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3697 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
3700 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
3701 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3703 // Rotate the root layer 90 degrees counter-clockwise about its center.
3704 gfx::Transform rotate_transform
;
3705 rotate_transform
.Rotate(-90.0);
3706 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
3708 gfx::Size
surface_size(50, 50);
3709 host_impl_
->SetViewportSize(surface_size
);
3712 // Scroll to the right in screen coordinates with a gesture.
3713 gfx::Vector2d
gesture_scroll_delta(10, 0);
3714 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3715 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3716 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3717 host_impl_
->ScrollEnd();
3719 // The layer should have scrolled down in its local coordinates.
3720 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3721 ExpectContains(*scroll_info
.get(), scroll_layer
->id(),
3722 gfx::Vector2dF(0, gesture_scroll_delta
.x()));
3724 // Reset and scroll down with the wheel.
3725 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3726 gfx::Vector2d
wheel_scroll_delta(0, 10);
3727 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3728 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
3729 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3730 host_impl_
->ScrollEnd();
3732 // The layer should have scrolled down in its local coordinates.
3733 scroll_info
= host_impl_
->ProcessScrollDeltas();
3734 ExpectContains(*scroll_info
.get(),
3736 wheel_scroll_delta
);
3739 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
3740 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3741 int child_clip_layer_id
= 6;
3742 int child_layer_id
= 7;
3743 float child_layer_angle
= -20.f
;
3745 // Create a child layer that is rotated to a non-axis-aligned angle.
3746 scoped_ptr
<LayerImpl
> clip_layer
=
3747 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
3748 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
3749 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
3750 gfx::Transform rotate_transform
;
3751 rotate_transform
.Translate(-50.0, -50.0);
3752 rotate_transform
.Rotate(child_layer_angle
);
3753 rotate_transform
.Translate(50.0, 50.0);
3754 clip_layer
->SetTransform(rotate_transform
);
3756 // Only allow vertical scrolling.
3757 clip_layer
->SetBounds(
3758 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
3759 // The rotation depends on the layer's transform origin, and the child layer
3760 // is a different size than the clip, so make sure the clip layer's origin
3761 // lines up over the child.
3762 clip_layer
->SetTransformOrigin(gfx::Point3F(
3763 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
3764 LayerImpl
* child_ptr
= child
.get();
3765 clip_layer
->AddChild(child
.Pass());
3766 scroll_layer
->AddChild(clip_layer
.Pass());
3768 gfx::Size
surface_size(50, 50);
3769 host_impl_
->SetViewportSize(surface_size
);
3772 // Scroll down in screen coordinates with a gesture.
3773 gfx::Vector2d
gesture_scroll_delta(0, 10);
3774 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3775 host_impl_
->ScrollBegin(gfx::Point(1, 1), InputHandler::GESTURE
));
3776 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3777 host_impl_
->ScrollEnd();
3779 // The child layer should have scrolled down in its local coordinates an
3780 // amount proportional to the angle between it and the input scroll delta.
3781 gfx::Vector2dF
expected_scroll_delta(
3782 0, gesture_scroll_delta
.y() *
3783 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
3784 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3785 host_impl_
->ProcessScrollDeltas();
3786 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3788 // The root scroll layer should not have scrolled, because the input delta
3789 // was close to the layer's axis of movement.
3790 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
3793 // Now reset and scroll the same amount horizontally.
3794 child_ptr
->SetScrollDelta(gfx::Vector2dF());
3795 gfx::Vector2d
gesture_scroll_delta(10, 0);
3796 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3797 host_impl_
->ScrollBegin(gfx::Point(1, 1), InputHandler::GESTURE
));
3798 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3799 host_impl_
->ScrollEnd();
3801 // The child layer should have scrolled down in its local coordinates an
3802 // amount proportional to the angle between it and the input scroll delta.
3803 gfx::Vector2dF
expected_scroll_delta(
3804 0, -gesture_scroll_delta
.x() *
3805 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
3806 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3807 host_impl_
->ProcessScrollDeltas();
3808 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3810 // The root scroll layer should have scrolled more, since the input scroll
3811 // delta was mostly orthogonal to the child layer's vertical scroll axis.
3812 gfx::Vector2dF
expected_root_scroll_delta(
3813 gesture_scroll_delta
.x() *
3814 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
3816 ExpectContains(*scroll_info
.get(),
3818 expected_root_scroll_delta
);
3822 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
3823 LayerImpl
* scroll_layer
=
3824 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3826 // Scale the layer to twice its normal size.
3828 gfx::Transform scale_transform
;
3829 scale_transform
.Scale(scale
, scale
);
3830 scroll_layer
->SetTransform(scale_transform
);
3832 gfx::Size
surface_size(50, 50);
3833 host_impl_
->SetViewportSize(surface_size
);
3836 // Scroll down in screen coordinates with a gesture.
3837 gfx::Vector2d
scroll_delta(0, 10);
3838 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3839 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
3840 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3841 host_impl_
->ScrollEnd();
3843 // The layer should have scrolled down in its local coordinates, but half the
3845 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3846 ExpectContains(*scroll_info
.get(),
3848 gfx::Vector2d(0, scroll_delta
.y() / scale
));
3850 // Reset and scroll down with the wheel.
3851 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3852 gfx::Vector2d
wheel_scroll_delta(0, 10);
3853 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
3854 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
3855 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3856 host_impl_
->ScrollEnd();
3858 // It should apply the scale factor to the scroll delta for the wheel event.
3859 scroll_info
= host_impl_
->ProcessScrollDeltas();
3860 ExpectContains(*scroll_info
.get(),
3862 wheel_scroll_delta
);
3865 TEST_F(LayerTreeHostImplTest
, ScrollViewportRounding
) {
3869 SetupScrollAndContentsLayers(gfx::Size(width
, height
));
3870 host_impl_
->active_tree()->InnerViewportContainerLayer()->SetBounds(
3871 gfx::Size(width
* scale
- 1, height
* scale
));
3872 host_impl_
->SetDeviceScaleFactor(scale
);
3873 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
3875 LayerImpl
* inner_viewport_scroll_layer
=
3876 host_impl_
->active_tree()->InnerViewportScrollLayer();
3877 EXPECT_EQ(gfx::ScrollOffset(0, 0),
3878 inner_viewport_scroll_layer
->MaxScrollOffset());
3881 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3883 TestScrollOffsetDelegate()
3884 : page_scale_factor_(0.f
),
3885 min_page_scale_factor_(-1.f
),
3886 max_page_scale_factor_(-1.f
) {}
3888 ~TestScrollOffsetDelegate() override
{}
3890 gfx::ScrollOffset
GetTotalScrollOffset() override
{
3891 return getter_return_value_
;
3894 bool IsExternalFlingActive() const override
{ return false; }
3896 void UpdateRootLayerState(const gfx::ScrollOffset
& total_scroll_offset
,
3897 const gfx::ScrollOffset
& max_scroll_offset
,
3898 const gfx::SizeF
& scrollable_size
,
3899 float page_scale_factor
,
3900 float min_page_scale_factor
,
3901 float max_page_scale_factor
) override
{
3902 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3903 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3904 last_set_scroll_offset_
= total_scroll_offset
;
3905 max_scroll_offset_
= max_scroll_offset
;
3906 scrollable_size_
= scrollable_size
;
3907 page_scale_factor_
= page_scale_factor
;
3908 min_page_scale_factor_
= min_page_scale_factor
;
3909 max_page_scale_factor_
= max_page_scale_factor
;
3911 set_getter_return_value(last_set_scroll_offset_
);
3914 gfx::ScrollOffset
last_set_scroll_offset() {
3915 return last_set_scroll_offset_
;
3918 void set_getter_return_value(const gfx::ScrollOffset
& value
) {
3919 getter_return_value_
= value
;
3922 gfx::ScrollOffset
max_scroll_offset() const {
3923 return max_scroll_offset_
;
3926 gfx::SizeF
scrollable_size() const {
3927 return scrollable_size_
;
3930 float page_scale_factor() const {
3931 return page_scale_factor_
;
3934 float min_page_scale_factor() const {
3935 return min_page_scale_factor_
;
3938 float max_page_scale_factor() const {
3939 return max_page_scale_factor_
;
3943 gfx::ScrollOffset last_set_scroll_offset_
;
3944 gfx::ScrollOffset getter_return_value_
;
3945 gfx::ScrollOffset max_scroll_offset_
;
3946 gfx::SizeF scrollable_size_
;
3947 float page_scale_factor_
;
3948 float min_page_scale_factor_
;
3949 float max_page_scale_factor_
;
3952 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3953 TestScrollOffsetDelegate scroll_delegate
;
3954 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3955 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3956 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3957 clip_layer
->SetBounds(gfx::Size(10, 20));
3959 // Setting the delegate results in the current scroll offset being set.
3960 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3961 scroll_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
3962 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3963 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3964 EXPECT_EQ(initial_scroll_delta
.ToString(),
3965 scroll_delegate
.last_set_scroll_offset().ToString());
3967 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3968 // page_scale_factor and {min|max}_page_scale_factor being set.
3969 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3970 EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate
.max_scroll_offset());
3971 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3972 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3973 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3975 // Updating page scale immediately updates the delegate.
3976 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 0.5f
, 4.f
);
3977 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3978 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3979 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3980 host_impl_
->SetPageScaleOnActiveTree(2.f
* 1.5f
);
3981 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3982 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3983 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3984 host_impl_
->SetPageScaleOnActiveTree(2.f
);
3985 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
3986 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3987 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3988 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3990 // The pinch gesture doesn't put the delegate into a state where the scroll
3991 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3993 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
3994 host_impl_
->PinchGestureBegin();
3995 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3996 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3997 host_impl_
->PinchGestureEnd();
3998 host_impl_
->ScrollEnd();
4000 // Scrolling should be relative to the offset as returned by the delegate.
4001 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
4002 gfx::ScrollOffset
current_offset(7.f
, 8.f
);
4004 scroll_delegate
.set_getter_return_value(current_offset
);
4005 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4006 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
4008 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4009 EXPECT_EQ(ScrollOffsetWithDelta(current_offset
, scroll_delta
),
4010 scroll_delegate
.last_set_scroll_offset());
4012 current_offset
= gfx::ScrollOffset(42.f
, 41.f
);
4013 scroll_delegate
.set_getter_return_value(current_offset
);
4014 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4015 EXPECT_EQ(current_offset
+ gfx::ScrollOffset(scroll_delta
),
4016 scroll_delegate
.last_set_scroll_offset());
4017 host_impl_
->ScrollEnd();
4018 scroll_delegate
.set_getter_return_value(gfx::ScrollOffset());
4020 // Forces a full tree synchronization and ensures that the scroll delegate
4021 // sees the correct size of the new tree.
4022 gfx::Size
new_size(42, 24);
4023 host_impl_
->CreatePendingTree();
4024 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
4025 host_impl_
->ActivateSyncTree();
4026 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
4028 // Un-setting the delegate should propagate the delegate's current offset to
4029 // the root scrollable layer.
4030 current_offset
= gfx::ScrollOffset(13.f
, 12.f
);
4031 scroll_delegate
.set_getter_return_value(current_offset
);
4032 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
4034 EXPECT_EQ(current_offset
.ToString(),
4035 scroll_layer
->CurrentScrollOffset().ToString());
4038 void CheckLayerScrollDelta(LayerImpl
* layer
, gfx::Vector2dF scroll_delta
) {
4039 const gfx::Transform target_space_transform
=
4040 layer
->draw_properties().target_space_transform
;
4041 EXPECT_TRUE(target_space_transform
.IsScaleOrTranslation());
4042 gfx::Point translated_point
;
4043 target_space_transform
.TransformPoint(&translated_point
);
4044 gfx::Point expected_point
= gfx::Point() - ToRoundedVector2d(scroll_delta
);
4045 EXPECT_EQ(expected_point
.ToString(), translated_point
.ToString());
4048 TEST_F(LayerTreeHostImplTest
,
4049 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw
) {
4050 TestScrollOffsetDelegate scroll_delegate
;
4051 host_impl_
->SetViewportSize(gfx::Size(10, 20));
4052 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
4053 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
4054 clip_layer
->SetBounds(gfx::Size(10, 20));
4055 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
4057 // Draw first frame to clear any pending draws and check scroll.
4059 CheckLayerScrollDelta(scroll_layer
, gfx::Vector2dF(0.f
, 0.f
));
4060 EXPECT_FALSE(host_impl_
->active_tree()->needs_update_draw_properties());
4062 // Set external scroll delta on delegate and notify LayerTreeHost.
4063 gfx::ScrollOffset
scroll_offset(10.f
, 10.f
);
4064 scroll_delegate
.set_getter_return_value(scroll_offset
);
4065 host_impl_
->OnRootLayerDelegatedScrollOffsetChanged();
4067 // Check scroll delta reflected in layer.
4068 LayerTreeHostImpl::FrameData frame
;
4069 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4070 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4071 host_impl_
->DidDrawAllLayers(frame
);
4072 EXPECT_FALSE(frame
.has_no_damage
);
4073 CheckLayerScrollDelta(scroll_layer
, ScrollOffsetToVector2dF(scroll_offset
));
4075 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
4078 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
4079 InputHandlerScrollResult scroll_result
;
4080 SetupScrollAndContentsLayers(gfx::Size(100, 100));
4081 host_impl_
->SetViewportSize(gfx::Size(50, 50));
4082 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
4084 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4086 // In-bounds scrolling does not affect overscroll.
4087 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4088 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
4089 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
4090 EXPECT_TRUE(scroll_result
.did_scroll
);
4091 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
4092 EXPECT_EQ(gfx::Vector2dF(), scroll_result
.unused_scroll_delta
);
4093 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4095 // Overscroll events are reflected immediately.
4096 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
4097 EXPECT_TRUE(scroll_result
.did_scroll
);
4098 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4099 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result
.unused_scroll_delta
);
4100 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
4101 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4102 host_impl_
->accumulated_root_overscroll());
4104 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
4105 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
4106 EXPECT_TRUE(scroll_result
.did_scroll
);
4107 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
4108 EXPECT_EQ(gfx::Vector2dF(), scroll_result
.unused_scroll_delta
);
4109 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
4110 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4111 host_impl_
->accumulated_root_overscroll());
4113 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
4114 EXPECT_FALSE(scroll_result
.did_scroll
);
4115 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4116 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
4117 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
4118 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4119 host_impl_
->accumulated_root_overscroll());
4121 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
4122 EXPECT_TRUE(scroll_result
.did_scroll
);
4123 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
4124 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result
.unused_scroll_delta
);
4125 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
4126 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4127 host_impl_
->accumulated_root_overscroll());
4129 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
4130 EXPECT_TRUE(scroll_result
.did_scroll
);
4131 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4132 EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result
.unused_scroll_delta
);
4133 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
4134 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4135 host_impl_
->accumulated_root_overscroll());
4137 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
4138 EXPECT_TRUE(scroll_result
.did_scroll
);
4139 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4140 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result
.unused_scroll_delta
);
4141 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
4142 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4143 host_impl_
->accumulated_root_overscroll());
4145 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
4146 EXPECT_TRUE(scroll_result
.did_scroll
);
4147 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4148 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
4149 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
4150 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4151 host_impl_
->accumulated_root_overscroll());
4153 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
4154 // as no scroll occurs.
4155 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
4156 EXPECT_FALSE(scroll_result
.did_scroll
);
4157 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4158 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result
.unused_scroll_delta
);
4159 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
4160 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4161 host_impl_
->accumulated_root_overscroll());
4163 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
4164 EXPECT_FALSE(scroll_result
.did_scroll
);
4165 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4166 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result
.unused_scroll_delta
);
4167 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
4168 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4169 host_impl_
->accumulated_root_overscroll());
4171 // Overscroll resets on valid scroll.
4172 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
4173 EXPECT_TRUE(scroll_result
.did_scroll
);
4174 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
4175 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result
.unused_scroll_delta
);
4176 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
4177 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4178 host_impl_
->accumulated_root_overscroll());
4180 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
4181 EXPECT_TRUE(scroll_result
.did_scroll
);
4182 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
4183 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
4184 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
4185 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
4186 host_impl_
->accumulated_root_overscroll());
4188 host_impl_
->ScrollEnd();
4192 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
4193 // Scroll child layers beyond their maximum scroll range and make sure root
4194 // overscroll does not accumulate.
4195 gfx::Size
surface_size(10, 10);
4196 scoped_ptr
<LayerImpl
> root_clip
=
4197 LayerImpl::Create(host_impl_
->active_tree(), 4);
4198 root_clip
->SetHasRenderSurface(true);
4200 scoped_ptr
<LayerImpl
> root
=
4201 CreateScrollableLayer(1, surface_size
, root_clip
.get());
4203 scoped_ptr
<LayerImpl
> grand_child
=
4204 CreateScrollableLayer(3, surface_size
, root_clip
.get());
4206 scoped_ptr
<LayerImpl
> child
=
4207 CreateScrollableLayer(2, surface_size
, root_clip
.get());
4208 LayerImpl
* grand_child_layer
= grand_child
.get();
4209 child
->AddChild(grand_child
.Pass());
4211 LayerImpl
* child_layer
= child
.get();
4212 root
->AddChild(child
.Pass());
4213 root_clip
->AddChild(root
.Pass());
4214 child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 3));
4215 grand_child_layer
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 2));
4216 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4217 host_impl_
->active_tree()->DidBecomeActive();
4218 host_impl_
->SetViewportSize(surface_size
);
4221 gfx::Vector2d
scroll_delta(0, -10);
4222 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4223 host_impl_
->ScrollBegin(gfx::Point(),
4224 InputHandler::NON_BUBBLING_GESTURE
));
4225 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4226 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4227 host_impl_
->ScrollEnd();
4229 // The next time we scroll we should only scroll the parent, but overscroll
4230 // should still not reach the root layer.
4231 scroll_delta
= gfx::Vector2d(0, -30);
4232 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4233 host_impl_
->ScrollBegin(gfx::Point(5, 5),
4234 InputHandler::NON_BUBBLING_GESTURE
));
4235 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
4236 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4237 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4238 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
4239 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4240 host_impl_
->ScrollEnd();
4242 // After scrolling the parent, another scroll on the opposite direction
4243 // should scroll the child.
4244 scroll_delta
= gfx::Vector2d(0, 70);
4245 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4246 host_impl_
->ScrollBegin(gfx::Point(5, 5),
4247 InputHandler::NON_BUBBLING_GESTURE
));
4248 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
4249 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4250 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
4251 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4252 host_impl_
->ScrollEnd();
4256 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
4257 // When we try to scroll a non-scrollable child layer, the scroll delta
4258 // should be applied to one of its ancestors if possible. Overscroll should
4259 // be reflected only when it has bubbled up to the root scrolling layer.
4260 gfx::Size
surface_size(10, 10);
4261 gfx::Size
content_size(20, 20);
4262 scoped_ptr
<LayerImpl
> root_clip
=
4263 LayerImpl::Create(host_impl_
->active_tree(), 3);
4264 root_clip
->SetHasRenderSurface(true);
4266 scoped_ptr
<LayerImpl
> root
=
4267 CreateScrollableLayer(1, content_size
, root_clip
.get());
4268 root
->SetIsContainerForFixedPositionLayers(true);
4269 scoped_ptr
<LayerImpl
> child
=
4270 CreateScrollableLayer(2, content_size
, root_clip
.get());
4272 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4273 root
->AddChild(child
.Pass());
4274 root_clip
->AddChild(root
.Pass());
4276 host_impl_
->SetViewportSize(surface_size
);
4277 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4278 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4280 host_impl_
->active_tree()->DidBecomeActive();
4283 gfx::Vector2d
scroll_delta(0, 8);
4284 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4285 host_impl_
->ScrollBegin(gfx::Point(5, 5), InputHandler::WHEEL
));
4286 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4287 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4288 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4289 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
4290 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4291 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
4292 host_impl_
->ScrollEnd();
4296 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
4297 LayerTreeSettings settings
;
4298 CreateHostImpl(settings
, CreateOutputSurface());
4300 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
4301 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
4302 clip_layer
->SetBounds(gfx::Size(50, 50));
4303 host_impl_
->SetViewportSize(gfx::Size(50, 50));
4304 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
4306 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4308 // Even though the layer can't scroll the overscroll still happens.
4309 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4310 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
4311 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
4312 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
4315 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
4316 gfx::Size
surface_size(980, 1439);
4317 gfx::Size
content_size(980, 1438);
4318 float device_scale_factor
= 1.5f
;
4319 scoped_ptr
<LayerImpl
> root_clip
=
4320 LayerImpl::Create(host_impl_
->active_tree(), 3);
4321 root_clip
->SetHasRenderSurface(true);
4323 scoped_ptr
<LayerImpl
> root
=
4324 CreateScrollableLayer(1, content_size
, root_clip
.get());
4325 root
->SetIsContainerForFixedPositionLayers(true);
4326 scoped_ptr
<LayerImpl
> child
=
4327 CreateScrollableLayer(2, content_size
, root_clip
.get());
4328 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
4329 host_impl_
->active_tree()->PushPageScaleFromMainThread(0.326531f
, 0.326531f
,
4331 host_impl_
->SetPageScaleOnActiveTree(0.326531f
);
4332 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4333 root
->AddChild(child
.Pass());
4334 root_clip
->AddChild(root
.Pass());
4336 host_impl_
->SetViewportSize(surface_size
);
4337 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4338 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4339 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4341 host_impl_
->active_tree()->DidBecomeActive();
4344 // Horizontal & Vertical GlowEffect should not be applied when
4345 // content size is less then view port size. For Example Horizontal &
4346 // vertical GlowEffect should not be applied in about:blank page.
4347 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4348 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL
));
4349 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
4350 EXPECT_EQ(gfx::Vector2dF().ToString(),
4351 host_impl_
->accumulated_root_overscroll().ToString());
4353 host_impl_
->ScrollEnd();
4357 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
4358 gfx::Size
surface_size(100, 100);
4359 gfx::Size
content_size(200, 200);
4360 scoped_ptr
<LayerImpl
> root_clip
=
4361 LayerImpl::Create(host_impl_
->active_tree(), 3);
4362 root_clip
->SetHasRenderSurface(true);
4364 scoped_ptr
<LayerImpl
> root
=
4365 CreateScrollableLayer(1, content_size
, root_clip
.get());
4366 root
->SetIsContainerForFixedPositionLayers(true);
4367 scoped_ptr
<LayerImpl
> child
=
4368 CreateScrollableLayer(2, content_size
, root_clip
.get());
4370 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4371 root
->AddChild(child
.Pass());
4372 root_clip
->AddChild(root
.Pass());
4374 host_impl_
->SetViewportSize(surface_size
);
4375 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4376 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4378 host_impl_
->active_tree()->DidBecomeActive();
4381 // Edge glow effect should be applicable only upon reaching Edges
4382 // of the content. unnecessary glow effect calls shouldn't be
4383 // called while scrolling up without reaching the edge of the content.
4384 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4385 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL
));
4386 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
4387 EXPECT_EQ(gfx::Vector2dF().ToString(),
4388 host_impl_
->accumulated_root_overscroll().ToString());
4389 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
4390 EXPECT_EQ(gfx::Vector2dF().ToString(),
4391 host_impl_
->accumulated_root_overscroll().ToString());
4392 host_impl_
->ScrollEnd();
4393 // unusedrootDelta should be subtracted from applied delta so that
4394 // unwanted glow effect calls are not called.
4395 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4396 host_impl_
->ScrollBegin(gfx::Point(0, 0),
4397 InputHandler::NON_BUBBLING_GESTURE
));
4398 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
4399 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
4400 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
4401 host_impl_
->accumulated_root_overscroll().ToString());
4403 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
4404 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
4405 host_impl_
->accumulated_root_overscroll().ToString());
4406 host_impl_
->ScrollEnd();
4407 // TestCase to check kEpsilon, which prevents minute values to trigger
4408 // gloweffect without reaching edge.
4409 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
4410 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::WHEEL
));
4411 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
4412 EXPECT_EQ(gfx::Vector2dF().ToString(),
4413 host_impl_
->accumulated_root_overscroll().ToString());
4414 host_impl_
->ScrollEnd();
4418 class BlendStateCheckLayer
: public LayerImpl
{
4420 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4422 ResourceProvider
* resource_provider
) {
4423 return make_scoped_ptr(
4424 new BlendStateCheckLayer(tree_impl
, id
, resource_provider
));
4427 void AppendQuads(RenderPass
* render_pass
,
4428 AppendQuadsData
* append_quads_data
) override
{
4429 quads_appended_
= true;
4431 gfx::Rect opaque_rect
;
4432 if (contents_opaque())
4433 opaque_rect
= quad_rect_
;
4435 opaque_rect
= opaque_content_rect_
;
4436 gfx::Rect visible_quad_rect
= quad_rect_
;
4438 SharedQuadState
* shared_quad_state
=
4439 render_pass
->CreateAndAppendSharedQuadState();
4440 PopulateSharedQuadState(shared_quad_state
);
4442 TileDrawQuad
* test_blending_draw_quad
=
4443 render_pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
4444 test_blending_draw_quad
->SetNew(shared_quad_state
,
4449 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
4453 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
4454 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
4455 EXPECT_EQ(has_render_surface_
, !!render_surface());
4458 void SetExpectation(bool blend
, bool has_render_surface
) {
4460 has_render_surface_
= has_render_surface
;
4461 quads_appended_
= false;
4464 bool quads_appended() const { return quads_appended_
; }
4466 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
4467 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
4468 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
4469 opaque_content_rect_
= rect
;
4473 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
4475 ResourceProvider
* resource_provider
)
4476 : LayerImpl(tree_impl
, id
),
4478 has_render_surface_(false),
4479 quads_appended_(false),
4480 quad_rect_(5, 5, 5, 5),
4481 quad_visible_rect_(5, 5, 5, 5),
4482 resource_id_(resource_provider
->CreateResource(
4485 ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
4487 resource_provider
->AllocateForTesting(resource_id_
);
4488 SetBounds(gfx::Size(10, 10));
4489 SetContentBounds(gfx::Size(10, 10));
4490 SetDrawsContent(true);
4494 bool has_render_surface_
;
4495 bool quads_appended_
;
4496 gfx::Rect quad_rect_
;
4497 gfx::Rect opaque_content_rect_
;
4498 gfx::Rect quad_visible_rect_
;
4499 ResourceProvider::ResourceId resource_id_
;
4502 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
4504 scoped_ptr
<LayerImpl
> root
=
4505 LayerImpl::Create(host_impl_
->active_tree(), 1);
4506 root
->SetBounds(gfx::Size(10, 10));
4507 root
->SetContentBounds(root
->bounds());
4508 root
->SetDrawsContent(false);
4509 root
->SetHasRenderSurface(true);
4510 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4512 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4515 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4517 host_impl_
->resource_provider()));
4518 BlendStateCheckLayer
* layer1
=
4519 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
4520 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
4522 LayerTreeHostImpl::FrameData frame
;
4524 // Opaque layer, drawn without blending.
4525 layer1
->SetContentsOpaque(true);
4526 layer1
->SetExpectation(false, false);
4527 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4528 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4529 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4530 EXPECT_TRUE(layer1
->quads_appended());
4531 host_impl_
->DidDrawAllLayers(frame
);
4533 // Layer with translucent content and painting, so drawn with blending.
4534 layer1
->SetContentsOpaque(false);
4535 layer1
->SetExpectation(true, false);
4536 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4537 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4538 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4539 EXPECT_TRUE(layer1
->quads_appended());
4540 host_impl_
->DidDrawAllLayers(frame
);
4542 // Layer with translucent opacity, drawn with blending.
4543 layer1
->SetContentsOpaque(true);
4544 layer1
->SetOpacity(0.5f
);
4545 layer1
->SetExpectation(true, false);
4546 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4547 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4548 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4549 EXPECT_TRUE(layer1
->quads_appended());
4550 host_impl_
->DidDrawAllLayers(frame
);
4552 // Layer with translucent opacity and painting, drawn with blending.
4553 layer1
->SetContentsOpaque(true);
4554 layer1
->SetOpacity(0.5f
);
4555 layer1
->SetExpectation(true, false);
4556 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4557 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4558 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4559 EXPECT_TRUE(layer1
->quads_appended());
4560 host_impl_
->DidDrawAllLayers(frame
);
4563 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4565 host_impl_
->resource_provider()));
4566 BlendStateCheckLayer
* layer2
=
4567 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
4568 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
4570 // 2 opaque layers, drawn without blending.
4571 layer1
->SetContentsOpaque(true);
4572 layer1
->SetOpacity(1.f
);
4573 layer1
->SetExpectation(false, false);
4574 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4575 layer2
->SetContentsOpaque(true);
4576 layer2
->SetOpacity(1.f
);
4577 layer2
->SetExpectation(false, false);
4578 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4579 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4580 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4581 EXPECT_TRUE(layer1
->quads_appended());
4582 EXPECT_TRUE(layer2
->quads_appended());
4583 host_impl_
->DidDrawAllLayers(frame
);
4585 // Parent layer with translucent content, drawn with blending.
4586 // Child layer with opaque content, drawn without blending.
4587 layer1
->SetContentsOpaque(false);
4588 layer1
->SetExpectation(true, false);
4589 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4590 layer2
->SetExpectation(false, false);
4591 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4592 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4593 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4594 EXPECT_TRUE(layer1
->quads_appended());
4595 EXPECT_TRUE(layer2
->quads_appended());
4596 host_impl_
->DidDrawAllLayers(frame
);
4598 // Parent layer with translucent content but opaque painting, drawn without
4600 // Child layer with opaque content, drawn without blending.
4601 layer1
->SetContentsOpaque(true);
4602 layer1
->SetExpectation(false, false);
4603 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4604 layer2
->SetExpectation(false, false);
4605 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4606 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4607 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4608 EXPECT_TRUE(layer1
->quads_appended());
4609 EXPECT_TRUE(layer2
->quads_appended());
4610 host_impl_
->DidDrawAllLayers(frame
);
4612 // Parent layer with translucent opacity and opaque content. Since it has a
4613 // drawing child, it's drawn to a render surface which carries the opacity,
4614 // so it's itself drawn without blending.
4615 // Child layer with opaque content, drawn without blending (parent surface
4616 // carries the inherited opacity).
4617 layer1
->SetContentsOpaque(true);
4618 layer1
->SetOpacity(0.5f
);
4619 layer1
->SetHasRenderSurface(true);
4620 layer1
->SetExpectation(false, true);
4621 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4622 layer2
->SetExpectation(false, false);
4623 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4624 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
4625 host_impl_
->active_tree()->root_layer());
4626 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4627 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4628 EXPECT_TRUE(layer1
->quads_appended());
4629 EXPECT_TRUE(layer2
->quads_appended());
4630 host_impl_
->DidDrawAllLayers(frame
);
4631 layer1
->SetHasRenderSurface(false);
4633 // Draw again, but with child non-opaque, to make sure
4634 // layer1 not culled.
4635 layer1
->SetContentsOpaque(true);
4636 layer1
->SetOpacity(1.f
);
4637 layer1
->SetExpectation(false, false);
4638 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4639 layer2
->SetContentsOpaque(true);
4640 layer2
->SetOpacity(0.5f
);
4641 layer2
->SetExpectation(true, false);
4642 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4643 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4644 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4645 EXPECT_TRUE(layer1
->quads_appended());
4646 EXPECT_TRUE(layer2
->quads_appended());
4647 host_impl_
->DidDrawAllLayers(frame
);
4649 // A second way of making the child non-opaque.
4650 layer1
->SetContentsOpaque(true);
4651 layer1
->SetOpacity(1.f
);
4652 layer1
->SetExpectation(false, false);
4653 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4654 layer2
->SetContentsOpaque(false);
4655 layer2
->SetOpacity(1.f
);
4656 layer2
->SetExpectation(true, false);
4657 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4658 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4659 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4660 EXPECT_TRUE(layer1
->quads_appended());
4661 EXPECT_TRUE(layer2
->quads_appended());
4662 host_impl_
->DidDrawAllLayers(frame
);
4664 // And when the layer says its not opaque but is painted opaque, it is not
4666 layer1
->SetContentsOpaque(true);
4667 layer1
->SetOpacity(1.f
);
4668 layer1
->SetExpectation(false, false);
4669 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4670 layer2
->SetContentsOpaque(true);
4671 layer2
->SetOpacity(1.f
);
4672 layer2
->SetExpectation(false, false);
4673 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4674 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4675 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4676 EXPECT_TRUE(layer1
->quads_appended());
4677 EXPECT_TRUE(layer2
->quads_appended());
4678 host_impl_
->DidDrawAllLayers(frame
);
4680 // Layer with partially opaque contents, drawn with blending.
4681 layer1
->SetContentsOpaque(false);
4682 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4683 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
4684 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4685 layer1
->SetExpectation(true, false);
4686 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4687 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4688 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4689 EXPECT_TRUE(layer1
->quads_appended());
4690 host_impl_
->DidDrawAllLayers(frame
);
4692 // Layer with partially opaque contents partially culled, drawn with blending.
4693 layer1
->SetContentsOpaque(false);
4694 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4695 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
4696 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4697 layer1
->SetExpectation(true, false);
4698 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4699 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4700 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4701 EXPECT_TRUE(layer1
->quads_appended());
4702 host_impl_
->DidDrawAllLayers(frame
);
4704 // Layer with partially opaque contents culled, drawn with blending.
4705 layer1
->SetContentsOpaque(false);
4706 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4707 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
4708 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4709 layer1
->SetExpectation(true, false);
4710 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4711 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4712 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4713 EXPECT_TRUE(layer1
->quads_appended());
4714 host_impl_
->DidDrawAllLayers(frame
);
4716 // Layer with partially opaque contents and translucent contents culled, drawn
4717 // without blending.
4718 layer1
->SetContentsOpaque(false);
4719 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4720 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
4721 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4722 layer1
->SetExpectation(false, false);
4723 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4724 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4725 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4726 EXPECT_TRUE(layer1
->quads_appended());
4727 host_impl_
->DidDrawAllLayers(frame
);
4730 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
4732 LayerTreeHostImplViewportCoveredTest() :
4733 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
4735 did_activate_pending_tree_(false) {}
4737 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
4739 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d();
4741 return FakeOutputSurface::Create3d();
4744 void SetupActiveTreeLayers() {
4745 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
4746 host_impl_
->active_tree()->SetRootLayer(
4747 LayerImpl::Create(host_impl_
->active_tree(), 1));
4748 host_impl_
->active_tree()->root_layer()->SetHasRenderSurface(true);
4749 host_impl_
->active_tree()->root_layer()->AddChild(
4750 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4752 host_impl_
->resource_provider()));
4753 child_
= static_cast<BlendStateCheckLayer
*>(
4754 host_impl_
->active_tree()->root_layer()->children()[0]);
4755 child_
->SetExpectation(false, false);
4756 child_
->SetContentsOpaque(true);
4759 // Expect no gutter rects.
4760 void TestLayerCoversFullViewport() {
4761 gfx::Rect
layer_rect(viewport_size_
);
4762 child_
->SetPosition(layer_rect
.origin());
4763 child_
->SetBounds(layer_rect
.size());
4764 child_
->SetContentBounds(layer_rect
.size());
4765 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4766 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4768 LayerTreeHostImpl::FrameData frame
;
4769 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4770 ASSERT_EQ(1u, frame
.render_passes
.size());
4772 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4773 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4774 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4776 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4777 host_impl_
->DidDrawAllLayers(frame
);
4780 // Expect fullscreen gutter rect.
4781 void TestEmptyLayer() {
4782 gfx::Rect
layer_rect(0, 0, 0, 0);
4783 child_
->SetPosition(layer_rect
.origin());
4784 child_
->SetBounds(layer_rect
.size());
4785 child_
->SetContentBounds(layer_rect
.size());
4786 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4787 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4789 LayerTreeHostImpl::FrameData frame
;
4790 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4791 ASSERT_EQ(1u, frame
.render_passes
.size());
4793 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4794 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4795 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4797 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4798 host_impl_
->DidDrawAllLayers(frame
);
4801 // Expect four surrounding gutter rects.
4802 void TestLayerInMiddleOfViewport() {
4803 gfx::Rect
layer_rect(500, 500, 200, 200);
4804 child_
->SetPosition(layer_rect
.origin());
4805 child_
->SetBounds(layer_rect
.size());
4806 child_
->SetContentBounds(layer_rect
.size());
4807 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4808 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4810 LayerTreeHostImpl::FrameData frame
;
4811 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4812 ASSERT_EQ(1u, frame
.render_passes
.size());
4814 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4815 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
4816 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4818 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4819 host_impl_
->DidDrawAllLayers(frame
);
4822 // Expect no gutter rects.
4823 void TestLayerIsLargerThanViewport() {
4824 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
4825 viewport_size_
.height() + 10);
4826 child_
->SetPosition(layer_rect
.origin());
4827 child_
->SetBounds(layer_rect
.size());
4828 child_
->SetContentBounds(layer_rect
.size());
4829 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4830 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4832 LayerTreeHostImpl::FrameData frame
;
4833 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4834 ASSERT_EQ(1u, frame
.render_passes
.size());
4836 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4837 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4838 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4840 host_impl_
->DidDrawAllLayers(frame
);
4843 void DidActivateSyncTree() override
{ did_activate_pending_tree_
= true; }
4845 void set_gutter_quad_material(DrawQuad::Material material
) {
4846 gutter_quad_material_
= material
;
4848 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
4849 gutter_texture_size_
= gutter_texture_size
;
4853 size_t CountGutterQuads(const QuadList
& quad_list
) {
4854 size_t num_gutter_quads
= 0;
4855 for (const auto& quad
: quad_list
) {
4856 num_gutter_quads
+= (quad
->material
== gutter_quad_material_
) ? 1 : 0;
4858 return num_gutter_quads
;
4861 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
4862 LayerTestCommon::VerifyQuadsExactlyCoverRect(
4863 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
4866 // Make sure that the texture coordinates match their expectations.
4867 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
4868 for (const auto& quad
: quad_list
) {
4869 if (quad
->material
!= DrawQuad::TEXTURE_CONTENT
)
4871 const TextureDrawQuad
* texture_quad
= TextureDrawQuad::MaterialCast(quad
);
4872 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
4873 gutter_texture_size_
, host_impl_
->device_scale_factor());
4874 EXPECT_EQ(texture_quad
->uv_top_left
.x(),
4875 texture_quad
->rect
.x() / gutter_texture_size_pixels
.width());
4876 EXPECT_EQ(texture_quad
->uv_top_left
.y(),
4877 texture_quad
->rect
.y() / gutter_texture_size_pixels
.height());
4879 texture_quad
->uv_bottom_right
.x(),
4880 texture_quad
->rect
.right() / gutter_texture_size_pixels
.width());
4882 texture_quad
->uv_bottom_right
.y(),
4883 texture_quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
4887 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
4888 return gfx::ToRoundedSize(
4889 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
4892 DrawQuad::Material gutter_quad_material_
;
4893 gfx::Size gutter_texture_size_
;
4894 gfx::Size viewport_size_
;
4895 BlendStateCheckLayer
* child_
;
4896 bool did_activate_pending_tree_
;
4899 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
4900 viewport_size_
= gfx::Size(1000, 1000);
4902 bool always_draw
= false;
4903 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4905 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4906 SetupActiveTreeLayers();
4907 TestLayerCoversFullViewport();
4909 TestLayerInMiddleOfViewport();
4910 TestLayerIsLargerThanViewport();
4913 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
4914 viewport_size_
= gfx::Size(1000, 1000);
4916 bool always_draw
= false;
4917 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4919 host_impl_
->SetDeviceScaleFactor(2.f
);
4920 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4921 SetupActiveTreeLayers();
4922 TestLayerCoversFullViewport();
4924 TestLayerInMiddleOfViewport();
4925 TestLayerIsLargerThanViewport();
4928 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
4929 viewport_size_
= gfx::Size(1000, 1000);
4931 bool always_draw
= true;
4932 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4934 // Pending tree to force active_tree size invalid. Not used otherwise.
4935 host_impl_
->CreatePendingTree();
4936 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4937 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4939 SetupActiveTreeLayers();
4941 TestLayerInMiddleOfViewport();
4942 TestLayerIsLargerThanViewport();
4945 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
4946 viewport_size_
= gfx::Size(1000, 1000);
4948 bool always_draw
= true;
4949 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4951 // Set larger viewport and activate it to active tree.
4952 host_impl_
->CreatePendingTree();
4953 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4954 viewport_size_
.height() + 100);
4955 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4956 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4957 host_impl_
->ActivateSyncTree();
4958 EXPECT_TRUE(did_activate_pending_tree_
);
4959 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4961 // Shrink pending tree viewport without activating.
4962 host_impl_
->CreatePendingTree();
4963 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4964 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4966 SetupActiveTreeLayers();
4968 TestLayerInMiddleOfViewport();
4969 TestLayerIsLargerThanViewport();
4972 class FakeDrawableLayerImpl
: public LayerImpl
{
4974 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4975 return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl
, id
));
4978 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4979 : LayerImpl(tree_impl
, id
) {}
4982 // Only reshape when we know we are going to draw. Otherwise, the reshape
4983 // can leave the window at the wrong size if we never draw and the proper
4984 // viewport size is never set.
4985 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4986 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4987 scoped_ptr
<OutputSurface
> output_surface(
4988 FakeOutputSurface::Create3d(provider
));
4989 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4991 scoped_ptr
<LayerImpl
> root
=
4992 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4993 root
->SetBounds(gfx::Size(10, 10));
4994 root
->SetContentBounds(gfx::Size(10, 10));
4995 root
->SetDrawsContent(true);
4996 root
->SetHasRenderSurface(true);
4997 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4998 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4999 provider
->TestContext3d()->clear_reshape_called();
5001 LayerTreeHostImpl::FrameData frame
;
5002 host_impl_
->SetViewportSize(gfx::Size(10, 10));
5003 host_impl_
->SetDeviceScaleFactor(1.f
);
5004 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5005 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5006 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
5007 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
5008 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
5009 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
5010 host_impl_
->DidDrawAllLayers(frame
);
5011 provider
->TestContext3d()->clear_reshape_called();
5013 host_impl_
->SetViewportSize(gfx::Size(20, 30));
5014 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5015 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5016 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
5017 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
5018 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
5019 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
5020 host_impl_
->DidDrawAllLayers(frame
);
5021 provider
->TestContext3d()->clear_reshape_called();
5023 host_impl_
->SetDeviceScaleFactor(2.f
);
5024 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5025 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5026 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
5027 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
5028 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
5029 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
5030 host_impl_
->DidDrawAllLayers(frame
);
5031 provider
->TestContext3d()->clear_reshape_called();
5034 // Make sure damage tracking propagates all the way to the graphics context,
5035 // where it should request to swap only the sub-buffer that is damaged.
5036 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
5037 scoped_refptr
<TestContextProvider
> context_provider(
5038 TestContextProvider::Create());
5039 context_provider
->BindToCurrentThread();
5040 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
5042 scoped_ptr
<FakeOutputSurface
> output_surface(
5043 FakeOutputSurface::Create3d(context_provider
));
5044 FakeOutputSurface
* fake_output_surface
= output_surface
.get();
5046 // This test creates its own LayerTreeHostImpl, so
5047 // that we can force partial swap enabled.
5048 LayerTreeSettings settings
;
5049 settings
.renderer_settings
.partial_swap_enabled
= true;
5050 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5051 new TestSharedBitmapManager());
5052 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
5053 LayerTreeHostImpl::Create(settings
,
5056 &stats_instrumentation_
,
5057 shared_bitmap_manager
.get(),
5060 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
5061 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
5063 scoped_ptr
<LayerImpl
> root
=
5064 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
5065 root
->SetHasRenderSurface(true);
5066 scoped_ptr
<LayerImpl
> child
=
5067 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
5068 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
5069 child
->SetBounds(gfx::Size(14, 15));
5070 child
->SetContentBounds(gfx::Size(14, 15));
5071 child
->SetDrawsContent(true);
5072 root
->SetBounds(gfx::Size(500, 500));
5073 root
->SetContentBounds(gfx::Size(500, 500));
5074 root
->SetDrawsContent(true);
5075 root
->AddChild(child
.Pass());
5076 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
5078 LayerTreeHostImpl::FrameData frame
;
5080 // First frame, the entire screen should get swapped.
5081 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
5082 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5083 layer_tree_host_impl
->DidDrawAllLayers(frame
);
5084 layer_tree_host_impl
->SwapBuffers(frame
);
5085 gfx::Rect
expected_swap_rect(0, 0, 500, 500);
5086 EXPECT_EQ(expected_swap_rect
.ToString(),
5087 fake_output_surface
->last_swap_rect().ToString());
5089 // Second frame, only the damaged area should get swapped. Damage should be
5090 // the union of old and new child rects.
5091 // expected damage rect: gfx::Rect(26, 28);
5092 // expected swap rect: vertically flipped, with origin at bottom left corner.
5093 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
5095 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
5096 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5097 host_impl_
->DidDrawAllLayers(frame
);
5098 layer_tree_host_impl
->SwapBuffers(frame
);
5100 // Make sure that partial swap is constrained to the viewport dimensions
5101 // expected damage rect: gfx::Rect(500, 500);
5102 // expected swap rect: flipped damage rect, but also clamped to viewport
5103 expected_swap_rect
= gfx::Rect(0, 500-28, 26, 28);
5104 EXPECT_EQ(expected_swap_rect
.ToString(),
5105 fake_output_surface
->last_swap_rect().ToString());
5107 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
5108 // This will damage everything.
5109 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
5111 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
5112 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5113 host_impl_
->DidDrawAllLayers(frame
);
5114 layer_tree_host_impl
->SwapBuffers(frame
);
5116 expected_swap_rect
= gfx::Rect(0, 0, 10, 10);
5117 EXPECT_EQ(expected_swap_rect
.ToString(),
5118 fake_output_surface
->last_swap_rect().ToString());
5121 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
5122 scoped_ptr
<LayerImpl
> root
=
5123 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
5124 scoped_ptr
<LayerImpl
> child
=
5125 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
5126 child
->SetBounds(gfx::Size(10, 10));
5127 child
->SetContentBounds(gfx::Size(10, 10));
5128 child
->SetDrawsContent(true);
5129 root
->SetBounds(gfx::Size(10, 10));
5130 root
->SetContentBounds(gfx::Size(10, 10));
5131 root
->SetDrawsContent(true);
5132 root
->SetHasRenderSurface(true);
5133 root
->AddChild(child
.Pass());
5135 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5137 LayerTreeHostImpl::FrameData frame
;
5139 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5140 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
5141 EXPECT_EQ(1u, frame
.render_passes
.size());
5142 host_impl_
->DidDrawAllLayers(frame
);
5145 class FakeLayerWithQuads
: public LayerImpl
{
5147 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
5148 return make_scoped_ptr(new FakeLayerWithQuads(tree_impl
, id
));
5151 void AppendQuads(RenderPass
* render_pass
,
5152 AppendQuadsData
* append_quads_data
) override
{
5153 SharedQuadState
* shared_quad_state
=
5154 render_pass
->CreateAndAppendSharedQuadState();
5155 PopulateSharedQuadState(shared_quad_state
);
5157 SkColor gray
= SkColorSetRGB(100, 100, 100);
5158 gfx::Rect
quad_rect(content_bounds());
5159 gfx::Rect
visible_quad_rect(quad_rect
);
5160 SolidColorDrawQuad
* my_quad
=
5161 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
5163 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
5167 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
5168 : LayerImpl(tree_impl
, id
) {}
5171 class MockContext
: public TestWebGraphicsContext3D
{
5173 MOCK_METHOD1(useProgram
, void(GLuint program
));
5174 MOCK_METHOD5(uniform4f
, void(GLint location
,
5179 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
5181 GLboolean transpose
,
5182 const GLfloat
* value
));
5183 MOCK_METHOD4(drawElements
, void(GLenum mode
,
5187 MOCK_METHOD1(enable
, void(GLenum cap
));
5188 MOCK_METHOD1(disable
, void(GLenum cap
));
5189 MOCK_METHOD4(scissor
, void(GLint x
,
5195 class MockContextHarness
{
5197 MockContext
* context_
;
5200 explicit MockContextHarness(MockContext
* context
)
5201 : context_(context
) {
5202 context_
->set_have_post_sub_buffer(true);
5204 // Catch "uninteresting" calls
5205 EXPECT_CALL(*context_
, useProgram(_
))
5208 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
5211 // These are not asserted
5212 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
5213 .WillRepeatedly(Return());
5215 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
5216 .WillRepeatedly(Return());
5218 // Any un-sanctioned calls to enable() are OK
5219 EXPECT_CALL(*context_
, enable(_
))
5220 .WillRepeatedly(Return());
5222 // Any un-sanctioned calls to disable() are OK
5223 EXPECT_CALL(*context_
, disable(_
))
5224 .WillRepeatedly(Return());
5227 void MustDrawSolidQuad() {
5228 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
5230 .RetiresOnSaturation();
5232 EXPECT_CALL(*context_
, useProgram(_
))
5234 .RetiresOnSaturation();
5237 void MustSetScissor(int x
, int y
, int width
, int height
) {
5238 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
5239 .WillRepeatedly(Return());
5241 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
5243 .WillRepeatedly(Return());
5246 void MustSetNoScissor() {
5247 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
5248 .WillRepeatedly(Return());
5250 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
5253 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
5258 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
5259 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
5260 MockContext
* mock_context
= mock_context_owned
.get();
5261 MockContextHarness
harness(mock_context
);
5264 LayerTreeSettings settings
= DefaultSettings();
5265 settings
.renderer_settings
.partial_swap_enabled
= false;
5266 CreateHostImpl(settings
,
5267 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
5268 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5270 // Without partial swap, and no clipping, no scissor is set.
5271 harness
.MustDrawSolidQuad();
5272 harness
.MustSetNoScissor();
5274 LayerTreeHostImpl::FrameData frame
;
5275 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5276 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5277 host_impl_
->DidDrawAllLayers(frame
);
5279 Mock::VerifyAndClearExpectations(&mock_context
);
5281 // Without partial swap, but a layer does clip its subtree, one scissor is
5283 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
5284 harness
.MustDrawSolidQuad();
5285 harness
.MustSetScissor(0, 0, 10, 10);
5287 LayerTreeHostImpl::FrameData frame
;
5288 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5289 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5290 host_impl_
->DidDrawAllLayers(frame
);
5292 Mock::VerifyAndClearExpectations(&mock_context
);
5295 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
5296 scoped_ptr
<MockContext
> context_owned(new MockContext
);
5297 MockContext
* mock_context
= context_owned
.get();
5298 MockContextHarness
harness(mock_context
);
5300 LayerTreeSettings settings
= DefaultSettings();
5301 settings
.renderer_settings
.partial_swap_enabled
= true;
5302 CreateHostImpl(settings
, FakeOutputSurface::Create3d(context_owned
.Pass()));
5303 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5305 // The first frame is not a partially-swapped one.
5306 harness
.MustSetScissor(0, 0, 10, 10);
5307 harness
.MustDrawSolidQuad();
5309 LayerTreeHostImpl::FrameData frame
;
5310 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5311 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5312 host_impl_
->DidDrawAllLayers(frame
);
5314 Mock::VerifyAndClearExpectations(&mock_context
);
5316 // Damage a portion of the frame.
5317 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
5318 gfx::Rect(0, 0, 2, 3));
5320 // The second frame will be partially-swapped (the y coordinates are flipped).
5321 harness
.MustSetScissor(0, 7, 2, 3);
5322 harness
.MustDrawSolidQuad();
5324 LayerTreeHostImpl::FrameData frame
;
5325 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5326 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5327 host_impl_
->DidDrawAllLayers(frame
);
5329 Mock::VerifyAndClearExpectations(&mock_context
);
5332 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
5334 LayerTreeHostImplClient
* client
,
5336 SharedBitmapManager
* manager
,
5337 RenderingStatsInstrumentation
* stats_instrumentation
) {
5338 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
5339 scoped_ptr
<OutputSurface
> output_surface(
5340 FakeOutputSurface::Create3d(provider
));
5341 provider
->BindToCurrentThread();
5342 provider
->TestContext3d()->set_have_post_sub_buffer(true);
5344 LayerTreeSettings settings
;
5345 settings
.renderer_settings
.partial_swap_enabled
= partial_swap
;
5346 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
5347 settings
, client
, proxy
, stats_instrumentation
, manager
, NULL
, 0);
5348 my_host_impl
->InitializeRenderer(output_surface
.Pass());
5349 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
5352 Layers are created as follows:
5354 +--------------------+
5358 | | +-------------------+
5360 | | +-------------------+
5365 +--------------------+
5367 Layers 1, 2 have render surfaces
5369 scoped_ptr
<LayerImpl
> root
=
5370 LayerImpl::Create(my_host_impl
->active_tree(), 1);
5371 scoped_ptr
<LayerImpl
> child
=
5372 LayerImpl::Create(my_host_impl
->active_tree(), 2);
5373 scoped_ptr
<LayerImpl
> grand_child
=
5374 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
5376 gfx::Rect
root_rect(0, 0, 100, 100);
5377 gfx::Rect
child_rect(10, 10, 50, 50);
5378 gfx::Rect
grand_child_rect(5, 5, 150, 150);
5380 root
->SetHasRenderSurface(true);
5381 root
->SetPosition(root_rect
.origin());
5382 root
->SetBounds(root_rect
.size());
5383 root
->SetContentBounds(root
->bounds());
5384 root
->draw_properties().visible_content_rect
= root_rect
;
5385 root
->SetDrawsContent(false);
5386 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
5388 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
5389 child
->SetOpacity(0.5f
);
5390 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
5391 child
->SetContentBounds(child
->bounds());
5392 child
->draw_properties().visible_content_rect
= child_rect
;
5393 child
->SetDrawsContent(false);
5394 child
->SetHasRenderSurface(true);
5396 grand_child
->SetPosition(grand_child_rect
.origin());
5397 grand_child
->SetBounds(grand_child_rect
.size());
5398 grand_child
->SetContentBounds(grand_child
->bounds());
5399 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
5400 grand_child
->SetDrawsContent(true);
5402 child
->AddChild(grand_child
.Pass());
5403 root
->AddChild(child
.Pass());
5405 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
5406 return my_host_impl
.Pass();
5409 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
5410 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5411 new TestSharedBitmapManager());
5412 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5413 SetupLayersForOpacity(true,
5416 shared_bitmap_manager
.get(),
5417 &stats_instrumentation_
);
5419 LayerTreeHostImpl::FrameData frame
;
5420 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5422 // Verify all quads have been computed
5423 ASSERT_EQ(2U, frame
.render_passes
.size());
5424 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5425 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5426 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5427 frame
.render_passes
[0]->quad_list
.front()->material
);
5428 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5429 frame
.render_passes
[1]->quad_list
.front()->material
);
5431 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5432 my_host_impl
->DidDrawAllLayers(frame
);
5436 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
5437 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5438 new TestSharedBitmapManager());
5439 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5440 SetupLayersForOpacity(false,
5443 shared_bitmap_manager
.get(),
5444 &stats_instrumentation_
);
5446 LayerTreeHostImpl::FrameData frame
;
5447 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5449 // Verify all quads have been computed
5450 ASSERT_EQ(2U, frame
.render_passes
.size());
5451 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5452 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5453 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5454 frame
.render_passes
[0]->quad_list
.front()->material
);
5455 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5456 frame
.render_passes
[1]->quad_list
.front()->material
);
5458 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5459 my_host_impl
->DidDrawAllLayers(frame
);
5463 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
5464 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5465 TestWebGraphicsContext3D::Create();
5466 TestWebGraphicsContext3D
* context3d
= context
.get();
5467 scoped_ptr
<OutputSurface
> output_surface(
5468 FakeOutputSurface::Create3d(context
.Pass()));
5469 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
5471 scoped_ptr
<LayerImpl
> root_layer
=
5472 LayerImpl::Create(host_impl_
->active_tree(), 1);
5473 root_layer
->SetBounds(gfx::Size(10, 10));
5474 root_layer
->SetHasRenderSurface(true);
5476 scoped_refptr
<VideoFrame
> softwareFrame
=
5477 media::VideoFrame::CreateColorFrame(
5478 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
5479 FakeVideoFrameProvider provider
;
5480 provider
.set_frame(softwareFrame
);
5481 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
5482 host_impl_
->active_tree(), 4, &provider
, media::VIDEO_ROTATION_0
);
5483 video_layer
->SetBounds(gfx::Size(10, 10));
5484 video_layer
->SetContentBounds(gfx::Size(10, 10));
5485 video_layer
->SetDrawsContent(true);
5486 root_layer
->AddChild(video_layer
.Pass());
5488 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
5489 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
5490 io_surface_layer
->SetBounds(gfx::Size(10, 10));
5491 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
5492 io_surface_layer
->SetDrawsContent(true);
5493 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
5494 root_layer
->AddChild(io_surface_layer
.Pass());
5496 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
5498 EXPECT_EQ(0u, context3d
->NumTextures());
5500 LayerTreeHostImpl::FrameData frame
;
5501 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5502 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5503 host_impl_
->DidDrawAllLayers(frame
);
5504 host_impl_
->SwapBuffers(frame
);
5506 EXPECT_GT(context3d
->NumTextures(), 0u);
5508 // Kill the layer tree.
5509 host_impl_
->active_tree()->SetRootLayer(
5510 LayerImpl::Create(host_impl_
->active_tree(), 100));
5511 // There should be no textures left in use after.
5512 EXPECT_EQ(0u, context3d
->NumTextures());
5515 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
5517 MOCK_METHOD1(useProgram
, void(GLuint program
));
5518 MOCK_METHOD4(drawElements
, void(GLenum mode
,
5524 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
5525 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
5526 new MockDrawQuadsToFillScreenContext
);
5527 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
5530 LayerTreeSettings settings
= DefaultSettings();
5531 settings
.renderer_settings
.partial_swap_enabled
= false;
5532 CreateHostImpl(settings
,
5533 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
5534 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5535 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
5537 // Verify one quad is drawn when transparent background set is not set.
5538 host_impl_
->active_tree()->set_has_transparent_background(false);
5539 EXPECT_CALL(*mock_context
, useProgram(_
))
5541 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
5543 LayerTreeHostImpl::FrameData frame
;
5544 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5545 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5546 host_impl_
->DidDrawAllLayers(frame
);
5547 Mock::VerifyAndClearExpectations(&mock_context
);
5549 // Verify no quads are drawn when transparent background is set.
5550 host_impl_
->active_tree()->set_has_transparent_background(true);
5551 host_impl_
->SetFullRootLayerDamage();
5552 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5553 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5554 host_impl_
->DidDrawAllLayers(frame
);
5555 Mock::VerifyAndClearExpectations(&mock_context
);
5558 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
5559 set_reduce_memory_result(false);
5561 // If changing the memory limit wouldn't result in changing what was
5562 // committed, then no commit should be requested.
5563 set_reduce_memory_result(false);
5564 host_impl_
->set_max_memory_needed_bytes(
5565 host_impl_
->memory_allocation_limit_bytes() - 1);
5566 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5567 host_impl_
->memory_allocation_limit_bytes() - 1));
5568 EXPECT_FALSE(did_request_commit_
);
5569 did_request_commit_
= false;
5571 // If changing the memory limit would result in changing what was
5572 // committed, then a commit should be requested, even though nothing was
5574 set_reduce_memory_result(false);
5575 host_impl_
->set_max_memory_needed_bytes(
5576 host_impl_
->memory_allocation_limit_bytes());
5577 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5578 host_impl_
->memory_allocation_limit_bytes() - 1));
5579 EXPECT_TRUE(did_request_commit_
);
5580 did_request_commit_
= false;
5582 // Especially if changing the memory limit caused evictions, we need
5584 set_reduce_memory_result(true);
5585 host_impl_
->set_max_memory_needed_bytes(1);
5586 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5587 host_impl_
->memory_allocation_limit_bytes() - 1));
5588 EXPECT_TRUE(did_request_commit_
);
5589 did_request_commit_
= false;
5591 // But if we set it to the same value that it was before, we shouldn't
5593 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5594 host_impl_
->memory_allocation_limit_bytes()));
5595 EXPECT_FALSE(did_request_commit_
);
5598 class LayerTreeHostImplTestWithDelegatingRenderer
5599 : public LayerTreeHostImplTest
{
5601 scoped_ptr
<OutputSurface
> CreateOutputSurface() override
{
5602 return FakeOutputSurface::CreateDelegating3d();
5605 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
5606 bool expect_to_draw
= !expected_damage
.IsEmpty();
5608 LayerTreeHostImpl::FrameData frame
;
5609 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5611 if (!expect_to_draw
) {
5612 // With no damage, we don't draw, and no quads are created.
5613 ASSERT_EQ(0u, frame
.render_passes
.size());
5615 ASSERT_EQ(1u, frame
.render_passes
.size());
5617 // Verify the damage rect for the root render pass.
5618 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
5619 EXPECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
5621 // Verify the root and child layers' quads are generated and not being
5623 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
5625 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
5626 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
5627 EXPECT_EQ(expected_child_visible_rect
,
5628 root_render_pass
->quad_list
.front()->visible_rect
);
5630 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
5631 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
5632 EXPECT_EQ(expected_root_visible_rect
,
5633 root_render_pass
->quad_list
.ElementAt(1)->visible_rect
);
5636 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5637 host_impl_
->DidDrawAllLayers(frame
);
5638 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
5642 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
5643 scoped_ptr
<SolidColorLayerImpl
> root
=
5644 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5645 root
->SetPosition(gfx::PointF());
5646 root
->SetBounds(gfx::Size(10, 10));
5647 root
->SetContentBounds(gfx::Size(10, 10));
5648 root
->SetDrawsContent(true);
5649 root
->SetHasRenderSurface(true);
5651 // Child layer is in the bottom right corner.
5652 scoped_ptr
<SolidColorLayerImpl
> child
=
5653 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
5654 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
5655 child
->SetBounds(gfx::Size(1, 1));
5656 child
->SetContentBounds(gfx::Size(1, 1));
5657 child
->SetDrawsContent(true);
5658 root
->AddChild(child
.Pass());
5660 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5662 // Draw a frame. In the first frame, the entire viewport should be damaged.
5663 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
5664 DrawFrameAndTestDamage(full_frame_damage
);
5666 // The second frame has damage that doesn't touch the child layer. Its quads
5667 // should still be generated.
5668 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
5669 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
5670 DrawFrameAndTestDamage(small_damage
);
5672 // The third frame should have no damage, so no quads should be generated.
5673 gfx::Rect no_damage
;
5674 DrawFrameAndTestDamage(no_damage
);
5677 // TODO(reveman): Remove this test and the ability to prevent on demand raster
5678 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
5679 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
5680 LayerTreeSettings settings
;
5681 CreateHostImpl(settings
, CreateOutputSurface());
5682 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
5685 class FakeMaskLayerImpl
: public LayerImpl
{
5687 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
5689 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
5692 void GetContentsResourceId(ResourceProvider::ResourceId
* resource_id
,
5693 gfx::Size
* resource_size
) const override
{
5698 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
5699 : LayerImpl(tree_impl
, id
) {}
5702 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
5703 LayerTreeSettings settings
;
5704 settings
.layer_transforms_should_scale_layer_contents
= true;
5705 CreateHostImpl(settings
, CreateOutputSurface());
5709 // +-- Scaling Layer (adds a 2x scale)
5711 // +-- Content Layer
5713 scoped_ptr
<LayerImpl
> scoped_root
=
5714 LayerImpl::Create(host_impl_
->active_tree(), 1);
5715 LayerImpl
* root
= scoped_root
.get();
5716 root
->SetHasRenderSurface(true);
5717 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5719 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
5720 LayerImpl::Create(host_impl_
->active_tree(), 2);
5721 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
5722 root
->AddChild(scoped_scaling_layer
.Pass());
5724 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5725 LayerImpl::Create(host_impl_
->active_tree(), 3);
5726 LayerImpl
* content_layer
= scoped_content_layer
.get();
5727 scaling_layer
->AddChild(scoped_content_layer
.Pass());
5729 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5730 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5731 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5732 content_layer
->SetHasRenderSurface(true);
5733 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5735 gfx::Size
root_size(100, 100);
5736 root
->SetBounds(root_size
);
5737 root
->SetContentBounds(root_size
);
5738 root
->SetPosition(gfx::PointF());
5740 gfx::Size
scaling_layer_size(50, 50);
5741 scaling_layer
->SetBounds(scaling_layer_size
);
5742 scaling_layer
->SetContentBounds(scaling_layer_size
);
5743 scaling_layer
->SetPosition(gfx::PointF());
5744 gfx::Transform scale
;
5745 scale
.Scale(2.f
, 2.f
);
5746 scaling_layer
->SetTransform(scale
);
5748 content_layer
->SetBounds(scaling_layer_size
);
5749 content_layer
->SetContentBounds(scaling_layer_size
);
5750 content_layer
->SetPosition(gfx::PointF());
5751 content_layer
->SetDrawsContent(true);
5753 mask_layer
->SetBounds(scaling_layer_size
);
5754 mask_layer
->SetContentBounds(scaling_layer_size
);
5755 mask_layer
->SetPosition(gfx::PointF());
5756 mask_layer
->SetDrawsContent(true);
5759 // Check that the tree scaling is correctly taken into account for the mask,
5760 // that should fully map onto the quad.
5761 float device_scale_factor
= 1.f
;
5762 host_impl_
->SetViewportSize(root_size
);
5763 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5765 LayerTreeHostImpl::FrameData frame
;
5766 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5768 ASSERT_EQ(1u, frame
.render_passes
.size());
5769 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5770 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5771 frame
.render_passes
[0]->quad_list
.front()->material
);
5772 const RenderPassDrawQuad
* render_pass_quad
=
5773 RenderPassDrawQuad::MaterialCast(
5774 frame
.render_passes
[0]->quad_list
.front());
5775 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5776 render_pass_quad
->rect
.ToString());
5777 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5778 render_pass_quad
->MaskUVRect().ToString());
5779 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5780 render_pass_quad
->mask_uv_scale
.ToString());
5782 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5783 host_impl_
->DidDrawAllLayers(frame
);
5787 // Applying a DSF should change the render surface size, but won't affect
5788 // which part of the mask is used.
5789 device_scale_factor
= 2.f
;
5790 gfx::Size device_viewport
=
5791 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5792 host_impl_
->SetViewportSize(device_viewport
);
5793 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5794 host_impl_
->active_tree()->set_needs_update_draw_properties();
5796 LayerTreeHostImpl::FrameData frame
;
5797 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5799 ASSERT_EQ(1u, frame
.render_passes
.size());
5800 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5801 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5802 frame
.render_passes
[0]->quad_list
.front()->material
);
5803 const RenderPassDrawQuad
* render_pass_quad
=
5804 RenderPassDrawQuad::MaterialCast(
5805 frame
.render_passes
[0]->quad_list
.front());
5806 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5807 render_pass_quad
->rect
.ToString());
5808 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5809 render_pass_quad
->MaskUVRect().ToString());
5810 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5811 render_pass_quad
->mask_uv_scale
.ToString());
5813 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5814 host_impl_
->DidDrawAllLayers(frame
);
5818 // Applying an equivalent content scale on the content layer and the mask
5819 // should still result in the same part of the mask being used.
5820 gfx::Size content_bounds
=
5821 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
5822 device_scale_factor
));
5823 content_layer
->SetContentBounds(content_bounds
);
5824 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5825 mask_layer
->SetContentBounds(content_bounds
);
5826 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5827 host_impl_
->active_tree()->set_needs_update_draw_properties();
5829 LayerTreeHostImpl::FrameData frame
;
5830 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5832 ASSERT_EQ(1u, frame
.render_passes
.size());
5833 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5834 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5835 frame
.render_passes
[0]->quad_list
.front()->material
);
5836 const RenderPassDrawQuad
* render_pass_quad
=
5837 RenderPassDrawQuad::MaterialCast(
5838 frame
.render_passes
[0]->quad_list
.front());
5839 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5840 render_pass_quad
->rect
.ToString());
5841 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5842 render_pass_quad
->MaskUVRect().ToString());
5843 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5844 render_pass_quad
->mask_uv_scale
.ToString());
5846 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5847 host_impl_
->DidDrawAllLayers(frame
);
5851 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
5852 // The mask layer has bounds 100x100 but is attached to a layer with bounds
5855 scoped_ptr
<LayerImpl
> scoped_root
=
5856 LayerImpl::Create(host_impl_
->active_tree(), 1);
5857 LayerImpl
* root
= scoped_root
.get();
5858 root
->SetHasRenderSurface(true);
5860 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5862 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5863 LayerImpl::Create(host_impl_
->active_tree(), 3);
5864 LayerImpl
* content_layer
= scoped_content_layer
.get();
5865 root
->AddChild(scoped_content_layer
.Pass());
5867 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5868 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5869 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5870 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5871 content_layer
->SetHasRenderSurface(true);
5873 gfx::Size
root_size(100, 100);
5874 root
->SetBounds(root_size
);
5875 root
->SetContentBounds(root_size
);
5876 root
->SetPosition(gfx::PointF());
5878 gfx::Size
layer_size(50, 50);
5879 content_layer
->SetBounds(layer_size
);
5880 content_layer
->SetContentBounds(layer_size
);
5881 content_layer
->SetPosition(gfx::PointF());
5882 content_layer
->SetDrawsContent(true);
5884 gfx::Size
mask_size(100, 100);
5885 mask_layer
->SetBounds(mask_size
);
5886 mask_layer
->SetContentBounds(mask_size
);
5887 mask_layer
->SetPosition(gfx::PointF());
5888 mask_layer
->SetDrawsContent(true);
5890 // Check that the mask fills the surface.
5891 float device_scale_factor
= 1.f
;
5892 host_impl_
->SetViewportSize(root_size
);
5893 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5895 LayerTreeHostImpl::FrameData frame
;
5896 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5898 ASSERT_EQ(1u, frame
.render_passes
.size());
5899 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5900 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5901 frame
.render_passes
[0]->quad_list
.front()->material
);
5902 const RenderPassDrawQuad
* render_pass_quad
=
5903 RenderPassDrawQuad::MaterialCast(
5904 frame
.render_passes
[0]->quad_list
.front());
5905 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5906 render_pass_quad
->rect
.ToString());
5907 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5908 render_pass_quad
->MaskUVRect().ToString());
5909 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5910 render_pass_quad
->mask_uv_scale
.ToString());
5912 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5913 host_impl_
->DidDrawAllLayers(frame
);
5916 // Applying a DSF should change the render surface size, but won't affect
5917 // which part of the mask is used.
5918 device_scale_factor
= 2.f
;
5919 gfx::Size device_viewport
=
5920 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5921 host_impl_
->SetViewportSize(device_viewport
);
5922 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5923 host_impl_
->active_tree()->set_needs_update_draw_properties();
5925 LayerTreeHostImpl::FrameData frame
;
5926 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5928 ASSERT_EQ(1u, frame
.render_passes
.size());
5929 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5930 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5931 frame
.render_passes
[0]->quad_list
.front()->material
);
5932 const RenderPassDrawQuad
* render_pass_quad
=
5933 RenderPassDrawQuad::MaterialCast(
5934 frame
.render_passes
[0]->quad_list
.front());
5935 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5936 render_pass_quad
->rect
.ToString());
5937 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5938 render_pass_quad
->MaskUVRect().ToString());
5939 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5940 render_pass_quad
->mask_uv_scale
.ToString());
5942 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5943 host_impl_
->DidDrawAllLayers(frame
);
5946 // Applying an equivalent content scale on the content layer and the mask
5947 // should still result in the same part of the mask being used.
5948 gfx::Size layer_size_large
=
5949 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5950 content_layer
->SetContentBounds(layer_size_large
);
5951 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5952 gfx::Size mask_size_large
=
5953 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5954 mask_layer
->SetContentBounds(mask_size_large
);
5955 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5956 host_impl_
->active_tree()->set_needs_update_draw_properties();
5958 LayerTreeHostImpl::FrameData frame
;
5959 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5961 ASSERT_EQ(1u, frame
.render_passes
.size());
5962 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5963 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5964 frame
.render_passes
[0]->quad_list
.front()->material
);
5965 const RenderPassDrawQuad
* render_pass_quad
=
5966 RenderPassDrawQuad::MaterialCast(
5967 frame
.render_passes
[0]->quad_list
.front());
5968 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5969 render_pass_quad
->rect
.ToString());
5970 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5971 render_pass_quad
->MaskUVRect().ToString());
5972 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5973 render_pass_quad
->mask_uv_scale
.ToString());
5975 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5976 host_impl_
->DidDrawAllLayers(frame
);
5979 // Applying a different contents scale to the mask layer means it will have
5980 // a larger texture, but it should use the same tex coords to cover the
5982 mask_layer
->SetContentBounds(mask_size
);
5983 mask_layer
->SetContentsScale(1.f
, 1.f
);
5984 host_impl_
->active_tree()->set_needs_update_draw_properties();
5986 LayerTreeHostImpl::FrameData frame
;
5987 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5989 ASSERT_EQ(1u, frame
.render_passes
.size());
5990 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5991 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5992 frame
.render_passes
[0]->quad_list
.front()->material
);
5993 const RenderPassDrawQuad
* render_pass_quad
=
5994 RenderPassDrawQuad::MaterialCast(
5995 frame
.render_passes
[0]->quad_list
.front());
5996 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5997 render_pass_quad
->rect
.ToString());
5998 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5999 render_pass_quad
->MaskUVRect().ToString());
6000 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
6001 render_pass_quad
->mask_uv_scale
.ToString());
6003 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6004 host_impl_
->DidDrawAllLayers(frame
);
6008 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
6009 // The replica's mask layer has bounds 100x100 but the replica is of a
6010 // layer with bounds 50x50.
6012 scoped_ptr
<LayerImpl
> scoped_root
=
6013 LayerImpl::Create(host_impl_
->active_tree(), 1);
6014 LayerImpl
* root
= scoped_root
.get();
6015 root
->SetHasRenderSurface(true);
6017 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
6019 scoped_ptr
<LayerImpl
> scoped_content_layer
=
6020 LayerImpl::Create(host_impl_
->active_tree(), 3);
6021 LayerImpl
* content_layer
= scoped_content_layer
.get();
6022 root
->AddChild(scoped_content_layer
.Pass());
6024 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
6025 LayerImpl::Create(host_impl_
->active_tree(), 2);
6026 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
6027 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
6028 content_layer
->SetHasRenderSurface(true);
6030 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
6031 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
6032 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
6033 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
6034 replica_layer
->SetHasRenderSurface(true);
6036 gfx::Size
root_size(100, 100);
6037 root
->SetBounds(root_size
);
6038 root
->SetContentBounds(root_size
);
6039 root
->SetPosition(gfx::PointF());
6041 gfx::Size
layer_size(50, 50);
6042 content_layer
->SetBounds(layer_size
);
6043 content_layer
->SetContentBounds(layer_size
);
6044 content_layer
->SetPosition(gfx::PointF());
6045 content_layer
->SetDrawsContent(true);
6047 gfx::Size
mask_size(100, 100);
6048 mask_layer
->SetBounds(mask_size
);
6049 mask_layer
->SetContentBounds(mask_size
);
6050 mask_layer
->SetPosition(gfx::PointF());
6051 mask_layer
->SetDrawsContent(true);
6053 // Check that the mask fills the surface.
6054 float device_scale_factor
= 1.f
;
6055 host_impl_
->SetViewportSize(root_size
);
6056 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6058 LayerTreeHostImpl::FrameData frame
;
6059 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6061 ASSERT_EQ(1u, frame
.render_passes
.size());
6062 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6063 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6064 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6065 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6066 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6067 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
6068 replica_quad
->rect
.ToString());
6069 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
6070 replica_quad
->MaskUVRect().ToString());
6071 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
6072 replica_quad
->mask_uv_scale
.ToString());
6074 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6075 host_impl_
->DidDrawAllLayers(frame
);
6078 // Applying a DSF should change the render surface size, but won't affect
6079 // which part of the mask is used.
6080 device_scale_factor
= 2.f
;
6081 gfx::Size device_viewport
=
6082 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
6083 host_impl_
->SetViewportSize(device_viewport
);
6084 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6085 host_impl_
->active_tree()->set_needs_update_draw_properties();
6087 LayerTreeHostImpl::FrameData frame
;
6088 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6090 ASSERT_EQ(1u, frame
.render_passes
.size());
6091 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6092 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6093 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6094 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6095 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6096 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6097 replica_quad
->rect
.ToString());
6098 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
6099 replica_quad
->MaskUVRect().ToString());
6100 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
6101 replica_quad
->mask_uv_scale
.ToString());
6103 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6104 host_impl_
->DidDrawAllLayers(frame
);
6107 // Applying an equivalent content scale on the content layer and the mask
6108 // should still result in the same part of the mask being used.
6109 gfx::Size layer_size_large
=
6110 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
6111 content_layer
->SetContentBounds(layer_size_large
);
6112 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
6113 gfx::Size mask_size_large
=
6114 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
6115 mask_layer
->SetContentBounds(mask_size_large
);
6116 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
6117 host_impl_
->active_tree()->set_needs_update_draw_properties();
6119 LayerTreeHostImpl::FrameData frame
;
6120 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6122 ASSERT_EQ(1u, frame
.render_passes
.size());
6123 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6124 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6125 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6126 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6127 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6128 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6129 replica_quad
->rect
.ToString());
6130 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
6131 replica_quad
->MaskUVRect().ToString());
6132 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
6133 replica_quad
->mask_uv_scale
.ToString());
6135 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6136 host_impl_
->DidDrawAllLayers(frame
);
6139 // Applying a different contents scale to the mask layer means it will have
6140 // a larger texture, but it should use the same tex coords to cover the
6142 mask_layer
->SetContentBounds(mask_size
);
6143 mask_layer
->SetContentsScale(1.f
, 1.f
);
6144 host_impl_
->active_tree()->set_needs_update_draw_properties();
6146 LayerTreeHostImpl::FrameData frame
;
6147 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6149 ASSERT_EQ(1u, frame
.render_passes
.size());
6150 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6151 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6152 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6153 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6154 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6155 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
6156 replica_quad
->rect
.ToString());
6157 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
6158 replica_quad
->MaskUVRect().ToString());
6159 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
6160 replica_quad
->mask_uv_scale
.ToString());
6162 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6163 host_impl_
->DidDrawAllLayers(frame
);
6167 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
6168 // The replica is of a layer with bounds 50x50, but it has a child that causes
6169 // the surface bounds to be larger.
6171 scoped_ptr
<LayerImpl
> scoped_root
=
6172 LayerImpl::Create(host_impl_
->active_tree(), 1);
6173 LayerImpl
* root
= scoped_root
.get();
6174 root
->SetHasRenderSurface(true);
6175 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
6177 scoped_ptr
<LayerImpl
> scoped_content_layer
=
6178 LayerImpl::Create(host_impl_
->active_tree(), 2);
6179 LayerImpl
* content_layer
= scoped_content_layer
.get();
6180 root
->AddChild(scoped_content_layer
.Pass());
6182 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
6183 LayerImpl::Create(host_impl_
->active_tree(), 3);
6184 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
6185 content_layer
->AddChild(scoped_content_child_layer
.Pass());
6187 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
6188 LayerImpl::Create(host_impl_
->active_tree(), 4);
6189 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
6190 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
6191 content_layer
->SetHasRenderSurface(true);
6193 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
6194 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
6195 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
6196 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
6197 replica_layer
->SetHasRenderSurface(true);
6199 gfx::Size
root_size(100, 100);
6200 root
->SetBounds(root_size
);
6201 root
->SetContentBounds(root_size
);
6202 root
->SetPosition(gfx::PointF());
6204 gfx::Size
layer_size(50, 50);
6205 content_layer
->SetBounds(layer_size
);
6206 content_layer
->SetContentBounds(layer_size
);
6207 content_layer
->SetPosition(gfx::PointF());
6208 content_layer
->SetDrawsContent(true);
6210 gfx::Size
child_size(50, 50);
6211 content_child_layer
->SetBounds(child_size
);
6212 content_child_layer
->SetContentBounds(child_size
);
6213 content_child_layer
->SetPosition(gfx::Point(50, 0));
6214 content_child_layer
->SetDrawsContent(true);
6216 gfx::Size
mask_size(50, 50);
6217 mask_layer
->SetBounds(mask_size
);
6218 mask_layer
->SetContentBounds(mask_size
);
6219 mask_layer
->SetPosition(gfx::PointF());
6220 mask_layer
->SetDrawsContent(true);
6222 float device_scale_factor
= 1.f
;
6223 host_impl_
->SetViewportSize(root_size
);
6224 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6226 LayerTreeHostImpl::FrameData frame
;
6227 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6229 ASSERT_EQ(1u, frame
.render_passes
.size());
6230 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6232 // The surface is 100x50.
6233 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6234 frame
.render_passes
[0]->quad_list
.front()->material
);
6235 const RenderPassDrawQuad
* render_pass_quad
=
6236 RenderPassDrawQuad::MaterialCast(
6237 frame
.render_passes
[0]->quad_list
.front());
6238 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
6239 render_pass_quad
->rect
.ToString());
6241 // The mask covers the owning layer only.
6242 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6243 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6244 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6245 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6246 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
6247 replica_quad
->rect
.ToString());
6248 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
6249 replica_quad
->MaskUVRect().ToString());
6250 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
6251 replica_quad
->mask_uv_scale
.ToString());
6253 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6254 host_impl_
->DidDrawAllLayers(frame
);
6257 // Move the child to (-50, 0) instead. Now the mask should be moved to still
6258 // cover the layer being replicated.
6259 content_child_layer
->SetPosition(gfx::Point(-50, 0));
6261 LayerTreeHostImpl::FrameData frame
;
6262 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6264 ASSERT_EQ(1u, frame
.render_passes
.size());
6265 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6267 // The surface is 100x50 with its origin at (-50, 0).
6268 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6269 frame
.render_passes
[0]->quad_list
.front()->material
);
6270 const RenderPassDrawQuad
* render_pass_quad
=
6271 RenderPassDrawQuad::MaterialCast(
6272 frame
.render_passes
[0]->quad_list
.front());
6273 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6274 render_pass_quad
->rect
.ToString());
6276 // The mask covers the owning layer only.
6277 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6278 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6279 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6280 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6281 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6282 replica_quad
->rect
.ToString());
6283 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
6284 replica_quad
->MaskUVRect().ToString());
6285 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
6286 replica_quad
->mask_uv_scale
.ToString());
6288 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6289 host_impl_
->DidDrawAllLayers(frame
);
6293 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
6294 // The masked layer has bounds 50x50, but it has a child that causes
6295 // the surface bounds to be larger. It also has a parent that clips the
6296 // masked layer and its surface.
6298 scoped_ptr
<LayerImpl
> scoped_root
=
6299 LayerImpl::Create(host_impl_
->active_tree(), 1);
6300 LayerImpl
* root
= scoped_root
.get();
6301 root
->SetHasRenderSurface(true);
6303 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
6305 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
6306 LayerImpl::Create(host_impl_
->active_tree(), 2);
6307 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
6308 root
->AddChild(scoped_clipping_layer
.Pass());
6310 scoped_ptr
<LayerImpl
> scoped_content_layer
=
6311 LayerImpl::Create(host_impl_
->active_tree(), 3);
6312 LayerImpl
* content_layer
= scoped_content_layer
.get();
6313 clipping_layer
->AddChild(scoped_content_layer
.Pass());
6315 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
6316 LayerImpl::Create(host_impl_
->active_tree(), 4);
6317 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
6318 content_layer
->AddChild(scoped_content_child_layer
.Pass());
6320 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
6321 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
6322 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
6323 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
6324 content_layer
->SetHasRenderSurface(true);
6326 gfx::Size
root_size(100, 100);
6327 root
->SetBounds(root_size
);
6328 root
->SetContentBounds(root_size
);
6329 root
->SetPosition(gfx::PointF());
6331 gfx::Rect
clipping_rect(20, 10, 10, 20);
6332 clipping_layer
->SetBounds(clipping_rect
.size());
6333 clipping_layer
->SetContentBounds(clipping_rect
.size());
6334 clipping_layer
->SetPosition(clipping_rect
.origin());
6335 clipping_layer
->SetMasksToBounds(true);
6337 gfx::Size
layer_size(50, 50);
6338 content_layer
->SetBounds(layer_size
);
6339 content_layer
->SetContentBounds(layer_size
);
6340 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
6341 content_layer
->SetDrawsContent(true);
6343 gfx::Size
child_size(50, 50);
6344 content_child_layer
->SetBounds(child_size
);
6345 content_child_layer
->SetContentBounds(child_size
);
6346 content_child_layer
->SetPosition(gfx::Point(50, 0));
6347 content_child_layer
->SetDrawsContent(true);
6349 gfx::Size
mask_size(100, 100);
6350 mask_layer
->SetBounds(mask_size
);
6351 mask_layer
->SetContentBounds(mask_size
);
6352 mask_layer
->SetPosition(gfx::PointF());
6353 mask_layer
->SetDrawsContent(true);
6355 float device_scale_factor
= 1.f
;
6356 host_impl_
->SetViewportSize(root_size
);
6357 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6359 LayerTreeHostImpl::FrameData frame
;
6360 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6362 ASSERT_EQ(1u, frame
.render_passes
.size());
6363 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
6365 // The surface is clipped to 10x20.
6366 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6367 frame
.render_passes
[0]->quad_list
.front()->material
);
6368 const RenderPassDrawQuad
* render_pass_quad
=
6369 RenderPassDrawQuad::MaterialCast(
6370 frame
.render_passes
[0]->quad_list
.front());
6371 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6372 render_pass_quad
->rect
.ToString());
6373 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6374 // coords in the mask are scaled by 10/50 and 20/50.
6375 // The surface is clipped to (20,10) so the mask texture coords are offset
6376 // by 20/50 and 10/50
6377 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
), 1.f
/ 50.f
)
6379 render_pass_quad
->MaskUVRect().ToString());
6380 EXPECT_EQ(gfx::Vector2dF(10.f
/ 50.f
, 20.f
/ 50.f
).ToString(),
6381 render_pass_quad
->mask_uv_scale
.ToString());
6383 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6384 host_impl_
->DidDrawAllLayers(frame
);
6388 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
6390 using GLRenderer::ShouldAntialiasQuad
;
6393 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
6394 // Due to precision issues (especially on Android), sometimes far
6395 // away quads can end up thinking they need AA.
6396 float device_scale_factor
= 4.f
/ 3.f
;
6397 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6398 gfx::Size
root_size(2000, 1000);
6399 gfx::Size device_viewport_size
=
6400 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
6401 host_impl_
->SetViewportSize(device_viewport_size
);
6403 host_impl_
->CreatePendingTree();
6404 host_impl_
->pending_tree()->PushPageScaleFromMainThread(1.f
, 1.f
/ 16.f
,
6407 scoped_ptr
<LayerImpl
> scoped_root
=
6408 LayerImpl::Create(host_impl_
->pending_tree(), 1);
6409 LayerImpl
* root
= scoped_root
.get();
6410 root
->SetHasRenderSurface(true);
6412 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
6414 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
6415 LayerImpl::Create(host_impl_
->pending_tree(), 2);
6416 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
6417 root
->AddChild(scoped_scrolling_layer
.Pass());
6419 gfx::Size
content_layer_bounds(100000, 100);
6420 gfx::Size
pile_tile_size(3000, 3000);
6421 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
6422 pile_tile_size
, content_layer_bounds
));
6424 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
6425 FakePictureLayerImpl::CreateWithRasterSource(host_impl_
->pending_tree(),
6427 LayerImpl
* content_layer
= scoped_content_layer
.get();
6428 scrolling_layer
->AddChild(scoped_content_layer
.Pass());
6429 content_layer
->SetBounds(content_layer_bounds
);
6430 content_layer
->SetDrawsContent(true);
6432 root
->SetBounds(root_size
);
6434 gfx::ScrollOffset
scroll_offset(100000, 0);
6435 scrolling_layer
->SetScrollClipLayer(root
->id());
6436 scrolling_layer
->PushScrollOffsetFromMainThread(scroll_offset
);
6438 host_impl_
->ActivateSyncTree();
6440 bool update_lcd_text
= false;
6441 host_impl_
->active_tree()->UpdateDrawProperties(update_lcd_text
);
6442 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
6444 LayerTreeHostImpl::FrameData frame
;
6445 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6447 ASSERT_EQ(1u, frame
.render_passes
.size());
6448 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
6449 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
.front();
6452 GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
6453 quad
->quadTransform(), quad
, false);
6454 EXPECT_FALSE(antialiased
);
6456 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6457 host_impl_
->DidDrawAllLayers(frame
);
6461 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
6463 CompositorFrameMetadataTest()
6464 : swap_buffers_complete_(0) {}
6466 void DidSwapBuffersCompleteOnImplThread() override
{
6467 swap_buffers_complete_
++;
6470 int swap_buffers_complete_
;
6473 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
6474 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
6476 LayerTreeHostImpl::FrameData frame
;
6477 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6478 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
6479 host_impl_
->DidDrawAllLayers(frame
);
6481 CompositorFrameAck ack
;
6482 host_impl_
->ReclaimResources(&ack
);
6483 host_impl_
->DidSwapBuffersComplete();
6484 EXPECT_EQ(swap_buffers_complete_
, 1);
6487 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
6489 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
6491 SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) override
{
6493 return SoftwareOutputDevice::BeginPaint(damage_rect
);
6495 void EndPaint(SoftwareFrameData
* frame_data
) override
{
6497 SoftwareOutputDevice::EndPaint(frame_data
);
6500 int frames_began_
, frames_ended_
;
6503 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
6504 // No main thread evictions in resourceless software mode.
6505 set_reduce_memory_result(false);
6506 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
6507 bool delegated_rendering
= false;
6508 FakeOutputSurface
* output_surface
=
6509 FakeOutputSurface::CreateDeferredGL(
6510 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
6511 delegated_rendering
).release();
6512 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6513 scoped_ptr
<OutputSurface
>(output_surface
)));
6514 host_impl_
->SetViewportSize(gfx::Size(50, 50));
6516 SetupScrollAndContentsLayers(gfx::Size(100, 100));
6518 const gfx::Transform external_transform
;
6519 const gfx::Rect external_viewport
;
6520 const gfx::Rect external_clip
;
6521 const bool resourceless_software_draw
= true;
6522 host_impl_
->SetExternalDrawConstraints(external_transform
,
6527 resourceless_software_draw
);
6529 EXPECT_EQ(0, software_device
->frames_began_
);
6530 EXPECT_EQ(0, software_device
->frames_ended_
);
6534 EXPECT_EQ(1, software_device
->frames_began_
);
6535 EXPECT_EQ(1, software_device
->frames_ended_
);
6537 // Call another API method that is likely to hit nullptr in this mode.
6538 scoped_refptr
<base::trace_event::TracedValue
> state
=
6539 make_scoped_refptr(new base::trace_event::TracedValue());
6540 host_impl_
->ActivationStateAsValueInto(state
.get());
6543 TEST_F(LayerTreeHostImplTest
,
6544 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
6545 set_reduce_memory_result(false);
6546 bool delegated_rendering
= false;
6547 FakeOutputSurface
* output_surface
=
6548 FakeOutputSurface::CreateDeferredGL(
6549 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6550 delegated_rendering
).release();
6551 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6552 scoped_ptr
<OutputSurface
>(output_surface
)));
6554 const gfx::Transform external_transform
;
6555 const gfx::Rect external_viewport
;
6556 const gfx::Rect external_clip
;
6557 const bool resourceless_software_draw
= true;
6558 host_impl_
->SetExternalDrawConstraints(external_transform
,
6563 resourceless_software_draw
);
6565 // SolidColorLayerImpl will be drawn.
6566 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6567 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6569 // VideoLayerImpl will not be drawn.
6570 FakeVideoFrameProvider provider
;
6571 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
6572 host_impl_
->active_tree(), 2, &provider
, media::VIDEO_ROTATION_0
);
6573 video_layer
->SetBounds(gfx::Size(10, 10));
6574 video_layer
->SetContentBounds(gfx::Size(10, 10));
6575 video_layer
->SetDrawsContent(true);
6576 root_layer
->AddChild(video_layer
.Pass());
6577 SetupRootLayerImpl(root_layer
.Pass());
6579 LayerTreeHostImpl::FrameData frame
;
6580 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6581 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6582 host_impl_
->DidDrawAllLayers(frame
);
6584 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
6585 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
6588 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
6590 void SetUp() override
{
6591 LayerTreeHostImplTest::SetUp();
6593 set_reduce_memory_result(false);
6595 bool delegated_rendering
= false;
6596 scoped_ptr
<FakeOutputSurface
> output_surface(
6597 FakeOutputSurface::CreateDeferredGL(
6598 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6599 delegated_rendering
));
6600 output_surface_
= output_surface
.get();
6602 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), output_surface
.Pass()));
6604 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6605 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6606 SetupRootLayerImpl(root_layer
.Pass());
6608 onscreen_context_provider_
= TestContextProvider::Create();
6611 void UpdateRendererCapabilitiesOnImplThread() override
{
6612 did_update_renderer_capabilities_
= true;
6615 FakeOutputSurface
* output_surface_
;
6616 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
6617 bool did_update_renderer_capabilities_
;
6621 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
6625 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6627 // DeferredInitialize and hardware draw.
6628 did_update_renderer_capabilities_
= false;
6629 EXPECT_TRUE(output_surface_
->InitializeAndSetContext3d(
6630 onscreen_context_provider_
, nullptr));
6631 EXPECT_EQ(onscreen_context_provider_
.get(),
6632 host_impl_
->output_surface()->context_provider());
6633 EXPECT_TRUE(did_update_renderer_capabilities_
);
6635 // Defer intialized GL draw.
6638 // Revert back to software.
6639 did_update_renderer_capabilities_
= false;
6640 output_surface_
->ReleaseGL();
6641 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6642 EXPECT_TRUE(did_update_renderer_capabilities_
);
6644 // Software draw again.
6648 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
6652 // Fail initialization of the onscreen context before the OutputSurface binds
6653 // it to the thread.
6654 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
6656 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6658 // DeferredInitialize fails.
6659 did_update_renderer_capabilities_
= false;
6660 EXPECT_FALSE(output_surface_
->InitializeAndSetContext3d(
6661 onscreen_context_provider_
, nullptr));
6662 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6663 EXPECT_FALSE(did_update_renderer_capabilities_
);
6665 // Software draw again.
6669 // Checks that we have a non-0 default allocation if we pass a context that
6670 // doesn't support memory management extensions.
6671 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
6672 LayerTreeSettings settings
;
6673 host_impl_
= LayerTreeHostImpl::Create(settings
,
6676 &stats_instrumentation_
,
6677 shared_bitmap_manager_
.get(),
6678 gpu_memory_buffer_manager_
.get(),
6681 scoped_ptr
<OutputSurface
> output_surface(
6682 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
6683 host_impl_
->InitializeRenderer(output_surface
.Pass());
6684 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
6687 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
6688 ManagedMemoryPolicy
policy1(
6689 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
6690 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6691 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
6692 int allow_nice_to_have_cutoff_value
=
6693 ManagedMemoryPolicy::PriorityCutoffToValue(
6694 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
6695 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6696 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
6698 // GPU rasterization should be disabled by default on the tree(s)
6699 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
6700 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
6702 host_impl_
->SetVisible(true);
6703 host_impl_
->SetMemoryPolicy(policy1
);
6704 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6705 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6707 host_impl_
->SetVisible(false);
6708 EXPECT_EQ(0u, current_limit_bytes_
);
6709 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6711 host_impl_
->SetVisible(true);
6712 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6713 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6715 // Now enable GPU rasterization and test if we get nice to have cutoff,
6717 LayerTreeSettings settings
;
6718 settings
.gpu_rasterization_enabled
= true;
6719 host_impl_
= LayerTreeHostImpl::Create(
6720 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, NULL
, 0);
6721 host_impl_
->SetUseGpuRasterization(true);
6722 host_impl_
->SetVisible(true);
6723 host_impl_
->SetMemoryPolicy(policy1
);
6724 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6725 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
6727 host_impl_
->SetVisible(false);
6728 EXPECT_EQ(0u, current_limit_bytes_
);
6729 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6732 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
6733 ASSERT_TRUE(host_impl_
->active_tree());
6735 // RequiresHighResToDraw is set when new output surface is used.
6736 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6738 host_impl_
->ResetRequiresHighResToDraw();
6740 host_impl_
->SetVisible(false);
6741 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6742 host_impl_
->SetVisible(true);
6743 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6744 host_impl_
->SetVisible(false);
6745 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6747 host_impl_
->ResetRequiresHighResToDraw();
6749 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6750 host_impl_
->SetVisible(true);
6751 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6754 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
6755 ASSERT_TRUE(host_impl_
->active_tree());
6756 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
6758 // RequiresHighResToDraw is set when new output surface is used.
6759 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6761 host_impl_
->ResetRequiresHighResToDraw();
6763 host_impl_
->SetUseGpuRasterization(false);
6764 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6765 host_impl_
->SetUseGpuRasterization(true);
6766 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6767 host_impl_
->SetUseGpuRasterization(false);
6768 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6770 host_impl_
->ResetRequiresHighResToDraw();
6772 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6773 host_impl_
->SetUseGpuRasterization(true);
6774 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6777 class LayerTreeHostImplTestPrepareTiles
: public LayerTreeHostImplTest
{
6779 void SetUp() override
{
6780 LayerTreeSettings settings
;
6781 settings
.impl_side_painting
= true;
6783 fake_host_impl_
= new FakeLayerTreeHostImpl(
6784 settings
, &proxy_
, shared_bitmap_manager_
.get());
6785 host_impl_
.reset(fake_host_impl_
);
6786 host_impl_
->InitializeRenderer(CreateOutputSurface());
6787 host_impl_
->SetViewportSize(gfx::Size(10, 10));
6790 FakeLayerTreeHostImpl
* fake_host_impl_
;
6793 TEST_F(LayerTreeHostImplTestPrepareTiles
, PrepareTilesWhenInvisible
) {
6794 fake_host_impl_
->DidModifyTilePriorities();
6795 EXPECT_TRUE(fake_host_impl_
->prepare_tiles_needed());
6796 fake_host_impl_
->SetVisible(false);
6797 EXPECT_FALSE(fake_host_impl_
->prepare_tiles_needed());
6800 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
6801 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6802 TestWebGraphicsContext3D::Create();
6803 TestWebGraphicsContext3D
* context3d
= context
.get();
6804 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
6805 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
6807 EXPECT_EQ(0u, context3d
->NumTextures());
6809 UIResourceId ui_resource_id
= 1;
6810 bool is_opaque
= false;
6811 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
6812 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6813 EXPECT_EQ(1u, context3d
->NumTextures());
6814 ResourceProvider::ResourceId id1
=
6815 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6818 // Multiple requests with the same id is allowed. The previous texture is
6820 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6821 EXPECT_EQ(1u, context3d
->NumTextures());
6822 ResourceProvider::ResourceId id2
=
6823 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6825 EXPECT_NE(id1
, id2
);
6827 // Deleting invalid UIResourceId is allowed and does not change state.
6828 host_impl_
->DeleteUIResource(-1);
6829 EXPECT_EQ(1u, context3d
->NumTextures());
6831 // Should return zero for invalid UIResourceId. Number of textures should
6833 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
6834 EXPECT_EQ(1u, context3d
->NumTextures());
6836 host_impl_
->DeleteUIResource(ui_resource_id
);
6837 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
6838 EXPECT_EQ(0u, context3d
->NumTextures());
6840 // Should not change state for multiple deletion on one UIResourceId
6841 host_impl_
->DeleteUIResource(ui_resource_id
);
6842 EXPECT_EQ(0u, context3d
->NumTextures());
6845 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
6846 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6847 TestWebGraphicsContext3D::Create();
6848 TestWebGraphicsContext3D
* context3d
= context
.get();
6849 CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d());
6851 EXPECT_EQ(0u, context3d
->NumTextures());
6853 gfx::Size
size(4, 4);
6854 // SkImageInfo has no support for ETC1. The |info| below contains the right
6855 // total pixel size for the bitmap but not the right height and width. The
6856 // correct width/height are passed directly to UIResourceBitmap.
6858 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
6859 skia::RefPtr
<SkPixelRef
> pixel_ref
=
6860 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
6861 pixel_ref
->setImmutable();
6862 UIResourceBitmap
bitmap(pixel_ref
, size
);
6863 UIResourceId ui_resource_id
= 1;
6864 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6865 EXPECT_EQ(1u, context3d
->NumTextures());
6866 ResourceProvider::ResourceId id1
=
6867 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6871 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
6874 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
6875 scoped_refptr
<TestContextProvider
> context_provider
=
6876 TestContextProvider::Create();
6878 CreateHostImpl(DefaultSettings(),
6879 FakeOutputSurface::Create3d(context_provider
));
6881 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
6883 ScopedPtrVector
<CopyOutputRequest
> requests
;
6884 requests
.push_back(CopyOutputRequest::CreateRequest(
6885 base::Bind(&ShutdownReleasesContext_Callback
)));
6887 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
6889 LayerTreeHostImpl::FrameData frame
;
6890 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6891 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6892 host_impl_
->DidDrawAllLayers(frame
);
6894 // The CopyOutputResult's callback has a ref on the ContextProvider and a
6895 // texture in a texture mailbox.
6896 EXPECT_FALSE(context_provider
->HasOneRef());
6897 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
6899 host_impl_
= nullptr;
6901 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
6902 // released, and the texture deleted.
6903 EXPECT_TRUE(context_provider
->HasOneRef());
6904 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
6907 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
6908 // When flinging via touch, only the child should scroll (we should not
6910 gfx::Size
surface_size(10, 10);
6911 gfx::Size
content_size(20, 20);
6912 scoped_ptr
<LayerImpl
> root_clip
=
6913 LayerImpl::Create(host_impl_
->active_tree(), 3);
6914 root_clip
->SetHasRenderSurface(true);
6916 scoped_ptr
<LayerImpl
> root
=
6917 CreateScrollableLayer(1, content_size
, root_clip
.get());
6918 root
->SetIsContainerForFixedPositionLayers(true);
6919 scoped_ptr
<LayerImpl
> child
=
6920 CreateScrollableLayer(2, content_size
, root_clip
.get());
6922 root
->AddChild(child
.Pass());
6923 int root_id
= root
->id();
6924 root_clip
->AddChild(root
.Pass());
6926 host_impl_
->SetViewportSize(surface_size
);
6927 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6928 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
6930 host_impl_
->active_tree()->DidBecomeActive();
6933 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
6934 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
6936 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
6938 gfx::Vector2d
scroll_delta(0, 100);
6939 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6940 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6942 host_impl_
->ScrollEnd();
6944 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6945 host_impl_
->ProcessScrollDeltas();
6947 // Only the child should have scrolled.
6948 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6949 ExpectNone(*scroll_info
.get(), root_id
);
6953 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
6954 // Scroll a child layer beyond its maximum scroll range and make sure the
6955 // the scroll doesn't bubble up to the parent layer.
6956 gfx::Size
surface_size(10, 10);
6957 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
6958 root
->SetHasRenderSurface(true);
6959 scoped_ptr
<LayerImpl
> root_scrolling
=
6960 CreateScrollableLayer(2, surface_size
, root
.get());
6962 scoped_ptr
<LayerImpl
> grand_child
=
6963 CreateScrollableLayer(4, surface_size
, root
.get());
6964 grand_child
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 2));
6966 scoped_ptr
<LayerImpl
> child
=
6967 CreateScrollableLayer(3, surface_size
, root
.get());
6968 child
->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 4));
6969 child
->AddChild(grand_child
.Pass());
6971 root_scrolling
->AddChild(child
.Pass());
6972 root
->AddChild(root_scrolling
.Pass());
6973 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6974 host_impl_
->active_tree()->DidBecomeActive();
6975 host_impl_
->SetViewportSize(surface_size
);
6978 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
6980 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
6981 LayerImpl
* grand_child
= child
->children()[0];
6983 gfx::Vector2d
scroll_delta(0, -2);
6984 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
6985 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
6986 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6988 // The grand child should have scrolled up to its limit.
6989 scroll_info
= host_impl_
->ProcessScrollDeltas();
6990 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6991 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6992 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6994 // The child should have received the bubbled delta, but the locked
6995 // scrolling layer should remain set as the grand child.
6996 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6997 scroll_info
= host_impl_
->ProcessScrollDeltas();
6998 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6999 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
7000 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
7001 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
7003 // The first |ScrollBy| after the fling should re-lock the scrolling
7004 // layer to the first layer that scrolled, which is the child.
7005 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
7006 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
7007 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
7009 // The child should have scrolled up to its limit.
7010 scroll_info
= host_impl_
->ProcessScrollDeltas();
7011 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
7012 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
7013 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
7015 // As the locked layer is at it's limit, no further scrolling can occur.
7016 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
7017 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
7018 host_impl_
->ScrollEnd();
7022 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
7023 // When flinging via wheel, the root should eventually scroll (we should
7025 gfx::Size
surface_size(10, 10);
7026 gfx::Size
content_size(20, 20);
7027 scoped_ptr
<LayerImpl
> root_clip
=
7028 LayerImpl::Create(host_impl_
->active_tree(), 3);
7029 root_clip
->SetHasRenderSurface(true);
7030 scoped_ptr
<LayerImpl
> root_scroll
=
7031 CreateScrollableLayer(1, content_size
, root_clip
.get());
7032 int root_scroll_id
= root_scroll
->id();
7033 scoped_ptr
<LayerImpl
> child
=
7034 CreateScrollableLayer(2, content_size
, root_clip
.get());
7036 root_scroll
->AddChild(child
.Pass());
7037 root_clip
->AddChild(root_scroll
.Pass());
7039 host_impl_
->SetViewportSize(surface_size
);
7040 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
7041 host_impl_
->active_tree()->DidBecomeActive();
7044 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7045 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7047 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
7049 gfx::Vector2d
scroll_delta(0, 100);
7050 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7051 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7053 host_impl_
->ScrollEnd();
7055 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
7056 host_impl_
->ProcessScrollDeltas();
7058 // The root should have scrolled.
7059 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
7060 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
7064 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
7065 // If we ray cast a scroller that is not on the first layer's ancestor chain,
7066 // we should return SCROLL_UNKNOWN.
7067 gfx::Size
content_size(100, 100);
7068 SetupScrollAndContentsLayers(content_size
);
7070 int scroll_layer_id
= 2;
7071 LayerImpl
* scroll_layer
=
7072 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
7073 scroll_layer
->SetDrawsContent(true);
7075 int page_scale_layer_id
= 5;
7076 LayerImpl
* page_scale_layer
=
7077 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
7079 int occluder_layer_id
= 6;
7080 scoped_ptr
<LayerImpl
> occluder_layer
=
7081 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
7082 occluder_layer
->SetDrawsContent(true);
7083 occluder_layer
->SetBounds(content_size
);
7084 occluder_layer
->SetContentBounds(content_size
);
7085 occluder_layer
->SetPosition(gfx::PointF());
7087 // The parent of the occluder is *above* the scroller.
7088 page_scale_layer
->AddChild(occluder_layer
.Pass());
7092 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN
,
7093 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7096 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
7097 // If we ray cast a scroller this is on the first layer's ancestor chain, but
7098 // is not the first scroller we encounter when walking up from the layer, we
7099 // should also return SCROLL_UNKNOWN.
7100 gfx::Size
content_size(100, 100);
7101 SetupScrollAndContentsLayers(content_size
);
7103 int scroll_layer_id
= 2;
7104 LayerImpl
* scroll_layer
=
7105 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
7106 scroll_layer
->SetDrawsContent(true);
7108 int occluder_layer_id
= 6;
7109 scoped_ptr
<LayerImpl
> occluder_layer
=
7110 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
7111 occluder_layer
->SetDrawsContent(true);
7112 occluder_layer
->SetBounds(content_size
);
7113 occluder_layer
->SetContentBounds(content_size
);
7114 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
7116 int child_scroll_clip_layer_id
= 7;
7117 scoped_ptr
<LayerImpl
> child_scroll_clip
=
7118 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
7120 int child_scroll_layer_id
= 8;
7121 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
7122 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
7124 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
7126 child_scroll
->AddChild(occluder_layer
.Pass());
7127 scroll_layer
->AddChild(child_scroll
.Pass());
7131 EXPECT_EQ(InputHandler::SCROLL_UNKNOWN
,
7132 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7135 TEST_F(LayerTreeHostImplTest
, NotScrollInvisibleScroller
) {
7136 gfx::Size
content_size(100, 100);
7137 SetupScrollAndContentsLayers(content_size
);
7139 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
7141 int scroll_layer_id
= 2;
7142 LayerImpl
* scroll_layer
=
7143 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
7145 int child_scroll_layer_id
= 7;
7146 scoped_ptr
<LayerImpl
> child_scroll
=
7147 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
7148 child_scroll
->SetDrawsContent(false);
7150 scroll_layer
->AddChild(child_scroll
.Pass());
7154 // We should not have scrolled |child_scroll| even though we technically "hit"
7155 // it. The reason for this is that if the scrolling the scroll would not move
7156 // any layer that is a drawn RSLL member, then we can ignore the hit.
7158 // Why SCROLL_STARTED? In this case, it's because we've bubbled out and
7159 // started scrolling the inner viewport.
7160 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7161 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7163 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
7166 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleDescendent
) {
7167 gfx::Size
content_size(100, 100);
7168 SetupScrollAndContentsLayers(content_size
);
7170 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
7171 LayerImpl
* root_scroll_layer
= host_impl_
->active_tree()->LayerById(2);
7173 scoped_ptr
<LayerImpl
> invisible_scroll_layer
=
7174 CreateScrollableLayer(7, content_size
, root
);
7175 invisible_scroll_layer
->SetDrawsContent(false);
7177 scoped_ptr
<LayerImpl
> child_layer
=
7178 LayerImpl::Create(host_impl_
->active_tree(), 8);
7179 child_layer
->SetDrawsContent(false);
7181 scoped_ptr
<LayerImpl
> grand_child_layer
=
7182 LayerImpl::Create(host_impl_
->active_tree(), 9);
7183 grand_child_layer
->SetDrawsContent(true);
7184 grand_child_layer
->SetBounds(content_size
);
7185 grand_child_layer
->SetContentBounds(content_size
);
7186 // Move the grand child so it's not hit by our test point.
7187 grand_child_layer
->SetPosition(gfx::PointF(10.f
, 10.f
));
7189 child_layer
->AddChild(grand_child_layer
.Pass());
7190 invisible_scroll_layer
->AddChild(child_layer
.Pass());
7191 root_scroll_layer
->AddChild(invisible_scroll_layer
.Pass());
7195 // We should have scrolled |invisible_scroll_layer| as it was hit and it has
7196 // a descendant which is a drawn RSLL member.
7197 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7198 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7200 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
7203 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
7204 // This test case is very similar to the one above with one key difference:
7205 // the invisible scroller has a scroll child that is indeed draw contents.
7206 // If we attempt to initiate a gesture scroll off of the visible scroll child
7207 // we should still start the scroll child.
7208 gfx::Size
content_size(100, 100);
7209 SetupScrollAndContentsLayers(content_size
);
7211 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
7213 int scroll_layer_id
= 2;
7214 LayerImpl
* scroll_layer
=
7215 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
7217 int scroll_child_id
= 6;
7218 scoped_ptr
<LayerImpl
> scroll_child
=
7219 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
7220 scroll_child
->SetDrawsContent(true);
7221 scroll_child
->SetBounds(content_size
);
7222 scroll_child
->SetContentBounds(content_size
);
7223 // Move the scroll child so it's not hit by our test point.
7224 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
7226 int invisible_scroll_layer_id
= 7;
7227 scoped_ptr
<LayerImpl
> invisible_scroll
=
7228 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
7229 invisible_scroll
->SetDrawsContent(false);
7231 int container_id
= 8;
7232 scoped_ptr
<LayerImpl
> container
=
7233 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
7235 scoped_ptr
<std::set
<LayerImpl
*>> scroll_children(new std::set
<LayerImpl
*>);
7236 scroll_children
->insert(scroll_child
.get());
7237 invisible_scroll
->SetScrollChildren(scroll_children
.release());
7239 scroll_child
->SetScrollParent(invisible_scroll
.get());
7241 container
->AddChild(invisible_scroll
.Pass());
7242 container
->AddChild(scroll_child
.Pass());
7244 scroll_layer
->AddChild(container
.Pass());
7248 // We should have scrolled |child_scroll| even though it is invisible.
7249 // The reason for this is that if the scrolling the scroll would move a layer
7250 // that is a drawn RSLL member, then we should accept this hit.
7251 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7252 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
7254 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
7257 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
7258 // to CompositorFrameMetadata after SwapBuffers();
7259 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
7260 scoped_ptr
<SolidColorLayerImpl
> root
=
7261 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
7262 root
->SetPosition(gfx::PointF());
7263 root
->SetBounds(gfx::Size(10, 10));
7264 root
->SetContentBounds(gfx::Size(10, 10));
7265 root
->SetDrawsContent(true);
7266 root
->SetHasRenderSurface(true);
7268 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
7270 FakeOutputSurface
* fake_output_surface
=
7271 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
7273 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
7274 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
7275 EXPECT_TRUE(metadata_latency_before
.empty());
7277 ui::LatencyInfo latency_info
;
7278 latency_info
.AddLatencyNumber(
7279 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
7280 scoped_ptr
<SwapPromise
> swap_promise(
7281 new LatencyInfoSwapPromise(latency_info
));
7282 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
7283 host_impl_
->SetNeedsRedraw();
7285 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
7286 LayerTreeHostImpl::FrameData frame
;
7287 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
7288 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
7289 host_impl_
->DidDrawAllLayers(frame
);
7290 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
7292 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
7293 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
7294 EXPECT_EQ(1u, metadata_latency_after
.size());
7295 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
7296 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
7299 TEST_F(LayerTreeHostImplTest
, SelectionBoundsPassedToCompositorFrameMetadata
) {
7300 int root_layer_id
= 1;
7301 scoped_ptr
<SolidColorLayerImpl
> root
=
7302 SolidColorLayerImpl::Create(host_impl_
->active_tree(), root_layer_id
);
7303 root
->SetPosition(gfx::PointF());
7304 root
->SetBounds(gfx::Size(10, 10));
7305 root
->SetContentBounds(gfx::Size(10, 10));
7306 root
->SetDrawsContent(true);
7307 root
->SetHasRenderSurface(true);
7309 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
7311 // Ensure the default frame selection bounds are empty.
7312 FakeOutputSurface
* fake_output_surface
=
7313 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
7314 const ViewportSelectionBound
& selection_start_before
=
7315 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
7316 const ViewportSelectionBound
& selection_end_before
=
7317 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
7318 EXPECT_EQ(ViewportSelectionBound(), selection_start_before
);
7319 EXPECT_EQ(ViewportSelectionBound(), selection_end_before
);
7321 // Plumb the layer-local selection bounds.
7322 gfx::PointF
selection_top(5, 0);
7323 gfx::PointF
selection_bottom(5, 5);
7324 LayerSelectionBound start
, end
;
7325 start
.type
= SELECTION_BOUND_CENTER
;
7326 start
.layer_id
= root_layer_id
;
7327 start
.edge_bottom
= selection_bottom
;
7328 start
.edge_top
= selection_top
;
7330 host_impl_
->active_tree()->RegisterSelection(start
, end
);
7332 // Trigger a draw-swap sequence.
7333 host_impl_
->SetNeedsRedraw();
7335 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
7336 LayerTreeHostImpl::FrameData frame
;
7337 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
7338 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
7339 host_impl_
->DidDrawAllLayers(frame
);
7340 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
7342 // Ensure the selection bounds have propagated to the frame metadata.
7343 const ViewportSelectionBound
& selection_start_after
=
7344 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
7345 const ViewportSelectionBound
& selection_end_after
=
7346 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
7347 EXPECT_EQ(start
.type
, selection_start_after
.type
);
7348 EXPECT_EQ(end
.type
, selection_end_after
.type
);
7349 EXPECT_EQ(selection_bottom
, selection_start_after
.edge_bottom
);
7350 EXPECT_EQ(selection_top
, selection_start_after
.edge_top
);
7351 EXPECT_TRUE(selection_start_after
.visible
);
7352 EXPECT_TRUE(selection_start_after
.visible
);
7355 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
7357 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
7358 LayerTreeHostImpl
* layer_tree_host_impl
,
7359 int* set_needs_commit_count
,
7360 int* set_needs_redraw_count
,
7361 int* forward_to_main_count
)
7362 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
7363 set_needs_commit_count_(set_needs_commit_count
),
7364 set_needs_redraw_count_(set_needs_redraw_count
),
7365 forward_to_main_count_(forward_to_main_count
) {}
7367 ~SimpleSwapPromiseMonitor() override
{}
7369 void OnSetNeedsCommitOnMain() override
{ (*set_needs_commit_count_
)++; }
7371 void OnSetNeedsRedrawOnImpl() override
{ (*set_needs_redraw_count_
)++; }
7373 void OnForwardScrollUpdateToMainThreadOnImpl() override
{
7374 (*forward_to_main_count_
)++;
7378 int* set_needs_commit_count_
;
7379 int* set_needs_redraw_count_
;
7380 int* forward_to_main_count_
;
7383 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
7384 int set_needs_commit_count
= 0;
7385 int set_needs_redraw_count
= 0;
7386 int forward_to_main_count
= 0;
7389 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7390 new SimpleSwapPromiseMonitor(NULL
,
7392 &set_needs_commit_count
,
7393 &set_needs_redraw_count
,
7394 &forward_to_main_count
));
7395 host_impl_
->SetNeedsRedraw();
7396 EXPECT_EQ(0, set_needs_commit_count
);
7397 EXPECT_EQ(1, set_needs_redraw_count
);
7398 EXPECT_EQ(0, forward_to_main_count
);
7401 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
7403 host_impl_
->SetNeedsRedraw();
7404 EXPECT_EQ(0, set_needs_commit_count
);
7405 EXPECT_EQ(1, set_needs_redraw_count
);
7406 EXPECT_EQ(0, forward_to_main_count
);
7409 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7410 new SimpleSwapPromiseMonitor(NULL
,
7412 &set_needs_commit_count
,
7413 &set_needs_redraw_count
,
7414 &forward_to_main_count
));
7415 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
7416 EXPECT_EQ(0, set_needs_commit_count
);
7417 EXPECT_EQ(2, set_needs_redraw_count
);
7418 EXPECT_EQ(0, forward_to_main_count
);
7422 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7423 new SimpleSwapPromiseMonitor(NULL
,
7425 &set_needs_commit_count
,
7426 &set_needs_redraw_count
,
7427 &forward_to_main_count
));
7428 // Empty damage rect won't signal the monitor.
7429 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
7430 EXPECT_EQ(0, set_needs_commit_count
);
7431 EXPECT_EQ(2, set_needs_redraw_count
);
7432 EXPECT_EQ(0, forward_to_main_count
);
7436 set_needs_commit_count
= 0;
7437 set_needs_redraw_count
= 0;
7438 forward_to_main_count
= 0;
7439 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7440 new SimpleSwapPromiseMonitor(NULL
,
7442 &set_needs_commit_count
,
7443 &set_needs_redraw_count
,
7444 &forward_to_main_count
));
7445 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
7447 // Scrolling normally should not trigger any forwarding.
7448 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7449 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7451 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
7452 host_impl_
->ScrollEnd();
7454 EXPECT_EQ(0, set_needs_commit_count
);
7455 EXPECT_EQ(1, set_needs_redraw_count
);
7456 EXPECT_EQ(0, forward_to_main_count
);
7458 // Scrolling with a scroll handler should defer the swap to the main
7460 scroll_layer
->SetHaveScrollEventHandlers(true);
7461 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7462 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7464 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
7465 host_impl_
->ScrollEnd();
7467 EXPECT_EQ(0, set_needs_commit_count
);
7468 EXPECT_EQ(2, set_needs_redraw_count
);
7469 EXPECT_EQ(1, forward_to_main_count
);
7473 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
7475 void SetUp() override
{
7476 LayerTreeSettings settings
= DefaultSettings();
7477 CreateHostImpl(settings
, CreateOutputSurface());
7478 host_impl_
->active_tree()->set_top_controls_height(top_controls_height_
);
7479 host_impl_
->sync_tree()->set_top_controls_height(top_controls_height_
);
7480 host_impl_
->active_tree()->SetCurrentTopControlsShownRatio(1.f
);
7484 static const int top_controls_height_
;
7487 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
7489 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
7490 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7491 ->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 10));
7492 host_impl_
->Animate(base::TimeTicks());
7493 EXPECT_FALSE(did_request_redraw_
);
7496 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsHeightIsCommitted
) {
7497 SetupScrollAndContentsLayers(gfx::Size(100, 100));
7498 EXPECT_FALSE(did_request_redraw_
);
7499 host_impl_
->CreatePendingTree();
7500 host_impl_
->sync_tree()->set_top_controls_height(100);
7501 host_impl_
->ActivateSyncTree();
7502 EXPECT_EQ(100, host_impl_
->top_controls_manager()->TopControlsHeight());
7505 TEST_F(LayerTreeHostImplWithTopControlsTest
,
7506 TopControlsStayFullyVisibleOnHeightChange
) {
7507 SetupScrollAndContentsLayers(gfx::Size(100, 100));
7508 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7510 host_impl_
->CreatePendingTree();
7511 host_impl_
->sync_tree()->set_top_controls_height(0);
7512 host_impl_
->ActivateSyncTree();
7513 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7515 host_impl_
->CreatePendingTree();
7516 host_impl_
->sync_tree()->set_top_controls_height(50);
7517 host_impl_
->ActivateSyncTree();
7518 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7521 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
7522 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7523 ->PushScrollOffsetFromMainThread(gfx::ScrollOffset(0, 10));
7524 host_impl_
->DidChangeTopControlsPosition();
7525 EXPECT_TRUE(did_request_animate_
);
7526 EXPECT_TRUE(did_request_redraw_
);
7529 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
7530 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7531 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7532 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7533 BOTH
, SHOWN
, false);
7536 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7537 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7538 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7539 EXPECT_EQ(gfx::Vector2dF().ToString(),
7540 scroll_layer
->CurrentScrollOffset().ToString());
7542 // Scroll just the top controls and verify that the scroll succeeds.
7543 const float residue
= 10;
7544 float offset
= top_controls_height_
- residue
;
7546 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7547 EXPECT_FLOAT_EQ(-offset
,
7548 host_impl_
->top_controls_manager()->ControlsTopOffset());
7549 EXPECT_EQ(gfx::Vector2dF().ToString(),
7550 scroll_layer
->CurrentScrollOffset().ToString());
7552 // Scroll across the boundary
7553 const float content_scroll
= 20;
7554 offset
= residue
+ content_scroll
;
7556 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7557 EXPECT_EQ(-top_controls_height_
,
7558 host_impl_
->top_controls_manager()->ControlsTopOffset());
7559 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
7560 scroll_layer
->CurrentScrollOffset().ToString());
7562 // Now scroll back to the top of the content
7563 offset
= -content_scroll
;
7565 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7566 EXPECT_EQ(-top_controls_height_
,
7567 host_impl_
->top_controls_manager()->ControlsTopOffset());
7568 EXPECT_EQ(gfx::Vector2dF().ToString(),
7569 scroll_layer
->CurrentScrollOffset().ToString());
7571 // And scroll the top controls completely into view
7572 offset
= -top_controls_height_
;
7574 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7575 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7576 EXPECT_EQ(gfx::Vector2dF().ToString(),
7577 scroll_layer
->CurrentScrollOffset().ToString());
7579 // And attempt to scroll past the end
7581 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7582 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7583 EXPECT_EQ(gfx::Vector2dF().ToString(),
7584 scroll_layer
->CurrentScrollOffset().ToString());
7586 host_impl_
->ScrollEnd();
7589 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAtOrigin
) {
7590 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7591 host_impl_
->SetViewportSize(gfx::Size(100, 200));
7592 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7593 BOTH
, SHOWN
, false);
7596 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7597 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7598 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7599 EXPECT_EQ(gfx::Vector2dF().ToString(),
7600 scroll_layer
->CurrentScrollOffset().ToString());
7602 // Scroll the top controls partially.
7603 const float residue
= 35;
7604 float offset
= top_controls_height_
- residue
;
7606 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7607 EXPECT_FLOAT_EQ(-offset
,
7608 host_impl_
->top_controls_manager()->ControlsTopOffset());
7609 EXPECT_EQ(gfx::Vector2dF().ToString(),
7610 scroll_layer
->CurrentScrollOffset().ToString());
7612 did_request_redraw_
= false;
7613 did_request_animate_
= false;
7614 did_request_commit_
= false;
7616 // End the scroll while the controls are still offset from their limit.
7617 host_impl_
->ScrollEnd();
7618 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7619 EXPECT_TRUE(did_request_animate_
);
7620 EXPECT_TRUE(did_request_redraw_
);
7621 EXPECT_FALSE(did_request_commit_
);
7623 // The top controls should properly animate until finished, despite the scroll
7624 // offset being at the origin.
7625 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7626 while (did_request_animate_
) {
7627 did_request_redraw_
= false;
7628 did_request_animate_
= false;
7629 did_request_commit_
= false;
7632 host_impl_
->top_controls_manager()->ControlsTopOffset();
7634 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7635 host_impl_
->Animate(animation_time
);
7636 EXPECT_EQ(gfx::Vector2dF().ToString(),
7637 scroll_layer
->CurrentScrollOffset().ToString());
7640 host_impl_
->top_controls_manager()->ControlsTopOffset();
7642 // No commit is needed as the controls are animating the content offset,
7643 // not the scroll offset.
7644 EXPECT_FALSE(did_request_commit_
);
7646 if (new_offset
!= old_offset
)
7647 EXPECT_TRUE(did_request_redraw_
);
7649 if (new_offset
!= 0) {
7650 EXPECT_TRUE(host_impl_
->top_controls_manager()->animation());
7651 EXPECT_TRUE(did_request_animate_
);
7654 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7657 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAfterScroll
) {
7658 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7659 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7660 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7661 BOTH
, SHOWN
, false);
7662 float initial_scroll_offset
= 50;
7663 scroll_layer
->PushScrollOffsetFromMainThread(
7664 gfx::ScrollOffset(0, initial_scroll_offset
));
7667 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7668 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7669 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7670 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7671 scroll_layer
->CurrentScrollOffset().ToString());
7673 // Scroll the top controls partially.
7674 const float residue
= 15;
7675 float offset
= top_controls_height_
- residue
;
7677 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7678 EXPECT_FLOAT_EQ(-offset
,
7679 host_impl_
->top_controls_manager()->ControlsTopOffset());
7680 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7681 scroll_layer
->CurrentScrollOffset().ToString());
7683 did_request_redraw_
= false;
7684 did_request_animate_
= false;
7685 did_request_commit_
= false;
7687 // End the scroll while the controls are still offset from the limit.
7688 host_impl_
->ScrollEnd();
7689 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7690 EXPECT_TRUE(did_request_animate_
);
7691 EXPECT_TRUE(did_request_redraw_
);
7692 EXPECT_FALSE(did_request_commit_
);
7694 // Animate the top controls to the limit.
7695 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7696 while (did_request_animate_
) {
7697 did_request_redraw_
= false;
7698 did_request_animate_
= false;
7699 did_request_commit_
= false;
7702 host_impl_
->top_controls_manager()->ControlsTopOffset();
7704 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7705 host_impl_
->Animate(animation_time
);
7708 host_impl_
->top_controls_manager()->ControlsTopOffset();
7710 if (new_offset
!= old_offset
) {
7711 EXPECT_TRUE(did_request_redraw_
);
7712 EXPECT_TRUE(did_request_commit_
);
7715 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7716 EXPECT_EQ(-top_controls_height_
,
7717 host_impl_
->top_controls_manager()->ControlsTopOffset());
7720 TEST_F(LayerTreeHostImplWithTopControlsTest
,
7721 TopControlsAnimationAfterMainThreadFlingStopped
) {
7722 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7723 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7724 host_impl_
->top_controls_manager()->UpdateTopControlsState(BOTH
, SHOWN
,
7726 float initial_scroll_offset
= 50;
7727 scroll_layer
->PushScrollOffsetFromMainThread(
7728 gfx::ScrollOffset(0, initial_scroll_offset
));
7731 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7732 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7733 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7734 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7735 scroll_layer
->CurrentScrollOffset().ToString());
7737 // Scroll the top controls partially.
7738 const float residue
= 15;
7739 float offset
= top_controls_height_
- residue
;
7741 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7742 EXPECT_FLOAT_EQ(-offset
,
7743 host_impl_
->top_controls_manager()->ControlsTopOffset());
7744 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7745 scroll_layer
->CurrentScrollOffset().ToString());
7747 did_request_redraw_
= false;
7748 did_request_animate_
= false;
7749 did_request_commit_
= false;
7751 // End the fling while the controls are still offset from the limit.
7752 host_impl_
->MainThreadHasStoppedFlinging();
7753 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7754 EXPECT_TRUE(did_request_animate_
);
7755 EXPECT_TRUE(did_request_redraw_
);
7756 EXPECT_FALSE(did_request_commit_
);
7758 // Animate the top controls to the limit.
7759 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7760 while (did_request_animate_
) {
7761 did_request_redraw_
= false;
7762 did_request_animate_
= false;
7763 did_request_commit_
= false;
7765 float old_offset
= host_impl_
->top_controls_manager()->ControlsTopOffset();
7767 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7768 host_impl_
->Animate(animation_time
);
7770 float new_offset
= host_impl_
->top_controls_manager()->ControlsTopOffset();
7772 if (new_offset
!= old_offset
) {
7773 EXPECT_TRUE(did_request_redraw_
);
7774 EXPECT_TRUE(did_request_commit_
);
7777 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7778 EXPECT_EQ(-top_controls_height_
,
7779 host_impl_
->top_controls_manager()->ControlsTopOffset());
7782 TEST_F(LayerTreeHostImplWithTopControlsTest
,
7783 TopControlsScrollDeltaInOverScroll
) {
7784 // test varifies that the overscroll delta should not have accumulated in
7785 // the top controls if we do a hide and show without releasing finger.
7787 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7788 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7789 host_impl_
->top_controls_manager()->UpdateTopControlsState(BOTH
, SHOWN
,
7793 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7794 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7795 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7799 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7800 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7801 EXPECT_EQ(gfx::Vector2dF().ToString(),
7802 scroll_layer
->CurrentScrollOffset().ToString());
7805 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7806 EXPECT_EQ(gfx::Vector2dF(0, offset
).ToString(),
7807 scroll_layer
->CurrentScrollOffset().ToString());
7810 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7812 // Should have fully scrolled
7813 EXPECT_EQ(gfx::Vector2dF(0, scroll_layer
->MaxScrollOffset().y()).ToString(),
7814 scroll_layer
->CurrentScrollOffset().ToString());
7816 float overscrollamount
= 10;
7818 // Overscroll the content
7820 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, overscrollamount
))
7822 EXPECT_EQ(gfx::Vector2dF(0, 2 * offset
).ToString(),
7823 scroll_layer
->CurrentScrollOffset().ToString());
7824 EXPECT_EQ(gfx::Vector2dF(0, overscrollamount
).ToString(),
7825 host_impl_
->accumulated_root_overscroll().ToString());
7827 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -2 * offset
))
7829 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
7830 scroll_layer
->CurrentScrollOffset().ToString());
7831 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7834 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -offset
)).did_scroll
);
7835 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
7836 scroll_layer
->CurrentScrollOffset().ToString());
7838 // Top controls should be fully visible
7839 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7841 host_impl_
->ScrollEnd();
7844 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
7846 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
7847 const gfx::Size
& outer_viewport
,
7848 const gfx::Size
& inner_viewport
) {
7849 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
7850 const int kOuterViewportClipLayerId
= 6;
7851 const int kOuterViewportScrollLayerId
= 7;
7852 const int kInnerViewportScrollLayerId
= 2;
7853 const int kInnerViewportClipLayerId
= 4;
7854 const int kPageScaleLayerId
= 5;
7856 scoped_ptr
<LayerImpl
> inner_scroll
=
7857 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
7858 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
7859 inner_scroll
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
7861 scoped_ptr
<LayerImpl
> inner_clip
=
7862 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
7863 inner_clip
->SetBounds(inner_viewport
);
7865 scoped_ptr
<LayerImpl
> page_scale
=
7866 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
7868 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
7869 inner_scroll
->SetBounds(outer_viewport
);
7870 inner_scroll
->SetContentBounds(outer_viewport
);
7871 inner_scroll
->SetPosition(gfx::PointF());
7873 scoped_ptr
<LayerImpl
> outer_clip
=
7874 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
7875 outer_clip
->SetBounds(outer_viewport
);
7876 outer_clip
->SetIsContainerForFixedPositionLayers(true);
7878 scoped_ptr
<LayerImpl
> outer_scroll
=
7879 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
7880 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
7881 outer_scroll
->PushScrollOffsetFromMainThread(gfx::ScrollOffset());
7882 outer_scroll
->SetBounds(content_size
);
7883 outer_scroll
->SetContentBounds(content_size
);
7884 outer_scroll
->SetPosition(gfx::PointF());
7886 scoped_ptr
<LayerImpl
> contents
=
7887 LayerImpl::Create(layer_tree_impl
, 8);
7888 contents
->SetDrawsContent(true);
7889 contents
->SetBounds(content_size
);
7890 contents
->SetContentBounds(content_size
);
7891 contents
->SetPosition(gfx::PointF());
7893 outer_scroll
->AddChild(contents
.Pass());
7894 outer_clip
->AddChild(outer_scroll
.Pass());
7895 inner_scroll
->AddChild(outer_clip
.Pass());
7896 page_scale
->AddChild(inner_scroll
.Pass());
7897 inner_clip
->AddChild(page_scale
.Pass());
7899 inner_clip
->SetHasRenderSurface(true);
7900 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
7901 layer_tree_impl
->SetViewportLayersFromIds(
7902 Layer::INVALID_ID
, kPageScaleLayerId
, kInnerViewportScrollLayerId
,
7903 kOuterViewportScrollLayerId
);
7905 host_impl_
->active_tree()->DidBecomeActive();
7909 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
7910 gfx::Size content_size
= gfx::Size(100, 160);
7911 gfx::Size outer_viewport
= gfx::Size(50, 80);
7912 gfx::Size inner_viewport
= gfx::Size(25, 40);
7914 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7916 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7917 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7920 gfx::Vector2dF inner_expected
;
7921 gfx::Vector2dF outer_expected
;
7922 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7923 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
7925 // Make sure the fling goes to the outer viewport first
7926 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7927 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7928 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
7930 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
7931 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7932 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7934 host_impl_
->ScrollEnd();
7936 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7937 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
7939 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
7940 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7941 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7942 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
7944 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7945 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7947 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7948 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7950 host_impl_
->ScrollEnd();
7952 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7953 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
7957 TEST_F(LayerTreeHostImplVirtualViewportTest
,
7958 DiagonalScrollBubblesPerfectlyToInner
) {
7959 gfx::Size content_size
= gfx::Size(100, 160);
7960 gfx::Size outer_viewport
= gfx::Size(50, 80);
7961 gfx::Size inner_viewport
= gfx::Size(25, 40);
7963 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7965 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7966 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7969 gfx::Vector2dF inner_expected
;
7970 gfx::Vector2dF outer_expected
;
7971 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7972 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
7974 // Make sure the scroll goes to the outer viewport first.
7975 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
7976 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
7977 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
7979 // Scroll near the edge of the outer viewport.
7980 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
7981 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7982 outer_expected
+= scroll_delta
;
7984 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7985 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
7987 // Now diagonal scroll across the outer viewport boundary in a single event.
7988 // The entirety of the scroll should be consumed, as bubbling between inner
7989 // and outer viewport layers is perfect.
7990 host_impl_
->ScrollBy(gfx::Point(), gfx::ScaleVector2d(scroll_delta
, 2));
7991 outer_expected
+= scroll_delta
;
7992 inner_expected
+= scroll_delta
;
7993 host_impl_
->ScrollEnd();
7995 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->CurrentScrollOffset());
7996 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->CurrentScrollOffset());
8000 TEST_F(LayerTreeHostImplVirtualViewportTest
,
8001 TouchFlingCanLockToViewportLayerAfterBubbling
) {
8002 gfx::Size content_size
= gfx::Size(100, 160);
8003 gfx::Size outer_viewport
= gfx::Size(50, 80);
8004 gfx::Size inner_viewport
= gfx::Size(25, 40);
8006 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
8008 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
8009 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
8011 scoped_ptr
<LayerImpl
> child
=
8012 CreateScrollableLayer(10, outer_viewport
, outer_scroll
);
8013 LayerImpl
* child_scroll
= child
.get();
8014 outer_scroll
->children()[0]->AddChild(child
.Pass());
8018 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
8020 gfx::Vector2d
scroll_delta(0, inner_viewport
.height());
8021 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
8022 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
));
8023 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
8025 // The child should have scrolled up to its limit.
8026 scroll_info
= host_impl_
->ProcessScrollDeltas();
8027 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
8028 ExpectContains(*scroll_info
, child_scroll
->id(), scroll_delta
);
8029 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_scroll
);
8031 // The first |ScrollBy| after the fling should re-lock the scrolling
8032 // layer to the first layer that scrolled, the inner viewport scroll layer.
8033 EXPECT_EQ(InputHandler::SCROLL_STARTED
, host_impl_
->FlingScrollBegin());
8034 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
8035 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
8037 // The inner viewport should have scrolled up to its limit.
8038 scroll_info
= host_impl_
->ProcessScrollDeltas();
8039 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
8040 ExpectContains(*scroll_info
, child_scroll
->id(), scroll_delta
);
8041 ExpectContains(*scroll_info
, inner_scroll
->id(), scroll_delta
);
8043 // As the locked layer is at its limit, no further scrolling can occur.
8044 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
8045 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
8046 host_impl_
->ScrollEnd();
8050 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
8052 void SetUp() override
{
8053 LayerTreeSettings settings
= DefaultSettings();
8054 settings
.max_memory_for_prepaint_percentage
= 50;
8055 CreateHostImpl(settings
, CreateOutputSurface());
8059 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
8060 // Set up a memory policy and percentages which could cause
8061 // 32-bit integer overflows.
8062 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
8064 // Verify implicit limits are calculated correctly with no overflows
8065 host_impl_
->SetMemoryPolicy(mem_policy
);
8066 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
8067 300u * 1024u * 1024u);
8068 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
8069 150u * 1024u * 1024u);
8072 TEST_F(LayerTreeHostImplTest
, ExternalTransformReflectedInNextDraw
) {
8073 const gfx::Size
layer_size(100, 100);
8074 gfx::Transform external_transform
;
8075 const gfx::Rect
external_viewport(layer_size
);
8076 const gfx::Rect
external_clip(layer_size
);
8077 const bool resourceless_software_draw
= false;
8078 LayerImpl
* layer
= SetupScrollAndContentsLayers(layer_size
);
8080 host_impl_
->SetExternalDrawConstraints(external_transform
,
8085 resourceless_software_draw
);
8087 EXPECT_TRANSFORMATION_MATRIX_EQ(
8088 external_transform
, layer
->draw_properties().target_space_transform
);
8090 external_transform
.Translate(20, 20);
8091 host_impl_
->SetExternalDrawConstraints(external_transform
,
8096 resourceless_software_draw
);
8098 EXPECT_TRANSFORMATION_MATRIX_EQ(
8099 external_transform
, layer
->draw_properties().target_space_transform
);
8102 TEST_F(LayerTreeHostImplTest
, ScrollAnimated
) {
8103 SetupScrollAndContentsLayers(gfx::Size(100, 200));
8106 base::TimeTicks start_time
=
8107 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
8109 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
8110 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
8112 LayerImpl
* scrolling_layer
= host_impl_
->CurrentlyScrollingLayer();
8114 host_impl_
->Animate(start_time
);
8115 host_impl_
->UpdateAnimationState(true);
8117 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer
->CurrentScrollOffset());
8119 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(50));
8120 host_impl_
->UpdateAnimationState(true);
8122 float y
= scrolling_layer
->CurrentScrollOffset().y();
8123 EXPECT_TRUE(y
> 1 && y
< 49);
8126 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
8127 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
8129 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(200));
8130 host_impl_
->UpdateAnimationState(true);
8132 y
= scrolling_layer
->CurrentScrollOffset().y();
8133 EXPECT_TRUE(y
> 50 && y
< 100);
8134 EXPECT_EQ(scrolling_layer
, host_impl_
->CurrentlyScrollingLayer());
8136 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(250));
8137 host_impl_
->UpdateAnimationState(true);
8139 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
8140 scrolling_layer
->CurrentScrollOffset());
8141 EXPECT_EQ(NULL
, host_impl_
->CurrentlyScrollingLayer());
8144 TEST_F(LayerTreeHostImplTest
, GetPictureLayerImplPairs
) {
8145 host_impl_
->CreatePendingTree();
8147 scoped_ptr
<PictureLayerImpl
> layer
=
8148 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 10);
8149 layer
->SetBounds(gfx::Size(10, 10));
8150 scoped_ptr
<FakePictureLayerImpl
> nondraw_layer
=
8151 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 12);
8152 nondraw_layer
->SetBounds(gfx::Size(10, 10));
8154 scoped_refptr
<RasterSource
> pile(FakePicturePileImpl::CreateEmptyPile(
8155 gfx::Size(10, 10), gfx::Size(10, 10)));
8156 Region empty_invalidation
;
8157 const PictureLayerTilingSet
* null_tiling_set
= nullptr;
8158 layer
->UpdateRasterSource(pile
, &empty_invalidation
, null_tiling_set
);
8159 nondraw_layer
->UpdateRasterSource(pile
, &empty_invalidation
, null_tiling_set
);
8161 layer
->AddChild(nondraw_layer
.Pass());
8162 host_impl_
->pending_tree()->SetRootLayer(layer
.Pass());
8164 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
8165 LayerImpl
* pending_layer
= pending_tree
->root_layer();
8166 FakePictureLayerImpl
* pending_nondraw_layer
=
8167 static_cast<FakePictureLayerImpl
*>(pending_layer
->children()[0]);
8169 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8171 std::vector
<PictureLayerImpl::Pair
> layer_pairs
;
8172 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8173 EXPECT_EQ(1u, layer_pairs
.size());
8174 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8175 EXPECT_EQ(nullptr, layer_pairs
[0].active
);
8177 host_impl_
->ActivateSyncTree();
8179 LayerTreeImpl
* active_tree
= host_impl_
->active_tree();
8180 LayerImpl
* active_layer
= active_tree
->root_layer();
8181 FakePictureLayerImpl
* active_nondraw_layer
=
8182 static_cast<FakePictureLayerImpl
*>(active_layer
->children()[0]);
8183 EXPECT_NE(active_tree
, pending_tree
);
8184 EXPECT_NE(active_layer
, pending_layer
);
8185 EXPECT_NE(active_nondraw_layer
, pending_nondraw_layer
);
8186 EXPECT_NE(nullptr, active_tree
);
8187 EXPECT_NE(nullptr, active_layer
);
8188 EXPECT_NE(nullptr, active_nondraw_layer
);
8190 active_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8192 host_impl_
->CreatePendingTree();
8194 layer_pairs
.clear();
8195 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8196 EXPECT_EQ(1u, layer_pairs
.size());
8197 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8198 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8200 // Activate, the active layer has no twin now.
8201 host_impl_
->ActivateSyncTree();
8203 layer_pairs
.clear();
8204 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8205 EXPECT_EQ(1u, layer_pairs
.size());
8206 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8207 EXPECT_EQ(nullptr, layer_pairs
[0].pending
);
8209 // Create another layer in the pending tree that's not in the active tree. We
8210 // should get two pairs.
8211 host_impl_
->CreatePendingTree();
8212 host_impl_
->pending_tree()->root_layer()->AddChild(
8213 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 11));
8215 LayerImpl
* new_pending_layer
= pending_tree
->root_layer()->children()[1];
8217 layer_pairs
.clear();
8218 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8219 EXPECT_EQ(2u, layer_pairs
.size());
8220 // The pair ordering is flaky, so make it consistent.
8221 if (layer_pairs
[0].active
!= active_layer
)
8222 std::swap(layer_pairs
[0], layer_pairs
[1]);
8223 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8224 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8225 EXPECT_EQ(new_pending_layer
, layer_pairs
[1].pending
);
8226 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
8228 host_impl_
->pending_tree()->root_layer()->RemoveChild(new_pending_layer
);
8230 // Have the pending layer be part of the RSLL now. It should appear in the
8231 // list without an active twin.
8232 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(true);
8234 layer_pairs
.clear();
8235 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8236 EXPECT_EQ(2u, layer_pairs
.size());
8237 // The pair ordering is flaky, so make it consistent.
8238 if (layer_pairs
[0].active
!= active_layer
)
8239 std::swap(layer_pairs
[0], layer_pairs
[1]);
8240 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8241 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8242 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[1].pending
);
8243 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
8245 // Have the active layer be part of the RSLL now instead. It should appear in
8246 // the list without a pending twin.
8247 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8248 active_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(true);
8250 layer_pairs
.clear();
8251 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
8252 EXPECT_EQ(2u, layer_pairs
.size());
8253 // The pair ordering is flaky, so make it consistent.
8254 if (layer_pairs
[0].active
!= active_layer
)
8255 std::swap(layer_pairs
[0], layer_pairs
[1]);
8256 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8257 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8258 EXPECT_EQ(nullptr, layer_pairs
[1].pending
);
8259 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[1].active
);
8262 TEST_F(LayerTreeHostImplTest
, GetPictureLayerImplPairsWithNonRSLLMembers
) {
8263 host_impl_
->CreatePendingTree();
8265 scoped_ptr
<PictureLayerImpl
> layer
=
8266 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 10);
8267 layer
->SetBounds(gfx::Size(10, 10));
8268 scoped_ptr
<FakePictureLayerImpl
> nondraw_layer
=
8269 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 12);
8270 nondraw_layer
->SetBounds(gfx::Size(10, 10));
8272 scoped_refptr
<RasterSource
> pile(FakePicturePileImpl::CreateEmptyPile(
8273 gfx::Size(10, 10), gfx::Size(10, 10)));
8274 Region empty_invalidation
;
8275 const PictureLayerTilingSet
* null_tiling_set
= nullptr;
8276 layer
->UpdateRasterSource(pile
, &empty_invalidation
, null_tiling_set
);
8277 nondraw_layer
->UpdateRasterSource(pile
, &empty_invalidation
, null_tiling_set
);
8279 layer
->AddChild(nondraw_layer
.Pass());
8280 host_impl_
->pending_tree()->SetRootLayer(layer
.Pass());
8282 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
8283 LayerImpl
* pending_layer
= pending_tree
->root_layer();
8284 FakePictureLayerImpl
* pending_nondraw_layer
=
8285 static_cast<FakePictureLayerImpl
*>(pending_layer
->children()[0]);
8287 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8289 std::vector
<PictureLayerImpl::Pair
> layer_pairs
;
8290 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8291 EXPECT_EQ(2u, layer_pairs
.size());
8292 // The pair ordering is flaky, so make it consistent.
8293 if (layer_pairs
[0].pending
!= pending_layer
)
8294 std::swap(layer_pairs
[0], layer_pairs
[1]);
8295 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8296 EXPECT_EQ(nullptr, layer_pairs
[0].active
);
8297 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[1].pending
);
8298 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
8300 host_impl_
->ActivateSyncTree();
8302 LayerTreeImpl
* active_tree
= host_impl_
->active_tree();
8303 LayerImpl
* active_layer
= active_tree
->root_layer();
8304 FakePictureLayerImpl
* active_nondraw_layer
=
8305 static_cast<FakePictureLayerImpl
*>(active_layer
->children()[0]);
8306 EXPECT_NE(active_tree
, pending_tree
);
8307 EXPECT_NE(active_layer
, pending_layer
);
8308 EXPECT_NE(active_nondraw_layer
, pending_nondraw_layer
);
8309 EXPECT_NE(nullptr, active_tree
);
8310 EXPECT_NE(nullptr, active_layer
);
8311 EXPECT_NE(nullptr, active_nondraw_layer
);
8313 active_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8315 host_impl_
->CreatePendingTree();
8317 layer_pairs
.clear();
8318 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8319 EXPECT_EQ(2u, layer_pairs
.size());
8320 // The pair ordering is flaky, so make it consistent.
8321 if (layer_pairs
[0].active
!= active_layer
)
8322 std::swap(layer_pairs
[0], layer_pairs
[1]);
8323 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8324 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8325 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[1].pending
);
8326 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[1].active
);
8328 // Activate, the active layer has no twin now.
8329 host_impl_
->ActivateSyncTree();
8331 layer_pairs
.clear();
8332 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8333 EXPECT_EQ(2u, layer_pairs
.size());
8334 // The pair ordering is flaky, so make it consistent.
8335 if (layer_pairs
[0].active
!= active_layer
)
8336 std::swap(layer_pairs
[0], layer_pairs
[1]);
8337 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8338 EXPECT_EQ(nullptr, layer_pairs
[0].pending
);
8339 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[1].active
);
8340 EXPECT_EQ(nullptr, layer_pairs
[1].pending
);
8342 // Create another layer in the pending tree that's not in the active tree. We
8343 // should get three pairs including the nondraw layers.
8344 host_impl_
->CreatePendingTree();
8345 host_impl_
->pending_tree()->root_layer()->AddChild(
8346 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 11));
8348 LayerImpl
* new_pending_layer
= pending_tree
->root_layer()->children()[1];
8350 layer_pairs
.clear();
8351 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8352 EXPECT_EQ(3u, layer_pairs
.size());
8353 // The pair ordering is flaky, so make it consistent.
8354 if (layer_pairs
[0].active
!= active_layer
)
8355 std::swap(layer_pairs
[0], layer_pairs
[1]);
8356 if (layer_pairs
[0].active
!= active_layer
)
8357 std::swap(layer_pairs
[0], layer_pairs
[2]);
8358 if (layer_pairs
[1].pending
!= new_pending_layer
)
8359 std::swap(layer_pairs
[1], layer_pairs
[2]);
8360 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8361 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8362 EXPECT_EQ(new_pending_layer
, layer_pairs
[1].pending
);
8363 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
8364 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[2].active
);
8365 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[2].pending
);
8367 host_impl_
->pending_tree()->root_layer()->RemoveChild(new_pending_layer
);
8369 // Have the pending layer be part of the RSLL now. It should appear in the
8370 // list, as should its active twin since we don't request only layers with
8371 // valid draw properties.
8372 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(true);
8374 layer_pairs
.clear();
8375 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8376 EXPECT_EQ(2u, layer_pairs
.size());
8377 // The pair ordering is flaky, so make it consistent.
8378 if (layer_pairs
[0].active
!= active_layer
)
8379 std::swap(layer_pairs
[0], layer_pairs
[1]);
8380 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8381 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8382 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[1].pending
);
8383 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[1].active
);
8385 // Have the active layer be part of the RSLL now instead. It should appear in
8386 // the list, as should its pending twin since we don't request only layers
8387 // with valid draw properties.
8388 pending_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(false);
8389 active_nondraw_layer
->SetIsDrawnRenderSurfaceLayerListMember(true);
8391 layer_pairs
.clear();
8392 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, false);
8393 EXPECT_EQ(2u, layer_pairs
.size());
8394 // The pair ordering is flaky, so make it consistent.
8395 if (layer_pairs
[0].active
!= active_layer
)
8396 std::swap(layer_pairs
[0], layer_pairs
[1]);
8397 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
8398 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
8399 EXPECT_EQ(active_nondraw_layer
, layer_pairs
[1].active
);
8400 EXPECT_EQ(pending_nondraw_layer
, layer_pairs
[1].pending
);
8403 TEST_F(LayerTreeHostImplTest
, DidBecomeActive
) {
8404 host_impl_
->CreatePendingTree();
8405 host_impl_
->ActivateSyncTree();
8406 host_impl_
->CreatePendingTree();
8408 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
8410 scoped_ptr
<FakePictureLayerImpl
> pending_layer
=
8411 FakePictureLayerImpl::Create(pending_tree
, 10);
8412 FakePictureLayerImpl
* raw_pending_layer
= pending_layer
.get();
8413 pending_tree
->SetRootLayer(pending_layer
.Pass());
8414 ASSERT_EQ(raw_pending_layer
, pending_tree
->root_layer());
8416 EXPECT_EQ(0u, raw_pending_layer
->did_become_active_call_count());
8417 pending_tree
->DidBecomeActive();
8418 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
8420 scoped_ptr
<FakePictureLayerImpl
> mask_layer
=
8421 FakePictureLayerImpl::Create(pending_tree
, 11);
8422 FakePictureLayerImpl
* raw_mask_layer
= mask_layer
.get();
8423 raw_pending_layer
->SetMaskLayer(mask_layer
.Pass());
8424 ASSERT_EQ(raw_mask_layer
, raw_pending_layer
->mask_layer());
8426 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
8427 EXPECT_EQ(0u, raw_mask_layer
->did_become_active_call_count());
8428 pending_tree
->DidBecomeActive();
8429 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
8430 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
8432 scoped_ptr
<FakePictureLayerImpl
> replica_layer
=
8433 FakePictureLayerImpl::Create(pending_tree
, 12);
8434 scoped_ptr
<FakePictureLayerImpl
> replica_mask_layer
=
8435 FakePictureLayerImpl::Create(pending_tree
, 13);
8436 FakePictureLayerImpl
* raw_replica_mask_layer
= replica_mask_layer
.get();
8437 replica_layer
->SetMaskLayer(replica_mask_layer
.Pass());
8438 raw_pending_layer
->SetReplicaLayer(replica_layer
.Pass());
8439 ASSERT_EQ(raw_replica_mask_layer
,
8440 raw_pending_layer
->replica_layer()->mask_layer());
8442 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
8443 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
8444 EXPECT_EQ(0u, raw_replica_mask_layer
->did_become_active_call_count());
8445 pending_tree
->DidBecomeActive();
8446 EXPECT_EQ(3u, raw_pending_layer
->did_become_active_call_count());
8447 EXPECT_EQ(2u, raw_mask_layer
->did_become_active_call_count());
8448 EXPECT_EQ(1u, raw_replica_mask_layer
->did_become_active_call_count());
8451 TEST_F(LayerTreeHostImplTest
, WheelScrollWithPageScaleFactorOnInnerLayer
) {
8452 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
8453 host_impl_
->SetViewportSize(gfx::Size(50, 50));
8456 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
8458 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
8459 float page_scale_factor
= 1.f
;
8461 // The scroll deltas should have the page scale factor applied.
8463 host_impl_
->active_tree()->PushPageScaleFromMainThread(
8464 page_scale_factor
, min_page_scale
, max_page_scale
);
8465 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
8466 scroll_layer
->SetScrollDelta(gfx::Vector2d());
8468 float page_scale_delta
= 2.f
;
8469 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::GESTURE
);
8470 host_impl_
->PinchGestureBegin();
8471 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
8472 host_impl_
->PinchGestureEnd();
8473 host_impl_
->ScrollEnd();
8475 gfx::Vector2dF
scroll_delta(0, 5);
8476 EXPECT_EQ(InputHandler::SCROLL_STARTED
,
8477 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::WHEEL
));
8478 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->CurrentScrollOffset());
8480 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
8481 host_impl_
->ScrollEnd();
8482 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 2.5),
8483 scroll_layer
->CurrentScrollOffset());
8487 class LayerTreeHostImplCountingLostSurfaces
: public LayerTreeHostImplTest
{
8489 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
8490 void DidLoseOutputSurfaceOnImplThread() override
{ num_lost_surfaces_
++; }
8493 int num_lost_surfaces_
;
8496 TEST_F(LayerTreeHostImplCountingLostSurfaces
, TwiceLostSurface
) {
8497 // Really we just need at least one client notification each time
8498 // we go from having a valid output surface to not having a valid output
8500 EXPECT_EQ(0, num_lost_surfaces_
);
8501 host_impl_
->DidLoseOutputSurface();
8502 EXPECT_EQ(1, num_lost_surfaces_
);
8503 host_impl_
->DidLoseOutputSurface();
8504 EXPECT_LE(1, num_lost_surfaces_
);