1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host_impl.h"
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/containers/scoped_ptr_hash_map.h"
14 #include "cc/animation/scrollbar_animation_controller_thinning.h"
15 #include "cc/base/latency_info_swap_promise.h"
16 #include "cc/base/math_util.h"
17 #include "cc/input/page_scale_animation.h"
18 #include "cc/input/top_controls_manager.h"
19 #include "cc/layers/append_quads_data.h"
20 #include "cc/layers/delegated_renderer_layer_impl.h"
21 #include "cc/layers/heads_up_display_layer_impl.h"
22 #include "cc/layers/io_surface_layer_impl.h"
23 #include "cc/layers/layer_impl.h"
24 #include "cc/layers/painted_scrollbar_layer_impl.h"
25 #include "cc/layers/render_surface_impl.h"
26 #include "cc/layers/solid_color_layer_impl.h"
27 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
28 #include "cc/layers/texture_layer_impl.h"
29 #include "cc/layers/tiled_layer_impl.h"
30 #include "cc/layers/video_layer_impl.h"
31 #include "cc/output/begin_frame_args.h"
32 #include "cc/output/compositor_frame_ack.h"
33 #include "cc/output/compositor_frame_metadata.h"
34 #include "cc/output/copy_output_request.h"
35 #include "cc/output/copy_output_result.h"
36 #include "cc/output/gl_renderer.h"
37 #include "cc/quads/render_pass_draw_quad.h"
38 #include "cc/quads/solid_color_draw_quad.h"
39 #include "cc/quads/texture_draw_quad.h"
40 #include "cc/quads/tile_draw_quad.h"
41 #include "cc/resources/layer_tiling_data.h"
42 #include "cc/test/animation_test_common.h"
43 #include "cc/test/begin_frame_args_test.h"
44 #include "cc/test/fake_layer_tree_host_impl.h"
45 #include "cc/test/fake_output_surface.h"
46 #include "cc/test/fake_output_surface_client.h"
47 #include "cc/test/fake_picture_layer_impl.h"
48 #include "cc/test/fake_picture_pile_impl.h"
49 #include "cc/test/fake_proxy.h"
50 #include "cc/test/fake_video_frame_provider.h"
51 #include "cc/test/geometry_test_utils.h"
52 #include "cc/test/layer_test_common.h"
53 #include "cc/test/render_pass_test_common.h"
54 #include "cc/test/test_gpu_memory_buffer_manager.h"
55 #include "cc/test/test_shared_bitmap_manager.h"
56 #include "cc/test/test_web_graphics_context_3d.h"
57 #include "cc/trees/layer_tree_impl.h"
58 #include "cc/trees/single_thread_proxy.h"
59 #include "media/base/media.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "third_party/skia/include/core/SkMallocPixelRef.h"
63 #include "ui/gfx/frame_time.h"
64 #include "ui/gfx/geometry/rect_conversions.h"
65 #include "ui/gfx/geometry/size_conversions.h"
66 #include "ui/gfx/geometry/vector2d_conversions.h"
68 using ::testing::Mock
;
69 using ::testing::Return
;
70 using ::testing::AnyNumber
;
71 using ::testing::AtLeast
;
73 using media::VideoFrame
;
78 class LayerTreeHostImplTest
: public testing::Test
,
79 public LayerTreeHostImplClient
{
81 LayerTreeHostImplTest()
82 : proxy_(base::MessageLoopProxy::current(),
83 base::MessageLoopProxy::current()),
84 always_impl_thread_(&proxy_
),
85 always_main_thread_blocked_(&proxy_
),
86 shared_bitmap_manager_(new TestSharedBitmapManager
),
87 gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager
),
88 on_can_draw_state_changed_called_(false),
89 did_notify_ready_to_activate_(false),
90 did_request_commit_(false),
91 did_request_redraw_(false),
92 did_request_animate_(false),
93 did_request_prepare_tiles_(false),
94 reduce_memory_result_(true),
95 current_limit_bytes_(0),
96 current_priority_cutoff_value_(0) {
97 media::InitializeMediaLibraryForTesting();
100 LayerTreeSettings
DefaultSettings() {
101 LayerTreeSettings settings
;
102 settings
.minimum_occlusion_tracking_size
= gfx::Size();
103 settings
.impl_side_painting
= true;
104 settings
.renderer_settings
.texture_id_allocation_chunk_size
= 1;
105 settings
.report_overscroll_only_for_scrollable_axes
= true;
106 settings
.use_pinch_virtual_viewport
= true;
110 void SetUp() override
{
111 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
114 void TearDown() override
{}
116 void UpdateRendererCapabilitiesOnImplThread() override
{}
117 void DidLoseOutputSurfaceOnImplThread() override
{}
118 void CommitVSyncParameters(base::TimeTicks timebase
,
119 base::TimeDelta interval
) override
{}
120 void SetEstimatedParentDrawTime(base::TimeDelta draw_time
) override
{}
121 void SetMaxSwapsPendingOnImplThread(int max
) override
{}
122 void DidSwapBuffersOnImplThread() override
{}
123 void DidSwapBuffersCompleteOnImplThread() override
{}
124 void OnCanDrawStateChanged(bool can_draw
) override
{
125 on_can_draw_state_changed_called_
= true;
127 void NotifyReadyToActivate() override
{
128 did_notify_ready_to_activate_
= true;
129 host_impl_
->ActivateSyncTree();
131 void NotifyReadyToDraw() override
{}
132 void SetNeedsRedrawOnImplThread() override
{ did_request_redraw_
= true; }
133 void SetNeedsRedrawRectOnImplThread(const gfx::Rect
& damage_rect
) override
{
134 did_request_redraw_
= true;
136 void SetNeedsAnimateOnImplThread() override
{ did_request_animate_
= true; }
137 void SetNeedsPrepareTilesOnImplThread() override
{
138 did_request_prepare_tiles_
= true;
140 void SetNeedsCommitOnImplThread() override
{ did_request_commit_
= true; }
141 void PostAnimationEventsToMainThreadOnImplThread(
142 scoped_ptr
<AnimationEventsVector
> events
) override
{}
143 bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes
,
144 int priority_cutoff
) override
{
145 current_limit_bytes_
= limit_bytes
;
146 current_priority_cutoff_value_
= priority_cutoff
;
147 return reduce_memory_result_
;
149 bool IsInsideDraw() override
{ return false; }
150 void RenewTreePriority() override
{}
151 void PostDelayedScrollbarFadeOnImplThread(const base::Closure
& start_fade
,
152 base::TimeDelta delay
) override
{
153 scrollbar_fade_start_
= start_fade
;
154 requested_scrollbar_animation_delay_
= delay
;
156 void DidActivateSyncTree() override
{}
157 void DidPrepareTiles() override
{}
159 void set_reduce_memory_result(bool reduce_memory_result
) {
160 reduce_memory_result_
= reduce_memory_result
;
163 virtual bool CreateHostImpl(const LayerTreeSettings
& settings
,
164 scoped_ptr
<OutputSurface
> output_surface
) {
165 host_impl_
= LayerTreeHostImpl::Create(settings
,
168 &stats_instrumentation_
,
169 shared_bitmap_manager_
.get(),
170 gpu_memory_buffer_manager_
.get(),
172 bool init
= host_impl_
->InitializeRenderer(output_surface
.Pass());
173 host_impl_
->SetViewportSize(gfx::Size(10, 10));
177 void SetupRootLayerImpl(scoped_ptr
<LayerImpl
> root
) {
178 root
->SetPosition(gfx::PointF());
179 root
->SetBounds(gfx::Size(10, 10));
180 root
->SetContentBounds(gfx::Size(10, 10));
181 root
->SetDrawsContent(true);
182 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
183 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
186 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
187 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
188 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
189 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
192 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
194 const gfx::Vector2d
& scroll_delta
) {
195 int times_encountered
= 0;
197 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
198 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
200 EXPECT_VECTOR_EQ(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
);
204 ASSERT_EQ(1, times_encountered
);
207 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
208 int times_encountered
= 0;
210 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
211 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
216 ASSERT_EQ(0, times_encountered
);
219 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
220 const gfx::Size
& content_size
) {
221 const int kInnerViewportScrollLayerId
= 2;
222 const int kInnerViewportClipLayerId
= 4;
223 const int kPageScaleLayerId
= 5;
224 scoped_ptr
<LayerImpl
> root
=
225 LayerImpl::Create(layer_tree_impl
, 1);
226 root
->SetBounds(content_size
);
227 root
->SetContentBounds(content_size
);
228 root
->SetPosition(gfx::PointF());
230 scoped_ptr
<LayerImpl
> scroll
=
231 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
232 LayerImpl
* scroll_layer
= scroll
.get();
233 scroll
->SetIsContainerForFixedPositionLayers(true);
234 scroll
->SetScrollOffset(gfx::ScrollOffset());
236 scoped_ptr
<LayerImpl
> clip
=
237 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
239 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
241 scoped_ptr
<LayerImpl
> page_scale
=
242 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
244 scroll
->SetScrollClipLayer(clip
->id());
245 scroll
->SetBounds(content_size
);
246 scroll
->SetContentBounds(content_size
);
247 scroll
->SetPosition(gfx::PointF());
248 scroll
->SetIsContainerForFixedPositionLayers(true);
250 scoped_ptr
<LayerImpl
> contents
=
251 LayerImpl::Create(layer_tree_impl
, 3);
252 contents
->SetDrawsContent(true);
253 contents
->SetBounds(content_size
);
254 contents
->SetContentBounds(content_size
);
255 contents
->SetPosition(gfx::PointF());
257 scroll
->AddChild(contents
.Pass());
258 page_scale
->AddChild(scroll
.Pass());
259 clip
->AddChild(page_scale
.Pass());
260 root
->AddChild(clip
.Pass());
262 layer_tree_impl
->SetRootLayer(root
.Pass());
263 layer_tree_impl
->SetViewportLayersFromIds(
264 Layer::INVALID_ID
, kPageScaleLayerId
, kInnerViewportScrollLayerId
,
270 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
271 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
272 host_impl_
->active_tree(), content_size
);
273 host_impl_
->active_tree()->DidBecomeActive();
277 // TODO(wjmaclean) Add clip-layer pointer to parameters.
278 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
279 const gfx::Size
& size
,
280 LayerImpl
* clip_layer
) {
282 DCHECK(id
!= clip_layer
->id());
283 scoped_ptr
<LayerImpl
> layer
=
284 LayerImpl::Create(host_impl_
->active_tree(), id
);
285 layer
->SetScrollClipLayer(clip_layer
->id());
286 layer
->SetDrawsContent(true);
287 layer
->SetBounds(size
);
288 layer
->SetContentBounds(size
);
289 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
294 LayerTreeHostImpl::FrameData frame
;
295 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
296 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
297 host_impl_
->DidDrawAllLayers(frame
);
300 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
301 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
302 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
303 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
304 float device_scale_factor
);
306 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
307 // Note: It is not possible to disable the renderer once it has been set,
308 // so we do not need to test that disabling the renderer notifies us
309 // that can_draw changed.
310 EXPECT_FALSE(host_impl_
->CanDraw());
311 on_can_draw_state_changed_called_
= false;
313 // Set up the root layer, which allows us to draw.
314 SetupScrollAndContentsLayers(gfx::Size(100, 100));
315 EXPECT_TRUE(host_impl_
->CanDraw());
316 EXPECT_TRUE(on_can_draw_state_changed_called_
);
317 on_can_draw_state_changed_called_
= false;
319 // Toggle the root layer to make sure it toggles can_draw
320 host_impl_
->active_tree()->SetRootLayer(nullptr);
321 EXPECT_FALSE(host_impl_
->CanDraw());
322 EXPECT_TRUE(on_can_draw_state_changed_called_
);
323 on_can_draw_state_changed_called_
= false;
325 SetupScrollAndContentsLayers(gfx::Size(100, 100));
326 EXPECT_TRUE(host_impl_
->CanDraw());
327 EXPECT_TRUE(on_can_draw_state_changed_called_
);
328 on_can_draw_state_changed_called_
= false;
330 // Toggle the device viewport size to make sure it toggles can_draw.
331 host_impl_
->SetViewportSize(gfx::Size());
333 EXPECT_TRUE(host_impl_
->CanDraw());
335 EXPECT_FALSE(host_impl_
->CanDraw());
337 EXPECT_TRUE(on_can_draw_state_changed_called_
);
338 on_can_draw_state_changed_called_
= false;
340 host_impl_
->SetViewportSize(gfx::Size(100, 100));
341 EXPECT_TRUE(host_impl_
->CanDraw());
342 EXPECT_TRUE(on_can_draw_state_changed_called_
);
343 on_can_draw_state_changed_called_
= false;
345 // Toggle contents textures purged without causing any evictions,
346 // and make sure that it does not change can_draw.
347 set_reduce_memory_result(false);
348 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
349 host_impl_
->memory_allocation_limit_bytes() - 1));
350 EXPECT_TRUE(host_impl_
->CanDraw());
351 EXPECT_FALSE(on_can_draw_state_changed_called_
);
352 on_can_draw_state_changed_called_
= false;
354 // Toggle contents textures purged to make sure it toggles can_draw.
355 set_reduce_memory_result(true);
356 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
357 host_impl_
->memory_allocation_limit_bytes() - 1));
359 EXPECT_TRUE(host_impl_
->CanDraw());
361 EXPECT_FALSE(host_impl_
->CanDraw());
363 EXPECT_TRUE(on_can_draw_state_changed_called_
);
364 on_can_draw_state_changed_called_
= false;
366 host_impl_
->active_tree()->ResetContentsTexturesPurged();
367 EXPECT_TRUE(host_impl_
->CanDraw());
368 EXPECT_TRUE(on_can_draw_state_changed_called_
);
369 on_can_draw_state_changed_called_
= false;
372 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
375 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
376 return FakeOutputSurface::Create3d();
379 void DrawOneFrame() {
380 LayerTreeHostImpl::FrameData frame_data
;
381 host_impl_
->PrepareToDraw(&frame_data
);
382 host_impl_
->DidDrawAllLayers(frame_data
);
386 DebugScopedSetImplThread always_impl_thread_
;
387 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
389 scoped_ptr
<TestSharedBitmapManager
> shared_bitmap_manager_
;
390 scoped_ptr
<TestGpuMemoryBufferManager
> gpu_memory_buffer_manager_
;
391 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
392 FakeRenderingStatsInstrumentation stats_instrumentation_
;
393 bool on_can_draw_state_changed_called_
;
394 bool did_notify_ready_to_activate_
;
395 bool did_request_commit_
;
396 bool did_request_redraw_
;
397 bool did_request_animate_
;
398 bool did_request_prepare_tiles_
;
399 bool reduce_memory_result_
;
400 base::Closure scrollbar_fade_start_
;
401 base::TimeDelta requested_scrollbar_animation_delay_
;
402 size_t current_limit_bytes_
;
403 int current_priority_cutoff_value_
;
406 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
407 bool always_draw
= false;
408 CheckNotifyCalledIfCanDrawChanged(always_draw
);
411 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
412 CreateHostImpl(DefaultSettings(),
413 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
415 bool always_draw
= true;
416 CheckNotifyCalledIfCanDrawChanged(always_draw
);
419 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
420 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
422 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
423 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
426 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
428 scoped_ptr
<LayerImpl
> root
=
429 LayerImpl::Create(host_impl_
->active_tree(), 1);
430 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
431 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
432 root
->children()[1]->AddChild(
433 LayerImpl::Create(host_impl_
->active_tree(), 4));
434 root
->children()[1]->AddChild(
435 LayerImpl::Create(host_impl_
->active_tree(), 5));
436 root
->children()[1]->children()[0]->AddChild(
437 LayerImpl::Create(host_impl_
->active_tree(), 6));
438 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
440 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
442 ExpectClearedScrollDeltasRecursive(root
);
444 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
446 scroll_info
= host_impl_
->ProcessScrollDeltas();
447 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
448 ExpectClearedScrollDeltasRecursive(root
);
450 scroll_info
= host_impl_
->ProcessScrollDeltas();
451 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
452 ExpectClearedScrollDeltasRecursive(root
);
455 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
456 gfx::ScrollOffset
scroll_offset(20, 30);
457 gfx::Vector2d
scroll_delta(11, -15);
459 scoped_ptr
<LayerImpl
> root_clip
=
460 LayerImpl::Create(host_impl_
->active_tree(), 2);
461 scoped_ptr
<LayerImpl
> root
=
462 LayerImpl::Create(host_impl_
->active_tree(), 1);
463 root_clip
->SetBounds(gfx::Size(10, 10));
464 LayerImpl
* root_layer
= root
.get();
465 root_clip
->AddChild(root
.Pass());
466 root_layer
->SetBounds(gfx::Size(110, 110));
467 root_layer
->SetScrollClipLayer(root_clip
->id());
468 root_layer
->SetScrollOffset(scroll_offset
);
469 root_layer
->ScrollBy(scroll_delta
);
470 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
472 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
474 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
476 scroll_info
= host_impl_
->ProcessScrollDeltas();
477 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
478 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
);
479 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
481 gfx::Vector2d
scroll_delta2(-5, 27);
482 root
->ScrollBy(scroll_delta2
);
483 scroll_info
= host_impl_
->ProcessScrollDeltas();
484 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
485 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
486 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
488 root
->ScrollBy(gfx::Vector2d());
489 scroll_info
= host_impl_
->ProcessScrollDeltas();
490 EXPECT_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
493 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
494 SetupScrollAndContentsLayers(gfx::Size(100, 100));
495 host_impl_
->SetViewportSize(gfx::Size(50, 50));
498 EXPECT_EQ(InputHandler::ScrollStarted
,
499 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
500 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
501 InputHandler::Wheel
));
502 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
503 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
504 InputHandler::Wheel
));
505 host_impl_
->ScrollEnd();
506 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
507 InputHandler::Wheel
));
508 EXPECT_TRUE(did_request_redraw_
);
509 EXPECT_TRUE(did_request_commit_
);
512 TEST_F(LayerTreeHostImplTest
, ScrollActiveOnlyAfterScrollMovement
) {
513 SetupScrollAndContentsLayers(gfx::Size(100, 100));
514 host_impl_
->SetViewportSize(gfx::Size(50, 50));
517 EXPECT_EQ(InputHandler::ScrollStarted
,
518 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
519 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
520 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
521 EXPECT_TRUE(host_impl_
->IsActivelyScrolling());
522 host_impl_
->ScrollEnd();
523 EXPECT_FALSE(host_impl_
->IsActivelyScrolling());
526 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
527 // We should not crash when trying to scroll an empty layer tree.
528 EXPECT_EQ(InputHandler::ScrollIgnored
,
529 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
532 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
533 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
534 TestWebGraphicsContext3D::Create();
535 context_owned
->set_context_lost(true);
537 // Initialization will fail.
538 EXPECT_FALSE(CreateHostImpl(
539 DefaultSettings(), FakeOutputSurface::Create3d(context_owned
.Pass())));
541 SetupScrollAndContentsLayers(gfx::Size(100, 100));
543 // We should not crash when trying to scroll after the renderer initialization
545 EXPECT_EQ(InputHandler::ScrollStarted
,
546 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
549 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
550 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
551 host_impl_
->SetViewportSize(gfx::Size(50, 50));
554 // We should not crash if the tree is replaced while we are scrolling.
555 EXPECT_EQ(InputHandler::ScrollStarted
,
556 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
557 host_impl_
->active_tree()->DetachLayerTree();
559 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
561 // We should still be scrolling, because the scrolled layer also exists in the
563 gfx::Vector2d
scroll_delta(0, 10);
564 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
565 host_impl_
->ScrollEnd();
566 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
567 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
570 TEST_F(LayerTreeHostImplTest
, ClearRootRenderSurfaceAndScroll
) {
571 SetupScrollAndContentsLayers(gfx::Size(100, 100));
572 host_impl_
->SetViewportSize(gfx::Size(50, 50));
575 // We should be able to scroll even if the root layer loses its render surface
576 // after the most recent render.
577 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
578 host_impl_
->active_tree()->set_needs_update_draw_properties();
580 EXPECT_EQ(InputHandler::ScrollStarted
,
581 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
584 TEST_F(LayerTreeHostImplTest
, WheelEventHandlers
) {
585 SetupScrollAndContentsLayers(gfx::Size(100, 100));
586 host_impl_
->SetViewportSize(gfx::Size(50, 50));
588 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
590 root
->SetHaveWheelEventHandlers(true);
592 // With registered event handlers, wheel scrolls have to go to the main
594 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
595 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
597 // But gesture scrolls can still be handled.
598 EXPECT_EQ(InputHandler::ScrollStarted
,
599 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
602 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
603 SetupScrollAndContentsLayers(gfx::Size(100, 100));
604 host_impl_
->SetViewportSize(gfx::Size(50, 50));
607 // Ignore the fling since no layer is being scrolled
608 EXPECT_EQ(InputHandler::ScrollIgnored
,
609 host_impl_
->FlingScrollBegin());
611 // Start scrolling a layer
612 EXPECT_EQ(InputHandler::ScrollStarted
,
613 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
615 // Now the fling should go ahead since we've started scrolling a layer
616 EXPECT_EQ(InputHandler::ScrollStarted
,
617 host_impl_
->FlingScrollBegin());
620 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
621 SetupScrollAndContentsLayers(gfx::Size(100, 100));
622 host_impl_
->SetViewportSize(gfx::Size(50, 50));
625 // Ignore the fling since no layer is being scrolled
626 EXPECT_EQ(InputHandler::ScrollIgnored
,
627 host_impl_
->FlingScrollBegin());
629 // Start scrolling a layer
630 EXPECT_EQ(InputHandler::ScrollStarted
,
631 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
633 // Now the fling should go ahead since we've started scrolling a layer
634 EXPECT_EQ(InputHandler::ScrollStarted
,
635 host_impl_
->FlingScrollBegin());
638 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
639 SetupScrollAndContentsLayers(gfx::Size(100, 100));
640 host_impl_
->SetViewportSize(gfx::Size(50, 50));
642 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
644 root
->SetShouldScrollOnMainThread(true);
646 // Start scrolling a layer
647 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
648 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
650 // The fling should be ignored since there's no layer being scrolled impl-side
651 EXPECT_EQ(InputHandler::ScrollIgnored
,
652 host_impl_
->FlingScrollBegin());
655 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
656 SetupScrollAndContentsLayers(gfx::Size(100, 100));
657 host_impl_
->SetViewportSize(gfx::Size(50, 50));
659 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
661 root
->SetShouldScrollOnMainThread(true);
663 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
664 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
665 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
666 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
669 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
670 SetupScrollAndContentsLayers(gfx::Size(200, 200));
671 host_impl_
->SetViewportSize(gfx::Size(100, 100));
673 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
674 root
->SetContentsScale(2.f
, 2.f
);
675 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
679 // All scroll types inside the non-fast scrollable region should fail.
680 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
681 host_impl_
->ScrollBegin(gfx::Point(25, 25),
682 InputHandler::Wheel
));
683 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
684 InputHandler::Wheel
));
685 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
686 host_impl_
->ScrollBegin(gfx::Point(25, 25),
687 InputHandler::Gesture
));
688 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
689 InputHandler::Gesture
));
691 // All scroll types outside this region should succeed.
692 EXPECT_EQ(InputHandler::ScrollStarted
,
693 host_impl_
->ScrollBegin(gfx::Point(75, 75),
694 InputHandler::Wheel
));
695 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
696 InputHandler::Gesture
));
697 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
698 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
699 InputHandler::Gesture
));
700 host_impl_
->ScrollEnd();
701 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
702 InputHandler::Gesture
));
703 EXPECT_EQ(InputHandler::ScrollStarted
,
704 host_impl_
->ScrollBegin(gfx::Point(75, 75),
705 InputHandler::Gesture
));
706 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
707 InputHandler::Gesture
));
708 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
709 host_impl_
->ScrollEnd();
710 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
711 InputHandler::Gesture
));
714 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
715 SetupScrollAndContentsLayers(gfx::Size(200, 200));
716 host_impl_
->SetViewportSize(gfx::Size(100, 100));
718 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
719 root
->SetContentsScale(2.f
, 2.f
);
720 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
721 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
725 // This point would fall into the non-fast scrollable region except that we've
726 // moved the layer down by 25 pixels.
727 EXPECT_EQ(InputHandler::ScrollStarted
,
728 host_impl_
->ScrollBegin(gfx::Point(40, 10),
729 InputHandler::Wheel
));
730 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
731 InputHandler::Wheel
));
732 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
733 host_impl_
->ScrollEnd();
735 // This point is still inside the non-fast region.
736 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
737 host_impl_
->ScrollBegin(gfx::Point(10, 10),
738 InputHandler::Wheel
));
741 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
742 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
743 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
744 host_impl_
->SetViewportSize(gfx::Size(50, 50));
747 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
748 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
749 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
750 host_impl_
->ScrollEnd();
751 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
754 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
755 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
756 scroll_layer
->SetHaveScrollEventHandlers(true);
757 host_impl_
->SetViewportSize(gfx::Size(50, 50));
760 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
761 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
762 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
763 host_impl_
->ScrollEnd();
764 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
767 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
768 SetupScrollAndContentsLayers(gfx::Size(200, 200));
769 host_impl_
->SetViewportSize(gfx::Size(100, 100));
773 EXPECT_EQ(InputHandler::ScrollStarted
,
774 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
776 // Trying to scroll to the left/top will not succeed.
778 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
780 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll
);
782 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll
);
784 // Scrolling to the right/bottom will succeed.
786 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)).did_scroll
);
788 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
790 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)).did_scroll
);
792 // Scrolling to left/top will now succeed.
794 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
796 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll
);
798 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll
);
800 // Scrolling diagonally against an edge will succeed.
802 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)).did_scroll
);
804 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll
);
806 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)).did_scroll
);
808 // Trying to scroll more than the available space will also succeed.
810 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)).did_scroll
);
813 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
814 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
815 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
819 EXPECT_EQ(InputHandler::ScrollStarted
,
820 host_impl_
->ScrollBegin(gfx::Point(),
821 InputHandler::Wheel
));
823 // Trying to scroll without a vertical scrollbar will fail.
824 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
825 gfx::Point(), SCROLL_FORWARD
));
826 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
827 gfx::Point(), SCROLL_BACKWARD
));
829 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
830 PaintedScrollbarLayerImpl::Create(
831 host_impl_
->active_tree(),
834 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
835 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
836 vertical_scrollbar
.get());
838 // Trying to scroll with a vertical scrollbar will succeed.
839 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
840 gfx::Point(), SCROLL_FORWARD
));
841 EXPECT_FLOAT_EQ(875.f
,
842 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
843 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
844 gfx::Point(), SCROLL_BACKWARD
));
847 TEST_F(LayerTreeHostImplTest
, ScrollWithUserUnscrollableLayers
) {
848 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
849 host_impl_
->SetViewportSize(gfx::Size(100, 100));
851 gfx::Size
overflow_size(400, 400);
852 ASSERT_EQ(1u, scroll_layer
->children().size());
853 LayerImpl
* overflow
= scroll_layer
->children()[0];
854 overflow
->SetBounds(overflow_size
);
855 overflow
->SetContentBounds(overflow_size
);
856 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
857 overflow
->SetScrollOffset(gfx::ScrollOffset());
858 overflow
->SetPosition(gfx::PointF());
861 gfx::Point
scroll_position(10, 10);
863 EXPECT_EQ(InputHandler::ScrollStarted
,
864 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
865 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
866 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->TotalScrollOffset());
868 gfx::Vector2dF
scroll_delta(10, 10);
869 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
870 host_impl_
->ScrollEnd();
871 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
872 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
874 overflow
->set_user_scrollable_horizontal(false);
876 EXPECT_EQ(InputHandler::ScrollStarted
,
877 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
878 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
879 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
881 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
882 host_impl_
->ScrollEnd();
883 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
884 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
886 overflow
->set_user_scrollable_vertical(false);
888 EXPECT_EQ(InputHandler::ScrollStarted
,
889 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
890 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
891 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
893 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
894 host_impl_
->ScrollEnd();
895 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->TotalScrollOffset());
896 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
899 TEST_F(LayerTreeHostImplTest
,
900 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion
) {
901 SetupScrollAndContentsLayers(gfx::Size(100, 100));
902 host_impl_
->SetViewportSize(gfx::Size(50, 50));
905 // We should be able to hit test for touch event handlers even if the root
906 // layer loses its render surface after the most recent render.
907 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
908 host_impl_
->active_tree()->set_needs_update_draw_properties();
910 EXPECT_EQ(host_impl_
->HaveTouchEventHandlersAt(gfx::Point()), false);
913 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
914 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
915 host_impl_
->SetViewportSize(gfx::Size(50, 50));
918 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
919 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
920 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
922 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
923 float page_scale_factor
= 1.f
;
925 // The impl-based pinch zoom should adjust the max scroll position.
927 host_impl_
->active_tree()->PushPageScaleFromMainThread(
928 page_scale_factor
, min_page_scale
, max_page_scale
);
929 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
930 scroll_layer
->SetScrollDelta(gfx::Vector2d());
932 float page_scale_delta
= 2.f
;
934 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
935 host_impl_
->PinchGestureBegin();
936 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
937 host_impl_
->PinchGestureEnd();
938 host_impl_
->ScrollEnd();
939 EXPECT_FALSE(did_request_animate_
);
940 EXPECT_TRUE(did_request_redraw_
);
941 EXPECT_TRUE(did_request_commit_
);
942 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
944 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
945 host_impl_
->ProcessScrollDeltas();
946 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
948 EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
949 scroll_layer
->MaxScrollOffset().ToString());
952 // Scrolling after a pinch gesture should always be in local space. The
953 // scroll deltas have the page scale factor applied.
955 host_impl_
->active_tree()->PushPageScaleFromMainThread(
956 page_scale_factor
, min_page_scale
, max_page_scale
);
957 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
958 scroll_layer
->SetScrollDelta(gfx::Vector2d());
960 float page_scale_delta
= 2.f
;
961 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
962 host_impl_
->PinchGestureBegin();
963 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
964 host_impl_
->PinchGestureEnd();
965 host_impl_
->ScrollEnd();
967 gfx::Vector2d
scroll_delta(0, 10);
968 EXPECT_EQ(InputHandler::ScrollStarted
,
969 host_impl_
->ScrollBegin(gfx::Point(5, 5),
970 InputHandler::Wheel
));
971 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
972 host_impl_
->ScrollEnd();
974 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
975 host_impl_
->ProcessScrollDeltas();
976 ExpectContains(*scroll_info
.get(), scroll_layer
->id(),
977 gfx::Vector2d(0, scroll_delta
.y() / page_scale_delta
));
981 TEST_F(LayerTreeHostImplTest
, ScrollWithSwapPromises
) {
982 ui::LatencyInfo latency_info
;
983 latency_info
.trace_id
= 1234;
984 scoped_ptr
<SwapPromise
> swap_promise(
985 new LatencyInfoSwapPromise(latency_info
));
987 SetupScrollAndContentsLayers(gfx::Size(100, 100));
988 EXPECT_EQ(InputHandler::ScrollStarted
,
989 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
990 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
991 host_impl_
->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise
.Pass());
992 host_impl_
->ScrollEnd();
994 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
995 EXPECT_EQ(1u, scroll_info
->swap_promises
.size());
996 EXPECT_EQ(latency_info
.trace_id
, scroll_info
->swap_promises
[0]->TraceId());
999 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1000 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1001 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1004 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1005 DCHECK(scroll_layer
);
1007 float min_page_scale
= 1.f
;
1008 float max_page_scale
= 4.f
;
1010 // Basic pinch zoom in gesture
1012 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1014 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1016 float page_scale_delta
= 2.f
;
1017 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1018 host_impl_
->PinchGestureBegin();
1019 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1020 host_impl_
->PinchGestureEnd();
1021 host_impl_
->ScrollEnd();
1022 EXPECT_FALSE(did_request_animate_
);
1023 EXPECT_TRUE(did_request_redraw_
);
1024 EXPECT_TRUE(did_request_commit_
);
1026 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1027 host_impl_
->ProcessScrollDeltas();
1028 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1033 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1035 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1036 float page_scale_delta
= 10.f
;
1038 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1039 host_impl_
->PinchGestureBegin();
1040 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1041 host_impl_
->PinchGestureEnd();
1042 host_impl_
->ScrollEnd();
1044 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1045 host_impl_
->ProcessScrollDeltas();
1046 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1049 // Zoom-out clamping
1051 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1053 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1054 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1056 float page_scale_delta
= 0.1f
;
1057 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1058 host_impl_
->PinchGestureBegin();
1059 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1060 host_impl_
->PinchGestureEnd();
1061 host_impl_
->ScrollEnd();
1063 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1064 host_impl_
->ProcessScrollDeltas();
1065 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1067 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1070 // Two-finger panning should not happen based on pinch events only
1072 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1074 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1075 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(20, 20));
1077 float page_scale_delta
= 1.f
;
1078 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1079 host_impl_
->PinchGestureBegin();
1080 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1081 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1082 host_impl_
->PinchGestureEnd();
1083 host_impl_
->ScrollEnd();
1085 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1086 host_impl_
->ProcessScrollDeltas();
1087 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1088 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1091 // Two-finger panning should work with interleaved scroll events
1093 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1095 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1096 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(20, 20));
1098 float page_scale_delta
= 1.f
;
1099 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1100 host_impl_
->PinchGestureBegin();
1101 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1102 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1103 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1104 host_impl_
->PinchGestureEnd();
1105 host_impl_
->ScrollEnd();
1107 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1108 host_impl_
->ProcessScrollDeltas();
1109 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1110 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1113 // Two-finger panning should work when starting fully zoomed out.
1115 host_impl_
->active_tree()->PushPageScaleFromMainThread(0.5f
, 0.5f
, 4.f
);
1116 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1117 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(0, 0));
1119 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1120 host_impl_
->PinchGestureBegin();
1121 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1122 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1123 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1124 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1125 host_impl_
->PinchGestureEnd();
1126 host_impl_
->ScrollEnd();
1128 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1129 host_impl_
->ProcessScrollDeltas();
1130 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1131 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1135 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1136 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1137 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1140 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1141 DCHECK(scroll_layer
);
1143 float min_page_scale
= 0.5f
;
1144 float max_page_scale
= 4.f
;
1145 base::TimeTicks start_time
= base::TimeTicks() +
1146 base::TimeDelta::FromSeconds(1);
1147 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1148 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1149 base::TimeTicks end_time
= start_time
+ duration
;
1151 // Non-anchor zoom-in
1153 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1155 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1157 did_request_redraw_
= false;
1158 did_request_animate_
= false;
1159 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1160 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1165 host_impl_
->ActivateSyncTree();
1166 EXPECT_FALSE(did_request_redraw_
);
1167 EXPECT_TRUE(did_request_animate_
);
1169 did_request_redraw_
= false;
1170 did_request_animate_
= false;
1171 host_impl_
->Animate(start_time
);
1172 EXPECT_TRUE(did_request_redraw_
);
1173 EXPECT_TRUE(did_request_animate_
);
1175 did_request_redraw_
= false;
1176 did_request_animate_
= false;
1177 host_impl_
->Animate(halfway_through_animation
);
1178 EXPECT_TRUE(did_request_redraw_
);
1179 EXPECT_TRUE(did_request_animate_
);
1181 did_request_redraw_
= false;
1182 did_request_animate_
= false;
1183 did_request_commit_
= false;
1184 host_impl_
->Animate(end_time
);
1185 EXPECT_TRUE(did_request_commit_
);
1186 EXPECT_FALSE(did_request_animate_
);
1188 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1189 host_impl_
->ProcessScrollDeltas();
1190 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1191 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1196 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1198 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1200 did_request_redraw_
= false;
1201 did_request_animate_
= false;
1202 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1203 scoped_ptr
<PendingPageScaleAnimation
> (new PendingPageScaleAnimation(
1204 gfx::Vector2d(25, 25),
1208 host_impl_
->ActivateSyncTree();
1209 EXPECT_FALSE(did_request_redraw_
);
1210 EXPECT_TRUE(did_request_animate_
);
1212 did_request_redraw_
= false;
1213 did_request_animate_
= false;
1214 host_impl_
->Animate(start_time
);
1215 EXPECT_TRUE(did_request_redraw_
);
1216 EXPECT_TRUE(did_request_animate_
);
1218 did_request_redraw_
= false;
1219 did_request_commit_
= false;
1220 did_request_animate_
= false;
1221 host_impl_
->Animate(end_time
);
1222 EXPECT_TRUE(did_request_redraw_
);
1223 EXPECT_FALSE(did_request_animate_
);
1224 EXPECT_TRUE(did_request_commit_
);
1226 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1227 host_impl_
->ProcessScrollDeltas();
1228 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1229 // Pushed to (0,0) via clamping against contents layer size.
1230 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1234 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1235 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1236 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1239 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1240 DCHECK(scroll_layer
);
1242 float min_page_scale
= 0.5f
;
1243 float max_page_scale
= 4.f
;
1244 base::TimeTicks start_time
= base::TimeTicks() +
1245 base::TimeDelta::FromSeconds(1);
1246 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1247 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1248 base::TimeTicks end_time
= start_time
+ duration
;
1250 // Anchor zoom with unchanged page scale should not change scroll or scale.
1252 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1254 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1256 host_impl_
->active_tree()->SetPendingPageScaleAnimation(
1257 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1262 host_impl_
->ActivateSyncTree();
1263 host_impl_
->Animate(start_time
);
1264 host_impl_
->Animate(halfway_through_animation
);
1265 EXPECT_TRUE(did_request_redraw_
);
1266 host_impl_
->Animate(end_time
);
1267 EXPECT_TRUE(did_request_commit_
);
1269 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1270 host_impl_
->ProcessScrollDeltas();
1271 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1272 ExpectNone(*scroll_info
, scroll_layer
->id());
1276 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationTransferedOnSyncTreeActivate
) {
1277 host_impl_
->CreatePendingTree();
1278 CreateScrollAndContentsLayers(
1279 host_impl_
->pending_tree(),
1280 gfx::Size(100, 100));
1281 host_impl_
->ActivateSyncTree();
1284 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1285 DCHECK(scroll_layer
);
1287 float min_page_scale
= 0.5f
;
1288 float max_page_scale
= 4.f
;
1289 host_impl_
->sync_tree()->PushPageScaleFromMainThread(1.f
, min_page_scale
,
1291 host_impl_
->ActivateSyncTree();
1293 base::TimeTicks start_time
= base::TimeTicks() +
1294 base::TimeDelta::FromSeconds(1);
1295 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1296 base::TimeTicks third_through_animation
= start_time
+ duration
/ 3;
1297 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1298 base::TimeTicks end_time
= start_time
+ duration
;
1299 float target_scale
= 2.f
;
1301 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(50, 50));
1303 // Make sure TakePageScaleAnimation works properly.
1305 host_impl_
->sync_tree()->SetPendingPageScaleAnimation(
1306 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1311 scoped_ptr
<PendingPageScaleAnimation
> psa
=
1312 host_impl_
->sync_tree()->TakePendingPageScaleAnimation();
1313 EXPECT_EQ(target_scale
, psa
->scale
);
1314 EXPECT_EQ(duration
, psa
->duration
);
1315 EXPECT_EQ(nullptr, host_impl_
->sync_tree()->TakePendingPageScaleAnimation());
1317 // Recreate the PSA. Nothing should happen here since the tree containing the
1318 // PSA hasn't been activated yet.
1319 did_request_redraw_
= false;
1320 did_request_animate_
= false;
1321 host_impl_
->sync_tree()->SetPendingPageScaleAnimation(
1322 scoped_ptr
<PendingPageScaleAnimation
>(new PendingPageScaleAnimation(
1327 host_impl_
->Animate(halfway_through_animation
);
1328 EXPECT_FALSE(did_request_animate_
);
1329 EXPECT_FALSE(did_request_redraw_
);
1331 // Activate the sync tree. This should cause the animation to become enabled.
1332 // It should also clear the pointer on the sync tree.
1333 host_impl_
->ActivateSyncTree();
1335 host_impl_
->sync_tree()->TakePendingPageScaleAnimation().get());
1336 EXPECT_FALSE(did_request_redraw_
);
1337 EXPECT_TRUE(did_request_animate_
);
1339 // From here on, make sure the animation runs as normal.
1340 did_request_redraw_
= false;
1341 did_request_animate_
= false;
1342 host_impl_
->Animate(start_time
);
1343 EXPECT_TRUE(did_request_redraw_
);
1344 EXPECT_TRUE(did_request_animate_
);
1346 did_request_redraw_
= false;
1347 did_request_animate_
= false;
1348 host_impl_
->Animate(third_through_animation
);
1349 EXPECT_TRUE(did_request_redraw_
);
1350 EXPECT_TRUE(did_request_animate_
);
1352 // Another activation shouldn't have any effect on the animation.
1353 host_impl_
->ActivateSyncTree();
1355 did_request_redraw_
= false;
1356 did_request_animate_
= false;
1357 host_impl_
->Animate(halfway_through_animation
);
1358 EXPECT_TRUE(did_request_redraw_
);
1359 EXPECT_TRUE(did_request_animate_
);
1361 did_request_redraw_
= false;
1362 did_request_animate_
= false;
1363 did_request_commit_
= false;
1364 host_impl_
->Animate(end_time
);
1365 EXPECT_TRUE(did_request_commit_
);
1366 EXPECT_FALSE(did_request_animate_
);
1368 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1369 host_impl_
->ProcessScrollDeltas();
1370 EXPECT_EQ(scroll_info
->page_scale_delta
, target_scale
);
1371 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1374 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1376 LayerTreeHostImplOverridePhysicalTime(
1377 const LayerTreeSettings
& settings
,
1378 LayerTreeHostImplClient
* client
,
1380 SharedBitmapManager
* manager
,
1381 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1382 : LayerTreeHostImpl(settings
,
1385 rendering_stats_instrumentation
,
1390 BeginFrameArgs
CurrentBeginFrameArgs() const override
{
1391 return CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
,
1392 fake_current_physical_time_
);
1395 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1396 fake_current_physical_time_
= fake_now
;
1400 base::TimeTicks fake_current_physical_time_
;
1403 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1404 gfx::Size viewport_size(10, 10); \
1405 gfx::Size content_size(100, 100); \
1407 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1408 new LayerTreeHostImplOverridePhysicalTime(settings, this, &proxy_, \
1409 shared_bitmap_manager_.get(), \
1410 &stats_instrumentation_); \
1411 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1412 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1413 host_impl_->SetViewportSize(viewport_size); \
1415 scoped_ptr<LayerImpl> root = \
1416 LayerImpl::Create(host_impl_->active_tree(), 1); \
1417 root->SetBounds(viewport_size); \
1419 scoped_ptr<LayerImpl> scroll = \
1420 LayerImpl::Create(host_impl_->active_tree(), 2); \
1421 scroll->SetScrollClipLayer(root->id()); \
1422 scroll->SetScrollOffset(gfx::ScrollOffset()); \
1423 root->SetBounds(viewport_size); \
1424 scroll->SetBounds(content_size); \
1425 scroll->SetContentBounds(content_size); \
1426 scroll->SetIsContainerForFixedPositionLayers(true); \
1428 scoped_ptr<LayerImpl> contents = \
1429 LayerImpl::Create(host_impl_->active_tree(), 3); \
1430 contents->SetDrawsContent(true); \
1431 contents->SetBounds(content_size); \
1432 contents->SetContentBounds(content_size); \
1434 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1435 SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 4, \
1436 VERTICAL, 10, 0, false, true); \
1437 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1439 scroll->AddChild(contents.Pass()); \
1440 root->AddChild(scroll.Pass()); \
1441 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \
1442 root->AddChild(scrollbar.Pass()); \
1444 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1445 host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 2, \
1446 Layer::INVALID_ID); \
1447 host_impl_->active_tree()->DidBecomeActive(); \
1450 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1451 LayerTreeSettings settings
;
1452 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1453 settings
.scrollbar_fade_delay_ms
= 20;
1454 settings
.scrollbar_fade_duration_ms
= 20;
1456 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1458 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1460 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1461 EXPECT_FALSE(did_request_redraw_
);
1463 // If no scroll happened during a scroll gesture, it should have no effect.
1464 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1465 host_impl_
->ScrollEnd();
1466 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1467 EXPECT_FALSE(did_request_redraw_
);
1468 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1470 // After a scroll, a fade animation should be scheduled about 20ms from now.
1471 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1472 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5));
1473 host_impl_
->ScrollEnd();
1474 did_request_redraw_
= false;
1475 did_request_animate_
= false;
1476 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1477 requested_scrollbar_animation_delay_
);
1478 EXPECT_FALSE(did_request_redraw_
);
1479 EXPECT_FALSE(did_request_animate_
);
1480 requested_scrollbar_animation_delay_
= base::TimeDelta();
1481 scrollbar_fade_start_
.Run();
1482 host_impl_
->Animate(fake_now
);
1484 // After the fade begins, we should start getting redraws instead of a
1485 // scheduled animation.
1486 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1487 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1488 EXPECT_TRUE(did_request_animate_
);
1489 did_request_animate_
= false;
1491 // Setting the scroll offset outside a scroll should also cause the scrollbar
1492 // to appear and to schedule a fade.
1493 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(
1494 gfx::ScrollOffset(5, 5));
1495 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1496 requested_scrollbar_animation_delay_
);
1497 EXPECT_FALSE(did_request_redraw_
);
1498 EXPECT_FALSE(did_request_animate_
);
1499 requested_scrollbar_animation_delay_
= base::TimeDelta();
1501 // Unnecessarily Fade animation of solid color scrollbar is not triggered.
1502 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1503 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1504 host_impl_
->ScrollEnd();
1505 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1508 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1509 LayerTreeSettings settings
;
1510 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1511 settings
.scrollbar_fade_delay_ms
= 20;
1512 settings
.scrollbar_fade_duration_ms
= 20;
1513 settings
.use_pinch_zoom_scrollbars
= true;
1515 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1517 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1519 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 1.f
, 4.f
);
1521 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1522 EXPECT_FALSE(did_request_animate_
);
1524 // If no scroll happened during a scroll gesture, it should have no effect.
1525 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1526 host_impl_
->ScrollEnd();
1527 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1528 EXPECT_FALSE(did_request_animate_
);
1529 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1531 // After a scroll, no fade animation should be scheduled.
1532 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1533 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1534 host_impl_
->ScrollEnd();
1535 did_request_redraw_
= false;
1536 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1537 EXPECT_FALSE(did_request_animate_
);
1538 requested_scrollbar_animation_delay_
= base::TimeDelta();
1540 // We should not see any draw requests.
1541 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1542 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1543 EXPECT_FALSE(did_request_animate_
);
1545 // Make page scale > min so that subsequent scrolls will trigger fades.
1546 host_impl_
->SetPageScaleOnActiveTree(1.1f
);
1548 // After a scroll, a fade animation should be scheduled about 20ms from now.
1549 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1550 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1551 host_impl_
->ScrollEnd();
1552 did_request_redraw_
= false;
1553 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1554 requested_scrollbar_animation_delay_
);
1555 EXPECT_FALSE(did_request_animate_
);
1556 requested_scrollbar_animation_delay_
= base::TimeDelta();
1557 scrollbar_fade_start_
.Run();
1559 // After the fade begins, we should start getting redraws instead of a
1560 // scheduled animation.
1561 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1562 host_impl_
->Animate(fake_now
);
1563 EXPECT_TRUE(did_request_animate_
);
1566 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1567 float device_scale_factor
) {
1568 LayerTreeSettings settings
;
1569 settings
.scrollbar_fade_delay_ms
= 500;
1570 settings
.scrollbar_fade_duration_ms
= 300;
1571 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1573 gfx::Size
viewport_size(300, 200);
1574 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1575 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1576 gfx::Size
content_size(1000, 1000);
1578 CreateHostImpl(settings
, CreateOutputSurface());
1579 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1580 host_impl_
->SetViewportSize(device_viewport_size
);
1582 scoped_ptr
<LayerImpl
> root
=
1583 LayerImpl::Create(host_impl_
->active_tree(), 1);
1584 root
->SetBounds(viewport_size
);
1586 scoped_ptr
<LayerImpl
> scroll
=
1587 LayerImpl::Create(host_impl_
->active_tree(), 2);
1588 scroll
->SetScrollClipLayer(root
->id());
1589 scroll
->SetScrollOffset(gfx::ScrollOffset());
1590 scroll
->SetBounds(content_size
);
1591 scroll
->SetContentBounds(content_size
);
1592 scroll
->SetIsContainerForFixedPositionLayers(true);
1594 scoped_ptr
<LayerImpl
> contents
=
1595 LayerImpl::Create(host_impl_
->active_tree(), 3);
1596 contents
->SetDrawsContent(true);
1597 contents
->SetBounds(content_size
);
1598 contents
->SetContentBounds(content_size
);
1600 // The scrollbar is on the right side.
1601 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1602 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1603 scrollbar
->SetDrawsContent(true);
1604 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1605 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1606 scrollbar
->SetPosition(gfx::Point(285, 0));
1608 scroll
->AddChild(contents
.Pass());
1609 root
->AddChild(scroll
.Pass());
1610 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1611 root
->AddChild(scrollbar
.Pass());
1613 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1614 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
1616 host_impl_
->active_tree()->DidBecomeActive();
1619 LayerImpl
* root_scroll
=
1620 host_impl_
->active_tree()->InnerViewportScrollLayer();
1621 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1622 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1623 static_cast<ScrollbarAnimationControllerThinning
*>(
1624 root_scroll
->scrollbar_animation_controller());
1625 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1627 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1628 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1630 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1631 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1633 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1634 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1636 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1637 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1638 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1640 did_request_redraw_
= false;
1641 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1642 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1643 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1644 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1645 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1646 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1647 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1650 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1651 SetupMouseMoveAtWithDeviceScale(1.f
);
1654 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1655 SetupMouseMoveAtWithDeviceScale(2.f
);
1658 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1659 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1660 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1661 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
1664 CompositorFrameMetadata metadata
=
1665 host_impl_
->MakeCompositorFrameMetadata();
1666 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1667 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1668 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.scrollable_viewport_size
);
1669 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1670 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1671 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1674 // Scrolling should update metadata immediately.
1675 EXPECT_EQ(InputHandler::ScrollStarted
,
1676 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1677 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1679 CompositorFrameMetadata metadata
=
1680 host_impl_
->MakeCompositorFrameMetadata();
1681 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1683 host_impl_
->ScrollEnd();
1685 CompositorFrameMetadata metadata
=
1686 host_impl_
->MakeCompositorFrameMetadata();
1687 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1690 // Page scale should update metadata correctly (shrinking only the viewport).
1691 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1692 host_impl_
->PinchGestureBegin();
1693 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1694 host_impl_
->PinchGestureEnd();
1695 host_impl_
->ScrollEnd();
1697 CompositorFrameMetadata metadata
=
1698 host_impl_
->MakeCompositorFrameMetadata();
1699 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1700 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1701 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.scrollable_viewport_size
);
1702 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1703 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1704 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1707 // Likewise if set from the main thread.
1708 host_impl_
->ProcessScrollDeltas();
1709 host_impl_
->active_tree()->PushPageScaleFromMainThread(4.f
, 0.5f
, 4.f
);
1710 host_impl_
->SetPageScaleOnActiveTree(4.f
);
1712 CompositorFrameMetadata metadata
=
1713 host_impl_
->MakeCompositorFrameMetadata();
1714 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1715 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1716 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.scrollable_viewport_size
);
1717 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1718 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1719 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1723 class DidDrawCheckLayer
: public LayerImpl
{
1725 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1726 return make_scoped_ptr(new DidDrawCheckLayer(tree_impl
, id
));
1729 bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
) override
{
1730 will_draw_called_
= true;
1731 if (will_draw_returns_false_
)
1733 return LayerImpl::WillDraw(draw_mode
, provider
);
1736 void AppendQuads(RenderPass
* render_pass
,
1737 const Occlusion
& occlusion_in_content_space
,
1738 AppendQuadsData
* append_quads_data
) override
{
1739 append_quads_called_
= true;
1740 LayerImpl::AppendQuads(
1741 render_pass
, occlusion_in_content_space
, append_quads_data
);
1744 void DidDraw(ResourceProvider
* provider
) override
{
1745 did_draw_called_
= true;
1746 LayerImpl::DidDraw(provider
);
1749 bool will_draw_called() const { return will_draw_called_
; }
1750 bool append_quads_called() const { return append_quads_called_
; }
1751 bool did_draw_called() const { return did_draw_called_
; }
1753 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1755 void ClearDidDrawCheck() {
1756 will_draw_called_
= false;
1757 append_quads_called_
= false;
1758 did_draw_called_
= false;
1762 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1763 : LayerImpl(tree_impl
, id
),
1764 will_draw_returns_false_(false),
1765 will_draw_called_(false),
1766 append_quads_called_(false),
1767 did_draw_called_(false) {
1768 SetBounds(gfx::Size(10, 10));
1769 SetContentBounds(gfx::Size(10, 10));
1770 SetDrawsContent(true);
1771 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1775 bool will_draw_returns_false_
;
1776 bool will_draw_called_
;
1777 bool append_quads_called_
;
1778 bool did_draw_called_
;
1781 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1782 // The root layer is always drawn, so run this test on a child layer that
1783 // will be masked out by the root layer's bounds.
1784 host_impl_
->active_tree()->SetRootLayer(
1785 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1786 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1787 host_impl_
->active_tree()->root_layer());
1789 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1790 DidDrawCheckLayer
* layer
=
1791 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1794 LayerTreeHostImpl::FrameData frame
;
1795 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1796 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1797 host_impl_
->DidDrawAllLayers(frame
);
1799 EXPECT_TRUE(layer
->will_draw_called());
1800 EXPECT_TRUE(layer
->append_quads_called());
1801 EXPECT_TRUE(layer
->did_draw_called());
1804 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1807 LayerTreeHostImpl::FrameData frame
;
1809 layer
->set_will_draw_returns_false();
1810 layer
->ClearDidDrawCheck();
1812 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1813 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1814 host_impl_
->DidDrawAllLayers(frame
);
1816 EXPECT_TRUE(layer
->will_draw_called());
1817 EXPECT_FALSE(layer
->append_quads_called());
1818 EXPECT_FALSE(layer
->did_draw_called());
1822 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1823 // The root layer is always drawn, so run this test on a child layer that
1824 // will be masked out by the root layer's bounds.
1825 host_impl_
->active_tree()->SetRootLayer(
1826 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1827 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1828 host_impl_
->active_tree()->root_layer());
1829 root
->SetMasksToBounds(true);
1831 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1832 DidDrawCheckLayer
* layer
=
1833 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1834 // Ensure visible_content_rect for layer is empty.
1835 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1836 layer
->SetBounds(gfx::Size(10, 10));
1837 layer
->SetContentBounds(gfx::Size(10, 10));
1839 LayerTreeHostImpl::FrameData frame
;
1841 EXPECT_FALSE(layer
->will_draw_called());
1842 EXPECT_FALSE(layer
->did_draw_called());
1844 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1845 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1846 host_impl_
->DidDrawAllLayers(frame
);
1848 EXPECT_FALSE(layer
->will_draw_called());
1849 EXPECT_FALSE(layer
->did_draw_called());
1851 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1853 // Ensure visible_content_rect for layer is not empty
1854 layer
->SetPosition(gfx::PointF());
1856 EXPECT_FALSE(layer
->will_draw_called());
1857 EXPECT_FALSE(layer
->did_draw_called());
1859 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1860 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1861 host_impl_
->DidDrawAllLayers(frame
);
1863 EXPECT_TRUE(layer
->will_draw_called());
1864 EXPECT_TRUE(layer
->did_draw_called());
1866 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1869 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1870 gfx::Size
big_size(1000, 1000);
1871 host_impl_
->SetViewportSize(big_size
);
1873 host_impl_
->active_tree()->SetRootLayer(
1874 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1875 DidDrawCheckLayer
* root
=
1876 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1878 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1879 DidDrawCheckLayer
* occluded_layer
=
1880 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1882 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1883 DidDrawCheckLayer
* top_layer
=
1884 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1885 // This layer covers the occluded_layer above. Make this layer large so it can
1887 top_layer
->SetBounds(big_size
);
1888 top_layer
->SetContentBounds(big_size
);
1889 top_layer
->SetContentsOpaque(true);
1891 LayerTreeHostImpl::FrameData frame
;
1893 EXPECT_FALSE(occluded_layer
->will_draw_called());
1894 EXPECT_FALSE(occluded_layer
->did_draw_called());
1895 EXPECT_FALSE(top_layer
->will_draw_called());
1896 EXPECT_FALSE(top_layer
->did_draw_called());
1898 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1899 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1900 host_impl_
->DidDrawAllLayers(frame
);
1902 EXPECT_FALSE(occluded_layer
->will_draw_called());
1903 EXPECT_FALSE(occluded_layer
->did_draw_called());
1904 EXPECT_TRUE(top_layer
->will_draw_called());
1905 EXPECT_TRUE(top_layer
->did_draw_called());
1908 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1909 host_impl_
->active_tree()->SetRootLayer(
1910 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1911 DidDrawCheckLayer
* root
=
1912 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1914 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1915 DidDrawCheckLayer
* layer1
=
1916 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1918 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1919 DidDrawCheckLayer
* layer2
=
1920 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1922 layer1
->SetOpacity(0.3f
);
1923 layer1
->SetShouldFlattenTransform(true);
1925 EXPECT_FALSE(root
->did_draw_called());
1926 EXPECT_FALSE(layer1
->did_draw_called());
1927 EXPECT_FALSE(layer2
->did_draw_called());
1929 LayerTreeHostImpl::FrameData frame
;
1930 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
1931 host_impl_
->active_tree()->root_layer());
1932 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1933 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1934 host_impl_
->DidDrawAllLayers(frame
);
1936 EXPECT_TRUE(root
->did_draw_called());
1937 EXPECT_TRUE(layer1
->did_draw_called());
1938 EXPECT_TRUE(layer2
->did_draw_called());
1940 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1941 EXPECT_TRUE(!!layer1
->render_surface());
1944 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1946 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1949 bool had_incomplete_tile
,
1951 ResourceProvider
* resource_provider
) {
1952 return make_scoped_ptr(new MissingTextureAnimatingLayer(tree_impl
,
1955 had_incomplete_tile
,
1957 resource_provider
));
1960 void AppendQuads(RenderPass
* render_pass
,
1961 const Occlusion
& occlusion_in_content_space
,
1962 AppendQuadsData
* append_quads_data
) override
{
1963 LayerImpl::AppendQuads(
1964 render_pass
, occlusion_in_content_space
, append_quads_data
);
1965 if (had_incomplete_tile_
)
1966 append_quads_data
->num_incomplete_tiles
++;
1968 append_quads_data
->num_missing_tiles
++;
1972 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1975 bool had_incomplete_tile
,
1977 ResourceProvider
* resource_provider
)
1978 : DidDrawCheckLayer(tree_impl
, id
),
1979 tile_missing_(tile_missing
),
1980 had_incomplete_tile_(had_incomplete_tile
) {
1982 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1986 bool had_incomplete_tile_
;
1989 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsOnDefault
) {
1990 host_impl_
->active_tree()->SetRootLayer(
1991 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1992 DidDrawCheckLayer
* root
=
1993 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1995 bool tile_missing
= false;
1996 bool had_incomplete_tile
= false;
1997 bool is_animating
= false;
1999 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2002 had_incomplete_tile
,
2004 host_impl_
->resource_provider()));
2006 LayerTreeHostImpl::FrameData frame
;
2008 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2009 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2010 host_impl_
->DidDrawAllLayers(frame
);
2013 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
2014 host_impl_
->active_tree()->SetRootLayer(
2015 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
2016 DidDrawCheckLayer
* root
=
2017 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2018 bool tile_missing
= false;
2019 bool had_incomplete_tile
= false;
2020 bool is_animating
= true;
2022 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2025 had_incomplete_tile
,
2027 host_impl_
->resource_provider()));
2029 LayerTreeHostImpl::FrameData frame
;
2031 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2032 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2033 host_impl_
->DidDrawAllLayers(frame
);
2036 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithMissingTiles
) {
2037 host_impl_
->active_tree()->SetRootLayer(
2038 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2039 DidDrawCheckLayer
* root
=
2040 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2042 LayerTreeHostImpl::FrameData frame
;
2043 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2044 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2045 host_impl_
->DidDrawAllLayers(frame
);
2046 host_impl_
->SwapBuffers(frame
);
2048 bool tile_missing
= true;
2049 bool had_incomplete_tile
= false;
2050 bool is_animating
= false;
2052 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2055 had_incomplete_tile
,
2057 host_impl_
->resource_provider()));
2058 LayerTreeHostImpl::FrameData frame2
;
2059 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2060 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2061 host_impl_
->DidDrawAllLayers(frame2
);
2064 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithIncompleteTile
) {
2065 host_impl_
->active_tree()->SetRootLayer(
2066 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
2067 DidDrawCheckLayer
* root
=
2068 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2070 LayerTreeHostImpl::FrameData frame
;
2071 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2072 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2073 host_impl_
->DidDrawAllLayers(frame
);
2074 host_impl_
->SwapBuffers(frame
);
2076 bool tile_missing
= false;
2077 bool had_incomplete_tile
= true;
2078 bool is_animating
= false;
2080 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2083 had_incomplete_tile
,
2085 host_impl_
->resource_provider()));
2086 LayerTreeHostImpl::FrameData frame2
;
2087 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2088 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2089 host_impl_
->DidDrawAllLayers(frame2
);
2092 TEST_F(LayerTreeHostImplTest
,
2093 PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard
) {
2094 host_impl_
->active_tree()->SetRootLayer(
2095 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2096 DidDrawCheckLayer
* root
=
2097 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2099 LayerTreeHostImpl::FrameData frame
;
2100 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2101 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2102 host_impl_
->DidDrawAllLayers(frame
);
2103 host_impl_
->SwapBuffers(frame
);
2105 bool tile_missing
= true;
2106 bool had_incomplete_tile
= false;
2107 bool is_animating
= true;
2109 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2112 had_incomplete_tile
,
2114 host_impl_
->resource_provider()));
2115 LayerTreeHostImpl::FrameData frame2
;
2116 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2117 host_impl_
->PrepareToDraw(&frame2
));
2118 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2119 host_impl_
->DidDrawAllLayers(frame2
);
2122 TEST_F(LayerTreeHostImplTest
,
2123 PrepareToDrawSucceedsWithAnimationAndIncompleteTiles
) {
2124 host_impl_
->active_tree()->SetRootLayer(
2125 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2126 DidDrawCheckLayer
* root
=
2127 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2129 LayerTreeHostImpl::FrameData frame
;
2130 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2131 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2132 host_impl_
->DidDrawAllLayers(frame
);
2133 host_impl_
->SwapBuffers(frame
);
2135 bool tile_missing
= false;
2136 bool had_incomplete_tile
= true;
2137 bool is_animating
= true;
2139 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2142 had_incomplete_tile
,
2144 host_impl_
->resource_provider()));
2145 LayerTreeHostImpl::FrameData frame2
;
2146 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2147 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2148 host_impl_
->DidDrawAllLayers(frame2
);
2151 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenHighResRequired
) {
2152 host_impl_
->active_tree()->SetRootLayer(
2153 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2154 DidDrawCheckLayer
* root
=
2155 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2157 LayerTreeHostImpl::FrameData frame
;
2158 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2159 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2160 host_impl_
->DidDrawAllLayers(frame
);
2161 host_impl_
->SwapBuffers(frame
);
2163 bool tile_missing
= false;
2164 bool had_incomplete_tile
= false;
2165 bool is_animating
= false;
2167 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2170 had_incomplete_tile
,
2172 host_impl_
->resource_provider()));
2173 host_impl_
->SetRequiresHighResToDraw();
2174 LayerTreeHostImpl::FrameData frame2
;
2175 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame2
));
2176 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2177 host_impl_
->DidDrawAllLayers(frame2
);
2180 TEST_F(LayerTreeHostImplTest
,
2181 PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles
) {
2182 host_impl_
->active_tree()->SetRootLayer(
2183 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2184 DidDrawCheckLayer
* root
=
2185 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2187 LayerTreeHostImpl::FrameData frame
;
2188 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2189 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2190 host_impl_
->DidDrawAllLayers(frame
);
2191 host_impl_
->SwapBuffers(frame
);
2193 bool tile_missing
= false;
2194 bool had_incomplete_tile
= true;
2195 bool is_animating
= false;
2197 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2200 had_incomplete_tile
,
2202 host_impl_
->resource_provider()));
2203 host_impl_
->SetRequiresHighResToDraw();
2204 LayerTreeHostImpl::FrameData frame2
;
2205 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2206 host_impl_
->PrepareToDraw(&frame2
));
2207 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2208 host_impl_
->DidDrawAllLayers(frame2
);
2211 TEST_F(LayerTreeHostImplTest
,
2212 PrepareToDrawFailsWhenHighResRequiredAndMissingTile
) {
2213 host_impl_
->active_tree()->SetRootLayer(
2214 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2215 DidDrawCheckLayer
* root
=
2216 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2218 LayerTreeHostImpl::FrameData frame
;
2219 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2220 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2221 host_impl_
->DidDrawAllLayers(frame
);
2222 host_impl_
->SwapBuffers(frame
);
2224 bool tile_missing
= true;
2225 bool had_incomplete_tile
= false;
2226 bool is_animating
= false;
2228 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2231 had_incomplete_tile
,
2233 host_impl_
->resource_provider()));
2234 host_impl_
->SetRequiresHighResToDraw();
2235 LayerTreeHostImpl::FrameData frame2
;
2236 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2237 host_impl_
->PrepareToDraw(&frame2
));
2238 host_impl_
->DrawLayers(&frame2
, gfx::FrameTime::Now());
2239 host_impl_
->DidDrawAllLayers(frame2
);
2242 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2243 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2244 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2245 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2248 // Scroll event is ignored because layer is not scrollable.
2249 EXPECT_EQ(InputHandler::ScrollIgnored
,
2250 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2251 EXPECT_FALSE(did_request_redraw_
);
2252 EXPECT_FALSE(did_request_commit_
);
2255 // TODO(bokan): Convert these tests to create inner and outer viewports.
2256 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2258 LayerTreeHostImplTopControlsTest()
2259 // Make the clip size the same as the layer (content) size so the layer is
2261 : layer_size_(10, 10),
2262 clip_size_(layer_size_
),
2263 top_controls_height_(50) {
2264 settings_
.calculate_top_controls_position
= true;
2265 settings_
.use_pinch_virtual_viewport
= true;
2267 viewport_size_
= gfx::Size(clip_size_
.width(),
2268 clip_size_
.height() + top_controls_height_
);
2271 bool CreateHostImpl(const LayerTreeSettings
& settings
,
2272 scoped_ptr
<OutputSurface
> output_surface
) override
{
2274 LayerTreeHostImplTest::CreateHostImpl(settings
, output_surface
.Pass());
2275 if (init
&& settings
.calculate_top_controls_position
) {
2276 host_impl_
->active_tree()->set_top_controls_height(top_controls_height_
);
2277 host_impl_
->active_tree()->set_top_controls_delta(top_controls_height_
);
2278 host_impl_
->top_controls_manager()->SetTopControlsHeight(
2279 top_controls_height_
);
2280 host_impl_
->DidChangeTopControlsPosition();
2285 void SetupTopControlsAndScrollLayer() {
2286 scoped_ptr
<LayerImpl
> root
=
2287 LayerImpl::Create(host_impl_
->active_tree(), 1);
2288 scoped_ptr
<LayerImpl
> root_clip
=
2289 LayerImpl::Create(host_impl_
->active_tree(), 2);
2290 root_clip
->SetBounds(clip_size_
);
2291 root
->SetScrollClipLayer(root_clip
->id());
2292 root
->SetBounds(layer_size_
);
2293 root
->SetContentBounds(layer_size_
);
2294 root
->SetPosition(gfx::PointF());
2295 root
->SetDrawsContent(false);
2296 root
->SetIsContainerForFixedPositionLayers(true);
2297 int inner_viewport_scroll_layer_id
= root
->id();
2298 int page_scale_layer_id
= root_clip
->id();
2299 root_clip
->AddChild(root
.Pass());
2300 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2301 host_impl_
->active_tree()->SetViewportLayersFromIds(
2302 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2304 // Set a viewport size that is large enough to contain both the top controls
2305 // and some content.
2306 host_impl_
->SetViewportSize(viewport_size_
);
2307 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2309 host_impl_
->DidChangeTopControlsPosition();
2311 host_impl_
->CreatePendingTree();
2313 LayerImpl::Create(host_impl_
->sync_tree(), 1);
2315 LayerImpl::Create(host_impl_
->sync_tree(), 2);
2316 root_clip
->SetBounds(clip_size_
);
2317 root
->SetScrollClipLayer(root_clip
->id());
2318 root
->SetBounds(layer_size_
);
2319 root
->SetContentBounds(layer_size_
);
2320 root
->SetPosition(gfx::PointF());
2321 root
->SetDrawsContent(false);
2322 root
->SetIsContainerForFixedPositionLayers(true);
2323 inner_viewport_scroll_layer_id
= root
->id();
2324 page_scale_layer_id
= root_clip
->id();
2325 root_clip
->AddChild(root
.Pass());
2326 host_impl_
->sync_tree()->SetRootLayer(root_clip
.Pass());
2327 host_impl_
->sync_tree()->SetViewportLayersFromIds(
2328 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2330 // Set a viewport size that is large enough to contain both the top controls
2331 // and some content.
2332 host_impl_
->SetViewportSize(viewport_size_
);
2333 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2334 host_impl_
->DidChangeTopControlsPosition();
2337 void SetupTopControlsAndScrollLayerWithVirtualViewport(
2338 const gfx::Size
& inner_viewport_size
,
2339 const gfx::Size
& outer_viewport_size
,
2340 const gfx::Size
& scroll_layer_size
) {
2341 CreateHostImpl(settings_
, CreateOutputSurface());
2342 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2343 host_impl_
->DidChangeTopControlsPosition();
2345 scoped_ptr
<LayerImpl
> root
=
2346 LayerImpl::Create(host_impl_
->active_tree(), 1);
2347 scoped_ptr
<LayerImpl
> root_clip
=
2348 LayerImpl::Create(host_impl_
->active_tree(), 2);
2349 scoped_ptr
<LayerImpl
> page_scale
=
2350 LayerImpl::Create(host_impl_
->active_tree(), 3);
2352 scoped_ptr
<LayerImpl
> outer_scroll
=
2353 LayerImpl::Create(host_impl_
->active_tree(), 4);
2354 scoped_ptr
<LayerImpl
> outer_clip
=
2355 LayerImpl::Create(host_impl_
->active_tree(), 5);
2357 root_clip
->SetBounds(inner_viewport_size
);
2358 root
->SetScrollClipLayer(root_clip
->id());
2359 root
->SetBounds(outer_viewport_size
);
2360 root
->SetContentBounds(outer_viewport_size
);
2361 root
->SetPosition(gfx::PointF());
2362 root
->SetDrawsContent(false);
2363 root
->SetIsContainerForFixedPositionLayers(true);
2365 outer_clip
->SetBounds(outer_viewport_size
);
2366 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
2367 outer_scroll
->SetBounds(scroll_layer_size
);
2368 outer_scroll
->SetContentBounds(scroll_layer_size
);
2369 outer_scroll
->SetPosition(gfx::PointF());
2370 outer_scroll
->SetDrawsContent(false);
2371 outer_scroll
->SetIsContainerForFixedPositionLayers(true);
2373 int inner_viewport_scroll_layer_id
= root
->id();
2374 int outer_viewport_scroll_layer_id
= outer_scroll
->id();
2375 int page_scale_layer_id
= page_scale
->id();
2377 outer_clip
->AddChild(outer_scroll
.Pass());
2378 root
->AddChild(outer_clip
.Pass());
2379 page_scale
->AddChild(root
.Pass());
2380 root_clip
->AddChild(page_scale
.Pass());
2382 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2383 host_impl_
->active_tree()->SetViewportLayersFromIds(
2384 Layer::INVALID_ID
, page_scale_layer_id
, inner_viewport_scroll_layer_id
,
2385 outer_viewport_scroll_layer_id
);
2387 host_impl_
->SetViewportSize(inner_viewport_size
);
2388 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2389 EXPECT_EQ(inner_viewport_size
, root_clip_ptr
->bounds());
2393 gfx::Size layer_size_
;
2394 gfx::Size clip_size_
;
2395 gfx::Size viewport_size_
;
2396 float top_controls_height_
;
2398 LayerTreeSettings settings_
;
2399 }; // class LayerTreeHostImplTopControlsTest
2401 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2402 SetupTopControlsAndScrollLayerWithVirtualViewport(
2403 gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
2406 EXPECT_EQ(InputHandler::ScrollStarted
,
2407 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2409 // Make the test scroll delta a fractional amount, to verify that the
2410 // fixed container size delta is (1) non-zero, and (2) fractional, and
2411 // (3) matches the movement of the top controls.
2412 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2413 host_impl_
->top_controls_manager()->ScrollBegin();
2414 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2415 host_impl_
->top_controls_manager()->ScrollEnd();
2417 LayerImpl
* inner_viewport_scroll_layer
=
2418 host_impl_
->active_tree()->InnerViewportScrollLayer();
2419 DCHECK(inner_viewport_scroll_layer
);
2420 host_impl_
->ScrollEnd();
2421 EXPECT_EQ(top_controls_scroll_delta
,
2422 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2425 // In this test, the outer viewport is initially unscrollable. We test that a
2426 // scroll initiated on the inner viewport, causing the top controls to show and
2427 // thus making the outer viewport scrollable, still scrolls the outer viewport.
2428 TEST_F(LayerTreeHostImplTopControlsTest
,
2429 TopControlsOuterViewportBecomesScrollable
) {
2430 SetupTopControlsAndScrollLayerWithVirtualViewport(
2431 gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
2434 LayerImpl
*inner_scroll
=
2435 host_impl_
->active_tree()->InnerViewportScrollLayer();
2436 LayerImpl
*inner_container
=
2437 host_impl_
->active_tree()->InnerViewportContainerLayer();
2438 LayerImpl
*outer_scroll
=
2439 host_impl_
->active_tree()->OuterViewportScrollLayer();
2440 LayerImpl
*outer_container
=
2441 host_impl_
->active_tree()->OuterViewportContainerLayer();
2443 // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
2444 outer_scroll
->SetDrawsContent(true);
2445 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 1.f
, 2.f
);
2447 EXPECT_EQ(InputHandler::ScrollStarted
,
2448 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2449 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, 50.f
));
2451 // The entire scroll delta should have been used to hide the top controls.
2452 // The viewport layers should be resized back to their full sizes.
2454 host_impl_
->active_tree()->total_top_controls_content_offset());
2455 EXPECT_EQ(0.f
, inner_scroll
->TotalScrollOffset().y());
2456 EXPECT_EQ(100.f
, inner_container
->BoundsForScrolling().height());
2457 EXPECT_EQ(100.f
, outer_container
->BoundsForScrolling().height());
2459 // The inner viewport should be scrollable by 50px * page_scale.
2460 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, 100.f
));
2461 EXPECT_EQ(50.f
, inner_scroll
->TotalScrollOffset().y());
2462 EXPECT_EQ(0.f
, outer_scroll
->TotalScrollOffset().y());
2463 EXPECT_EQ(gfx::ScrollOffset(), outer_scroll
->MaxScrollOffset());
2465 host_impl_
->ScrollEnd();
2467 EXPECT_EQ(InputHandler::ScrollStarted
,
2468 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2469 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
2471 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -50.f
));
2473 // The entire scroll delta should have been used to show the top controls.
2474 // The outer viewport should be resized to accomodate and scrolled to the
2475 // bottom of the document to keep the viewport in place.
2477 host_impl_
->active_tree()->total_top_controls_content_offset());
2478 EXPECT_EQ(50.f
, outer_container
->BoundsForScrolling().height());
2479 EXPECT_EQ(50.f
, inner_container
->BoundsForScrolling().height());
2480 EXPECT_EQ(25.f
, outer_scroll
->TotalScrollOffset().y());
2481 EXPECT_EQ(25.f
, inner_scroll
->TotalScrollOffset().y());
2483 // Now when we continue scrolling, make sure the outer viewport gets scrolled
2484 // since it wasn't scrollable when the scroll began.
2485 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -20.f
));
2486 EXPECT_EQ(15.f
, outer_scroll
->TotalScrollOffset().y());
2487 EXPECT_EQ(25.f
, inner_scroll
->TotalScrollOffset().y());
2489 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -30.f
));
2490 EXPECT_EQ(0.f
, outer_scroll
->TotalScrollOffset().y());
2491 EXPECT_EQ(25.f
, inner_scroll
->TotalScrollOffset().y());
2493 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f
, -50.f
));
2494 host_impl_
->ScrollEnd();
2496 EXPECT_EQ(0.f
, outer_scroll
->TotalScrollOffset().y());
2497 EXPECT_EQ(0.f
, inner_scroll
->TotalScrollOffset().y());
2500 // Test that the fixed position container delta is appropriately adjusted
2501 // by the top controls showing/hiding and page scale doesn't affect it.
2502 TEST_F(LayerTreeHostImplTopControlsTest
, FixedContainerDelta
) {
2503 SetupTopControlsAndScrollLayerWithVirtualViewport(
2504 gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
2507 float page_scale
= 1.5f
;
2508 LayerImpl
* outer_viewport_scroll_layer
=
2509 host_impl_
->active_tree()->OuterViewportScrollLayer();
2511 // Zoom in, since the fixed container is the outer viewport, the delta should
2513 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, 1.f
, 2.f
);
2515 EXPECT_EQ(InputHandler::ScrollStarted
,
2516 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2518 // Scroll down, the top controls hiding should expand the viewport size so
2519 // the delta should be equal to the scroll distance.
2520 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 20.f
);
2521 host_impl_
->top_controls_manager()->ScrollBegin();
2522 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2523 EXPECT_EQ(top_controls_height_
- top_controls_scroll_delta
.y(),
2524 host_impl_
->top_controls_manager()->ContentTopOffset());
2525 EXPECT_VECTOR_EQ(top_controls_scroll_delta
,
2526 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2527 host_impl_
->ScrollEnd();
2529 // Scroll past the maximum extent. The delta shouldn't be greater than the
2530 // top controls height.
2531 host_impl_
->top_controls_manager()->ScrollBegin();
2532 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2533 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2534 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2535 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2536 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_
),
2537 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2538 host_impl_
->ScrollEnd();
2540 // Scroll in the direction to make the top controls show.
2541 host_impl_
->top_controls_manager()->ScrollBegin();
2542 host_impl_
->top_controls_manager()->ScrollBy(-top_controls_scroll_delta
);
2543 EXPECT_EQ(top_controls_scroll_delta
.y(),
2544 host_impl_
->top_controls_manager()->ContentTopOffset());
2546 gfx::Vector2dF(0, top_controls_height_
- top_controls_scroll_delta
.y()),
2547 outer_viewport_scroll_layer
->FixedContainerSizeDelta());
2548 host_impl_
->top_controls_manager()->ScrollEnd();
2551 // Ensure setting the top controls position explicitly using the setters on the
2552 // TreeImpl correctly affects the top controls manager and viewport bounds.
2553 TEST_F(LayerTreeHostImplTopControlsTest
, PositionTopControlsExplicitly
) {
2554 CreateHostImpl(settings_
, CreateOutputSurface());
2555 SetupTopControlsAndScrollLayer();
2558 host_impl_
->active_tree()->set_top_controls_delta(0.f
);
2559 host_impl_
->active_tree()->set_top_controls_content_offset(30.f
);
2560 EXPECT_EQ(30.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2561 EXPECT_EQ(-20.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
2563 host_impl_
->active_tree()->set_top_controls_delta(-30.f
);
2564 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2565 EXPECT_EQ(-50.f
, host_impl_
->top_controls_manager()->ControlsTopOffset());
2567 host_impl_
->DidChangeTopControlsPosition();
2569 // Now that top controls have moved, expect the clip to resize.
2570 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2571 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2574 // Test that the top_controls delta and sent delta are appropriately
2575 // applied on sync tree activation. The total top controls offset shouldn't
2576 // change after the activation.
2577 TEST_F(LayerTreeHostImplTopControlsTest
, ApplyDeltaOnTreeActivation
) {
2578 CreateHostImpl(settings_
, CreateOutputSurface());
2579 SetupTopControlsAndScrollLayer();
2582 host_impl_
->sync_tree()->set_top_controls_content_offset(15.f
);
2584 host_impl_
->active_tree()->set_top_controls_content_offset(20.f
);
2585 host_impl_
->active_tree()->set_top_controls_delta(-20.f
);
2586 host_impl_
->active_tree()->set_sent_top_controls_delta(-5.f
);
2588 host_impl_
->DidChangeTopControlsPosition();
2589 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2590 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2591 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2593 host_impl_
->active_tree()->total_top_controls_content_offset());
2595 host_impl_
->ActivateSyncTree();
2597 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2598 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2599 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2601 EXPECT_EQ(0.f
, host_impl_
->active_tree()->sent_top_controls_delta());
2602 EXPECT_EQ(-15.f
, host_impl_
->active_tree()->top_controls_delta());
2603 EXPECT_EQ(15.f
, host_impl_
->active_tree()->top_controls_content_offset());
2605 host_impl_
->active_tree()->total_top_controls_content_offset());
2608 // Test that changing the top controls layout height is correctly applied to
2609 // the inner viewport container bounds. That is, the top controls layout
2610 // height is the amount that the inner viewport container was shrunk outside
2611 // the compositor to accommodate the top controls.
2612 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsLayoutHeightChanged
) {
2613 CreateHostImpl(settings_
, CreateOutputSurface());
2614 SetupTopControlsAndScrollLayer();
2617 host_impl_
->sync_tree()->set_top_controls_content_offset(50.f
);
2618 host_impl_
->sync_tree()->set_top_controls_shrink_blink_size(true);
2620 host_impl_
->active_tree()->set_top_controls_content_offset(50.f
);
2621 host_impl_
->active_tree()->set_top_controls_delta(-50.f
);
2623 host_impl_
->DidChangeTopControlsPosition();
2624 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2625 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2626 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2628 host_impl_
->sync_tree()->root_layer()->SetBounds(
2629 gfx::Size(root_clip_ptr
->bounds().width(),
2630 root_clip_ptr
->bounds().height() - 50.f
));
2632 host_impl_
->ActivateSyncTree();
2634 root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2635 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2637 // The total bounds should remain unchanged since the bounds delta should
2638 // account for the difference between the layout height and the current
2639 // top controls offset.
2640 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2641 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 50.f
), root_clip_ptr
->bounds_delta());
2643 host_impl_
->active_tree()->set_top_controls_delta(0.f
);
2644 host_impl_
->DidChangeTopControlsPosition();
2646 EXPECT_EQ(50.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2647 EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f
, 0.f
), root_clip_ptr
->bounds_delta());
2648 EXPECT_EQ(gfx::Size(viewport_size_
.width(), viewport_size_
.height() - 50.f
),
2649 root_clip_ptr
->bounds());
2652 // Test that showing/hiding the top controls when the viewport is fully scrolled
2653 // doesn't incorrectly change the viewport offset due to clamping from changing
2655 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsViewportOffsetClamping
) {
2656 SetupTopControlsAndScrollLayerWithVirtualViewport(
2657 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2660 EXPECT_EQ(top_controls_height_
,
2661 host_impl_
->active_tree()->total_top_controls_content_offset());
2663 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
2664 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
2666 // Scroll the viewports to max scroll offset.
2667 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2668 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2670 gfx::ScrollOffset viewport_offset
=
2671 host_impl_
->active_tree()->TotalScrollOffset();
2672 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(), viewport_offset
);
2674 // Hide the top controls by 25px.
2675 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2676 EXPECT_EQ(InputHandler::ScrollStarted
,
2677 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2678 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2680 // scrolling down at the max extents no longer hides the top controls
2682 top_controls_height_
-
2683 host_impl_
->active_tree()->total_top_controls_content_offset());
2685 // forcefully hide the top controls by 25px
2686 host_impl_
->top_controls_manager()->ScrollBy(scroll_delta
);
2687 host_impl_
->ScrollEnd();
2689 EXPECT_EQ(scroll_delta
.y(),
2690 top_controls_height_
-
2691 host_impl_
->active_tree()->total_top_controls_content_offset());
2693 inner_scroll
->ClampScrollToMaxScrollOffset();
2694 outer_scroll
->ClampScrollToMaxScrollOffset();
2696 // We should still be fully scrolled.
2697 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2698 host_impl_
->active_tree()->TotalScrollOffset());
2700 viewport_offset
= host_impl_
->active_tree()->TotalScrollOffset();
2702 // Bring the top controls down by 25px.
2703 scroll_delta
= gfx::Vector2dF(0.f
, -25.f
);
2704 EXPECT_EQ(InputHandler::ScrollStarted
,
2705 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2706 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2707 host_impl_
->ScrollEnd();
2709 // The viewport offset shouldn't have changed.
2710 EXPECT_EQ(viewport_offset
,
2711 host_impl_
->active_tree()->TotalScrollOffset());
2713 // Scroll the viewports to max scroll offset.
2714 outer_scroll
->SetScrollDelta(gfx::Vector2dF(0, 200.f
));
2715 inner_scroll
->SetScrollDelta(gfx::Vector2dF(100, 100.f
));
2716 EXPECT_EQ(host_impl_
->active_tree()->TotalMaxScrollOffset(),
2717 host_impl_
->active_tree()->TotalScrollOffset());
2720 // Test that the top controls coming in and out maintains the same aspect ratio
2721 // between the inner and outer viewports.
2722 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsAspectRatio
) {
2723 SetupTopControlsAndScrollLayerWithVirtualViewport(
2724 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2727 EXPECT_EQ(top_controls_height_
,
2728 host_impl_
->active_tree()->total_top_controls_content_offset());
2730 gfx::Vector2dF
scroll_delta(0.f
, 25.f
);
2731 EXPECT_EQ(InputHandler::ScrollStarted
,
2732 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2733 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2734 host_impl_
->ScrollEnd();
2736 EXPECT_EQ(scroll_delta
.y(),
2737 top_controls_height_
-
2738 host_impl_
->active_tree()->total_top_controls_content_offset());
2740 // Top controls were hidden by 25px so the inner viewport should have expanded
2742 LayerImpl
* outer_container
=
2743 host_impl_
->active_tree()->OuterViewportContainerLayer();
2744 LayerImpl
* inner_container
=
2745 host_impl_
->active_tree()->InnerViewportContainerLayer();
2746 EXPECT_EQ(gfx::Size(100, 100+25), inner_container
->BoundsForScrolling());
2748 // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
2749 float aspect_ratio
= inner_container
->BoundsForScrolling().width() /
2750 inner_container
->BoundsForScrolling().height();
2751 gfx::Size expected
= gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio
));
2752 EXPECT_EQ(expected
, outer_container
->BoundsForScrolling());
2754 host_impl_
->InnerViewportScrollLayer()->BoundsForScrolling());
2757 // Test that scrolling the outer viewport affects the top controls.
2758 TEST_F(LayerTreeHostImplTopControlsTest
, TopControlsScrollOuterViewport
) {
2759 SetupTopControlsAndScrollLayerWithVirtualViewport(
2760 gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2763 EXPECT_EQ(top_controls_height_
,
2764 host_impl_
->active_tree()->total_top_controls_content_offset());
2766 // Send a gesture scroll that will scroll the outer viewport, make sure the
2767 // top controls get scrolled.
2768 gfx::Vector2dF
scroll_delta(0.f
, 15.f
);
2769 EXPECT_EQ(InputHandler::ScrollStarted
,
2770 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2771 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2772 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
2773 host_impl_
->CurrentlyScrollingLayer());
2774 host_impl_
->ScrollEnd();
2776 EXPECT_EQ(scroll_delta
.y(),
2777 top_controls_height_
-
2778 host_impl_
->active_tree()->total_top_controls_content_offset());
2780 scroll_delta
= gfx::Vector2dF(0.f
, 50.f
);
2781 EXPECT_EQ(InputHandler::ScrollStarted
,
2782 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2783 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2785 EXPECT_EQ(0, host_impl_
->active_tree()->total_top_controls_content_offset());
2786 EXPECT_EQ(host_impl_
->OuterViewportScrollLayer(),
2787 host_impl_
->CurrentlyScrollingLayer());
2789 host_impl_
->ScrollEnd();
2791 // Position the viewports such that the inner viewport will be scrolled.
2792 gfx::Vector2dF
inner_viewport_offset(0.f
, 25.f
);
2793 host_impl_
->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2dF());
2794 host_impl_
->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset
);
2796 scroll_delta
= gfx::Vector2dF(0.f
, -65.f
);
2797 EXPECT_EQ(InputHandler::ScrollStarted
,
2798 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2799 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2801 EXPECT_EQ(top_controls_height_
,
2802 host_impl_
->active_tree()->total_top_controls_content_offset());
2804 inner_viewport_offset
.y() + (scroll_delta
.y() + top_controls_height_
),
2805 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
2807 host_impl_
->ScrollEnd();
2810 TEST_F(LayerTreeHostImplTopControlsTest
,
2811 ScrollNonScrollableRootWithTopControls
) {
2812 CreateHostImpl(settings_
, CreateOutputSurface());
2813 SetupTopControlsAndScrollLayer();
2816 EXPECT_EQ(InputHandler::ScrollStarted
,
2817 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2819 host_impl_
->top_controls_manager()->ScrollBegin();
2820 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2821 host_impl_
->top_controls_manager()->ScrollEnd();
2822 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->ContentTopOffset());
2823 // Now that top controls have moved, expect the clip to resize.
2824 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2825 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2827 host_impl_
->ScrollEnd();
2829 EXPECT_EQ(InputHandler::ScrollStarted
,
2830 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2832 float scroll_increment_y
= -25.f
;
2833 host_impl_
->top_controls_manager()->ScrollBegin();
2834 host_impl_
->top_controls_manager()->ScrollBy(
2835 gfx::Vector2dF(0.f
, scroll_increment_y
));
2836 EXPECT_EQ(-scroll_increment_y
,
2837 host_impl_
->top_controls_manager()->ContentTopOffset());
2838 // Now that top controls have moved, expect the clip to resize.
2839 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2840 viewport_size_
.height() + scroll_increment_y
),
2841 root_clip_ptr
->bounds());
2843 host_impl_
->top_controls_manager()->ScrollBy(
2844 gfx::Vector2dF(0.f
, scroll_increment_y
));
2845 host_impl_
->top_controls_manager()->ScrollEnd();
2846 EXPECT_EQ(-2 * scroll_increment_y
,
2847 host_impl_
->top_controls_manager()->ContentTopOffset());
2848 // Now that top controls have moved, expect the clip to resize.
2849 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2851 host_impl_
->ScrollEnd();
2853 // Verify the layer is once-again non-scrollable.
2855 gfx::ScrollOffset(),
2856 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2858 EXPECT_EQ(InputHandler::ScrollStarted
,
2859 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2862 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2863 // Test the configuration where a non-composited root layer is embedded in a
2864 // scrollable outer layer.
2865 gfx::Size
surface_size(10, 10);
2866 gfx::Size
contents_size(20, 20);
2868 scoped_ptr
<LayerImpl
> content_layer
=
2869 LayerImpl::Create(host_impl_
->active_tree(), 1);
2870 content_layer
->SetDrawsContent(true);
2871 content_layer
->SetPosition(gfx::PointF());
2872 content_layer
->SetBounds(contents_size
);
2873 content_layer
->SetContentBounds(contents_size
);
2874 content_layer
->SetContentsScale(2.f
, 2.f
);
2876 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2877 LayerImpl::Create(host_impl_
->active_tree(), 3);
2878 scroll_clip_layer
->SetBounds(surface_size
);
2880 scoped_ptr
<LayerImpl
> scroll_layer
=
2881 LayerImpl::Create(host_impl_
->active_tree(), 2);
2882 scroll_layer
->SetScrollClipLayer(3);
2883 scroll_layer
->SetBounds(contents_size
);
2884 scroll_layer
->SetContentBounds(contents_size
);
2885 scroll_layer
->SetPosition(gfx::PointF());
2886 scroll_layer
->AddChild(content_layer
.Pass());
2887 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2889 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2890 host_impl_
->SetViewportSize(surface_size
);
2893 EXPECT_EQ(InputHandler::ScrollStarted
,
2894 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2895 InputHandler::Wheel
));
2896 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2897 host_impl_
->ScrollEnd();
2898 EXPECT_TRUE(did_request_redraw_
);
2899 EXPECT_TRUE(did_request_commit_
);
2902 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2903 gfx::Size
surface_size(10, 10);
2904 gfx::Size
contents_size(20, 20);
2905 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2906 root
->SetBounds(surface_size
);
2907 root
->SetContentBounds(contents_size
);
2908 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2909 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2910 host_impl_
->SetViewportSize(surface_size
);
2913 EXPECT_EQ(InputHandler::ScrollStarted
,
2914 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2915 InputHandler::Wheel
));
2916 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2917 host_impl_
->ScrollEnd();
2918 EXPECT_TRUE(did_request_redraw_
);
2919 EXPECT_TRUE(did_request_commit_
);
2922 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2923 gfx::Size
surface_size(10, 10);
2924 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2925 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2926 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2927 host_impl_
->SetViewportSize(surface_size
);
2930 // Scroll event is ignored because the input coordinate is outside the layer
2932 EXPECT_EQ(InputHandler::ScrollIgnored
,
2933 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2934 InputHandler::Wheel
));
2935 EXPECT_FALSE(did_request_redraw_
);
2936 EXPECT_FALSE(did_request_commit_
);
2939 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2940 gfx::Size
surface_size(10, 10);
2941 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2942 scoped_ptr
<LayerImpl
> child
=
2943 CreateScrollableLayer(2, surface_size
, root
.get());
2944 host_impl_
->SetViewportSize(surface_size
);
2946 gfx::Transform matrix
;
2947 matrix
.RotateAboutXAxis(180.0);
2948 child
->SetTransform(matrix
);
2949 child
->SetDoubleSided(false);
2951 root
->AddChild(child
.Pass());
2952 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2955 // Scroll event is ignored because the scrollable layer is not facing the
2956 // viewer and there is nothing scrollable behind it.
2957 EXPECT_EQ(InputHandler::ScrollIgnored
,
2958 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2959 InputHandler::Wheel
));
2960 EXPECT_FALSE(did_request_redraw_
);
2961 EXPECT_FALSE(did_request_commit_
);
2964 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2965 gfx::Size
surface_size(10, 10);
2966 scoped_ptr
<LayerImpl
> clip_layer
=
2967 LayerImpl::Create(host_impl_
->active_tree(), 3);
2968 scoped_ptr
<LayerImpl
> content_layer
=
2969 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2970 content_layer
->SetShouldScrollOnMainThread(true);
2971 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2973 // Note: we can use the same clip layer for both since both calls to
2974 // CreateScrollableLayer() use the same surface size.
2975 scoped_ptr
<LayerImpl
> scroll_layer
=
2976 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2977 scroll_layer
->AddChild(content_layer
.Pass());
2978 clip_layer
->AddChild(scroll_layer
.Pass());
2980 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2981 host_impl_
->SetViewportSize(surface_size
);
2984 // Scrolling fails because the content layer is asking to be scrolled on the
2986 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2987 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2988 InputHandler::Wheel
));
2991 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2992 gfx::Size
surface_size(20, 20);
2993 gfx::Size
viewport_size(10, 10);
2994 float page_scale
= 2.f
;
2995 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2996 scoped_ptr
<LayerImpl
> root_clip
=
2997 LayerImpl::Create(host_impl_
->active_tree(), 2);
2998 scoped_ptr
<LayerImpl
> root_scrolling
=
2999 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3000 EXPECT_EQ(viewport_size
, root_clip
->bounds());
3001 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3002 root_clip
->AddChild(root_scrolling
.Pass());
3003 root
->AddChild(root_clip
.Pass());
3004 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3005 // The behaviour in this test assumes the page scale is applied at a layer
3006 // above the clip layer.
3007 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 3,
3009 host_impl_
->active_tree()->DidBecomeActive();
3010 host_impl_
->SetViewportSize(viewport_size
);
3013 LayerImpl
* root_scroll
=
3014 host_impl_
->active_tree()->InnerViewportScrollLayer();
3015 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
3017 gfx::Vector2d
scroll_delta(0, 10);
3018 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
3019 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
3020 EXPECT_EQ(InputHandler::ScrollStarted
,
3021 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3022 InputHandler::Wheel
));
3023 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3024 host_impl_
->ScrollEnd();
3026 // Set new page scale from main thread.
3027 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, page_scale
,
3030 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3031 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
3033 // The scroll range should also have been updated.
3034 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
3036 // The page scale delta remains constant because the impl thread did not
3038 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
3041 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
3042 gfx::Size
surface_size(20, 20);
3043 gfx::Size
viewport_size(10, 10);
3044 float page_scale
= 2.f
;
3045 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3046 scoped_ptr
<LayerImpl
> root_clip
=
3047 LayerImpl::Create(host_impl_
->active_tree(), 2);
3048 scoped_ptr
<LayerImpl
> root_scrolling
=
3049 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3050 EXPECT_EQ(viewport_size
, root_clip
->bounds());
3051 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3052 root_clip
->AddChild(root_scrolling
.Pass());
3053 root
->AddChild(root_clip
.Pass());
3054 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3055 // The behaviour in this test assumes the page scale is applied at a layer
3056 // above the clip layer.
3057 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 3,
3059 host_impl_
->active_tree()->DidBecomeActive();
3060 host_impl_
->SetViewportSize(viewport_size
);
3061 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 1.f
, page_scale
);
3064 LayerImpl
* root_scroll
=
3065 host_impl_
->active_tree()->InnerViewportScrollLayer();
3066 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
3068 gfx::Vector2d
scroll_delta(0, 10);
3069 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
3070 gfx::ScrollOffset expected_max_scroll
= root_scroll
->MaxScrollOffset();
3071 EXPECT_EQ(InputHandler::ScrollStarted
,
3072 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3073 InputHandler::Wheel
));
3074 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3075 host_impl_
->ScrollEnd();
3077 // Set new page scale on impl thread by pinching.
3078 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3079 host_impl_
->PinchGestureBegin();
3080 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
3081 host_impl_
->PinchGestureEnd();
3082 host_impl_
->ScrollEnd();
3085 // The scroll delta is not scaled because the main thread did not scale.
3086 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3087 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
3089 // The scroll range should also have been updated.
3090 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
3092 // The page scale delta should match the new scale on the impl side.
3093 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->current_page_scale_factor());
3096 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
3097 gfx::Size
surface_size(10, 10);
3098 float default_page_scale
= 1.f
;
3099 gfx::Transform default_page_scale_matrix
;
3100 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
3102 float new_page_scale
= 2.f
;
3103 gfx::Transform new_page_scale_matrix
;
3104 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
3106 // Create a normal scrollable root layer and another scrollable child layer.
3107 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
3108 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3109 LayerImpl
* child
= scroll
->children()[0];
3111 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
3112 LayerImpl::Create(host_impl_
->active_tree(), 6);
3113 scoped_ptr
<LayerImpl
> scrollable_child
=
3114 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
3115 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
3116 child
->AddChild(scrollable_child_clip
.Pass());
3117 LayerImpl
* grand_child
= child
->children()[0];
3119 // Set new page scale on impl thread by pinching.
3120 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3121 host_impl_
->PinchGestureBegin();
3122 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
3123 host_impl_
->PinchGestureEnd();
3124 host_impl_
->ScrollEnd();
3127 EXPECT_EQ(1.f
, root
->contents_scale_x());
3128 EXPECT_EQ(1.f
, root
->contents_scale_y());
3129 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
3130 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
3131 EXPECT_EQ(1.f
, child
->contents_scale_x());
3132 EXPECT_EQ(1.f
, child
->contents_scale_y());
3133 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
3134 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
3136 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
3137 // the page scale delta on the root layer is applied hierarchically.
3138 LayerTreeHostImpl::FrameData frame
;
3139 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3140 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3141 host_impl_
->DidDrawAllLayers(frame
);
3143 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
3144 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
3145 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
3146 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
3147 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
3148 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
3149 EXPECT_EQ(new_page_scale
,
3150 grand_child
->draw_transform().matrix().getDouble(0, 0));
3151 EXPECT_EQ(new_page_scale
,
3152 grand_child
->draw_transform().matrix().getDouble(1, 1));
3155 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
3156 gfx::Size
surface_size(30, 30);
3157 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3158 root
->SetBounds(gfx::Size(5, 5));
3159 scoped_ptr
<LayerImpl
> root_scrolling
=
3160 LayerImpl::Create(host_impl_
->active_tree(), 2);
3161 root_scrolling
->SetBounds(surface_size
);
3162 root_scrolling
->SetContentBounds(surface_size
);
3163 root_scrolling
->SetScrollClipLayer(root
->id());
3164 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3165 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
3166 root
->AddChild(root_scrolling
.Pass());
3167 int child_scroll_layer_id
= 3;
3168 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
3169 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
3170 LayerImpl
* child
= child_scrolling
.get();
3171 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
3172 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3173 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3175 host_impl_
->active_tree()->DidBecomeActive();
3176 host_impl_
->SetViewportSize(surface_size
);
3179 gfx::Vector2d
scroll_delta(0, 10);
3180 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
3181 gfx::ScrollOffset
expected_max_scroll(child
->MaxScrollOffset());
3182 EXPECT_EQ(InputHandler::ScrollStarted
,
3183 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3184 InputHandler::Wheel
));
3185 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3186 host_impl_
->ScrollEnd();
3188 float page_scale
= 2.f
;
3189 host_impl_
->active_tree()->PushPageScaleFromMainThread(page_scale
, 1.f
,
3194 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3196 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
3198 // The scroll range should not have changed.
3199 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
3201 // The page scale delta remains constant because the impl thread did not
3203 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
3206 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
3207 // Scroll a child layer beyond its maximum scroll range and make sure the
3208 // parent layer is scrolled on the axis on which the child was unable to
3210 gfx::Size
surface_size(10, 10);
3211 gfx::Size
content_size(20, 20);
3212 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3213 root
->SetBounds(surface_size
);
3215 scoped_ptr
<LayerImpl
> grand_child
=
3216 CreateScrollableLayer(3, content_size
, root
.get());
3218 scoped_ptr
<LayerImpl
> child
=
3219 CreateScrollableLayer(2, content_size
, root
.get());
3220 LayerImpl
* grand_child_layer
= grand_child
.get();
3221 child
->AddChild(grand_child
.Pass());
3223 LayerImpl
* child_layer
= child
.get();
3224 root
->AddChild(child
.Pass());
3225 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3226 host_impl_
->active_tree()->DidBecomeActive();
3227 host_impl_
->SetViewportSize(surface_size
);
3228 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 5));
3229 child_layer
->SetScrollOffset(gfx::ScrollOffset(3, 0));
3233 gfx::Vector2d
scroll_delta(-8, -7);
3234 EXPECT_EQ(InputHandler::ScrollStarted
,
3235 host_impl_
->ScrollBegin(gfx::Point(),
3236 InputHandler::Wheel
));
3237 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3238 host_impl_
->ScrollEnd();
3240 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3241 host_impl_
->ProcessScrollDeltas();
3243 // The grand child should have scrolled up to its limit.
3244 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
3245 LayerImpl
* grand_child
= child
->children()[0];
3246 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
3248 // The child should have only scrolled on the other axis.
3249 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
3253 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
3254 // Scroll a child layer beyond its maximum scroll range and make sure the
3255 // the scroll doesn't bubble up to the parent layer.
3256 gfx::Size
surface_size(20, 20);
3257 gfx::Size
viewport_size(10, 10);
3258 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
3259 scoped_ptr
<LayerImpl
> root_scrolling
=
3260 CreateScrollableLayer(2, surface_size
, root
.get());
3261 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
3263 scoped_ptr
<LayerImpl
> grand_child
=
3264 CreateScrollableLayer(4, surface_size
, root
.get());
3266 scoped_ptr
<LayerImpl
> child
=
3267 CreateScrollableLayer(3, surface_size
, root
.get());
3268 LayerImpl
* grand_child_layer
= grand_child
.get();
3269 child
->AddChild(grand_child
.Pass());
3271 LayerImpl
* child_layer
= child
.get();
3272 root_scrolling
->AddChild(child
.Pass());
3273 root
->AddChild(root_scrolling
.Pass());
3274 EXPECT_EQ(viewport_size
, root
->bounds());
3275 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3276 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3278 host_impl_
->active_tree()->DidBecomeActive();
3279 host_impl_
->SetViewportSize(viewport_size
);
3281 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 2));
3282 child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 3));
3286 gfx::Vector2d
scroll_delta(0, -10);
3287 EXPECT_EQ(InputHandler::ScrollStarted
,
3288 host_impl_
->ScrollBegin(gfx::Point(),
3289 InputHandler::NonBubblingGesture
));
3290 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3291 host_impl_
->ScrollEnd();
3293 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3294 host_impl_
->ProcessScrollDeltas();
3296 // The grand child should have scrolled up to its limit.
3298 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
3299 LayerImpl
* grand_child
= child
->children()[0];
3300 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3302 // The child should not have scrolled.
3303 ExpectNone(*scroll_info
.get(), child
->id());
3305 // The next time we scroll we should only scroll the parent.
3306 scroll_delta
= gfx::Vector2d(0, -3);
3307 EXPECT_EQ(InputHandler::ScrollStarted
,
3308 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3309 InputHandler::NonBubblingGesture
));
3310 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3311 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3312 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
3313 host_impl_
->ScrollEnd();
3315 scroll_info
= host_impl_
->ProcessScrollDeltas();
3317 // The child should have scrolled up to its limit.
3318 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3320 // The grand child should not have scrolled.
3321 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
3323 // After scrolling the parent, another scroll on the opposite direction
3324 // should still scroll the child.
3325 scroll_delta
= gfx::Vector2d(0, 7);
3326 EXPECT_EQ(InputHandler::ScrollStarted
,
3327 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3328 InputHandler::NonBubblingGesture
));
3329 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3330 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3331 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
3332 host_impl_
->ScrollEnd();
3334 scroll_info
= host_impl_
->ProcessScrollDeltas();
3336 // The grand child should have scrolled.
3337 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
3339 // The child should not have scrolled.
3340 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
3343 // Scrolling should be adjusted from viewport space.
3344 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 2.f
, 2.f
);
3345 host_impl_
->SetPageScaleOnActiveTree(2.f
);
3347 scroll_delta
= gfx::Vector2d(0, -2);
3348 EXPECT_EQ(InputHandler::ScrollStarted
,
3349 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3350 InputHandler::NonBubblingGesture
));
3351 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
3352 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3353 host_impl_
->ScrollEnd();
3355 scroll_info
= host_impl_
->ProcessScrollDeltas();
3357 // Should have scrolled by half the amount in layer space (5 - 2/2)
3358 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
3361 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
3362 // When we try to scroll a non-scrollable child layer, the scroll delta
3363 // should be applied to one of its ancestors if possible.
3364 gfx::Size
surface_size(10, 10);
3365 gfx::Size
content_size(20, 20);
3366 scoped_ptr
<LayerImpl
> root_clip
=
3367 LayerImpl::Create(host_impl_
->active_tree(), 3);
3368 scoped_ptr
<LayerImpl
> root
=
3369 CreateScrollableLayer(1, content_size
, root_clip
.get());
3370 // Make 'root' the clip layer for child: since they have the same sizes the
3371 // child will have zero max_scroll_offset and scrolls will bubble.
3372 scoped_ptr
<LayerImpl
> child
=
3373 CreateScrollableLayer(2, content_size
, root
.get());
3374 child
->SetIsContainerForFixedPositionLayers(true);
3375 root
->SetBounds(content_size
);
3377 int root_scroll_id
= root
->id();
3378 root
->AddChild(child
.Pass());
3379 root_clip
->AddChild(root
.Pass());
3381 host_impl_
->SetViewportSize(surface_size
);
3382 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3383 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 2,
3385 host_impl_
->active_tree()->DidBecomeActive();
3388 gfx::Vector2d
scroll_delta(0, 4);
3389 EXPECT_EQ(InputHandler::ScrollStarted
,
3390 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3391 InputHandler::Wheel
));
3392 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3393 host_impl_
->ScrollEnd();
3395 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3396 host_impl_
->ProcessScrollDeltas();
3398 // Only the root scroll should have scrolled.
3399 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
3400 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
3404 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
3405 gfx::Size
surface_size(10, 10);
3406 scoped_ptr
<LayerImpl
> root_clip
=
3407 LayerImpl::Create(host_impl_
->active_tree(), 1);
3408 scoped_ptr
<LayerImpl
> root_scroll
=
3409 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3410 root_scroll
->SetIsContainerForFixedPositionLayers(true);
3411 root_clip
->AddChild(root_scroll
.Pass());
3412 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3413 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 1, 2,
3415 host_impl_
->active_tree()->DidBecomeActive();
3416 host_impl_
->SetViewportSize(surface_size
);
3418 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
3421 host_impl_
->active_tree()->DetachLayerTree();
3422 scoped_ptr
<LayerImpl
> root_clip2
=
3423 LayerImpl::Create(host_impl_
->active_tree(), 3);
3424 scoped_ptr
<LayerImpl
> root_scroll2
=
3425 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
3426 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
3427 root_clip2
->AddChild(root_scroll2
.Pass());
3428 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
3429 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 4,
3431 host_impl_
->active_tree()->DidBecomeActive();
3433 // Scrolling should still work even though we did not draw yet.
3434 EXPECT_EQ(InputHandler::ScrollStarted
,
3435 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3436 InputHandler::Wheel
));
3439 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
3440 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3442 // Rotate the root layer 90 degrees counter-clockwise about its center.
3443 gfx::Transform rotate_transform
;
3444 rotate_transform
.Rotate(-90.0);
3445 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
3447 gfx::Size
surface_size(50, 50);
3448 host_impl_
->SetViewportSize(surface_size
);
3451 // Scroll to the right in screen coordinates with a gesture.
3452 gfx::Vector2d
gesture_scroll_delta(10, 0);
3453 EXPECT_EQ(InputHandler::ScrollStarted
,
3454 host_impl_
->ScrollBegin(gfx::Point(),
3455 InputHandler::Gesture
));
3456 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3457 host_impl_
->ScrollEnd();
3459 // The layer should have scrolled down in its local coordinates.
3460 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3461 ExpectContains(*scroll_info
.get(),
3463 gfx::Vector2d(0, gesture_scroll_delta
.x()));
3465 // Reset and scroll down with the wheel.
3466 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3467 gfx::Vector2d
wheel_scroll_delta(0, 10);
3468 EXPECT_EQ(InputHandler::ScrollStarted
,
3469 host_impl_
->ScrollBegin(gfx::Point(),
3470 InputHandler::Wheel
));
3471 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3472 host_impl_
->ScrollEnd();
3474 // The layer should have scrolled down in its local coordinates.
3475 scroll_info
= host_impl_
->ProcessScrollDeltas();
3476 ExpectContains(*scroll_info
.get(),
3478 wheel_scroll_delta
);
3481 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
3482 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3483 int child_clip_layer_id
= 6;
3484 int child_layer_id
= 7;
3485 float child_layer_angle
= -20.f
;
3487 // Create a child layer that is rotated to a non-axis-aligned angle.
3488 scoped_ptr
<LayerImpl
> clip_layer
=
3489 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
3490 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
3491 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
3492 gfx::Transform rotate_transform
;
3493 rotate_transform
.Translate(-50.0, -50.0);
3494 rotate_transform
.Rotate(child_layer_angle
);
3495 rotate_transform
.Translate(50.0, 50.0);
3496 clip_layer
->SetTransform(rotate_transform
);
3498 // Only allow vertical scrolling.
3499 clip_layer
->SetBounds(
3500 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
3501 // The rotation depends on the layer's transform origin, and the child layer
3502 // is a different size than the clip, so make sure the clip layer's origin
3503 // lines up over the child.
3504 clip_layer
->SetTransformOrigin(gfx::Point3F(
3505 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
3506 LayerImpl
* child_ptr
= child
.get();
3507 clip_layer
->AddChild(child
.Pass());
3508 scroll_layer
->AddChild(clip_layer
.Pass());
3510 gfx::Size
surface_size(50, 50);
3511 host_impl_
->SetViewportSize(surface_size
);
3514 // Scroll down in screen coordinates with a gesture.
3515 gfx::Vector2d
gesture_scroll_delta(0, 10);
3516 EXPECT_EQ(InputHandler::ScrollStarted
,
3517 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3518 InputHandler::Gesture
));
3519 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3520 host_impl_
->ScrollEnd();
3522 // The child layer should have scrolled down in its local coordinates an
3523 // amount proportional to the angle between it and the input scroll delta.
3524 gfx::Vector2d
expected_scroll_delta(
3526 gesture_scroll_delta
.y() *
3527 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
3528 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3529 host_impl_
->ProcessScrollDeltas();
3530 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3532 // The root scroll layer should not have scrolled, because the input delta
3533 // was close to the layer's axis of movement.
3534 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
3537 // Now reset and scroll the same amount horizontally.
3538 child_ptr
->SetScrollDelta(gfx::Vector2dF());
3539 gfx::Vector2d
gesture_scroll_delta(10, 0);
3540 EXPECT_EQ(InputHandler::ScrollStarted
,
3541 host_impl_
->ScrollBegin(gfx::Point(1, 1),
3542 InputHandler::Gesture
));
3543 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
3544 host_impl_
->ScrollEnd();
3546 // The child layer should have scrolled down in its local coordinates an
3547 // amount proportional to the angle between it and the input scroll delta.
3548 gfx::Vector2d
expected_scroll_delta(
3550 -gesture_scroll_delta
.x() *
3551 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
3552 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
3553 host_impl_
->ProcessScrollDeltas();
3554 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
3556 // The root scroll layer should have scrolled more, since the input scroll
3557 // delta was mostly orthogonal to the child layer's vertical scroll axis.
3558 gfx::Vector2d
expected_root_scroll_delta(
3559 gesture_scroll_delta
.x() *
3560 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
3562 ExpectContains(*scroll_info
.get(),
3564 expected_root_scroll_delta
);
3568 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
3569 LayerImpl
* scroll_layer
=
3570 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3572 // Scale the layer to twice its normal size.
3574 gfx::Transform scale_transform
;
3575 scale_transform
.Scale(scale
, scale
);
3576 scroll_layer
->SetTransform(scale_transform
);
3578 gfx::Size
surface_size(50, 50);
3579 host_impl_
->SetViewportSize(surface_size
);
3582 // Scroll down in screen coordinates with a gesture.
3583 gfx::Vector2d
scroll_delta(0, 10);
3584 EXPECT_EQ(InputHandler::ScrollStarted
,
3585 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3586 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3587 host_impl_
->ScrollEnd();
3589 // The layer should have scrolled down in its local coordinates, but half the
3591 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3592 ExpectContains(*scroll_info
.get(),
3594 gfx::Vector2d(0, scroll_delta
.y() / scale
));
3596 // Reset and scroll down with the wheel.
3597 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3598 gfx::Vector2d
wheel_scroll_delta(0, 10);
3599 EXPECT_EQ(InputHandler::ScrollStarted
,
3600 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3601 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3602 host_impl_
->ScrollEnd();
3604 // It should apply the scale factor to the scroll delta for the wheel event.
3605 scroll_info
= host_impl_
->ProcessScrollDeltas();
3606 ExpectContains(*scroll_info
.get(),
3608 wheel_scroll_delta
);
3611 TEST_F(LayerTreeHostImplTest
, ScrollViewportRounding
) {
3615 SetupScrollAndContentsLayers(gfx::Size(width
, height
));
3616 host_impl_
->active_tree()->InnerViewportContainerLayer()->SetBounds(
3617 gfx::Size(width
* scale
- 1, height
* scale
));
3618 host_impl_
->SetDeviceScaleFactor(scale
);
3619 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
3621 LayerImpl
* inner_viewport_scroll_layer
=
3622 host_impl_
->active_tree()->InnerViewportScrollLayer();
3623 EXPECT_EQ(gfx::ScrollOffset(0, 0),
3624 inner_viewport_scroll_layer
->MaxScrollOffset());
3627 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3629 TestScrollOffsetDelegate()
3630 : page_scale_factor_(0.f
),
3631 min_page_scale_factor_(-1.f
),
3632 max_page_scale_factor_(-1.f
) {}
3634 ~TestScrollOffsetDelegate() override
{}
3636 gfx::ScrollOffset
GetTotalScrollOffset() override
{
3637 return getter_return_value_
;
3640 bool IsExternalFlingActive() const override
{ return false; }
3642 void UpdateRootLayerState(const gfx::ScrollOffset
& total_scroll_offset
,
3643 const gfx::ScrollOffset
& max_scroll_offset
,
3644 const gfx::SizeF
& scrollable_size
,
3645 float page_scale_factor
,
3646 float min_page_scale_factor
,
3647 float max_page_scale_factor
) override
{
3648 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3649 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3650 last_set_scroll_offset_
= total_scroll_offset
;
3651 max_scroll_offset_
= max_scroll_offset
;
3652 scrollable_size_
= scrollable_size
;
3653 page_scale_factor_
= page_scale_factor
;
3654 min_page_scale_factor_
= min_page_scale_factor
;
3655 max_page_scale_factor_
= max_page_scale_factor
;
3658 gfx::ScrollOffset
last_set_scroll_offset() {
3659 return last_set_scroll_offset_
;
3662 void set_getter_return_value(const gfx::ScrollOffset
& value
) {
3663 getter_return_value_
= value
;
3666 gfx::ScrollOffset
max_scroll_offset() const {
3667 return max_scroll_offset_
;
3670 gfx::SizeF
scrollable_size() const {
3671 return scrollable_size_
;
3674 float page_scale_factor() const {
3675 return page_scale_factor_
;
3678 float min_page_scale_factor() const {
3679 return min_page_scale_factor_
;
3682 float max_page_scale_factor() const {
3683 return max_page_scale_factor_
;
3687 gfx::ScrollOffset last_set_scroll_offset_
;
3688 gfx::ScrollOffset getter_return_value_
;
3689 gfx::ScrollOffset max_scroll_offset_
;
3690 gfx::SizeF scrollable_size_
;
3691 float page_scale_factor_
;
3692 float min_page_scale_factor_
;
3693 float max_page_scale_factor_
;
3696 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3697 TestScrollOffsetDelegate scroll_delegate
;
3698 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3699 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3700 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3701 clip_layer
->SetBounds(gfx::Size(10, 20));
3703 // Setting the delegate results in the current scroll offset being set.
3704 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3705 scroll_layer
->SetScrollOffset(gfx::ScrollOffset());
3706 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3707 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3708 EXPECT_EQ(initial_scroll_delta
.ToString(),
3709 scroll_delegate
.last_set_scroll_offset().ToString());
3711 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3712 // page_scale_factor and {min|max}_page_scale_factor being set.
3713 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3714 EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate
.max_scroll_offset());
3715 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3716 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3717 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3719 // Updating page scale immediately updates the delegate.
3720 host_impl_
->active_tree()->PushPageScaleFromMainThread(2.f
, 0.5f
, 4.f
);
3721 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3722 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3723 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3724 host_impl_
->SetPageScaleOnActiveTree(2.f
* 1.5f
);
3725 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3726 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3727 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3728 host_impl_
->SetPageScaleOnActiveTree(2.f
);
3729 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
3730 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3731 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3732 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3734 // The pinch gesture doesn't put the delegate into a state where the scroll
3735 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3737 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3738 host_impl_
->PinchGestureBegin();
3739 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3740 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3741 host_impl_
->PinchGestureEnd();
3742 host_impl_
->ScrollEnd();
3744 // Scrolling should be relative to the offset as returned by the delegate.
3745 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3746 gfx::ScrollOffset
current_offset(7.f
, 8.f
);
3748 scroll_delegate
.set_getter_return_value(current_offset
);
3749 EXPECT_EQ(InputHandler::ScrollStarted
,
3750 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3752 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3753 EXPECT_EQ(ScrollOffsetWithDelta(current_offset
, scroll_delta
),
3754 scroll_delegate
.last_set_scroll_offset());
3756 current_offset
= gfx::ScrollOffset(42.f
, 41.f
);
3757 scroll_delegate
.set_getter_return_value(current_offset
);
3758 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3759 EXPECT_EQ(current_offset
+ gfx::ScrollOffset(scroll_delta
),
3760 scroll_delegate
.last_set_scroll_offset());
3761 host_impl_
->ScrollEnd();
3762 scroll_delegate
.set_getter_return_value(gfx::ScrollOffset());
3764 // Forces a full tree synchronization and ensures that the scroll delegate
3765 // sees the correct size of the new tree.
3766 gfx::Size
new_size(42, 24);
3767 host_impl_
->CreatePendingTree();
3768 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3769 host_impl_
->ActivateSyncTree();
3770 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3772 // Un-setting the delegate should propagate the delegate's current offset to
3773 // the root scrollable layer.
3774 current_offset
= gfx::ScrollOffset(13.f
, 12.f
);
3775 scroll_delegate
.set_getter_return_value(current_offset
);
3776 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3778 EXPECT_EQ(current_offset
.ToString(),
3779 scroll_layer
->TotalScrollOffset().ToString());
3782 void CheckLayerScrollDelta(LayerImpl
* layer
, gfx::Vector2dF scroll_delta
) {
3783 const gfx::Transform target_space_transform
=
3784 layer
->draw_properties().target_space_transform
;
3785 EXPECT_TRUE(target_space_transform
.IsScaleOrTranslation());
3786 gfx::Point translated_point
;
3787 target_space_transform
.TransformPoint(&translated_point
);
3788 gfx::Point expected_point
= gfx::Point() - ToRoundedVector2d(scroll_delta
);
3789 EXPECT_EQ(expected_point
.ToString(), translated_point
.ToString());
3792 TEST_F(LayerTreeHostImplTest
,
3793 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw
) {
3794 TestScrollOffsetDelegate scroll_delegate
;
3795 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3796 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3797 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3798 clip_layer
->SetBounds(gfx::Size(10, 20));
3799 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3801 // Draw first frame to clear any pending draws and check scroll.
3803 CheckLayerScrollDelta(scroll_layer
, gfx::Vector2dF(0.f
, 0.f
));
3804 EXPECT_FALSE(host_impl_
->active_tree()->needs_update_draw_properties());
3806 // Set external scroll delta on delegate and notify LayerTreeHost.
3807 gfx::ScrollOffset
scroll_offset(10.f
, 10.f
);
3808 scroll_delegate
.set_getter_return_value(scroll_offset
);
3809 host_impl_
->OnRootLayerDelegatedScrollOffsetChanged();
3811 // Check scroll delta reflected in layer.
3812 LayerTreeHostImpl::FrameData frame
;
3813 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3814 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3815 host_impl_
->DidDrawAllLayers(frame
);
3816 EXPECT_FALSE(frame
.has_no_damage
);
3817 CheckLayerScrollDelta(scroll_layer
, ScrollOffsetToVector2dF(scroll_offset
));
3819 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3822 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3823 InputHandlerScrollResult scroll_result
;
3824 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3825 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3826 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
3828 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3830 // In-bounds scrolling does not affect overscroll.
3831 EXPECT_EQ(InputHandler::ScrollStarted
,
3832 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3833 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3834 EXPECT_TRUE(scroll_result
.did_scroll
);
3835 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
3836 EXPECT_EQ(gfx::Vector2dF(), scroll_result
.unused_scroll_delta
);
3837 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3839 // Overscroll events are reflected immediately.
3840 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3841 EXPECT_TRUE(scroll_result
.did_scroll
);
3842 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3843 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result
.unused_scroll_delta
);
3844 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3845 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3846 host_impl_
->accumulated_root_overscroll());
3848 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3849 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3850 EXPECT_TRUE(scroll_result
.did_scroll
);
3851 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
3852 EXPECT_EQ(gfx::Vector2dF(), scroll_result
.unused_scroll_delta
);
3853 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3854 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3855 host_impl_
->accumulated_root_overscroll());
3857 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3858 EXPECT_FALSE(scroll_result
.did_scroll
);
3859 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3860 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
3861 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3862 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3863 host_impl_
->accumulated_root_overscroll());
3865 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3866 EXPECT_TRUE(scroll_result
.did_scroll
);
3867 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
3868 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result
.unused_scroll_delta
);
3869 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3870 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3871 host_impl_
->accumulated_root_overscroll());
3873 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3874 EXPECT_TRUE(scroll_result
.did_scroll
);
3875 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3876 EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result
.unused_scroll_delta
);
3877 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3878 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3879 host_impl_
->accumulated_root_overscroll());
3881 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3882 EXPECT_TRUE(scroll_result
.did_scroll
);
3883 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3884 EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result
.unused_scroll_delta
);
3885 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3886 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3887 host_impl_
->accumulated_root_overscroll());
3889 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3890 EXPECT_TRUE(scroll_result
.did_scroll
);
3891 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3892 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
3893 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3894 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3895 host_impl_
->accumulated_root_overscroll());
3897 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3898 // as no scroll occurs.
3899 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3900 EXPECT_FALSE(scroll_result
.did_scroll
);
3901 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3902 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result
.unused_scroll_delta
);
3903 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3904 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3905 host_impl_
->accumulated_root_overscroll());
3907 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3908 EXPECT_FALSE(scroll_result
.did_scroll
);
3909 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3910 EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result
.unused_scroll_delta
);
3911 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3912 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3913 host_impl_
->accumulated_root_overscroll());
3915 // Overscroll resets on valid scroll.
3916 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3917 EXPECT_TRUE(scroll_result
.did_scroll
);
3918 EXPECT_FALSE(scroll_result
.did_overscroll_root
);
3919 EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result
.unused_scroll_delta
);
3920 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3921 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3922 host_impl_
->accumulated_root_overscroll());
3924 scroll_result
= host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3925 EXPECT_TRUE(scroll_result
.did_scroll
);
3926 EXPECT_TRUE(scroll_result
.did_overscroll_root
);
3927 EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result
.unused_scroll_delta
);
3928 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3929 EXPECT_EQ(scroll_result
.accumulated_root_overscroll
,
3930 host_impl_
->accumulated_root_overscroll());
3932 host_impl_
->ScrollEnd();
3936 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3937 // Scroll child layers beyond their maximum scroll range and make sure root
3938 // overscroll does not accumulate.
3939 gfx::Size
surface_size(10, 10);
3940 scoped_ptr
<LayerImpl
> root_clip
=
3941 LayerImpl::Create(host_impl_
->active_tree(), 4);
3942 scoped_ptr
<LayerImpl
> root
=
3943 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3945 scoped_ptr
<LayerImpl
> grand_child
=
3946 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3948 scoped_ptr
<LayerImpl
> child
=
3949 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3950 LayerImpl
* grand_child_layer
= grand_child
.get();
3951 child
->AddChild(grand_child
.Pass());
3953 LayerImpl
* child_layer
= child
.get();
3954 root
->AddChild(child
.Pass());
3955 root_clip
->AddChild(root
.Pass());
3956 child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 3));
3957 grand_child_layer
->SetScrollOffset(gfx::ScrollOffset(0, 2));
3958 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3959 host_impl_
->active_tree()->DidBecomeActive();
3960 host_impl_
->SetViewportSize(surface_size
);
3963 gfx::Vector2d
scroll_delta(0, -10);
3964 EXPECT_EQ(InputHandler::ScrollStarted
,
3965 host_impl_
->ScrollBegin(gfx::Point(),
3966 InputHandler::NonBubblingGesture
));
3967 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3968 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3969 host_impl_
->ScrollEnd();
3971 // The next time we scroll we should only scroll the parent, but overscroll
3972 // should still not reach the root layer.
3973 scroll_delta
= gfx::Vector2d(0, -30);
3974 EXPECT_EQ(InputHandler::ScrollStarted
,
3975 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3976 InputHandler::NonBubblingGesture
));
3977 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3978 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3979 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3980 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3981 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3982 host_impl_
->ScrollEnd();
3984 // After scrolling the parent, another scroll on the opposite direction
3985 // should scroll the child.
3986 scroll_delta
= gfx::Vector2d(0, 70);
3987 EXPECT_EQ(InputHandler::ScrollStarted
,
3988 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3989 InputHandler::NonBubblingGesture
));
3990 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3991 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3992 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3993 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3994 host_impl_
->ScrollEnd();
3998 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3999 // When we try to scroll a non-scrollable child layer, the scroll delta
4000 // should be applied to one of its ancestors if possible. Overscroll should
4001 // be reflected only when it has bubbled up to the root scrolling layer.
4002 gfx::Size
surface_size(10, 10);
4003 gfx::Size
content_size(20, 20);
4004 scoped_ptr
<LayerImpl
> root_clip
=
4005 LayerImpl::Create(host_impl_
->active_tree(), 3);
4006 scoped_ptr
<LayerImpl
> root
=
4007 CreateScrollableLayer(1, content_size
, root_clip
.get());
4008 root
->SetIsContainerForFixedPositionLayers(true);
4009 scoped_ptr
<LayerImpl
> child
=
4010 CreateScrollableLayer(2, content_size
, root_clip
.get());
4012 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4013 root
->AddChild(child
.Pass());
4014 root_clip
->AddChild(root
.Pass());
4016 host_impl_
->SetViewportSize(surface_size
);
4017 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4018 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4020 host_impl_
->active_tree()->DidBecomeActive();
4023 gfx::Vector2d
scroll_delta(0, 8);
4024 EXPECT_EQ(InputHandler::ScrollStarted
,
4025 host_impl_
->ScrollBegin(gfx::Point(5, 5),
4026 InputHandler::Wheel
));
4027 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4028 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4029 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4030 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
4031 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
4032 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
4033 host_impl_
->ScrollEnd();
4037 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
4038 LayerTreeSettings settings
;
4039 CreateHostImpl(settings
, CreateOutputSurface());
4041 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
4042 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
4043 clip_layer
->SetBounds(gfx::Size(50, 50));
4044 host_impl_
->SetViewportSize(gfx::Size(50, 50));
4045 host_impl_
->active_tree()->PushPageScaleFromMainThread(1.f
, 0.5f
, 4.f
);
4047 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
4049 // Even though the layer can't scroll the overscroll still happens.
4050 EXPECT_EQ(InputHandler::ScrollStarted
,
4051 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
4052 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
4053 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
4056 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
4057 gfx::Size
surface_size(980, 1439);
4058 gfx::Size
content_size(980, 1438);
4059 float device_scale_factor
= 1.5f
;
4060 scoped_ptr
<LayerImpl
> root_clip
=
4061 LayerImpl::Create(host_impl_
->active_tree(), 3);
4062 scoped_ptr
<LayerImpl
> root
=
4063 CreateScrollableLayer(1, content_size
, root_clip
.get());
4064 root
->SetIsContainerForFixedPositionLayers(true);
4065 scoped_ptr
<LayerImpl
> child
=
4066 CreateScrollableLayer(2, content_size
, root_clip
.get());
4067 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
4068 host_impl_
->active_tree()->PushPageScaleFromMainThread(0.326531f
, 0.326531f
,
4070 host_impl_
->SetPageScaleOnActiveTree(0.326531f
);
4071 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4072 root
->AddChild(child
.Pass());
4073 root_clip
->AddChild(root
.Pass());
4075 host_impl_
->SetViewportSize(surface_size
);
4076 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4077 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4078 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4080 host_impl_
->active_tree()->DidBecomeActive();
4083 // Horizontal & Vertical GlowEffect should not be applied when
4084 // content size is less then view port size. For Example Horizontal &
4085 // vertical GlowEffect should not be applied in about:blank page.
4086 EXPECT_EQ(InputHandler::ScrollStarted
,
4087 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
4088 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
4089 EXPECT_EQ(gfx::Vector2dF().ToString(),
4090 host_impl_
->accumulated_root_overscroll().ToString());
4092 host_impl_
->ScrollEnd();
4096 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
4097 gfx::Size
surface_size(100, 100);
4098 gfx::Size
content_size(200, 200);
4099 scoped_ptr
<LayerImpl
> root_clip
=
4100 LayerImpl::Create(host_impl_
->active_tree(), 3);
4101 scoped_ptr
<LayerImpl
> root
=
4102 CreateScrollableLayer(1, content_size
, root_clip
.get());
4103 root
->SetIsContainerForFixedPositionLayers(true);
4104 scoped_ptr
<LayerImpl
> child
=
4105 CreateScrollableLayer(2, content_size
, root_clip
.get());
4107 child
->SetScrollClipLayer(Layer::INVALID_ID
);
4108 root
->AddChild(child
.Pass());
4109 root_clip
->AddChild(root
.Pass());
4111 host_impl_
->SetViewportSize(surface_size
);
4112 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
4113 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
4115 host_impl_
->active_tree()->DidBecomeActive();
4118 // Edge glow effect should be applicable only upon reaching Edges
4119 // of the content. unnecessary glow effect calls shouldn't be
4120 // called while scrolling up without reaching the edge of the content.
4121 EXPECT_EQ(InputHandler::ScrollStarted
,
4122 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
4123 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
4124 EXPECT_EQ(gfx::Vector2dF().ToString(),
4125 host_impl_
->accumulated_root_overscroll().ToString());
4126 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
4127 EXPECT_EQ(gfx::Vector2dF().ToString(),
4128 host_impl_
->accumulated_root_overscroll().ToString());
4129 host_impl_
->ScrollEnd();
4130 // unusedrootDelta should be subtracted from applied delta so that
4131 // unwanted glow effect calls are not called.
4132 EXPECT_EQ(InputHandler::ScrollStarted
,
4133 host_impl_
->ScrollBegin(gfx::Point(0, 0),
4134 InputHandler::NonBubblingGesture
));
4135 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
4136 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
4137 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
4138 host_impl_
->accumulated_root_overscroll().ToString());
4140 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
4141 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
4142 host_impl_
->accumulated_root_overscroll().ToString());
4143 host_impl_
->ScrollEnd();
4144 // TestCase to check kEpsilon, which prevents minute values to trigger
4145 // gloweffect without reaching edge.
4146 EXPECT_EQ(InputHandler::ScrollStarted
,
4147 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
4148 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
4149 EXPECT_EQ(gfx::Vector2dF().ToString(),
4150 host_impl_
->accumulated_root_overscroll().ToString());
4151 host_impl_
->ScrollEnd();
4155 class BlendStateCheckLayer
: public LayerImpl
{
4157 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4159 ResourceProvider
* resource_provider
) {
4160 return make_scoped_ptr(
4161 new BlendStateCheckLayer(tree_impl
, id
, resource_provider
));
4164 void AppendQuads(RenderPass
* render_pass
,
4165 const Occlusion
& occlusion_in_content_space
,
4166 AppendQuadsData
* append_quads_data
) override
{
4167 quads_appended_
= true;
4169 gfx::Rect opaque_rect
;
4170 if (contents_opaque())
4171 opaque_rect
= quad_rect_
;
4173 opaque_rect
= opaque_content_rect_
;
4174 gfx::Rect visible_quad_rect
= quad_rect_
;
4176 SharedQuadState
* shared_quad_state
=
4177 render_pass
->CreateAndAppendSharedQuadState();
4178 PopulateSharedQuadState(shared_quad_state
);
4180 TileDrawQuad
* test_blending_draw_quad
=
4181 render_pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
4182 test_blending_draw_quad
->SetNew(shared_quad_state
,
4187 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
4190 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
4191 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
4192 EXPECT_EQ(has_render_surface_
, !!render_surface());
4195 void SetExpectation(bool blend
, bool has_render_surface
) {
4197 has_render_surface_
= has_render_surface
;
4198 quads_appended_
= false;
4201 bool quads_appended() const { return quads_appended_
; }
4203 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
4204 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
4205 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
4206 opaque_content_rect_
= rect
;
4210 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
4212 ResourceProvider
* resource_provider
)
4213 : LayerImpl(tree_impl
, id
),
4215 has_render_surface_(false),
4216 quads_appended_(false),
4217 quad_rect_(5, 5, 5, 5),
4218 quad_visible_rect_(5, 5, 5, 5),
4219 resource_id_(resource_provider
->CreateResource(
4222 ResourceProvider::TextureHintImmutable
,
4224 resource_provider
->AllocateForTesting(resource_id_
);
4225 SetBounds(gfx::Size(10, 10));
4226 SetContentBounds(gfx::Size(10, 10));
4227 SetDrawsContent(true);
4231 bool has_render_surface_
;
4232 bool quads_appended_
;
4233 gfx::Rect quad_rect_
;
4234 gfx::Rect opaque_content_rect_
;
4235 gfx::Rect quad_visible_rect_
;
4236 ResourceProvider::ResourceId resource_id_
;
4239 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
4241 scoped_ptr
<LayerImpl
> root
=
4242 LayerImpl::Create(host_impl_
->active_tree(), 1);
4243 root
->SetBounds(gfx::Size(10, 10));
4244 root
->SetContentBounds(root
->bounds());
4245 root
->SetDrawsContent(false);
4246 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4248 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4251 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4253 host_impl_
->resource_provider()));
4254 BlendStateCheckLayer
* layer1
=
4255 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
4256 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
4258 LayerTreeHostImpl::FrameData frame
;
4260 // Opaque layer, drawn without blending.
4261 layer1
->SetContentsOpaque(true);
4262 layer1
->SetExpectation(false, false);
4263 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4264 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4265 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4266 EXPECT_TRUE(layer1
->quads_appended());
4267 host_impl_
->DidDrawAllLayers(frame
);
4269 // Layer with translucent content and painting, so drawn with blending.
4270 layer1
->SetContentsOpaque(false);
4271 layer1
->SetExpectation(true, false);
4272 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4273 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4274 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4275 EXPECT_TRUE(layer1
->quads_appended());
4276 host_impl_
->DidDrawAllLayers(frame
);
4278 // Layer with translucent opacity, drawn with blending.
4279 layer1
->SetContentsOpaque(true);
4280 layer1
->SetOpacity(0.5f
);
4281 layer1
->SetExpectation(true, false);
4282 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4283 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4284 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4285 EXPECT_TRUE(layer1
->quads_appended());
4286 host_impl_
->DidDrawAllLayers(frame
);
4288 // Layer with translucent opacity and painting, drawn with blending.
4289 layer1
->SetContentsOpaque(true);
4290 layer1
->SetOpacity(0.5f
);
4291 layer1
->SetExpectation(true, false);
4292 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4293 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4294 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4295 EXPECT_TRUE(layer1
->quads_appended());
4296 host_impl_
->DidDrawAllLayers(frame
);
4299 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4301 host_impl_
->resource_provider()));
4302 BlendStateCheckLayer
* layer2
=
4303 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
4304 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
4306 // 2 opaque layers, drawn without blending.
4307 layer1
->SetContentsOpaque(true);
4308 layer1
->SetOpacity(1.f
);
4309 layer1
->SetExpectation(false, false);
4310 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4311 layer2
->SetContentsOpaque(true);
4312 layer2
->SetOpacity(1.f
);
4313 layer2
->SetExpectation(false, false);
4314 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4315 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4316 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4317 EXPECT_TRUE(layer1
->quads_appended());
4318 EXPECT_TRUE(layer2
->quads_appended());
4319 host_impl_
->DidDrawAllLayers(frame
);
4321 // Parent layer with translucent content, drawn with blending.
4322 // Child layer with opaque content, drawn without blending.
4323 layer1
->SetContentsOpaque(false);
4324 layer1
->SetExpectation(true, false);
4325 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4326 layer2
->SetExpectation(false, false);
4327 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4328 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4329 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4330 EXPECT_TRUE(layer1
->quads_appended());
4331 EXPECT_TRUE(layer2
->quads_appended());
4332 host_impl_
->DidDrawAllLayers(frame
);
4334 // Parent layer with translucent content but opaque painting, drawn without
4336 // Child layer with opaque content, drawn without blending.
4337 layer1
->SetContentsOpaque(true);
4338 layer1
->SetExpectation(false, false);
4339 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4340 layer2
->SetExpectation(false, false);
4341 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4342 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4343 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4344 EXPECT_TRUE(layer1
->quads_appended());
4345 EXPECT_TRUE(layer2
->quads_appended());
4346 host_impl_
->DidDrawAllLayers(frame
);
4348 // Parent layer with translucent opacity and opaque content. Since it has a
4349 // drawing child, it's drawn to a render surface which carries the opacity,
4350 // so it's itself drawn without blending.
4351 // Child layer with opaque content, drawn without blending (parent surface
4352 // carries the inherited opacity).
4353 layer1
->SetContentsOpaque(true);
4354 layer1
->SetOpacity(0.5f
);
4355 layer1
->SetExpectation(false, true);
4356 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4357 layer2
->SetExpectation(false, false);
4358 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4359 FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
4360 host_impl_
->active_tree()->root_layer());
4361 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4362 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4363 EXPECT_TRUE(layer1
->quads_appended());
4364 EXPECT_TRUE(layer2
->quads_appended());
4365 host_impl_
->DidDrawAllLayers(frame
);
4367 // Draw again, but with child non-opaque, to make sure
4368 // layer1 not culled.
4369 layer1
->SetContentsOpaque(true);
4370 layer1
->SetOpacity(1.f
);
4371 layer1
->SetExpectation(false, false);
4372 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4373 layer2
->SetContentsOpaque(true);
4374 layer2
->SetOpacity(0.5f
);
4375 layer2
->SetExpectation(true, false);
4376 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4377 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4378 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4379 EXPECT_TRUE(layer1
->quads_appended());
4380 EXPECT_TRUE(layer2
->quads_appended());
4381 host_impl_
->DidDrawAllLayers(frame
);
4383 // A second way of making the child non-opaque.
4384 layer1
->SetContentsOpaque(true);
4385 layer1
->SetOpacity(1.f
);
4386 layer1
->SetExpectation(false, false);
4387 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4388 layer2
->SetContentsOpaque(false);
4389 layer2
->SetOpacity(1.f
);
4390 layer2
->SetExpectation(true, false);
4391 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4392 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4393 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4394 EXPECT_TRUE(layer1
->quads_appended());
4395 EXPECT_TRUE(layer2
->quads_appended());
4396 host_impl_
->DidDrawAllLayers(frame
);
4398 // And when the layer says its not opaque but is painted opaque, it is not
4400 layer1
->SetContentsOpaque(true);
4401 layer1
->SetOpacity(1.f
);
4402 layer1
->SetExpectation(false, false);
4403 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4404 layer2
->SetContentsOpaque(true);
4405 layer2
->SetOpacity(1.f
);
4406 layer2
->SetExpectation(false, false);
4407 layer2
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4408 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4409 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4410 EXPECT_TRUE(layer1
->quads_appended());
4411 EXPECT_TRUE(layer2
->quads_appended());
4412 host_impl_
->DidDrawAllLayers(frame
);
4414 // Layer with partially opaque contents, drawn with blending.
4415 layer1
->SetContentsOpaque(false);
4416 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4417 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
4418 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4419 layer1
->SetExpectation(true, false);
4420 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4421 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4422 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4423 EXPECT_TRUE(layer1
->quads_appended());
4424 host_impl_
->DidDrawAllLayers(frame
);
4426 // Layer with partially opaque contents partially culled, drawn with blending.
4427 layer1
->SetContentsOpaque(false);
4428 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4429 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
4430 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4431 layer1
->SetExpectation(true, false);
4432 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4433 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4434 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4435 EXPECT_TRUE(layer1
->quads_appended());
4436 host_impl_
->DidDrawAllLayers(frame
);
4438 // Layer with partially opaque contents culled, drawn with blending.
4439 layer1
->SetContentsOpaque(false);
4440 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4441 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
4442 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4443 layer1
->SetExpectation(true, false);
4444 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4445 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4446 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4447 EXPECT_TRUE(layer1
->quads_appended());
4448 host_impl_
->DidDrawAllLayers(frame
);
4450 // Layer with partially opaque contents and translucent contents culled, drawn
4451 // without blending.
4452 layer1
->SetContentsOpaque(false);
4453 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4454 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
4455 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4456 layer1
->SetExpectation(false, false);
4457 layer1
->SetUpdateRect(gfx::Rect(layer1
->content_bounds()));
4458 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4459 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4460 EXPECT_TRUE(layer1
->quads_appended());
4461 host_impl_
->DidDrawAllLayers(frame
);
4464 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
4466 LayerTreeHostImplViewportCoveredTest() :
4467 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
4469 did_activate_pending_tree_(false) {}
4471 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
4473 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d();
4475 return FakeOutputSurface::Create3d();
4478 void SetupActiveTreeLayers() {
4479 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
4480 host_impl_
->active_tree()->SetRootLayer(
4481 LayerImpl::Create(host_impl_
->active_tree(), 1));
4482 host_impl_
->active_tree()->root_layer()->AddChild(
4483 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
4485 host_impl_
->resource_provider()));
4486 child_
= static_cast<BlendStateCheckLayer
*>(
4487 host_impl_
->active_tree()->root_layer()->children()[0]);
4488 child_
->SetExpectation(false, false);
4489 child_
->SetContentsOpaque(true);
4492 // Expect no gutter rects.
4493 void TestLayerCoversFullViewport() {
4494 gfx::Rect
layer_rect(viewport_size_
);
4495 child_
->SetPosition(layer_rect
.origin());
4496 child_
->SetBounds(layer_rect
.size());
4497 child_
->SetContentBounds(layer_rect
.size());
4498 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4499 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4501 LayerTreeHostImpl::FrameData frame
;
4502 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4503 ASSERT_EQ(1u, frame
.render_passes
.size());
4505 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4506 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4507 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4509 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4510 host_impl_
->DidDrawAllLayers(frame
);
4513 // Expect fullscreen gutter rect.
4514 void TestEmptyLayer() {
4515 gfx::Rect
layer_rect(0, 0, 0, 0);
4516 child_
->SetPosition(layer_rect
.origin());
4517 child_
->SetBounds(layer_rect
.size());
4518 child_
->SetContentBounds(layer_rect
.size());
4519 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4520 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4522 LayerTreeHostImpl::FrameData frame
;
4523 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4524 ASSERT_EQ(1u, frame
.render_passes
.size());
4526 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4527 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4528 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4530 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4531 host_impl_
->DidDrawAllLayers(frame
);
4534 // Expect four surrounding gutter rects.
4535 void TestLayerInMiddleOfViewport() {
4536 gfx::Rect
layer_rect(500, 500, 200, 200);
4537 child_
->SetPosition(layer_rect
.origin());
4538 child_
->SetBounds(layer_rect
.size());
4539 child_
->SetContentBounds(layer_rect
.size());
4540 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4541 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4543 LayerTreeHostImpl::FrameData frame
;
4544 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4545 ASSERT_EQ(1u, frame
.render_passes
.size());
4547 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4548 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
4549 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4551 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
4552 host_impl_
->DidDrawAllLayers(frame
);
4555 // Expect no gutter rects.
4556 void TestLayerIsLargerThanViewport() {
4557 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
4558 viewport_size_
.height() + 10);
4559 child_
->SetPosition(layer_rect
.origin());
4560 child_
->SetBounds(layer_rect
.size());
4561 child_
->SetContentBounds(layer_rect
.size());
4562 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
4563 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
4565 LayerTreeHostImpl::FrameData frame
;
4566 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4567 ASSERT_EQ(1u, frame
.render_passes
.size());
4569 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
4570 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4571 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
4573 host_impl_
->DidDrawAllLayers(frame
);
4576 void DidActivateSyncTree() override
{ did_activate_pending_tree_
= true; }
4578 void set_gutter_quad_material(DrawQuad::Material material
) {
4579 gutter_quad_material_
= material
;
4581 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
4582 gutter_texture_size_
= gutter_texture_size
;
4586 size_t CountGutterQuads(const QuadList
& quad_list
) {
4587 size_t num_gutter_quads
= 0;
4588 for (const auto& quad
: quad_list
) {
4589 num_gutter_quads
+= (quad
->material
== gutter_quad_material_
) ? 1 : 0;
4591 return num_gutter_quads
;
4594 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
4595 LayerTestCommon::VerifyQuadsExactlyCoverRect(
4596 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
4599 // Make sure that the texture coordinates match their expectations.
4600 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
4601 for (const auto& quad
: quad_list
) {
4602 if (quad
->material
!= DrawQuad::TEXTURE_CONTENT
)
4604 const TextureDrawQuad
* texture_quad
= TextureDrawQuad::MaterialCast(quad
);
4605 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
4606 gutter_texture_size_
, host_impl_
->device_scale_factor());
4607 EXPECT_EQ(texture_quad
->uv_top_left
.x(),
4608 texture_quad
->rect
.x() / gutter_texture_size_pixels
.width());
4609 EXPECT_EQ(texture_quad
->uv_top_left
.y(),
4610 texture_quad
->rect
.y() / gutter_texture_size_pixels
.height());
4612 texture_quad
->uv_bottom_right
.x(),
4613 texture_quad
->rect
.right() / gutter_texture_size_pixels
.width());
4615 texture_quad
->uv_bottom_right
.y(),
4616 texture_quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
4620 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
4621 return gfx::ToRoundedSize(
4622 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
4625 DrawQuad::Material gutter_quad_material_
;
4626 gfx::Size gutter_texture_size_
;
4627 gfx::Size viewport_size_
;
4628 BlendStateCheckLayer
* child_
;
4629 bool did_activate_pending_tree_
;
4632 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
4633 viewport_size_
= gfx::Size(1000, 1000);
4635 bool always_draw
= false;
4636 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4638 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4639 SetupActiveTreeLayers();
4640 TestLayerCoversFullViewport();
4642 TestLayerInMiddleOfViewport();
4643 TestLayerIsLargerThanViewport();
4646 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
4647 viewport_size_
= gfx::Size(1000, 1000);
4649 bool always_draw
= false;
4650 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4652 host_impl_
->SetDeviceScaleFactor(2.f
);
4653 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4654 SetupActiveTreeLayers();
4655 TestLayerCoversFullViewport();
4657 TestLayerInMiddleOfViewport();
4658 TestLayerIsLargerThanViewport();
4661 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
4662 viewport_size_
= gfx::Size(1000, 1000);
4664 bool always_draw
= false;
4665 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4667 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4668 SetupActiveTreeLayers();
4670 // Specify an overhang bitmap to use.
4671 bool is_opaque
= false;
4672 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
4673 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
4674 UIResourceId ui_resource_id
= 12345;
4675 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
4676 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
4677 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
4678 set_gutter_texture_size(gfx::Size(32, 32));
4680 TestLayerCoversFullViewport();
4682 TestLayerInMiddleOfViewport();
4683 TestLayerIsLargerThanViewport();
4685 // Change the resource size.
4686 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
4687 set_gutter_texture_size(gfx::Size(128, 16));
4689 TestLayerCoversFullViewport();
4691 TestLayerInMiddleOfViewport();
4692 TestLayerIsLargerThanViewport();
4694 // Change the device scale factor
4695 host_impl_
->SetDeviceScaleFactor(2.f
);
4696 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4698 TestLayerCoversFullViewport();
4700 TestLayerInMiddleOfViewport();
4701 TestLayerIsLargerThanViewport();
4704 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
4705 viewport_size_
= gfx::Size(1000, 1000);
4707 bool always_draw
= true;
4708 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4710 // Pending tree to force active_tree size invalid. Not used otherwise.
4711 host_impl_
->CreatePendingTree();
4712 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4713 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4715 SetupActiveTreeLayers();
4717 TestLayerInMiddleOfViewport();
4718 TestLayerIsLargerThanViewport();
4721 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
4722 viewport_size_
= gfx::Size(1000, 1000);
4724 bool always_draw
= true;
4725 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4727 // Set larger viewport and activate it to active tree.
4728 host_impl_
->CreatePendingTree();
4729 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4730 viewport_size_
.height() + 100);
4731 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4732 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4733 host_impl_
->ActivateSyncTree();
4734 EXPECT_TRUE(did_activate_pending_tree_
);
4735 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4737 // Shrink pending tree viewport without activating.
4738 host_impl_
->CreatePendingTree();
4739 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4740 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4742 SetupActiveTreeLayers();
4744 TestLayerInMiddleOfViewport();
4745 TestLayerIsLargerThanViewport();
4748 class FakeDrawableLayerImpl
: public LayerImpl
{
4750 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4751 return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl
, id
));
4754 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4755 : LayerImpl(tree_impl
, id
) {}
4758 // Only reshape when we know we are going to draw. Otherwise, the reshape
4759 // can leave the window at the wrong size if we never draw and the proper
4760 // viewport size is never set.
4761 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4762 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4763 scoped_ptr
<OutputSurface
> output_surface(
4764 FakeOutputSurface::Create3d(provider
));
4765 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4767 scoped_ptr
<LayerImpl
> root
=
4768 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4769 root
->SetBounds(gfx::Size(10, 10));
4770 root
->SetContentBounds(gfx::Size(10, 10));
4771 root
->SetDrawsContent(true);
4772 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4773 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4774 provider
->TestContext3d()->clear_reshape_called();
4776 LayerTreeHostImpl::FrameData frame
;
4777 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4778 host_impl_
->SetDeviceScaleFactor(1.f
);
4779 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4780 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4781 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4782 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4783 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4784 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4785 host_impl_
->DidDrawAllLayers(frame
);
4786 provider
->TestContext3d()->clear_reshape_called();
4788 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4789 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4790 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4791 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4792 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4793 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4794 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4795 host_impl_
->DidDrawAllLayers(frame
);
4796 provider
->TestContext3d()->clear_reshape_called();
4798 host_impl_
->SetDeviceScaleFactor(2.f
);
4799 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4800 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4801 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4802 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4803 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4804 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4805 host_impl_
->DidDrawAllLayers(frame
);
4806 provider
->TestContext3d()->clear_reshape_called();
4809 // Make sure damage tracking propagates all the way to the graphics context,
4810 // where it should request to swap only the sub-buffer that is damaged.
4811 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4812 scoped_refptr
<TestContextProvider
> context_provider(
4813 TestContextProvider::Create());
4814 context_provider
->BindToCurrentThread();
4815 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4817 scoped_ptr
<FakeOutputSurface
> output_surface(
4818 FakeOutputSurface::Create3d(context_provider
));
4819 FakeOutputSurface
* fake_output_surface
= output_surface
.get();
4821 // This test creates its own LayerTreeHostImpl, so
4822 // that we can force partial swap enabled.
4823 LayerTreeSettings settings
;
4824 settings
.renderer_settings
.partial_swap_enabled
= true;
4825 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4826 new TestSharedBitmapManager());
4827 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4828 LayerTreeHostImpl::Create(settings
,
4831 &stats_instrumentation_
,
4832 shared_bitmap_manager
.get(),
4835 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4836 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4838 scoped_ptr
<LayerImpl
> root
=
4839 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4840 scoped_ptr
<LayerImpl
> child
=
4841 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4842 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4843 child
->SetBounds(gfx::Size(14, 15));
4844 child
->SetContentBounds(gfx::Size(14, 15));
4845 child
->SetDrawsContent(true);
4846 root
->SetBounds(gfx::Size(500, 500));
4847 root
->SetContentBounds(gfx::Size(500, 500));
4848 root
->SetDrawsContent(true);
4849 root
->AddChild(child
.Pass());
4850 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4852 LayerTreeHostImpl::FrameData frame
;
4854 // First frame, the entire screen should get swapped.
4855 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4856 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4857 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4858 layer_tree_host_impl
->SwapBuffers(frame
);
4859 gfx::Rect
expected_swap_rect(0, 0, 500, 500);
4860 EXPECT_EQ(expected_swap_rect
.ToString(),
4861 fake_output_surface
->last_swap_rect().ToString());
4863 // Second frame, only the damaged area should get swapped. Damage should be
4864 // the union of old and new child rects.
4865 // expected damage rect: gfx::Rect(26, 28);
4866 // expected swap rect: vertically flipped, with origin at bottom left corner.
4867 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4869 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4870 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4871 host_impl_
->DidDrawAllLayers(frame
);
4872 layer_tree_host_impl
->SwapBuffers(frame
);
4874 // Make sure that partial swap is constrained to the viewport dimensions
4875 // expected damage rect: gfx::Rect(500, 500);
4876 // expected swap rect: flipped damage rect, but also clamped to viewport
4877 expected_swap_rect
= gfx::Rect(0, 500-28, 26, 28);
4878 EXPECT_EQ(expected_swap_rect
.ToString(),
4879 fake_output_surface
->last_swap_rect().ToString());
4881 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4882 // This will damage everything.
4883 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4885 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4886 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4887 host_impl_
->DidDrawAllLayers(frame
);
4888 layer_tree_host_impl
->SwapBuffers(frame
);
4890 expected_swap_rect
= gfx::Rect(0, 0, 10, 10);
4891 EXPECT_EQ(expected_swap_rect
.ToString(),
4892 fake_output_surface
->last_swap_rect().ToString());
4895 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4896 scoped_ptr
<LayerImpl
> root
=
4897 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4898 scoped_ptr
<LayerImpl
> child
=
4899 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4900 child
->SetBounds(gfx::Size(10, 10));
4901 child
->SetContentBounds(gfx::Size(10, 10));
4902 child
->SetDrawsContent(true);
4903 root
->SetBounds(gfx::Size(10, 10));
4904 root
->SetContentBounds(gfx::Size(10, 10));
4905 root
->SetDrawsContent(true);
4906 root
->SetForceRenderSurface(true);
4907 root
->AddChild(child
.Pass());
4909 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4911 LayerTreeHostImpl::FrameData frame
;
4913 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4914 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4915 EXPECT_EQ(1u, frame
.render_passes
.size());
4916 host_impl_
->DidDrawAllLayers(frame
);
4919 class FakeLayerWithQuads
: public LayerImpl
{
4921 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4922 return make_scoped_ptr(new FakeLayerWithQuads(tree_impl
, id
));
4925 void AppendQuads(RenderPass
* render_pass
,
4926 const Occlusion
& occlusion_in_content_space
,
4927 AppendQuadsData
* append_quads_data
) override
{
4928 SharedQuadState
* shared_quad_state
=
4929 render_pass
->CreateAndAppendSharedQuadState();
4930 PopulateSharedQuadState(shared_quad_state
);
4932 SkColor gray
= SkColorSetRGB(100, 100, 100);
4933 gfx::Rect
quad_rect(content_bounds());
4934 gfx::Rect
visible_quad_rect(quad_rect
);
4935 SolidColorDrawQuad
* my_quad
=
4936 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
4938 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4942 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4943 : LayerImpl(tree_impl
, id
) {}
4946 class MockContext
: public TestWebGraphicsContext3D
{
4948 MOCK_METHOD1(useProgram
, void(GLuint program
));
4949 MOCK_METHOD5(uniform4f
, void(GLint location
,
4954 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4956 GLboolean transpose
,
4957 const GLfloat
* value
));
4958 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4962 MOCK_METHOD1(enable
, void(GLenum cap
));
4963 MOCK_METHOD1(disable
, void(GLenum cap
));
4964 MOCK_METHOD4(scissor
, void(GLint x
,
4970 class MockContextHarness
{
4972 MockContext
* context_
;
4975 explicit MockContextHarness(MockContext
* context
)
4976 : context_(context
) {
4977 context_
->set_have_post_sub_buffer(true);
4979 // Catch "uninteresting" calls
4980 EXPECT_CALL(*context_
, useProgram(_
))
4983 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4986 // These are not asserted
4987 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4988 .WillRepeatedly(Return());
4990 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4991 .WillRepeatedly(Return());
4993 // Any un-sanctioned calls to enable() are OK
4994 EXPECT_CALL(*context_
, enable(_
))
4995 .WillRepeatedly(Return());
4997 // Any un-sanctioned calls to disable() are OK
4998 EXPECT_CALL(*context_
, disable(_
))
4999 .WillRepeatedly(Return());
5002 void MustDrawSolidQuad() {
5003 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
5005 .RetiresOnSaturation();
5007 EXPECT_CALL(*context_
, useProgram(_
))
5009 .RetiresOnSaturation();
5012 void MustSetScissor(int x
, int y
, int width
, int height
) {
5013 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
5014 .WillRepeatedly(Return());
5016 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
5018 .WillRepeatedly(Return());
5021 void MustSetNoScissor() {
5022 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
5023 .WillRepeatedly(Return());
5025 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
5028 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
5033 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
5034 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
5035 MockContext
* mock_context
= mock_context_owned
.get();
5036 MockContextHarness
harness(mock_context
);
5039 LayerTreeSettings settings
= DefaultSettings();
5040 settings
.renderer_settings
.partial_swap_enabled
= false;
5041 CreateHostImpl(settings
,
5042 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
5043 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5045 // Without partial swap, and no clipping, no scissor is set.
5046 harness
.MustDrawSolidQuad();
5047 harness
.MustSetNoScissor();
5049 LayerTreeHostImpl::FrameData frame
;
5050 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5051 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5052 host_impl_
->DidDrawAllLayers(frame
);
5054 Mock::VerifyAndClearExpectations(&mock_context
);
5056 // Without partial swap, but a layer does clip its subtree, one scissor is
5058 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
5059 harness
.MustDrawSolidQuad();
5060 harness
.MustSetScissor(0, 0, 10, 10);
5062 LayerTreeHostImpl::FrameData frame
;
5063 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5064 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5065 host_impl_
->DidDrawAllLayers(frame
);
5067 Mock::VerifyAndClearExpectations(&mock_context
);
5070 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
5071 scoped_ptr
<MockContext
> context_owned(new MockContext
);
5072 MockContext
* mock_context
= context_owned
.get();
5073 MockContextHarness
harness(mock_context
);
5075 LayerTreeSettings settings
= DefaultSettings();
5076 settings
.renderer_settings
.partial_swap_enabled
= true;
5077 CreateHostImpl(settings
, FakeOutputSurface::Create3d(context_owned
.Pass()));
5078 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5080 // The first frame is not a partially-swapped one.
5081 harness
.MustSetScissor(0, 0, 10, 10);
5082 harness
.MustDrawSolidQuad();
5084 LayerTreeHostImpl::FrameData frame
;
5085 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5086 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5087 host_impl_
->DidDrawAllLayers(frame
);
5089 Mock::VerifyAndClearExpectations(&mock_context
);
5091 // Damage a portion of the frame.
5092 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
5093 gfx::Rect(0, 0, 2, 3));
5095 // The second frame will be partially-swapped (the y coordinates are flipped).
5096 harness
.MustSetScissor(0, 7, 2, 3);
5097 harness
.MustDrawSolidQuad();
5099 LayerTreeHostImpl::FrameData frame
;
5100 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5101 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5102 host_impl_
->DidDrawAllLayers(frame
);
5104 Mock::VerifyAndClearExpectations(&mock_context
);
5107 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
5109 LayerTreeHostImplClient
* client
,
5111 SharedBitmapManager
* manager
,
5112 RenderingStatsInstrumentation
* stats_instrumentation
) {
5113 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
5114 scoped_ptr
<OutputSurface
> output_surface(
5115 FakeOutputSurface::Create3d(provider
));
5116 provider
->BindToCurrentThread();
5117 provider
->TestContext3d()->set_have_post_sub_buffer(true);
5119 LayerTreeSettings settings
;
5120 settings
.renderer_settings
.partial_swap_enabled
= partial_swap
;
5121 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
5122 settings
, client
, proxy
, stats_instrumentation
, manager
, NULL
, 0);
5123 my_host_impl
->InitializeRenderer(output_surface
.Pass());
5124 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
5127 Layers are created as follows:
5129 +--------------------+
5133 | | +-------------------+
5135 | | +-------------------+
5140 +--------------------+
5142 Layers 1, 2 have render surfaces
5144 scoped_ptr
<LayerImpl
> root
=
5145 LayerImpl::Create(my_host_impl
->active_tree(), 1);
5146 scoped_ptr
<LayerImpl
> child
=
5147 LayerImpl::Create(my_host_impl
->active_tree(), 2);
5148 scoped_ptr
<LayerImpl
> grand_child
=
5149 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
5151 gfx::Rect
root_rect(0, 0, 100, 100);
5152 gfx::Rect
child_rect(10, 10, 50, 50);
5153 gfx::Rect
grand_child_rect(5, 5, 150, 150);
5155 root
->CreateRenderSurface();
5156 root
->SetPosition(root_rect
.origin());
5157 root
->SetBounds(root_rect
.size());
5158 root
->SetContentBounds(root
->bounds());
5159 root
->draw_properties().visible_content_rect
= root_rect
;
5160 root
->SetDrawsContent(false);
5161 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
5163 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
5164 child
->SetOpacity(0.5f
);
5165 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
5166 child
->SetContentBounds(child
->bounds());
5167 child
->draw_properties().visible_content_rect
= child_rect
;
5168 child
->SetDrawsContent(false);
5169 child
->SetForceRenderSurface(true);
5171 grand_child
->SetPosition(grand_child_rect
.origin());
5172 grand_child
->SetBounds(grand_child_rect
.size());
5173 grand_child
->SetContentBounds(grand_child
->bounds());
5174 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
5175 grand_child
->SetDrawsContent(true);
5177 child
->AddChild(grand_child
.Pass());
5178 root
->AddChild(child
.Pass());
5180 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
5181 return my_host_impl
.Pass();
5184 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
5185 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5186 new TestSharedBitmapManager());
5187 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5188 SetupLayersForOpacity(true,
5191 shared_bitmap_manager
.get(),
5192 &stats_instrumentation_
);
5194 LayerTreeHostImpl::FrameData frame
;
5195 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5197 // Verify all quads have been computed
5198 ASSERT_EQ(2U, frame
.render_passes
.size());
5199 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5200 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5201 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5202 frame
.render_passes
[0]->quad_list
.front()->material
);
5203 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5204 frame
.render_passes
[1]->quad_list
.front()->material
);
5206 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5207 my_host_impl
->DidDrawAllLayers(frame
);
5211 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
5212 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
5213 new TestSharedBitmapManager());
5214 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
5215 SetupLayersForOpacity(false,
5218 shared_bitmap_manager
.get(),
5219 &stats_instrumentation_
);
5221 LayerTreeHostImpl::FrameData frame
;
5222 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
5224 // Verify all quads have been computed
5225 ASSERT_EQ(2U, frame
.render_passes
.size());
5226 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
5227 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
5228 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
5229 frame
.render_passes
[0]->quad_list
.front()->material
);
5230 EXPECT_EQ(DrawQuad::RENDER_PASS
,
5231 frame
.render_passes
[1]->quad_list
.front()->material
);
5233 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
5234 my_host_impl
->DidDrawAllLayers(frame
);
5238 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
5239 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5240 TestWebGraphicsContext3D::Create();
5241 TestWebGraphicsContext3D
* context3d
= context
.get();
5242 scoped_ptr
<OutputSurface
> output_surface(
5243 FakeOutputSurface::Create3d(context
.Pass()));
5244 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
5246 scoped_ptr
<LayerImpl
> root_layer
=
5247 LayerImpl::Create(host_impl_
->active_tree(), 1);
5248 root_layer
->SetBounds(gfx::Size(10, 10));
5250 scoped_refptr
<VideoFrame
> softwareFrame
=
5251 media::VideoFrame::CreateColorFrame(
5252 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
5253 FakeVideoFrameProvider provider
;
5254 provider
.set_frame(softwareFrame
);
5255 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
5256 host_impl_
->active_tree(), 4, &provider
, media::VIDEO_ROTATION_0
);
5257 video_layer
->SetBounds(gfx::Size(10, 10));
5258 video_layer
->SetContentBounds(gfx::Size(10, 10));
5259 video_layer
->SetDrawsContent(true);
5260 root_layer
->AddChild(video_layer
.Pass());
5262 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
5263 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
5264 io_surface_layer
->SetBounds(gfx::Size(10, 10));
5265 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
5266 io_surface_layer
->SetDrawsContent(true);
5267 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
5268 root_layer
->AddChild(io_surface_layer
.Pass());
5270 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
5272 EXPECT_EQ(0u, context3d
->NumTextures());
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
);
5278 host_impl_
->SwapBuffers(frame
);
5280 EXPECT_GT(context3d
->NumTextures(), 0u);
5282 // Kill the layer tree.
5283 host_impl_
->active_tree()->SetRootLayer(
5284 LayerImpl::Create(host_impl_
->active_tree(), 100));
5285 // There should be no textures left in use after.
5286 EXPECT_EQ(0u, context3d
->NumTextures());
5289 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
5291 MOCK_METHOD1(useProgram
, void(GLuint program
));
5292 MOCK_METHOD4(drawElements
, void(GLenum mode
,
5298 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
5299 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
5300 new MockDrawQuadsToFillScreenContext
);
5301 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
5304 LayerTreeSettings settings
= DefaultSettings();
5305 settings
.renderer_settings
.partial_swap_enabled
= false;
5306 CreateHostImpl(settings
,
5307 FakeOutputSurface::Create3d(mock_context_owned
.Pass()));
5308 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5309 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
5311 // Verify one quad is drawn when transparent background set is not set.
5312 host_impl_
->active_tree()->set_has_transparent_background(false);
5313 EXPECT_CALL(*mock_context
, useProgram(_
))
5315 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
5317 LayerTreeHostImpl::FrameData frame
;
5318 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5319 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5320 host_impl_
->DidDrawAllLayers(frame
);
5321 Mock::VerifyAndClearExpectations(&mock_context
);
5323 // Verify no quads are drawn when transparent background is set.
5324 host_impl_
->active_tree()->set_has_transparent_background(true);
5325 host_impl_
->SetFullRootLayerDamage();
5326 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5327 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5328 host_impl_
->DidDrawAllLayers(frame
);
5329 Mock::VerifyAndClearExpectations(&mock_context
);
5332 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
5333 set_reduce_memory_result(false);
5335 // If changing the memory limit wouldn't result in changing what was
5336 // committed, then no commit should be requested.
5337 set_reduce_memory_result(false);
5338 host_impl_
->set_max_memory_needed_bytes(
5339 host_impl_
->memory_allocation_limit_bytes() - 1);
5340 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5341 host_impl_
->memory_allocation_limit_bytes() - 1));
5342 EXPECT_FALSE(did_request_commit_
);
5343 did_request_commit_
= false;
5345 // If changing the memory limit would result in changing what was
5346 // committed, then a commit should be requested, even though nothing was
5348 set_reduce_memory_result(false);
5349 host_impl_
->set_max_memory_needed_bytes(
5350 host_impl_
->memory_allocation_limit_bytes());
5351 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5352 host_impl_
->memory_allocation_limit_bytes() - 1));
5353 EXPECT_TRUE(did_request_commit_
);
5354 did_request_commit_
= false;
5356 // Especially if changing the memory limit caused evictions, we need
5358 set_reduce_memory_result(true);
5359 host_impl_
->set_max_memory_needed_bytes(1);
5360 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5361 host_impl_
->memory_allocation_limit_bytes() - 1));
5362 EXPECT_TRUE(did_request_commit_
);
5363 did_request_commit_
= false;
5365 // But if we set it to the same value that it was before, we shouldn't
5367 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
5368 host_impl_
->memory_allocation_limit_bytes()));
5369 EXPECT_FALSE(did_request_commit_
);
5372 class LayerTreeHostImplTestWithDelegatingRenderer
5373 : public LayerTreeHostImplTest
{
5375 scoped_ptr
<OutputSurface
> CreateOutputSurface() override
{
5376 return FakeOutputSurface::CreateDelegating3d();
5379 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
5380 bool expect_to_draw
= !expected_damage
.IsEmpty();
5382 LayerTreeHostImpl::FrameData frame
;
5383 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5385 if (!expect_to_draw
) {
5386 // With no damage, we don't draw, and no quads are created.
5387 ASSERT_EQ(0u, frame
.render_passes
.size());
5389 ASSERT_EQ(1u, frame
.render_passes
.size());
5391 // Verify the damage rect for the root render pass.
5392 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
5393 EXPECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
5395 // Verify the root and child layers' quads are generated and not being
5397 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
5399 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
5400 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
5401 EXPECT_EQ(expected_child_visible_rect
,
5402 root_render_pass
->quad_list
.front()->visible_rect
);
5404 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
5405 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
5406 EXPECT_EQ(expected_root_visible_rect
,
5407 root_render_pass
->quad_list
.ElementAt(1)->visible_rect
);
5410 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5411 host_impl_
->DidDrawAllLayers(frame
);
5412 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
5416 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
5417 scoped_ptr
<SolidColorLayerImpl
> root
=
5418 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5419 root
->SetPosition(gfx::PointF());
5420 root
->SetBounds(gfx::Size(10, 10));
5421 root
->SetContentBounds(gfx::Size(10, 10));
5422 root
->SetDrawsContent(true);
5424 // Child layer is in the bottom right corner.
5425 scoped_ptr
<SolidColorLayerImpl
> child
=
5426 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
5427 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
5428 child
->SetBounds(gfx::Size(1, 1));
5429 child
->SetContentBounds(gfx::Size(1, 1));
5430 child
->SetDrawsContent(true);
5431 root
->AddChild(child
.Pass());
5433 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5435 // Draw a frame. In the first frame, the entire viewport should be damaged.
5436 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
5437 DrawFrameAndTestDamage(full_frame_damage
);
5439 // The second frame has damage that doesn't touch the child layer. Its quads
5440 // should still be generated.
5441 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
5442 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
5443 DrawFrameAndTestDamage(small_damage
);
5445 // The third frame should have no damage, so no quads should be generated.
5446 gfx::Rect no_damage
;
5447 DrawFrameAndTestDamage(no_damage
);
5450 // TODO(reveman): Remove this test and the ability to prevent on demand raster
5451 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
5452 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
5453 LayerTreeSettings settings
;
5454 CreateHostImpl(settings
, CreateOutputSurface());
5455 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
5458 class FakeMaskLayerImpl
: public LayerImpl
{
5460 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
5462 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
5465 void GetContentsResourceId(ResourceProvider::ResourceId
* resource_id
,
5466 gfx::Size
* resource_size
) const override
{
5471 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
5472 : LayerImpl(tree_impl
, id
) {}
5475 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
5476 LayerTreeSettings settings
;
5477 settings
.layer_transforms_should_scale_layer_contents
= true;
5478 CreateHostImpl(settings
, CreateOutputSurface());
5482 // +-- Scaling Layer (adds a 2x scale)
5484 // +-- Content Layer
5486 scoped_ptr
<LayerImpl
> scoped_root
=
5487 LayerImpl::Create(host_impl_
->active_tree(), 1);
5488 LayerImpl
* root
= scoped_root
.get();
5489 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5491 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
5492 LayerImpl::Create(host_impl_
->active_tree(), 2);
5493 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
5494 root
->AddChild(scoped_scaling_layer
.Pass());
5496 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5497 LayerImpl::Create(host_impl_
->active_tree(), 3);
5498 LayerImpl
* content_layer
= scoped_content_layer
.get();
5499 scaling_layer
->AddChild(scoped_content_layer
.Pass());
5501 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5502 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5503 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5504 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5506 gfx::Size
root_size(100, 100);
5507 root
->SetBounds(root_size
);
5508 root
->SetContentBounds(root_size
);
5509 root
->SetPosition(gfx::PointF());
5511 gfx::Size
scaling_layer_size(50, 50);
5512 scaling_layer
->SetBounds(scaling_layer_size
);
5513 scaling_layer
->SetContentBounds(scaling_layer_size
);
5514 scaling_layer
->SetPosition(gfx::PointF());
5515 gfx::Transform scale
;
5516 scale
.Scale(2.f
, 2.f
);
5517 scaling_layer
->SetTransform(scale
);
5519 content_layer
->SetBounds(scaling_layer_size
);
5520 content_layer
->SetContentBounds(scaling_layer_size
);
5521 content_layer
->SetPosition(gfx::PointF());
5522 content_layer
->SetDrawsContent(true);
5524 mask_layer
->SetBounds(scaling_layer_size
);
5525 mask_layer
->SetContentBounds(scaling_layer_size
);
5526 mask_layer
->SetPosition(gfx::PointF());
5527 mask_layer
->SetDrawsContent(true);
5530 // Check that the tree scaling is correctly taken into account for the mask,
5531 // that should fully map onto the quad.
5532 float device_scale_factor
= 1.f
;
5533 host_impl_
->SetViewportSize(root_size
);
5534 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5536 LayerTreeHostImpl::FrameData frame
;
5537 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5539 ASSERT_EQ(1u, frame
.render_passes
.size());
5540 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5541 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5542 frame
.render_passes
[0]->quad_list
.front()->material
);
5543 const RenderPassDrawQuad
* render_pass_quad
=
5544 RenderPassDrawQuad::MaterialCast(
5545 frame
.render_passes
[0]->quad_list
.front());
5546 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5547 render_pass_quad
->rect
.ToString());
5548 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5549 render_pass_quad
->MaskUVRect().ToString());
5550 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5551 render_pass_quad
->mask_uv_scale
.ToString());
5553 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5554 host_impl_
->DidDrawAllLayers(frame
);
5558 // Applying a DSF should change the render surface size, but won't affect
5559 // which part of the mask is used.
5560 device_scale_factor
= 2.f
;
5561 gfx::Size device_viewport
=
5562 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5563 host_impl_
->SetViewportSize(device_viewport
);
5564 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5565 host_impl_
->active_tree()->set_needs_update_draw_properties();
5567 LayerTreeHostImpl::FrameData frame
;
5568 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5570 ASSERT_EQ(1u, frame
.render_passes
.size());
5571 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5572 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5573 frame
.render_passes
[0]->quad_list
.front()->material
);
5574 const RenderPassDrawQuad
* render_pass_quad
=
5575 RenderPassDrawQuad::MaterialCast(
5576 frame
.render_passes
[0]->quad_list
.front());
5577 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5578 render_pass_quad
->rect
.ToString());
5579 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5580 render_pass_quad
->MaskUVRect().ToString());
5581 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5582 render_pass_quad
->mask_uv_scale
.ToString());
5584 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5585 host_impl_
->DidDrawAllLayers(frame
);
5589 // Applying an equivalent content scale on the content layer and the mask
5590 // should still result in the same part of the mask being used.
5591 gfx::Size content_bounds
=
5592 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
5593 device_scale_factor
));
5594 content_layer
->SetContentBounds(content_bounds
);
5595 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5596 mask_layer
->SetContentBounds(content_bounds
);
5597 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5598 host_impl_
->active_tree()->set_needs_update_draw_properties();
5600 LayerTreeHostImpl::FrameData frame
;
5601 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5603 ASSERT_EQ(1u, frame
.render_passes
.size());
5604 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5605 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5606 frame
.render_passes
[0]->quad_list
.front()->material
);
5607 const RenderPassDrawQuad
* render_pass_quad
=
5608 RenderPassDrawQuad::MaterialCast(
5609 frame
.render_passes
[0]->quad_list
.front());
5610 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5611 render_pass_quad
->rect
.ToString());
5612 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5613 render_pass_quad
->MaskUVRect().ToString());
5614 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5615 render_pass_quad
->mask_uv_scale
.ToString());
5617 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5618 host_impl_
->DidDrawAllLayers(frame
);
5622 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
5623 // The mask layer has bounds 100x100 but is attached to a layer with bounds
5626 scoped_ptr
<LayerImpl
> scoped_root
=
5627 LayerImpl::Create(host_impl_
->active_tree(), 1);
5628 LayerImpl
* root
= scoped_root
.get();
5629 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5631 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5632 LayerImpl::Create(host_impl_
->active_tree(), 3);
5633 LayerImpl
* content_layer
= scoped_content_layer
.get();
5634 root
->AddChild(scoped_content_layer
.Pass());
5636 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5637 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5638 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5639 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5641 gfx::Size
root_size(100, 100);
5642 root
->SetBounds(root_size
);
5643 root
->SetContentBounds(root_size
);
5644 root
->SetPosition(gfx::PointF());
5646 gfx::Size
layer_size(50, 50);
5647 content_layer
->SetBounds(layer_size
);
5648 content_layer
->SetContentBounds(layer_size
);
5649 content_layer
->SetPosition(gfx::PointF());
5650 content_layer
->SetDrawsContent(true);
5652 gfx::Size
mask_size(100, 100);
5653 mask_layer
->SetBounds(mask_size
);
5654 mask_layer
->SetContentBounds(mask_size
);
5655 mask_layer
->SetPosition(gfx::PointF());
5656 mask_layer
->SetDrawsContent(true);
5658 // Check that the mask fills the surface.
5659 float device_scale_factor
= 1.f
;
5660 host_impl_
->SetViewportSize(root_size
);
5661 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5663 LayerTreeHostImpl::FrameData frame
;
5664 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5666 ASSERT_EQ(1u, frame
.render_passes
.size());
5667 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5668 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5669 frame
.render_passes
[0]->quad_list
.front()->material
);
5670 const RenderPassDrawQuad
* render_pass_quad
=
5671 RenderPassDrawQuad::MaterialCast(
5672 frame
.render_passes
[0]->quad_list
.front());
5673 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5674 render_pass_quad
->rect
.ToString());
5675 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5676 render_pass_quad
->MaskUVRect().ToString());
5677 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5678 render_pass_quad
->mask_uv_scale
.ToString());
5680 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5681 host_impl_
->DidDrawAllLayers(frame
);
5684 // Applying a DSF should change the render surface size, but won't affect
5685 // which part of the mask is used.
5686 device_scale_factor
= 2.f
;
5687 gfx::Size device_viewport
=
5688 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5689 host_impl_
->SetViewportSize(device_viewport
);
5690 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5691 host_impl_
->active_tree()->set_needs_update_draw_properties();
5693 LayerTreeHostImpl::FrameData frame
;
5694 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5696 ASSERT_EQ(1u, frame
.render_passes
.size());
5697 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5698 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5699 frame
.render_passes
[0]->quad_list
.front()->material
);
5700 const RenderPassDrawQuad
* render_pass_quad
=
5701 RenderPassDrawQuad::MaterialCast(
5702 frame
.render_passes
[0]->quad_list
.front());
5703 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5704 render_pass_quad
->rect
.ToString());
5705 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5706 render_pass_quad
->MaskUVRect().ToString());
5707 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5708 render_pass_quad
->mask_uv_scale
.ToString());
5710 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5711 host_impl_
->DidDrawAllLayers(frame
);
5714 // Applying an equivalent content scale on the content layer and the mask
5715 // should still result in the same part of the mask being used.
5716 gfx::Size layer_size_large
=
5717 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5718 content_layer
->SetContentBounds(layer_size_large
);
5719 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5720 gfx::Size mask_size_large
=
5721 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5722 mask_layer
->SetContentBounds(mask_size_large
);
5723 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5724 host_impl_
->active_tree()->set_needs_update_draw_properties();
5726 LayerTreeHostImpl::FrameData frame
;
5727 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5729 ASSERT_EQ(1u, frame
.render_passes
.size());
5730 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5731 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5732 frame
.render_passes
[0]->quad_list
.front()->material
);
5733 const RenderPassDrawQuad
* render_pass_quad
=
5734 RenderPassDrawQuad::MaterialCast(
5735 frame
.render_passes
[0]->quad_list
.front());
5736 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5737 render_pass_quad
->rect
.ToString());
5738 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5739 render_pass_quad
->MaskUVRect().ToString());
5740 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5741 render_pass_quad
->mask_uv_scale
.ToString());
5743 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5744 host_impl_
->DidDrawAllLayers(frame
);
5747 // Applying a different contents scale to the mask layer means it will have
5748 // a larger texture, but it should use the same tex coords to cover the
5750 mask_layer
->SetContentBounds(mask_size
);
5751 mask_layer
->SetContentsScale(1.f
, 1.f
);
5752 host_impl_
->active_tree()->set_needs_update_draw_properties();
5754 LayerTreeHostImpl::FrameData frame
;
5755 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5757 ASSERT_EQ(1u, frame
.render_passes
.size());
5758 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5759 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5760 frame
.render_passes
[0]->quad_list
.front()->material
);
5761 const RenderPassDrawQuad
* render_pass_quad
=
5762 RenderPassDrawQuad::MaterialCast(
5763 frame
.render_passes
[0]->quad_list
.front());
5764 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5765 render_pass_quad
->rect
.ToString());
5766 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5767 render_pass_quad
->MaskUVRect().ToString());
5768 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5769 render_pass_quad
->mask_uv_scale
.ToString());
5771 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5772 host_impl_
->DidDrawAllLayers(frame
);
5776 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5777 // The replica's mask layer has bounds 100x100 but the replica is of a
5778 // layer with bounds 50x50.
5780 scoped_ptr
<LayerImpl
> scoped_root
=
5781 LayerImpl::Create(host_impl_
->active_tree(), 1);
5782 LayerImpl
* root
= scoped_root
.get();
5783 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5785 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5786 LayerImpl::Create(host_impl_
->active_tree(), 3);
5787 LayerImpl
* content_layer
= scoped_content_layer
.get();
5788 root
->AddChild(scoped_content_layer
.Pass());
5790 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5791 LayerImpl::Create(host_impl_
->active_tree(), 2);
5792 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5793 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5795 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5796 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5797 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5798 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5800 gfx::Size
root_size(100, 100);
5801 root
->SetBounds(root_size
);
5802 root
->SetContentBounds(root_size
);
5803 root
->SetPosition(gfx::PointF());
5805 gfx::Size
layer_size(50, 50);
5806 content_layer
->SetBounds(layer_size
);
5807 content_layer
->SetContentBounds(layer_size
);
5808 content_layer
->SetPosition(gfx::PointF());
5809 content_layer
->SetDrawsContent(true);
5811 gfx::Size
mask_size(100, 100);
5812 mask_layer
->SetBounds(mask_size
);
5813 mask_layer
->SetContentBounds(mask_size
);
5814 mask_layer
->SetPosition(gfx::PointF());
5815 mask_layer
->SetDrawsContent(true);
5817 // Check that the mask fills the surface.
5818 float device_scale_factor
= 1.f
;
5819 host_impl_
->SetViewportSize(root_size
);
5820 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5822 LayerTreeHostImpl::FrameData frame
;
5823 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5825 ASSERT_EQ(1u, frame
.render_passes
.size());
5826 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5827 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5828 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5829 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5830 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5831 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5832 replica_quad
->rect
.ToString());
5833 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5834 replica_quad
->MaskUVRect().ToString());
5835 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5836 replica_quad
->mask_uv_scale
.ToString());
5838 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5839 host_impl_
->DidDrawAllLayers(frame
);
5842 // Applying a DSF should change the render surface size, but won't affect
5843 // which part of the mask is used.
5844 device_scale_factor
= 2.f
;
5845 gfx::Size device_viewport
=
5846 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5847 host_impl_
->SetViewportSize(device_viewport
);
5848 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5849 host_impl_
->active_tree()->set_needs_update_draw_properties();
5851 LayerTreeHostImpl::FrameData frame
;
5852 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5854 ASSERT_EQ(1u, frame
.render_passes
.size());
5855 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5856 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5857 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5858 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5859 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5860 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5861 replica_quad
->rect
.ToString());
5862 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5863 replica_quad
->MaskUVRect().ToString());
5864 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5865 replica_quad
->mask_uv_scale
.ToString());
5867 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5868 host_impl_
->DidDrawAllLayers(frame
);
5871 // Applying an equivalent content scale on the content layer and the mask
5872 // should still result in the same part of the mask being used.
5873 gfx::Size layer_size_large
=
5874 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5875 content_layer
->SetContentBounds(layer_size_large
);
5876 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5877 gfx::Size mask_size_large
=
5878 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5879 mask_layer
->SetContentBounds(mask_size_large
);
5880 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5881 host_impl_
->active_tree()->set_needs_update_draw_properties();
5883 LayerTreeHostImpl::FrameData frame
;
5884 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5886 ASSERT_EQ(1u, frame
.render_passes
.size());
5887 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5888 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5889 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5890 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5891 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5892 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5893 replica_quad
->rect
.ToString());
5894 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5895 replica_quad
->MaskUVRect().ToString());
5896 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5897 replica_quad
->mask_uv_scale
.ToString());
5899 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5900 host_impl_
->DidDrawAllLayers(frame
);
5903 // Applying a different contents scale to the mask layer means it will have
5904 // a larger texture, but it should use the same tex coords to cover the
5906 mask_layer
->SetContentBounds(mask_size
);
5907 mask_layer
->SetContentsScale(1.f
, 1.f
);
5908 host_impl_
->active_tree()->set_needs_update_draw_properties();
5910 LayerTreeHostImpl::FrameData frame
;
5911 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5913 ASSERT_EQ(1u, frame
.render_passes
.size());
5914 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5915 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5916 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
5917 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
5918 frame
.render_passes
[0]->quad_list
.ElementAt(1));
5919 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5920 replica_quad
->rect
.ToString());
5921 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5922 replica_quad
->MaskUVRect().ToString());
5923 EXPECT_EQ(gfx::Vector2dF(1.f
, 1.f
).ToString(),
5924 replica_quad
->mask_uv_scale
.ToString());
5926 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5927 host_impl_
->DidDrawAllLayers(frame
);
5931 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5932 // The replica is of a layer with bounds 50x50, but it has a child that causes
5933 // the surface bounds to be larger.
5935 scoped_ptr
<LayerImpl
> scoped_root
=
5936 LayerImpl::Create(host_impl_
->active_tree(), 1);
5937 LayerImpl
* root
= scoped_root
.get();
5938 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5940 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5941 LayerImpl::Create(host_impl_
->active_tree(), 2);
5942 LayerImpl
* content_layer
= scoped_content_layer
.get();
5943 root
->AddChild(scoped_content_layer
.Pass());
5945 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5946 LayerImpl::Create(host_impl_
->active_tree(), 3);
5947 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5948 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5950 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5951 LayerImpl::Create(host_impl_
->active_tree(), 4);
5952 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5953 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5955 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5956 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5957 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5958 replica_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
5960 gfx::Size
root_size(100, 100);
5961 root
->SetBounds(root_size
);
5962 root
->SetContentBounds(root_size
);
5963 root
->SetPosition(gfx::PointF());
5965 gfx::Size
layer_size(50, 50);
5966 content_layer
->SetBounds(layer_size
);
5967 content_layer
->SetContentBounds(layer_size
);
5968 content_layer
->SetPosition(gfx::PointF());
5969 content_layer
->SetDrawsContent(true);
5971 gfx::Size
child_size(50, 50);
5972 content_child_layer
->SetBounds(child_size
);
5973 content_child_layer
->SetContentBounds(child_size
);
5974 content_child_layer
->SetPosition(gfx::Point(50, 0));
5975 content_child_layer
->SetDrawsContent(true);
5977 gfx::Size
mask_size(50, 50);
5978 mask_layer
->SetBounds(mask_size
);
5979 mask_layer
->SetContentBounds(mask_size
);
5980 mask_layer
->SetPosition(gfx::PointF());
5981 mask_layer
->SetDrawsContent(true);
5983 float device_scale_factor
= 1.f
;
5984 host_impl_
->SetViewportSize(root_size
);
5985 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5987 LayerTreeHostImpl::FrameData frame
;
5988 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5990 ASSERT_EQ(1u, frame
.render_passes
.size());
5991 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5993 // The surface is 100x50.
5994 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5995 frame
.render_passes
[0]->quad_list
.front()->material
);
5996 const RenderPassDrawQuad
* render_pass_quad
=
5997 RenderPassDrawQuad::MaterialCast(
5998 frame
.render_passes
[0]->quad_list
.front());
5999 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
6000 render_pass_quad
->rect
.ToString());
6002 // The mask covers the owning layer only.
6003 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6004 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6005 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6006 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6007 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
6008 replica_quad
->rect
.ToString());
6009 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
6010 replica_quad
->MaskUVRect().ToString());
6011 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
6012 replica_quad
->mask_uv_scale
.ToString());
6014 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6015 host_impl_
->DidDrawAllLayers(frame
);
6018 // Move the child to (-50, 0) instead. Now the mask should be moved to still
6019 // cover the layer being replicated.
6020 content_child_layer
->SetPosition(gfx::Point(-50, 0));
6022 LayerTreeHostImpl::FrameData frame
;
6023 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6025 ASSERT_EQ(1u, frame
.render_passes
.size());
6026 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
6028 // The surface is 100x50 with its origin at (-50, 0).
6029 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6030 frame
.render_passes
[0]->quad_list
.front()->material
);
6031 const RenderPassDrawQuad
* render_pass_quad
=
6032 RenderPassDrawQuad::MaterialCast(
6033 frame
.render_passes
[0]->quad_list
.front());
6034 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6035 render_pass_quad
->rect
.ToString());
6037 // The mask covers the owning layer only.
6038 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6039 frame
.render_passes
[0]->quad_list
.ElementAt(1)->material
);
6040 const RenderPassDrawQuad
* replica_quad
= RenderPassDrawQuad::MaterialCast(
6041 frame
.render_passes
[0]->quad_list
.ElementAt(1));
6042 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6043 replica_quad
->rect
.ToString());
6044 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
6045 replica_quad
->MaskUVRect().ToString());
6046 EXPECT_EQ(gfx::Vector2dF(2.f
, 1.f
).ToString(),
6047 replica_quad
->mask_uv_scale
.ToString());
6049 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6050 host_impl_
->DidDrawAllLayers(frame
);
6054 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
6055 // The masked layer has bounds 50x50, but it has a child that causes
6056 // the surface bounds to be larger. It also has a parent that clips the
6057 // masked layer and its surface.
6059 scoped_ptr
<LayerImpl
> scoped_root
=
6060 LayerImpl::Create(host_impl_
->active_tree(), 1);
6061 LayerImpl
* root
= scoped_root
.get();
6062 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
6064 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
6065 LayerImpl::Create(host_impl_
->active_tree(), 2);
6066 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
6067 root
->AddChild(scoped_clipping_layer
.Pass());
6069 scoped_ptr
<LayerImpl
> scoped_content_layer
=
6070 LayerImpl::Create(host_impl_
->active_tree(), 3);
6071 LayerImpl
* content_layer
= scoped_content_layer
.get();
6072 clipping_layer
->AddChild(scoped_content_layer
.Pass());
6074 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
6075 LayerImpl::Create(host_impl_
->active_tree(), 4);
6076 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
6077 content_layer
->AddChild(scoped_content_child_layer
.Pass());
6079 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
6080 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
6081 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
6082 content_layer
->SetMaskLayer(scoped_mask_layer
.Pass());
6084 gfx::Size
root_size(100, 100);
6085 root
->SetBounds(root_size
);
6086 root
->SetContentBounds(root_size
);
6087 root
->SetPosition(gfx::PointF());
6089 gfx::Rect
clipping_rect(20, 10, 10, 20);
6090 clipping_layer
->SetBounds(clipping_rect
.size());
6091 clipping_layer
->SetContentBounds(clipping_rect
.size());
6092 clipping_layer
->SetPosition(clipping_rect
.origin());
6093 clipping_layer
->SetMasksToBounds(true);
6095 gfx::Size
layer_size(50, 50);
6096 content_layer
->SetBounds(layer_size
);
6097 content_layer
->SetContentBounds(layer_size
);
6098 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
6099 content_layer
->SetDrawsContent(true);
6101 gfx::Size
child_size(50, 50);
6102 content_child_layer
->SetBounds(child_size
);
6103 content_child_layer
->SetContentBounds(child_size
);
6104 content_child_layer
->SetPosition(gfx::Point(50, 0));
6105 content_child_layer
->SetDrawsContent(true);
6107 gfx::Size
mask_size(100, 100);
6108 mask_layer
->SetBounds(mask_size
);
6109 mask_layer
->SetContentBounds(mask_size
);
6110 mask_layer
->SetPosition(gfx::PointF());
6111 mask_layer
->SetDrawsContent(true);
6113 float device_scale_factor
= 1.f
;
6114 host_impl_
->SetViewportSize(root_size
);
6115 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6117 LayerTreeHostImpl::FrameData frame
;
6118 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6120 ASSERT_EQ(1u, frame
.render_passes
.size());
6121 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
6123 // The surface is clipped to 10x20.
6124 ASSERT_EQ(DrawQuad::RENDER_PASS
,
6125 frame
.render_passes
[0]->quad_list
.front()->material
);
6126 const RenderPassDrawQuad
* render_pass_quad
=
6127 RenderPassDrawQuad::MaterialCast(
6128 frame
.render_passes
[0]->quad_list
.front());
6129 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6130 render_pass_quad
->rect
.ToString());
6131 // The masked layer is 50x50, but the surface size is 10x20. So the texture
6132 // coords in the mask are scaled by 10/50 and 20/50.
6133 // The surface is clipped to (20,10) so the mask texture coords are offset
6134 // by 20/50 and 10/50
6135 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
), 1.f
/ 50.f
)
6137 render_pass_quad
->MaskUVRect().ToString());
6138 EXPECT_EQ(gfx::Vector2dF(10.f
/ 50.f
, 20.f
/ 50.f
).ToString(),
6139 render_pass_quad
->mask_uv_scale
.ToString());
6141 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6142 host_impl_
->DidDrawAllLayers(frame
);
6146 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
6148 using GLRenderer::ShouldAntialiasQuad
;
6151 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
6152 // Due to precision issues (especially on Android), sometimes far
6153 // away quads can end up thinking they need AA.
6154 float device_scale_factor
= 4.f
/ 3.f
;
6155 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
6156 gfx::Size
root_size(2000, 1000);
6157 gfx::Size device_viewport_size
=
6158 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
6159 host_impl_
->SetViewportSize(device_viewport_size
);
6161 host_impl_
->CreatePendingTree();
6162 host_impl_
->pending_tree()->PushPageScaleFromMainThread(1.f
, 1.f
/ 16.f
,
6165 scoped_ptr
<LayerImpl
> scoped_root
=
6166 LayerImpl::Create(host_impl_
->pending_tree(), 1);
6167 LayerImpl
* root
= scoped_root
.get();
6169 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
6171 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
6172 LayerImpl::Create(host_impl_
->pending_tree(), 2);
6173 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
6174 root
->AddChild(scoped_scrolling_layer
.Pass());
6176 gfx::Size
content_layer_bounds(100000, 100);
6177 gfx::Size
pile_tile_size(3000, 3000);
6178 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
6179 pile_tile_size
, content_layer_bounds
));
6181 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
6182 FakePictureLayerImpl::CreateWithRasterSource(host_impl_
->pending_tree(),
6184 LayerImpl
* content_layer
= scoped_content_layer
.get();
6185 scrolling_layer
->AddChild(scoped_content_layer
.Pass());
6186 content_layer
->SetBounds(content_layer_bounds
);
6187 content_layer
->SetDrawsContent(true);
6189 root
->SetBounds(root_size
);
6191 gfx::ScrollOffset
scroll_offset(100000, 0);
6192 scrolling_layer
->SetScrollClipLayer(root
->id());
6193 scrolling_layer
->SetScrollOffset(scroll_offset
);
6195 host_impl_
->ActivateSyncTree();
6197 host_impl_
->active_tree()->UpdateDrawProperties();
6198 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
6200 LayerTreeHostImpl::FrameData frame
;
6201 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6203 ASSERT_EQ(1u, frame
.render_passes
.size());
6204 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
6205 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
.front();
6208 GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
6209 quad
->quadTransform(), quad
, false);
6210 EXPECT_FALSE(antialiased
);
6212 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6213 host_impl_
->DidDrawAllLayers(frame
);
6217 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
6219 CompositorFrameMetadataTest()
6220 : swap_buffers_complete_(0) {}
6222 void DidSwapBuffersCompleteOnImplThread() override
{
6223 swap_buffers_complete_
++;
6226 int swap_buffers_complete_
;
6229 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
6230 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
6232 LayerTreeHostImpl::FrameData frame
;
6233 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6234 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
6235 host_impl_
->DidDrawAllLayers(frame
);
6237 CompositorFrameAck ack
;
6238 host_impl_
->ReclaimResources(&ack
);
6239 host_impl_
->DidSwapBuffersComplete();
6240 EXPECT_EQ(swap_buffers_complete_
, 1);
6243 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
6245 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
6247 SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) override
{
6249 return SoftwareOutputDevice::BeginPaint(damage_rect
);
6251 void EndPaint(SoftwareFrameData
* frame_data
) override
{
6253 SoftwareOutputDevice::EndPaint(frame_data
);
6256 int frames_began_
, frames_ended_
;
6259 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
6260 // No main thread evictions in resourceless software mode.
6261 set_reduce_memory_result(false);
6262 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
6263 bool delegated_rendering
= false;
6264 FakeOutputSurface
* output_surface
=
6265 FakeOutputSurface::CreateDeferredGL(
6266 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
6267 delegated_rendering
).release();
6268 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6269 scoped_ptr
<OutputSurface
>(output_surface
)));
6270 host_impl_
->SetViewportSize(gfx::Size(50, 50));
6272 SetupScrollAndContentsLayers(gfx::Size(100, 100));
6274 const gfx::Transform external_transform
;
6275 const gfx::Rect external_viewport
;
6276 const gfx::Rect external_clip
;
6277 const bool resourceless_software_draw
= true;
6278 host_impl_
->SetExternalDrawConstraints(external_transform
,
6283 resourceless_software_draw
);
6285 EXPECT_EQ(0, software_device
->frames_began_
);
6286 EXPECT_EQ(0, software_device
->frames_ended_
);
6290 EXPECT_EQ(1, software_device
->frames_began_
);
6291 EXPECT_EQ(1, software_device
->frames_ended_
);
6293 // Call other API methods that are likely to hit NULL pointer in this mode.
6294 EXPECT_TRUE(host_impl_
->AsValue().get());
6295 EXPECT_TRUE(host_impl_
->ActivationStateAsValue().get());
6298 TEST_F(LayerTreeHostImplTest
,
6299 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
6300 set_reduce_memory_result(false);
6301 bool delegated_rendering
= false;
6302 FakeOutputSurface
* output_surface
=
6303 FakeOutputSurface::CreateDeferredGL(
6304 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6305 delegated_rendering
).release();
6306 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6307 scoped_ptr
<OutputSurface
>(output_surface
)));
6309 const gfx::Transform external_transform
;
6310 const gfx::Rect external_viewport
;
6311 const gfx::Rect external_clip
;
6312 const bool resourceless_software_draw
= true;
6313 host_impl_
->SetExternalDrawConstraints(external_transform
,
6318 resourceless_software_draw
);
6320 // SolidColorLayerImpl will be drawn.
6321 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6322 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6324 // VideoLayerImpl will not be drawn.
6325 FakeVideoFrameProvider provider
;
6326 scoped_ptr
<VideoLayerImpl
> video_layer
= VideoLayerImpl::Create(
6327 host_impl_
->active_tree(), 2, &provider
, media::VIDEO_ROTATION_0
);
6328 video_layer
->SetBounds(gfx::Size(10, 10));
6329 video_layer
->SetContentBounds(gfx::Size(10, 10));
6330 video_layer
->SetDrawsContent(true);
6331 root_layer
->AddChild(video_layer
.Pass());
6332 SetupRootLayerImpl(root_layer
.Pass());
6334 LayerTreeHostImpl::FrameData frame
;
6335 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6336 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6337 host_impl_
->DidDrawAllLayers(frame
);
6339 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
6340 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
6343 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
6345 void SetUp() override
{
6346 LayerTreeHostImplTest::SetUp();
6348 set_reduce_memory_result(false);
6350 bool delegated_rendering
= false;
6351 scoped_ptr
<FakeOutputSurface
> output_surface(
6352 FakeOutputSurface::CreateDeferredGL(
6353 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
6354 delegated_rendering
));
6355 output_surface_
= output_surface
.get();
6357 EXPECT_TRUE(CreateHostImpl(DefaultSettings(), output_surface
.Pass()));
6359 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
6360 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6361 SetupRootLayerImpl(root_layer
.Pass());
6363 onscreen_context_provider_
= TestContextProvider::Create();
6366 void UpdateRendererCapabilitiesOnImplThread() override
{
6367 did_update_renderer_capabilities_
= true;
6370 FakeOutputSurface
* output_surface_
;
6371 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
6372 bool did_update_renderer_capabilities_
;
6376 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
6380 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6382 // DeferredInitialize and hardware draw.
6383 did_update_renderer_capabilities_
= false;
6385 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
6386 EXPECT_EQ(onscreen_context_provider_
.get(),
6387 host_impl_
->output_surface()->context_provider());
6388 EXPECT_TRUE(did_update_renderer_capabilities_
);
6390 // Defer intialized GL draw.
6393 // Revert back to software.
6394 did_update_renderer_capabilities_
= false;
6395 output_surface_
->ReleaseGL();
6396 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6397 EXPECT_TRUE(did_update_renderer_capabilities_
);
6399 // Software draw again.
6403 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
6407 // Fail initialization of the onscreen context before the OutputSurface binds
6408 // it to the thread.
6409 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
6411 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6413 // DeferredInitialize fails.
6414 did_update_renderer_capabilities_
= false;
6416 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
6417 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
6418 EXPECT_FALSE(did_update_renderer_capabilities_
);
6420 // Software draw again.
6424 // Checks that we have a non-0 default allocation if we pass a context that
6425 // doesn't support memory management extensions.
6426 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
6427 LayerTreeSettings settings
;
6428 host_impl_
= LayerTreeHostImpl::Create(settings
,
6431 &stats_instrumentation_
,
6432 shared_bitmap_manager_
.get(),
6433 gpu_memory_buffer_manager_
.get(),
6436 scoped_ptr
<OutputSurface
> output_surface(
6437 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
6438 host_impl_
->InitializeRenderer(output_surface
.Pass());
6439 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
6442 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
6443 ManagedMemoryPolicy
policy1(
6444 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
6445 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6446 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
6447 int allow_nice_to_have_cutoff_value
=
6448 ManagedMemoryPolicy::PriorityCutoffToValue(
6449 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
6450 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
6451 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
6453 // GPU rasterization should be disabled by default on the tree(s)
6454 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
6455 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
6457 host_impl_
->SetVisible(true);
6458 host_impl_
->SetMemoryPolicy(policy1
);
6459 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6460 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6462 host_impl_
->SetVisible(false);
6463 EXPECT_EQ(0u, current_limit_bytes_
);
6464 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6466 host_impl_
->SetVisible(true);
6467 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6468 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
6470 // Now enable GPU rasterization and test if we get nice to have cutoff,
6472 LayerTreeSettings settings
;
6473 settings
.gpu_rasterization_enabled
= true;
6474 host_impl_
= LayerTreeHostImpl::Create(
6475 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, NULL
, 0);
6476 host_impl_
->SetUseGpuRasterization(true);
6477 host_impl_
->SetVisible(true);
6478 host_impl_
->SetMemoryPolicy(policy1
);
6479 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
6480 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
6482 host_impl_
->SetVisible(false);
6483 EXPECT_EQ(0u, current_limit_bytes_
);
6484 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
6487 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
6488 ASSERT_TRUE(host_impl_
->active_tree());
6490 // RequiresHighResToDraw is set when new output surface is used.
6491 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6493 host_impl_
->ResetRequiresHighResToDraw();
6495 host_impl_
->SetVisible(false);
6496 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6497 host_impl_
->SetVisible(true);
6498 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6499 host_impl_
->SetVisible(false);
6500 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6502 host_impl_
->ResetRequiresHighResToDraw();
6504 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6505 host_impl_
->SetVisible(true);
6506 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6509 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
6510 ASSERT_TRUE(host_impl_
->active_tree());
6511 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
6513 // RequiresHighResToDraw is set when new output surface is used.
6514 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6516 host_impl_
->ResetRequiresHighResToDraw();
6518 host_impl_
->SetUseGpuRasterization(false);
6519 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6520 host_impl_
->SetUseGpuRasterization(true);
6521 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6522 host_impl_
->SetUseGpuRasterization(false);
6523 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6525 host_impl_
->ResetRequiresHighResToDraw();
6527 EXPECT_FALSE(host_impl_
->RequiresHighResToDraw());
6528 host_impl_
->SetUseGpuRasterization(true);
6529 EXPECT_TRUE(host_impl_
->RequiresHighResToDraw());
6532 class LayerTreeHostImplTestPrepareTiles
: public LayerTreeHostImplTest
{
6534 void SetUp() override
{
6535 LayerTreeSettings settings
;
6536 settings
.impl_side_painting
= true;
6538 fake_host_impl_
= new FakeLayerTreeHostImpl(
6539 settings
, &proxy_
, shared_bitmap_manager_
.get());
6540 host_impl_
.reset(fake_host_impl_
);
6541 host_impl_
->InitializeRenderer(CreateOutputSurface());
6542 host_impl_
->SetViewportSize(gfx::Size(10, 10));
6545 FakeLayerTreeHostImpl
* fake_host_impl_
;
6548 TEST_F(LayerTreeHostImplTestPrepareTiles
, PrepareTilesWhenInvisible
) {
6549 fake_host_impl_
->DidModifyTilePriorities();
6550 EXPECT_TRUE(fake_host_impl_
->prepare_tiles_needed());
6551 fake_host_impl_
->SetVisible(false);
6552 EXPECT_FALSE(fake_host_impl_
->prepare_tiles_needed());
6555 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
6556 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6557 TestWebGraphicsContext3D::Create();
6558 TestWebGraphicsContext3D
* context3d
= context
.get();
6559 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
6560 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
6562 EXPECT_EQ(0u, context3d
->NumTextures());
6564 UIResourceId ui_resource_id
= 1;
6565 bool is_opaque
= false;
6566 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
6567 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6568 EXPECT_EQ(1u, context3d
->NumTextures());
6569 ResourceProvider::ResourceId id1
=
6570 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6573 // Multiple requests with the same id is allowed. The previous texture is
6575 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6576 EXPECT_EQ(1u, context3d
->NumTextures());
6577 ResourceProvider::ResourceId id2
=
6578 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6580 EXPECT_NE(id1
, id2
);
6582 // Deleting invalid UIResourceId is allowed and does not change state.
6583 host_impl_
->DeleteUIResource(-1);
6584 EXPECT_EQ(1u, context3d
->NumTextures());
6586 // Should return zero for invalid UIResourceId. Number of textures should
6588 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
6589 EXPECT_EQ(1u, context3d
->NumTextures());
6591 host_impl_
->DeleteUIResource(ui_resource_id
);
6592 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
6593 EXPECT_EQ(0u, context3d
->NumTextures());
6595 // Should not change state for multiple deletion on one UIResourceId
6596 host_impl_
->DeleteUIResource(ui_resource_id
);
6597 EXPECT_EQ(0u, context3d
->NumTextures());
6600 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
6601 scoped_ptr
<TestWebGraphicsContext3D
> context
=
6602 TestWebGraphicsContext3D::Create();
6603 TestWebGraphicsContext3D
* context3d
= context
.get();
6604 CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d());
6606 EXPECT_EQ(0u, context3d
->NumTextures());
6608 gfx::Size
size(4, 4);
6609 // SkImageInfo has no support for ETC1. The |info| below contains the right
6610 // total pixel size for the bitmap but not the right height and width. The
6611 // correct width/height are passed directly to UIResourceBitmap.
6613 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
6614 skia::RefPtr
<SkPixelRef
> pixel_ref
=
6615 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
6616 pixel_ref
->setImmutable();
6617 UIResourceBitmap
bitmap(pixel_ref
, size
);
6618 UIResourceId ui_resource_id
= 1;
6619 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
6620 EXPECT_EQ(1u, context3d
->NumTextures());
6621 ResourceProvider::ResourceId id1
=
6622 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
6626 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
6629 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
6630 scoped_refptr
<TestContextProvider
> context_provider
=
6631 TestContextProvider::Create();
6633 CreateHostImpl(DefaultSettings(),
6634 FakeOutputSurface::Create3d(context_provider
));
6636 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
6638 ScopedPtrVector
<CopyOutputRequest
> requests
;
6639 requests
.push_back(CopyOutputRequest::CreateRequest(
6640 base::Bind(&ShutdownReleasesContext_Callback
)));
6642 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
6644 LayerTreeHostImpl::FrameData frame
;
6645 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6646 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6647 host_impl_
->DidDrawAllLayers(frame
);
6649 // The CopyOutputResult's callback has a ref on the ContextProvider and a
6650 // texture in a texture mailbox.
6651 EXPECT_FALSE(context_provider
->HasOneRef());
6652 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
6654 host_impl_
= nullptr;
6656 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
6657 // released, and the texture deleted.
6658 EXPECT_TRUE(context_provider
->HasOneRef());
6659 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
6662 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
6663 // When flinging via touch, only the child should scroll (we should not
6665 gfx::Size
surface_size(10, 10);
6666 gfx::Size
content_size(20, 20);
6667 scoped_ptr
<LayerImpl
> root_clip
=
6668 LayerImpl::Create(host_impl_
->active_tree(), 3);
6669 scoped_ptr
<LayerImpl
> root
=
6670 CreateScrollableLayer(1, content_size
, root_clip
.get());
6671 root
->SetIsContainerForFixedPositionLayers(true);
6672 scoped_ptr
<LayerImpl
> child
=
6673 CreateScrollableLayer(2, content_size
, root_clip
.get());
6675 root
->AddChild(child
.Pass());
6676 int root_id
= root
->id();
6677 root_clip
->AddChild(root
.Pass());
6679 host_impl_
->SetViewportSize(surface_size
);
6680 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6681 host_impl_
->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID
, 3, 1,
6683 host_impl_
->active_tree()->DidBecomeActive();
6686 EXPECT_EQ(InputHandler::ScrollStarted
,
6687 host_impl_
->ScrollBegin(gfx::Point(),
6688 InputHandler::Gesture
));
6690 EXPECT_EQ(InputHandler::ScrollStarted
,
6691 host_impl_
->FlingScrollBegin());
6693 gfx::Vector2d
scroll_delta(0, 100);
6694 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6695 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6697 host_impl_
->ScrollEnd();
6699 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6700 host_impl_
->ProcessScrollDeltas();
6702 // Only the child should have scrolled.
6703 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6704 ExpectNone(*scroll_info
.get(), root_id
);
6708 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
6709 // Scroll a child layer beyond its maximum scroll range and make sure the
6710 // the scroll doesn't bubble up to the parent layer.
6711 gfx::Size
surface_size(10, 10);
6712 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
6713 scoped_ptr
<LayerImpl
> root_scrolling
=
6714 CreateScrollableLayer(2, surface_size
, root
.get());
6716 scoped_ptr
<LayerImpl
> grand_child
=
6717 CreateScrollableLayer(4, surface_size
, root
.get());
6718 grand_child
->SetScrollOffset(gfx::ScrollOffset(0, 2));
6720 scoped_ptr
<LayerImpl
> child
=
6721 CreateScrollableLayer(3, surface_size
, root
.get());
6722 child
->SetScrollOffset(gfx::ScrollOffset(0, 4));
6723 child
->AddChild(grand_child
.Pass());
6725 root_scrolling
->AddChild(child
.Pass());
6726 root
->AddChild(root_scrolling
.Pass());
6727 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6728 host_impl_
->active_tree()->DidBecomeActive();
6729 host_impl_
->SetViewportSize(surface_size
);
6732 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
6734 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
6735 LayerImpl
* grand_child
= child
->children()[0];
6737 gfx::Vector2d
scroll_delta(0, -2);
6738 EXPECT_EQ(InputHandler::ScrollStarted
,
6739 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6740 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6742 // The grand child should have scrolled up to its limit.
6743 scroll_info
= host_impl_
->ProcessScrollDeltas();
6744 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6745 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6746 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6748 // The child should have received the bubbled delta, but the locked
6749 // scrolling layer should remain set as the grand child.
6750 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6751 scroll_info
= host_impl_
->ProcessScrollDeltas();
6752 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6753 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6754 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
6755 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6757 // The first |ScrollBy| after the fling should re-lock the scrolling
6758 // layer to the first layer that scrolled, which is the child.
6759 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6760 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6761 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6763 // The child should have scrolled up to its limit.
6764 scroll_info
= host_impl_
->ProcessScrollDeltas();
6765 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6766 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6767 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
6769 // As the locked layer is at it's limit, no further scrolling can occur.
6770 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
6771 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6772 host_impl_
->ScrollEnd();
6776 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
6777 // When flinging via wheel, the root should eventually scroll (we should
6779 gfx::Size
surface_size(10, 10);
6780 gfx::Size
content_size(20, 20);
6781 scoped_ptr
<LayerImpl
> root_clip
=
6782 LayerImpl::Create(host_impl_
->active_tree(), 3);
6783 scoped_ptr
<LayerImpl
> root_scroll
=
6784 CreateScrollableLayer(1, content_size
, root_clip
.get());
6785 int root_scroll_id
= root_scroll
->id();
6786 scoped_ptr
<LayerImpl
> child
=
6787 CreateScrollableLayer(2, content_size
, root_clip
.get());
6789 root_scroll
->AddChild(child
.Pass());
6790 root_clip
->AddChild(root_scroll
.Pass());
6792 host_impl_
->SetViewportSize(surface_size
);
6793 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6794 host_impl_
->active_tree()->DidBecomeActive();
6797 EXPECT_EQ(InputHandler::ScrollStarted
,
6798 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6800 EXPECT_EQ(InputHandler::ScrollStarted
,
6801 host_impl_
->FlingScrollBegin());
6803 gfx::Vector2d
scroll_delta(0, 100);
6804 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6805 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6807 host_impl_
->ScrollEnd();
6809 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6810 host_impl_
->ProcessScrollDeltas();
6812 // The root should have scrolled.
6813 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6814 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6818 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6819 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6820 // we should return ScrollUnknown.
6821 gfx::Size
content_size(100, 100);
6822 SetupScrollAndContentsLayers(content_size
);
6824 int scroll_layer_id
= 2;
6825 LayerImpl
* scroll_layer
=
6826 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6827 scroll_layer
->SetDrawsContent(true);
6829 int page_scale_layer_id
= 5;
6830 LayerImpl
* page_scale_layer
=
6831 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6833 int occluder_layer_id
= 6;
6834 scoped_ptr
<LayerImpl
> occluder_layer
=
6835 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6836 occluder_layer
->SetDrawsContent(true);
6837 occluder_layer
->SetBounds(content_size
);
6838 occluder_layer
->SetContentBounds(content_size
);
6839 occluder_layer
->SetPosition(gfx::PointF());
6841 // The parent of the occluder is *above* the scroller.
6842 page_scale_layer
->AddChild(occluder_layer
.Pass());
6846 EXPECT_EQ(InputHandler::ScrollUnknown
,
6847 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6850 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6851 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6852 // is not the first scroller we encounter when walking up from the layer, we
6853 // should also return ScrollUnknown.
6854 gfx::Size
content_size(100, 100);
6855 SetupScrollAndContentsLayers(content_size
);
6857 int scroll_layer_id
= 2;
6858 LayerImpl
* scroll_layer
=
6859 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6860 scroll_layer
->SetDrawsContent(true);
6862 int occluder_layer_id
= 6;
6863 scoped_ptr
<LayerImpl
> occluder_layer
=
6864 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6865 occluder_layer
->SetDrawsContent(true);
6866 occluder_layer
->SetBounds(content_size
);
6867 occluder_layer
->SetContentBounds(content_size
);
6868 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6870 int child_scroll_clip_layer_id
= 7;
6871 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6872 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6874 int child_scroll_layer_id
= 8;
6875 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6876 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6878 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6880 child_scroll
->AddChild(occluder_layer
.Pass());
6881 scroll_layer
->AddChild(child_scroll
.Pass());
6885 EXPECT_EQ(InputHandler::ScrollUnknown
,
6886 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6889 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6890 gfx::Size
content_size(100, 100);
6891 SetupScrollAndContentsLayers(content_size
);
6893 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6895 int scroll_layer_id
= 2;
6896 LayerImpl
* scroll_layer
=
6897 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6899 int child_scroll_layer_id
= 7;
6900 scoped_ptr
<LayerImpl
> child_scroll
=
6901 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6902 child_scroll
->SetDrawsContent(false);
6904 scroll_layer
->AddChild(child_scroll
.Pass());
6908 // We should not have scrolled |child_scroll| even though we technically "hit"
6909 // it. The reason for this is that if the scrolling the scroll would not move
6910 // any layer that is a drawn RSLL member, then we can ignore the hit.
6912 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6913 // overscrolling the inner viewport.
6914 EXPECT_EQ(InputHandler::ScrollStarted
,
6915 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6917 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6920 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6921 // This test case is very similar to the one above with one key difference:
6922 // the invisible scroller has a scroll child that is indeed draw contents.
6923 // If we attempt to initiate a gesture scroll off of the visible scroll child
6924 // we should still start the scroll child.
6925 gfx::Size
content_size(100, 100);
6926 SetupScrollAndContentsLayers(content_size
);
6928 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6930 int scroll_layer_id
= 2;
6931 LayerImpl
* scroll_layer
=
6932 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6934 int scroll_child_id
= 6;
6935 scoped_ptr
<LayerImpl
> scroll_child
=
6936 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6937 scroll_child
->SetDrawsContent(true);
6938 scroll_child
->SetBounds(content_size
);
6939 scroll_child
->SetContentBounds(content_size
);
6940 // Move the scroll child so it's not hit by our test point.
6941 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6943 int invisible_scroll_layer_id
= 7;
6944 scoped_ptr
<LayerImpl
> invisible_scroll
=
6945 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6946 invisible_scroll
->SetDrawsContent(false);
6948 int container_id
= 8;
6949 scoped_ptr
<LayerImpl
> container
=
6950 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6952 scoped_ptr
<std::set
<LayerImpl
*>> scroll_children(new std::set
<LayerImpl
*>);
6953 scroll_children
->insert(scroll_child
.get());
6954 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6956 scroll_child
->SetScrollParent(invisible_scroll
.get());
6958 container
->AddChild(invisible_scroll
.Pass());
6959 container
->AddChild(scroll_child
.Pass());
6961 scroll_layer
->AddChild(container
.Pass());
6965 // We should not have scrolled |child_scroll| even though we technically "hit"
6966 // it. The reason for this is that if the scrolling the scroll would not move
6967 // any layer that is a drawn RSLL member, then we can ignore the hit.
6969 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6970 // overscrolling the inner viewport.
6971 EXPECT_EQ(InputHandler::ScrollStarted
,
6972 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6974 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6977 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6978 // to CompositorFrameMetadata after SwapBuffers();
6979 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6980 scoped_ptr
<SolidColorLayerImpl
> root
=
6981 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6982 root
->SetPosition(gfx::PointF());
6983 root
->SetBounds(gfx::Size(10, 10));
6984 root
->SetContentBounds(gfx::Size(10, 10));
6985 root
->SetDrawsContent(true);
6987 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6989 FakeOutputSurface
* fake_output_surface
=
6990 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6992 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6993 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6994 EXPECT_TRUE(metadata_latency_before
.empty());
6996 ui::LatencyInfo latency_info
;
6997 latency_info
.AddLatencyNumber(
6998 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6999 scoped_ptr
<SwapPromise
> swap_promise(
7000 new LatencyInfoSwapPromise(latency_info
));
7001 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
7002 host_impl_
->SetNeedsRedraw();
7004 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
7005 LayerTreeHostImpl::FrameData frame
;
7006 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
7007 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
7008 host_impl_
->DidDrawAllLayers(frame
);
7009 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
7011 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
7012 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
7013 EXPECT_EQ(1u, metadata_latency_after
.size());
7014 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
7015 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
7018 TEST_F(LayerTreeHostImplTest
, SelectionBoundsPassedToCompositorFrameMetadata
) {
7019 int root_layer_id
= 1;
7020 scoped_ptr
<SolidColorLayerImpl
> root
=
7021 SolidColorLayerImpl::Create(host_impl_
->active_tree(), root_layer_id
);
7022 root
->SetPosition(gfx::PointF());
7023 root
->SetBounds(gfx::Size(10, 10));
7024 root
->SetContentBounds(gfx::Size(10, 10));
7025 root
->SetDrawsContent(true);
7027 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
7029 // Ensure the default frame selection bounds are empty.
7030 FakeOutputSurface
* fake_output_surface
=
7031 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
7032 const ViewportSelectionBound
& selection_start_before
=
7033 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
7034 const ViewportSelectionBound
& selection_end_before
=
7035 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
7036 EXPECT_EQ(ViewportSelectionBound(), selection_start_before
);
7037 EXPECT_EQ(ViewportSelectionBound(), selection_end_before
);
7039 // Plumb the layer-local selection bounds.
7040 gfx::PointF
selection_top(5, 0);
7041 gfx::PointF
selection_bottom(5, 5);
7042 LayerSelectionBound start
, end
;
7043 start
.type
= SELECTION_BOUND_CENTER
;
7044 start
.layer_id
= root_layer_id
;
7045 start
.edge_bottom
= selection_bottom
;
7046 start
.edge_top
= selection_top
;
7048 host_impl_
->active_tree()->RegisterSelection(start
, end
);
7050 // Trigger a draw-swap sequence.
7051 host_impl_
->SetNeedsRedraw();
7053 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
7054 LayerTreeHostImpl::FrameData frame
;
7055 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
7056 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
7057 host_impl_
->DidDrawAllLayers(frame
);
7058 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
7060 // Ensure the selection bounds have propagated to the frame metadata.
7061 const ViewportSelectionBound
& selection_start_after
=
7062 fake_output_surface
->last_sent_frame().metadata
.selection_start
;
7063 const ViewportSelectionBound
& selection_end_after
=
7064 fake_output_surface
->last_sent_frame().metadata
.selection_end
;
7065 EXPECT_EQ(start
.type
, selection_start_after
.type
);
7066 EXPECT_EQ(end
.type
, selection_end_after
.type
);
7067 EXPECT_EQ(selection_bottom
, selection_start_after
.edge_bottom
);
7068 EXPECT_EQ(selection_top
, selection_start_after
.edge_top
);
7069 EXPECT_TRUE(selection_start_after
.visible
);
7070 EXPECT_TRUE(selection_start_after
.visible
);
7073 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
7075 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
7076 LayerTreeHostImpl
* layer_tree_host_impl
,
7077 int* set_needs_commit_count
,
7078 int* set_needs_redraw_count
,
7079 int* forward_to_main_count
)
7080 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
7081 set_needs_commit_count_(set_needs_commit_count
),
7082 set_needs_redraw_count_(set_needs_redraw_count
),
7083 forward_to_main_count_(forward_to_main_count
) {}
7085 ~SimpleSwapPromiseMonitor() override
{}
7087 void OnSetNeedsCommitOnMain() override
{ (*set_needs_commit_count_
)++; }
7089 void OnSetNeedsRedrawOnImpl() override
{ (*set_needs_redraw_count_
)++; }
7091 void OnForwardScrollUpdateToMainThreadOnImpl() override
{
7092 (*forward_to_main_count_
)++;
7096 int* set_needs_commit_count_
;
7097 int* set_needs_redraw_count_
;
7098 int* forward_to_main_count_
;
7101 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
7102 int set_needs_commit_count
= 0;
7103 int set_needs_redraw_count
= 0;
7104 int forward_to_main_count
= 0;
7107 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7108 new SimpleSwapPromiseMonitor(NULL
,
7110 &set_needs_commit_count
,
7111 &set_needs_redraw_count
,
7112 &forward_to_main_count
));
7113 host_impl_
->SetNeedsRedraw();
7114 EXPECT_EQ(0, set_needs_commit_count
);
7115 EXPECT_EQ(1, set_needs_redraw_count
);
7116 EXPECT_EQ(0, forward_to_main_count
);
7119 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
7121 host_impl_
->SetNeedsRedraw();
7122 EXPECT_EQ(0, set_needs_commit_count
);
7123 EXPECT_EQ(1, set_needs_redraw_count
);
7124 EXPECT_EQ(0, forward_to_main_count
);
7127 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7128 new SimpleSwapPromiseMonitor(NULL
,
7130 &set_needs_commit_count
,
7131 &set_needs_redraw_count
,
7132 &forward_to_main_count
));
7133 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
7134 EXPECT_EQ(0, set_needs_commit_count
);
7135 EXPECT_EQ(2, set_needs_redraw_count
);
7136 EXPECT_EQ(0, forward_to_main_count
);
7140 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7141 new SimpleSwapPromiseMonitor(NULL
,
7143 &set_needs_commit_count
,
7144 &set_needs_redraw_count
,
7145 &forward_to_main_count
));
7146 // Empty damage rect won't signal the monitor.
7147 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
7148 EXPECT_EQ(0, set_needs_commit_count
);
7149 EXPECT_EQ(2, set_needs_redraw_count
);
7150 EXPECT_EQ(0, forward_to_main_count
);
7154 set_needs_commit_count
= 0;
7155 set_needs_redraw_count
= 0;
7156 forward_to_main_count
= 0;
7157 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
7158 new SimpleSwapPromiseMonitor(NULL
,
7160 &set_needs_commit_count
,
7161 &set_needs_redraw_count
,
7162 &forward_to_main_count
));
7163 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
7165 // Scrolling normally should not trigger any forwarding.
7166 EXPECT_EQ(InputHandler::ScrollStarted
,
7167 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7169 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
7170 host_impl_
->ScrollEnd();
7172 EXPECT_EQ(0, set_needs_commit_count
);
7173 EXPECT_EQ(1, set_needs_redraw_count
);
7174 EXPECT_EQ(0, forward_to_main_count
);
7176 // Scrolling with a scroll handler should defer the swap to the main
7178 scroll_layer
->SetHaveScrollEventHandlers(true);
7179 EXPECT_EQ(InputHandler::ScrollStarted
,
7180 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7182 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll
);
7183 host_impl_
->ScrollEnd();
7185 EXPECT_EQ(0, set_needs_commit_count
);
7186 EXPECT_EQ(2, set_needs_redraw_count
);
7187 EXPECT_EQ(1, forward_to_main_count
);
7191 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
7193 void SetUp() override
{
7194 LayerTreeSettings settings
= DefaultSettings();
7195 settings
.calculate_top_controls_position
= true;
7196 CreateHostImpl(settings
, CreateOutputSurface());
7197 host_impl_
->active_tree()->set_top_controls_height(top_controls_height_
);
7198 host_impl_
->active_tree()->set_top_controls_delta(top_controls_height_
);
7199 host_impl_
->top_controls_manager()->SetTopControlsHeight(
7200 top_controls_height_
);
7204 static const int top_controls_height_
;
7207 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
7209 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
7210 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7211 ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7212 host_impl_
->Animate(base::TimeTicks());
7213 EXPECT_FALSE(did_request_redraw_
);
7216 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsHeightIsCommitted
) {
7217 SetupScrollAndContentsLayers(gfx::Size(100, 100));
7218 EXPECT_FALSE(did_request_redraw_
);
7219 host_impl_
->CreatePendingTree();
7220 host_impl_
->sync_tree()->set_top_controls_height(100);
7221 host_impl_
->ActivateSyncTree();
7222 EXPECT_EQ(100, host_impl_
->top_controls_manager()->top_controls_height());
7225 TEST_F(LayerTreeHostImplWithTopControlsTest
,
7226 TopControlsStayFullyVisibleOnHeightChange
) {
7227 SetupScrollAndContentsLayers(gfx::Size(100, 100));
7228 EXPECT_EQ(0.f
, host_impl_
->ControlsTopOffset());
7230 host_impl_
->CreatePendingTree();
7231 host_impl_
->sync_tree()->set_top_controls_height(0);
7232 host_impl_
->ActivateSyncTree();
7233 EXPECT_EQ(0.f
, host_impl_
->ControlsTopOffset());
7235 host_impl_
->CreatePendingTree();
7236 host_impl_
->sync_tree()->set_top_controls_height(50);
7237 host_impl_
->ActivateSyncTree();
7238 EXPECT_EQ(0.f
, host_impl_
->ControlsTopOffset());
7241 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
7242 SetupScrollAndContentsLayers(gfx::Size(100, 100))
7243 ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7244 host_impl_
->DidChangeTopControlsPosition();
7245 EXPECT_TRUE(did_request_animate_
);
7246 EXPECT_TRUE(did_request_redraw_
);
7249 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
7250 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7251 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7252 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7253 BOTH
, SHOWN
, false);
7256 EXPECT_EQ(InputHandler::ScrollStarted
,
7257 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7258 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7259 EXPECT_EQ(gfx::Vector2dF().ToString(),
7260 scroll_layer
->TotalScrollOffset().ToString());
7262 // Scroll just the top controls and verify that the scroll succeeds.
7263 const float residue
= 10;
7264 float offset
= top_controls_height_
- residue
;
7266 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7267 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7268 EXPECT_EQ(gfx::Vector2dF().ToString(),
7269 scroll_layer
->TotalScrollOffset().ToString());
7271 // Scroll across the boundary
7272 const float content_scroll
= 20;
7273 offset
= residue
+ content_scroll
;
7275 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7276 EXPECT_EQ(-top_controls_height_
,
7277 host_impl_
->top_controls_manager()->ControlsTopOffset());
7278 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
7279 scroll_layer
->TotalScrollOffset().ToString());
7281 // Now scroll back to the top of the content
7282 offset
= -content_scroll
;
7284 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7285 EXPECT_EQ(-top_controls_height_
,
7286 host_impl_
->top_controls_manager()->ControlsTopOffset());
7287 EXPECT_EQ(gfx::Vector2dF().ToString(),
7288 scroll_layer
->TotalScrollOffset().ToString());
7290 // And scroll the top controls completely into view
7291 offset
= -top_controls_height_
;
7293 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7294 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7295 EXPECT_EQ(gfx::Vector2dF().ToString(),
7296 scroll_layer
->TotalScrollOffset().ToString());
7298 // And attempt to scroll past the end
7300 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7301 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7302 EXPECT_EQ(gfx::Vector2dF().ToString(),
7303 scroll_layer
->TotalScrollOffset().ToString());
7305 host_impl_
->ScrollEnd();
7308 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAtOrigin
) {
7309 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7310 host_impl_
->SetViewportSize(gfx::Size(100, 200));
7311 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7312 BOTH
, SHOWN
, false);
7315 EXPECT_EQ(InputHandler::ScrollStarted
,
7316 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7317 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7318 EXPECT_EQ(gfx::Vector2dF().ToString(),
7319 scroll_layer
->TotalScrollOffset().ToString());
7321 // Scroll the top controls partially.
7322 const float residue
= 35;
7323 float offset
= top_controls_height_
- residue
;
7325 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7326 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7327 EXPECT_EQ(gfx::Vector2dF().ToString(),
7328 scroll_layer
->TotalScrollOffset().ToString());
7330 did_request_redraw_
= false;
7331 did_request_animate_
= false;
7332 did_request_commit_
= false;
7334 // End the scroll while the controls are still offset from their limit.
7335 host_impl_
->ScrollEnd();
7336 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7337 EXPECT_TRUE(did_request_animate_
);
7338 EXPECT_TRUE(did_request_redraw_
);
7339 EXPECT_FALSE(did_request_commit_
);
7341 // The top controls should properly animate until finished, despite the scroll
7342 // offset being at the origin.
7343 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7344 while (did_request_animate_
) {
7345 did_request_redraw_
= false;
7346 did_request_animate_
= false;
7347 did_request_commit_
= false;
7350 host_impl_
->top_controls_manager()->ControlsTopOffset();
7352 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7353 host_impl_
->Animate(animation_time
);
7354 EXPECT_EQ(gfx::Vector2dF().ToString(),
7355 scroll_layer
->TotalScrollOffset().ToString());
7358 host_impl_
->top_controls_manager()->ControlsTopOffset();
7360 // No commit is needed as the controls are animating the content offset,
7361 // not the scroll offset.
7362 EXPECT_FALSE(did_request_commit_
);
7364 if (new_offset
!= old_offset
)
7365 EXPECT_TRUE(did_request_redraw_
);
7367 if (new_offset
!= 0) {
7368 EXPECT_TRUE(host_impl_
->top_controls_manager()->animation());
7369 EXPECT_TRUE(did_request_animate_
);
7372 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7375 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationAfterScroll
) {
7376 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7377 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7378 host_impl_
->top_controls_manager()->UpdateTopControlsState(
7379 BOTH
, SHOWN
, false);
7380 float initial_scroll_offset
= 50;
7381 scroll_layer
->SetScrollOffset(gfx::ScrollOffset(0, initial_scroll_offset
));
7384 EXPECT_EQ(InputHandler::ScrollStarted
,
7385 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7386 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7387 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7388 scroll_layer
->TotalScrollOffset().ToString());
7390 // Scroll the top controls partially.
7391 const float residue
= 15;
7392 float offset
= top_controls_height_
- residue
;
7394 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7395 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7396 EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset
).ToString(),
7397 scroll_layer
->TotalScrollOffset().ToString());
7399 did_request_redraw_
= false;
7400 did_request_animate_
= false;
7401 did_request_commit_
= false;
7403 // End the scroll while the controls are still offset from the limit.
7404 host_impl_
->ScrollEnd();
7405 ASSERT_TRUE(host_impl_
->top_controls_manager()->animation());
7406 EXPECT_TRUE(did_request_animate_
);
7407 EXPECT_TRUE(did_request_redraw_
);
7408 EXPECT_FALSE(did_request_commit_
);
7410 // Animate the top controls to the limit.
7411 base::TimeTicks animation_time
= gfx::FrameTime::Now();
7412 while (did_request_animate_
) {
7413 did_request_redraw_
= false;
7414 did_request_animate_
= false;
7415 did_request_commit_
= false;
7418 host_impl_
->top_controls_manager()->ControlsTopOffset();
7420 animation_time
+= base::TimeDelta::FromMilliseconds(5);
7421 host_impl_
->Animate(animation_time
);
7424 host_impl_
->top_controls_manager()->ControlsTopOffset();
7426 if (new_offset
!= old_offset
) {
7427 EXPECT_TRUE(did_request_redraw_
);
7428 EXPECT_TRUE(did_request_commit_
);
7431 EXPECT_FALSE(host_impl_
->top_controls_manager()->animation());
7434 TEST_F(LayerTreeHostImplWithTopControlsTest
,
7435 TopControlsScrollDeltaInOverScroll
) {
7436 // test varifies that the overscroll delta should not have accumulated in
7437 // the top controls if we do a hide and show without releasing finger.
7439 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
7440 host_impl_
->SetViewportSize(gfx::Size(100, 100));
7441 host_impl_
->top_controls_manager()->UpdateTopControlsState(BOTH
, SHOWN
,
7445 EXPECT_EQ(InputHandler::ScrollStarted
,
7446 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7447 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7451 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7452 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7453 EXPECT_EQ(gfx::Vector2dF().ToString(),
7454 scroll_layer
->TotalScrollOffset().ToString());
7457 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7458 EXPECT_EQ(gfx::Vector2dF(0, offset
).ToString(),
7459 scroll_layer
->TotalScrollOffset().ToString());
7462 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)).did_scroll
);
7464 // Should have fully scrolled
7465 EXPECT_EQ(gfx::Vector2dF(0, scroll_layer
->MaxScrollOffset().y()).ToString(),
7466 scroll_layer
->TotalScrollOffset().ToString());
7468 float overscrollamount
= 10;
7470 // Overscroll the content
7472 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, overscrollamount
))
7474 EXPECT_EQ(gfx::Vector2dF(0, 2 * offset
).ToString(),
7475 scroll_layer
->TotalScrollOffset().ToString());
7476 EXPECT_EQ(gfx::Vector2dF(0, overscrollamount
).ToString(),
7477 host_impl_
->accumulated_root_overscroll().ToString());
7479 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -2 * offset
))
7481 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
7482 scroll_layer
->TotalScrollOffset().ToString());
7483 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->ControlsTopOffset());
7486 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -offset
)).did_scroll
);
7487 EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(),
7488 scroll_layer
->TotalScrollOffset().ToString());
7490 // Top controls should be fully visible
7491 EXPECT_EQ(0, host_impl_
->top_controls_manager()->ControlsTopOffset());
7493 host_impl_
->ScrollEnd();
7496 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
7498 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
7499 const gfx::Size
& outer_viewport
,
7500 const gfx::Size
& inner_viewport
) {
7501 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
7502 const int kOuterViewportClipLayerId
= 6;
7503 const int kOuterViewportScrollLayerId
= 7;
7504 const int kInnerViewportScrollLayerId
= 2;
7505 const int kInnerViewportClipLayerId
= 4;
7506 const int kPageScaleLayerId
= 5;
7508 scoped_ptr
<LayerImpl
> inner_scroll
=
7509 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
7510 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
7511 inner_scroll
->SetScrollOffset(gfx::ScrollOffset());
7513 scoped_ptr
<LayerImpl
> inner_clip
=
7514 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
7515 inner_clip
->SetBounds(inner_viewport
);
7517 scoped_ptr
<LayerImpl
> page_scale
=
7518 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
7520 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
7521 inner_scroll
->SetBounds(outer_viewport
);
7522 inner_scroll
->SetContentBounds(outer_viewport
);
7523 inner_scroll
->SetPosition(gfx::PointF());
7525 scoped_ptr
<LayerImpl
> outer_clip
=
7526 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
7527 outer_clip
->SetBounds(outer_viewport
);
7528 outer_clip
->SetIsContainerForFixedPositionLayers(true);
7530 scoped_ptr
<LayerImpl
> outer_scroll
=
7531 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
7532 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
7533 outer_scroll
->SetScrollOffset(gfx::ScrollOffset());
7534 outer_scroll
->SetBounds(content_size
);
7535 outer_scroll
->SetContentBounds(content_size
);
7536 outer_scroll
->SetPosition(gfx::PointF());
7538 scoped_ptr
<LayerImpl
> contents
=
7539 LayerImpl::Create(layer_tree_impl
, 8);
7540 contents
->SetDrawsContent(true);
7541 contents
->SetBounds(content_size
);
7542 contents
->SetContentBounds(content_size
);
7543 contents
->SetPosition(gfx::PointF());
7545 outer_scroll
->AddChild(contents
.Pass());
7546 outer_clip
->AddChild(outer_scroll
.Pass());
7547 inner_scroll
->AddChild(outer_clip
.Pass());
7548 page_scale
->AddChild(inner_scroll
.Pass());
7549 inner_clip
->AddChild(page_scale
.Pass());
7551 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
7552 layer_tree_impl
->SetViewportLayersFromIds(
7553 Layer::INVALID_ID
, kPageScaleLayerId
, kInnerViewportScrollLayerId
,
7554 kOuterViewportScrollLayerId
);
7556 host_impl_
->active_tree()->DidBecomeActive();
7560 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
7561 gfx::Size content_size
= gfx::Size(100, 160);
7562 gfx::Size outer_viewport
= gfx::Size(50, 80);
7563 gfx::Size inner_viewport
= gfx::Size(25, 40);
7565 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7567 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7568 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7571 gfx::Vector2dF inner_expected
;
7572 gfx::Vector2dF outer_expected
;
7573 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7574 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7576 // Make sure the fling goes to the outer viewport first
7577 EXPECT_EQ(InputHandler::ScrollStarted
,
7578 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7579 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7581 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
7582 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7583 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7585 host_impl_
->ScrollEnd();
7587 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7588 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7590 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
7591 EXPECT_EQ(InputHandler::ScrollStarted
,
7592 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7593 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7595 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7596 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7598 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7599 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
7601 host_impl_
->ScrollEnd();
7603 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7604 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7608 TEST_F(LayerTreeHostImplVirtualViewportTest
,
7609 DiagonalScrollBubblesPerfectlyToInner
) {
7610 gfx::Size content_size
= gfx::Size(100, 160);
7611 gfx::Size outer_viewport
= gfx::Size(50, 80);
7612 gfx::Size inner_viewport
= gfx::Size(25, 40);
7614 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7616 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7617 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7620 gfx::Vector2dF inner_expected
;
7621 gfx::Vector2dF outer_expected
;
7622 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7623 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7625 // Make sure the scroll goes to the outer viewport first.
7626 EXPECT_EQ(InputHandler::ScrollStarted
,
7627 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7628 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7630 // Scroll near the edge of the outer viewport.
7631 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
7632 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7633 outer_expected
+= scroll_delta
;
7635 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7636 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7638 // Now diagonal scroll across the outer viewport boundary in a single event.
7639 // The entirety of the scroll should be consumed, as bubbling between inner
7640 // and outer viewport layers is perfect.
7641 host_impl_
->ScrollBy(gfx::Point(), gfx::ScaleVector2d(scroll_delta
, 2));
7642 outer_expected
+= scroll_delta
;
7643 inner_expected
+= scroll_delta
;
7644 host_impl_
->ScrollEnd();
7646 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
7647 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
7651 TEST_F(LayerTreeHostImplVirtualViewportTest
,
7652 TouchFlingCanLockToViewportLayerAfterBubbling
) {
7653 gfx::Size content_size
= gfx::Size(100, 160);
7654 gfx::Size outer_viewport
= gfx::Size(50, 80);
7655 gfx::Size inner_viewport
= gfx::Size(25, 40);
7657 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
7659 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
7660 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
7662 scoped_ptr
<LayerImpl
> child
=
7663 CreateScrollableLayer(10, outer_viewport
, outer_scroll
);
7664 LayerImpl
* child_scroll
= child
.get();
7665 outer_scroll
->children()[0]->AddChild(child
.Pass());
7669 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
7671 gfx::Vector2d
scroll_delta(0, inner_viewport
.height());
7672 EXPECT_EQ(InputHandler::ScrollStarted
,
7673 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
7674 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
7676 // The child should have scrolled up to its limit.
7677 scroll_info
= host_impl_
->ProcessScrollDeltas();
7678 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
7679 ExpectContains(*scroll_info
, child_scroll
->id(), scroll_delta
);
7680 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_scroll
);
7682 // The first |ScrollBy| after the fling should re-lock the scrolling
7683 // layer to the first layer that scrolled, the inner viewport scroll layer.
7684 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
7685 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
7686 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
7688 // The inner viewport should have scrolled up to its limit.
7689 scroll_info
= host_impl_
->ProcessScrollDeltas();
7690 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
7691 ExpectContains(*scroll_info
, child_scroll
->id(), scroll_delta
);
7692 ExpectContains(*scroll_info
, inner_scroll
->id(), scroll_delta
);
7694 // As the locked layer is at its limit, no further scrolling can occur.
7695 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
).did_scroll
);
7696 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), inner_scroll
);
7697 host_impl_
->ScrollEnd();
7701 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
7703 void SetUp() override
{
7704 LayerTreeSettings settings
= DefaultSettings();
7705 settings
.max_memory_for_prepaint_percentage
= 50;
7706 CreateHostImpl(settings
, CreateOutputSurface());
7710 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
7711 // Set up a memory policy and percentages which could cause
7712 // 32-bit integer overflows.
7713 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
7715 // Verify implicit limits are calculated correctly with no overflows
7716 host_impl_
->SetMemoryPolicy(mem_policy
);
7717 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
7718 300u * 1024u * 1024u);
7719 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
7720 150u * 1024u * 1024u);
7723 TEST_F(LayerTreeHostImplTest
, ExternalTransformReflectedInNextDraw
) {
7724 const gfx::Size
layer_size(100, 100);
7725 gfx::Transform external_transform
;
7726 const gfx::Rect
external_viewport(layer_size
);
7727 const gfx::Rect
external_clip(layer_size
);
7728 const bool resourceless_software_draw
= false;
7729 LayerImpl
* layer
= SetupScrollAndContentsLayers(layer_size
);
7731 host_impl_
->SetExternalDrawConstraints(external_transform
,
7736 resourceless_software_draw
);
7738 EXPECT_TRANSFORMATION_MATRIX_EQ(
7739 external_transform
, layer
->draw_properties().target_space_transform
);
7741 external_transform
.Translate(20, 20);
7742 host_impl_
->SetExternalDrawConstraints(external_transform
,
7747 resourceless_software_draw
);
7749 EXPECT_TRANSFORMATION_MATRIX_EQ(
7750 external_transform
, layer
->draw_properties().target_space_transform
);
7753 TEST_F(LayerTreeHostImplTest
, ScrollAnimated
) {
7754 SetupScrollAndContentsLayers(gfx::Size(100, 200));
7757 base::TimeTicks start_time
=
7758 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
7760 EXPECT_EQ(InputHandler::ScrollStarted
,
7761 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7763 LayerImpl
* scrolling_layer
= host_impl_
->CurrentlyScrollingLayer();
7765 host_impl_
->Animate(start_time
);
7766 host_impl_
->UpdateAnimationState(true);
7768 EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer
->TotalScrollOffset());
7770 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(50));
7771 host_impl_
->UpdateAnimationState(true);
7773 float y
= scrolling_layer
->TotalScrollOffset().y();
7774 EXPECT_TRUE(y
> 1 && y
< 49);
7777 EXPECT_EQ(InputHandler::ScrollStarted
,
7778 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7780 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(200));
7781 host_impl_
->UpdateAnimationState(true);
7783 y
= scrolling_layer
->TotalScrollOffset().y();
7784 EXPECT_TRUE(y
> 50 && y
< 100);
7785 EXPECT_EQ(scrolling_layer
, host_impl_
->CurrentlyScrollingLayer());
7787 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(250));
7788 host_impl_
->UpdateAnimationState(true);
7790 EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
7791 scrolling_layer
->TotalScrollOffset());
7792 EXPECT_EQ(NULL
, host_impl_
->CurrentlyScrollingLayer());
7795 TEST_F(LayerTreeHostImplTest
, GetPictureLayerImplPairs
) {
7796 host_impl_
->CreatePendingTree();
7797 host_impl_
->pending_tree()->SetRootLayer(
7798 PictureLayerImpl::Create(host_impl_
->pending_tree(), 10, false));
7800 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
7801 LayerImpl
* pending_layer
= pending_tree
->root_layer();
7803 std::vector
<PictureLayerImpl::Pair
> layer_pairs
;
7804 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
7805 EXPECT_EQ(1u, layer_pairs
.size());
7806 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7807 EXPECT_EQ(nullptr, layer_pairs
[0].active
);
7809 host_impl_
->ActivateSyncTree();
7811 LayerTreeImpl
* active_tree
= host_impl_
->active_tree();
7812 LayerImpl
* active_layer
= active_tree
->root_layer();
7813 EXPECT_NE(active_tree
, pending_tree
);
7814 EXPECT_NE(active_layer
, pending_layer
);
7815 EXPECT_NE(nullptr, active_tree
);
7816 EXPECT_NE(nullptr, active_layer
);
7818 host_impl_
->CreatePendingTree();
7820 layer_pairs
.clear();
7821 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
7822 EXPECT_EQ(1u, layer_pairs
.size());
7823 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7824 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7826 // Activate, the active layer has no twin now.
7827 host_impl_
->ActivateSyncTree();
7829 layer_pairs
.clear();
7830 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
7831 EXPECT_EQ(1u, layer_pairs
.size());
7832 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7833 EXPECT_EQ(nullptr, layer_pairs
[0].pending
);
7835 // Create another layer in the pending tree that's not in the active tree. We
7836 // should get two pairs.
7837 host_impl_
->CreatePendingTree();
7838 host_impl_
->pending_tree()->root_layer()->AddChild(
7839 PictureLayerImpl::Create(host_impl_
->pending_tree(), 11, false));
7841 LayerImpl
* new_pending_layer
= pending_tree
->root_layer()->children()[0];
7843 layer_pairs
.clear();
7844 host_impl_
->GetPictureLayerImplPairs(&layer_pairs
, true);
7845 EXPECT_EQ(2u, layer_pairs
.size());
7847 // The pair ordering is flaky, so make it consistent.
7848 if (layer_pairs
[0].active
!= active_layer
)
7849 std::swap(layer_pairs
[0], layer_pairs
[1]);
7851 EXPECT_EQ(active_layer
, layer_pairs
[0].active
);
7852 EXPECT_EQ(pending_layer
, layer_pairs
[0].pending
);
7853 EXPECT_EQ(new_pending_layer
, layer_pairs
[1].pending
);
7854 EXPECT_EQ(nullptr, layer_pairs
[1].active
);
7857 TEST_F(LayerTreeHostImplTest
, DidBecomeActive
) {
7858 host_impl_
->CreatePendingTree();
7859 host_impl_
->ActivateSyncTree();
7860 host_impl_
->CreatePendingTree();
7862 LayerTreeImpl
* pending_tree
= host_impl_
->pending_tree();
7864 scoped_ptr
<FakePictureLayerImpl
> pending_layer
=
7865 FakePictureLayerImpl::Create(pending_tree
, 10);
7866 pending_layer
->DoPostCommitInitializationIfNeeded();
7867 FakePictureLayerImpl
* raw_pending_layer
= pending_layer
.get();
7868 pending_tree
->SetRootLayer(pending_layer
.Pass());
7869 ASSERT_EQ(raw_pending_layer
, pending_tree
->root_layer());
7871 EXPECT_EQ(0u, raw_pending_layer
->did_become_active_call_count());
7872 pending_tree
->DidBecomeActive();
7873 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
7875 scoped_ptr
<FakePictureLayerImpl
> mask_layer
=
7876 FakePictureLayerImpl::Create(pending_tree
, 11);
7877 mask_layer
->DoPostCommitInitializationIfNeeded();
7878 FakePictureLayerImpl
* raw_mask_layer
= mask_layer
.get();
7879 raw_pending_layer
->SetMaskLayer(mask_layer
.Pass());
7880 ASSERT_EQ(raw_mask_layer
, raw_pending_layer
->mask_layer());
7882 EXPECT_EQ(1u, raw_pending_layer
->did_become_active_call_count());
7883 EXPECT_EQ(0u, raw_mask_layer
->did_become_active_call_count());
7884 pending_tree
->DidBecomeActive();
7885 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
7886 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
7888 scoped_ptr
<FakePictureLayerImpl
> replica_layer
=
7889 FakePictureLayerImpl::Create(pending_tree
, 12);
7890 scoped_ptr
<FakePictureLayerImpl
> replica_mask_layer
=
7891 FakePictureLayerImpl::Create(pending_tree
, 13);
7892 replica_mask_layer
->DoPostCommitInitializationIfNeeded();
7893 FakePictureLayerImpl
* raw_replica_mask_layer
= replica_mask_layer
.get();
7894 replica_layer
->SetMaskLayer(replica_mask_layer
.Pass());
7895 raw_pending_layer
->SetReplicaLayer(replica_layer
.Pass());
7896 ASSERT_EQ(raw_replica_mask_layer
,
7897 raw_pending_layer
->replica_layer()->mask_layer());
7899 EXPECT_EQ(2u, raw_pending_layer
->did_become_active_call_count());
7900 EXPECT_EQ(1u, raw_mask_layer
->did_become_active_call_count());
7901 EXPECT_EQ(0u, raw_replica_mask_layer
->did_become_active_call_count());
7902 pending_tree
->DidBecomeActive();
7903 EXPECT_EQ(3u, raw_pending_layer
->did_become_active_call_count());
7904 EXPECT_EQ(2u, raw_mask_layer
->did_become_active_call_count());
7905 EXPECT_EQ(1u, raw_replica_mask_layer
->did_become_active_call_count());
7908 TEST_F(LayerTreeHostImplTest
, WheelScrollWithPageScaleFactorOnInnerLayer
) {
7909 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
7910 host_impl_
->SetViewportSize(gfx::Size(50, 50));
7913 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
7915 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
7916 float page_scale_factor
= 1.f
;
7918 // The scroll deltas should have the page scale factor applied.
7920 host_impl_
->active_tree()->PushPageScaleFromMainThread(
7921 page_scale_factor
, min_page_scale
, max_page_scale
);
7922 host_impl_
->SetPageScaleOnActiveTree(page_scale_factor
);
7923 scroll_layer
->SetScrollDelta(gfx::Vector2d());
7925 float page_scale_delta
= 2.f
;
7926 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
7927 host_impl_
->PinchGestureBegin();
7928 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
7929 host_impl_
->PinchGestureEnd();
7930 host_impl_
->ScrollEnd();
7932 gfx::Vector2dF
scroll_delta(0, 5);
7933 EXPECT_EQ(InputHandler::ScrollStarted
,
7934 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
7935 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
7937 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
7938 host_impl_
->ScrollEnd();
7939 EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 2.5), scroll_layer
->TotalScrollOffset());
7943 class LayerTreeHostImplCountingLostSurfaces
: public LayerTreeHostImplTest
{
7945 LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
7946 void DidLoseOutputSurfaceOnImplThread() override
{ num_lost_surfaces_
++; }
7949 int num_lost_surfaces_
;
7952 TEST_F(LayerTreeHostImplCountingLostSurfaces
, TwiceLostSurface
) {
7953 // Really we just need at least one client notification each time
7954 // we go from having a valid output surface to not having a valid output
7956 EXPECT_EQ(0, num_lost_surfaces_
);
7957 host_impl_
->DidLoseOutputSurface();
7958 EXPECT_EQ(1, num_lost_surfaces_
);
7959 host_impl_
->DidLoseOutputSurface();
7960 EXPECT_LE(1, num_lost_surfaces_
);