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/command_line.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/containers/scoped_ptr_hash_map.h"
13 #include "cc/animation/scrollbar_animation_controller_thinning.h"
14 #include "cc/base/latency_info_swap_promise.h"
15 #include "cc/base/math_util.h"
16 #include "cc/input/top_controls_manager.h"
17 #include "cc/layers/append_quads_data.h"
18 #include "cc/layers/delegated_renderer_layer_impl.h"
19 #include "cc/layers/heads_up_display_layer_impl.h"
20 #include "cc/layers/io_surface_layer_impl.h"
21 #include "cc/layers/layer_impl.h"
22 #include "cc/layers/painted_scrollbar_layer_impl.h"
23 #include "cc/layers/render_surface_impl.h"
24 #include "cc/layers/solid_color_layer_impl.h"
25 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
26 #include "cc/layers/texture_layer_impl.h"
27 #include "cc/layers/tiled_layer_impl.h"
28 #include "cc/layers/video_layer_impl.h"
29 #include "cc/output/begin_frame_args.h"
30 #include "cc/output/compositor_frame_ack.h"
31 #include "cc/output/compositor_frame_metadata.h"
32 #include "cc/output/copy_output_request.h"
33 #include "cc/output/copy_output_result.h"
34 #include "cc/output/gl_renderer.h"
35 #include "cc/quads/render_pass_draw_quad.h"
36 #include "cc/quads/solid_color_draw_quad.h"
37 #include "cc/quads/texture_draw_quad.h"
38 #include "cc/quads/tile_draw_quad.h"
39 #include "cc/resources/layer_tiling_data.h"
40 #include "cc/test/animation_test_common.h"
41 #include "cc/test/fake_layer_tree_host_impl.h"
42 #include "cc/test/fake_output_surface.h"
43 #include "cc/test/fake_output_surface_client.h"
44 #include "cc/test/fake_picture_layer_impl.h"
45 #include "cc/test/fake_picture_pile_impl.h"
46 #include "cc/test/fake_proxy.h"
47 #include "cc/test/fake_rendering_stats_instrumentation.h"
48 #include "cc/test/fake_video_frame_provider.h"
49 #include "cc/test/geometry_test_utils.h"
50 #include "cc/test/layer_test_common.h"
51 #include "cc/test/render_pass_test_common.h"
52 #include "cc/test/test_shared_bitmap_manager.h"
53 #include "cc/test/test_web_graphics_context_3d.h"
54 #include "cc/trees/layer_tree_impl.h"
55 #include "cc/trees/single_thread_proxy.h"
56 #include "media/base/media.h"
57 #include "testing/gmock/include/gmock/gmock.h"
58 #include "testing/gtest/include/gtest/gtest.h"
59 #include "third_party/skia/include/core/SkMallocPixelRef.h"
60 #include "ui/gfx/frame_time.h"
61 #include "ui/gfx/rect_conversions.h"
62 #include "ui/gfx/size_conversions.h"
63 #include "ui/gfx/vector2d_conversions.h"
65 using ::testing::Mock
;
66 using ::testing::Return
;
67 using ::testing::AnyNumber
;
68 using ::testing::AtLeast
;
70 using media::VideoFrame
;
75 class LayerTreeHostImplTest
: public testing::Test
,
76 public LayerTreeHostImplClient
{
78 LayerTreeHostImplTest()
79 : proxy_(base::MessageLoopProxy::current()),
80 always_impl_thread_(&proxy_
),
81 always_main_thread_blocked_(&proxy_
),
82 shared_bitmap_manager_(new TestSharedBitmapManager()),
83 on_can_draw_state_changed_called_(false),
84 did_notify_ready_to_activate_(false),
85 did_request_commit_(false),
86 did_request_redraw_(false),
87 did_request_animate_(false),
88 did_request_manage_tiles_(false),
89 did_upload_visible_tile_(false),
90 reduce_memory_result_(true),
91 current_limit_bytes_(0),
92 current_priority_cutoff_value_(0) {
93 media::InitializeMediaLibraryForTesting();
96 LayerTreeSettings
DefaultSettings() {
97 LayerTreeSettings settings
;
98 settings
.minimum_occlusion_tracking_size
= gfx::Size();
99 settings
.impl_side_painting
= true;
100 settings
.texture_id_allocation_chunk_size
= 1;
101 settings
.report_overscroll_only_for_scrollable_axes
= true;
105 virtual void SetUp() OVERRIDE
{
106 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
109 virtual void TearDown() OVERRIDE
{}
111 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{}
112 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE
{}
113 virtual void CommitVSyncParameters(base::TimeTicks timebase
,
114 base::TimeDelta interval
) OVERRIDE
{}
115 virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time
) OVERRIDE
{}
116 virtual void SetMaxSwapsPendingOnImplThread(int max
) OVERRIDE
{}
117 virtual void DidSwapBuffersOnImplThread() OVERRIDE
{}
118 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{}
119 virtual void BeginFrame(const BeginFrameArgs
& args
) OVERRIDE
{}
120 virtual void OnCanDrawStateChanged(bool can_draw
) OVERRIDE
{
121 on_can_draw_state_changed_called_
= true;
123 virtual void NotifyReadyToActivate() OVERRIDE
{
124 did_notify_ready_to_activate_
= true;
125 host_impl_
->ActivateSyncTree();
127 virtual void SetNeedsRedrawOnImplThread() OVERRIDE
{
128 did_request_redraw_
= true;
130 virtual void SetNeedsRedrawRectOnImplThread(
131 const gfx::Rect
& damage_rect
) OVERRIDE
{
132 did_request_redraw_
= true;
134 virtual void SetNeedsAnimateOnImplThread() OVERRIDE
{
135 did_request_animate_
= true;
137 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE
{
138 did_request_manage_tiles_
= true;
140 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE
{
141 did_upload_visible_tile_
= true;
143 virtual void SetNeedsCommitOnImplThread() OVERRIDE
{
144 did_request_commit_
= true;
146 virtual void PostAnimationEventsToMainThreadOnImplThread(
147 scoped_ptr
<AnimationEventsVector
> events
) OVERRIDE
{}
148 virtual bool ReduceContentsTextureMemoryOnImplThread(
149 size_t limit_bytes
, int priority_cutoff
) OVERRIDE
{
150 current_limit_bytes_
= limit_bytes
;
151 current_priority_cutoff_value_
= priority_cutoff
;
152 return reduce_memory_result_
;
154 virtual bool IsInsideDraw() OVERRIDE
{ return false; }
155 virtual void RenewTreePriority() OVERRIDE
{}
156 virtual void PostDelayedScrollbarFadeOnImplThread(
157 const base::Closure
& start_fade
,
158 base::TimeDelta delay
) OVERRIDE
{
159 scrollbar_fade_start_
= start_fade
;
160 requested_scrollbar_animation_delay_
= delay
;
162 virtual void DidActivateSyncTree() OVERRIDE
{}
163 virtual void DidManageTiles() OVERRIDE
{}
165 void set_reduce_memory_result(bool reduce_memory_result
) {
166 reduce_memory_result_
= reduce_memory_result
;
169 bool CreateHostImpl(const LayerTreeSettings
& settings
,
170 scoped_ptr
<OutputSurface
> output_surface
) {
171 host_impl_
= LayerTreeHostImpl::Create(settings
,
174 &stats_instrumentation_
,
175 shared_bitmap_manager_
.get(),
177 bool init
= host_impl_
->InitializeRenderer(output_surface
.Pass());
178 host_impl_
->SetViewportSize(gfx::Size(10, 10));
182 void SetupRootLayerImpl(scoped_ptr
<LayerImpl
> root
) {
183 root
->SetPosition(gfx::PointF());
184 root
->SetBounds(gfx::Size(10, 10));
185 root
->SetContentBounds(gfx::Size(10, 10));
186 root
->SetDrawsContent(true);
187 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
188 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
191 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
192 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
193 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
194 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
197 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
199 const gfx::Vector2d
& scroll_delta
) {
200 int times_encountered
= 0;
202 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
203 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
205 EXPECT_VECTOR_EQ(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
);
209 ASSERT_EQ(1, times_encountered
);
212 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
213 int times_encountered
= 0;
215 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
216 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
221 ASSERT_EQ(0, times_encountered
);
224 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
225 const gfx::Size
& content_size
) {
226 const int kInnerViewportScrollLayerId
= 2;
227 const int kInnerViewportClipLayerId
= 4;
228 const int kPageScaleLayerId
= 5;
229 scoped_ptr
<LayerImpl
> root
=
230 LayerImpl::Create(layer_tree_impl
, 1);
231 root
->SetBounds(content_size
);
232 root
->SetContentBounds(content_size
);
233 root
->SetPosition(gfx::PointF());
235 scoped_ptr
<LayerImpl
> scroll
=
236 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
237 LayerImpl
* scroll_layer
= scroll
.get();
238 scroll
->SetIsContainerForFixedPositionLayers(true);
239 scroll
->SetScrollOffset(gfx::Vector2d());
241 scoped_ptr
<LayerImpl
> clip
=
242 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
244 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
246 scoped_ptr
<LayerImpl
> page_scale
=
247 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
249 scroll
->SetScrollClipLayer(clip
->id());
250 scroll
->SetBounds(content_size
);
251 scroll
->SetContentBounds(content_size
);
252 scroll
->SetPosition(gfx::PointF());
253 scroll
->SetIsContainerForFixedPositionLayers(true);
255 scoped_ptr
<LayerImpl
> contents
=
256 LayerImpl::Create(layer_tree_impl
, 3);
257 contents
->SetDrawsContent(true);
258 contents
->SetBounds(content_size
);
259 contents
->SetContentBounds(content_size
);
260 contents
->SetPosition(gfx::PointF());
262 scroll
->AddChild(contents
.Pass());
263 page_scale
->AddChild(scroll
.Pass());
264 clip
->AddChild(page_scale
.Pass());
265 root
->AddChild(clip
.Pass());
267 layer_tree_impl
->SetRootLayer(root
.Pass());
268 layer_tree_impl
->SetViewportLayersFromIds(
269 kPageScaleLayerId
, kInnerViewportScrollLayerId
, Layer::INVALID_ID
);
274 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
275 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
276 host_impl_
->active_tree(), content_size
);
277 host_impl_
->active_tree()->DidBecomeActive();
281 // TODO(wjmaclean) Add clip-layer pointer to parameters.
282 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
283 const gfx::Size
& size
,
284 LayerImpl
* clip_layer
) {
286 DCHECK(id
!= clip_layer
->id());
287 scoped_ptr
<LayerImpl
> layer
=
288 LayerImpl::Create(host_impl_
->active_tree(), id
);
289 layer
->SetScrollClipLayer(clip_layer
->id());
290 layer
->SetDrawsContent(true);
291 layer
->SetBounds(size
);
292 layer
->SetContentBounds(size
);
293 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
298 LayerTreeHostImpl::FrameData frame
;
299 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
300 host_impl_
->DrawLayers(&frame
);
301 host_impl_
->DidDrawAllLayers(frame
);
304 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
305 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
306 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
307 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
308 float device_scale_factor
);
310 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
311 // Note: It is not possible to disable the renderer once it has been set,
312 // so we do not need to test that disabling the renderer notifies us
313 // that can_draw changed.
314 EXPECT_FALSE(host_impl_
->CanDraw());
315 on_can_draw_state_changed_called_
= false;
317 // Set up the root layer, which allows us to draw.
318 SetupScrollAndContentsLayers(gfx::Size(100, 100));
319 EXPECT_TRUE(host_impl_
->CanDraw());
320 EXPECT_TRUE(on_can_draw_state_changed_called_
);
321 on_can_draw_state_changed_called_
= false;
323 // Toggle the root layer to make sure it toggles can_draw
324 host_impl_
->active_tree()->SetRootLayer(scoped_ptr
<LayerImpl
>());
325 EXPECT_FALSE(host_impl_
->CanDraw());
326 EXPECT_TRUE(on_can_draw_state_changed_called_
);
327 on_can_draw_state_changed_called_
= false;
329 SetupScrollAndContentsLayers(gfx::Size(100, 100));
330 EXPECT_TRUE(host_impl_
->CanDraw());
331 EXPECT_TRUE(on_can_draw_state_changed_called_
);
332 on_can_draw_state_changed_called_
= false;
334 // Toggle the device viewport size to make sure it toggles can_draw.
335 host_impl_
->SetViewportSize(gfx::Size());
337 EXPECT_TRUE(host_impl_
->CanDraw());
339 EXPECT_FALSE(host_impl_
->CanDraw());
341 EXPECT_TRUE(on_can_draw_state_changed_called_
);
342 on_can_draw_state_changed_called_
= false;
344 host_impl_
->SetViewportSize(gfx::Size(100, 100));
345 EXPECT_TRUE(host_impl_
->CanDraw());
346 EXPECT_TRUE(on_can_draw_state_changed_called_
);
347 on_can_draw_state_changed_called_
= false;
349 // Toggle contents textures purged without causing any evictions,
350 // and make sure that it does not change can_draw.
351 set_reduce_memory_result(false);
352 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
353 host_impl_
->memory_allocation_limit_bytes() - 1));
354 EXPECT_TRUE(host_impl_
->CanDraw());
355 EXPECT_FALSE(on_can_draw_state_changed_called_
);
356 on_can_draw_state_changed_called_
= false;
358 // Toggle contents textures purged to make sure it toggles can_draw.
359 set_reduce_memory_result(true);
360 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
361 host_impl_
->memory_allocation_limit_bytes() - 1));
363 EXPECT_TRUE(host_impl_
->CanDraw());
365 EXPECT_FALSE(host_impl_
->CanDraw());
367 EXPECT_TRUE(on_can_draw_state_changed_called_
);
368 on_can_draw_state_changed_called_
= false;
370 host_impl_
->active_tree()->ResetContentsTexturesPurged();
371 EXPECT_TRUE(host_impl_
->CanDraw());
372 EXPECT_TRUE(on_can_draw_state_changed_called_
);
373 on_can_draw_state_changed_called_
= false;
376 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
379 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
380 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
383 void DrawOneFrame() {
384 LayerTreeHostImpl::FrameData frame_data
;
385 host_impl_
->PrepareToDraw(&frame_data
);
386 host_impl_
->DidDrawAllLayers(frame_data
);
390 DebugScopedSetImplThread always_impl_thread_
;
391 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
393 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
394 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
395 FakeRenderingStatsInstrumentation stats_instrumentation_
;
396 bool on_can_draw_state_changed_called_
;
397 bool did_notify_ready_to_activate_
;
398 bool did_request_commit_
;
399 bool did_request_redraw_
;
400 bool did_request_animate_
;
401 bool did_request_manage_tiles_
;
402 bool did_upload_visible_tile_
;
403 bool reduce_memory_result_
;
404 base::Closure scrollbar_fade_start_
;
405 base::TimeDelta requested_scrollbar_animation_delay_
;
406 size_t current_limit_bytes_
;
407 int current_priority_cutoff_value_
;
410 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
411 bool always_draw
= false;
412 CheckNotifyCalledIfCanDrawChanged(always_draw
);
415 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
416 scoped_ptr
<FakeOutputSurface
> output_surface(
417 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
418 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
420 bool always_draw
= true;
421 CheckNotifyCalledIfCanDrawChanged(always_draw
);
424 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
425 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
427 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
428 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
431 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
433 scoped_ptr
<LayerImpl
> root
=
434 LayerImpl::Create(host_impl_
->active_tree(), 1);
435 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
436 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
437 root
->children()[1]->AddChild(
438 LayerImpl::Create(host_impl_
->active_tree(), 4));
439 root
->children()[1]->AddChild(
440 LayerImpl::Create(host_impl_
->active_tree(), 5));
441 root
->children()[1]->children()[0]->AddChild(
442 LayerImpl::Create(host_impl_
->active_tree(), 6));
443 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
445 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
447 ExpectClearedScrollDeltasRecursive(root
);
449 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
451 scroll_info
= host_impl_
->ProcessScrollDeltas();
452 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
453 ExpectClearedScrollDeltasRecursive(root
);
455 scroll_info
= host_impl_
->ProcessScrollDeltas();
456 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
457 ExpectClearedScrollDeltasRecursive(root
);
460 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
461 gfx::Vector2d
scroll_offset(20, 30);
462 gfx::Vector2d
scroll_delta(11, -15);
464 scoped_ptr
<LayerImpl
> root_clip
=
465 LayerImpl::Create(host_impl_
->active_tree(), 2);
466 scoped_ptr
<LayerImpl
> root
=
467 LayerImpl::Create(host_impl_
->active_tree(), 1);
468 root_clip
->SetBounds(gfx::Size(10, 10));
469 LayerImpl
* root_layer
= root
.get();
470 root_clip
->AddChild(root
.Pass());
471 root_layer
->SetBounds(gfx::Size(110, 110));
472 root_layer
->SetScrollClipLayer(root_clip
->id());
473 root_layer
->SetScrollOffset(scroll_offset
);
474 root_layer
->ScrollBy(scroll_delta
);
475 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
477 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
479 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
481 scroll_info
= host_impl_
->ProcessScrollDeltas();
482 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
483 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
);
484 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
486 gfx::Vector2d
scroll_delta2(-5, 27);
487 root
->ScrollBy(scroll_delta2
);
488 scroll_info
= host_impl_
->ProcessScrollDeltas();
489 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
490 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
491 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
493 root
->ScrollBy(gfx::Vector2d());
494 scroll_info
= host_impl_
->ProcessScrollDeltas();
495 EXPECT_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
498 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
499 SetupScrollAndContentsLayers(gfx::Size(100, 100));
500 host_impl_
->SetViewportSize(gfx::Size(50, 50));
503 EXPECT_EQ(InputHandler::ScrollStarted
,
504 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
505 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
506 InputHandler::Wheel
));
507 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
508 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
509 InputHandler::Wheel
));
510 host_impl_
->ScrollEnd();
511 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
512 InputHandler::Wheel
));
513 EXPECT_TRUE(did_request_redraw_
);
514 EXPECT_TRUE(did_request_commit_
);
517 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
518 // We should not crash when trying to scroll an empty layer tree.
519 EXPECT_EQ(InputHandler::ScrollIgnored
,
520 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
523 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
524 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
525 TestWebGraphicsContext3D::Create();
526 context_owned
->set_context_lost(true);
528 scoped_ptr
<FakeOutputSurface
> output_surface(FakeOutputSurface::Create3d(
529 context_owned
.Pass()));
531 // Initialization will fail.
532 EXPECT_FALSE(CreateHostImpl(DefaultSettings(),
533 output_surface
.PassAs
<OutputSurface
>()));
535 SetupScrollAndContentsLayers(gfx::Size(100, 100));
537 // We should not crash when trying to scroll after the renderer initialization
539 EXPECT_EQ(InputHandler::ScrollStarted
,
540 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
543 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
544 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
545 host_impl_
->SetViewportSize(gfx::Size(50, 50));
548 // We should not crash if the tree is replaced while we are scrolling.
549 EXPECT_EQ(InputHandler::ScrollStarted
,
550 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
551 host_impl_
->active_tree()->DetachLayerTree();
553 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
555 // We should still be scrolling, because the scrolled layer also exists in the
557 gfx::Vector2d
scroll_delta(0, 10);
558 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
559 host_impl_
->ScrollEnd();
560 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
561 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
564 TEST_F(LayerTreeHostImplTest
, ClearRootRenderSurfaceAndScroll
) {
565 SetupScrollAndContentsLayers(gfx::Size(100, 100));
566 host_impl_
->SetViewportSize(gfx::Size(50, 50));
569 // We should be able to scroll even if the root layer loses its render surface
570 // after the most recent render.
571 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
572 host_impl_
->active_tree()->set_needs_update_draw_properties();
574 EXPECT_EQ(InputHandler::ScrollStarted
,
575 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
578 TEST_F(LayerTreeHostImplTest
, WheelEventHandlers
) {
579 SetupScrollAndContentsLayers(gfx::Size(100, 100));
580 host_impl_
->SetViewportSize(gfx::Size(50, 50));
582 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
584 root
->SetHaveWheelEventHandlers(true);
586 // With registered event handlers, wheel scrolls have to go to the main
588 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
589 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
591 // But gesture scrolls can still be handled.
592 EXPECT_EQ(InputHandler::ScrollStarted
,
593 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
596 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
597 SetupScrollAndContentsLayers(gfx::Size(100, 100));
598 host_impl_
->SetViewportSize(gfx::Size(50, 50));
601 // Ignore the fling since no layer is being scrolled
602 EXPECT_EQ(InputHandler::ScrollIgnored
,
603 host_impl_
->FlingScrollBegin());
605 // Start scrolling a layer
606 EXPECT_EQ(InputHandler::ScrollStarted
,
607 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
609 // Now the fling should go ahead since we've started scrolling a layer
610 EXPECT_EQ(InputHandler::ScrollStarted
,
611 host_impl_
->FlingScrollBegin());
614 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
615 SetupScrollAndContentsLayers(gfx::Size(100, 100));
616 host_impl_
->SetViewportSize(gfx::Size(50, 50));
619 // Ignore the fling since no layer is being scrolled
620 EXPECT_EQ(InputHandler::ScrollIgnored
,
621 host_impl_
->FlingScrollBegin());
623 // Start scrolling a layer
624 EXPECT_EQ(InputHandler::ScrollStarted
,
625 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
627 // Now the fling should go ahead since we've started scrolling a layer
628 EXPECT_EQ(InputHandler::ScrollStarted
,
629 host_impl_
->FlingScrollBegin());
632 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
633 SetupScrollAndContentsLayers(gfx::Size(100, 100));
634 host_impl_
->SetViewportSize(gfx::Size(50, 50));
636 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
638 root
->SetShouldScrollOnMainThread(true);
640 // Start scrolling a layer
641 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
642 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
644 // The fling should be ignored since there's no layer being scrolled impl-side
645 EXPECT_EQ(InputHandler::ScrollIgnored
,
646 host_impl_
->FlingScrollBegin());
649 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
650 SetupScrollAndContentsLayers(gfx::Size(100, 100));
651 host_impl_
->SetViewportSize(gfx::Size(50, 50));
653 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
655 root
->SetShouldScrollOnMainThread(true);
657 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
658 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
659 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
660 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
663 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
664 SetupScrollAndContentsLayers(gfx::Size(200, 200));
665 host_impl_
->SetViewportSize(gfx::Size(100, 100));
667 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
668 root
->SetContentsScale(2.f
, 2.f
);
669 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
673 // All scroll types inside the non-fast scrollable region should fail.
674 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
675 host_impl_
->ScrollBegin(gfx::Point(25, 25),
676 InputHandler::Wheel
));
677 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
678 InputHandler::Wheel
));
679 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
680 host_impl_
->ScrollBegin(gfx::Point(25, 25),
681 InputHandler::Gesture
));
682 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
683 InputHandler::Gesture
));
685 // All scroll types outside this region should succeed.
686 EXPECT_EQ(InputHandler::ScrollStarted
,
687 host_impl_
->ScrollBegin(gfx::Point(75, 75),
688 InputHandler::Wheel
));
689 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
690 InputHandler::Gesture
));
691 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
692 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
693 InputHandler::Gesture
));
694 host_impl_
->ScrollEnd();
695 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
696 InputHandler::Gesture
));
697 EXPECT_EQ(InputHandler::ScrollStarted
,
698 host_impl_
->ScrollBegin(gfx::Point(75, 75),
699 InputHandler::Gesture
));
700 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
701 InputHandler::Gesture
));
702 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
703 host_impl_
->ScrollEnd();
704 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
705 InputHandler::Gesture
));
708 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
709 SetupScrollAndContentsLayers(gfx::Size(200, 200));
710 host_impl_
->SetViewportSize(gfx::Size(100, 100));
712 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
713 root
->SetContentsScale(2.f
, 2.f
);
714 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
715 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
719 // This point would fall into the non-fast scrollable region except that we've
720 // moved the layer down by 25 pixels.
721 EXPECT_EQ(InputHandler::ScrollStarted
,
722 host_impl_
->ScrollBegin(gfx::Point(40, 10),
723 InputHandler::Wheel
));
724 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
725 InputHandler::Wheel
));
726 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
727 host_impl_
->ScrollEnd();
729 // This point is still inside the non-fast region.
730 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
731 host_impl_
->ScrollBegin(gfx::Point(10, 10),
732 InputHandler::Wheel
));
735 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
736 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
737 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
738 host_impl_
->SetViewportSize(gfx::Size(50, 50));
741 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
742 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
743 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
744 host_impl_
->ScrollEnd();
745 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
748 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
749 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
750 scroll_layer
->SetHaveScrollEventHandlers(true);
751 host_impl_
->SetViewportSize(gfx::Size(50, 50));
754 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
755 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
756 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
757 host_impl_
->ScrollEnd();
758 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
761 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
762 SetupScrollAndContentsLayers(gfx::Size(200, 200));
763 host_impl_
->SetViewportSize(gfx::Size(100, 100));
767 EXPECT_EQ(InputHandler::ScrollStarted
,
768 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
770 // Trying to scroll to the left/top will not succeed.
771 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
772 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
773 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
775 // Scrolling to the right/bottom will succeed.
776 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
777 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
778 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
780 // Scrolling to left/top will now succeed.
781 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
782 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
783 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
785 // Scrolling diagonally against an edge will succeed.
786 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
787 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
788 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
790 // Trying to scroll more than the available space will also succeed.
791 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
794 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
795 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
796 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
800 EXPECT_EQ(InputHandler::ScrollStarted
,
801 host_impl_
->ScrollBegin(gfx::Point(),
802 InputHandler::Wheel
));
804 // Trying to scroll without a vertical scrollbar will fail.
805 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
806 gfx::Point(), SCROLL_FORWARD
));
807 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
808 gfx::Point(), SCROLL_BACKWARD
));
810 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
811 PaintedScrollbarLayerImpl::Create(
812 host_impl_
->active_tree(),
815 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
816 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
817 vertical_scrollbar
.get());
819 // Trying to scroll with a vertical scrollbar will succeed.
820 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
821 gfx::Point(), SCROLL_FORWARD
));
822 EXPECT_FLOAT_EQ(875.f
,
823 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
824 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
825 gfx::Point(), SCROLL_BACKWARD
));
828 // The user-scrollability breaks for zoomed-in pages. So disable this.
829 // http://crbug.com/322223
830 TEST_F(LayerTreeHostImplTest
, DISABLED_ScrollWithUserUnscrollableLayers
) {
831 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
832 host_impl_
->SetViewportSize(gfx::Size(100, 100));
834 gfx::Size
overflow_size(400, 400);
835 ASSERT_EQ(1u, scroll_layer
->children().size());
836 LayerImpl
* overflow
= scroll_layer
->children()[0];
837 overflow
->SetBounds(overflow_size
);
838 overflow
->SetContentBounds(overflow_size
);
839 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
840 overflow
->SetScrollOffset(gfx::Vector2d());
841 overflow
->SetPosition(gfx::PointF());
844 gfx::Point
scroll_position(10, 10);
846 EXPECT_EQ(InputHandler::ScrollStarted
,
847 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
848 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
849 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->TotalScrollOffset());
851 gfx::Vector2dF
scroll_delta(10, 10);
852 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
853 host_impl_
->ScrollEnd();
854 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
855 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
857 overflow
->set_user_scrollable_horizontal(false);
859 EXPECT_EQ(InputHandler::ScrollStarted
,
860 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
861 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
862 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
864 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
865 host_impl_
->ScrollEnd();
866 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
867 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
869 overflow
->set_user_scrollable_vertical(false);
871 EXPECT_EQ(InputHandler::ScrollStarted
,
872 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
873 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
874 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
876 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
877 host_impl_
->ScrollEnd();
878 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->TotalScrollOffset());
879 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
882 TEST_F(LayerTreeHostImplTest
,
883 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion
) {
884 SetupScrollAndContentsLayers(gfx::Size(100, 100));
885 host_impl_
->SetViewportSize(gfx::Size(50, 50));
888 // We should be able to hit test for touch event handlers even if the root
889 // layer loses its render surface after the most recent render.
890 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
891 host_impl_
->active_tree()->set_needs_update_draw_properties();
893 EXPECT_EQ(host_impl_
->HaveTouchEventHandlersAt(gfx::Point()), false);
896 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
897 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
898 host_impl_
->SetViewportSize(gfx::Size(50, 50));
901 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
902 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
903 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
905 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
906 float page_scale_factor
= 1.f
;
908 // The impl-based pinch zoom should adjust the max scroll position.
910 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
911 page_scale_factor
, min_page_scale
, max_page_scale
);
912 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
913 scroll_layer
->SetScrollDelta(gfx::Vector2d());
915 float page_scale_delta
= 2.f
;
916 gfx::Vector2dF
expected_container_size_delta(
917 container_layer
->bounds().width(), container_layer
->bounds().height());
918 expected_container_size_delta
.Scale((1.f
- page_scale_delta
) /
919 (page_scale_factor
* page_scale_delta
));
921 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
922 host_impl_
->PinchGestureBegin();
923 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
924 // While the gesture is still active, the scroll layer should have a
925 // container size delta = container->bounds() * ((1.f -
926 // page_scale_delta)/())
927 EXPECT_EQ(expected_container_size_delta
,
928 scroll_layer
->FixedContainerSizeDelta());
929 host_impl_
->PinchGestureEnd();
930 host_impl_
->ScrollEnd();
931 EXPECT_FALSE(did_request_animate_
);
932 EXPECT_TRUE(did_request_redraw_
);
933 EXPECT_TRUE(did_request_commit_
);
934 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
936 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
937 host_impl_
->ProcessScrollDeltas();
938 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
940 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
941 scroll_layer
->MaxScrollOffset().ToString());
944 // Scrolling after a pinch gesture should always be in local space. The
945 // scroll deltas do not have the page scale factor applied.
947 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
948 page_scale_factor
, min_page_scale
, max_page_scale
);
949 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
950 scroll_layer
->SetScrollDelta(gfx::Vector2d());
952 float page_scale_delta
= 2.f
;
953 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
954 host_impl_
->PinchGestureBegin();
955 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
956 host_impl_
->PinchGestureEnd();
957 host_impl_
->ScrollEnd();
959 gfx::Vector2d
scroll_delta(0, 10);
960 EXPECT_EQ(InputHandler::ScrollStarted
,
961 host_impl_
->ScrollBegin(gfx::Point(5, 5),
962 InputHandler::Wheel
));
963 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
964 host_impl_
->ScrollEnd();
966 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
967 host_impl_
->ProcessScrollDeltas();
968 ExpectContains(*scroll_info
.get(),
974 TEST_F(LayerTreeHostImplTest
, ScrollWithSwapPromises
) {
975 ui::LatencyInfo latency_info
;
976 latency_info
.trace_id
= 1234;
977 scoped_ptr
<SwapPromise
> swap_promise(
978 new LatencyInfoSwapPromise(latency_info
));
980 SetupScrollAndContentsLayers(gfx::Size(100, 100));
981 EXPECT_EQ(InputHandler::ScrollStarted
,
982 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
983 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
984 host_impl_
->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise
.Pass());
985 host_impl_
->ScrollEnd();
987 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
988 EXPECT_EQ(1u, scroll_info
->swap_promises
.size());
989 EXPECT_EQ(latency_info
.trace_id
, scroll_info
->swap_promises
[0]->TraceId());
992 TEST_F(LayerTreeHostImplTest
, MasksToBoundsDoesntClobberInnerContainerSize
) {
993 SetupScrollAndContentsLayers(gfx::Size(100, 100));
994 host_impl_
->SetViewportSize(gfx::Size(50, 50));
997 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
998 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
999 DCHECK(scroll_layer
);
1001 float min_page_scale
= 1.f
;
1002 float max_page_scale
= 4.f
;
1003 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1007 // If the container's masks_to_bounds is false, the viewport size should
1008 // overwrite the inner viewport container layer's size.
1010 EXPECT_EQ(gfx::Size(50, 50),
1011 container_layer
->bounds());
1012 container_layer
->SetMasksToBounds(false);
1014 container_layer
->SetBounds(gfx::Size(30, 25));
1015 EXPECT_EQ(gfx::Size(30, 25),
1016 container_layer
->bounds());
1018 // This should cause a reset of the inner viewport container layer's bounds.
1019 host_impl_
->DidChangeTopControlsPosition();
1021 EXPECT_EQ(gfx::Size(50, 50),
1022 container_layer
->bounds());
1025 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1026 container_layer
->SetBounds(gfx::Size(50, 50));
1028 // If the container's masks_to_bounds is true, the viewport size should
1029 // *NOT* overwrite the inner viewport container layer's size.
1031 EXPECT_EQ(gfx::Size(50, 50),
1032 container_layer
->bounds());
1033 container_layer
->SetMasksToBounds(true);
1035 container_layer
->SetBounds(gfx::Size(30, 25));
1036 EXPECT_EQ(gfx::Size(30, 25),
1037 container_layer
->bounds());
1039 // This should cause a reset of the inner viewport container layer's bounds.
1040 host_impl_
->DidChangeTopControlsPosition();
1042 EXPECT_EQ(gfx::Size(30, 25),
1043 container_layer
->bounds());
1047 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1048 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1049 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1052 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1053 DCHECK(scroll_layer
);
1055 float min_page_scale
= 1.f
;
1056 float max_page_scale
= 4.f
;
1058 // Basic pinch zoom in gesture
1060 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1063 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1065 float page_scale_delta
= 2.f
;
1066 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1067 host_impl_
->PinchGestureBegin();
1068 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1069 host_impl_
->PinchGestureEnd();
1070 host_impl_
->ScrollEnd();
1071 EXPECT_FALSE(did_request_animate_
);
1072 EXPECT_TRUE(did_request_redraw_
);
1073 EXPECT_TRUE(did_request_commit_
);
1075 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1076 host_impl_
->ProcessScrollDeltas();
1077 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1082 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1085 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1086 float page_scale_delta
= 10.f
;
1088 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1089 host_impl_
->PinchGestureBegin();
1090 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1091 host_impl_
->PinchGestureEnd();
1092 host_impl_
->ScrollEnd();
1094 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1095 host_impl_
->ProcessScrollDeltas();
1096 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1099 // Zoom-out clamping
1101 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1104 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1105 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1107 float page_scale_delta
= 0.1f
;
1108 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1109 host_impl_
->PinchGestureBegin();
1110 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1111 host_impl_
->PinchGestureEnd();
1112 host_impl_
->ScrollEnd();
1114 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1115 host_impl_
->ProcessScrollDeltas();
1116 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1118 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1121 // Two-finger panning should not happen based on pinch events only
1123 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1126 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1127 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1129 float page_scale_delta
= 1.f
;
1130 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1131 host_impl_
->PinchGestureBegin();
1132 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1133 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1134 host_impl_
->PinchGestureEnd();
1135 host_impl_
->ScrollEnd();
1137 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1138 host_impl_
->ProcessScrollDeltas();
1139 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1140 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1143 // Two-finger panning should work with interleaved scroll events
1145 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1148 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1149 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1151 float page_scale_delta
= 1.f
;
1152 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1153 host_impl_
->PinchGestureBegin();
1154 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1155 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1156 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1157 host_impl_
->PinchGestureEnd();
1158 host_impl_
->ScrollEnd();
1160 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1161 host_impl_
->ProcessScrollDeltas();
1162 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1163 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1166 // Two-finger panning should work when starting fully zoomed out.
1168 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(0.5f
,
1171 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1172 scroll_layer
->SetScrollOffset(gfx::Vector2d(0, 0));
1174 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1175 host_impl_
->PinchGestureBegin();
1176 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1177 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1178 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1179 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1180 host_impl_
->PinchGestureEnd();
1181 host_impl_
->ScrollEnd();
1183 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1184 host_impl_
->ProcessScrollDeltas();
1185 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1186 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1190 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1191 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1192 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1195 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1196 DCHECK(scroll_layer
);
1198 float min_page_scale
= 0.5f
;
1199 float max_page_scale
= 4.f
;
1200 base::TimeTicks start_time
= base::TimeTicks() +
1201 base::TimeDelta::FromSeconds(1);
1202 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1203 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1204 base::TimeTicks end_time
= start_time
+ duration
;
1206 // Non-anchor zoom-in
1208 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1211 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1213 did_request_redraw_
= false;
1214 did_request_animate_
= false;
1215 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f
, duration
);
1216 EXPECT_FALSE(did_request_redraw_
);
1217 EXPECT_TRUE(did_request_animate_
);
1219 did_request_redraw_
= false;
1220 did_request_animate_
= false;
1221 host_impl_
->Animate(start_time
);
1222 EXPECT_TRUE(did_request_redraw_
);
1223 EXPECT_TRUE(did_request_animate_
);
1225 did_request_redraw_
= false;
1226 did_request_animate_
= false;
1227 host_impl_
->Animate(halfway_through_animation
);
1228 EXPECT_TRUE(did_request_redraw_
);
1229 EXPECT_TRUE(did_request_animate_
);
1231 did_request_redraw_
= false;
1232 did_request_animate_
= false;
1233 did_request_commit_
= false;
1234 host_impl_
->Animate(end_time
);
1235 EXPECT_TRUE(did_request_commit_
);
1236 EXPECT_FALSE(did_request_animate_
);
1238 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1239 host_impl_
->ProcessScrollDeltas();
1240 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1241 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1246 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1249 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1251 did_request_redraw_
= false;
1252 did_request_animate_
= false;
1253 host_impl_
->StartPageScaleAnimation(
1254 gfx::Vector2d(25, 25), true, min_page_scale
, duration
);
1255 EXPECT_FALSE(did_request_redraw_
);
1256 EXPECT_TRUE(did_request_animate_
);
1258 did_request_redraw_
= false;
1259 did_request_animate_
= false;
1260 host_impl_
->Animate(start_time
);
1261 EXPECT_TRUE(did_request_redraw_
);
1262 EXPECT_TRUE(did_request_animate_
);
1264 did_request_redraw_
= false;
1265 did_request_commit_
= false;
1266 did_request_animate_
= false;
1267 host_impl_
->Animate(end_time
);
1268 EXPECT_TRUE(did_request_redraw_
);
1269 EXPECT_FALSE(did_request_animate_
);
1270 EXPECT_TRUE(did_request_commit_
);
1272 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1273 host_impl_
->ProcessScrollDeltas();
1274 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1275 // Pushed to (0,0) via clamping against contents layer size.
1276 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1280 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1281 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1282 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1285 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1286 DCHECK(scroll_layer
);
1288 float min_page_scale
= 0.5f
;
1289 float max_page_scale
= 4.f
;
1290 base::TimeTicks start_time
= base::TimeTicks() +
1291 base::TimeDelta::FromSeconds(1);
1292 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1293 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1294 base::TimeTicks end_time
= start_time
+ duration
;
1296 // Anchor zoom with unchanged page scale should not change scroll or scale.
1298 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1301 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1303 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f
, duration
);
1304 host_impl_
->Animate(start_time
);
1305 host_impl_
->Animate(halfway_through_animation
);
1306 EXPECT_TRUE(did_request_redraw_
);
1307 host_impl_
->Animate(end_time
);
1308 EXPECT_TRUE(did_request_commit_
);
1310 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1311 host_impl_
->ProcessScrollDeltas();
1312 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1313 ExpectNone(*scroll_info
, scroll_layer
->id());
1317 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1319 LayerTreeHostImplOverridePhysicalTime(
1320 const LayerTreeSettings
& settings
,
1321 LayerTreeHostImplClient
* client
,
1323 SharedBitmapManager
* manager
,
1324 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1325 : LayerTreeHostImpl(settings
,
1328 rendering_stats_instrumentation
,
1332 virtual base::TimeTicks
CurrentFrameTimeTicks() OVERRIDE
{
1333 return fake_current_physical_time_
;
1336 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1337 fake_current_physical_time_
= fake_now
;
1341 base::TimeTicks fake_current_physical_time_
;
1344 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1345 gfx::Size viewport_size(10, 10); \
1346 gfx::Size content_size(100, 100); \
1348 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1349 new LayerTreeHostImplOverridePhysicalTime(settings, \
1352 shared_bitmap_manager_.get(), \
1353 &stats_instrumentation_); \
1354 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1355 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1356 host_impl_->SetViewportSize(viewport_size); \
1358 scoped_ptr<LayerImpl> root = \
1359 LayerImpl::Create(host_impl_->active_tree(), 1); \
1360 root->SetBounds(viewport_size); \
1362 scoped_ptr<LayerImpl> scroll = \
1363 LayerImpl::Create(host_impl_->active_tree(), 2); \
1364 scroll->SetScrollClipLayer(root->id()); \
1365 scroll->SetScrollOffset(gfx::Vector2d()); \
1366 root->SetBounds(viewport_size); \
1367 scroll->SetBounds(content_size); \
1368 scroll->SetContentBounds(content_size); \
1369 scroll->SetIsContainerForFixedPositionLayers(true); \
1371 scoped_ptr<LayerImpl> contents = \
1372 LayerImpl::Create(host_impl_->active_tree(), 3); \
1373 contents->SetDrawsContent(true); \
1374 contents->SetBounds(content_size); \
1375 contents->SetContentBounds(content_size); \
1377 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1378 SolidColorScrollbarLayerImpl::Create( \
1379 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \
1380 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1382 scroll->AddChild(contents.Pass()); \
1383 root->AddChild(scroll.Pass()); \
1384 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \
1385 root->AddChild(scrollbar.PassAs<LayerImpl>()); \
1387 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1388 host_impl_->active_tree()->SetViewportLayersFromIds( \
1389 1, 2, Layer::INVALID_ID); \
1390 host_impl_->active_tree()->DidBecomeActive(); \
1393 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1394 LayerTreeSettings settings
;
1395 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1396 settings
.scrollbar_fade_delay_ms
= 20;
1397 settings
.scrollbar_fade_duration_ms
= 20;
1399 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1401 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1403 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1404 EXPECT_FALSE(did_request_redraw_
);
1406 // If no scroll happened during a scroll gesture, it should have no effect.
1407 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1408 host_impl_
->ScrollEnd();
1409 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1410 EXPECT_FALSE(did_request_redraw_
);
1411 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1413 // After a scroll, a fade animation should be scheduled about 20ms from now.
1414 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1415 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1416 host_impl_
->ScrollEnd();
1417 did_request_redraw_
= false;
1418 did_request_animate_
= false;
1419 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1420 requested_scrollbar_animation_delay_
);
1421 EXPECT_FALSE(did_request_redraw_
);
1422 EXPECT_FALSE(did_request_animate_
);
1423 requested_scrollbar_animation_delay_
= base::TimeDelta();
1424 scrollbar_fade_start_
.Run();
1425 host_impl_
->Animate(fake_now
);
1427 // After the fade begins, we should start getting redraws instead of a
1428 // scheduled animation.
1429 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1430 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1431 EXPECT_TRUE(did_request_animate_
);
1432 did_request_animate_
= false;
1434 // Setting the scroll offset outside a scroll should also cause the scrollbar
1435 // to appear and to schedule a fade.
1436 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1437 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1438 requested_scrollbar_animation_delay_
);
1439 EXPECT_FALSE(did_request_redraw_
);
1440 EXPECT_FALSE(did_request_animate_
);
1441 requested_scrollbar_animation_delay_
= base::TimeDelta();
1444 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1445 LayerTreeSettings settings
;
1446 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1447 settings
.scrollbar_fade_delay_ms
= 20;
1448 settings
.scrollbar_fade_duration_ms
= 20;
1449 settings
.use_pinch_zoom_scrollbars
= true;
1451 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1453 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1455 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, 4.f
);
1457 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1458 EXPECT_FALSE(did_request_animate_
);
1460 // If no scroll happened during a scroll gesture, it should have no effect.
1461 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1462 host_impl_
->ScrollEnd();
1463 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1464 EXPECT_FALSE(did_request_animate_
);
1465 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1467 // After a scroll, no fade animation should be scheduled.
1468 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1469 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1470 host_impl_
->ScrollEnd();
1471 did_request_redraw_
= false;
1472 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1473 EXPECT_FALSE(did_request_animate_
);
1474 requested_scrollbar_animation_delay_
= base::TimeDelta();
1476 // We should not see any draw requests.
1477 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1478 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1479 EXPECT_FALSE(did_request_animate_
);
1481 // Make page scale > min so that subsequent scrolls will trigger fades.
1482 host_impl_
->active_tree()->SetPageScaleDelta(1.1f
);
1484 // After a scroll, a fade animation should be scheduled about 20ms from now.
1485 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1486 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1487 host_impl_
->ScrollEnd();
1488 did_request_redraw_
= false;
1489 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1490 requested_scrollbar_animation_delay_
);
1491 EXPECT_FALSE(did_request_animate_
);
1492 requested_scrollbar_animation_delay_
= base::TimeDelta();
1493 scrollbar_fade_start_
.Run();
1495 // After the fade begins, we should start getting redraws instead of a
1496 // scheduled animation.
1497 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1498 host_impl_
->Animate(fake_now
);
1499 EXPECT_TRUE(did_request_animate_
);
1502 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1503 float device_scale_factor
) {
1504 LayerTreeSettings settings
;
1505 settings
.scrollbar_fade_delay_ms
= 500;
1506 settings
.scrollbar_fade_duration_ms
= 300;
1507 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1509 gfx::Size
viewport_size(300, 200);
1510 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1511 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1512 gfx::Size
content_size(1000, 1000);
1514 CreateHostImpl(settings
, CreateOutputSurface());
1515 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1516 host_impl_
->SetViewportSize(device_viewport_size
);
1518 scoped_ptr
<LayerImpl
> root
=
1519 LayerImpl::Create(host_impl_
->active_tree(), 1);
1520 root
->SetBounds(viewport_size
);
1522 scoped_ptr
<LayerImpl
> scroll
=
1523 LayerImpl::Create(host_impl_
->active_tree(), 2);
1524 scroll
->SetScrollClipLayer(root
->id());
1525 scroll
->SetScrollOffset(gfx::Vector2d());
1526 scroll
->SetBounds(content_size
);
1527 scroll
->SetContentBounds(content_size
);
1528 scroll
->SetIsContainerForFixedPositionLayers(true);
1530 scoped_ptr
<LayerImpl
> contents
=
1531 LayerImpl::Create(host_impl_
->active_tree(), 3);
1532 contents
->SetDrawsContent(true);
1533 contents
->SetBounds(content_size
);
1534 contents
->SetContentBounds(content_size
);
1536 // The scrollbar is on the right side.
1537 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1538 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1539 scrollbar
->SetDrawsContent(true);
1540 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1541 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1542 scrollbar
->SetPosition(gfx::Point(285, 0));
1544 scroll
->AddChild(contents
.Pass());
1545 root
->AddChild(scroll
.Pass());
1546 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1547 root
->AddChild(scrollbar
.PassAs
<LayerImpl
>());
1549 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1550 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
1551 host_impl_
->active_tree()->DidBecomeActive();
1554 LayerImpl
* root_scroll
=
1555 host_impl_
->active_tree()->InnerViewportScrollLayer();
1556 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1557 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1558 static_cast<ScrollbarAnimationControllerThinning
*>(
1559 root_scroll
->scrollbar_animation_controller());
1560 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1562 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1563 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1565 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1566 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1568 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1569 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1571 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1572 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1573 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1575 did_request_redraw_
= false;
1576 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1577 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1578 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1579 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1580 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1581 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1582 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1585 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1586 SetupMouseMoveAtWithDeviceScale(1.f
);
1589 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1590 SetupMouseMoveAtWithDeviceScale(2.f
);
1593 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1594 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1595 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1596 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
1599 CompositorFrameMetadata metadata
=
1600 host_impl_
->MakeCompositorFrameMetadata();
1601 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1602 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1603 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.scrollable_viewport_size
);
1604 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1605 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1606 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1609 // Scrolling should update metadata immediately.
1610 EXPECT_EQ(InputHandler::ScrollStarted
,
1611 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1612 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1614 CompositorFrameMetadata metadata
=
1615 host_impl_
->MakeCompositorFrameMetadata();
1616 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1618 host_impl_
->ScrollEnd();
1620 CompositorFrameMetadata metadata
=
1621 host_impl_
->MakeCompositorFrameMetadata();
1622 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1625 // Page scale should update metadata correctly (shrinking only the viewport).
1626 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1627 host_impl_
->PinchGestureBegin();
1628 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1629 host_impl_
->PinchGestureEnd();
1630 host_impl_
->ScrollEnd();
1632 CompositorFrameMetadata metadata
=
1633 host_impl_
->MakeCompositorFrameMetadata();
1634 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1635 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1636 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.scrollable_viewport_size
);
1637 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1638 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1639 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1642 // Likewise if set from the main thread.
1643 host_impl_
->ProcessScrollDeltas();
1644 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(4.f
, 0.5f
, 4.f
);
1645 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
1647 CompositorFrameMetadata metadata
=
1648 host_impl_
->MakeCompositorFrameMetadata();
1649 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1650 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1651 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.scrollable_viewport_size
);
1652 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1653 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1654 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1658 class DidDrawCheckLayer
: public LayerImpl
{
1660 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1661 return scoped_ptr
<LayerImpl
>(new DidDrawCheckLayer(tree_impl
, id
));
1664 virtual bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
)
1666 will_draw_called_
= true;
1667 if (will_draw_returns_false_
)
1669 return LayerImpl::WillDraw(draw_mode
, provider
);
1672 virtual void AppendQuads(RenderPass
* render_pass
,
1673 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
1674 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1675 append_quads_called_
= true;
1676 LayerImpl::AppendQuads(render_pass
, occlusion_tracker
, append_quads_data
);
1679 virtual void DidDraw(ResourceProvider
* provider
) OVERRIDE
{
1680 did_draw_called_
= true;
1681 LayerImpl::DidDraw(provider
);
1684 bool will_draw_called() const { return will_draw_called_
; }
1685 bool append_quads_called() const { return append_quads_called_
; }
1686 bool did_draw_called() const { return did_draw_called_
; }
1688 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1690 void ClearDidDrawCheck() {
1691 will_draw_called_
= false;
1692 append_quads_called_
= false;
1693 did_draw_called_
= false;
1697 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1698 : LayerImpl(tree_impl
, id
),
1699 will_draw_returns_false_(false),
1700 will_draw_called_(false),
1701 append_quads_called_(false),
1702 did_draw_called_(false) {
1703 SetBounds(gfx::Size(10, 10));
1704 SetContentBounds(gfx::Size(10, 10));
1705 SetDrawsContent(true);
1706 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1710 bool will_draw_returns_false_
;
1711 bool will_draw_called_
;
1712 bool append_quads_called_
;
1713 bool did_draw_called_
;
1716 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1717 // The root layer is always drawn, so run this test on a child layer that
1718 // will be masked out by the root layer's bounds.
1719 host_impl_
->active_tree()->SetRootLayer(
1720 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1721 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1722 host_impl_
->active_tree()->root_layer());
1724 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1725 DidDrawCheckLayer
* layer
=
1726 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1729 LayerTreeHostImpl::FrameData frame
;
1730 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1731 host_impl_
->DrawLayers(&frame
);
1732 host_impl_
->DidDrawAllLayers(frame
);
1734 EXPECT_TRUE(layer
->will_draw_called());
1735 EXPECT_TRUE(layer
->append_quads_called());
1736 EXPECT_TRUE(layer
->did_draw_called());
1739 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1742 LayerTreeHostImpl::FrameData frame
;
1744 layer
->set_will_draw_returns_false();
1745 layer
->ClearDidDrawCheck();
1747 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1748 host_impl_
->DrawLayers(&frame
);
1749 host_impl_
->DidDrawAllLayers(frame
);
1751 EXPECT_TRUE(layer
->will_draw_called());
1752 EXPECT_FALSE(layer
->append_quads_called());
1753 EXPECT_FALSE(layer
->did_draw_called());
1757 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1758 // The root layer is always drawn, so run this test on a child layer that
1759 // will be masked out by the root layer's bounds.
1760 host_impl_
->active_tree()->SetRootLayer(
1761 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1762 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1763 host_impl_
->active_tree()->root_layer());
1764 root
->SetMasksToBounds(true);
1766 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1767 DidDrawCheckLayer
* layer
=
1768 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1769 // Ensure visible_content_rect for layer is empty.
1770 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1771 layer
->SetBounds(gfx::Size(10, 10));
1772 layer
->SetContentBounds(gfx::Size(10, 10));
1774 LayerTreeHostImpl::FrameData frame
;
1776 EXPECT_FALSE(layer
->will_draw_called());
1777 EXPECT_FALSE(layer
->did_draw_called());
1779 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1780 host_impl_
->DrawLayers(&frame
);
1781 host_impl_
->DidDrawAllLayers(frame
);
1783 EXPECT_FALSE(layer
->will_draw_called());
1784 EXPECT_FALSE(layer
->did_draw_called());
1786 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1788 // Ensure visible_content_rect for layer is not empty
1789 layer
->SetPosition(gfx::PointF());
1791 EXPECT_FALSE(layer
->will_draw_called());
1792 EXPECT_FALSE(layer
->did_draw_called());
1794 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1795 host_impl_
->DrawLayers(&frame
);
1796 host_impl_
->DidDrawAllLayers(frame
);
1798 EXPECT_TRUE(layer
->will_draw_called());
1799 EXPECT_TRUE(layer
->did_draw_called());
1801 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1804 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1805 gfx::Size
big_size(1000, 1000);
1806 host_impl_
->SetViewportSize(big_size
);
1808 host_impl_
->active_tree()->SetRootLayer(
1809 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1810 DidDrawCheckLayer
* root
=
1811 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1813 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1814 DidDrawCheckLayer
* occluded_layer
=
1815 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1817 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1818 DidDrawCheckLayer
* top_layer
=
1819 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1820 // This layer covers the occluded_layer above. Make this layer large so it can
1822 top_layer
->SetBounds(big_size
);
1823 top_layer
->SetContentBounds(big_size
);
1824 top_layer
->SetContentsOpaque(true);
1826 LayerTreeHostImpl::FrameData frame
;
1828 EXPECT_FALSE(occluded_layer
->will_draw_called());
1829 EXPECT_FALSE(occluded_layer
->did_draw_called());
1830 EXPECT_FALSE(top_layer
->will_draw_called());
1831 EXPECT_FALSE(top_layer
->did_draw_called());
1833 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1834 host_impl_
->DrawLayers(&frame
);
1835 host_impl_
->DidDrawAllLayers(frame
);
1837 EXPECT_FALSE(occluded_layer
->will_draw_called());
1838 EXPECT_FALSE(occluded_layer
->did_draw_called());
1839 EXPECT_TRUE(top_layer
->will_draw_called());
1840 EXPECT_TRUE(top_layer
->did_draw_called());
1843 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1844 host_impl_
->active_tree()->SetRootLayer(
1845 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1846 DidDrawCheckLayer
* root
=
1847 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1849 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1850 DidDrawCheckLayer
* layer1
=
1851 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1853 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1854 DidDrawCheckLayer
* layer2
=
1855 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1857 layer1
->SetOpacity(0.3f
);
1858 layer1
->SetShouldFlattenTransform(true);
1860 EXPECT_FALSE(root
->did_draw_called());
1861 EXPECT_FALSE(layer1
->did_draw_called());
1862 EXPECT_FALSE(layer2
->did_draw_called());
1864 LayerTreeHostImpl::FrameData frame
;
1865 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1866 host_impl_
->DrawLayers(&frame
);
1867 host_impl_
->DidDrawAllLayers(frame
);
1869 EXPECT_TRUE(root
->did_draw_called());
1870 EXPECT_TRUE(layer1
->did_draw_called());
1871 EXPECT_TRUE(layer2
->did_draw_called());
1873 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1874 EXPECT_TRUE(!!layer1
->render_surface());
1877 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1879 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1882 bool had_incomplete_tile
,
1884 ResourceProvider
* resource_provider
) {
1885 return scoped_ptr
<LayerImpl
>(
1886 new MissingTextureAnimatingLayer(tree_impl
,
1889 had_incomplete_tile
,
1891 resource_provider
));
1894 virtual void AppendQuads(RenderPass
* render_pass
,
1895 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
1896 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1897 LayerImpl::AppendQuads(render_pass
, occlusion_tracker
, append_quads_data
);
1898 if (had_incomplete_tile_
)
1899 append_quads_data
->had_incomplete_tile
= true;
1901 append_quads_data
->num_missing_tiles
++;
1905 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1908 bool had_incomplete_tile
,
1910 ResourceProvider
* resource_provider
)
1911 : DidDrawCheckLayer(tree_impl
, id
),
1912 tile_missing_(tile_missing
),
1913 had_incomplete_tile_(had_incomplete_tile
) {
1915 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1919 bool had_incomplete_tile_
;
1922 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsOnDefault
) {
1923 host_impl_
->active_tree()->SetRootLayer(
1924 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1925 DidDrawCheckLayer
* root
=
1926 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1928 bool tile_missing
= false;
1929 bool had_incomplete_tile
= false;
1930 bool is_animating
= false;
1932 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1935 had_incomplete_tile
,
1937 host_impl_
->resource_provider()));
1939 LayerTreeHostImpl::FrameData frame
;
1941 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1942 host_impl_
->DrawLayers(&frame
);
1943 host_impl_
->DidDrawAllLayers(frame
);
1946 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
1947 host_impl_
->active_tree()->SetRootLayer(
1948 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1949 DidDrawCheckLayer
* root
=
1950 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1951 bool tile_missing
= false;
1952 bool had_incomplete_tile
= false;
1953 bool is_animating
= true;
1955 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1958 had_incomplete_tile
,
1960 host_impl_
->resource_provider()));
1962 LayerTreeHostImpl::FrameData frame
;
1964 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1965 host_impl_
->DrawLayers(&frame
);
1966 host_impl_
->DidDrawAllLayers(frame
);
1969 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithMissingTiles
) {
1970 host_impl_
->active_tree()->SetRootLayer(
1971 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1972 DidDrawCheckLayer
* root
=
1973 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1975 bool tile_missing
= true;
1976 bool had_incomplete_tile
= false;
1977 bool is_animating
= false;
1979 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1982 had_incomplete_tile
,
1984 host_impl_
->resource_provider()));
1985 LayerTreeHostImpl::FrameData frame
;
1986 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1987 host_impl_
->DrawLayers(&frame
);
1988 host_impl_
->DidDrawAllLayers(frame
);
1991 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithIncompleteTile
) {
1992 host_impl_
->active_tree()->SetRootLayer(
1993 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1994 DidDrawCheckLayer
* root
=
1995 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1997 bool tile_missing
= false;
1998 bool had_incomplete_tile
= true;
1999 bool is_animating
= false;
2001 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2004 had_incomplete_tile
,
2006 host_impl_
->resource_provider()));
2007 LayerTreeHostImpl::FrameData frame
;
2008 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2009 host_impl_
->DrawLayers(&frame
);
2010 host_impl_
->DidDrawAllLayers(frame
);
2013 TEST_F(LayerTreeHostImplTest
,
2014 PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard
) {
2015 host_impl_
->active_tree()->SetRootLayer(
2016 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2017 DidDrawCheckLayer
* root
=
2018 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2019 bool tile_missing
= true;
2020 bool had_incomplete_tile
= false;
2021 bool is_animating
= true;
2023 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2026 had_incomplete_tile
,
2028 host_impl_
->resource_provider()));
2029 LayerTreeHostImpl::FrameData frame
;
2030 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2031 host_impl_
->PrepareToDraw(&frame
));
2032 host_impl_
->DrawLayers(&frame
);
2033 host_impl_
->DidDrawAllLayers(frame
);
2036 TEST_F(LayerTreeHostImplTest
,
2037 PrepareToDrawSucceedsWithAnimationAndIncompleteTiles
) {
2038 host_impl_
->active_tree()->SetRootLayer(
2039 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2040 DidDrawCheckLayer
* root
=
2041 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2042 bool tile_missing
= false;
2043 bool had_incomplete_tile
= true;
2044 bool is_animating
= true;
2046 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2049 had_incomplete_tile
,
2051 host_impl_
->resource_provider()));
2052 LayerTreeHostImpl::FrameData frame
;
2053 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2054 host_impl_
->DrawLayers(&frame
);
2055 host_impl_
->DidDrawAllLayers(frame
);
2058 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenHighResRequired
) {
2059 host_impl_
->active_tree()->SetRootLayer(
2060 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2061 DidDrawCheckLayer
* root
=
2062 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2063 bool tile_missing
= false;
2064 bool had_incomplete_tile
= false;
2065 bool is_animating
= false;
2067 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2070 had_incomplete_tile
,
2072 host_impl_
->resource_provider()));
2073 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2074 LayerTreeHostImpl::FrameData frame
;
2075 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2076 host_impl_
->DrawLayers(&frame
);
2077 host_impl_
->DidDrawAllLayers(frame
);
2080 TEST_F(LayerTreeHostImplTest
,
2081 PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles
) {
2082 host_impl_
->active_tree()->SetRootLayer(
2083 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2084 DidDrawCheckLayer
* root
=
2085 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2086 bool tile_missing
= false;
2087 bool had_incomplete_tile
= true;
2088 bool is_animating
= false;
2090 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2093 had_incomplete_tile
,
2095 host_impl_
->resource_provider()));
2096 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2097 LayerTreeHostImpl::FrameData frame
;
2098 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2099 host_impl_
->PrepareToDraw(&frame
));
2100 host_impl_
->DrawLayers(&frame
);
2101 host_impl_
->DidDrawAllLayers(frame
);
2104 TEST_F(LayerTreeHostImplTest
,
2105 PrepareToDrawSucceedsWhenHighResRequiredAndMissingTile
) {
2106 host_impl_
->active_tree()->SetRootLayer(
2107 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2108 DidDrawCheckLayer
* root
=
2109 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2110 bool tile_missing
= true;
2111 bool had_incomplete_tile
= false;
2112 bool is_animating
= false;
2114 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2117 had_incomplete_tile
,
2119 host_impl_
->resource_provider()));
2120 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2121 LayerTreeHostImpl::FrameData frame
;
2122 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2123 host_impl_
->DrawLayers(&frame
);
2124 host_impl_
->DidDrawAllLayers(frame
);
2127 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2128 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2129 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2130 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2133 // Scroll event is ignored because layer is not scrollable.
2134 EXPECT_EQ(InputHandler::ScrollIgnored
,
2135 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2136 EXPECT_FALSE(did_request_redraw_
);
2137 EXPECT_FALSE(did_request_commit_
);
2140 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2142 LayerTreeHostImplTopControlsTest()
2143 // Make the clip size the same as the layer (content) size so the layer is
2145 : layer_size_(10, 10),
2146 clip_size_(layer_size_
) {
2147 settings_
.calculate_top_controls_position
= true;
2148 settings_
.top_controls_height
= 50;
2151 gfx::Size(clip_size_
.width(),
2152 clip_size_
.height() + settings_
.top_controls_height
);
2155 void SetupTopControlsAndScrollLayer() {
2156 CreateHostImpl(settings_
, CreateOutputSurface());
2158 scoped_ptr
<LayerImpl
> root
=
2159 LayerImpl::Create(host_impl_
->active_tree(), 1);
2160 scoped_ptr
<LayerImpl
> root_clip
=
2161 LayerImpl::Create(host_impl_
->active_tree(), 2);
2162 root_clip
->SetBounds(clip_size_
);
2163 root
->SetScrollClipLayer(root_clip
->id());
2164 root
->SetBounds(layer_size_
);
2165 root
->SetContentBounds(layer_size_
);
2166 root
->SetPosition(gfx::PointF());
2167 root
->SetDrawsContent(false);
2168 root
->SetIsContainerForFixedPositionLayers(true);
2169 int inner_viewport_scroll_layer_id
= root
->id();
2170 int page_scale_layer_id
= root_clip
->id();
2171 root_clip
->AddChild(root
.Pass());
2172 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2173 host_impl_
->active_tree()->SetViewportLayersFromIds(
2174 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2175 // Set a viewport size that is large enough to contain both the top controls
2176 // and some content.
2177 host_impl_
->SetViewportSize(viewport_size_
);
2178 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2179 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2183 gfx::Size layer_size_
;
2184 gfx::Size clip_size_
;
2185 gfx::Size viewport_size_
;
2187 LayerTreeSettings settings_
;
2188 }; // class LayerTreeHostImplTopControlsTest
2190 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2191 SetupTopControlsAndScrollLayer();
2194 EXPECT_EQ(InputHandler::ScrollStarted
,
2195 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2197 // Make the test scroll delta a fractional amount, to verify that the
2198 // fixed container size delta is (1) non-zero, and (2) fractional, and
2199 // (3) matches the movement of the top controls.
2200 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2201 host_impl_
->top_controls_manager()->ScrollBegin();
2202 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2203 host_impl_
->top_controls_manager()->ScrollEnd();
2205 LayerImpl
* inner_viewport_scroll_layer
=
2206 host_impl_
->active_tree()->InnerViewportScrollLayer();
2207 DCHECK(inner_viewport_scroll_layer
);
2208 host_impl_
->ScrollEnd();
2209 EXPECT_EQ(top_controls_scroll_delta
,
2210 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2213 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsWithPageScale
) {
2214 SetupTopControlsAndScrollLayer();
2217 EXPECT_EQ(InputHandler::ScrollStarted
,
2218 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2220 float page_scale
= 1.5f
;
2221 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
, 1.f
, 2.f
);
2223 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.f
);
2224 gfx::Vector2dF expected_container_size_delta
=
2225 ScaleVector2d(top_controls_scroll_delta
, 1.f
/ page_scale
);
2226 host_impl_
->top_controls_manager()->ScrollBegin();
2227 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2228 host_impl_
->top_controls_manager()->ScrollEnd();
2230 LayerImpl
* inner_viewport_scroll_layer
=
2231 host_impl_
->active_tree()->InnerViewportScrollLayer();
2232 DCHECK(inner_viewport_scroll_layer
);
2233 host_impl_
->ScrollEnd();
2235 // Use a tolerance that requires the container size delta to be within 0.01
2237 double tolerance
= 0.0001;
2239 (expected_container_size_delta
-
2240 inner_viewport_scroll_layer
->FixedContainerSizeDelta()).LengthSquared(),
2244 TEST_F(LayerTreeHostImplTopControlsTest
,
2245 ScrollNonScrollableRootWithTopControls
) {
2246 SetupTopControlsAndScrollLayer();
2249 EXPECT_EQ(InputHandler::ScrollStarted
,
2250 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2252 host_impl_
->top_controls_manager()->ScrollBegin();
2253 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2254 host_impl_
->top_controls_manager()->ScrollEnd();
2255 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->content_top_offset());
2256 // Now that top controls have moved, expect the clip to resize.
2257 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2258 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2260 host_impl_
->ScrollEnd();
2262 EXPECT_EQ(InputHandler::ScrollStarted
,
2263 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2265 float scroll_increment_y
= -25.f
;
2266 host_impl_
->top_controls_manager()->ScrollBegin();
2267 host_impl_
->top_controls_manager()->ScrollBy(
2268 gfx::Vector2dF(0.f
, scroll_increment_y
));
2269 EXPECT_EQ(-scroll_increment_y
,
2270 host_impl_
->top_controls_manager()->content_top_offset());
2271 // Now that top controls have moved, expect the clip to resize.
2272 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2273 viewport_size_
.height() + scroll_increment_y
),
2274 root_clip_ptr
->bounds());
2276 host_impl_
->top_controls_manager()->ScrollBy(
2277 gfx::Vector2dF(0.f
, scroll_increment_y
));
2278 host_impl_
->top_controls_manager()->ScrollEnd();
2279 EXPECT_EQ(-2 * scroll_increment_y
,
2280 host_impl_
->top_controls_manager()->content_top_offset());
2281 // Now that top controls have moved, expect the clip to resize.
2282 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2284 host_impl_
->ScrollEnd();
2286 // Verify the layer is once-again non-scrollable.
2289 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2291 EXPECT_EQ(InputHandler::ScrollStarted
,
2292 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2295 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2296 // Test the configuration where a non-composited root layer is embedded in a
2297 // scrollable outer layer.
2298 gfx::Size
surface_size(10, 10);
2299 gfx::Size
contents_size(20, 20);
2301 scoped_ptr
<LayerImpl
> content_layer
=
2302 LayerImpl::Create(host_impl_
->active_tree(), 1);
2303 content_layer
->SetDrawsContent(true);
2304 content_layer
->SetPosition(gfx::PointF());
2305 content_layer
->SetBounds(contents_size
);
2306 content_layer
->SetContentBounds(contents_size
);
2307 content_layer
->SetContentsScale(2.f
, 2.f
);
2309 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2310 LayerImpl::Create(host_impl_
->active_tree(), 3);
2311 scroll_clip_layer
->SetBounds(surface_size
);
2313 scoped_ptr
<LayerImpl
> scroll_layer
=
2314 LayerImpl::Create(host_impl_
->active_tree(), 2);
2315 scroll_layer
->SetScrollClipLayer(3);
2316 scroll_layer
->SetBounds(contents_size
);
2317 scroll_layer
->SetContentBounds(contents_size
);
2318 scroll_layer
->SetPosition(gfx::PointF());
2319 scroll_layer
->AddChild(content_layer
.Pass());
2320 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2322 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2323 host_impl_
->SetViewportSize(surface_size
);
2326 EXPECT_EQ(InputHandler::ScrollStarted
,
2327 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2328 InputHandler::Wheel
));
2329 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2330 host_impl_
->ScrollEnd();
2331 EXPECT_TRUE(did_request_redraw_
);
2332 EXPECT_TRUE(did_request_commit_
);
2335 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2336 gfx::Size
surface_size(10, 10);
2337 gfx::Size
contents_size(20, 20);
2338 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2339 root
->SetBounds(surface_size
);
2340 root
->SetContentBounds(contents_size
);
2341 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2342 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2343 host_impl_
->SetViewportSize(surface_size
);
2346 EXPECT_EQ(InputHandler::ScrollStarted
,
2347 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2348 InputHandler::Wheel
));
2349 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2350 host_impl_
->ScrollEnd();
2351 EXPECT_TRUE(did_request_redraw_
);
2352 EXPECT_TRUE(did_request_commit_
);
2355 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2356 gfx::Size
surface_size(10, 10);
2357 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2358 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2359 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2360 host_impl_
->SetViewportSize(surface_size
);
2363 // Scroll event is ignored because the input coordinate is outside the layer
2365 EXPECT_EQ(InputHandler::ScrollIgnored
,
2366 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2367 InputHandler::Wheel
));
2368 EXPECT_FALSE(did_request_redraw_
);
2369 EXPECT_FALSE(did_request_commit_
);
2372 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2373 gfx::Size
surface_size(10, 10);
2374 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2375 scoped_ptr
<LayerImpl
> child
=
2376 CreateScrollableLayer(2, surface_size
, root
.get());
2377 host_impl_
->SetViewportSize(surface_size
);
2379 gfx::Transform matrix
;
2380 matrix
.RotateAboutXAxis(180.0);
2381 child
->SetTransform(matrix
);
2382 child
->SetDoubleSided(false);
2384 root
->AddChild(child
.Pass());
2385 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2388 // Scroll event is ignored because the scrollable layer is not facing the
2389 // viewer and there is nothing scrollable behind it.
2390 EXPECT_EQ(InputHandler::ScrollIgnored
,
2391 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2392 InputHandler::Wheel
));
2393 EXPECT_FALSE(did_request_redraw_
);
2394 EXPECT_FALSE(did_request_commit_
);
2397 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2398 gfx::Size
surface_size(10, 10);
2399 scoped_ptr
<LayerImpl
> clip_layer
=
2400 LayerImpl::Create(host_impl_
->active_tree(), 3);
2401 scoped_ptr
<LayerImpl
> content_layer
=
2402 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2403 content_layer
->SetShouldScrollOnMainThread(true);
2404 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2406 // Note: we can use the same clip layer for both since both calls to
2407 // CreateScrollableLayer() use the same surface size.
2408 scoped_ptr
<LayerImpl
> scroll_layer
=
2409 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2410 scroll_layer
->AddChild(content_layer
.Pass());
2411 clip_layer
->AddChild(scroll_layer
.Pass());
2413 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2414 host_impl_
->SetViewportSize(surface_size
);
2417 // Scrolling fails because the content layer is asking to be scrolled on the
2419 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2420 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2421 InputHandler::Wheel
));
2424 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2425 gfx::Size
surface_size(20, 20);
2426 gfx::Size
viewport_size(10, 10);
2427 float page_scale
= 2.f
;
2428 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2429 scoped_ptr
<LayerImpl
> root_clip
=
2430 LayerImpl::Create(host_impl_
->active_tree(), 2);
2431 scoped_ptr
<LayerImpl
> root_scrolling
=
2432 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2433 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2434 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2435 root_clip
->AddChild(root_scrolling
.Pass());
2436 root
->AddChild(root_clip
.Pass());
2437 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2438 // The behaviour in this test assumes the page scale is applied at a layer
2439 // above the clip layer.
2440 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2441 host_impl_
->active_tree()->DidBecomeActive();
2442 host_impl_
->SetViewportSize(viewport_size
);
2445 LayerImpl
* root_scroll
=
2446 host_impl_
->active_tree()->InnerViewportScrollLayer();
2447 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2449 gfx::Vector2d
scroll_delta(0, 10);
2450 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2451 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2452 EXPECT_EQ(InputHandler::ScrollStarted
,
2453 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2454 InputHandler::Wheel
));
2455 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2456 host_impl_
->ScrollEnd();
2458 // Set new page scale from main thread.
2459 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2463 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2464 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2466 // The scroll range should also have been updated.
2467 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2469 // The page scale delta remains constant because the impl thread did not
2471 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2474 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
2475 gfx::Size
surface_size(20, 20);
2476 gfx::Size
viewport_size(10, 10);
2477 float page_scale
= 2.f
;
2478 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2479 scoped_ptr
<LayerImpl
> root_clip
=
2480 LayerImpl::Create(host_impl_
->active_tree(), 2);
2481 scoped_ptr
<LayerImpl
> root_scrolling
=
2482 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2483 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2484 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2485 root_clip
->AddChild(root_scrolling
.Pass());
2486 root
->AddChild(root_clip
.Pass());
2487 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2488 // The behaviour in this test assumes the page scale is applied at a layer
2489 // above the clip layer.
2490 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2491 host_impl_
->active_tree()->DidBecomeActive();
2492 host_impl_
->SetViewportSize(viewport_size
);
2493 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, page_scale
);
2496 LayerImpl
* root_scroll
=
2497 host_impl_
->active_tree()->InnerViewportScrollLayer();
2498 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2500 gfx::Vector2d
scroll_delta(0, 10);
2501 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2502 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2503 EXPECT_EQ(InputHandler::ScrollStarted
,
2504 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2505 InputHandler::Wheel
));
2506 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2507 host_impl_
->ScrollEnd();
2509 // Set new page scale on impl thread by pinching.
2510 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2511 host_impl_
->PinchGestureBegin();
2512 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
2513 host_impl_
->PinchGestureEnd();
2514 host_impl_
->ScrollEnd();
2517 // The scroll delta is not scaled because the main thread did not scale.
2518 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2519 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2521 // The scroll range should also have been updated.
2522 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2524 // The page scale delta should match the new scale on the impl side.
2525 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->total_page_scale_factor());
2528 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
2529 gfx::Size
surface_size(10, 10);
2530 float default_page_scale
= 1.f
;
2531 gfx::Transform default_page_scale_matrix
;
2532 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
2534 float new_page_scale
= 2.f
;
2535 gfx::Transform new_page_scale_matrix
;
2536 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
2538 // Create a normal scrollable root layer and another scrollable child layer.
2539 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
2540 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
2541 LayerImpl
* child
= scroll
->children()[0];
2543 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
2544 LayerImpl::Create(host_impl_
->active_tree(), 6);
2545 scoped_ptr
<LayerImpl
> scrollable_child
=
2546 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
2547 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
2548 child
->AddChild(scrollable_child_clip
.Pass());
2549 LayerImpl
* grand_child
= child
->children()[0];
2551 // Set new page scale on impl thread by pinching.
2552 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2553 host_impl_
->PinchGestureBegin();
2554 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
2555 host_impl_
->PinchGestureEnd();
2556 host_impl_
->ScrollEnd();
2559 EXPECT_EQ(1.f
, root
->contents_scale_x());
2560 EXPECT_EQ(1.f
, root
->contents_scale_y());
2561 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
2562 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
2563 EXPECT_EQ(1.f
, child
->contents_scale_x());
2564 EXPECT_EQ(1.f
, child
->contents_scale_y());
2565 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
2566 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
2568 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2569 // the page scale delta on the root layer is applied hierarchically.
2570 LayerTreeHostImpl::FrameData frame
;
2571 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2572 host_impl_
->DrawLayers(&frame
);
2573 host_impl_
->DidDrawAllLayers(frame
);
2575 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
2576 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
2577 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
2578 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
2579 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
2580 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
2581 EXPECT_EQ(new_page_scale
,
2582 grand_child
->draw_transform().matrix().getDouble(0, 0));
2583 EXPECT_EQ(new_page_scale
,
2584 grand_child
->draw_transform().matrix().getDouble(1, 1));
2587 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
2588 gfx::Size
surface_size(30, 30);
2589 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2590 root
->SetBounds(gfx::Size(5, 5));
2591 scoped_ptr
<LayerImpl
> root_scrolling
=
2592 LayerImpl::Create(host_impl_
->active_tree(), 2);
2593 root_scrolling
->SetBounds(surface_size
);
2594 root_scrolling
->SetContentBounds(surface_size
);
2595 root_scrolling
->SetScrollClipLayer(root
->id());
2596 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2597 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
2598 root
->AddChild(root_scrolling
.Pass());
2599 int child_scroll_layer_id
= 3;
2600 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
2601 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
2602 LayerImpl
* child
= child_scrolling
.get();
2603 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
2604 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2605 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2606 host_impl_
->active_tree()->DidBecomeActive();
2607 host_impl_
->SetViewportSize(surface_size
);
2610 gfx::Vector2d
scroll_delta(0, 10);
2611 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
2612 gfx::Vector2d
expected_max_scroll(child
->MaxScrollOffset());
2613 EXPECT_EQ(InputHandler::ScrollStarted
,
2614 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2615 InputHandler::Wheel
));
2616 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2617 host_impl_
->ScrollEnd();
2619 float page_scale
= 2.f
;
2620 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2626 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2628 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
2630 // The scroll range should not have changed.
2631 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
2633 // The page scale delta remains constant because the impl thread did not
2635 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2638 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
2639 // Scroll a child layer beyond its maximum scroll range and make sure the
2640 // parent layer is scrolled on the axis on which the child was unable to
2642 gfx::Size
surface_size(10, 10);
2643 gfx::Size
content_size(20, 20);
2644 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2645 root
->SetBounds(surface_size
);
2647 scoped_ptr
<LayerImpl
> grand_child
=
2648 CreateScrollableLayer(3, content_size
, root
.get());
2650 scoped_ptr
<LayerImpl
> child
=
2651 CreateScrollableLayer(2, content_size
, root
.get());
2652 LayerImpl
* grand_child_layer
= grand_child
.get();
2653 child
->AddChild(grand_child
.Pass());
2655 LayerImpl
* child_layer
= child
.get();
2656 root
->AddChild(child
.Pass());
2657 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2658 host_impl_
->active_tree()->DidBecomeActive();
2659 host_impl_
->SetViewportSize(surface_size
);
2660 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 5));
2661 child_layer
->SetScrollOffset(gfx::Vector2d(3, 0));
2665 gfx::Vector2d
scroll_delta(-8, -7);
2666 EXPECT_EQ(InputHandler::ScrollStarted
,
2667 host_impl_
->ScrollBegin(gfx::Point(),
2668 InputHandler::Wheel
));
2669 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2670 host_impl_
->ScrollEnd();
2672 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2673 host_impl_
->ProcessScrollDeltas();
2675 // The grand child should have scrolled up to its limit.
2676 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
2677 LayerImpl
* grand_child
= child
->children()[0];
2678 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
2680 // The child should have only scrolled on the other axis.
2681 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
2685 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
2686 // Scroll a child layer beyond its maximum scroll range and make sure the
2687 // the scroll doesn't bubble up to the parent layer.
2688 gfx::Size
surface_size(20, 20);
2689 gfx::Size
viewport_size(10, 10);
2690 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2691 scoped_ptr
<LayerImpl
> root_scrolling
=
2692 CreateScrollableLayer(2, surface_size
, root
.get());
2693 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2695 scoped_ptr
<LayerImpl
> grand_child
=
2696 CreateScrollableLayer(4, surface_size
, root
.get());
2698 scoped_ptr
<LayerImpl
> child
=
2699 CreateScrollableLayer(3, surface_size
, root
.get());
2700 LayerImpl
* grand_child_layer
= grand_child
.get();
2701 child
->AddChild(grand_child
.Pass());
2703 LayerImpl
* child_layer
= child
.get();
2704 root_scrolling
->AddChild(child
.Pass());
2705 root
->AddChild(root_scrolling
.Pass());
2706 EXPECT_EQ(viewport_size
, root
->bounds());
2707 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2708 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2709 host_impl_
->active_tree()->DidBecomeActive();
2710 host_impl_
->SetViewportSize(viewport_size
);
2712 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
2713 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
2717 gfx::Vector2d
scroll_delta(0, -10);
2718 EXPECT_EQ(InputHandler::ScrollStarted
,
2719 host_impl_
->ScrollBegin(gfx::Point(),
2720 InputHandler::NonBubblingGesture
));
2721 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2722 host_impl_
->ScrollEnd();
2724 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2725 host_impl_
->ProcessScrollDeltas();
2727 // The grand child should have scrolled up to its limit.
2729 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
2730 LayerImpl
* grand_child
= child
->children()[0];
2731 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2733 // The child should not have scrolled.
2734 ExpectNone(*scroll_info
.get(), child
->id());
2736 // The next time we scroll we should only scroll the parent.
2737 scroll_delta
= gfx::Vector2d(0, -3);
2738 EXPECT_EQ(InputHandler::ScrollStarted
,
2739 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2740 InputHandler::NonBubblingGesture
));
2741 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2742 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2743 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
2744 host_impl_
->ScrollEnd();
2746 scroll_info
= host_impl_
->ProcessScrollDeltas();
2748 // The child should have scrolled up to its limit.
2749 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2751 // The grand child should not have scrolled.
2752 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2754 // After scrolling the parent, another scroll on the opposite direction
2755 // should still scroll the child.
2756 scroll_delta
= gfx::Vector2d(0, 7);
2757 EXPECT_EQ(InputHandler::ScrollStarted
,
2758 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2759 InputHandler::NonBubblingGesture
));
2760 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2761 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2762 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2763 host_impl_
->ScrollEnd();
2765 scroll_info
= host_impl_
->ProcessScrollDeltas();
2767 // The grand child should have scrolled.
2768 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
2770 // The child should not have scrolled.
2771 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2774 // Scrolling should be adjusted from viewport space.
2775 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 2.f
, 2.f
);
2776 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
2778 scroll_delta
= gfx::Vector2d(0, -2);
2779 EXPECT_EQ(InputHandler::ScrollStarted
,
2780 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2781 InputHandler::NonBubblingGesture
));
2782 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
2783 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2784 host_impl_
->ScrollEnd();
2786 scroll_info
= host_impl_
->ProcessScrollDeltas();
2788 // Should have scrolled by half the amount in layer space (5 - 2/2)
2789 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
2792 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
2793 // When we try to scroll a non-scrollable child layer, the scroll delta
2794 // should be applied to one of its ancestors if possible.
2795 gfx::Size
surface_size(10, 10);
2796 gfx::Size
content_size(20, 20);
2797 scoped_ptr
<LayerImpl
> root_clip
=
2798 LayerImpl::Create(host_impl_
->active_tree(), 3);
2799 scoped_ptr
<LayerImpl
> root
=
2800 CreateScrollableLayer(1, content_size
, root_clip
.get());
2801 // Make 'root' the clip layer for child: since they have the same sizes the
2802 // child will have zero max_scroll_offset and scrolls will bubble.
2803 scoped_ptr
<LayerImpl
> child
=
2804 CreateScrollableLayer(2, content_size
, root
.get());
2805 child
->SetIsContainerForFixedPositionLayers(true);
2806 root
->SetBounds(content_size
);
2808 int root_scroll_id
= root
->id();
2809 root
->AddChild(child
.Pass());
2810 root_clip
->AddChild(root
.Pass());
2812 host_impl_
->SetViewportSize(surface_size
);
2813 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2814 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID
);
2815 host_impl_
->active_tree()->DidBecomeActive();
2818 gfx::Vector2d
scroll_delta(0, 4);
2819 EXPECT_EQ(InputHandler::ScrollStarted
,
2820 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2821 InputHandler::Wheel
));
2822 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2823 host_impl_
->ScrollEnd();
2825 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2826 host_impl_
->ProcessScrollDeltas();
2828 // Only the root scroll should have scrolled.
2829 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
2830 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
2834 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
2835 gfx::Size
surface_size(10, 10);
2836 scoped_ptr
<LayerImpl
> root_clip
=
2837 LayerImpl::Create(host_impl_
->active_tree(), 1);
2838 scoped_ptr
<LayerImpl
> root_scroll
=
2839 CreateScrollableLayer(2, surface_size
, root_clip
.get());
2840 root_scroll
->SetIsContainerForFixedPositionLayers(true);
2841 root_clip
->AddChild(root_scroll
.Pass());
2842 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2843 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2844 host_impl_
->active_tree()->DidBecomeActive();
2845 host_impl_
->SetViewportSize(surface_size
);
2847 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2850 host_impl_
->active_tree()->DetachLayerTree();
2851 scoped_ptr
<LayerImpl
> root_clip2
=
2852 LayerImpl::Create(host_impl_
->active_tree(), 3);
2853 scoped_ptr
<LayerImpl
> root_scroll2
=
2854 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
2855 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
2856 root_clip2
->AddChild(root_scroll2
.Pass());
2857 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
2858 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID
);
2859 host_impl_
->active_tree()->DidBecomeActive();
2861 // Scrolling should still work even though we did not draw yet.
2862 EXPECT_EQ(InputHandler::ScrollStarted
,
2863 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2864 InputHandler::Wheel
));
2867 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
2868 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2870 // Rotate the root layer 90 degrees counter-clockwise about its center.
2871 gfx::Transform rotate_transform
;
2872 rotate_transform
.Rotate(-90.0);
2873 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
2875 gfx::Size
surface_size(50, 50);
2876 host_impl_
->SetViewportSize(surface_size
);
2879 // Scroll to the right in screen coordinates with a gesture.
2880 gfx::Vector2d
gesture_scroll_delta(10, 0);
2881 EXPECT_EQ(InputHandler::ScrollStarted
,
2882 host_impl_
->ScrollBegin(gfx::Point(),
2883 InputHandler::Gesture
));
2884 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2885 host_impl_
->ScrollEnd();
2887 // The layer should have scrolled down in its local coordinates.
2888 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2889 ExpectContains(*scroll_info
.get(),
2891 gfx::Vector2d(0, gesture_scroll_delta
.x()));
2893 // Reset and scroll down with the wheel.
2894 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2895 gfx::Vector2d
wheel_scroll_delta(0, 10);
2896 EXPECT_EQ(InputHandler::ScrollStarted
,
2897 host_impl_
->ScrollBegin(gfx::Point(),
2898 InputHandler::Wheel
));
2899 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
2900 host_impl_
->ScrollEnd();
2902 // The layer should have scrolled down in its local coordinates.
2903 scroll_info
= host_impl_
->ProcessScrollDeltas();
2904 ExpectContains(*scroll_info
.get(),
2906 wheel_scroll_delta
);
2909 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
2910 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2911 int child_clip_layer_id
= 6;
2912 int child_layer_id
= 7;
2913 float child_layer_angle
= -20.f
;
2915 // Create a child layer that is rotated to a non-axis-aligned angle.
2916 scoped_ptr
<LayerImpl
> clip_layer
=
2917 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
2918 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
2919 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
2920 gfx::Transform rotate_transform
;
2921 rotate_transform
.Translate(-50.0, -50.0);
2922 rotate_transform
.Rotate(child_layer_angle
);
2923 rotate_transform
.Translate(50.0, 50.0);
2924 clip_layer
->SetTransform(rotate_transform
);
2926 // Only allow vertical scrolling.
2927 clip_layer
->SetBounds(
2928 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
2929 // The rotation depends on the layer's transform origin, and the child layer
2930 // is a different size than the clip, so make sure the clip layer's origin
2931 // lines up over the child.
2932 clip_layer
->SetTransformOrigin(gfx::Point3F(
2933 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
2934 LayerImpl
* child_ptr
= child
.get();
2935 clip_layer
->AddChild(child
.Pass());
2936 scroll_layer
->AddChild(clip_layer
.Pass());
2938 gfx::Size
surface_size(50, 50);
2939 host_impl_
->SetViewportSize(surface_size
);
2942 // Scroll down in screen coordinates with a gesture.
2943 gfx::Vector2d
gesture_scroll_delta(0, 10);
2944 EXPECT_EQ(InputHandler::ScrollStarted
,
2945 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2946 InputHandler::Gesture
));
2947 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2948 host_impl_
->ScrollEnd();
2950 // The child layer should have scrolled down in its local coordinates an
2951 // amount proportional to the angle between it and the input scroll delta.
2952 gfx::Vector2d
expected_scroll_delta(
2954 gesture_scroll_delta
.y() *
2955 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
2956 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2957 host_impl_
->ProcessScrollDeltas();
2958 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2960 // The root scroll layer should not have scrolled, because the input delta
2961 // was close to the layer's axis of movement.
2962 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
2965 // Now reset and scroll the same amount horizontally.
2966 child_ptr
->SetScrollDelta(gfx::Vector2dF());
2967 gfx::Vector2d
gesture_scroll_delta(10, 0);
2968 EXPECT_EQ(InputHandler::ScrollStarted
,
2969 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2970 InputHandler::Gesture
));
2971 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2972 host_impl_
->ScrollEnd();
2974 // The child layer should have scrolled down in its local coordinates an
2975 // amount proportional to the angle between it and the input scroll delta.
2976 gfx::Vector2d
expected_scroll_delta(
2978 -gesture_scroll_delta
.x() *
2979 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
2980 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2981 host_impl_
->ProcessScrollDeltas();
2982 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2984 // The root scroll layer should have scrolled more, since the input scroll
2985 // delta was mostly orthogonal to the child layer's vertical scroll axis.
2986 gfx::Vector2d
expected_root_scroll_delta(
2987 gesture_scroll_delta
.x() *
2988 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
2990 ExpectContains(*scroll_info
.get(),
2992 expected_root_scroll_delta
);
2996 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
2997 LayerImpl
* scroll_layer
=
2998 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3000 // Scale the layer to twice its normal size.
3002 gfx::Transform scale_transform
;
3003 scale_transform
.Scale(scale
, scale
);
3004 scroll_layer
->SetTransform(scale_transform
);
3006 gfx::Size
surface_size(50, 50);
3007 host_impl_
->SetViewportSize(surface_size
);
3010 // Scroll down in screen coordinates with a gesture.
3011 gfx::Vector2d
scroll_delta(0, 10);
3012 EXPECT_EQ(InputHandler::ScrollStarted
,
3013 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3014 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3015 host_impl_
->ScrollEnd();
3017 // The layer should have scrolled down in its local coordinates, but half the
3019 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3020 ExpectContains(*scroll_info
.get(),
3022 gfx::Vector2d(0, scroll_delta
.y() / scale
));
3024 // Reset and scroll down with the wheel.
3025 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3026 gfx::Vector2d
wheel_scroll_delta(0, 10);
3027 EXPECT_EQ(InputHandler::ScrollStarted
,
3028 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3029 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3030 host_impl_
->ScrollEnd();
3032 // The scale should not have been applied to the scroll delta.
3033 scroll_info
= host_impl_
->ProcessScrollDeltas();
3034 ExpectContains(*scroll_info
.get(),
3036 wheel_scroll_delta
);
3039 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3041 TestScrollOffsetDelegate()
3042 : page_scale_factor_(0.f
),
3043 min_page_scale_factor_(-1.f
),
3044 max_page_scale_factor_(-1.f
) {}
3046 virtual ~TestScrollOffsetDelegate() {}
3048 virtual gfx::Vector2dF
GetTotalScrollOffset() OVERRIDE
{
3049 return getter_return_value_
;
3052 virtual bool IsExternalFlingActive() const OVERRIDE
{ return false; }
3054 virtual void UpdateRootLayerState(const gfx::Vector2dF
& total_scroll_offset
,
3055 const gfx::Vector2dF
& max_scroll_offset
,
3056 const gfx::SizeF
& scrollable_size
,
3057 float page_scale_factor
,
3058 float min_page_scale_factor
,
3059 float max_page_scale_factor
) OVERRIDE
{
3060 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3061 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3062 last_set_scroll_offset_
= total_scroll_offset
;
3063 max_scroll_offset_
= max_scroll_offset
;
3064 scrollable_size_
= scrollable_size
;
3065 page_scale_factor_
= page_scale_factor
;
3066 min_page_scale_factor_
= min_page_scale_factor
;
3067 max_page_scale_factor_
= max_page_scale_factor
;
3070 gfx::Vector2dF
last_set_scroll_offset() {
3071 return last_set_scroll_offset_
;
3074 void set_getter_return_value(const gfx::Vector2dF
& value
) {
3075 getter_return_value_
= value
;
3078 gfx::Vector2dF
max_scroll_offset() const {
3079 return max_scroll_offset_
;
3082 gfx::SizeF
scrollable_size() const {
3083 return scrollable_size_
;
3086 float page_scale_factor() const {
3087 return page_scale_factor_
;
3090 float min_page_scale_factor() const {
3091 return min_page_scale_factor_
;
3094 float max_page_scale_factor() const {
3095 return max_page_scale_factor_
;
3099 gfx::Vector2dF last_set_scroll_offset_
;
3100 gfx::Vector2dF getter_return_value_
;
3101 gfx::Vector2dF max_scroll_offset_
;
3102 gfx::SizeF scrollable_size_
;
3103 float page_scale_factor_
;
3104 float min_page_scale_factor_
;
3105 float max_page_scale_factor_
;
3108 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3109 TestScrollOffsetDelegate scroll_delegate
;
3110 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3111 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3112 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3113 clip_layer
->SetBounds(gfx::Size(10, 20));
3115 // Setting the delegate results in the current scroll offset being set.
3116 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3117 scroll_layer
->SetScrollOffset(gfx::Vector2d());
3118 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3119 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3120 EXPECT_EQ(initial_scroll_delta
.ToString(),
3121 scroll_delegate
.last_set_scroll_offset().ToString());
3123 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3124 // page_scale_factor and {min|max}_page_scale_factor being set.
3125 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3126 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate
.max_scroll_offset());
3127 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3128 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3129 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3131 // Updating page scale immediately updates the delegate.
3132 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 0.5f
, 4.f
);
3133 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3134 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3135 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3136 host_impl_
->active_tree()->SetPageScaleDelta(1.5f
);
3137 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3138 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3139 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3140 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3141 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3142 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3143 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3144 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3146 // The pinch gesture doesn't put the delegate into a state where the scroll
3147 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3149 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3150 host_impl_
->PinchGestureBegin();
3151 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3152 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3153 host_impl_
->PinchGestureEnd();
3154 host_impl_
->ScrollEnd();
3156 // Scrolling should be relative to the offset as returned by the delegate.
3157 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3158 gfx::Vector2dF
current_offset(7.f
, 8.f
);
3160 scroll_delegate
.set_getter_return_value(current_offset
);
3161 EXPECT_EQ(InputHandler::ScrollStarted
,
3162 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3164 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3165 EXPECT_EQ(current_offset
+ scroll_delta
,
3166 scroll_delegate
.last_set_scroll_offset());
3168 current_offset
= gfx::Vector2dF(42.f
, 41.f
);
3169 scroll_delegate
.set_getter_return_value(current_offset
);
3170 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3171 EXPECT_EQ(current_offset
+ scroll_delta
,
3172 scroll_delegate
.last_set_scroll_offset());
3173 host_impl_
->ScrollEnd();
3174 scroll_delegate
.set_getter_return_value(gfx::Vector2dF());
3176 // Forces a full tree synchronization and ensures that the scroll delegate
3177 // sees the correct size of the new tree.
3178 gfx::Size
new_size(42, 24);
3179 host_impl_
->CreatePendingTree();
3180 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3181 host_impl_
->ActivateSyncTree();
3182 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3184 // Un-setting the delegate should propagate the delegate's current offset to
3185 // the root scrollable layer.
3186 current_offset
= gfx::Vector2dF(13.f
, 12.f
);
3187 scroll_delegate
.set_getter_return_value(current_offset
);
3188 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3190 EXPECT_EQ(current_offset
.ToString(),
3191 scroll_layer
->TotalScrollOffset().ToString());
3194 void CheckLayerScrollDelta(LayerImpl
* layer
, gfx::Vector2dF scroll_delta
) {
3195 const gfx::Transform target_space_transform
=
3196 layer
->draw_properties().target_space_transform
;
3197 EXPECT_TRUE(target_space_transform
.IsScaleOrTranslation());
3198 gfx::Point translated_point
;
3199 target_space_transform
.TransformPoint(&translated_point
);
3200 gfx::Point expected_point
= gfx::Point() - ToRoundedVector2d(scroll_delta
);
3201 EXPECT_EQ(expected_point
.ToString(), translated_point
.ToString());
3204 TEST_F(LayerTreeHostImplTest
,
3205 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw
) {
3206 TestScrollOffsetDelegate scroll_delegate
;
3207 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3208 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3209 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3210 clip_layer
->SetBounds(gfx::Size(10, 20));
3211 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3213 // Draw first frame to clear any pending draws and check scroll.
3215 CheckLayerScrollDelta(scroll_layer
, gfx::Vector2dF(0.f
, 0.f
));
3216 EXPECT_FALSE(host_impl_
->active_tree()->needs_update_draw_properties());
3218 // Set external scroll delta on delegate and notify LayerTreeHost.
3219 gfx::Vector2dF
scroll_delta(10.f
, 10.f
);
3220 scroll_delegate
.set_getter_return_value(scroll_delta
);
3221 host_impl_
->OnRootLayerDelegatedScrollOffsetChanged();
3223 // Check scroll delta reflected in layer.
3225 CheckLayerScrollDelta(scroll_layer
, scroll_delta
);
3227 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3230 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3231 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3232 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3233 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3235 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3237 // In-bounds scrolling does not affect overscroll.
3238 EXPECT_EQ(InputHandler::ScrollStarted
,
3239 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3240 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3241 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3243 // Overscroll events are reflected immediately.
3244 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3245 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3247 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3248 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3249 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3250 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3251 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3252 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3253 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3254 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3255 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3256 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3257 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3258 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3259 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3261 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3262 // as no scroll occurs.
3263 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3264 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3265 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3266 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3267 // Overscroll resets on valid scroll.
3268 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3269 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3270 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3271 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3272 host_impl_
->ScrollEnd();
3276 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3277 // Scroll child layers beyond their maximum scroll range and make sure root
3278 // overscroll does not accumulate.
3279 gfx::Size
surface_size(10, 10);
3280 scoped_ptr
<LayerImpl
> root_clip
=
3281 LayerImpl::Create(host_impl_
->active_tree(), 4);
3282 scoped_ptr
<LayerImpl
> root
=
3283 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3285 scoped_ptr
<LayerImpl
> grand_child
=
3286 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3288 scoped_ptr
<LayerImpl
> child
=
3289 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3290 LayerImpl
* grand_child_layer
= grand_child
.get();
3291 child
->AddChild(grand_child
.Pass());
3293 LayerImpl
* child_layer
= child
.get();
3294 root
->AddChild(child
.Pass());
3295 root_clip
->AddChild(root
.Pass());
3296 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
3297 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
3298 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3299 host_impl_
->active_tree()->DidBecomeActive();
3300 host_impl_
->SetViewportSize(surface_size
);
3303 gfx::Vector2d
scroll_delta(0, -10);
3304 EXPECT_EQ(InputHandler::ScrollStarted
,
3305 host_impl_
->ScrollBegin(gfx::Point(),
3306 InputHandler::NonBubblingGesture
));
3307 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3308 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3309 host_impl_
->ScrollEnd();
3311 // The next time we scroll we should only scroll the parent, but overscroll
3312 // should still not reach the root layer.
3313 scroll_delta
= gfx::Vector2d(0, -30);
3314 EXPECT_EQ(InputHandler::ScrollStarted
,
3315 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3316 InputHandler::NonBubblingGesture
));
3317 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3318 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3319 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3320 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3321 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3322 host_impl_
->ScrollEnd();
3324 // After scrolling the parent, another scroll on the opposite direction
3325 // should scroll the child.
3326 scroll_delta
= gfx::Vector2d(0, 70);
3327 EXPECT_EQ(InputHandler::ScrollStarted
,
3328 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3329 InputHandler::NonBubblingGesture
));
3330 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3331 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3332 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3333 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3334 host_impl_
->ScrollEnd();
3338 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3339 // When we try to scroll a non-scrollable child layer, the scroll delta
3340 // should be applied to one of its ancestors if possible. Overscroll should
3341 // be reflected only when it has bubbled up to the root scrolling layer.
3342 gfx::Size
surface_size(10, 10);
3343 gfx::Size
content_size(20, 20);
3344 scoped_ptr
<LayerImpl
> root_clip
=
3345 LayerImpl::Create(host_impl_
->active_tree(), 3);
3346 scoped_ptr
<LayerImpl
> root
=
3347 CreateScrollableLayer(1, content_size
, root_clip
.get());
3348 root
->SetIsContainerForFixedPositionLayers(true);
3349 scoped_ptr
<LayerImpl
> child
=
3350 CreateScrollableLayer(2, content_size
, root_clip
.get());
3352 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3353 root
->AddChild(child
.Pass());
3354 root_clip
->AddChild(root
.Pass());
3356 host_impl_
->SetViewportSize(surface_size
);
3357 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3358 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3359 host_impl_
->active_tree()->DidBecomeActive();
3362 gfx::Vector2d
scroll_delta(0, 8);
3363 EXPECT_EQ(InputHandler::ScrollStarted
,
3364 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3365 InputHandler::Wheel
));
3366 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3367 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3368 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3369 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
3370 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3371 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
3372 host_impl_
->ScrollEnd();
3376 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
3377 LayerTreeSettings settings
;
3378 CreateHostImpl(settings
, CreateOutputSurface());
3380 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
3381 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3382 clip_layer
->SetBounds(gfx::Size(50, 50));
3383 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3384 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3386 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3388 // Even though the layer can't scroll the overscroll still happens.
3389 EXPECT_EQ(InputHandler::ScrollStarted
,
3390 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3391 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3392 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3395 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
3396 gfx::Size
surface_size(980, 1439);
3397 gfx::Size
content_size(980, 1438);
3398 float device_scale_factor
= 1.5f
;
3399 scoped_ptr
<LayerImpl
> root_clip
=
3400 LayerImpl::Create(host_impl_
->active_tree(), 3);
3401 scoped_ptr
<LayerImpl
> root
=
3402 CreateScrollableLayer(1, content_size
, root_clip
.get());
3403 root
->SetIsContainerForFixedPositionLayers(true);
3404 scoped_ptr
<LayerImpl
> child
=
3405 CreateScrollableLayer(2, content_size
, root_clip
.get());
3406 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
3407 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
3408 0.326531f
, 0.326531f
, 5.f
);
3409 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3410 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3411 root
->AddChild(child
.Pass());
3412 root_clip
->AddChild(root
.Pass());
3414 host_impl_
->SetViewportSize(surface_size
);
3415 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
3416 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3417 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3418 host_impl_
->active_tree()->DidBecomeActive();
3421 // Horizontal & Vertical GlowEffect should not be applied when
3422 // content size is less then view port size. For Example Horizontal &
3423 // vertical GlowEffect should not be applied in about:blank page.
3424 EXPECT_EQ(InputHandler::ScrollStarted
,
3425 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3426 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
3427 EXPECT_EQ(gfx::Vector2dF().ToString(),
3428 host_impl_
->accumulated_root_overscroll().ToString());
3430 host_impl_
->ScrollEnd();
3434 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
3435 gfx::Size
surface_size(100, 100);
3436 gfx::Size
content_size(200, 200);
3437 scoped_ptr
<LayerImpl
> root_clip
=
3438 LayerImpl::Create(host_impl_
->active_tree(), 3);
3439 scoped_ptr
<LayerImpl
> root
=
3440 CreateScrollableLayer(1, content_size
, root_clip
.get());
3441 root
->SetIsContainerForFixedPositionLayers(true);
3442 scoped_ptr
<LayerImpl
> child
=
3443 CreateScrollableLayer(2, content_size
, root_clip
.get());
3445 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3446 root
->AddChild(child
.Pass());
3447 root_clip
->AddChild(root
.Pass());
3449 host_impl_
->SetViewportSize(surface_size
);
3450 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3451 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3452 host_impl_
->active_tree()->DidBecomeActive();
3455 // Edge glow effect should be applicable only upon reaching Edges
3456 // of the content. unnecessary glow effect calls shouldn't be
3457 // called while scrolling up without reaching the edge of the content.
3458 EXPECT_EQ(InputHandler::ScrollStarted
,
3459 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3460 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
3461 EXPECT_EQ(gfx::Vector2dF().ToString(),
3462 host_impl_
->accumulated_root_overscroll().ToString());
3463 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
3464 EXPECT_EQ(gfx::Vector2dF().ToString(),
3465 host_impl_
->accumulated_root_overscroll().ToString());
3466 host_impl_
->ScrollEnd();
3467 // unusedrootDelta should be subtracted from applied delta so that
3468 // unwanted glow effect calls are not called.
3469 EXPECT_EQ(InputHandler::ScrollStarted
,
3470 host_impl_
->ScrollBegin(gfx::Point(0, 0),
3471 InputHandler::NonBubblingGesture
));
3472 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
3473 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
3474 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3475 host_impl_
->accumulated_root_overscroll().ToString());
3477 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
3478 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3479 host_impl_
->accumulated_root_overscroll().ToString());
3480 host_impl_
->ScrollEnd();
3481 // TestCase to check kEpsilon, which prevents minute values to trigger
3482 // gloweffect without reaching edge.
3483 EXPECT_EQ(InputHandler::ScrollStarted
,
3484 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3485 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
3486 EXPECT_EQ(gfx::Vector2dF().ToString(),
3487 host_impl_
->accumulated_root_overscroll().ToString());
3488 host_impl_
->ScrollEnd();
3492 class BlendStateCheckLayer
: public LayerImpl
{
3494 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
3496 ResourceProvider
* resource_provider
) {
3497 return scoped_ptr
<LayerImpl
>(new BlendStateCheckLayer(tree_impl
,
3499 resource_provider
));
3502 virtual void AppendQuads(RenderPass
* render_pass
,
3503 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
3504 AppendQuadsData
* append_quads_data
) OVERRIDE
{
3505 quads_appended_
= true;
3507 gfx::Rect opaque_rect
;
3508 if (contents_opaque())
3509 opaque_rect
= quad_rect_
;
3511 opaque_rect
= opaque_content_rect_
;
3512 gfx::Rect visible_quad_rect
= quad_rect_
;
3514 SharedQuadState
* shared_quad_state
=
3515 render_pass
->CreateAndAppendSharedQuadState();
3516 PopulateSharedQuadState(shared_quad_state
);
3518 TileDrawQuad
* test_blending_draw_quad
=
3519 render_pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
3520 test_blending_draw_quad
->SetNew(shared_quad_state
,
3525 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
3528 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
3529 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
3530 EXPECT_EQ(has_render_surface_
, !!render_surface());
3533 void SetExpectation(bool blend
, bool has_render_surface
) {
3535 has_render_surface_
= has_render_surface
;
3536 quads_appended_
= false;
3539 bool quads_appended() const { return quads_appended_
; }
3541 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
3542 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
3543 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
3544 opaque_content_rect_
= rect
;
3548 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
3550 ResourceProvider
* resource_provider
)
3551 : LayerImpl(tree_impl
, id
),
3553 has_render_surface_(false),
3554 quads_appended_(false),
3555 quad_rect_(5, 5, 5, 5),
3556 quad_visible_rect_(5, 5, 5, 5),
3557 resource_id_(resource_provider
->CreateResource(
3560 ResourceProvider::TextureUsageAny
,
3562 resource_provider
->AllocateForTesting(resource_id_
);
3563 SetBounds(gfx::Size(10, 10));
3564 SetContentBounds(gfx::Size(10, 10));
3565 SetDrawsContent(true);
3569 bool has_render_surface_
;
3570 bool quads_appended_
;
3571 gfx::Rect quad_rect_
;
3572 gfx::Rect opaque_content_rect_
;
3573 gfx::Rect quad_visible_rect_
;
3574 ResourceProvider::ResourceId resource_id_
;
3577 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
3579 scoped_ptr
<LayerImpl
> root
=
3580 LayerImpl::Create(host_impl_
->active_tree(), 1);
3581 root
->SetBounds(gfx::Size(10, 10));
3582 root
->SetContentBounds(root
->bounds());
3583 root
->SetDrawsContent(false);
3584 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3586 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3589 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3591 host_impl_
->resource_provider()));
3592 BlendStateCheckLayer
* layer1
=
3593 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
3594 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
3596 LayerTreeHostImpl::FrameData frame
;
3598 // Opaque layer, drawn without blending.
3599 layer1
->SetContentsOpaque(true);
3600 layer1
->SetExpectation(false, false);
3601 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3602 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3603 host_impl_
->DrawLayers(&frame
);
3604 EXPECT_TRUE(layer1
->quads_appended());
3605 host_impl_
->DidDrawAllLayers(frame
);
3607 // Layer with translucent content and painting, so drawn with blending.
3608 layer1
->SetContentsOpaque(false);
3609 layer1
->SetExpectation(true, false);
3610 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3611 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3612 host_impl_
->DrawLayers(&frame
);
3613 EXPECT_TRUE(layer1
->quads_appended());
3614 host_impl_
->DidDrawAllLayers(frame
);
3616 // Layer with translucent opacity, drawn with blending.
3617 layer1
->SetContentsOpaque(true);
3618 layer1
->SetOpacity(0.5f
);
3619 layer1
->SetExpectation(true, false);
3620 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3621 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3622 host_impl_
->DrawLayers(&frame
);
3623 EXPECT_TRUE(layer1
->quads_appended());
3624 host_impl_
->DidDrawAllLayers(frame
);
3626 // Layer with translucent opacity and painting, drawn with blending.
3627 layer1
->SetContentsOpaque(true);
3628 layer1
->SetOpacity(0.5f
);
3629 layer1
->SetExpectation(true, false);
3630 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3631 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3632 host_impl_
->DrawLayers(&frame
);
3633 EXPECT_TRUE(layer1
->quads_appended());
3634 host_impl_
->DidDrawAllLayers(frame
);
3637 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3639 host_impl_
->resource_provider()));
3640 BlendStateCheckLayer
* layer2
=
3641 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
3642 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
3644 // 2 opaque layers, drawn without blending.
3645 layer1
->SetContentsOpaque(true);
3646 layer1
->SetOpacity(1.f
);
3647 layer1
->SetExpectation(false, false);
3648 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3649 layer2
->SetContentsOpaque(true);
3650 layer2
->SetOpacity(1.f
);
3651 layer2
->SetExpectation(false, false);
3652 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3653 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3654 host_impl_
->DrawLayers(&frame
);
3655 EXPECT_TRUE(layer1
->quads_appended());
3656 EXPECT_TRUE(layer2
->quads_appended());
3657 host_impl_
->DidDrawAllLayers(frame
);
3659 // Parent layer with translucent content, drawn with blending.
3660 // Child layer with opaque content, drawn without blending.
3661 layer1
->SetContentsOpaque(false);
3662 layer1
->SetExpectation(true, false);
3663 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3664 layer2
->SetExpectation(false, false);
3665 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3666 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3667 host_impl_
->DrawLayers(&frame
);
3668 EXPECT_TRUE(layer1
->quads_appended());
3669 EXPECT_TRUE(layer2
->quads_appended());
3670 host_impl_
->DidDrawAllLayers(frame
);
3672 // Parent layer with translucent content but opaque painting, drawn without
3674 // Child layer with opaque content, drawn without blending.
3675 layer1
->SetContentsOpaque(true);
3676 layer1
->SetExpectation(false, false);
3677 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3678 layer2
->SetExpectation(false, false);
3679 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3680 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3681 host_impl_
->DrawLayers(&frame
);
3682 EXPECT_TRUE(layer1
->quads_appended());
3683 EXPECT_TRUE(layer2
->quads_appended());
3684 host_impl_
->DidDrawAllLayers(frame
);
3686 // Parent layer with translucent opacity and opaque content. Since it has a
3687 // drawing child, it's drawn to a render surface which carries the opacity,
3688 // so it's itself drawn without blending.
3689 // Child layer with opaque content, drawn without blending (parent surface
3690 // carries the inherited opacity).
3691 layer1
->SetContentsOpaque(true);
3692 layer1
->SetOpacity(0.5f
);
3693 layer1
->SetExpectation(false, true);
3694 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3695 layer2
->SetExpectation(false, false);
3696 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3697 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3698 host_impl_
->DrawLayers(&frame
);
3699 EXPECT_TRUE(layer1
->quads_appended());
3700 EXPECT_TRUE(layer2
->quads_appended());
3701 host_impl_
->DidDrawAllLayers(frame
);
3703 // Draw again, but with child non-opaque, to make sure
3704 // layer1 not culled.
3705 layer1
->SetContentsOpaque(true);
3706 layer1
->SetOpacity(1.f
);
3707 layer1
->SetExpectation(false, false);
3708 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3709 layer2
->SetContentsOpaque(true);
3710 layer2
->SetOpacity(0.5f
);
3711 layer2
->SetExpectation(true, false);
3712 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3713 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3714 host_impl_
->DrawLayers(&frame
);
3715 EXPECT_TRUE(layer1
->quads_appended());
3716 EXPECT_TRUE(layer2
->quads_appended());
3717 host_impl_
->DidDrawAllLayers(frame
);
3719 // A second way of making the child non-opaque.
3720 layer1
->SetContentsOpaque(true);
3721 layer1
->SetOpacity(1.f
);
3722 layer1
->SetExpectation(false, false);
3723 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3724 layer2
->SetContentsOpaque(false);
3725 layer2
->SetOpacity(1.f
);
3726 layer2
->SetExpectation(true, false);
3727 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3728 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3729 host_impl_
->DrawLayers(&frame
);
3730 EXPECT_TRUE(layer1
->quads_appended());
3731 EXPECT_TRUE(layer2
->quads_appended());
3732 host_impl_
->DidDrawAllLayers(frame
);
3734 // And when the layer says its not opaque but is painted opaque, it is not
3736 layer1
->SetContentsOpaque(true);
3737 layer1
->SetOpacity(1.f
);
3738 layer1
->SetExpectation(false, false);
3739 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3740 layer2
->SetContentsOpaque(true);
3741 layer2
->SetOpacity(1.f
);
3742 layer2
->SetExpectation(false, false);
3743 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3744 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3745 host_impl_
->DrawLayers(&frame
);
3746 EXPECT_TRUE(layer1
->quads_appended());
3747 EXPECT_TRUE(layer2
->quads_appended());
3748 host_impl_
->DidDrawAllLayers(frame
);
3750 // Layer with partially opaque contents, drawn with blending.
3751 layer1
->SetContentsOpaque(false);
3752 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3753 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
3754 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3755 layer1
->SetExpectation(true, false);
3756 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3757 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3758 host_impl_
->DrawLayers(&frame
);
3759 EXPECT_TRUE(layer1
->quads_appended());
3760 host_impl_
->DidDrawAllLayers(frame
);
3762 // Layer with partially opaque contents partially culled, drawn with blending.
3763 layer1
->SetContentsOpaque(false);
3764 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3765 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3766 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3767 layer1
->SetExpectation(true, false);
3768 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3769 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3770 host_impl_
->DrawLayers(&frame
);
3771 EXPECT_TRUE(layer1
->quads_appended());
3772 host_impl_
->DidDrawAllLayers(frame
);
3774 // Layer with partially opaque contents culled, drawn with blending.
3775 layer1
->SetContentsOpaque(false);
3776 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3777 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3778 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3779 layer1
->SetExpectation(true, false);
3780 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3781 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3782 host_impl_
->DrawLayers(&frame
);
3783 EXPECT_TRUE(layer1
->quads_appended());
3784 host_impl_
->DidDrawAllLayers(frame
);
3786 // Layer with partially opaque contents and translucent contents culled, drawn
3787 // without blending.
3788 layer1
->SetContentsOpaque(false);
3789 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3790 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3791 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3792 layer1
->SetExpectation(false, false);
3793 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3794 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3795 host_impl_
->DrawLayers(&frame
);
3796 EXPECT_TRUE(layer1
->quads_appended());
3797 host_impl_
->DidDrawAllLayers(frame
);
3800 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
3802 LayerTreeHostImplViewportCoveredTest() :
3803 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
3805 did_activate_pending_tree_(false) {}
3807 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
3809 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d()
3810 .PassAs
<OutputSurface
>();
3812 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
3815 void SetupActiveTreeLayers() {
3816 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
3817 host_impl_
->active_tree()->SetRootLayer(
3818 LayerImpl::Create(host_impl_
->active_tree(), 1));
3819 host_impl_
->active_tree()->root_layer()->AddChild(
3820 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3822 host_impl_
->resource_provider()));
3823 child_
= static_cast<BlendStateCheckLayer
*>(
3824 host_impl_
->active_tree()->root_layer()->children()[0]);
3825 child_
->SetExpectation(false, false);
3826 child_
->SetContentsOpaque(true);
3829 // Expect no gutter rects.
3830 void TestLayerCoversFullViewport() {
3831 gfx::Rect
layer_rect(viewport_size_
);
3832 child_
->SetPosition(layer_rect
.origin());
3833 child_
->SetBounds(layer_rect
.size());
3834 child_
->SetContentBounds(layer_rect
.size());
3835 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3836 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3838 LayerTreeHostImpl::FrameData frame
;
3839 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3840 ASSERT_EQ(1u, frame
.render_passes
.size());
3842 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3843 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3844 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3846 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3847 host_impl_
->DidDrawAllLayers(frame
);
3850 // Expect fullscreen gutter rect.
3851 void TestEmptyLayer() {
3852 gfx::Rect
layer_rect(0, 0, 0, 0);
3853 child_
->SetPosition(layer_rect
.origin());
3854 child_
->SetBounds(layer_rect
.size());
3855 child_
->SetContentBounds(layer_rect
.size());
3856 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3857 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3859 LayerTreeHostImpl::FrameData frame
;
3860 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3861 ASSERT_EQ(1u, frame
.render_passes
.size());
3863 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3864 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3865 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3867 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3868 host_impl_
->DidDrawAllLayers(frame
);
3871 // Expect four surrounding gutter rects.
3872 void TestLayerInMiddleOfViewport() {
3873 gfx::Rect
layer_rect(500, 500, 200, 200);
3874 child_
->SetPosition(layer_rect
.origin());
3875 child_
->SetBounds(layer_rect
.size());
3876 child_
->SetContentBounds(layer_rect
.size());
3877 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3878 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3880 LayerTreeHostImpl::FrameData frame
;
3881 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3882 ASSERT_EQ(1u, frame
.render_passes
.size());
3884 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3885 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
3886 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3888 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3889 host_impl_
->DidDrawAllLayers(frame
);
3892 // Expect no gutter rects.
3893 void TestLayerIsLargerThanViewport() {
3894 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
3895 viewport_size_
.height() + 10);
3896 child_
->SetPosition(layer_rect
.origin());
3897 child_
->SetBounds(layer_rect
.size());
3898 child_
->SetContentBounds(layer_rect
.size());
3899 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3900 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3902 LayerTreeHostImpl::FrameData frame
;
3903 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3904 ASSERT_EQ(1u, frame
.render_passes
.size());
3906 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3907 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3908 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3910 host_impl_
->DidDrawAllLayers(frame
);
3913 virtual void DidActivateSyncTree() OVERRIDE
{
3914 did_activate_pending_tree_
= true;
3917 void set_gutter_quad_material(DrawQuad::Material material
) {
3918 gutter_quad_material_
= material
;
3920 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
3921 gutter_texture_size_
= gutter_texture_size
;
3925 size_t CountGutterQuads(const QuadList
& quad_list
) {
3926 size_t num_gutter_quads
= 0;
3927 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3928 num_gutter_quads
+= (quad_list
[i
]->material
==
3929 gutter_quad_material_
) ? 1 : 0;
3931 return num_gutter_quads
;
3934 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
3935 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3936 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
3939 // Make sure that the texture coordinates match their expectations.
3940 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
3941 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3942 if (quad_list
[i
]->material
!= DrawQuad::TEXTURE_CONTENT
)
3944 const TextureDrawQuad
* quad
= TextureDrawQuad::MaterialCast(quad_list
[i
]);
3945 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
3946 gutter_texture_size_
, host_impl_
->device_scale_factor());
3947 EXPECT_EQ(quad
->uv_top_left
.x(),
3948 quad
->rect
.x() / gutter_texture_size_pixels
.width());
3949 EXPECT_EQ(quad
->uv_top_left
.y(),
3950 quad
->rect
.y() / gutter_texture_size_pixels
.height());
3951 EXPECT_EQ(quad
->uv_bottom_right
.x(),
3952 quad
->rect
.right() / gutter_texture_size_pixels
.width());
3953 EXPECT_EQ(quad
->uv_bottom_right
.y(),
3954 quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
3958 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
3959 return gfx::ToRoundedSize(
3960 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
3963 DrawQuad::Material gutter_quad_material_
;
3964 gfx::Size gutter_texture_size_
;
3965 gfx::Size viewport_size_
;
3966 BlendStateCheckLayer
* child_
;
3967 bool did_activate_pending_tree_
;
3970 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
3971 viewport_size_
= gfx::Size(1000, 1000);
3973 bool always_draw
= false;
3974 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3976 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3977 SetupActiveTreeLayers();
3978 TestLayerCoversFullViewport();
3980 TestLayerInMiddleOfViewport();
3981 TestLayerIsLargerThanViewport();
3984 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
3985 viewport_size_
= gfx::Size(1000, 1000);
3987 bool always_draw
= false;
3988 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3990 host_impl_
->SetDeviceScaleFactor(2.f
);
3991 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3992 SetupActiveTreeLayers();
3993 TestLayerCoversFullViewport();
3995 TestLayerInMiddleOfViewport();
3996 TestLayerIsLargerThanViewport();
3999 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
4000 viewport_size_
= gfx::Size(1000, 1000);
4002 bool always_draw
= false;
4003 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4005 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4006 SetupActiveTreeLayers();
4008 // Specify an overhang bitmap to use.
4009 bool is_opaque
= false;
4010 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
4011 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
4012 UIResourceId ui_resource_id
= 12345;
4013 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
4014 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
4015 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
4016 set_gutter_texture_size(gfx::Size(32, 32));
4018 TestLayerCoversFullViewport();
4020 TestLayerInMiddleOfViewport();
4021 TestLayerIsLargerThanViewport();
4023 // Change the resource size.
4024 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
4025 set_gutter_texture_size(gfx::Size(128, 16));
4027 TestLayerCoversFullViewport();
4029 TestLayerInMiddleOfViewport();
4030 TestLayerIsLargerThanViewport();
4032 // Change the device scale factor
4033 host_impl_
->SetDeviceScaleFactor(2.f
);
4034 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4036 TestLayerCoversFullViewport();
4038 TestLayerInMiddleOfViewport();
4039 TestLayerIsLargerThanViewport();
4042 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
4043 viewport_size_
= gfx::Size(1000, 1000);
4045 bool always_draw
= true;
4046 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4048 // Pending tree to force active_tree size invalid. Not used otherwise.
4049 host_impl_
->CreatePendingTree();
4050 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4051 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4053 SetupActiveTreeLayers();
4055 TestLayerInMiddleOfViewport();
4056 TestLayerIsLargerThanViewport();
4059 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
4060 viewport_size_
= gfx::Size(1000, 1000);
4062 bool always_draw
= true;
4063 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4065 // Set larger viewport and activate it to active tree.
4066 host_impl_
->CreatePendingTree();
4067 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4068 viewport_size_
.height() + 100);
4069 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4070 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4071 host_impl_
->ActivateSyncTree();
4072 EXPECT_TRUE(did_activate_pending_tree_
);
4073 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4075 // Shrink pending tree viewport without activating.
4076 host_impl_
->CreatePendingTree();
4077 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4078 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4080 SetupActiveTreeLayers();
4082 TestLayerInMiddleOfViewport();
4083 TestLayerIsLargerThanViewport();
4086 class FakeDrawableLayerImpl
: public LayerImpl
{
4088 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4089 return scoped_ptr
<LayerImpl
>(new FakeDrawableLayerImpl(tree_impl
, id
));
4092 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4093 : LayerImpl(tree_impl
, id
) {}
4096 // Only reshape when we know we are going to draw. Otherwise, the reshape
4097 // can leave the window at the wrong size if we never draw and the proper
4098 // viewport size is never set.
4099 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4100 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4101 scoped_ptr
<OutputSurface
> output_surface(
4102 FakeOutputSurface::Create3d(provider
));
4103 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4105 scoped_ptr
<LayerImpl
> root
=
4106 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4107 root
->SetBounds(gfx::Size(10, 10));
4108 root
->SetContentBounds(gfx::Size(10, 10));
4109 root
->SetDrawsContent(true);
4110 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4111 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4112 provider
->TestContext3d()->clear_reshape_called();
4114 LayerTreeHostImpl::FrameData frame
;
4115 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4116 host_impl_
->SetDeviceScaleFactor(1.f
);
4117 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4118 host_impl_
->DrawLayers(&frame
);
4119 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4120 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4121 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4122 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4123 host_impl_
->DidDrawAllLayers(frame
);
4124 provider
->TestContext3d()->clear_reshape_called();
4126 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4127 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4128 host_impl_
->DrawLayers(&frame
);
4129 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4130 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4131 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4132 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4133 host_impl_
->DidDrawAllLayers(frame
);
4134 provider
->TestContext3d()->clear_reshape_called();
4136 host_impl_
->SetDeviceScaleFactor(2.f
);
4137 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4138 host_impl_
->DrawLayers(&frame
);
4139 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4140 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4141 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4142 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4143 host_impl_
->DidDrawAllLayers(frame
);
4144 provider
->TestContext3d()->clear_reshape_called();
4147 // Make sure damage tracking propagates all the way to the graphics context,
4148 // where it should request to swap only the sub-buffer that is damaged.
4149 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4150 scoped_refptr
<TestContextProvider
> context_provider(
4151 TestContextProvider::Create());
4152 context_provider
->BindToCurrentThread();
4153 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4155 scoped_ptr
<OutputSurface
> output_surface(
4156 FakeOutputSurface::Create3d(context_provider
));
4158 // This test creates its own LayerTreeHostImpl, so
4159 // that we can force partial swap enabled.
4160 LayerTreeSettings settings
;
4161 settings
.partial_swap_enabled
= true;
4162 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4163 new TestSharedBitmapManager());
4164 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4165 LayerTreeHostImpl::Create(settings
,
4168 &stats_instrumentation_
,
4169 shared_bitmap_manager
.get(),
4171 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4172 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4174 scoped_ptr
<LayerImpl
> root
=
4175 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4176 scoped_ptr
<LayerImpl
> child
=
4177 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4178 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4179 child
->SetBounds(gfx::Size(14, 15));
4180 child
->SetContentBounds(gfx::Size(14, 15));
4181 child
->SetDrawsContent(true);
4182 root
->SetBounds(gfx::Size(500, 500));
4183 root
->SetContentBounds(gfx::Size(500, 500));
4184 root
->SetDrawsContent(true);
4185 root
->AddChild(child
.Pass());
4186 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4188 LayerTreeHostImpl::FrameData frame
;
4190 // First frame, the entire screen should get swapped.
4191 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4192 layer_tree_host_impl
->DrawLayers(&frame
);
4193 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4194 layer_tree_host_impl
->SwapBuffers(frame
);
4195 EXPECT_EQ(TestContextSupport::SWAP
,
4196 context_provider
->support()->last_swap_type());
4198 // Second frame, only the damaged area should get swapped. Damage should be
4199 // the union of old and new child rects.
4200 // expected damage rect: gfx::Rect(26, 28);
4201 // expected swap rect: vertically flipped, with origin at bottom left corner.
4202 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4204 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4205 layer_tree_host_impl
->DrawLayers(&frame
);
4206 host_impl_
->DidDrawAllLayers(frame
);
4207 layer_tree_host_impl
->SwapBuffers(frame
);
4209 // Make sure that partial swap is constrained to the viewport dimensions
4210 // expected damage rect: gfx::Rect(500, 500);
4211 // expected swap rect: flipped damage rect, but also clamped to viewport
4212 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP
,
4213 context_provider
->support()->last_swap_type());
4214 gfx::Rect
expected_swap_rect(0, 500-28, 26, 28);
4215 EXPECT_EQ(expected_swap_rect
.ToString(),
4216 context_provider
->support()->
4217 last_partial_swap_rect().ToString());
4219 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4220 // This will damage everything.
4221 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4223 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4224 layer_tree_host_impl
->DrawLayers(&frame
);
4225 host_impl_
->DidDrawAllLayers(frame
);
4226 layer_tree_host_impl
->SwapBuffers(frame
);
4228 EXPECT_EQ(TestContextSupport::SWAP
,
4229 context_provider
->support()->last_swap_type());
4232 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4233 scoped_ptr
<LayerImpl
> root
=
4234 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4235 scoped_ptr
<LayerImpl
> child
=
4236 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4237 child
->SetBounds(gfx::Size(10, 10));
4238 child
->SetContentBounds(gfx::Size(10, 10));
4239 child
->SetDrawsContent(true);
4240 root
->SetBounds(gfx::Size(10, 10));
4241 root
->SetContentBounds(gfx::Size(10, 10));
4242 root
->SetDrawsContent(true);
4243 root
->SetForceRenderSurface(true);
4244 root
->AddChild(child
.Pass());
4246 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4248 LayerTreeHostImpl::FrameData frame
;
4250 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4251 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4252 EXPECT_EQ(1u, frame
.render_passes
.size());
4253 host_impl_
->DidDrawAllLayers(frame
);
4256 class FakeLayerWithQuads
: public LayerImpl
{
4258 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4259 return scoped_ptr
<LayerImpl
>(new FakeLayerWithQuads(tree_impl
, id
));
4262 virtual void AppendQuads(RenderPass
* render_pass
,
4263 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
4264 AppendQuadsData
* append_quads_data
) OVERRIDE
{
4265 SharedQuadState
* shared_quad_state
=
4266 render_pass
->CreateAndAppendSharedQuadState();
4267 PopulateSharedQuadState(shared_quad_state
);
4269 SkColor gray
= SkColorSetRGB(100, 100, 100);
4270 gfx::Rect
quad_rect(content_bounds());
4271 gfx::Rect
visible_quad_rect(quad_rect
);
4272 SolidColorDrawQuad
* my_quad
=
4273 render_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
4275 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4279 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4280 : LayerImpl(tree_impl
, id
) {}
4283 class MockContext
: public TestWebGraphicsContext3D
{
4285 MOCK_METHOD1(useProgram
, void(GLuint program
));
4286 MOCK_METHOD5(uniform4f
, void(GLint location
,
4291 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4293 GLboolean transpose
,
4294 const GLfloat
* value
));
4295 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4299 MOCK_METHOD1(enable
, void(GLenum cap
));
4300 MOCK_METHOD1(disable
, void(GLenum cap
));
4301 MOCK_METHOD4(scissor
, void(GLint x
,
4307 class MockContextHarness
{
4309 MockContext
* context_
;
4312 explicit MockContextHarness(MockContext
* context
)
4313 : context_(context
) {
4314 context_
->set_have_post_sub_buffer(true);
4316 // Catch "uninteresting" calls
4317 EXPECT_CALL(*context_
, useProgram(_
))
4320 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4323 // These are not asserted
4324 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4325 .WillRepeatedly(Return());
4327 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4328 .WillRepeatedly(Return());
4330 // Any un-sanctioned calls to enable() are OK
4331 EXPECT_CALL(*context_
, enable(_
))
4332 .WillRepeatedly(Return());
4334 // Any un-sanctioned calls to disable() are OK
4335 EXPECT_CALL(*context_
, disable(_
))
4336 .WillRepeatedly(Return());
4339 void MustDrawSolidQuad() {
4340 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
4342 .RetiresOnSaturation();
4344 EXPECT_CALL(*context_
, useProgram(_
))
4346 .RetiresOnSaturation();
4349 void MustSetScissor(int x
, int y
, int width
, int height
) {
4350 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4351 .WillRepeatedly(Return());
4353 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
4355 .WillRepeatedly(Return());
4358 void MustSetNoScissor() {
4359 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
4360 .WillRepeatedly(Return());
4362 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4365 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
4370 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
4371 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
4372 MockContext
* mock_context
= mock_context_owned
.get();
4374 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4375 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4376 MockContextHarness
harness(mock_context
);
4379 LayerTreeSettings settings
= DefaultSettings();
4380 settings
.partial_swap_enabled
= false;
4381 CreateHostImpl(settings
, output_surface
.Pass());
4382 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4384 // Without partial swap, and no clipping, no scissor is set.
4385 harness
.MustDrawSolidQuad();
4386 harness
.MustSetNoScissor();
4388 LayerTreeHostImpl::FrameData frame
;
4389 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4390 host_impl_
->DrawLayers(&frame
);
4391 host_impl_
->DidDrawAllLayers(frame
);
4393 Mock::VerifyAndClearExpectations(&mock_context
);
4395 // Without partial swap, but a layer does clip its subtree, one scissor is
4397 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
4398 harness
.MustDrawSolidQuad();
4399 harness
.MustSetScissor(0, 0, 10, 10);
4401 LayerTreeHostImpl::FrameData frame
;
4402 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4403 host_impl_
->DrawLayers(&frame
);
4404 host_impl_
->DidDrawAllLayers(frame
);
4406 Mock::VerifyAndClearExpectations(&mock_context
);
4409 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
4410 scoped_ptr
<MockContext
> context_owned(new MockContext
);
4411 MockContext
* mock_context
= context_owned
.get();
4412 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4413 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4414 MockContextHarness
harness(mock_context
);
4416 LayerTreeSettings settings
= DefaultSettings();
4417 settings
.partial_swap_enabled
= true;
4418 CreateHostImpl(settings
, output_surface
.Pass());
4419 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4421 // The first frame is not a partially-swapped one.
4422 harness
.MustSetScissor(0, 0, 10, 10);
4423 harness
.MustDrawSolidQuad();
4425 LayerTreeHostImpl::FrameData frame
;
4426 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4427 host_impl_
->DrawLayers(&frame
);
4428 host_impl_
->DidDrawAllLayers(frame
);
4430 Mock::VerifyAndClearExpectations(&mock_context
);
4432 // Damage a portion of the frame.
4433 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
4434 gfx::Rect(0, 0, 2, 3));
4436 // The second frame will be partially-swapped (the y coordinates are flipped).
4437 harness
.MustSetScissor(0, 7, 2, 3);
4438 harness
.MustDrawSolidQuad();
4440 LayerTreeHostImpl::FrameData frame
;
4441 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4442 host_impl_
->DrawLayers(&frame
);
4443 host_impl_
->DidDrawAllLayers(frame
);
4445 Mock::VerifyAndClearExpectations(&mock_context
);
4448 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
4450 LayerTreeHostImplClient
* client
,
4452 SharedBitmapManager
* manager
,
4453 RenderingStatsInstrumentation
* stats_instrumentation
) {
4454 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4455 scoped_ptr
<OutputSurface
> output_surface(
4456 FakeOutputSurface::Create3d(provider
));
4457 provider
->BindToCurrentThread();
4458 provider
->TestContext3d()->set_have_post_sub_buffer(true);
4460 LayerTreeSettings settings
;
4461 settings
.partial_swap_enabled
= partial_swap
;
4462 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
4463 settings
, client
, proxy
, stats_instrumentation
, manager
, 0);
4464 my_host_impl
->InitializeRenderer(output_surface
.Pass());
4465 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
4468 Layers are created as follows:
4470 +--------------------+
4474 | | +-------------------+
4476 | | +-------------------+
4481 +--------------------+
4483 Layers 1, 2 have render surfaces
4485 scoped_ptr
<LayerImpl
> root
=
4486 LayerImpl::Create(my_host_impl
->active_tree(), 1);
4487 scoped_ptr
<LayerImpl
> child
=
4488 LayerImpl::Create(my_host_impl
->active_tree(), 2);
4489 scoped_ptr
<LayerImpl
> grand_child
=
4490 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
4492 gfx::Rect
root_rect(0, 0, 100, 100);
4493 gfx::Rect
child_rect(10, 10, 50, 50);
4494 gfx::Rect
grand_child_rect(5, 5, 150, 150);
4496 root
->CreateRenderSurface();
4497 root
->SetPosition(root_rect
.origin());
4498 root
->SetBounds(root_rect
.size());
4499 root
->SetContentBounds(root
->bounds());
4500 root
->draw_properties().visible_content_rect
= root_rect
;
4501 root
->SetDrawsContent(false);
4502 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
4504 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
4505 child
->SetOpacity(0.5f
);
4506 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
4507 child
->SetContentBounds(child
->bounds());
4508 child
->draw_properties().visible_content_rect
= child_rect
;
4509 child
->SetDrawsContent(false);
4510 child
->SetForceRenderSurface(true);
4512 grand_child
->SetPosition(grand_child_rect
.origin());
4513 grand_child
->SetBounds(grand_child_rect
.size());
4514 grand_child
->SetContentBounds(grand_child
->bounds());
4515 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
4516 grand_child
->SetDrawsContent(true);
4518 child
->AddChild(grand_child
.Pass());
4519 root
->AddChild(child
.Pass());
4521 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4522 return my_host_impl
.Pass();
4525 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
4526 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4527 new TestSharedBitmapManager());
4528 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4529 SetupLayersForOpacity(true,
4532 shared_bitmap_manager
.get(),
4533 &stats_instrumentation_
);
4535 LayerTreeHostImpl::FrameData frame
;
4536 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4538 // Verify all quads have been computed
4539 ASSERT_EQ(2U, frame
.render_passes
.size());
4540 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4541 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4542 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4543 frame
.render_passes
[0]->quad_list
[0]->material
);
4544 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4545 frame
.render_passes
[1]->quad_list
[0]->material
);
4547 my_host_impl
->DrawLayers(&frame
);
4548 my_host_impl
->DidDrawAllLayers(frame
);
4552 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
4553 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4554 new TestSharedBitmapManager());
4555 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4556 SetupLayersForOpacity(false,
4559 shared_bitmap_manager
.get(),
4560 &stats_instrumentation_
);
4562 LayerTreeHostImpl::FrameData frame
;
4563 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4565 // Verify all quads have been computed
4566 ASSERT_EQ(2U, frame
.render_passes
.size());
4567 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4568 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4569 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4570 frame
.render_passes
[0]->quad_list
[0]->material
);
4571 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4572 frame
.render_passes
[1]->quad_list
[0]->material
);
4574 my_host_impl
->DrawLayers(&frame
);
4575 my_host_impl
->DidDrawAllLayers(frame
);
4579 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
4580 scoped_ptr
<TestWebGraphicsContext3D
> context
=
4581 TestWebGraphicsContext3D::Create();
4582 TestWebGraphicsContext3D
* context3d
= context
.get();
4583 scoped_ptr
<OutputSurface
> output_surface(
4584 FakeOutputSurface::Create3d(context
.Pass()));
4585 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4587 scoped_ptr
<LayerImpl
> root_layer
=
4588 LayerImpl::Create(host_impl_
->active_tree(), 1);
4589 root_layer
->SetBounds(gfx::Size(10, 10));
4591 scoped_refptr
<VideoFrame
> softwareFrame
=
4592 media::VideoFrame::CreateColorFrame(
4593 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
4594 FakeVideoFrameProvider provider
;
4595 provider
.set_frame(softwareFrame
);
4596 scoped_ptr
<VideoLayerImpl
> video_layer
=
4597 VideoLayerImpl::Create(host_impl_
->active_tree(), 4, &provider
);
4598 video_layer
->SetBounds(gfx::Size(10, 10));
4599 video_layer
->SetContentBounds(gfx::Size(10, 10));
4600 video_layer
->SetDrawsContent(true);
4601 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
4603 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
4604 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
4605 io_surface_layer
->SetBounds(gfx::Size(10, 10));
4606 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
4607 io_surface_layer
->SetDrawsContent(true);
4608 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
4609 root_layer
->AddChild(io_surface_layer
.PassAs
<LayerImpl
>());
4611 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
4613 EXPECT_EQ(0u, context3d
->NumTextures());
4615 LayerTreeHostImpl::FrameData frame
;
4616 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4617 host_impl_
->DrawLayers(&frame
);
4618 host_impl_
->DidDrawAllLayers(frame
);
4619 host_impl_
->SwapBuffers(frame
);
4621 EXPECT_GT(context3d
->NumTextures(), 0u);
4623 // Kill the layer tree.
4624 host_impl_
->active_tree()->SetRootLayer(
4625 LayerImpl::Create(host_impl_
->active_tree(), 100));
4626 // There should be no textures left in use after.
4627 EXPECT_EQ(0u, context3d
->NumTextures());
4630 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
4632 MOCK_METHOD1(useProgram
, void(GLuint program
));
4633 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4639 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
4640 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
4641 new MockDrawQuadsToFillScreenContext
);
4642 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
4644 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4645 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4648 LayerTreeSettings settings
= DefaultSettings();
4649 settings
.partial_swap_enabled
= false;
4650 CreateHostImpl(settings
, output_surface
.Pass());
4651 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
4652 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
4654 // Verify one quad is drawn when transparent background set is not set.
4655 host_impl_
->active_tree()->set_has_transparent_background(false);
4656 EXPECT_CALL(*mock_context
, useProgram(_
))
4658 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
4660 LayerTreeHostImpl::FrameData frame
;
4661 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4662 host_impl_
->DrawLayers(&frame
);
4663 host_impl_
->DidDrawAllLayers(frame
);
4664 Mock::VerifyAndClearExpectations(&mock_context
);
4666 // Verify no quads are drawn when transparent background is set.
4667 host_impl_
->active_tree()->set_has_transparent_background(true);
4668 host_impl_
->SetFullRootLayerDamage();
4669 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4670 host_impl_
->DrawLayers(&frame
);
4671 host_impl_
->DidDrawAllLayers(frame
);
4672 Mock::VerifyAndClearExpectations(&mock_context
);
4675 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
4676 set_reduce_memory_result(false);
4678 // If changing the memory limit wouldn't result in changing what was
4679 // committed, then no commit should be requested.
4680 set_reduce_memory_result(false);
4681 host_impl_
->set_max_memory_needed_bytes(
4682 host_impl_
->memory_allocation_limit_bytes() - 1);
4683 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4684 host_impl_
->memory_allocation_limit_bytes() - 1));
4685 EXPECT_FALSE(did_request_commit_
);
4686 did_request_commit_
= false;
4688 // If changing the memory limit would result in changing what was
4689 // committed, then a commit should be requested, even though nothing was
4691 set_reduce_memory_result(false);
4692 host_impl_
->set_max_memory_needed_bytes(
4693 host_impl_
->memory_allocation_limit_bytes());
4694 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4695 host_impl_
->memory_allocation_limit_bytes() - 1));
4696 EXPECT_TRUE(did_request_commit_
);
4697 did_request_commit_
= false;
4699 // Especially if changing the memory limit caused evictions, we need
4701 set_reduce_memory_result(true);
4702 host_impl_
->set_max_memory_needed_bytes(1);
4703 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4704 host_impl_
->memory_allocation_limit_bytes() - 1));
4705 EXPECT_TRUE(did_request_commit_
);
4706 did_request_commit_
= false;
4708 // But if we set it to the same value that it was before, we shouldn't
4710 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4711 host_impl_
->memory_allocation_limit_bytes()));
4712 EXPECT_FALSE(did_request_commit_
);
4715 class LayerTreeHostImplTestWithDelegatingRenderer
4716 : public LayerTreeHostImplTest
{
4718 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
4719 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
4722 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
4723 bool expect_to_draw
= !expected_damage
.IsEmpty();
4725 LayerTreeHostImpl::FrameData frame
;
4726 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4728 if (!expect_to_draw
) {
4729 // With no damage, we don't draw, and no quads are created.
4730 ASSERT_EQ(0u, frame
.render_passes
.size());
4732 ASSERT_EQ(1u, frame
.render_passes
.size());
4734 // Verify the damage rect for the root render pass.
4735 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
4736 EXPECT_RECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
4738 // Verify the root and child layers' quads are generated and not being
4740 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
4742 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
4743 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
4744 EXPECT_RECT_EQ(expected_child_visible_rect
,
4745 root_render_pass
->quad_list
[0]->visible_rect
);
4747 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4748 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
4749 EXPECT_RECT_EQ(expected_root_visible_rect
,
4750 root_render_pass
->quad_list
[1]->visible_rect
);
4753 host_impl_
->DrawLayers(&frame
);
4754 host_impl_
->DidDrawAllLayers(frame
);
4755 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
4759 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
4760 scoped_ptr
<SolidColorLayerImpl
> root
=
4761 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
4762 root
->SetPosition(gfx::PointF());
4763 root
->SetBounds(gfx::Size(10, 10));
4764 root
->SetContentBounds(gfx::Size(10, 10));
4765 root
->SetDrawsContent(true);
4767 // Child layer is in the bottom right corner.
4768 scoped_ptr
<SolidColorLayerImpl
> child
=
4769 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
4770 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
4771 child
->SetBounds(gfx::Size(1, 1));
4772 child
->SetContentBounds(gfx::Size(1, 1));
4773 child
->SetDrawsContent(true);
4774 root
->AddChild(child
.PassAs
<LayerImpl
>());
4776 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
4778 // Draw a frame. In the first frame, the entire viewport should be damaged.
4779 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
4780 DrawFrameAndTestDamage(full_frame_damage
);
4782 // The second frame has damage that doesn't touch the child layer. Its quads
4783 // should still be generated.
4784 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
4785 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
4786 DrawFrameAndTestDamage(small_damage
);
4788 // The third frame should have no damage, so no quads should be generated.
4789 gfx::Rect no_damage
;
4790 DrawFrameAndTestDamage(no_damage
);
4793 // TODO(reveman): Remove this test and the ability to prevent on demand raster
4794 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
4795 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
4796 LayerTreeSettings settings
;
4797 CreateHostImpl(settings
, CreateOutputSurface());
4798 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
4801 class FakeMaskLayerImpl
: public LayerImpl
{
4803 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4805 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
4808 virtual ResourceProvider::ResourceId
ContentsResourceId() const OVERRIDE
{
4813 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4814 : LayerImpl(tree_impl
, id
) {}
4817 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
4818 LayerTreeSettings settings
;
4819 settings
.layer_transforms_should_scale_layer_contents
= true;
4820 CreateHostImpl(settings
, CreateOutputSurface());
4824 // +-- Scaling Layer (adds a 2x scale)
4826 // +-- Content Layer
4828 scoped_ptr
<LayerImpl
> scoped_root
=
4829 LayerImpl::Create(host_impl_
->active_tree(), 1);
4830 LayerImpl
* root
= scoped_root
.get();
4831 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4833 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
4834 LayerImpl::Create(host_impl_
->active_tree(), 2);
4835 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
4836 root
->AddChild(scoped_scaling_layer
.Pass());
4838 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4839 LayerImpl::Create(host_impl_
->active_tree(), 3);
4840 LayerImpl
* content_layer
= scoped_content_layer
.get();
4841 scaling_layer
->AddChild(scoped_content_layer
.Pass());
4843 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4844 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4845 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4846 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4848 gfx::Size
root_size(100, 100);
4849 root
->SetBounds(root_size
);
4850 root
->SetContentBounds(root_size
);
4851 root
->SetPosition(gfx::PointF());
4853 gfx::Size
scaling_layer_size(50, 50);
4854 scaling_layer
->SetBounds(scaling_layer_size
);
4855 scaling_layer
->SetContentBounds(scaling_layer_size
);
4856 scaling_layer
->SetPosition(gfx::PointF());
4857 gfx::Transform scale
;
4858 scale
.Scale(2.f
, 2.f
);
4859 scaling_layer
->SetTransform(scale
);
4861 content_layer
->SetBounds(scaling_layer_size
);
4862 content_layer
->SetContentBounds(scaling_layer_size
);
4863 content_layer
->SetPosition(gfx::PointF());
4864 content_layer
->SetDrawsContent(true);
4866 mask_layer
->SetBounds(scaling_layer_size
);
4867 mask_layer
->SetContentBounds(scaling_layer_size
);
4868 mask_layer
->SetPosition(gfx::PointF());
4869 mask_layer
->SetDrawsContent(true);
4872 // Check that the tree scaling is correctly taken into account for the mask,
4873 // that should fully map onto the quad.
4874 float device_scale_factor
= 1.f
;
4875 host_impl_
->SetViewportSize(root_size
);
4876 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4878 LayerTreeHostImpl::FrameData frame
;
4879 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4881 ASSERT_EQ(1u, frame
.render_passes
.size());
4882 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4883 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4884 frame
.render_passes
[0]->quad_list
[0]->material
);
4885 const RenderPassDrawQuad
* render_pass_quad
=
4886 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4887 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4888 render_pass_quad
->rect
.ToString());
4889 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4890 render_pass_quad
->mask_uv_rect
.ToString());
4892 host_impl_
->DrawLayers(&frame
);
4893 host_impl_
->DidDrawAllLayers(frame
);
4897 // Applying a DSF should change the render surface size, but won't affect
4898 // which part of the mask is used.
4899 device_scale_factor
= 2.f
;
4900 gfx::Size device_viewport
=
4901 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4902 host_impl_
->SetViewportSize(device_viewport
);
4903 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4904 host_impl_
->active_tree()->set_needs_update_draw_properties();
4906 LayerTreeHostImpl::FrameData frame
;
4907 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4909 ASSERT_EQ(1u, frame
.render_passes
.size());
4910 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4911 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4912 frame
.render_passes
[0]->quad_list
[0]->material
);
4913 const RenderPassDrawQuad
* render_pass_quad
=
4914 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4915 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4916 render_pass_quad
->rect
.ToString());
4917 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4918 render_pass_quad
->mask_uv_rect
.ToString());
4920 host_impl_
->DrawLayers(&frame
);
4921 host_impl_
->DidDrawAllLayers(frame
);
4925 // Applying an equivalent content scale on the content layer and the mask
4926 // should still result in the same part of the mask being used.
4927 gfx::Size content_bounds
=
4928 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
4929 device_scale_factor
));
4930 content_layer
->SetContentBounds(content_bounds
);
4931 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4932 mask_layer
->SetContentBounds(content_bounds
);
4933 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4934 host_impl_
->active_tree()->set_needs_update_draw_properties();
4936 LayerTreeHostImpl::FrameData frame
;
4937 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4939 ASSERT_EQ(1u, frame
.render_passes
.size());
4940 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4941 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4942 frame
.render_passes
[0]->quad_list
[0]->material
);
4943 const RenderPassDrawQuad
* render_pass_quad
=
4944 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4945 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4946 render_pass_quad
->rect
.ToString());
4947 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4948 render_pass_quad
->mask_uv_rect
.ToString());
4950 host_impl_
->DrawLayers(&frame
);
4951 host_impl_
->DidDrawAllLayers(frame
);
4955 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
4956 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4959 scoped_ptr
<LayerImpl
> scoped_root
=
4960 LayerImpl::Create(host_impl_
->active_tree(), 1);
4961 LayerImpl
* root
= scoped_root
.get();
4962 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4964 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4965 LayerImpl::Create(host_impl_
->active_tree(), 3);
4966 LayerImpl
* content_layer
= scoped_content_layer
.get();
4967 root
->AddChild(scoped_content_layer
.Pass());
4969 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4970 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4971 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4972 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4974 gfx::Size
root_size(100, 100);
4975 root
->SetBounds(root_size
);
4976 root
->SetContentBounds(root_size
);
4977 root
->SetPosition(gfx::PointF());
4979 gfx::Size
layer_size(50, 50);
4980 content_layer
->SetBounds(layer_size
);
4981 content_layer
->SetContentBounds(layer_size
);
4982 content_layer
->SetPosition(gfx::PointF());
4983 content_layer
->SetDrawsContent(true);
4985 gfx::Size
mask_size(100, 100);
4986 mask_layer
->SetBounds(mask_size
);
4987 mask_layer
->SetContentBounds(mask_size
);
4988 mask_layer
->SetPosition(gfx::PointF());
4989 mask_layer
->SetDrawsContent(true);
4991 // Check that the mask fills the surface.
4992 float device_scale_factor
= 1.f
;
4993 host_impl_
->SetViewportSize(root_size
);
4994 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4996 LayerTreeHostImpl::FrameData frame
;
4997 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4999 ASSERT_EQ(1u, frame
.render_passes
.size());
5000 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5001 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5002 frame
.render_passes
[0]->quad_list
[0]->material
);
5003 const RenderPassDrawQuad
* render_pass_quad
=
5004 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5005 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5006 render_pass_quad
->rect
.ToString());
5007 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5008 render_pass_quad
->mask_uv_rect
.ToString());
5010 host_impl_
->DrawLayers(&frame
);
5011 host_impl_
->DidDrawAllLayers(frame
);
5014 // Applying a DSF should change the render surface size, but won't affect
5015 // which part of the mask is used.
5016 device_scale_factor
= 2.f
;
5017 gfx::Size device_viewport
=
5018 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5019 host_impl_
->SetViewportSize(device_viewport
);
5020 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5021 host_impl_
->active_tree()->set_needs_update_draw_properties();
5023 LayerTreeHostImpl::FrameData frame
;
5024 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5026 ASSERT_EQ(1u, frame
.render_passes
.size());
5027 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5028 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5029 frame
.render_passes
[0]->quad_list
[0]->material
);
5030 const RenderPassDrawQuad
* render_pass_quad
=
5031 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5032 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5033 render_pass_quad
->rect
.ToString());
5034 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5035 render_pass_quad
->mask_uv_rect
.ToString());
5037 host_impl_
->DrawLayers(&frame
);
5038 host_impl_
->DidDrawAllLayers(frame
);
5041 // Applying an equivalent content scale on the content layer and the mask
5042 // should still result in the same part of the mask being used.
5043 gfx::Size layer_size_large
=
5044 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5045 content_layer
->SetContentBounds(layer_size_large
);
5046 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5047 gfx::Size mask_size_large
=
5048 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5049 mask_layer
->SetContentBounds(mask_size_large
);
5050 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5051 host_impl_
->active_tree()->set_needs_update_draw_properties();
5053 LayerTreeHostImpl::FrameData frame
;
5054 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5056 ASSERT_EQ(1u, frame
.render_passes
.size());
5057 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5058 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5059 frame
.render_passes
[0]->quad_list
[0]->material
);
5060 const RenderPassDrawQuad
* render_pass_quad
=
5061 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5062 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5063 render_pass_quad
->rect
.ToString());
5064 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5065 render_pass_quad
->mask_uv_rect
.ToString());
5067 host_impl_
->DrawLayers(&frame
);
5068 host_impl_
->DidDrawAllLayers(frame
);
5071 // Applying a different contents scale to the mask layer means it will have
5072 // a larger texture, but it should use the same tex coords to cover the
5074 mask_layer
->SetContentBounds(mask_size
);
5075 mask_layer
->SetContentsScale(1.f
, 1.f
);
5076 host_impl_
->active_tree()->set_needs_update_draw_properties();
5078 LayerTreeHostImpl::FrameData frame
;
5079 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5081 ASSERT_EQ(1u, frame
.render_passes
.size());
5082 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5083 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5084 frame
.render_passes
[0]->quad_list
[0]->material
);
5085 const RenderPassDrawQuad
* render_pass_quad
=
5086 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5087 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5088 render_pass_quad
->rect
.ToString());
5089 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5090 render_pass_quad
->mask_uv_rect
.ToString());
5092 host_impl_
->DrawLayers(&frame
);
5093 host_impl_
->DidDrawAllLayers(frame
);
5097 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5098 // The replica's mask layer has bounds 100x100 but the replica is of a
5099 // layer with bounds 50x50.
5101 scoped_ptr
<LayerImpl
> scoped_root
=
5102 LayerImpl::Create(host_impl_
->active_tree(), 1);
5103 LayerImpl
* root
= scoped_root
.get();
5104 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5106 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5107 LayerImpl::Create(host_impl_
->active_tree(), 3);
5108 LayerImpl
* content_layer
= scoped_content_layer
.get();
5109 root
->AddChild(scoped_content_layer
.Pass());
5111 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5112 LayerImpl::Create(host_impl_
->active_tree(), 2);
5113 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5114 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5116 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5117 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5118 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5119 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5121 gfx::Size
root_size(100, 100);
5122 root
->SetBounds(root_size
);
5123 root
->SetContentBounds(root_size
);
5124 root
->SetPosition(gfx::PointF());
5126 gfx::Size
layer_size(50, 50);
5127 content_layer
->SetBounds(layer_size
);
5128 content_layer
->SetContentBounds(layer_size
);
5129 content_layer
->SetPosition(gfx::PointF());
5130 content_layer
->SetDrawsContent(true);
5132 gfx::Size
mask_size(100, 100);
5133 mask_layer
->SetBounds(mask_size
);
5134 mask_layer
->SetContentBounds(mask_size
);
5135 mask_layer
->SetPosition(gfx::PointF());
5136 mask_layer
->SetDrawsContent(true);
5138 // Check that the mask fills the surface.
5139 float device_scale_factor
= 1.f
;
5140 host_impl_
->SetViewportSize(root_size
);
5141 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5143 LayerTreeHostImpl::FrameData frame
;
5144 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5146 ASSERT_EQ(1u, frame
.render_passes
.size());
5147 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5148 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5149 frame
.render_passes
[0]->quad_list
[1]->material
);
5150 const RenderPassDrawQuad
* replica_quad
=
5151 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5152 EXPECT_TRUE(replica_quad
->is_replica
);
5153 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5154 replica_quad
->rect
.ToString());
5155 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5156 replica_quad
->mask_uv_rect
.ToString());
5158 host_impl_
->DrawLayers(&frame
);
5159 host_impl_
->DidDrawAllLayers(frame
);
5162 // Applying a DSF should change the render surface size, but won't affect
5163 // which part of the mask is used.
5164 device_scale_factor
= 2.f
;
5165 gfx::Size device_viewport
=
5166 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5167 host_impl_
->SetViewportSize(device_viewport
);
5168 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5169 host_impl_
->active_tree()->set_needs_update_draw_properties();
5171 LayerTreeHostImpl::FrameData frame
;
5172 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5174 ASSERT_EQ(1u, frame
.render_passes
.size());
5175 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5176 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5177 frame
.render_passes
[0]->quad_list
[1]->material
);
5178 const RenderPassDrawQuad
* replica_quad
=
5179 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5180 EXPECT_TRUE(replica_quad
->is_replica
);
5181 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5182 replica_quad
->rect
.ToString());
5183 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5184 replica_quad
->mask_uv_rect
.ToString());
5186 host_impl_
->DrawLayers(&frame
);
5187 host_impl_
->DidDrawAllLayers(frame
);
5190 // Applying an equivalent content scale on the content layer and the mask
5191 // should still result in the same part of the mask being used.
5192 gfx::Size layer_size_large
=
5193 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5194 content_layer
->SetContentBounds(layer_size_large
);
5195 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5196 gfx::Size mask_size_large
=
5197 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5198 mask_layer
->SetContentBounds(mask_size_large
);
5199 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5200 host_impl_
->active_tree()->set_needs_update_draw_properties();
5202 LayerTreeHostImpl::FrameData frame
;
5203 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5205 ASSERT_EQ(1u, frame
.render_passes
.size());
5206 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5207 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5208 frame
.render_passes
[0]->quad_list
[1]->material
);
5209 const RenderPassDrawQuad
* replica_quad
=
5210 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5211 EXPECT_TRUE(replica_quad
->is_replica
);
5212 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5213 replica_quad
->rect
.ToString());
5214 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5215 replica_quad
->mask_uv_rect
.ToString());
5217 host_impl_
->DrawLayers(&frame
);
5218 host_impl_
->DidDrawAllLayers(frame
);
5221 // Applying a different contents scale to the mask layer means it will have
5222 // a larger texture, but it should use the same tex coords to cover the
5224 mask_layer
->SetContentBounds(mask_size
);
5225 mask_layer
->SetContentsScale(1.f
, 1.f
);
5226 host_impl_
->active_tree()->set_needs_update_draw_properties();
5228 LayerTreeHostImpl::FrameData frame
;
5229 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5231 ASSERT_EQ(1u, frame
.render_passes
.size());
5232 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5233 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5234 frame
.render_passes
[0]->quad_list
[1]->material
);
5235 const RenderPassDrawQuad
* replica_quad
=
5236 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5237 EXPECT_TRUE(replica_quad
->is_replica
);
5238 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5239 replica_quad
->rect
.ToString());
5240 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5241 replica_quad
->mask_uv_rect
.ToString());
5243 host_impl_
->DrawLayers(&frame
);
5244 host_impl_
->DidDrawAllLayers(frame
);
5248 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5249 // The replica is of a layer with bounds 50x50, but it has a child that causes
5250 // the surface bounds to be larger.
5252 scoped_ptr
<LayerImpl
> scoped_root
=
5253 LayerImpl::Create(host_impl_
->active_tree(), 1);
5254 LayerImpl
* root
= scoped_root
.get();
5255 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5257 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5258 LayerImpl::Create(host_impl_
->active_tree(), 2);
5259 LayerImpl
* content_layer
= scoped_content_layer
.get();
5260 root
->AddChild(scoped_content_layer
.Pass());
5262 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5263 LayerImpl::Create(host_impl_
->active_tree(), 3);
5264 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5265 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5267 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5268 LayerImpl::Create(host_impl_
->active_tree(), 4);
5269 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5270 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5272 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5273 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5274 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5275 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5277 gfx::Size
root_size(100, 100);
5278 root
->SetBounds(root_size
);
5279 root
->SetContentBounds(root_size
);
5280 root
->SetPosition(gfx::PointF());
5282 gfx::Size
layer_size(50, 50);
5283 content_layer
->SetBounds(layer_size
);
5284 content_layer
->SetContentBounds(layer_size
);
5285 content_layer
->SetPosition(gfx::PointF());
5286 content_layer
->SetDrawsContent(true);
5288 gfx::Size
child_size(50, 50);
5289 content_child_layer
->SetBounds(child_size
);
5290 content_child_layer
->SetContentBounds(child_size
);
5291 content_child_layer
->SetPosition(gfx::Point(50, 0));
5292 content_child_layer
->SetDrawsContent(true);
5294 gfx::Size
mask_size(50, 50);
5295 mask_layer
->SetBounds(mask_size
);
5296 mask_layer
->SetContentBounds(mask_size
);
5297 mask_layer
->SetPosition(gfx::PointF());
5298 mask_layer
->SetDrawsContent(true);
5300 float device_scale_factor
= 1.f
;
5301 host_impl_
->SetViewportSize(root_size
);
5302 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5304 LayerTreeHostImpl::FrameData frame
;
5305 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5307 ASSERT_EQ(1u, frame
.render_passes
.size());
5308 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5310 // The surface is 100x50.
5311 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5312 frame
.render_passes
[0]->quad_list
[0]->material
);
5313 const RenderPassDrawQuad
* render_pass_quad
=
5314 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5315 EXPECT_FALSE(render_pass_quad
->is_replica
);
5316 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5317 render_pass_quad
->rect
.ToString());
5319 // The mask covers the owning layer only.
5320 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5321 frame
.render_passes
[0]->quad_list
[1]->material
);
5322 const RenderPassDrawQuad
* replica_quad
=
5323 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5324 EXPECT_TRUE(replica_quad
->is_replica
);
5325 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5326 replica_quad
->rect
.ToString());
5327 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
5328 replica_quad
->mask_uv_rect
.ToString());
5330 host_impl_
->DrawLayers(&frame
);
5331 host_impl_
->DidDrawAllLayers(frame
);
5334 // Move the child to (-50, 0) instead. Now the mask should be moved to still
5335 // cover the layer being replicated.
5336 content_child_layer
->SetPosition(gfx::Point(-50, 0));
5338 LayerTreeHostImpl::FrameData frame
;
5339 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5341 ASSERT_EQ(1u, frame
.render_passes
.size());
5342 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5344 // The surface is 100x50 with its origin at (-50, 0).
5345 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5346 frame
.render_passes
[0]->quad_list
[0]->material
);
5347 const RenderPassDrawQuad
* render_pass_quad
=
5348 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5349 EXPECT_FALSE(render_pass_quad
->is_replica
);
5350 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5351 render_pass_quad
->rect
.ToString());
5353 // The mask covers the owning layer only.
5354 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5355 frame
.render_passes
[0]->quad_list
[1]->material
);
5356 const RenderPassDrawQuad
* replica_quad
=
5357 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5358 EXPECT_TRUE(replica_quad
->is_replica
);
5359 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5360 replica_quad
->rect
.ToString());
5361 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
5362 replica_quad
->mask_uv_rect
.ToString());
5364 host_impl_
->DrawLayers(&frame
);
5365 host_impl_
->DidDrawAllLayers(frame
);
5369 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
5370 // The masked layer has bounds 50x50, but it has a child that causes
5371 // the surface bounds to be larger. It also has a parent that clips the
5372 // masked layer and its surface.
5374 scoped_ptr
<LayerImpl
> scoped_root
=
5375 LayerImpl::Create(host_impl_
->active_tree(), 1);
5376 LayerImpl
* root
= scoped_root
.get();
5377 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5379 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
5380 LayerImpl::Create(host_impl_
->active_tree(), 2);
5381 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
5382 root
->AddChild(scoped_clipping_layer
.Pass());
5384 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5385 LayerImpl::Create(host_impl_
->active_tree(), 3);
5386 LayerImpl
* content_layer
= scoped_content_layer
.get();
5387 clipping_layer
->AddChild(scoped_content_layer
.Pass());
5389 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5390 LayerImpl::Create(host_impl_
->active_tree(), 4);
5391 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5392 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5394 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5395 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
5396 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5397 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5399 gfx::Size
root_size(100, 100);
5400 root
->SetBounds(root_size
);
5401 root
->SetContentBounds(root_size
);
5402 root
->SetPosition(gfx::PointF());
5404 gfx::Rect
clipping_rect(20, 10, 10, 20);
5405 clipping_layer
->SetBounds(clipping_rect
.size());
5406 clipping_layer
->SetContentBounds(clipping_rect
.size());
5407 clipping_layer
->SetPosition(clipping_rect
.origin());
5408 clipping_layer
->SetMasksToBounds(true);
5410 gfx::Size
layer_size(50, 50);
5411 content_layer
->SetBounds(layer_size
);
5412 content_layer
->SetContentBounds(layer_size
);
5413 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
5414 content_layer
->SetDrawsContent(true);
5416 gfx::Size
child_size(50, 50);
5417 content_child_layer
->SetBounds(child_size
);
5418 content_child_layer
->SetContentBounds(child_size
);
5419 content_child_layer
->SetPosition(gfx::Point(50, 0));
5420 content_child_layer
->SetDrawsContent(true);
5422 gfx::Size
mask_size(100, 100);
5423 mask_layer
->SetBounds(mask_size
);
5424 mask_layer
->SetContentBounds(mask_size
);
5425 mask_layer
->SetPosition(gfx::PointF());
5426 mask_layer
->SetDrawsContent(true);
5428 float device_scale_factor
= 1.f
;
5429 host_impl_
->SetViewportSize(root_size
);
5430 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5432 LayerTreeHostImpl::FrameData frame
;
5433 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5435 ASSERT_EQ(1u, frame
.render_passes
.size());
5436 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5438 // The surface is clipped to 10x20.
5439 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5440 frame
.render_passes
[0]->quad_list
[0]->material
);
5441 const RenderPassDrawQuad
* render_pass_quad
=
5442 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5443 EXPECT_FALSE(render_pass_quad
->is_replica
);
5444 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5445 render_pass_quad
->rect
.ToString());
5447 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5448 // coords in the mask are scaled by 10/50 and 20/50.
5449 // The surface is clipped to (20,10) so the mask texture coords are offset
5450 // by 20/50 and 10/50
5451 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
),
5452 1.f
/ 50.f
).ToString(),
5453 render_pass_quad
->mask_uv_rect
.ToString());
5455 host_impl_
->DrawLayers(&frame
);
5456 host_impl_
->DidDrawAllLayers(frame
);
5460 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
5462 using GLRenderer::SetupQuadForAntialiasing
;
5465 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
5466 // Due to precision issues (especially on Android), sometimes far
5467 // away quads can end up thinking they need AA.
5468 float device_scale_factor
= 4.f
/ 3.f
;
5469 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5470 gfx::Size
root_size(2000, 1000);
5471 gfx::Size device_viewport_size
=
5472 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5473 host_impl_
->SetViewportSize(device_viewport_size
);
5475 host_impl_
->CreatePendingTree();
5476 host_impl_
->pending_tree()
5477 ->SetPageScaleFactorAndLimits(1.f
, 1.f
/ 16.f
, 16.f
);
5479 scoped_ptr
<LayerImpl
> scoped_root
=
5480 LayerImpl::Create(host_impl_
->pending_tree(), 1);
5481 LayerImpl
* root
= scoped_root
.get();
5483 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
5485 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
5486 LayerImpl::Create(host_impl_
->pending_tree(), 2);
5487 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
5488 root
->AddChild(scoped_scrolling_layer
.Pass());
5490 gfx::Size
content_layer_bounds(100000, 100);
5491 gfx::Size
pile_tile_size(3000, 3000);
5492 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
5493 pile_tile_size
, content_layer_bounds
));
5495 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
5496 FakePictureLayerImpl::CreateWithPile(host_impl_
->pending_tree(), 3, pile
);
5497 LayerImpl
* content_layer
= scoped_content_layer
.get();
5498 scrolling_layer
->AddChild(scoped_content_layer
.PassAs
<LayerImpl
>());
5499 content_layer
->SetBounds(content_layer_bounds
);
5500 content_layer
->SetDrawsContent(true);
5502 root
->SetBounds(root_size
);
5504 gfx::Vector2d
scroll_offset(100000, 0);
5505 scrolling_layer
->SetScrollClipLayer(root
->id());
5506 scrolling_layer
->SetScrollOffset(scroll_offset
);
5508 host_impl_
->ActivateSyncTree();
5510 host_impl_
->active_tree()->UpdateDrawProperties();
5511 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
5513 LayerTreeHostImpl::FrameData frame
;
5514 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5516 ASSERT_EQ(1u, frame
.render_passes
.size());
5517 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
5518 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
[0];
5521 gfx::QuadF device_layer_quad
;
5523 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
5524 quad
->quadTransform(), quad
, &device_layer_quad
, edge
);
5525 EXPECT_FALSE(antialiased
);
5527 host_impl_
->DrawLayers(&frame
);
5528 host_impl_
->DidDrawAllLayers(frame
);
5532 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
5534 CompositorFrameMetadataTest()
5535 : swap_buffers_complete_(0) {}
5537 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{
5538 swap_buffers_complete_
++;
5541 int swap_buffers_complete_
;
5544 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
5545 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5547 LayerTreeHostImpl::FrameData frame
;
5548 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5549 host_impl_
->DrawLayers(&frame
);
5550 host_impl_
->DidDrawAllLayers(frame
);
5552 CompositorFrameAck ack
;
5553 host_impl_
->ReclaimResources(&ack
);
5554 host_impl_
->DidSwapBuffersComplete();
5555 EXPECT_EQ(swap_buffers_complete_
, 1);
5558 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
5560 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
5562 virtual SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) OVERRIDE
{
5564 return SoftwareOutputDevice::BeginPaint(damage_rect
);
5566 virtual void EndPaint(SoftwareFrameData
* frame_data
) OVERRIDE
{
5568 SoftwareOutputDevice::EndPaint(frame_data
);
5571 int frames_began_
, frames_ended_
;
5574 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
5575 // No main thread evictions in resourceless software mode.
5576 set_reduce_memory_result(false);
5577 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
5578 bool delegated_rendering
= false;
5579 FakeOutputSurface
* output_surface
=
5580 FakeOutputSurface::CreateDeferredGL(
5581 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
5582 delegated_rendering
).release();
5583 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5584 scoped_ptr
<OutputSurface
>(output_surface
)));
5585 host_impl_
->SetViewportSize(gfx::Size(50, 50));
5587 SetupScrollAndContentsLayers(gfx::Size(100, 100));
5589 const gfx::Transform external_transform
;
5590 const gfx::Rect external_viewport
;
5591 const gfx::Rect external_clip
;
5592 const bool resourceless_software_draw
= true;
5593 host_impl_
->SetExternalDrawConstraints(external_transform
,
5596 resourceless_software_draw
);
5598 EXPECT_EQ(0, software_device
->frames_began_
);
5599 EXPECT_EQ(0, software_device
->frames_ended_
);
5603 EXPECT_EQ(1, software_device
->frames_began_
);
5604 EXPECT_EQ(1, software_device
->frames_ended_
);
5606 // Call other API methods that are likely to hit NULL pointer in this mode.
5607 EXPECT_TRUE(host_impl_
->AsValue());
5608 EXPECT_TRUE(host_impl_
->ActivationStateAsValue());
5611 TEST_F(LayerTreeHostImplTest
,
5612 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
5613 set_reduce_memory_result(false);
5614 bool delegated_rendering
= false;
5615 FakeOutputSurface
* output_surface
=
5616 FakeOutputSurface::CreateDeferredGL(
5617 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5618 delegated_rendering
).release();
5619 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5620 scoped_ptr
<OutputSurface
>(output_surface
)));
5622 const gfx::Transform external_transform
;
5623 const gfx::Rect external_viewport
;
5624 const gfx::Rect external_clip
;
5625 const bool resourceless_software_draw
= true;
5626 host_impl_
->SetExternalDrawConstraints(external_transform
,
5629 resourceless_software_draw
);
5631 // SolidColorLayerImpl will be drawn.
5632 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5633 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5635 // VideoLayerImpl will not be drawn.
5636 FakeVideoFrameProvider provider
;
5637 scoped_ptr
<VideoLayerImpl
> video_layer
=
5638 VideoLayerImpl::Create(host_impl_
->active_tree(), 2, &provider
);
5639 video_layer
->SetBounds(gfx::Size(10, 10));
5640 video_layer
->SetContentBounds(gfx::Size(10, 10));
5641 video_layer
->SetDrawsContent(true);
5642 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
5643 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5645 LayerTreeHostImpl::FrameData frame
;
5646 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5647 host_impl_
->DrawLayers(&frame
);
5648 host_impl_
->DidDrawAllLayers(frame
);
5650 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
5651 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
5654 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
5656 virtual void SetUp() OVERRIDE
{
5657 LayerTreeHostImplTest::SetUp();
5659 set_reduce_memory_result(false);
5661 bool delegated_rendering
= false;
5662 scoped_ptr
<FakeOutputSurface
> output_surface(
5663 FakeOutputSurface::CreateDeferredGL(
5664 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5665 delegated_rendering
));
5666 output_surface_
= output_surface
.get();
5668 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5669 output_surface
.PassAs
<OutputSurface
>()));
5671 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5672 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5673 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5675 onscreen_context_provider_
= TestContextProvider::Create();
5678 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{
5679 did_update_renderer_capabilities_
= true;
5682 FakeOutputSurface
* output_surface_
;
5683 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
5684 bool did_update_renderer_capabilities_
;
5688 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
5692 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5694 // DeferredInitialize and hardware draw.
5695 did_update_renderer_capabilities_
= false;
5697 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5698 EXPECT_EQ(onscreen_context_provider_
,
5699 host_impl_
->output_surface()->context_provider());
5700 EXPECT_TRUE(did_update_renderer_capabilities_
);
5702 // Defer intialized GL draw.
5705 // Revert back to software.
5706 did_update_renderer_capabilities_
= false;
5707 output_surface_
->ReleaseGL();
5708 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5709 EXPECT_TRUE(did_update_renderer_capabilities_
);
5711 // Software draw again.
5715 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
5719 // Fail initialization of the onscreen context before the OutputSurface binds
5720 // it to the thread.
5721 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
5723 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5725 // DeferredInitialize fails.
5726 did_update_renderer_capabilities_
= false;
5728 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5729 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5730 EXPECT_FALSE(did_update_renderer_capabilities_
);
5732 // Software draw again.
5736 // Checks that we have a non-0 default allocation if we pass a context that
5737 // doesn't support memory management extensions.
5738 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
5739 LayerTreeSettings settings
;
5740 host_impl_
= LayerTreeHostImpl::Create(settings
,
5743 &stats_instrumentation_
,
5744 shared_bitmap_manager_
.get(),
5747 scoped_ptr
<OutputSurface
> output_surface(
5748 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
5749 host_impl_
->InitializeRenderer(output_surface
.Pass());
5750 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
5753 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
5754 ManagedMemoryPolicy
policy1(
5755 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
5756 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5757 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
5758 int allow_nice_to_have_cutoff_value
=
5759 ManagedMemoryPolicy::PriorityCutoffToValue(
5760 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
5761 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5762 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
5764 // GPU rasterization should be disabled by default on the tree(s)
5765 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
5766 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
5768 host_impl_
->SetVisible(true);
5769 host_impl_
->SetMemoryPolicy(policy1
);
5770 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5771 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5773 host_impl_
->SetVisible(false);
5774 EXPECT_EQ(0u, current_limit_bytes_
);
5775 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5777 host_impl_
->SetVisible(true);
5778 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5779 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5781 // Now enable GPU rasterization and test if we get nice to have cutoff,
5783 LayerTreeSettings settings
;
5784 settings
.gpu_rasterization_enabled
= true;
5785 host_impl_
= LayerTreeHostImpl::Create(
5786 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, 0);
5787 host_impl_
->SetUseGpuRasterization(true);
5788 host_impl_
->SetVisible(true);
5789 host_impl_
->SetMemoryPolicy(policy1
);
5790 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5791 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
5793 host_impl_
->SetVisible(false);
5794 EXPECT_EQ(0u, current_limit_bytes_
);
5795 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5798 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
5799 ASSERT_TRUE(host_impl_
->active_tree());
5801 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5802 host_impl_
->SetVisible(false);
5803 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5804 host_impl_
->SetVisible(true);
5805 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5806 host_impl_
->SetVisible(false);
5807 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5809 host_impl_
->CreatePendingTree();
5810 host_impl_
->ActivateSyncTree();
5812 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5813 host_impl_
->SetVisible(true);
5814 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5817 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
5818 ASSERT_TRUE(host_impl_
->active_tree());
5819 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
5821 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5822 host_impl_
->SetUseGpuRasterization(false);
5823 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5824 host_impl_
->SetUseGpuRasterization(true);
5825 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5826 host_impl_
->SetUseGpuRasterization(false);
5827 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5829 host_impl_
->CreatePendingTree();
5830 host_impl_
->ActivateSyncTree();
5832 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5833 host_impl_
->SetUseGpuRasterization(true);
5834 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5837 class LayerTreeHostImplTestManageTiles
: public LayerTreeHostImplTest
{
5839 virtual void SetUp() OVERRIDE
{
5840 LayerTreeSettings settings
;
5841 settings
.impl_side_painting
= true;
5843 fake_host_impl_
= new FakeLayerTreeHostImpl(
5844 settings
, &proxy_
, shared_bitmap_manager_
.get());
5845 host_impl_
.reset(fake_host_impl_
);
5846 host_impl_
->InitializeRenderer(CreateOutputSurface());
5847 host_impl_
->SetViewportSize(gfx::Size(10, 10));
5850 FakeLayerTreeHostImpl
* fake_host_impl_
;
5853 TEST_F(LayerTreeHostImplTestManageTiles
, ManageTilesWhenInvisible
) {
5854 fake_host_impl_
->DidModifyTilePriorities();
5855 EXPECT_TRUE(fake_host_impl_
->manage_tiles_needed());
5856 fake_host_impl_
->SetVisible(false);
5857 EXPECT_FALSE(fake_host_impl_
->manage_tiles_needed());
5860 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
5861 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5862 TestWebGraphicsContext3D::Create();
5863 TestWebGraphicsContext3D
* context3d
= context
.get();
5864 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5865 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5867 EXPECT_EQ(0u, context3d
->NumTextures());
5869 UIResourceId ui_resource_id
= 1;
5870 bool is_opaque
= false;
5871 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
5872 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5873 EXPECT_EQ(1u, context3d
->NumTextures());
5874 ResourceProvider::ResourceId id1
=
5875 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5878 // Multiple requests with the same id is allowed. The previous texture is
5880 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5881 EXPECT_EQ(1u, context3d
->NumTextures());
5882 ResourceProvider::ResourceId id2
=
5883 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5885 EXPECT_NE(id1
, id2
);
5887 // Deleting invalid UIResourceId is allowed and does not change state.
5888 host_impl_
->DeleteUIResource(-1);
5889 EXPECT_EQ(1u, context3d
->NumTextures());
5891 // Should return zero for invalid UIResourceId. Number of textures should
5893 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
5894 EXPECT_EQ(1u, context3d
->NumTextures());
5896 host_impl_
->DeleteUIResource(ui_resource_id
);
5897 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
5898 EXPECT_EQ(0u, context3d
->NumTextures());
5900 // Should not change state for multiple deletion on one UIResourceId
5901 host_impl_
->DeleteUIResource(ui_resource_id
);
5902 EXPECT_EQ(0u, context3d
->NumTextures());
5905 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
5906 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5907 TestWebGraphicsContext3D::Create();
5908 TestWebGraphicsContext3D
* context3d
= context
.get();
5909 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5910 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5912 EXPECT_EQ(0u, context3d
->NumTextures());
5914 gfx::Size
size(4, 4);
5915 // SkImageInfo has no support for ETC1. The |info| below contains the right
5916 // total pixel size for the bitmap but not the right height and width. The
5917 // correct width/height are passed directly to UIResourceBitmap.
5919 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
5920 skia::RefPtr
<SkPixelRef
> pixel_ref
=
5921 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
5922 pixel_ref
->setImmutable();
5923 UIResourceBitmap
bitmap(pixel_ref
, size
);
5924 UIResourceId ui_resource_id
= 1;
5925 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5926 EXPECT_EQ(1u, context3d
->NumTextures());
5927 ResourceProvider::ResourceId id1
=
5928 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5932 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
5935 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
5936 scoped_refptr
<TestContextProvider
> context_provider
=
5937 TestContextProvider::Create();
5941 FakeOutputSurface::Create3d(context_provider
).PassAs
<OutputSurface
>());
5943 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5945 ScopedPtrVector
<CopyOutputRequest
> requests
;
5946 requests
.push_back(CopyOutputRequest::CreateRequest(
5947 base::Bind(&ShutdownReleasesContext_Callback
)));
5949 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
5951 LayerTreeHostImpl::FrameData frame
;
5952 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5953 host_impl_
->DrawLayers(&frame
);
5954 host_impl_
->DidDrawAllLayers(frame
);
5956 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5957 // texture in a texture mailbox.
5958 EXPECT_FALSE(context_provider
->HasOneRef());
5959 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
5963 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5964 // released, and the texture deleted.
5965 EXPECT_TRUE(context_provider
->HasOneRef());
5966 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
5969 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
5970 // When flinging via touch, only the child should scroll (we should not
5972 gfx::Size
surface_size(10, 10);
5973 gfx::Size
content_size(20, 20);
5974 scoped_ptr
<LayerImpl
> root_clip
=
5975 LayerImpl::Create(host_impl_
->active_tree(), 3);
5976 scoped_ptr
<LayerImpl
> root
=
5977 CreateScrollableLayer(1, content_size
, root_clip
.get());
5978 root
->SetIsContainerForFixedPositionLayers(true);
5979 scoped_ptr
<LayerImpl
> child
=
5980 CreateScrollableLayer(2, content_size
, root_clip
.get());
5982 root
->AddChild(child
.Pass());
5983 int root_id
= root
->id();
5984 root_clip
->AddChild(root
.Pass());
5986 host_impl_
->SetViewportSize(surface_size
);
5987 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
5988 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
5989 host_impl_
->active_tree()->DidBecomeActive();
5992 EXPECT_EQ(InputHandler::ScrollStarted
,
5993 host_impl_
->ScrollBegin(gfx::Point(),
5994 InputHandler::Gesture
));
5996 EXPECT_EQ(InputHandler::ScrollStarted
,
5997 host_impl_
->FlingScrollBegin());
5999 gfx::Vector2d
scroll_delta(0, 100);
6000 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6001 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6003 host_impl_
->ScrollEnd();
6005 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6006 host_impl_
->ProcessScrollDeltas();
6008 // Only the child should have scrolled.
6009 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6010 ExpectNone(*scroll_info
.get(), root_id
);
6014 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
6015 // Scroll a child layer beyond its maximum scroll range and make sure the
6016 // the scroll doesn't bubble up to the parent layer.
6017 gfx::Size
surface_size(10, 10);
6018 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
6019 scoped_ptr
<LayerImpl
> root_scrolling
=
6020 CreateScrollableLayer(2, surface_size
, root
.get());
6022 scoped_ptr
<LayerImpl
> grand_child
=
6023 CreateScrollableLayer(4, surface_size
, root
.get());
6024 grand_child
->SetScrollOffset(gfx::Vector2d(0, 2));
6026 scoped_ptr
<LayerImpl
> child
=
6027 CreateScrollableLayer(3, surface_size
, root
.get());
6028 child
->SetScrollOffset(gfx::Vector2d(0, 4));
6029 child
->AddChild(grand_child
.Pass());
6031 root_scrolling
->AddChild(child
.Pass());
6032 root
->AddChild(root_scrolling
.Pass());
6033 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6034 host_impl_
->active_tree()->DidBecomeActive();
6035 host_impl_
->SetViewportSize(surface_size
);
6038 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
6040 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
6041 LayerImpl
* grand_child
= child
->children()[0];
6043 gfx::Vector2d
scroll_delta(0, -2);
6044 EXPECT_EQ(InputHandler::ScrollStarted
,
6045 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6046 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6048 // The grand child should have scrolled up to its limit.
6049 scroll_info
= host_impl_
->ProcessScrollDeltas();
6050 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6051 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6052 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6054 // The child should have received the bubbled delta, but the locked
6055 // scrolling layer should remain set as the grand child.
6056 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6057 scroll_info
= host_impl_
->ProcessScrollDeltas();
6058 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6059 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6060 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
6061 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6063 // The first |ScrollBy| after the fling should re-lock the scrolling
6064 // layer to the first layer that scrolled, which is the child.
6065 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6066 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6067 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6069 // The child should have scrolled up to its limit.
6070 scroll_info
= host_impl_
->ProcessScrollDeltas();
6071 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6072 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6073 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
6075 // As the locked layer is at it's limit, no further scrolling can occur.
6076 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6077 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6078 host_impl_
->ScrollEnd();
6082 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
6083 // When flinging via wheel, the root should eventually scroll (we should
6085 gfx::Size
surface_size(10, 10);
6086 gfx::Size
content_size(20, 20);
6087 scoped_ptr
<LayerImpl
> root_clip
=
6088 LayerImpl::Create(host_impl_
->active_tree(), 3);
6089 scoped_ptr
<LayerImpl
> root_scroll
=
6090 CreateScrollableLayer(1, content_size
, root_clip
.get());
6091 int root_scroll_id
= root_scroll
->id();
6092 scoped_ptr
<LayerImpl
> child
=
6093 CreateScrollableLayer(2, content_size
, root_clip
.get());
6095 root_scroll
->AddChild(child
.Pass());
6096 root_clip
->AddChild(root_scroll
.Pass());
6098 host_impl_
->SetViewportSize(surface_size
);
6099 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6100 host_impl_
->active_tree()->DidBecomeActive();
6103 EXPECT_EQ(InputHandler::ScrollStarted
,
6104 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6106 EXPECT_EQ(InputHandler::ScrollStarted
,
6107 host_impl_
->FlingScrollBegin());
6109 gfx::Vector2d
scroll_delta(0, 100);
6110 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6111 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6113 host_impl_
->ScrollEnd();
6115 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6116 host_impl_
->ProcessScrollDeltas();
6118 // The root should have scrolled.
6119 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6120 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6124 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6125 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6126 // we should return ScrollUnknown.
6127 gfx::Size
content_size(100, 100);
6128 SetupScrollAndContentsLayers(content_size
);
6130 int scroll_layer_id
= 2;
6131 LayerImpl
* scroll_layer
=
6132 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6133 scroll_layer
->SetDrawsContent(true);
6135 int page_scale_layer_id
= 5;
6136 LayerImpl
* page_scale_layer
=
6137 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6139 int occluder_layer_id
= 6;
6140 scoped_ptr
<LayerImpl
> occluder_layer
=
6141 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6142 occluder_layer
->SetDrawsContent(true);
6143 occluder_layer
->SetBounds(content_size
);
6144 occluder_layer
->SetContentBounds(content_size
);
6145 occluder_layer
->SetPosition(gfx::PointF());
6147 // The parent of the occluder is *above* the scroller.
6148 page_scale_layer
->AddChild(occluder_layer
.Pass());
6152 EXPECT_EQ(InputHandler::ScrollUnknown
,
6153 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6156 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6157 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6158 // is not the first scroller we encounter when walking up from the layer, we
6159 // should also return ScrollUnknown.
6160 gfx::Size
content_size(100, 100);
6161 SetupScrollAndContentsLayers(content_size
);
6163 int scroll_layer_id
= 2;
6164 LayerImpl
* scroll_layer
=
6165 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6166 scroll_layer
->SetDrawsContent(true);
6168 int occluder_layer_id
= 6;
6169 scoped_ptr
<LayerImpl
> occluder_layer
=
6170 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6171 occluder_layer
->SetDrawsContent(true);
6172 occluder_layer
->SetBounds(content_size
);
6173 occluder_layer
->SetContentBounds(content_size
);
6174 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6176 int child_scroll_clip_layer_id
= 7;
6177 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6178 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6180 int child_scroll_layer_id
= 8;
6181 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6182 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6184 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6186 child_scroll
->AddChild(occluder_layer
.Pass());
6187 scroll_layer
->AddChild(child_scroll
.Pass());
6191 EXPECT_EQ(InputHandler::ScrollUnknown
,
6192 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6195 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6196 gfx::Size
content_size(100, 100);
6197 SetupScrollAndContentsLayers(content_size
);
6199 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6201 int scroll_layer_id
= 2;
6202 LayerImpl
* scroll_layer
=
6203 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6205 int child_scroll_layer_id
= 7;
6206 scoped_ptr
<LayerImpl
> child_scroll
=
6207 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6208 child_scroll
->SetDrawsContent(false);
6210 scroll_layer
->AddChild(child_scroll
.Pass());
6214 // We should not have scrolled |child_scroll| even though we technically "hit"
6215 // it. The reason for this is that if the scrolling the scroll would not move
6216 // any layer that is a drawn RSLL member, then we can ignore the hit.
6218 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6219 // overscrolling the inner viewport.
6220 EXPECT_EQ(InputHandler::ScrollStarted
,
6221 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6223 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6226 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6227 // This test case is very similar to the one above with one key difference:
6228 // the invisible scroller has a scroll child that is indeed draw contents.
6229 // If we attempt to initiate a gesture scroll off of the visible scroll child
6230 // we should still start the scroll child.
6231 gfx::Size
content_size(100, 100);
6232 SetupScrollAndContentsLayers(content_size
);
6234 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6236 int scroll_layer_id
= 2;
6237 LayerImpl
* scroll_layer
=
6238 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6240 int scroll_child_id
= 6;
6241 scoped_ptr
<LayerImpl
> scroll_child
=
6242 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6243 scroll_child
->SetDrawsContent(true);
6244 scroll_child
->SetBounds(content_size
);
6245 scroll_child
->SetContentBounds(content_size
);
6246 // Move the scroll child so it's not hit by our test point.
6247 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6249 int invisible_scroll_layer_id
= 7;
6250 scoped_ptr
<LayerImpl
> invisible_scroll
=
6251 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6252 invisible_scroll
->SetDrawsContent(false);
6254 int container_id
= 8;
6255 scoped_ptr
<LayerImpl
> container
=
6256 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6258 scoped_ptr
<std::set
<LayerImpl
*> > scroll_children(new std::set
<LayerImpl
*>());
6259 scroll_children
->insert(scroll_child
.get());
6260 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6262 scroll_child
->SetScrollParent(invisible_scroll
.get());
6264 container
->AddChild(invisible_scroll
.Pass());
6265 container
->AddChild(scroll_child
.Pass());
6267 scroll_layer
->AddChild(container
.Pass());
6271 // We should not have scrolled |child_scroll| even though we technically "hit"
6272 // it. The reason for this is that if the scrolling the scroll would not move
6273 // any layer that is a drawn RSLL member, then we can ignore the hit.
6275 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6276 // overscrolling the inner viewport.
6277 EXPECT_EQ(InputHandler::ScrollStarted
,
6278 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6280 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6283 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6284 // to CompositorFrameMetadata after SwapBuffers();
6285 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6286 scoped_ptr
<SolidColorLayerImpl
> root
=
6287 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6288 root
->SetPosition(gfx::PointF());
6289 root
->SetBounds(gfx::Size(10, 10));
6290 root
->SetContentBounds(gfx::Size(10, 10));
6291 root
->SetDrawsContent(true);
6293 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6295 FakeOutputSurface
* fake_output_surface
=
6296 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6298 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6299 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6300 EXPECT_TRUE(metadata_latency_before
.empty());
6302 ui::LatencyInfo latency_info
;
6303 latency_info
.AddLatencyNumber(
6304 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6305 scoped_ptr
<SwapPromise
> swap_promise(
6306 new LatencyInfoSwapPromise(latency_info
));
6307 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
6308 host_impl_
->SetNeedsRedraw();
6310 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6311 LayerTreeHostImpl::FrameData frame
;
6312 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6313 host_impl_
->DrawLayers(&frame
);
6314 host_impl_
->DidDrawAllLayers(frame
);
6315 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6317 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
6318 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6319 EXPECT_EQ(1u, metadata_latency_after
.size());
6320 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
6321 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
6324 TEST_F(LayerTreeHostImplTest
, SelectionBoundsPassedToCompositorFrameMetadata
) {
6325 int root_layer_id
= 1;
6326 scoped_ptr
<SolidColorLayerImpl
> root
=
6327 SolidColorLayerImpl::Create(host_impl_
->active_tree(), root_layer_id
);
6328 root
->SetPosition(gfx::PointF());
6329 root
->SetBounds(gfx::Size(10, 10));
6330 root
->SetContentBounds(gfx::Size(10, 10));
6331 root
->SetDrawsContent(true);
6333 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6335 // Ensure the default frame selection bounds are empty.
6336 FakeOutputSurface
* fake_output_surface
=
6337 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6338 const ViewportSelectionBound
& selection_anchor_before
=
6339 fake_output_surface
->last_sent_frame().metadata
.selection_anchor
;
6340 const ViewportSelectionBound
& selection_focus_before
=
6341 fake_output_surface
->last_sent_frame().metadata
.selection_focus
;
6342 EXPECT_EQ(ViewportSelectionBound(), selection_anchor_before
);
6343 EXPECT_EQ(ViewportSelectionBound(), selection_focus_before
);
6345 // Plumb the layer-local selection bounds.
6346 gfx::Rect
selection_rect(5, 0, 0, 5);
6347 LayerSelectionBound anchor
, focus
;
6348 anchor
.type
= SELECTION_BOUND_CENTER
;
6349 anchor
.layer_id
= root_layer_id
;
6350 anchor
.layer_rect
= selection_rect
;
6352 host_impl_
->active_tree()->RegisterSelection(anchor
, focus
);
6354 // Trigger a draw-swap sequence.
6355 host_impl_
->SetNeedsRedraw();
6357 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6358 LayerTreeHostImpl::FrameData frame
;
6359 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6360 host_impl_
->DrawLayers(&frame
);
6361 host_impl_
->DidDrawAllLayers(frame
);
6362 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6364 // Ensure the selection bounds have propagated to the frame metadata.
6365 const ViewportSelectionBound
& selection_anchor_after
=
6366 fake_output_surface
->last_sent_frame().metadata
.selection_anchor
;
6367 const ViewportSelectionBound
& selection_focus_after
=
6368 fake_output_surface
->last_sent_frame().metadata
.selection_focus
;
6369 EXPECT_EQ(anchor
.type
, selection_anchor_after
.type
);
6370 EXPECT_EQ(focus
.type
, selection_focus_after
.type
);
6371 EXPECT_EQ(selection_rect
, selection_anchor_after
.viewport_rect
);
6372 EXPECT_EQ(selection_rect
, selection_anchor_after
.viewport_rect
);
6373 EXPECT_TRUE(selection_anchor_after
.visible
);
6374 EXPECT_TRUE(selection_anchor_after
.visible
);
6377 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
6379 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
6380 LayerTreeHostImpl
* layer_tree_host_impl
,
6381 int* set_needs_commit_count
,
6382 int* set_needs_redraw_count
,
6383 int* forward_to_main_count
)
6384 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
6385 set_needs_commit_count_(set_needs_commit_count
),
6386 set_needs_redraw_count_(set_needs_redraw_count
),
6387 forward_to_main_count_(forward_to_main_count
) {}
6389 virtual ~SimpleSwapPromiseMonitor() {}
6391 virtual void OnSetNeedsCommitOnMain() OVERRIDE
{
6392 (*set_needs_commit_count_
)++;
6395 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE
{
6396 (*set_needs_redraw_count_
)++;
6399 virtual void OnForwardScrollUpdateToMainThreadOnImpl() OVERRIDE
{
6400 (*forward_to_main_count_
)++;
6404 int* set_needs_commit_count_
;
6405 int* set_needs_redraw_count_
;
6406 int* forward_to_main_count_
;
6409 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
6410 int set_needs_commit_count
= 0;
6411 int set_needs_redraw_count
= 0;
6412 int forward_to_main_count
= 0;
6415 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6416 new SimpleSwapPromiseMonitor(NULL
,
6418 &set_needs_commit_count
,
6419 &set_needs_redraw_count
,
6420 &forward_to_main_count
));
6421 host_impl_
->SetNeedsRedraw();
6422 EXPECT_EQ(0, set_needs_commit_count
);
6423 EXPECT_EQ(1, set_needs_redraw_count
);
6424 EXPECT_EQ(0, forward_to_main_count
);
6427 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
6429 host_impl_
->SetNeedsRedraw();
6430 EXPECT_EQ(0, set_needs_commit_count
);
6431 EXPECT_EQ(1, set_needs_redraw_count
);
6432 EXPECT_EQ(0, forward_to_main_count
);
6435 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6436 new SimpleSwapPromiseMonitor(NULL
,
6438 &set_needs_commit_count
,
6439 &set_needs_redraw_count
,
6440 &forward_to_main_count
));
6441 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
6442 EXPECT_EQ(0, set_needs_commit_count
);
6443 EXPECT_EQ(2, set_needs_redraw_count
);
6444 EXPECT_EQ(0, forward_to_main_count
);
6448 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6449 new SimpleSwapPromiseMonitor(NULL
,
6451 &set_needs_commit_count
,
6452 &set_needs_redraw_count
,
6453 &forward_to_main_count
));
6454 // Empty damage rect won't signal the monitor.
6455 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
6456 EXPECT_EQ(0, set_needs_commit_count
);
6457 EXPECT_EQ(2, set_needs_redraw_count
);
6458 EXPECT_EQ(0, forward_to_main_count
);
6462 set_needs_commit_count
= 0;
6463 set_needs_redraw_count
= 0;
6464 forward_to_main_count
= 0;
6465 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6466 new SimpleSwapPromiseMonitor(NULL
,
6468 &set_needs_commit_count
,
6469 &set_needs_redraw_count
,
6470 &forward_to_main_count
));
6471 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
6473 // Scrolling normally should not trigger any forwarding.
6474 EXPECT_EQ(InputHandler::ScrollStarted
,
6475 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6476 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
6477 host_impl_
->ScrollEnd();
6479 EXPECT_EQ(0, set_needs_commit_count
);
6480 EXPECT_EQ(1, set_needs_redraw_count
);
6481 EXPECT_EQ(0, forward_to_main_count
);
6483 // Scrolling with a scroll handler should defer the swap to the main
6485 scroll_layer
->SetHaveScrollEventHandlers(true);
6486 EXPECT_EQ(InputHandler::ScrollStarted
,
6487 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6488 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
6489 host_impl_
->ScrollEnd();
6491 EXPECT_EQ(0, set_needs_commit_count
);
6492 EXPECT_EQ(2, set_needs_redraw_count
);
6493 EXPECT_EQ(1, forward_to_main_count
);
6497 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
6499 virtual void SetUp() OVERRIDE
{
6500 LayerTreeSettings settings
= DefaultSettings();
6501 settings
.calculate_top_controls_position
= true;
6502 settings
.top_controls_height
= top_controls_height_
;
6503 CreateHostImpl(settings
, CreateOutputSurface());
6507 static const int top_controls_height_
;
6510 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
6512 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
6513 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6514 ->SetScrollOffset(gfx::Vector2d(0, 10));
6515 host_impl_
->Animate(base::TimeTicks());
6516 EXPECT_FALSE(did_request_redraw_
);
6519 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
6520 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6521 ->SetScrollOffset(gfx::Vector2d(0, 10));
6522 host_impl_
->DidChangeTopControlsPosition();
6523 EXPECT_TRUE(did_request_animate_
);
6524 EXPECT_TRUE(did_request_redraw_
);
6527 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
6528 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
6529 host_impl_
->SetViewportSize(gfx::Size(100, 100));
6532 EXPECT_EQ(InputHandler::ScrollStarted
,
6533 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6534 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6535 EXPECT_EQ(gfx::Vector2dF().ToString(),
6536 scroll_layer
->TotalScrollOffset().ToString());
6538 // Scroll just the top controls and verify that the scroll succeeds.
6539 const float residue
= 10;
6540 float offset
= top_controls_height_
- residue
;
6541 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6542 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->controls_top_offset());
6543 EXPECT_EQ(gfx::Vector2dF().ToString(),
6544 scroll_layer
->TotalScrollOffset().ToString());
6546 // Scroll across the boundary
6547 const float content_scroll
= 20;
6548 offset
= residue
+ content_scroll
;
6549 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6550 EXPECT_EQ(-top_controls_height_
,
6551 host_impl_
->top_controls_manager()->controls_top_offset());
6552 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
6553 scroll_layer
->TotalScrollOffset().ToString());
6555 // Now scroll back to the top of the content
6556 offset
= -content_scroll
;
6557 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6558 EXPECT_EQ(-top_controls_height_
,
6559 host_impl_
->top_controls_manager()->controls_top_offset());
6560 EXPECT_EQ(gfx::Vector2dF().ToString(),
6561 scroll_layer
->TotalScrollOffset().ToString());
6563 // And scroll the top controls completely into view
6564 offset
= -top_controls_height_
;
6565 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6566 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6567 EXPECT_EQ(gfx::Vector2dF().ToString(),
6568 scroll_layer
->TotalScrollOffset().ToString());
6570 // And attempt to scroll past the end
6571 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6572 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6573 EXPECT_EQ(gfx::Vector2dF().ToString(),
6574 scroll_layer
->TotalScrollOffset().ToString());
6576 host_impl_
->ScrollEnd();
6579 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
6581 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
6582 const gfx::Size
& outer_viewport
,
6583 const gfx::Size
& inner_viewport
) {
6584 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
6585 const int kOuterViewportClipLayerId
= 6;
6586 const int kOuterViewportScrollLayerId
= 7;
6587 const int kInnerViewportScrollLayerId
= 2;
6588 const int kInnerViewportClipLayerId
= 4;
6589 const int kPageScaleLayerId
= 5;
6591 scoped_ptr
<LayerImpl
> inner_scroll
=
6592 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
6593 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
6594 inner_scroll
->SetScrollOffset(gfx::Vector2d());
6596 scoped_ptr
<LayerImpl
> inner_clip
=
6597 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
6598 inner_clip
->SetBounds(inner_viewport
);
6600 scoped_ptr
<LayerImpl
> page_scale
=
6601 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
6603 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
6604 inner_scroll
->SetBounds(outer_viewport
);
6605 inner_scroll
->SetContentBounds(outer_viewport
);
6606 inner_scroll
->SetPosition(gfx::PointF());
6608 scoped_ptr
<LayerImpl
> outer_clip
=
6609 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
6610 outer_clip
->SetBounds(outer_viewport
);
6611 outer_clip
->SetIsContainerForFixedPositionLayers(true);
6613 scoped_ptr
<LayerImpl
> outer_scroll
=
6614 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
6615 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
6616 outer_scroll
->SetScrollOffset(gfx::Vector2d());
6617 outer_scroll
->SetBounds(content_size
);
6618 outer_scroll
->SetContentBounds(content_size
);
6619 outer_scroll
->SetPosition(gfx::PointF());
6621 scoped_ptr
<LayerImpl
> contents
=
6622 LayerImpl::Create(layer_tree_impl
, 8);
6623 contents
->SetDrawsContent(true);
6624 contents
->SetBounds(content_size
);
6625 contents
->SetContentBounds(content_size
);
6626 contents
->SetPosition(gfx::PointF());
6628 outer_scroll
->AddChild(contents
.Pass());
6629 outer_clip
->AddChild(outer_scroll
.Pass());
6630 inner_scroll
->AddChild(outer_clip
.Pass());
6631 page_scale
->AddChild(inner_scroll
.Pass());
6632 inner_clip
->AddChild(page_scale
.Pass());
6634 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
6635 layer_tree_impl
->SetViewportLayersFromIds(kPageScaleLayerId
,
6636 kInnerViewportScrollLayerId
, kOuterViewportScrollLayerId
);
6638 host_impl_
->active_tree()->DidBecomeActive();
6642 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
6643 gfx::Size content_size
= gfx::Size(100, 160);
6644 gfx::Size outer_viewport
= gfx::Size(50, 80);
6645 gfx::Size inner_viewport
= gfx::Size(25, 40);
6647 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
6649 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
6650 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
6653 gfx::Vector2dF inner_expected
;
6654 gfx::Vector2dF outer_expected
;
6655 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6656 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6658 // Make sure the fling goes to the outer viewport first
6659 EXPECT_EQ(InputHandler::ScrollStarted
,
6660 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6661 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6663 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
6664 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6665 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6667 host_impl_
->ScrollEnd();
6669 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6670 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6672 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
6673 EXPECT_EQ(InputHandler::ScrollStarted
,
6674 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6675 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6677 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6678 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6680 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6681 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6683 host_impl_
->ScrollEnd();
6685 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6686 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6690 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
6692 virtual void SetUp() OVERRIDE
{
6693 LayerTreeSettings settings
= DefaultSettings();
6694 settings
.max_memory_for_prepaint_percentage
= 50;
6695 CreateHostImpl(settings
, CreateOutputSurface());
6699 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
6700 // Set up a memory policy and percentages which could cause
6701 // 32-bit integer overflows.
6702 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
6704 // Verify implicit limits are calculated correctly with no overflows
6705 host_impl_
->SetMemoryPolicy(mem_policy
);
6706 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
6707 300u * 1024u * 1024u);
6708 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
6709 150u * 1024u * 1024u);
6712 TEST_F(LayerTreeHostImplTest
, ExternalTransformReflectedInNextDraw
) {
6713 const gfx::Size
layer_size(100, 100);
6714 gfx::Transform external_transform
;
6715 const gfx::Rect
external_viewport(layer_size
);
6716 const gfx::Rect
external_clip(layer_size
);
6717 const bool resourceless_software_draw
= false;
6718 LayerImpl
* layer
= SetupScrollAndContentsLayers(layer_size
);
6720 host_impl_
->SetExternalDrawConstraints(external_transform
,
6723 resourceless_software_draw
);
6725 EXPECT_TRANSFORMATION_MATRIX_EQ(
6726 external_transform
, layer
->draw_properties().target_space_transform
);
6728 external_transform
.Translate(20, 20);
6729 host_impl_
->SetExternalDrawConstraints(external_transform
,
6732 resourceless_software_draw
);
6734 EXPECT_TRANSFORMATION_MATRIX_EQ(
6735 external_transform
, layer
->draw_properties().target_space_transform
);
6738 TEST_F(LayerTreeHostImplTest
, ScrollAnimated
) {
6739 SetupScrollAndContentsLayers(gfx::Size(100, 100));
6740 host_impl_
->SetViewportSize(gfx::Size(50, 50));
6743 base::TimeTicks start_time
=
6744 base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
6746 EXPECT_EQ(InputHandler::ScrollStarted
,
6747 host_impl_
->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
6749 LayerImpl
* scrolling_layer
= host_impl_
->CurrentlyScrollingLayer();
6751 host_impl_
->Animate(start_time
);
6752 host_impl_
->UpdateAnimationState(true);
6754 EXPECT_EQ(gfx::Vector2dF(), scrolling_layer
->TotalScrollOffset());
6756 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(50));
6757 host_impl_
->UpdateAnimationState(true);
6759 float y
= scrolling_layer
->TotalScrollOffset().y();
6760 EXPECT_TRUE(y
> 1 && y
< 49);
6762 host_impl_
->Animate(start_time
+ base::TimeDelta::FromMilliseconds(200));
6763 host_impl_
->UpdateAnimationState(true);
6765 EXPECT_EQ(gfx::Vector2dF(0, 50), scrolling_layer
->TotalScrollOffset());
6766 EXPECT_EQ(NULL
, host_impl_
->CurrentlyScrollingLayer());