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
, gfx::FrameTime::Now());
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
, MasksToBoundsDoesntClobberInnerContainerSize
) {
975 SetupScrollAndContentsLayers(gfx::Size(100, 100));
976 host_impl_
->SetViewportSize(gfx::Size(50, 50));
979 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
980 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
981 DCHECK(scroll_layer
);
983 float min_page_scale
= 1.f
;
984 float max_page_scale
= 4.f
;
985 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
989 // If the container's masks_to_bounds is false, the viewport size should
990 // overwrite the inner viewport container layer's size.
992 EXPECT_EQ(gfx::Size(50, 50),
993 container_layer
->bounds());
994 container_layer
->SetMasksToBounds(false);
996 container_layer
->SetBounds(gfx::Size(30, 25));
997 EXPECT_EQ(gfx::Size(30, 25),
998 container_layer
->bounds());
1000 // This should cause a reset of the inner viewport container layer's bounds.
1001 host_impl_
->DidChangeTopControlsPosition();
1003 EXPECT_EQ(gfx::Size(50, 50),
1004 container_layer
->bounds());
1007 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1008 container_layer
->SetBounds(gfx::Size(50, 50));
1010 // If the container's masks_to_bounds is true, the viewport size should
1011 // *NOT* overwrite the inner viewport container layer's size.
1013 EXPECT_EQ(gfx::Size(50, 50),
1014 container_layer
->bounds());
1015 container_layer
->SetMasksToBounds(true);
1017 container_layer
->SetBounds(gfx::Size(30, 25));
1018 EXPECT_EQ(gfx::Size(30, 25),
1019 container_layer
->bounds());
1021 // This should cause a reset of the inner viewport container layer's bounds.
1022 host_impl_
->DidChangeTopControlsPosition();
1024 EXPECT_EQ(gfx::Size(30, 25),
1025 container_layer
->bounds());
1029 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1030 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1031 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1034 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1035 DCHECK(scroll_layer
);
1037 float min_page_scale
= 1.f
;
1038 float max_page_scale
= 4.f
;
1040 // Basic pinch zoom in gesture
1042 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1045 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1047 float page_scale_delta
= 2.f
;
1048 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1049 host_impl_
->PinchGestureBegin();
1050 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1051 host_impl_
->PinchGestureEnd();
1052 host_impl_
->ScrollEnd();
1053 EXPECT_FALSE(did_request_animate_
);
1054 EXPECT_TRUE(did_request_redraw_
);
1055 EXPECT_TRUE(did_request_commit_
);
1057 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1058 host_impl_
->ProcessScrollDeltas();
1059 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1064 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1067 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1068 float page_scale_delta
= 10.f
;
1070 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1071 host_impl_
->PinchGestureBegin();
1072 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1073 host_impl_
->PinchGestureEnd();
1074 host_impl_
->ScrollEnd();
1076 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1077 host_impl_
->ProcessScrollDeltas();
1078 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1081 // Zoom-out clamping
1083 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1086 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1087 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1089 float page_scale_delta
= 0.1f
;
1090 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1091 host_impl_
->PinchGestureBegin();
1092 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1093 host_impl_
->PinchGestureEnd();
1094 host_impl_
->ScrollEnd();
1096 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1097 host_impl_
->ProcessScrollDeltas();
1098 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1100 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1103 // Two-finger panning should not happen based on pinch events only
1105 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1108 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1109 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1111 float page_scale_delta
= 1.f
;
1112 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1113 host_impl_
->PinchGestureBegin();
1114 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1115 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1116 host_impl_
->PinchGestureEnd();
1117 host_impl_
->ScrollEnd();
1119 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1120 host_impl_
->ProcessScrollDeltas();
1121 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1122 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1125 // Two-finger panning should work with interleaved scroll events
1127 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1130 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1131 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1133 float page_scale_delta
= 1.f
;
1134 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1135 host_impl_
->PinchGestureBegin();
1136 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1137 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1138 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1139 host_impl_
->PinchGestureEnd();
1140 host_impl_
->ScrollEnd();
1142 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1143 host_impl_
->ProcessScrollDeltas();
1144 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1145 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1148 // Two-finger panning should work when starting fully zoomed out.
1150 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(0.5f
,
1153 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1154 scroll_layer
->SetScrollOffset(gfx::Vector2d(0, 0));
1156 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1157 host_impl_
->PinchGestureBegin();
1158 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1159 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1160 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1161 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1162 host_impl_
->PinchGestureEnd();
1163 host_impl_
->ScrollEnd();
1165 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1166 host_impl_
->ProcessScrollDeltas();
1167 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1168 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1172 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1173 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1174 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1177 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1178 DCHECK(scroll_layer
);
1180 float min_page_scale
= 0.5f
;
1181 float max_page_scale
= 4.f
;
1182 base::TimeTicks start_time
= base::TimeTicks() +
1183 base::TimeDelta::FromSeconds(1);
1184 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1185 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1186 base::TimeTicks end_time
= start_time
+ duration
;
1188 // Non-anchor zoom-in
1190 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1193 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1195 did_request_redraw_
= false;
1196 did_request_animate_
= false;
1197 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f
, duration
);
1198 EXPECT_FALSE(did_request_redraw_
);
1199 EXPECT_TRUE(did_request_animate_
);
1201 did_request_redraw_
= false;
1202 did_request_animate_
= false;
1203 host_impl_
->Animate(start_time
);
1204 EXPECT_TRUE(did_request_redraw_
);
1205 EXPECT_TRUE(did_request_animate_
);
1207 did_request_redraw_
= false;
1208 did_request_animate_
= false;
1209 host_impl_
->Animate(halfway_through_animation
);
1210 EXPECT_TRUE(did_request_redraw_
);
1211 EXPECT_TRUE(did_request_animate_
);
1213 did_request_redraw_
= false;
1214 did_request_animate_
= false;
1215 did_request_commit_
= false;
1216 host_impl_
->Animate(end_time
);
1217 EXPECT_TRUE(did_request_commit_
);
1218 EXPECT_FALSE(did_request_animate_
);
1220 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1221 host_impl_
->ProcessScrollDeltas();
1222 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1223 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1228 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1231 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1233 did_request_redraw_
= false;
1234 did_request_animate_
= false;
1235 host_impl_
->StartPageScaleAnimation(
1236 gfx::Vector2d(25, 25), true, min_page_scale
, duration
);
1237 EXPECT_FALSE(did_request_redraw_
);
1238 EXPECT_TRUE(did_request_animate_
);
1240 did_request_redraw_
= false;
1241 did_request_animate_
= false;
1242 host_impl_
->Animate(start_time
);
1243 EXPECT_TRUE(did_request_redraw_
);
1244 EXPECT_TRUE(did_request_animate_
);
1246 did_request_redraw_
= false;
1247 did_request_commit_
= false;
1248 did_request_animate_
= false;
1249 host_impl_
->Animate(end_time
);
1250 EXPECT_TRUE(did_request_redraw_
);
1251 EXPECT_FALSE(did_request_animate_
);
1252 EXPECT_TRUE(did_request_commit_
);
1254 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1255 host_impl_
->ProcessScrollDeltas();
1256 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1257 // Pushed to (0,0) via clamping against contents layer size.
1258 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1262 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1263 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1264 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1267 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1268 DCHECK(scroll_layer
);
1270 float min_page_scale
= 0.5f
;
1271 float max_page_scale
= 4.f
;
1272 base::TimeTicks start_time
= base::TimeTicks() +
1273 base::TimeDelta::FromSeconds(1);
1274 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1275 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1276 base::TimeTicks end_time
= start_time
+ duration
;
1278 // Anchor zoom with unchanged page scale should not change scroll or scale.
1280 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1283 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1285 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f
, duration
);
1286 host_impl_
->Animate(start_time
);
1287 host_impl_
->Animate(halfway_through_animation
);
1288 EXPECT_TRUE(did_request_redraw_
);
1289 host_impl_
->Animate(end_time
);
1290 EXPECT_TRUE(did_request_commit_
);
1292 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1293 host_impl_
->ProcessScrollDeltas();
1294 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1295 ExpectNone(*scroll_info
, scroll_layer
->id());
1299 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1301 LayerTreeHostImplOverridePhysicalTime(
1302 const LayerTreeSettings
& settings
,
1303 LayerTreeHostImplClient
* client
,
1305 SharedBitmapManager
* manager
,
1306 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1307 : LayerTreeHostImpl(settings
,
1310 rendering_stats_instrumentation
,
1314 virtual base::TimeTicks
CurrentFrameTimeTicks() OVERRIDE
{
1315 return fake_current_physical_time_
;
1318 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1319 fake_current_physical_time_
= fake_now
;
1323 base::TimeTicks fake_current_physical_time_
;
1326 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1327 gfx::Size viewport_size(10, 10); \
1328 gfx::Size content_size(100, 100); \
1330 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1331 new LayerTreeHostImplOverridePhysicalTime(settings, \
1334 shared_bitmap_manager_.get(), \
1335 &stats_instrumentation_); \
1336 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1337 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1338 host_impl_->SetViewportSize(viewport_size); \
1340 scoped_ptr<LayerImpl> root = \
1341 LayerImpl::Create(host_impl_->active_tree(), 1); \
1342 root->SetBounds(viewport_size); \
1344 scoped_ptr<LayerImpl> scroll = \
1345 LayerImpl::Create(host_impl_->active_tree(), 2); \
1346 scroll->SetScrollClipLayer(root->id()); \
1347 scroll->SetScrollOffset(gfx::Vector2d()); \
1348 root->SetBounds(viewport_size); \
1349 scroll->SetBounds(content_size); \
1350 scroll->SetContentBounds(content_size); \
1351 scroll->SetIsContainerForFixedPositionLayers(true); \
1353 scoped_ptr<LayerImpl> contents = \
1354 LayerImpl::Create(host_impl_->active_tree(), 3); \
1355 contents->SetDrawsContent(true); \
1356 contents->SetBounds(content_size); \
1357 contents->SetContentBounds(content_size); \
1359 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1360 SolidColorScrollbarLayerImpl::Create( \
1361 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \
1362 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1364 scroll->AddChild(contents.Pass()); \
1365 root->AddChild(scroll.Pass()); \
1366 scrollbar->SetScrollLayerAndClipLayerByIds(2, 1); \
1367 root->AddChild(scrollbar.PassAs<LayerImpl>()); \
1369 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1370 host_impl_->active_tree()->SetViewportLayersFromIds( \
1371 1, 2, Layer::INVALID_ID); \
1372 host_impl_->active_tree()->DidBecomeActive(); \
1375 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1376 LayerTreeSettings settings
;
1377 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1378 settings
.scrollbar_fade_delay_ms
= 20;
1379 settings
.scrollbar_fade_duration_ms
= 20;
1381 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1383 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1385 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1386 EXPECT_FALSE(did_request_redraw_
);
1388 // If no scroll happened during a scroll gesture, it should have no effect.
1389 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1390 host_impl_
->ScrollEnd();
1391 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1392 EXPECT_FALSE(did_request_redraw_
);
1393 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1395 // After a scroll, a fade animation should be scheduled about 20ms from now.
1396 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1397 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1398 host_impl_
->ScrollEnd();
1399 did_request_redraw_
= false;
1400 did_request_animate_
= false;
1401 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1402 requested_scrollbar_animation_delay_
);
1403 EXPECT_FALSE(did_request_redraw_
);
1404 EXPECT_FALSE(did_request_animate_
);
1405 requested_scrollbar_animation_delay_
= base::TimeDelta();
1406 scrollbar_fade_start_
.Run();
1407 host_impl_
->Animate(fake_now
);
1409 // After the fade begins, we should start getting redraws instead of a
1410 // scheduled animation.
1411 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1412 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1413 EXPECT_TRUE(did_request_animate_
);
1414 did_request_animate_
= false;
1416 // Setting the scroll offset outside a scroll should also cause the scrollbar
1417 // to appear and to schedule a fade.
1418 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
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();
1426 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1427 LayerTreeSettings settings
;
1428 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1429 settings
.scrollbar_fade_delay_ms
= 20;
1430 settings
.scrollbar_fade_duration_ms
= 20;
1431 settings
.use_pinch_zoom_scrollbars
= true;
1433 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1435 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1437 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, 4.f
);
1439 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1440 EXPECT_FALSE(did_request_animate_
);
1442 // If no scroll happened during a scroll gesture, it should have no effect.
1443 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1444 host_impl_
->ScrollEnd();
1445 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1446 EXPECT_FALSE(did_request_animate_
);
1447 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1449 // After a scroll, no fade animation should be scheduled.
1450 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1451 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1452 host_impl_
->ScrollEnd();
1453 did_request_redraw_
= false;
1454 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1455 EXPECT_FALSE(did_request_animate_
);
1456 requested_scrollbar_animation_delay_
= base::TimeDelta();
1458 // We should not see any draw requests.
1459 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1460 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1461 EXPECT_FALSE(did_request_animate_
);
1463 // Make page scale > min so that subsequent scrolls will trigger fades.
1464 host_impl_
->active_tree()->SetPageScaleDelta(1.1f
);
1466 // After a scroll, a fade animation should be scheduled about 20ms from now.
1467 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1468 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1469 host_impl_
->ScrollEnd();
1470 did_request_redraw_
= false;
1471 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1472 requested_scrollbar_animation_delay_
);
1473 EXPECT_FALSE(did_request_animate_
);
1474 requested_scrollbar_animation_delay_
= base::TimeDelta();
1475 scrollbar_fade_start_
.Run();
1477 // After the fade begins, we should start getting redraws instead of a
1478 // scheduled animation.
1479 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1480 host_impl_
->Animate(fake_now
);
1481 EXPECT_TRUE(did_request_animate_
);
1484 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1485 float device_scale_factor
) {
1486 LayerTreeSettings settings
;
1487 settings
.scrollbar_fade_delay_ms
= 500;
1488 settings
.scrollbar_fade_duration_ms
= 300;
1489 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1491 gfx::Size
viewport_size(300, 200);
1492 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1493 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1494 gfx::Size
content_size(1000, 1000);
1496 CreateHostImpl(settings
, CreateOutputSurface());
1497 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1498 host_impl_
->SetViewportSize(device_viewport_size
);
1500 scoped_ptr
<LayerImpl
> root
=
1501 LayerImpl::Create(host_impl_
->active_tree(), 1);
1502 root
->SetBounds(viewport_size
);
1504 scoped_ptr
<LayerImpl
> scroll
=
1505 LayerImpl::Create(host_impl_
->active_tree(), 2);
1506 scroll
->SetScrollClipLayer(root
->id());
1507 scroll
->SetScrollOffset(gfx::Vector2d());
1508 scroll
->SetBounds(content_size
);
1509 scroll
->SetContentBounds(content_size
);
1510 scroll
->SetIsContainerForFixedPositionLayers(true);
1512 scoped_ptr
<LayerImpl
> contents
=
1513 LayerImpl::Create(host_impl_
->active_tree(), 3);
1514 contents
->SetDrawsContent(true);
1515 contents
->SetBounds(content_size
);
1516 contents
->SetContentBounds(content_size
);
1518 // The scrollbar is on the right side.
1519 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1520 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1521 scrollbar
->SetDrawsContent(true);
1522 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1523 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1524 scrollbar
->SetPosition(gfx::Point(285, 0));
1526 scroll
->AddChild(contents
.Pass());
1527 root
->AddChild(scroll
.Pass());
1528 scrollbar
->SetScrollLayerAndClipLayerByIds(2, 1);
1529 root
->AddChild(scrollbar
.PassAs
<LayerImpl
>());
1531 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1532 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
1533 host_impl_
->active_tree()->DidBecomeActive();
1536 LayerImpl
* root_scroll
=
1537 host_impl_
->active_tree()->InnerViewportScrollLayer();
1538 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1539 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1540 static_cast<ScrollbarAnimationControllerThinning
*>(
1541 root_scroll
->scrollbar_animation_controller());
1542 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1544 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1545 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1547 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1548 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1550 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1551 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1553 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1554 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1555 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1557 did_request_redraw_
= false;
1558 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1559 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1560 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1561 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1562 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1563 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1564 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1567 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1568 SetupMouseMoveAtWithDeviceScale(1.f
);
1571 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1572 SetupMouseMoveAtWithDeviceScale(2.f
);
1575 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1576 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1577 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1578 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
1581 CompositorFrameMetadata metadata
=
1582 host_impl_
->MakeCompositorFrameMetadata();
1583 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1584 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1585 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.viewport_size
);
1586 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1587 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1588 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1591 // Scrolling should update metadata immediately.
1592 EXPECT_EQ(InputHandler::ScrollStarted
,
1593 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1594 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1596 CompositorFrameMetadata metadata
=
1597 host_impl_
->MakeCompositorFrameMetadata();
1598 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1600 host_impl_
->ScrollEnd();
1602 CompositorFrameMetadata metadata
=
1603 host_impl_
->MakeCompositorFrameMetadata();
1604 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1607 // Page scale should update metadata correctly (shrinking only the viewport).
1608 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1609 host_impl_
->PinchGestureBegin();
1610 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1611 host_impl_
->PinchGestureEnd();
1612 host_impl_
->ScrollEnd();
1614 CompositorFrameMetadata metadata
=
1615 host_impl_
->MakeCompositorFrameMetadata();
1616 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1617 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1618 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.viewport_size
);
1619 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1620 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1621 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1624 // Likewise if set from the main thread.
1625 host_impl_
->ProcessScrollDeltas();
1626 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(4.f
, 0.5f
, 4.f
);
1627 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
1629 CompositorFrameMetadata metadata
=
1630 host_impl_
->MakeCompositorFrameMetadata();
1631 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1632 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1633 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.viewport_size
);
1634 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1635 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1636 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1640 class DidDrawCheckLayer
: public LayerImpl
{
1642 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1643 return scoped_ptr
<LayerImpl
>(new DidDrawCheckLayer(tree_impl
, id
));
1646 virtual bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
)
1648 will_draw_called_
= true;
1649 if (will_draw_returns_false_
)
1651 return LayerImpl::WillDraw(draw_mode
, provider
);
1654 virtual void AppendQuads(RenderPass
* render_pass
,
1655 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
1656 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1657 append_quads_called_
= true;
1658 LayerImpl::AppendQuads(render_pass
, occlusion_tracker
, append_quads_data
);
1661 virtual void DidDraw(ResourceProvider
* provider
) OVERRIDE
{
1662 did_draw_called_
= true;
1663 LayerImpl::DidDraw(provider
);
1666 bool will_draw_called() const { return will_draw_called_
; }
1667 bool append_quads_called() const { return append_quads_called_
; }
1668 bool did_draw_called() const { return did_draw_called_
; }
1670 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1672 void ClearDidDrawCheck() {
1673 will_draw_called_
= false;
1674 append_quads_called_
= false;
1675 did_draw_called_
= false;
1679 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1680 : LayerImpl(tree_impl
, id
),
1681 will_draw_returns_false_(false),
1682 will_draw_called_(false),
1683 append_quads_called_(false),
1684 did_draw_called_(false) {
1685 SetBounds(gfx::Size(10, 10));
1686 SetContentBounds(gfx::Size(10, 10));
1687 SetDrawsContent(true);
1688 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1692 bool will_draw_returns_false_
;
1693 bool will_draw_called_
;
1694 bool append_quads_called_
;
1695 bool did_draw_called_
;
1698 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1699 // The root layer is always drawn, so run this test on a child layer that
1700 // will be masked out by the root layer's bounds.
1701 host_impl_
->active_tree()->SetRootLayer(
1702 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1703 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1704 host_impl_
->active_tree()->root_layer());
1706 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1707 DidDrawCheckLayer
* layer
=
1708 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1711 LayerTreeHostImpl::FrameData frame
;
1712 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1713 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1714 host_impl_
->DidDrawAllLayers(frame
);
1716 EXPECT_TRUE(layer
->will_draw_called());
1717 EXPECT_TRUE(layer
->append_quads_called());
1718 EXPECT_TRUE(layer
->did_draw_called());
1721 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1724 LayerTreeHostImpl::FrameData frame
;
1726 layer
->set_will_draw_returns_false();
1727 layer
->ClearDidDrawCheck();
1729 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1730 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1731 host_impl_
->DidDrawAllLayers(frame
);
1733 EXPECT_TRUE(layer
->will_draw_called());
1734 EXPECT_FALSE(layer
->append_quads_called());
1735 EXPECT_FALSE(layer
->did_draw_called());
1739 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1740 // The root layer is always drawn, so run this test on a child layer that
1741 // will be masked out by the root layer's bounds.
1742 host_impl_
->active_tree()->SetRootLayer(
1743 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1744 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1745 host_impl_
->active_tree()->root_layer());
1746 root
->SetMasksToBounds(true);
1748 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1749 DidDrawCheckLayer
* layer
=
1750 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1751 // Ensure visible_content_rect for layer is empty.
1752 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1753 layer
->SetBounds(gfx::Size(10, 10));
1754 layer
->SetContentBounds(gfx::Size(10, 10));
1756 LayerTreeHostImpl::FrameData frame
;
1758 EXPECT_FALSE(layer
->will_draw_called());
1759 EXPECT_FALSE(layer
->did_draw_called());
1761 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1762 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1763 host_impl_
->DidDrawAllLayers(frame
);
1765 EXPECT_FALSE(layer
->will_draw_called());
1766 EXPECT_FALSE(layer
->did_draw_called());
1768 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1770 // Ensure visible_content_rect for layer is not empty
1771 layer
->SetPosition(gfx::PointF());
1773 EXPECT_FALSE(layer
->will_draw_called());
1774 EXPECT_FALSE(layer
->did_draw_called());
1776 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1777 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1778 host_impl_
->DidDrawAllLayers(frame
);
1780 EXPECT_TRUE(layer
->will_draw_called());
1781 EXPECT_TRUE(layer
->did_draw_called());
1783 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1786 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1787 gfx::Size
big_size(1000, 1000);
1788 host_impl_
->SetViewportSize(big_size
);
1790 host_impl_
->active_tree()->SetRootLayer(
1791 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1792 DidDrawCheckLayer
* root
=
1793 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1795 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1796 DidDrawCheckLayer
* occluded_layer
=
1797 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1799 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1800 DidDrawCheckLayer
* top_layer
=
1801 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1802 // This layer covers the occluded_layer above. Make this layer large so it can
1804 top_layer
->SetBounds(big_size
);
1805 top_layer
->SetContentBounds(big_size
);
1806 top_layer
->SetContentsOpaque(true);
1808 LayerTreeHostImpl::FrameData frame
;
1810 EXPECT_FALSE(occluded_layer
->will_draw_called());
1811 EXPECT_FALSE(occluded_layer
->did_draw_called());
1812 EXPECT_FALSE(top_layer
->will_draw_called());
1813 EXPECT_FALSE(top_layer
->did_draw_called());
1815 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1816 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1817 host_impl_
->DidDrawAllLayers(frame
);
1819 EXPECT_FALSE(occluded_layer
->will_draw_called());
1820 EXPECT_FALSE(occluded_layer
->did_draw_called());
1821 EXPECT_TRUE(top_layer
->will_draw_called());
1822 EXPECT_TRUE(top_layer
->did_draw_called());
1825 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1826 host_impl_
->active_tree()->SetRootLayer(
1827 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1828 DidDrawCheckLayer
* root
=
1829 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1831 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1832 DidDrawCheckLayer
* layer1
=
1833 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1835 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1836 DidDrawCheckLayer
* layer2
=
1837 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1839 layer1
->SetOpacity(0.3f
);
1840 layer1
->SetShouldFlattenTransform(true);
1842 EXPECT_FALSE(root
->did_draw_called());
1843 EXPECT_FALSE(layer1
->did_draw_called());
1844 EXPECT_FALSE(layer2
->did_draw_called());
1846 LayerTreeHostImpl::FrameData frame
;
1847 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1848 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1849 host_impl_
->DidDrawAllLayers(frame
);
1851 EXPECT_TRUE(root
->did_draw_called());
1852 EXPECT_TRUE(layer1
->did_draw_called());
1853 EXPECT_TRUE(layer2
->did_draw_called());
1855 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1856 EXPECT_TRUE(!!layer1
->render_surface());
1859 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1861 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1864 bool had_incomplete_tile
,
1866 ResourceProvider
* resource_provider
) {
1867 return scoped_ptr
<LayerImpl
>(
1868 new MissingTextureAnimatingLayer(tree_impl
,
1871 had_incomplete_tile
,
1873 resource_provider
));
1876 virtual void AppendQuads(RenderPass
* render_pass
,
1877 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
1878 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1879 LayerImpl::AppendQuads(render_pass
, occlusion_tracker
, append_quads_data
);
1880 if (had_incomplete_tile_
)
1881 append_quads_data
->had_incomplete_tile
= true;
1883 append_quads_data
->num_missing_tiles
++;
1887 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1890 bool had_incomplete_tile
,
1892 ResourceProvider
* resource_provider
)
1893 : DidDrawCheckLayer(tree_impl
, id
),
1894 tile_missing_(tile_missing
),
1895 had_incomplete_tile_(had_incomplete_tile
) {
1897 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1901 bool had_incomplete_tile_
;
1904 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsOnDefault
) {
1905 host_impl_
->active_tree()->SetRootLayer(
1906 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1907 DidDrawCheckLayer
* root
=
1908 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1910 bool tile_missing
= false;
1911 bool had_incomplete_tile
= false;
1912 bool is_animating
= false;
1914 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1917 had_incomplete_tile
,
1919 host_impl_
->resource_provider()));
1921 LayerTreeHostImpl::FrameData frame
;
1923 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1924 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1925 host_impl_
->DidDrawAllLayers(frame
);
1928 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
1929 host_impl_
->active_tree()->SetRootLayer(
1930 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1931 DidDrawCheckLayer
* root
=
1932 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1933 bool tile_missing
= false;
1934 bool had_incomplete_tile
= false;
1935 bool is_animating
= true;
1937 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1940 had_incomplete_tile
,
1942 host_impl_
->resource_provider()));
1944 LayerTreeHostImpl::FrameData frame
;
1946 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1947 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1948 host_impl_
->DidDrawAllLayers(frame
);
1951 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithMissingTiles
) {
1952 host_impl_
->active_tree()->SetRootLayer(
1953 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1954 DidDrawCheckLayer
* root
=
1955 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1957 bool tile_missing
= true;
1958 bool had_incomplete_tile
= false;
1959 bool is_animating
= false;
1961 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1964 had_incomplete_tile
,
1966 host_impl_
->resource_provider()));
1967 LayerTreeHostImpl::FrameData frame
;
1968 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1969 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1970 host_impl_
->DidDrawAllLayers(frame
);
1973 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithIncompleteTile
) {
1974 host_impl_
->active_tree()->SetRootLayer(
1975 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1976 DidDrawCheckLayer
* root
=
1977 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1979 bool tile_missing
= false;
1980 bool had_incomplete_tile
= true;
1981 bool is_animating
= false;
1983 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1986 had_incomplete_tile
,
1988 host_impl_
->resource_provider()));
1989 LayerTreeHostImpl::FrameData frame
;
1990 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1991 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1992 host_impl_
->DidDrawAllLayers(frame
);
1995 TEST_F(LayerTreeHostImplTest
,
1996 PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard
) {
1997 host_impl_
->active_tree()->SetRootLayer(
1998 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
1999 DidDrawCheckLayer
* root
=
2000 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2001 bool tile_missing
= true;
2002 bool had_incomplete_tile
= false;
2003 bool is_animating
= true;
2005 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2008 had_incomplete_tile
,
2010 host_impl_
->resource_provider()));
2011 LayerTreeHostImpl::FrameData frame
;
2012 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2013 host_impl_
->PrepareToDraw(&frame
));
2014 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2015 host_impl_
->DidDrawAllLayers(frame
);
2018 TEST_F(LayerTreeHostImplTest
,
2019 PrepareToDrawSucceedsWithAnimationAndIncompleteTiles
) {
2020 host_impl_
->active_tree()->SetRootLayer(
2021 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2022 DidDrawCheckLayer
* root
=
2023 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2024 bool tile_missing
= false;
2025 bool had_incomplete_tile
= true;
2026 bool is_animating
= true;
2028 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2031 had_incomplete_tile
,
2033 host_impl_
->resource_provider()));
2034 LayerTreeHostImpl::FrameData frame
;
2035 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2036 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2037 host_impl_
->DidDrawAllLayers(frame
);
2040 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenHighResRequired
) {
2041 host_impl_
->active_tree()->SetRootLayer(
2042 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2043 DidDrawCheckLayer
* root
=
2044 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2045 bool tile_missing
= false;
2046 bool had_incomplete_tile
= false;
2047 bool is_animating
= false;
2049 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2052 had_incomplete_tile
,
2054 host_impl_
->resource_provider()));
2055 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2056 LayerTreeHostImpl::FrameData frame
;
2057 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2058 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2059 host_impl_
->DidDrawAllLayers(frame
);
2062 TEST_F(LayerTreeHostImplTest
,
2063 PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles
) {
2064 host_impl_
->active_tree()->SetRootLayer(
2065 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2066 DidDrawCheckLayer
* root
=
2067 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2068 bool tile_missing
= false;
2069 bool had_incomplete_tile
= true;
2070 bool is_animating
= false;
2072 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2075 had_incomplete_tile
,
2077 host_impl_
->resource_provider()));
2078 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2079 LayerTreeHostImpl::FrameData frame
;
2080 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2081 host_impl_
->PrepareToDraw(&frame
));
2082 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2083 host_impl_
->DidDrawAllLayers(frame
);
2086 TEST_F(LayerTreeHostImplTest
,
2087 PrepareToDrawSucceedsWhenHighResRequiredAndMissingTile
) {
2088 host_impl_
->active_tree()->SetRootLayer(
2089 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2090 DidDrawCheckLayer
* root
=
2091 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2092 bool tile_missing
= true;
2093 bool had_incomplete_tile
= false;
2094 bool is_animating
= false;
2096 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2099 had_incomplete_tile
,
2101 host_impl_
->resource_provider()));
2102 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2103 LayerTreeHostImpl::FrameData frame
;
2104 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2105 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2106 host_impl_
->DidDrawAllLayers(frame
);
2109 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2110 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2111 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2112 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2115 // Scroll event is ignored because layer is not scrollable.
2116 EXPECT_EQ(InputHandler::ScrollIgnored
,
2117 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2118 EXPECT_FALSE(did_request_redraw_
);
2119 EXPECT_FALSE(did_request_commit_
);
2122 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2124 LayerTreeHostImplTopControlsTest()
2125 // Make the clip size the same as the layer (content) size so the layer is
2127 : layer_size_(10, 10),
2128 clip_size_(layer_size_
) {
2129 settings_
.calculate_top_controls_position
= true;
2130 settings_
.top_controls_height
= 50;
2133 gfx::Size(clip_size_
.width(),
2134 clip_size_
.height() + settings_
.top_controls_height
);
2137 void SetupTopControlsAndScrollLayer() {
2138 CreateHostImpl(settings_
, CreateOutputSurface());
2140 scoped_ptr
<LayerImpl
> root
=
2141 LayerImpl::Create(host_impl_
->active_tree(), 1);
2142 scoped_ptr
<LayerImpl
> root_clip
=
2143 LayerImpl::Create(host_impl_
->active_tree(), 2);
2144 root_clip
->SetBounds(clip_size_
);
2145 root
->SetScrollClipLayer(root_clip
->id());
2146 root
->SetBounds(layer_size_
);
2147 root
->SetContentBounds(layer_size_
);
2148 root
->SetPosition(gfx::PointF());
2149 root
->SetDrawsContent(false);
2150 root
->SetIsContainerForFixedPositionLayers(true);
2151 int inner_viewport_scroll_layer_id
= root
->id();
2152 int page_scale_layer_id
= root_clip
->id();
2153 root_clip
->AddChild(root
.Pass());
2154 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2155 host_impl_
->active_tree()->SetViewportLayersFromIds(
2156 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2157 // Set a viewport size that is large enough to contain both the top controls
2158 // and some content.
2159 host_impl_
->SetViewportSize(viewport_size_
);
2160 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2161 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2165 gfx::Size layer_size_
;
2166 gfx::Size clip_size_
;
2167 gfx::Size viewport_size_
;
2169 LayerTreeSettings settings_
;
2170 }; // class LayerTreeHostImplTopControlsTest
2172 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2173 SetupTopControlsAndScrollLayer();
2176 EXPECT_EQ(InputHandler::ScrollStarted
,
2177 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2179 // Make the test scroll delta a fractional amount, to verify that the
2180 // fixed container size delta is (1) non-zero, and (2) fractional, and
2181 // (3) matches the movement of the top controls.
2182 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2183 host_impl_
->top_controls_manager()->ScrollBegin();
2184 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2185 host_impl_
->top_controls_manager()->ScrollEnd();
2187 LayerImpl
* inner_viewport_scroll_layer
=
2188 host_impl_
->active_tree()->InnerViewportScrollLayer();
2189 DCHECK(inner_viewport_scroll_layer
);
2190 host_impl_
->ScrollEnd();
2191 EXPECT_EQ(top_controls_scroll_delta
,
2192 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2195 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsWithPageScale
) {
2196 SetupTopControlsAndScrollLayer();
2199 EXPECT_EQ(InputHandler::ScrollStarted
,
2200 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2202 float page_scale
= 1.5f
;
2203 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
, 1.f
, 2.f
);
2205 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.f
);
2206 gfx::Vector2dF expected_container_size_delta
=
2207 ScaleVector2d(top_controls_scroll_delta
, 1.f
/ page_scale
);
2208 host_impl_
->top_controls_manager()->ScrollBegin();
2209 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2210 host_impl_
->top_controls_manager()->ScrollEnd();
2212 LayerImpl
* inner_viewport_scroll_layer
=
2213 host_impl_
->active_tree()->InnerViewportScrollLayer();
2214 DCHECK(inner_viewport_scroll_layer
);
2215 host_impl_
->ScrollEnd();
2217 // Use a tolerance that requires the container size delta to be within 0.01
2219 double tolerance
= 0.0001;
2221 (expected_container_size_delta
-
2222 inner_viewport_scroll_layer
->FixedContainerSizeDelta()).LengthSquared(),
2226 TEST_F(LayerTreeHostImplTopControlsTest
,
2227 ScrollNonScrollableRootWithTopControls
) {
2228 SetupTopControlsAndScrollLayer();
2231 EXPECT_EQ(InputHandler::ScrollStarted
,
2232 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2234 host_impl_
->top_controls_manager()->ScrollBegin();
2235 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2236 host_impl_
->top_controls_manager()->ScrollEnd();
2237 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->content_top_offset());
2238 // Now that top controls have moved, expect the clip to resize.
2239 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2240 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2242 host_impl_
->ScrollEnd();
2244 EXPECT_EQ(InputHandler::ScrollStarted
,
2245 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2247 float scroll_increment_y
= -25.f
;
2248 host_impl_
->top_controls_manager()->ScrollBegin();
2249 host_impl_
->top_controls_manager()->ScrollBy(
2250 gfx::Vector2dF(0.f
, scroll_increment_y
));
2251 EXPECT_EQ(-scroll_increment_y
,
2252 host_impl_
->top_controls_manager()->content_top_offset());
2253 // Now that top controls have moved, expect the clip to resize.
2254 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2255 viewport_size_
.height() + scroll_increment_y
),
2256 root_clip_ptr
->bounds());
2258 host_impl_
->top_controls_manager()->ScrollBy(
2259 gfx::Vector2dF(0.f
, scroll_increment_y
));
2260 host_impl_
->top_controls_manager()->ScrollEnd();
2261 EXPECT_EQ(-2 * scroll_increment_y
,
2262 host_impl_
->top_controls_manager()->content_top_offset());
2263 // Now that top controls have moved, expect the clip to resize.
2264 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2266 host_impl_
->ScrollEnd();
2268 // Verify the layer is once-again non-scrollable.
2271 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2273 EXPECT_EQ(InputHandler::ScrollStarted
,
2274 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2277 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2278 // Test the configuration where a non-composited root layer is embedded in a
2279 // scrollable outer layer.
2280 gfx::Size
surface_size(10, 10);
2281 gfx::Size
contents_size(20, 20);
2283 scoped_ptr
<LayerImpl
> content_layer
=
2284 LayerImpl::Create(host_impl_
->active_tree(), 1);
2285 content_layer
->SetDrawsContent(true);
2286 content_layer
->SetPosition(gfx::PointF());
2287 content_layer
->SetBounds(contents_size
);
2288 content_layer
->SetContentBounds(contents_size
);
2289 content_layer
->SetContentsScale(2.f
, 2.f
);
2291 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2292 LayerImpl::Create(host_impl_
->active_tree(), 3);
2293 scroll_clip_layer
->SetBounds(surface_size
);
2295 scoped_ptr
<LayerImpl
> scroll_layer
=
2296 LayerImpl::Create(host_impl_
->active_tree(), 2);
2297 scroll_layer
->SetScrollClipLayer(3);
2298 scroll_layer
->SetBounds(contents_size
);
2299 scroll_layer
->SetContentBounds(contents_size
);
2300 scroll_layer
->SetPosition(gfx::PointF());
2301 scroll_layer
->AddChild(content_layer
.Pass());
2302 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2304 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2305 host_impl_
->SetViewportSize(surface_size
);
2308 EXPECT_EQ(InputHandler::ScrollStarted
,
2309 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2310 InputHandler::Wheel
));
2311 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2312 host_impl_
->ScrollEnd();
2313 EXPECT_TRUE(did_request_redraw_
);
2314 EXPECT_TRUE(did_request_commit_
);
2317 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2318 gfx::Size
surface_size(10, 10);
2319 gfx::Size
contents_size(20, 20);
2320 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2321 root
->SetBounds(surface_size
);
2322 root
->SetContentBounds(contents_size
);
2323 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2324 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2325 host_impl_
->SetViewportSize(surface_size
);
2328 EXPECT_EQ(InputHandler::ScrollStarted
,
2329 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2330 InputHandler::Wheel
));
2331 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2332 host_impl_
->ScrollEnd();
2333 EXPECT_TRUE(did_request_redraw_
);
2334 EXPECT_TRUE(did_request_commit_
);
2337 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2338 gfx::Size
surface_size(10, 10);
2339 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2340 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2341 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2342 host_impl_
->SetViewportSize(surface_size
);
2345 // Scroll event is ignored because the input coordinate is outside the layer
2347 EXPECT_EQ(InputHandler::ScrollIgnored
,
2348 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2349 InputHandler::Wheel
));
2350 EXPECT_FALSE(did_request_redraw_
);
2351 EXPECT_FALSE(did_request_commit_
);
2354 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2355 gfx::Size
surface_size(10, 10);
2356 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2357 scoped_ptr
<LayerImpl
> child
=
2358 CreateScrollableLayer(2, surface_size
, root
.get());
2359 host_impl_
->SetViewportSize(surface_size
);
2361 gfx::Transform matrix
;
2362 matrix
.RotateAboutXAxis(180.0);
2363 child
->SetTransform(matrix
);
2364 child
->SetDoubleSided(false);
2366 root
->AddChild(child
.Pass());
2367 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2370 // Scroll event is ignored because the scrollable layer is not facing the
2371 // viewer and there is nothing scrollable behind it.
2372 EXPECT_EQ(InputHandler::ScrollIgnored
,
2373 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2374 InputHandler::Wheel
));
2375 EXPECT_FALSE(did_request_redraw_
);
2376 EXPECT_FALSE(did_request_commit_
);
2379 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2380 gfx::Size
surface_size(10, 10);
2381 scoped_ptr
<LayerImpl
> clip_layer
=
2382 LayerImpl::Create(host_impl_
->active_tree(), 3);
2383 scoped_ptr
<LayerImpl
> content_layer
=
2384 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2385 content_layer
->SetShouldScrollOnMainThread(true);
2386 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2388 // Note: we can use the same clip layer for both since both calls to
2389 // CreateScrollableLayer() use the same surface size.
2390 scoped_ptr
<LayerImpl
> scroll_layer
=
2391 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2392 scroll_layer
->AddChild(content_layer
.Pass());
2393 clip_layer
->AddChild(scroll_layer
.Pass());
2395 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2396 host_impl_
->SetViewportSize(surface_size
);
2399 // Scrolling fails because the content layer is asking to be scrolled on the
2401 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2402 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2403 InputHandler::Wheel
));
2406 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2407 gfx::Size
surface_size(20, 20);
2408 gfx::Size
viewport_size(10, 10);
2409 float page_scale
= 2.f
;
2410 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2411 scoped_ptr
<LayerImpl
> root_clip
=
2412 LayerImpl::Create(host_impl_
->active_tree(), 2);
2413 scoped_ptr
<LayerImpl
> root_scrolling
=
2414 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2415 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2416 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2417 root_clip
->AddChild(root_scrolling
.Pass());
2418 root
->AddChild(root_clip
.Pass());
2419 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2420 // The behaviour in this test assumes the page scale is applied at a layer
2421 // above the clip layer.
2422 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2423 host_impl_
->active_tree()->DidBecomeActive();
2424 host_impl_
->SetViewportSize(viewport_size
);
2427 LayerImpl
* root_scroll
=
2428 host_impl_
->active_tree()->InnerViewportScrollLayer();
2429 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2431 gfx::Vector2d
scroll_delta(0, 10);
2432 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2433 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2434 EXPECT_EQ(InputHandler::ScrollStarted
,
2435 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2436 InputHandler::Wheel
));
2437 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2438 host_impl_
->ScrollEnd();
2440 // Set new page scale from main thread.
2441 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2445 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2446 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2448 // The scroll range should also have been updated.
2449 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2451 // The page scale delta remains constant because the impl thread did not
2453 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2456 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
2457 gfx::Size
surface_size(20, 20);
2458 gfx::Size
viewport_size(10, 10);
2459 float page_scale
= 2.f
;
2460 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2461 scoped_ptr
<LayerImpl
> root_clip
=
2462 LayerImpl::Create(host_impl_
->active_tree(), 2);
2463 scoped_ptr
<LayerImpl
> root_scrolling
=
2464 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2465 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2466 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2467 root_clip
->AddChild(root_scrolling
.Pass());
2468 root
->AddChild(root_clip
.Pass());
2469 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2470 // The behaviour in this test assumes the page scale is applied at a layer
2471 // above the clip layer.
2472 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2473 host_impl_
->active_tree()->DidBecomeActive();
2474 host_impl_
->SetViewportSize(viewport_size
);
2475 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, page_scale
);
2478 LayerImpl
* root_scroll
=
2479 host_impl_
->active_tree()->InnerViewportScrollLayer();
2480 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2482 gfx::Vector2d
scroll_delta(0, 10);
2483 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2484 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2485 EXPECT_EQ(InputHandler::ScrollStarted
,
2486 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2487 InputHandler::Wheel
));
2488 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2489 host_impl_
->ScrollEnd();
2491 // Set new page scale on impl thread by pinching.
2492 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2493 host_impl_
->PinchGestureBegin();
2494 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
2495 host_impl_
->PinchGestureEnd();
2496 host_impl_
->ScrollEnd();
2499 // The scroll delta is not scaled because the main thread did not scale.
2500 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2501 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2503 // The scroll range should also have been updated.
2504 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2506 // The page scale delta should match the new scale on the impl side.
2507 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->total_page_scale_factor());
2510 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
2511 gfx::Size
surface_size(10, 10);
2512 float default_page_scale
= 1.f
;
2513 gfx::Transform default_page_scale_matrix
;
2514 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
2516 float new_page_scale
= 2.f
;
2517 gfx::Transform new_page_scale_matrix
;
2518 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
2520 // Create a normal scrollable root layer and another scrollable child layer.
2521 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
2522 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
2523 LayerImpl
* child
= scroll
->children()[0];
2525 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
2526 LayerImpl::Create(host_impl_
->active_tree(), 6);
2527 scoped_ptr
<LayerImpl
> scrollable_child
=
2528 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
2529 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
2530 child
->AddChild(scrollable_child_clip
.Pass());
2531 LayerImpl
* grand_child
= child
->children()[0];
2533 // Set new page scale on impl thread by pinching.
2534 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2535 host_impl_
->PinchGestureBegin();
2536 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
2537 host_impl_
->PinchGestureEnd();
2538 host_impl_
->ScrollEnd();
2541 EXPECT_EQ(1.f
, root
->contents_scale_x());
2542 EXPECT_EQ(1.f
, root
->contents_scale_y());
2543 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
2544 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
2545 EXPECT_EQ(1.f
, child
->contents_scale_x());
2546 EXPECT_EQ(1.f
, child
->contents_scale_y());
2547 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
2548 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
2550 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2551 // the page scale delta on the root layer is applied hierarchically.
2552 LayerTreeHostImpl::FrameData frame
;
2553 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2554 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2555 host_impl_
->DidDrawAllLayers(frame
);
2557 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
2558 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
2559 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
2560 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
2561 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
2562 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
2563 EXPECT_EQ(new_page_scale
,
2564 grand_child
->draw_transform().matrix().getDouble(0, 0));
2565 EXPECT_EQ(new_page_scale
,
2566 grand_child
->draw_transform().matrix().getDouble(1, 1));
2569 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
2570 gfx::Size
surface_size(30, 30);
2571 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2572 root
->SetBounds(gfx::Size(5, 5));
2573 scoped_ptr
<LayerImpl
> root_scrolling
=
2574 LayerImpl::Create(host_impl_
->active_tree(), 2);
2575 root_scrolling
->SetBounds(surface_size
);
2576 root_scrolling
->SetContentBounds(surface_size
);
2577 root_scrolling
->SetScrollClipLayer(root
->id());
2578 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2579 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
2580 root
->AddChild(root_scrolling
.Pass());
2581 int child_scroll_layer_id
= 3;
2582 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
2583 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
2584 LayerImpl
* child
= child_scrolling
.get();
2585 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
2586 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2587 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2588 host_impl_
->active_tree()->DidBecomeActive();
2589 host_impl_
->SetViewportSize(surface_size
);
2592 gfx::Vector2d
scroll_delta(0, 10);
2593 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
2594 gfx::Vector2d
expected_max_scroll(child
->MaxScrollOffset());
2595 EXPECT_EQ(InputHandler::ScrollStarted
,
2596 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2597 InputHandler::Wheel
));
2598 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2599 host_impl_
->ScrollEnd();
2601 float page_scale
= 2.f
;
2602 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2608 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2610 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
2612 // The scroll range should not have changed.
2613 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
2615 // The page scale delta remains constant because the impl thread did not
2617 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2620 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
2621 // Scroll a child layer beyond its maximum scroll range and make sure the
2622 // parent layer is scrolled on the axis on which the child was unable to
2624 gfx::Size
surface_size(10, 10);
2625 gfx::Size
content_size(20, 20);
2626 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2627 root
->SetBounds(surface_size
);
2629 scoped_ptr
<LayerImpl
> grand_child
=
2630 CreateScrollableLayer(3, content_size
, root
.get());
2632 scoped_ptr
<LayerImpl
> child
=
2633 CreateScrollableLayer(2, content_size
, root
.get());
2634 LayerImpl
* grand_child_layer
= grand_child
.get();
2635 child
->AddChild(grand_child
.Pass());
2637 LayerImpl
* child_layer
= child
.get();
2638 root
->AddChild(child
.Pass());
2639 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2640 host_impl_
->active_tree()->DidBecomeActive();
2641 host_impl_
->SetViewportSize(surface_size
);
2642 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 5));
2643 child_layer
->SetScrollOffset(gfx::Vector2d(3, 0));
2647 gfx::Vector2d
scroll_delta(-8, -7);
2648 EXPECT_EQ(InputHandler::ScrollStarted
,
2649 host_impl_
->ScrollBegin(gfx::Point(),
2650 InputHandler::Wheel
));
2651 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2652 host_impl_
->ScrollEnd();
2654 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2655 host_impl_
->ProcessScrollDeltas();
2657 // The grand child should have scrolled up to its limit.
2658 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
2659 LayerImpl
* grand_child
= child
->children()[0];
2660 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
2662 // The child should have only scrolled on the other axis.
2663 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
2667 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
2668 // Scroll a child layer beyond its maximum scroll range and make sure the
2669 // the scroll doesn't bubble up to the parent layer.
2670 gfx::Size
surface_size(20, 20);
2671 gfx::Size
viewport_size(10, 10);
2672 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2673 scoped_ptr
<LayerImpl
> root_scrolling
=
2674 CreateScrollableLayer(2, surface_size
, root
.get());
2675 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2677 scoped_ptr
<LayerImpl
> grand_child
=
2678 CreateScrollableLayer(4, surface_size
, root
.get());
2680 scoped_ptr
<LayerImpl
> child
=
2681 CreateScrollableLayer(3, surface_size
, root
.get());
2682 LayerImpl
* grand_child_layer
= grand_child
.get();
2683 child
->AddChild(grand_child
.Pass());
2685 LayerImpl
* child_layer
= child
.get();
2686 root_scrolling
->AddChild(child
.Pass());
2687 root
->AddChild(root_scrolling
.Pass());
2688 EXPECT_EQ(viewport_size
, root
->bounds());
2689 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2690 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2691 host_impl_
->active_tree()->DidBecomeActive();
2692 host_impl_
->SetViewportSize(viewport_size
);
2694 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
2695 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
2699 gfx::Vector2d
scroll_delta(0, -10);
2700 EXPECT_EQ(InputHandler::ScrollStarted
,
2701 host_impl_
->ScrollBegin(gfx::Point(),
2702 InputHandler::NonBubblingGesture
));
2703 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2704 host_impl_
->ScrollEnd();
2706 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2707 host_impl_
->ProcessScrollDeltas();
2709 // The grand child should have scrolled up to its limit.
2711 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
2712 LayerImpl
* grand_child
= child
->children()[0];
2713 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2715 // The child should not have scrolled.
2716 ExpectNone(*scroll_info
.get(), child
->id());
2718 // The next time we scroll we should only scroll the parent.
2719 scroll_delta
= gfx::Vector2d(0, -3);
2720 EXPECT_EQ(InputHandler::ScrollStarted
,
2721 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2722 InputHandler::NonBubblingGesture
));
2723 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2724 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2725 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
2726 host_impl_
->ScrollEnd();
2728 scroll_info
= host_impl_
->ProcessScrollDeltas();
2730 // The child should have scrolled up to its limit.
2731 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2733 // The grand child should not have scrolled.
2734 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2736 // After scrolling the parent, another scroll on the opposite direction
2737 // should still scroll the child.
2738 scroll_delta
= gfx::Vector2d(0, 7);
2739 EXPECT_EQ(InputHandler::ScrollStarted
,
2740 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2741 InputHandler::NonBubblingGesture
));
2742 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2743 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2744 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2745 host_impl_
->ScrollEnd();
2747 scroll_info
= host_impl_
->ProcessScrollDeltas();
2749 // The grand child should have scrolled.
2750 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
2752 // The child should not have scrolled.
2753 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2756 // Scrolling should be adjusted from viewport space.
2757 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 2.f
, 2.f
);
2758 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
2760 scroll_delta
= gfx::Vector2d(0, -2);
2761 EXPECT_EQ(InputHandler::ScrollStarted
,
2762 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2763 InputHandler::NonBubblingGesture
));
2764 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
2765 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2766 host_impl_
->ScrollEnd();
2768 scroll_info
= host_impl_
->ProcessScrollDeltas();
2770 // Should have scrolled by half the amount in layer space (5 - 2/2)
2771 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
2774 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
2775 // When we try to scroll a non-scrollable child layer, the scroll delta
2776 // should be applied to one of its ancestors if possible.
2777 gfx::Size
surface_size(10, 10);
2778 gfx::Size
content_size(20, 20);
2779 scoped_ptr
<LayerImpl
> root_clip
=
2780 LayerImpl::Create(host_impl_
->active_tree(), 3);
2781 scoped_ptr
<LayerImpl
> root
=
2782 CreateScrollableLayer(1, content_size
, root_clip
.get());
2783 // Make 'root' the clip layer for child: since they have the same sizes the
2784 // child will have zero max_scroll_offset and scrolls will bubble.
2785 scoped_ptr
<LayerImpl
> child
=
2786 CreateScrollableLayer(2, content_size
, root
.get());
2787 child
->SetIsContainerForFixedPositionLayers(true);
2788 root
->SetBounds(content_size
);
2790 int root_scroll_id
= root
->id();
2791 root
->AddChild(child
.Pass());
2792 root_clip
->AddChild(root
.Pass());
2794 host_impl_
->SetViewportSize(surface_size
);
2795 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2796 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID
);
2797 host_impl_
->active_tree()->DidBecomeActive();
2800 gfx::Vector2d
scroll_delta(0, 4);
2801 EXPECT_EQ(InputHandler::ScrollStarted
,
2802 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2803 InputHandler::Wheel
));
2804 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2805 host_impl_
->ScrollEnd();
2807 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2808 host_impl_
->ProcessScrollDeltas();
2810 // Only the root scroll should have scrolled.
2811 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
2812 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
2816 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
2817 gfx::Size
surface_size(10, 10);
2818 scoped_ptr
<LayerImpl
> root_clip
=
2819 LayerImpl::Create(host_impl_
->active_tree(), 1);
2820 scoped_ptr
<LayerImpl
> root_scroll
=
2821 CreateScrollableLayer(2, surface_size
, root_clip
.get());
2822 root_scroll
->SetIsContainerForFixedPositionLayers(true);
2823 root_clip
->AddChild(root_scroll
.Pass());
2824 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2825 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2826 host_impl_
->active_tree()->DidBecomeActive();
2827 host_impl_
->SetViewportSize(surface_size
);
2829 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2832 host_impl_
->active_tree()->DetachLayerTree();
2833 scoped_ptr
<LayerImpl
> root_clip2
=
2834 LayerImpl::Create(host_impl_
->active_tree(), 3);
2835 scoped_ptr
<LayerImpl
> root_scroll2
=
2836 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
2837 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
2838 root_clip2
->AddChild(root_scroll2
.Pass());
2839 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
2840 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID
);
2841 host_impl_
->active_tree()->DidBecomeActive();
2843 // Scrolling should still work even though we did not draw yet.
2844 EXPECT_EQ(InputHandler::ScrollStarted
,
2845 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2846 InputHandler::Wheel
));
2849 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
2850 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2852 // Rotate the root layer 90 degrees counter-clockwise about its center.
2853 gfx::Transform rotate_transform
;
2854 rotate_transform
.Rotate(-90.0);
2855 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
2857 gfx::Size
surface_size(50, 50);
2858 host_impl_
->SetViewportSize(surface_size
);
2861 // Scroll to the right in screen coordinates with a gesture.
2862 gfx::Vector2d
gesture_scroll_delta(10, 0);
2863 EXPECT_EQ(InputHandler::ScrollStarted
,
2864 host_impl_
->ScrollBegin(gfx::Point(),
2865 InputHandler::Gesture
));
2866 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2867 host_impl_
->ScrollEnd();
2869 // The layer should have scrolled down in its local coordinates.
2870 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2871 ExpectContains(*scroll_info
.get(),
2873 gfx::Vector2d(0, gesture_scroll_delta
.x()));
2875 // Reset and scroll down with the wheel.
2876 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2877 gfx::Vector2d
wheel_scroll_delta(0, 10);
2878 EXPECT_EQ(InputHandler::ScrollStarted
,
2879 host_impl_
->ScrollBegin(gfx::Point(),
2880 InputHandler::Wheel
));
2881 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
2882 host_impl_
->ScrollEnd();
2884 // The layer should have scrolled down in its local coordinates.
2885 scroll_info
= host_impl_
->ProcessScrollDeltas();
2886 ExpectContains(*scroll_info
.get(),
2888 wheel_scroll_delta
);
2891 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
2892 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2893 int child_clip_layer_id
= 6;
2894 int child_layer_id
= 7;
2895 float child_layer_angle
= -20.f
;
2897 // Create a child layer that is rotated to a non-axis-aligned angle.
2898 scoped_ptr
<LayerImpl
> clip_layer
=
2899 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
2900 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
2901 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
2902 gfx::Transform rotate_transform
;
2903 rotate_transform
.Translate(-50.0, -50.0);
2904 rotate_transform
.Rotate(child_layer_angle
);
2905 rotate_transform
.Translate(50.0, 50.0);
2906 clip_layer
->SetTransform(rotate_transform
);
2908 // Only allow vertical scrolling.
2909 clip_layer
->SetBounds(
2910 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
2911 // The rotation depends on the layer's transform origin, and the child layer
2912 // is a different size than the clip, so make sure the clip layer's origin
2913 // lines up over the child.
2914 clip_layer
->SetTransformOrigin(gfx::Point3F(
2915 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
2916 LayerImpl
* child_ptr
= child
.get();
2917 clip_layer
->AddChild(child
.Pass());
2918 scroll_layer
->AddChild(clip_layer
.Pass());
2920 gfx::Size
surface_size(50, 50);
2921 host_impl_
->SetViewportSize(surface_size
);
2924 // Scroll down in screen coordinates with a gesture.
2925 gfx::Vector2d
gesture_scroll_delta(0, 10);
2926 EXPECT_EQ(InputHandler::ScrollStarted
,
2927 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2928 InputHandler::Gesture
));
2929 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2930 host_impl_
->ScrollEnd();
2932 // The child layer should have scrolled down in its local coordinates an
2933 // amount proportional to the angle between it and the input scroll delta.
2934 gfx::Vector2d
expected_scroll_delta(
2936 gesture_scroll_delta
.y() *
2937 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
2938 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2939 host_impl_
->ProcessScrollDeltas();
2940 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2942 // The root scroll layer should not have scrolled, because the input delta
2943 // was close to the layer's axis of movement.
2944 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
2947 // Now reset and scroll the same amount horizontally.
2948 child_ptr
->SetScrollDelta(gfx::Vector2dF());
2949 gfx::Vector2d
gesture_scroll_delta(10, 0);
2950 EXPECT_EQ(InputHandler::ScrollStarted
,
2951 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2952 InputHandler::Gesture
));
2953 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2954 host_impl_
->ScrollEnd();
2956 // The child layer should have scrolled down in its local coordinates an
2957 // amount proportional to the angle between it and the input scroll delta.
2958 gfx::Vector2d
expected_scroll_delta(
2960 -gesture_scroll_delta
.x() *
2961 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
2962 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2963 host_impl_
->ProcessScrollDeltas();
2964 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2966 // The root scroll layer should have scrolled more, since the input scroll
2967 // delta was mostly orthogonal to the child layer's vertical scroll axis.
2968 gfx::Vector2d
expected_root_scroll_delta(
2969 gesture_scroll_delta
.x() *
2970 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
2972 ExpectContains(*scroll_info
.get(),
2974 expected_root_scroll_delta
);
2978 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
2979 LayerImpl
* scroll_layer
=
2980 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2982 // Scale the layer to twice its normal size.
2984 gfx::Transform scale_transform
;
2985 scale_transform
.Scale(scale
, scale
);
2986 scroll_layer
->SetTransform(scale_transform
);
2988 gfx::Size
surface_size(50, 50);
2989 host_impl_
->SetViewportSize(surface_size
);
2992 // Scroll down in screen coordinates with a gesture.
2993 gfx::Vector2d
scroll_delta(0, 10);
2994 EXPECT_EQ(InputHandler::ScrollStarted
,
2995 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2996 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2997 host_impl_
->ScrollEnd();
2999 // The layer should have scrolled down in its local coordinates, but half the
3001 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
3002 ExpectContains(*scroll_info
.get(),
3004 gfx::Vector2d(0, scroll_delta
.y() / scale
));
3006 // Reset and scroll down with the wheel.
3007 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
3008 gfx::Vector2d
wheel_scroll_delta(0, 10);
3009 EXPECT_EQ(InputHandler::ScrollStarted
,
3010 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3011 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3012 host_impl_
->ScrollEnd();
3014 // The scale should not have been applied to the scroll delta.
3015 scroll_info
= host_impl_
->ProcessScrollDeltas();
3016 ExpectContains(*scroll_info
.get(),
3018 wheel_scroll_delta
);
3021 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3023 TestScrollOffsetDelegate()
3024 : page_scale_factor_(0.f
),
3025 min_page_scale_factor_(-1.f
),
3026 max_page_scale_factor_(-1.f
) {}
3028 virtual ~TestScrollOffsetDelegate() {}
3030 virtual gfx::Vector2dF
GetTotalScrollOffset() OVERRIDE
{
3031 return getter_return_value_
;
3034 virtual bool IsExternalFlingActive() const OVERRIDE
{ return false; }
3036 virtual void UpdateRootLayerState(const gfx::Vector2dF
& total_scroll_offset
,
3037 const gfx::Vector2dF
& max_scroll_offset
,
3038 const gfx::SizeF
& scrollable_size
,
3039 float page_scale_factor
,
3040 float min_page_scale_factor
,
3041 float max_page_scale_factor
) OVERRIDE
{
3042 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3043 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3044 last_set_scroll_offset_
= total_scroll_offset
;
3045 max_scroll_offset_
= max_scroll_offset
;
3046 scrollable_size_
= scrollable_size
;
3047 page_scale_factor_
= page_scale_factor
;
3048 min_page_scale_factor_
= min_page_scale_factor
;
3049 max_page_scale_factor_
= max_page_scale_factor
;
3052 gfx::Vector2dF
last_set_scroll_offset() {
3053 return last_set_scroll_offset_
;
3056 void set_getter_return_value(const gfx::Vector2dF
& value
) {
3057 getter_return_value_
= value
;
3060 gfx::Vector2dF
max_scroll_offset() const {
3061 return max_scroll_offset_
;
3064 gfx::SizeF
scrollable_size() const {
3065 return scrollable_size_
;
3068 float page_scale_factor() const {
3069 return page_scale_factor_
;
3072 float min_page_scale_factor() const {
3073 return min_page_scale_factor_
;
3076 float max_page_scale_factor() const {
3077 return max_page_scale_factor_
;
3081 gfx::Vector2dF last_set_scroll_offset_
;
3082 gfx::Vector2dF getter_return_value_
;
3083 gfx::Vector2dF max_scroll_offset_
;
3084 gfx::SizeF scrollable_size_
;
3085 float page_scale_factor_
;
3086 float min_page_scale_factor_
;
3087 float max_page_scale_factor_
;
3090 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3091 TestScrollOffsetDelegate scroll_delegate
;
3092 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3093 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3094 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3095 clip_layer
->SetBounds(gfx::Size(10, 20));
3097 // Setting the delegate results in the current scroll offset being set.
3098 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3099 scroll_layer
->SetScrollOffset(gfx::Vector2d());
3100 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3101 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3102 EXPECT_EQ(initial_scroll_delta
.ToString(),
3103 scroll_delegate
.last_set_scroll_offset().ToString());
3105 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3106 // page_scale_factor and {min|max}_page_scale_factor being set.
3107 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3108 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate
.max_scroll_offset());
3109 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3110 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3111 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3113 // Updating page scale immediately updates the delegate.
3114 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 0.5f
, 4.f
);
3115 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3116 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3117 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3118 host_impl_
->active_tree()->SetPageScaleDelta(1.5f
);
3119 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3120 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3121 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3122 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3123 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3124 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3125 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3126 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3128 // The pinch gesture doesn't put the delegate into a state where the scroll
3129 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3131 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3132 host_impl_
->PinchGestureBegin();
3133 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3134 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3135 host_impl_
->PinchGestureEnd();
3136 host_impl_
->ScrollEnd();
3138 // Scrolling should be relative to the offset as returned by the delegate.
3139 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3140 gfx::Vector2dF
current_offset(7.f
, 8.f
);
3142 scroll_delegate
.set_getter_return_value(current_offset
);
3143 EXPECT_EQ(InputHandler::ScrollStarted
,
3144 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3146 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3147 EXPECT_EQ(current_offset
+ scroll_delta
,
3148 scroll_delegate
.last_set_scroll_offset());
3150 current_offset
= gfx::Vector2dF(42.f
, 41.f
);
3151 scroll_delegate
.set_getter_return_value(current_offset
);
3152 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3153 EXPECT_EQ(current_offset
+ scroll_delta
,
3154 scroll_delegate
.last_set_scroll_offset());
3155 host_impl_
->ScrollEnd();
3156 scroll_delegate
.set_getter_return_value(gfx::Vector2dF());
3158 // Forces a full tree synchronization and ensures that the scroll delegate
3159 // sees the correct size of the new tree.
3160 gfx::Size
new_size(42, 24);
3161 host_impl_
->CreatePendingTree();
3162 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3163 host_impl_
->ActivateSyncTree();
3164 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3166 // Un-setting the delegate should propagate the delegate's current offset to
3167 // the root scrollable layer.
3168 current_offset
= gfx::Vector2dF(13.f
, 12.f
);
3169 scroll_delegate
.set_getter_return_value(current_offset
);
3170 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3172 EXPECT_EQ(current_offset
.ToString(),
3173 scroll_layer
->TotalScrollOffset().ToString());
3176 void CheckLayerScrollDelta(LayerImpl
* layer
, gfx::Vector2dF scroll_delta
) {
3177 const gfx::Transform target_space_transform
=
3178 layer
->draw_properties().target_space_transform
;
3179 EXPECT_TRUE(target_space_transform
.IsScaleOrTranslation());
3180 gfx::Point translated_point
;
3181 target_space_transform
.TransformPoint(&translated_point
);
3182 gfx::Point expected_point
= gfx::Point() - ToRoundedVector2d(scroll_delta
);
3183 EXPECT_EQ(expected_point
.ToString(), translated_point
.ToString());
3186 TEST_F(LayerTreeHostImplTest
,
3187 ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw
) {
3188 TestScrollOffsetDelegate scroll_delegate
;
3189 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3190 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3191 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3192 clip_layer
->SetBounds(gfx::Size(10, 20));
3193 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3195 // Draw first frame to clear any pending draws and check scroll.
3197 CheckLayerScrollDelta(scroll_layer
, gfx::Vector2dF(0.f
, 0.f
));
3198 EXPECT_FALSE(host_impl_
->active_tree()->needs_update_draw_properties());
3200 // Set external scroll delta on delegate and notify LayerTreeHost.
3201 gfx::Vector2dF
scroll_delta(10.f
, 10.f
);
3202 scroll_delegate
.set_getter_return_value(scroll_delta
);
3203 host_impl_
->OnRootLayerDelegatedScrollOffsetChanged();
3205 // Check scroll delta reflected in layer.
3207 CheckLayerScrollDelta(scroll_layer
, scroll_delta
);
3209 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3212 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3213 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3214 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3215 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3217 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3219 // In-bounds scrolling does not affect overscroll.
3220 EXPECT_EQ(InputHandler::ScrollStarted
,
3221 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3222 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3223 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3225 // Overscroll events are reflected immediately.
3226 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3227 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3229 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3230 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3231 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3232 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3233 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3234 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3235 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3236 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3237 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3238 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3239 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3240 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3241 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3243 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3244 // as no scroll occurs.
3245 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3246 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3247 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3248 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3249 // Overscroll resets on valid scroll.
3250 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3251 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3252 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3253 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3254 host_impl_
->ScrollEnd();
3258 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3259 // Scroll child layers beyond their maximum scroll range and make sure root
3260 // overscroll does not accumulate.
3261 gfx::Size
surface_size(10, 10);
3262 scoped_ptr
<LayerImpl
> root_clip
=
3263 LayerImpl::Create(host_impl_
->active_tree(), 4);
3264 scoped_ptr
<LayerImpl
> root
=
3265 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3267 scoped_ptr
<LayerImpl
> grand_child
=
3268 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3270 scoped_ptr
<LayerImpl
> child
=
3271 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3272 LayerImpl
* grand_child_layer
= grand_child
.get();
3273 child
->AddChild(grand_child
.Pass());
3275 LayerImpl
* child_layer
= child
.get();
3276 root
->AddChild(child
.Pass());
3277 root_clip
->AddChild(root
.Pass());
3278 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
3279 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
3280 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3281 host_impl_
->active_tree()->DidBecomeActive();
3282 host_impl_
->SetViewportSize(surface_size
);
3285 gfx::Vector2d
scroll_delta(0, -10);
3286 EXPECT_EQ(InputHandler::ScrollStarted
,
3287 host_impl_
->ScrollBegin(gfx::Point(),
3288 InputHandler::NonBubblingGesture
));
3289 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3290 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3291 host_impl_
->ScrollEnd();
3293 // The next time we scroll we should only scroll the parent, but overscroll
3294 // should still not reach the root layer.
3295 scroll_delta
= gfx::Vector2d(0, -30);
3296 EXPECT_EQ(InputHandler::ScrollStarted
,
3297 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3298 InputHandler::NonBubblingGesture
));
3299 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3300 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3301 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3302 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3303 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3304 host_impl_
->ScrollEnd();
3306 // After scrolling the parent, another scroll on the opposite direction
3307 // should scroll the child.
3308 scroll_delta
= gfx::Vector2d(0, 70);
3309 EXPECT_EQ(InputHandler::ScrollStarted
,
3310 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3311 InputHandler::NonBubblingGesture
));
3312 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3313 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3314 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3315 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3316 host_impl_
->ScrollEnd();
3320 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3321 // When we try to scroll a non-scrollable child layer, the scroll delta
3322 // should be applied to one of its ancestors if possible. Overscroll should
3323 // be reflected only when it has bubbled up to the root scrolling layer.
3324 gfx::Size
surface_size(10, 10);
3325 gfx::Size
content_size(20, 20);
3326 scoped_ptr
<LayerImpl
> root_clip
=
3327 LayerImpl::Create(host_impl_
->active_tree(), 3);
3328 scoped_ptr
<LayerImpl
> root
=
3329 CreateScrollableLayer(1, content_size
, root_clip
.get());
3330 root
->SetIsContainerForFixedPositionLayers(true);
3331 scoped_ptr
<LayerImpl
> child
=
3332 CreateScrollableLayer(2, content_size
, root_clip
.get());
3334 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3335 root
->AddChild(child
.Pass());
3336 root_clip
->AddChild(root
.Pass());
3338 host_impl_
->SetViewportSize(surface_size
);
3339 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3340 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3341 host_impl_
->active_tree()->DidBecomeActive();
3344 gfx::Vector2d
scroll_delta(0, 8);
3345 EXPECT_EQ(InputHandler::ScrollStarted
,
3346 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3347 InputHandler::Wheel
));
3348 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3349 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3350 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3351 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
3352 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3353 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
3354 host_impl_
->ScrollEnd();
3358 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
3359 LayerTreeSettings settings
;
3360 CreateHostImpl(settings
, CreateOutputSurface());
3362 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
3363 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3364 clip_layer
->SetBounds(gfx::Size(50, 50));
3365 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3366 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3368 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3370 // Even though the layer can't scroll the overscroll still happens.
3371 EXPECT_EQ(InputHandler::ScrollStarted
,
3372 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3373 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3374 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3377 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
3378 gfx::Size
surface_size(980, 1439);
3379 gfx::Size
content_size(980, 1438);
3380 float device_scale_factor
= 1.5f
;
3381 scoped_ptr
<LayerImpl
> root_clip
=
3382 LayerImpl::Create(host_impl_
->active_tree(), 3);
3383 scoped_ptr
<LayerImpl
> root
=
3384 CreateScrollableLayer(1, content_size
, root_clip
.get());
3385 root
->SetIsContainerForFixedPositionLayers(true);
3386 scoped_ptr
<LayerImpl
> child
=
3387 CreateScrollableLayer(2, content_size
, root_clip
.get());
3388 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
3389 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
3390 0.326531f
, 0.326531f
, 5.f
);
3391 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3392 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3393 root
->AddChild(child
.Pass());
3394 root_clip
->AddChild(root
.Pass());
3396 host_impl_
->SetViewportSize(surface_size
);
3397 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
3398 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3399 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3400 host_impl_
->active_tree()->DidBecomeActive();
3403 // Horizontal & Vertical GlowEffect should not be applied when
3404 // content size is less then view port size. For Example Horizontal &
3405 // vertical GlowEffect should not be applied in about:blank page.
3406 EXPECT_EQ(InputHandler::ScrollStarted
,
3407 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3408 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
3409 EXPECT_EQ(gfx::Vector2dF().ToString(),
3410 host_impl_
->accumulated_root_overscroll().ToString());
3412 host_impl_
->ScrollEnd();
3416 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
3417 gfx::Size
surface_size(100, 100);
3418 gfx::Size
content_size(200, 200);
3419 scoped_ptr
<LayerImpl
> root_clip
=
3420 LayerImpl::Create(host_impl_
->active_tree(), 3);
3421 scoped_ptr
<LayerImpl
> root
=
3422 CreateScrollableLayer(1, content_size
, root_clip
.get());
3423 root
->SetIsContainerForFixedPositionLayers(true);
3424 scoped_ptr
<LayerImpl
> child
=
3425 CreateScrollableLayer(2, content_size
, root_clip
.get());
3427 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3428 root
->AddChild(child
.Pass());
3429 root_clip
->AddChild(root
.Pass());
3431 host_impl_
->SetViewportSize(surface_size
);
3432 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3433 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3434 host_impl_
->active_tree()->DidBecomeActive();
3437 // Edge glow effect should be applicable only upon reaching Edges
3438 // of the content. unnecessary glow effect calls shouldn't be
3439 // called while scrolling up without reaching the edge of the content.
3440 EXPECT_EQ(InputHandler::ScrollStarted
,
3441 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3442 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
3443 EXPECT_EQ(gfx::Vector2dF().ToString(),
3444 host_impl_
->accumulated_root_overscroll().ToString());
3445 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
3446 EXPECT_EQ(gfx::Vector2dF().ToString(),
3447 host_impl_
->accumulated_root_overscroll().ToString());
3448 host_impl_
->ScrollEnd();
3449 // unusedrootDelta should be subtracted from applied delta so that
3450 // unwanted glow effect calls are not called.
3451 EXPECT_EQ(InputHandler::ScrollStarted
,
3452 host_impl_
->ScrollBegin(gfx::Point(0, 0),
3453 InputHandler::NonBubblingGesture
));
3454 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
3455 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
3456 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3457 host_impl_
->accumulated_root_overscroll().ToString());
3459 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
3460 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3461 host_impl_
->accumulated_root_overscroll().ToString());
3462 host_impl_
->ScrollEnd();
3463 // TestCase to check kEpsilon, which prevents minute values to trigger
3464 // gloweffect without reaching edge.
3465 EXPECT_EQ(InputHandler::ScrollStarted
,
3466 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3467 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
3468 EXPECT_EQ(gfx::Vector2dF().ToString(),
3469 host_impl_
->accumulated_root_overscroll().ToString());
3470 host_impl_
->ScrollEnd();
3474 class BlendStateCheckLayer
: public LayerImpl
{
3476 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
3478 ResourceProvider
* resource_provider
) {
3479 return scoped_ptr
<LayerImpl
>(new BlendStateCheckLayer(tree_impl
,
3481 resource_provider
));
3484 virtual void AppendQuads(RenderPass
* render_pass
,
3485 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
3486 AppendQuadsData
* append_quads_data
) OVERRIDE
{
3487 quads_appended_
= true;
3489 gfx::Rect opaque_rect
;
3490 if (contents_opaque())
3491 opaque_rect
= quad_rect_
;
3493 opaque_rect
= opaque_content_rect_
;
3494 gfx::Rect visible_quad_rect
= quad_rect_
;
3496 SharedQuadState
* shared_quad_state
=
3497 render_pass
->CreateAndAppendSharedQuadState();
3498 PopulateSharedQuadState(shared_quad_state
);
3500 scoped_ptr
<TileDrawQuad
> test_blending_draw_quad
= TileDrawQuad::Create();
3501 test_blending_draw_quad
->SetNew(shared_quad_state
,
3506 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
3509 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
3510 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
3511 EXPECT_EQ(has_render_surface_
, !!render_surface());
3512 render_pass
->AppendDrawQuad(test_blending_draw_quad
.PassAs
<DrawQuad
>());
3515 void SetExpectation(bool blend
, bool has_render_surface
) {
3517 has_render_surface_
= has_render_surface
;
3518 quads_appended_
= false;
3521 bool quads_appended() const { return quads_appended_
; }
3523 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
3524 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
3525 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
3526 opaque_content_rect_
= rect
;
3530 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
3532 ResourceProvider
* resource_provider
)
3533 : LayerImpl(tree_impl
, id
),
3535 has_render_surface_(false),
3536 quads_appended_(false),
3537 quad_rect_(5, 5, 5, 5),
3538 quad_visible_rect_(5, 5, 5, 5),
3539 resource_id_(resource_provider
->CreateResource(
3542 ResourceProvider::TextureUsageAny
,
3544 resource_provider
->AllocateForTesting(resource_id_
);
3545 SetBounds(gfx::Size(10, 10));
3546 SetContentBounds(gfx::Size(10, 10));
3547 SetDrawsContent(true);
3551 bool has_render_surface_
;
3552 bool quads_appended_
;
3553 gfx::Rect quad_rect_
;
3554 gfx::Rect opaque_content_rect_
;
3555 gfx::Rect quad_visible_rect_
;
3556 ResourceProvider::ResourceId resource_id_
;
3559 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
3561 scoped_ptr
<LayerImpl
> root
=
3562 LayerImpl::Create(host_impl_
->active_tree(), 1);
3563 root
->SetBounds(gfx::Size(10, 10));
3564 root
->SetContentBounds(root
->bounds());
3565 root
->SetDrawsContent(false);
3566 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3568 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3571 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3573 host_impl_
->resource_provider()));
3574 BlendStateCheckLayer
* layer1
=
3575 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
3576 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
3578 LayerTreeHostImpl::FrameData frame
;
3580 // Opaque layer, drawn without blending.
3581 layer1
->SetContentsOpaque(true);
3582 layer1
->SetExpectation(false, false);
3583 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3584 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3585 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3586 EXPECT_TRUE(layer1
->quads_appended());
3587 host_impl_
->DidDrawAllLayers(frame
);
3589 // Layer with translucent content and painting, so drawn with blending.
3590 layer1
->SetContentsOpaque(false);
3591 layer1
->SetExpectation(true, false);
3592 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3593 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3594 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3595 EXPECT_TRUE(layer1
->quads_appended());
3596 host_impl_
->DidDrawAllLayers(frame
);
3598 // Layer with translucent opacity, drawn with blending.
3599 layer1
->SetContentsOpaque(true);
3600 layer1
->SetOpacity(0.5f
);
3601 layer1
->SetExpectation(true, false);
3602 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3603 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3604 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3605 EXPECT_TRUE(layer1
->quads_appended());
3606 host_impl_
->DidDrawAllLayers(frame
);
3608 // Layer with translucent opacity and painting, drawn with blending.
3609 layer1
->SetContentsOpaque(true);
3610 layer1
->SetOpacity(0.5f
);
3611 layer1
->SetExpectation(true, false);
3612 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3613 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3614 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3615 EXPECT_TRUE(layer1
->quads_appended());
3616 host_impl_
->DidDrawAllLayers(frame
);
3619 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3621 host_impl_
->resource_provider()));
3622 BlendStateCheckLayer
* layer2
=
3623 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
3624 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
3626 // 2 opaque layers, drawn without blending.
3627 layer1
->SetContentsOpaque(true);
3628 layer1
->SetOpacity(1.f
);
3629 layer1
->SetExpectation(false, false);
3630 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3631 layer2
->SetContentsOpaque(true);
3632 layer2
->SetOpacity(1.f
);
3633 layer2
->SetExpectation(false, false);
3634 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3635 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3636 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3637 EXPECT_TRUE(layer1
->quads_appended());
3638 EXPECT_TRUE(layer2
->quads_appended());
3639 host_impl_
->DidDrawAllLayers(frame
);
3641 // Parent layer with translucent content, drawn with blending.
3642 // Child layer with opaque content, drawn without blending.
3643 layer1
->SetContentsOpaque(false);
3644 layer1
->SetExpectation(true, false);
3645 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3646 layer2
->SetExpectation(false, false);
3647 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3648 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3649 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3650 EXPECT_TRUE(layer1
->quads_appended());
3651 EXPECT_TRUE(layer2
->quads_appended());
3652 host_impl_
->DidDrawAllLayers(frame
);
3654 // Parent layer with translucent content but opaque painting, drawn without
3656 // Child layer with opaque content, drawn without blending.
3657 layer1
->SetContentsOpaque(true);
3658 layer1
->SetExpectation(false, false);
3659 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3660 layer2
->SetExpectation(false, false);
3661 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3662 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3663 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3664 EXPECT_TRUE(layer1
->quads_appended());
3665 EXPECT_TRUE(layer2
->quads_appended());
3666 host_impl_
->DidDrawAllLayers(frame
);
3668 // Parent layer with translucent opacity and opaque content. Since it has a
3669 // drawing child, it's drawn to a render surface which carries the opacity,
3670 // so it's itself drawn without blending.
3671 // Child layer with opaque content, drawn without blending (parent surface
3672 // carries the inherited opacity).
3673 layer1
->SetContentsOpaque(true);
3674 layer1
->SetOpacity(0.5f
);
3675 layer1
->SetExpectation(false, true);
3676 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3677 layer2
->SetExpectation(false, false);
3678 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3679 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3680 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3681 EXPECT_TRUE(layer1
->quads_appended());
3682 EXPECT_TRUE(layer2
->quads_appended());
3683 host_impl_
->DidDrawAllLayers(frame
);
3685 // Draw again, but with child non-opaque, to make sure
3686 // layer1 not culled.
3687 layer1
->SetContentsOpaque(true);
3688 layer1
->SetOpacity(1.f
);
3689 layer1
->SetExpectation(false, false);
3690 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3691 layer2
->SetContentsOpaque(true);
3692 layer2
->SetOpacity(0.5f
);
3693 layer2
->SetExpectation(true, false);
3694 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3695 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3696 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3697 EXPECT_TRUE(layer1
->quads_appended());
3698 EXPECT_TRUE(layer2
->quads_appended());
3699 host_impl_
->DidDrawAllLayers(frame
);
3701 // A second way of making the child non-opaque.
3702 layer1
->SetContentsOpaque(true);
3703 layer1
->SetOpacity(1.f
);
3704 layer1
->SetExpectation(false, false);
3705 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3706 layer2
->SetContentsOpaque(false);
3707 layer2
->SetOpacity(1.f
);
3708 layer2
->SetExpectation(true, false);
3709 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3710 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3711 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3712 EXPECT_TRUE(layer1
->quads_appended());
3713 EXPECT_TRUE(layer2
->quads_appended());
3714 host_impl_
->DidDrawAllLayers(frame
);
3716 // And when the layer says its not opaque but is painted opaque, it is not
3718 layer1
->SetContentsOpaque(true);
3719 layer1
->SetOpacity(1.f
);
3720 layer1
->SetExpectation(false, false);
3721 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3722 layer2
->SetContentsOpaque(true);
3723 layer2
->SetOpacity(1.f
);
3724 layer2
->SetExpectation(false, false);
3725 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3726 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3727 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3728 EXPECT_TRUE(layer1
->quads_appended());
3729 EXPECT_TRUE(layer2
->quads_appended());
3730 host_impl_
->DidDrawAllLayers(frame
);
3732 // Layer with partially opaque contents, drawn with blending.
3733 layer1
->SetContentsOpaque(false);
3734 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3735 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
3736 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3737 layer1
->SetExpectation(true, false);
3738 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3739 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3740 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3741 EXPECT_TRUE(layer1
->quads_appended());
3742 host_impl_
->DidDrawAllLayers(frame
);
3744 // Layer with partially opaque contents partially culled, drawn with blending.
3745 layer1
->SetContentsOpaque(false);
3746 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3747 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3748 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3749 layer1
->SetExpectation(true, false);
3750 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3751 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3752 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3753 EXPECT_TRUE(layer1
->quads_appended());
3754 host_impl_
->DidDrawAllLayers(frame
);
3756 // Layer with partially opaque contents culled, drawn with blending.
3757 layer1
->SetContentsOpaque(false);
3758 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3759 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3760 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3761 layer1
->SetExpectation(true, false);
3762 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3763 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3764 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3765 EXPECT_TRUE(layer1
->quads_appended());
3766 host_impl_
->DidDrawAllLayers(frame
);
3768 // Layer with partially opaque contents and translucent contents culled, drawn
3769 // without blending.
3770 layer1
->SetContentsOpaque(false);
3771 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3772 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3773 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3774 layer1
->SetExpectation(false, false);
3775 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3776 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3777 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3778 EXPECT_TRUE(layer1
->quads_appended());
3779 host_impl_
->DidDrawAllLayers(frame
);
3782 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
3784 LayerTreeHostImplViewportCoveredTest() :
3785 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
3787 did_activate_pending_tree_(false) {}
3789 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
3791 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d()
3792 .PassAs
<OutputSurface
>();
3794 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
3797 void SetupActiveTreeLayers() {
3798 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
3799 host_impl_
->active_tree()->SetRootLayer(
3800 LayerImpl::Create(host_impl_
->active_tree(), 1));
3801 host_impl_
->active_tree()->root_layer()->AddChild(
3802 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3804 host_impl_
->resource_provider()));
3805 child_
= static_cast<BlendStateCheckLayer
*>(
3806 host_impl_
->active_tree()->root_layer()->children()[0]);
3807 child_
->SetExpectation(false, false);
3808 child_
->SetContentsOpaque(true);
3811 // Expect no gutter rects.
3812 void TestLayerCoversFullViewport() {
3813 gfx::Rect
layer_rect(viewport_size_
);
3814 child_
->SetPosition(layer_rect
.origin());
3815 child_
->SetBounds(layer_rect
.size());
3816 child_
->SetContentBounds(layer_rect
.size());
3817 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3818 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3820 LayerTreeHostImpl::FrameData frame
;
3821 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3822 ASSERT_EQ(1u, frame
.render_passes
.size());
3824 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3825 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3826 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3828 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3829 host_impl_
->DidDrawAllLayers(frame
);
3832 // Expect fullscreen gutter rect.
3833 void TestEmptyLayer() {
3834 gfx::Rect
layer_rect(0, 0, 0, 0);
3835 child_
->SetPosition(layer_rect
.origin());
3836 child_
->SetBounds(layer_rect
.size());
3837 child_
->SetContentBounds(layer_rect
.size());
3838 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3839 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3841 LayerTreeHostImpl::FrameData frame
;
3842 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3843 ASSERT_EQ(1u, frame
.render_passes
.size());
3845 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3846 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3847 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3849 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3850 host_impl_
->DidDrawAllLayers(frame
);
3853 // Expect four surrounding gutter rects.
3854 void TestLayerInMiddleOfViewport() {
3855 gfx::Rect
layer_rect(500, 500, 200, 200);
3856 child_
->SetPosition(layer_rect
.origin());
3857 child_
->SetBounds(layer_rect
.size());
3858 child_
->SetContentBounds(layer_rect
.size());
3859 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3860 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3862 LayerTreeHostImpl::FrameData frame
;
3863 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3864 ASSERT_EQ(1u, frame
.render_passes
.size());
3866 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3867 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
3868 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3870 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3871 host_impl_
->DidDrawAllLayers(frame
);
3874 // Expect no gutter rects.
3875 void TestLayerIsLargerThanViewport() {
3876 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
3877 viewport_size_
.height() + 10);
3878 child_
->SetPosition(layer_rect
.origin());
3879 child_
->SetBounds(layer_rect
.size());
3880 child_
->SetContentBounds(layer_rect
.size());
3881 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3882 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3884 LayerTreeHostImpl::FrameData frame
;
3885 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3886 ASSERT_EQ(1u, frame
.render_passes
.size());
3888 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3889 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3890 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3892 host_impl_
->DidDrawAllLayers(frame
);
3895 virtual void DidActivateSyncTree() OVERRIDE
{
3896 did_activate_pending_tree_
= true;
3899 void set_gutter_quad_material(DrawQuad::Material material
) {
3900 gutter_quad_material_
= material
;
3902 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
3903 gutter_texture_size_
= gutter_texture_size
;
3907 size_t CountGutterQuads(const QuadList
& quad_list
) {
3908 size_t num_gutter_quads
= 0;
3909 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3910 num_gutter_quads
+= (quad_list
[i
]->material
==
3911 gutter_quad_material_
) ? 1 : 0;
3913 return num_gutter_quads
;
3916 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
3917 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3918 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
3921 // Make sure that the texture coordinates match their expectations.
3922 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
3923 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3924 if (quad_list
[i
]->material
!= DrawQuad::TEXTURE_CONTENT
)
3926 const TextureDrawQuad
* quad
= TextureDrawQuad::MaterialCast(quad_list
[i
]);
3927 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
3928 gutter_texture_size_
, host_impl_
->device_scale_factor());
3929 EXPECT_EQ(quad
->uv_top_left
.x(),
3930 quad
->rect
.x() / gutter_texture_size_pixels
.width());
3931 EXPECT_EQ(quad
->uv_top_left
.y(),
3932 quad
->rect
.y() / gutter_texture_size_pixels
.height());
3933 EXPECT_EQ(quad
->uv_bottom_right
.x(),
3934 quad
->rect
.right() / gutter_texture_size_pixels
.width());
3935 EXPECT_EQ(quad
->uv_bottom_right
.y(),
3936 quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
3940 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
3941 return gfx::ToRoundedSize(
3942 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
3945 DrawQuad::Material gutter_quad_material_
;
3946 gfx::Size gutter_texture_size_
;
3947 gfx::Size viewport_size_
;
3948 BlendStateCheckLayer
* child_
;
3949 bool did_activate_pending_tree_
;
3952 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
3953 viewport_size_
= gfx::Size(1000, 1000);
3955 bool always_draw
= false;
3956 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3958 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3959 SetupActiveTreeLayers();
3960 TestLayerCoversFullViewport();
3962 TestLayerInMiddleOfViewport();
3963 TestLayerIsLargerThanViewport();
3966 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
3967 viewport_size_
= gfx::Size(1000, 1000);
3969 bool always_draw
= false;
3970 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3972 host_impl_
->SetDeviceScaleFactor(2.f
);
3973 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3974 SetupActiveTreeLayers();
3975 TestLayerCoversFullViewport();
3977 TestLayerInMiddleOfViewport();
3978 TestLayerIsLargerThanViewport();
3981 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
3982 viewport_size_
= gfx::Size(1000, 1000);
3984 bool always_draw
= false;
3985 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3987 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3988 SetupActiveTreeLayers();
3990 // Specify an overhang bitmap to use.
3991 bool is_opaque
= false;
3992 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
3993 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
3994 UIResourceId ui_resource_id
= 12345;
3995 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
3996 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
3997 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
3998 set_gutter_texture_size(gfx::Size(32, 32));
4000 TestLayerCoversFullViewport();
4002 TestLayerInMiddleOfViewport();
4003 TestLayerIsLargerThanViewport();
4005 // Change the resource size.
4006 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
4007 set_gutter_texture_size(gfx::Size(128, 16));
4009 TestLayerCoversFullViewport();
4011 TestLayerInMiddleOfViewport();
4012 TestLayerIsLargerThanViewport();
4014 // Change the device scale factor
4015 host_impl_
->SetDeviceScaleFactor(2.f
);
4016 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4018 TestLayerCoversFullViewport();
4020 TestLayerInMiddleOfViewport();
4021 TestLayerIsLargerThanViewport();
4024 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
4025 viewport_size_
= gfx::Size(1000, 1000);
4027 bool always_draw
= true;
4028 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4030 // Pending tree to force active_tree size invalid. Not used otherwise.
4031 host_impl_
->CreatePendingTree();
4032 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4033 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4035 SetupActiveTreeLayers();
4037 TestLayerInMiddleOfViewport();
4038 TestLayerIsLargerThanViewport();
4041 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
4042 viewport_size_
= gfx::Size(1000, 1000);
4044 bool always_draw
= true;
4045 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4047 // Set larger viewport and activate it to active tree.
4048 host_impl_
->CreatePendingTree();
4049 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4050 viewport_size_
.height() + 100);
4051 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4052 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4053 host_impl_
->ActivateSyncTree();
4054 EXPECT_TRUE(did_activate_pending_tree_
);
4055 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4057 // Shrink pending tree viewport without activating.
4058 host_impl_
->CreatePendingTree();
4059 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4060 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4062 SetupActiveTreeLayers();
4064 TestLayerInMiddleOfViewport();
4065 TestLayerIsLargerThanViewport();
4068 class FakeDrawableLayerImpl
: public LayerImpl
{
4070 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4071 return scoped_ptr
<LayerImpl
>(new FakeDrawableLayerImpl(tree_impl
, id
));
4074 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4075 : LayerImpl(tree_impl
, id
) {}
4078 // Only reshape when we know we are going to draw. Otherwise, the reshape
4079 // can leave the window at the wrong size if we never draw and the proper
4080 // viewport size is never set.
4081 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4082 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4083 scoped_ptr
<OutputSurface
> output_surface(
4084 FakeOutputSurface::Create3d(provider
));
4085 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4087 scoped_ptr
<LayerImpl
> root
=
4088 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4089 root
->SetBounds(gfx::Size(10, 10));
4090 root
->SetContentBounds(gfx::Size(10, 10));
4091 root
->SetDrawsContent(true);
4092 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4093 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4094 provider
->TestContext3d()->clear_reshape_called();
4096 LayerTreeHostImpl::FrameData frame
;
4097 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4098 host_impl_
->SetDeviceScaleFactor(1.f
);
4099 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4100 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4101 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4102 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4103 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4104 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4105 host_impl_
->DidDrawAllLayers(frame
);
4106 provider
->TestContext3d()->clear_reshape_called();
4108 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4109 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4110 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4111 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4112 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4113 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4114 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4115 host_impl_
->DidDrawAllLayers(frame
);
4116 provider
->TestContext3d()->clear_reshape_called();
4118 host_impl_
->SetDeviceScaleFactor(2.f
);
4119 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4120 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4121 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4122 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4123 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4124 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4125 host_impl_
->DidDrawAllLayers(frame
);
4126 provider
->TestContext3d()->clear_reshape_called();
4129 // Make sure damage tracking propagates all the way to the graphics context,
4130 // where it should request to swap only the sub-buffer that is damaged.
4131 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4132 scoped_refptr
<TestContextProvider
> context_provider(
4133 TestContextProvider::Create());
4134 context_provider
->BindToCurrentThread();
4135 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4137 scoped_ptr
<OutputSurface
> output_surface(
4138 FakeOutputSurface::Create3d(context_provider
));
4140 // This test creates its own LayerTreeHostImpl, so
4141 // that we can force partial swap enabled.
4142 LayerTreeSettings settings
;
4143 settings
.partial_swap_enabled
= true;
4144 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4145 new TestSharedBitmapManager());
4146 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4147 LayerTreeHostImpl::Create(settings
,
4150 &stats_instrumentation_
,
4151 shared_bitmap_manager
.get(),
4153 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4154 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4156 scoped_ptr
<LayerImpl
> root
=
4157 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4158 scoped_ptr
<LayerImpl
> child
=
4159 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4160 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4161 child
->SetBounds(gfx::Size(14, 15));
4162 child
->SetContentBounds(gfx::Size(14, 15));
4163 child
->SetDrawsContent(true);
4164 root
->SetBounds(gfx::Size(500, 500));
4165 root
->SetContentBounds(gfx::Size(500, 500));
4166 root
->SetDrawsContent(true);
4167 root
->AddChild(child
.Pass());
4168 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4170 LayerTreeHostImpl::FrameData frame
;
4172 // First frame, the entire screen should get swapped.
4173 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4174 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4175 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4176 layer_tree_host_impl
->SwapBuffers(frame
);
4177 EXPECT_EQ(TestContextSupport::SWAP
,
4178 context_provider
->support()->last_swap_type());
4180 // Second frame, only the damaged area should get swapped. Damage should be
4181 // the union of old and new child rects.
4182 // expected damage rect: gfx::Rect(26, 28);
4183 // expected swap rect: vertically flipped, with origin at bottom left corner.
4184 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4186 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4187 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4188 host_impl_
->DidDrawAllLayers(frame
);
4189 layer_tree_host_impl
->SwapBuffers(frame
);
4191 // Make sure that partial swap is constrained to the viewport dimensions
4192 // expected damage rect: gfx::Rect(500, 500);
4193 // expected swap rect: flipped damage rect, but also clamped to viewport
4194 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP
,
4195 context_provider
->support()->last_swap_type());
4196 gfx::Rect
expected_swap_rect(0, 500-28, 26, 28);
4197 EXPECT_EQ(expected_swap_rect
.ToString(),
4198 context_provider
->support()->
4199 last_partial_swap_rect().ToString());
4201 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4202 // This will damage everything.
4203 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4205 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4206 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4207 host_impl_
->DidDrawAllLayers(frame
);
4208 layer_tree_host_impl
->SwapBuffers(frame
);
4210 EXPECT_EQ(TestContextSupport::SWAP
,
4211 context_provider
->support()->last_swap_type());
4214 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4215 scoped_ptr
<LayerImpl
> root
=
4216 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4217 scoped_ptr
<LayerImpl
> child
=
4218 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4219 child
->SetBounds(gfx::Size(10, 10));
4220 child
->SetContentBounds(gfx::Size(10, 10));
4221 child
->SetDrawsContent(true);
4222 root
->SetBounds(gfx::Size(10, 10));
4223 root
->SetContentBounds(gfx::Size(10, 10));
4224 root
->SetDrawsContent(true);
4225 root
->SetForceRenderSurface(true);
4226 root
->AddChild(child
.Pass());
4228 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4230 LayerTreeHostImpl::FrameData frame
;
4232 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4233 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4234 EXPECT_EQ(1u, frame
.render_passes
.size());
4235 host_impl_
->DidDrawAllLayers(frame
);
4238 class FakeLayerWithQuads
: public LayerImpl
{
4240 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4241 return scoped_ptr
<LayerImpl
>(new FakeLayerWithQuads(tree_impl
, id
));
4244 virtual void AppendQuads(RenderPass
* render_pass
,
4245 const OcclusionTracker
<LayerImpl
>& occlusion_tracker
,
4246 AppendQuadsData
* append_quads_data
) OVERRIDE
{
4247 SharedQuadState
* shared_quad_state
=
4248 render_pass
->CreateAndAppendSharedQuadState();
4249 PopulateSharedQuadState(shared_quad_state
);
4251 SkColor gray
= SkColorSetRGB(100, 100, 100);
4252 gfx::Rect
quad_rect(content_bounds());
4253 gfx::Rect
visible_quad_rect(quad_rect
);
4254 scoped_ptr
<SolidColorDrawQuad
> my_quad
= SolidColorDrawQuad::Create();
4256 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4257 render_pass
->AppendDrawQuad(my_quad
.PassAs
<DrawQuad
>());
4261 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4262 : LayerImpl(tree_impl
, id
) {}
4265 class MockContext
: public TestWebGraphicsContext3D
{
4267 MOCK_METHOD1(useProgram
, void(GLuint program
));
4268 MOCK_METHOD5(uniform4f
, void(GLint location
,
4273 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4275 GLboolean transpose
,
4276 const GLfloat
* value
));
4277 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4281 MOCK_METHOD1(enable
, void(GLenum cap
));
4282 MOCK_METHOD1(disable
, void(GLenum cap
));
4283 MOCK_METHOD4(scissor
, void(GLint x
,
4289 class MockContextHarness
{
4291 MockContext
* context_
;
4294 explicit MockContextHarness(MockContext
* context
)
4295 : context_(context
) {
4296 context_
->set_have_post_sub_buffer(true);
4298 // Catch "uninteresting" calls
4299 EXPECT_CALL(*context_
, useProgram(_
))
4302 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4305 // These are not asserted
4306 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4307 .WillRepeatedly(Return());
4309 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4310 .WillRepeatedly(Return());
4312 // Any un-sanctioned calls to enable() are OK
4313 EXPECT_CALL(*context_
, enable(_
))
4314 .WillRepeatedly(Return());
4316 // Any un-sanctioned calls to disable() are OK
4317 EXPECT_CALL(*context_
, disable(_
))
4318 .WillRepeatedly(Return());
4321 void MustDrawSolidQuad() {
4322 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
4324 .RetiresOnSaturation();
4326 EXPECT_CALL(*context_
, useProgram(_
))
4328 .RetiresOnSaturation();
4331 void MustSetScissor(int x
, int y
, int width
, int height
) {
4332 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4333 .WillRepeatedly(Return());
4335 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
4337 .WillRepeatedly(Return());
4340 void MustSetNoScissor() {
4341 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
4342 .WillRepeatedly(Return());
4344 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4347 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
4352 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
4353 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
4354 MockContext
* mock_context
= mock_context_owned
.get();
4356 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4357 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4358 MockContextHarness
harness(mock_context
);
4361 LayerTreeSettings settings
= DefaultSettings();
4362 settings
.partial_swap_enabled
= false;
4363 CreateHostImpl(settings
, output_surface
.Pass());
4364 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4366 // Without partial swap, and no clipping, no scissor is set.
4367 harness
.MustDrawSolidQuad();
4368 harness
.MustSetNoScissor();
4370 LayerTreeHostImpl::FrameData frame
;
4371 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4372 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4373 host_impl_
->DidDrawAllLayers(frame
);
4375 Mock::VerifyAndClearExpectations(&mock_context
);
4377 // Without partial swap, but a layer does clip its subtree, one scissor is
4379 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
4380 harness
.MustDrawSolidQuad();
4381 harness
.MustSetScissor(0, 0, 10, 10);
4383 LayerTreeHostImpl::FrameData frame
;
4384 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4385 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4386 host_impl_
->DidDrawAllLayers(frame
);
4388 Mock::VerifyAndClearExpectations(&mock_context
);
4391 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
4392 scoped_ptr
<MockContext
> context_owned(new MockContext
);
4393 MockContext
* mock_context
= context_owned
.get();
4394 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4395 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4396 MockContextHarness
harness(mock_context
);
4398 LayerTreeSettings settings
= DefaultSettings();
4399 settings
.partial_swap_enabled
= true;
4400 CreateHostImpl(settings
, output_surface
.Pass());
4401 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4403 // The first frame is not a partially-swapped one.
4404 harness
.MustSetScissor(0, 0, 10, 10);
4405 harness
.MustDrawSolidQuad();
4407 LayerTreeHostImpl::FrameData frame
;
4408 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4409 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4410 host_impl_
->DidDrawAllLayers(frame
);
4412 Mock::VerifyAndClearExpectations(&mock_context
);
4414 // Damage a portion of the frame.
4415 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
4416 gfx::Rect(0, 0, 2, 3));
4418 // The second frame will be partially-swapped (the y coordinates are flipped).
4419 harness
.MustSetScissor(0, 7, 2, 3);
4420 harness
.MustDrawSolidQuad();
4422 LayerTreeHostImpl::FrameData frame
;
4423 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4424 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4425 host_impl_
->DidDrawAllLayers(frame
);
4427 Mock::VerifyAndClearExpectations(&mock_context
);
4430 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
4432 LayerTreeHostImplClient
* client
,
4434 SharedBitmapManager
* manager
,
4435 RenderingStatsInstrumentation
* stats_instrumentation
) {
4436 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4437 scoped_ptr
<OutputSurface
> output_surface(
4438 FakeOutputSurface::Create3d(provider
));
4439 provider
->BindToCurrentThread();
4440 provider
->TestContext3d()->set_have_post_sub_buffer(true);
4442 LayerTreeSettings settings
;
4443 settings
.partial_swap_enabled
= partial_swap
;
4444 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
4445 settings
, client
, proxy
, stats_instrumentation
, manager
, 0);
4446 my_host_impl
->InitializeRenderer(output_surface
.Pass());
4447 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
4450 Layers are created as follows:
4452 +--------------------+
4456 | | +-------------------+
4458 | | +-------------------+
4463 +--------------------+
4465 Layers 1, 2 have render surfaces
4467 scoped_ptr
<LayerImpl
> root
=
4468 LayerImpl::Create(my_host_impl
->active_tree(), 1);
4469 scoped_ptr
<LayerImpl
> child
=
4470 LayerImpl::Create(my_host_impl
->active_tree(), 2);
4471 scoped_ptr
<LayerImpl
> grand_child
=
4472 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
4474 gfx::Rect
root_rect(0, 0, 100, 100);
4475 gfx::Rect
child_rect(10, 10, 50, 50);
4476 gfx::Rect
grand_child_rect(5, 5, 150, 150);
4478 root
->CreateRenderSurface();
4479 root
->SetPosition(root_rect
.origin());
4480 root
->SetBounds(root_rect
.size());
4481 root
->SetContentBounds(root
->bounds());
4482 root
->draw_properties().visible_content_rect
= root_rect
;
4483 root
->SetDrawsContent(false);
4484 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
4486 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
4487 child
->SetOpacity(0.5f
);
4488 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
4489 child
->SetContentBounds(child
->bounds());
4490 child
->draw_properties().visible_content_rect
= child_rect
;
4491 child
->SetDrawsContent(false);
4492 child
->SetForceRenderSurface(true);
4494 grand_child
->SetPosition(grand_child_rect
.origin());
4495 grand_child
->SetBounds(grand_child_rect
.size());
4496 grand_child
->SetContentBounds(grand_child
->bounds());
4497 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
4498 grand_child
->SetDrawsContent(true);
4500 child
->AddChild(grand_child
.Pass());
4501 root
->AddChild(child
.Pass());
4503 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4504 return my_host_impl
.Pass();
4507 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
4508 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4509 new TestSharedBitmapManager());
4510 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4511 SetupLayersForOpacity(true,
4514 shared_bitmap_manager
.get(),
4515 &stats_instrumentation_
);
4517 LayerTreeHostImpl::FrameData frame
;
4518 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4520 // Verify all quads have been computed
4521 ASSERT_EQ(2U, frame
.render_passes
.size());
4522 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4523 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4524 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4525 frame
.render_passes
[0]->quad_list
[0]->material
);
4526 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4527 frame
.render_passes
[1]->quad_list
[0]->material
);
4529 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4530 my_host_impl
->DidDrawAllLayers(frame
);
4534 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
4535 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4536 new TestSharedBitmapManager());
4537 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4538 SetupLayersForOpacity(false,
4541 shared_bitmap_manager
.get(),
4542 &stats_instrumentation_
);
4544 LayerTreeHostImpl::FrameData frame
;
4545 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4547 // Verify all quads have been computed
4548 ASSERT_EQ(2U, frame
.render_passes
.size());
4549 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4550 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4551 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4552 frame
.render_passes
[0]->quad_list
[0]->material
);
4553 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4554 frame
.render_passes
[1]->quad_list
[0]->material
);
4556 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4557 my_host_impl
->DidDrawAllLayers(frame
);
4561 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
4562 scoped_ptr
<TestWebGraphicsContext3D
> context
=
4563 TestWebGraphicsContext3D::Create();
4564 TestWebGraphicsContext3D
* context3d
= context
.get();
4565 scoped_ptr
<OutputSurface
> output_surface(
4566 FakeOutputSurface::Create3d(context
.Pass()));
4567 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4569 scoped_ptr
<LayerImpl
> root_layer
=
4570 LayerImpl::Create(host_impl_
->active_tree(), 1);
4571 root_layer
->SetBounds(gfx::Size(10, 10));
4573 scoped_refptr
<VideoFrame
> softwareFrame
=
4574 media::VideoFrame::CreateColorFrame(
4575 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
4576 FakeVideoFrameProvider provider
;
4577 provider
.set_frame(softwareFrame
);
4578 scoped_ptr
<VideoLayerImpl
> video_layer
=
4579 VideoLayerImpl::Create(host_impl_
->active_tree(), 4, &provider
);
4580 video_layer
->SetBounds(gfx::Size(10, 10));
4581 video_layer
->SetContentBounds(gfx::Size(10, 10));
4582 video_layer
->SetDrawsContent(true);
4583 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
4585 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
4586 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
4587 io_surface_layer
->SetBounds(gfx::Size(10, 10));
4588 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
4589 io_surface_layer
->SetDrawsContent(true);
4590 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
4591 root_layer
->AddChild(io_surface_layer
.PassAs
<LayerImpl
>());
4593 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
4595 EXPECT_EQ(0u, context3d
->NumTextures());
4597 LayerTreeHostImpl::FrameData frame
;
4598 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4599 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4600 host_impl_
->DidDrawAllLayers(frame
);
4601 host_impl_
->SwapBuffers(frame
);
4603 EXPECT_GT(context3d
->NumTextures(), 0u);
4605 // Kill the layer tree.
4606 host_impl_
->active_tree()->SetRootLayer(
4607 LayerImpl::Create(host_impl_
->active_tree(), 100));
4608 // There should be no textures left in use after.
4609 EXPECT_EQ(0u, context3d
->NumTextures());
4612 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
4614 MOCK_METHOD1(useProgram
, void(GLuint program
));
4615 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4621 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
4622 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
4623 new MockDrawQuadsToFillScreenContext
);
4624 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
4626 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4627 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4630 LayerTreeSettings settings
= DefaultSettings();
4631 settings
.partial_swap_enabled
= false;
4632 CreateHostImpl(settings
, output_surface
.Pass());
4633 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
4634 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
4636 // Verify one quad is drawn when transparent background set is not set.
4637 host_impl_
->active_tree()->set_has_transparent_background(false);
4638 EXPECT_CALL(*mock_context
, useProgram(_
))
4640 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
4642 LayerTreeHostImpl::FrameData frame
;
4643 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4644 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4645 host_impl_
->DidDrawAllLayers(frame
);
4646 Mock::VerifyAndClearExpectations(&mock_context
);
4648 // Verify no quads are drawn when transparent background is set.
4649 host_impl_
->active_tree()->set_has_transparent_background(true);
4650 host_impl_
->SetFullRootLayerDamage();
4651 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4652 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4653 host_impl_
->DidDrawAllLayers(frame
);
4654 Mock::VerifyAndClearExpectations(&mock_context
);
4657 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
4658 set_reduce_memory_result(false);
4660 // If changing the memory limit wouldn't result in changing what was
4661 // committed, then no commit should be requested.
4662 set_reduce_memory_result(false);
4663 host_impl_
->set_max_memory_needed_bytes(
4664 host_impl_
->memory_allocation_limit_bytes() - 1);
4665 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4666 host_impl_
->memory_allocation_limit_bytes() - 1));
4667 EXPECT_FALSE(did_request_commit_
);
4668 did_request_commit_
= false;
4670 // If changing the memory limit would result in changing what was
4671 // committed, then a commit should be requested, even though nothing was
4673 set_reduce_memory_result(false);
4674 host_impl_
->set_max_memory_needed_bytes(
4675 host_impl_
->memory_allocation_limit_bytes());
4676 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4677 host_impl_
->memory_allocation_limit_bytes() - 1));
4678 EXPECT_TRUE(did_request_commit_
);
4679 did_request_commit_
= false;
4681 // Especially if changing the memory limit caused evictions, we need
4683 set_reduce_memory_result(true);
4684 host_impl_
->set_max_memory_needed_bytes(1);
4685 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4686 host_impl_
->memory_allocation_limit_bytes() - 1));
4687 EXPECT_TRUE(did_request_commit_
);
4688 did_request_commit_
= false;
4690 // But if we set it to the same value that it was before, we shouldn't
4692 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4693 host_impl_
->memory_allocation_limit_bytes()));
4694 EXPECT_FALSE(did_request_commit_
);
4697 class LayerTreeHostImplTestWithDelegatingRenderer
4698 : public LayerTreeHostImplTest
{
4700 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
4701 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
4704 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
4705 bool expect_to_draw
= !expected_damage
.IsEmpty();
4707 LayerTreeHostImpl::FrameData frame
;
4708 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4710 if (!expect_to_draw
) {
4711 // With no damage, we don't draw, and no quads are created.
4712 ASSERT_EQ(0u, frame
.render_passes
.size());
4714 ASSERT_EQ(1u, frame
.render_passes
.size());
4716 // Verify the damage rect for the root render pass.
4717 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
4718 EXPECT_RECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
4720 // Verify the root and child layers' quads are generated and not being
4722 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
4724 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
4725 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
4726 EXPECT_RECT_EQ(expected_child_visible_rect
,
4727 root_render_pass
->quad_list
[0]->visible_rect
);
4729 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4730 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
4731 EXPECT_RECT_EQ(expected_root_visible_rect
,
4732 root_render_pass
->quad_list
[1]->visible_rect
);
4735 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4736 host_impl_
->DidDrawAllLayers(frame
);
4737 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
4741 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
4742 scoped_ptr
<SolidColorLayerImpl
> root
=
4743 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
4744 root
->SetPosition(gfx::PointF());
4745 root
->SetBounds(gfx::Size(10, 10));
4746 root
->SetContentBounds(gfx::Size(10, 10));
4747 root
->SetDrawsContent(true);
4749 // Child layer is in the bottom right corner.
4750 scoped_ptr
<SolidColorLayerImpl
> child
=
4751 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
4752 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
4753 child
->SetBounds(gfx::Size(1, 1));
4754 child
->SetContentBounds(gfx::Size(1, 1));
4755 child
->SetDrawsContent(true);
4756 root
->AddChild(child
.PassAs
<LayerImpl
>());
4758 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
4760 // Draw a frame. In the first frame, the entire viewport should be damaged.
4761 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
4762 DrawFrameAndTestDamage(full_frame_damage
);
4764 // The second frame has damage that doesn't touch the child layer. Its quads
4765 // should still be generated.
4766 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
4767 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
4768 DrawFrameAndTestDamage(small_damage
);
4770 // The third frame should have no damage, so no quads should be generated.
4771 gfx::Rect no_damage
;
4772 DrawFrameAndTestDamage(no_damage
);
4775 // TODO(reveman): Remove this test and the ability to prevent on demand raster
4776 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
4777 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
4778 LayerTreeSettings settings
;
4779 CreateHostImpl(settings
, CreateOutputSurface());
4780 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
4783 class FakeMaskLayerImpl
: public LayerImpl
{
4785 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4787 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
4790 virtual ResourceProvider::ResourceId
ContentsResourceId() const OVERRIDE
{
4795 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4796 : LayerImpl(tree_impl
, id
) {}
4799 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
4800 LayerTreeSettings settings
;
4801 settings
.layer_transforms_should_scale_layer_contents
= true;
4802 CreateHostImpl(settings
, CreateOutputSurface());
4806 // +-- Scaling Layer (adds a 2x scale)
4808 // +-- Content Layer
4810 scoped_ptr
<LayerImpl
> scoped_root
=
4811 LayerImpl::Create(host_impl_
->active_tree(), 1);
4812 LayerImpl
* root
= scoped_root
.get();
4813 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4815 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
4816 LayerImpl::Create(host_impl_
->active_tree(), 2);
4817 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
4818 root
->AddChild(scoped_scaling_layer
.Pass());
4820 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4821 LayerImpl::Create(host_impl_
->active_tree(), 3);
4822 LayerImpl
* content_layer
= scoped_content_layer
.get();
4823 scaling_layer
->AddChild(scoped_content_layer
.Pass());
4825 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4826 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4827 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4828 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4830 gfx::Size
root_size(100, 100);
4831 root
->SetBounds(root_size
);
4832 root
->SetContentBounds(root_size
);
4833 root
->SetPosition(gfx::PointF());
4835 gfx::Size
scaling_layer_size(50, 50);
4836 scaling_layer
->SetBounds(scaling_layer_size
);
4837 scaling_layer
->SetContentBounds(scaling_layer_size
);
4838 scaling_layer
->SetPosition(gfx::PointF());
4839 gfx::Transform scale
;
4840 scale
.Scale(2.f
, 2.f
);
4841 scaling_layer
->SetTransform(scale
);
4843 content_layer
->SetBounds(scaling_layer_size
);
4844 content_layer
->SetContentBounds(scaling_layer_size
);
4845 content_layer
->SetPosition(gfx::PointF());
4846 content_layer
->SetDrawsContent(true);
4848 mask_layer
->SetBounds(scaling_layer_size
);
4849 mask_layer
->SetContentBounds(scaling_layer_size
);
4850 mask_layer
->SetPosition(gfx::PointF());
4851 mask_layer
->SetDrawsContent(true);
4854 // Check that the tree scaling is correctly taken into account for the mask,
4855 // that should fully map onto the quad.
4856 float device_scale_factor
= 1.f
;
4857 host_impl_
->SetViewportSize(root_size
);
4858 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4860 LayerTreeHostImpl::FrameData frame
;
4861 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4863 ASSERT_EQ(1u, frame
.render_passes
.size());
4864 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4865 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4866 frame
.render_passes
[0]->quad_list
[0]->material
);
4867 const RenderPassDrawQuad
* render_pass_quad
=
4868 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4869 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4870 render_pass_quad
->rect
.ToString());
4871 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4872 render_pass_quad
->mask_uv_rect
.ToString());
4874 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4875 host_impl_
->DidDrawAllLayers(frame
);
4879 // Applying a DSF should change the render surface size, but won't affect
4880 // which part of the mask is used.
4881 device_scale_factor
= 2.f
;
4882 gfx::Size device_viewport
=
4883 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4884 host_impl_
->SetViewportSize(device_viewport
);
4885 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4886 host_impl_
->active_tree()->set_needs_update_draw_properties();
4888 LayerTreeHostImpl::FrameData frame
;
4889 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4891 ASSERT_EQ(1u, frame
.render_passes
.size());
4892 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4893 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4894 frame
.render_passes
[0]->quad_list
[0]->material
);
4895 const RenderPassDrawQuad
* render_pass_quad
=
4896 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4897 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4898 render_pass_quad
->rect
.ToString());
4899 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4900 render_pass_quad
->mask_uv_rect
.ToString());
4902 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4903 host_impl_
->DidDrawAllLayers(frame
);
4907 // Applying an equivalent content scale on the content layer and the mask
4908 // should still result in the same part of the mask being used.
4909 gfx::Size content_bounds
=
4910 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
4911 device_scale_factor
));
4912 content_layer
->SetContentBounds(content_bounds
);
4913 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4914 mask_layer
->SetContentBounds(content_bounds
);
4915 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4916 host_impl_
->active_tree()->set_needs_update_draw_properties();
4918 LayerTreeHostImpl::FrameData frame
;
4919 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4921 ASSERT_EQ(1u, frame
.render_passes
.size());
4922 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4923 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4924 frame
.render_passes
[0]->quad_list
[0]->material
);
4925 const RenderPassDrawQuad
* render_pass_quad
=
4926 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4927 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4928 render_pass_quad
->rect
.ToString());
4929 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4930 render_pass_quad
->mask_uv_rect
.ToString());
4932 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4933 host_impl_
->DidDrawAllLayers(frame
);
4937 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
4938 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4941 scoped_ptr
<LayerImpl
> scoped_root
=
4942 LayerImpl::Create(host_impl_
->active_tree(), 1);
4943 LayerImpl
* root
= scoped_root
.get();
4944 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4946 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4947 LayerImpl::Create(host_impl_
->active_tree(), 3);
4948 LayerImpl
* content_layer
= scoped_content_layer
.get();
4949 root
->AddChild(scoped_content_layer
.Pass());
4951 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4952 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4953 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4954 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4956 gfx::Size
root_size(100, 100);
4957 root
->SetBounds(root_size
);
4958 root
->SetContentBounds(root_size
);
4959 root
->SetPosition(gfx::PointF());
4961 gfx::Size
layer_size(50, 50);
4962 content_layer
->SetBounds(layer_size
);
4963 content_layer
->SetContentBounds(layer_size
);
4964 content_layer
->SetPosition(gfx::PointF());
4965 content_layer
->SetDrawsContent(true);
4967 gfx::Size
mask_size(100, 100);
4968 mask_layer
->SetBounds(mask_size
);
4969 mask_layer
->SetContentBounds(mask_size
);
4970 mask_layer
->SetPosition(gfx::PointF());
4971 mask_layer
->SetDrawsContent(true);
4973 // Check that the mask fills the surface.
4974 float device_scale_factor
= 1.f
;
4975 host_impl_
->SetViewportSize(root_size
);
4976 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4978 LayerTreeHostImpl::FrameData frame
;
4979 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4981 ASSERT_EQ(1u, frame
.render_passes
.size());
4982 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4983 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4984 frame
.render_passes
[0]->quad_list
[0]->material
);
4985 const RenderPassDrawQuad
* render_pass_quad
=
4986 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4987 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4988 render_pass_quad
->rect
.ToString());
4989 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4990 render_pass_quad
->mask_uv_rect
.ToString());
4992 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4993 host_impl_
->DidDrawAllLayers(frame
);
4996 // Applying a DSF should change the render surface size, but won't affect
4997 // which part of the mask is used.
4998 device_scale_factor
= 2.f
;
4999 gfx::Size device_viewport
=
5000 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5001 host_impl_
->SetViewportSize(device_viewport
);
5002 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5003 host_impl_
->active_tree()->set_needs_update_draw_properties();
5005 LayerTreeHostImpl::FrameData frame
;
5006 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5008 ASSERT_EQ(1u, frame
.render_passes
.size());
5009 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5010 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5011 frame
.render_passes
[0]->quad_list
[0]->material
);
5012 const RenderPassDrawQuad
* render_pass_quad
=
5013 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5014 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5015 render_pass_quad
->rect
.ToString());
5016 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5017 render_pass_quad
->mask_uv_rect
.ToString());
5019 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5020 host_impl_
->DidDrawAllLayers(frame
);
5023 // Applying an equivalent content scale on the content layer and the mask
5024 // should still result in the same part of the mask being used.
5025 gfx::Size layer_size_large
=
5026 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5027 content_layer
->SetContentBounds(layer_size_large
);
5028 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5029 gfx::Size mask_size_large
=
5030 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5031 mask_layer
->SetContentBounds(mask_size_large
);
5032 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5033 host_impl_
->active_tree()->set_needs_update_draw_properties();
5035 LayerTreeHostImpl::FrameData frame
;
5036 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5038 ASSERT_EQ(1u, frame
.render_passes
.size());
5039 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5040 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5041 frame
.render_passes
[0]->quad_list
[0]->material
);
5042 const RenderPassDrawQuad
* render_pass_quad
=
5043 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5044 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5045 render_pass_quad
->rect
.ToString());
5046 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5047 render_pass_quad
->mask_uv_rect
.ToString());
5049 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5050 host_impl_
->DidDrawAllLayers(frame
);
5053 // Applying a different contents scale to the mask layer means it will have
5054 // a larger texture, but it should use the same tex coords to cover the
5056 mask_layer
->SetContentBounds(mask_size
);
5057 mask_layer
->SetContentsScale(1.f
, 1.f
);
5058 host_impl_
->active_tree()->set_needs_update_draw_properties();
5060 LayerTreeHostImpl::FrameData frame
;
5061 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5063 ASSERT_EQ(1u, frame
.render_passes
.size());
5064 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5065 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5066 frame
.render_passes
[0]->quad_list
[0]->material
);
5067 const RenderPassDrawQuad
* render_pass_quad
=
5068 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5069 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5070 render_pass_quad
->rect
.ToString());
5071 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5072 render_pass_quad
->mask_uv_rect
.ToString());
5074 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5075 host_impl_
->DidDrawAllLayers(frame
);
5079 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5080 // The replica's mask layer has bounds 100x100 but the replica is of a
5081 // layer with bounds 50x50.
5083 scoped_ptr
<LayerImpl
> scoped_root
=
5084 LayerImpl::Create(host_impl_
->active_tree(), 1);
5085 LayerImpl
* root
= scoped_root
.get();
5086 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5088 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5089 LayerImpl::Create(host_impl_
->active_tree(), 3);
5090 LayerImpl
* content_layer
= scoped_content_layer
.get();
5091 root
->AddChild(scoped_content_layer
.Pass());
5093 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5094 LayerImpl::Create(host_impl_
->active_tree(), 2);
5095 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5096 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5098 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5099 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5100 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5101 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5103 gfx::Size
root_size(100, 100);
5104 root
->SetBounds(root_size
);
5105 root
->SetContentBounds(root_size
);
5106 root
->SetPosition(gfx::PointF());
5108 gfx::Size
layer_size(50, 50);
5109 content_layer
->SetBounds(layer_size
);
5110 content_layer
->SetContentBounds(layer_size
);
5111 content_layer
->SetPosition(gfx::PointF());
5112 content_layer
->SetDrawsContent(true);
5114 gfx::Size
mask_size(100, 100);
5115 mask_layer
->SetBounds(mask_size
);
5116 mask_layer
->SetContentBounds(mask_size
);
5117 mask_layer
->SetPosition(gfx::PointF());
5118 mask_layer
->SetDrawsContent(true);
5120 // Check that the mask fills the surface.
5121 float device_scale_factor
= 1.f
;
5122 host_impl_
->SetViewportSize(root_size
);
5123 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5125 LayerTreeHostImpl::FrameData frame
;
5126 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5128 ASSERT_EQ(1u, frame
.render_passes
.size());
5129 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5130 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5131 frame
.render_passes
[0]->quad_list
[1]->material
);
5132 const RenderPassDrawQuad
* replica_quad
=
5133 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5134 EXPECT_TRUE(replica_quad
->is_replica
);
5135 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5136 replica_quad
->rect
.ToString());
5137 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5138 replica_quad
->mask_uv_rect
.ToString());
5140 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5141 host_impl_
->DidDrawAllLayers(frame
);
5144 // Applying a DSF should change the render surface size, but won't affect
5145 // which part of the mask is used.
5146 device_scale_factor
= 2.f
;
5147 gfx::Size device_viewport
=
5148 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5149 host_impl_
->SetViewportSize(device_viewport
);
5150 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5151 host_impl_
->active_tree()->set_needs_update_draw_properties();
5153 LayerTreeHostImpl::FrameData frame
;
5154 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5156 ASSERT_EQ(1u, frame
.render_passes
.size());
5157 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5158 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5159 frame
.render_passes
[0]->quad_list
[1]->material
);
5160 const RenderPassDrawQuad
* replica_quad
=
5161 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5162 EXPECT_TRUE(replica_quad
->is_replica
);
5163 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5164 replica_quad
->rect
.ToString());
5165 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5166 replica_quad
->mask_uv_rect
.ToString());
5168 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5169 host_impl_
->DidDrawAllLayers(frame
);
5172 // Applying an equivalent content scale on the content layer and the mask
5173 // should still result in the same part of the mask being used.
5174 gfx::Size layer_size_large
=
5175 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5176 content_layer
->SetContentBounds(layer_size_large
);
5177 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5178 gfx::Size mask_size_large
=
5179 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5180 mask_layer
->SetContentBounds(mask_size_large
);
5181 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5182 host_impl_
->active_tree()->set_needs_update_draw_properties();
5184 LayerTreeHostImpl::FrameData frame
;
5185 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5187 ASSERT_EQ(1u, frame
.render_passes
.size());
5188 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5189 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5190 frame
.render_passes
[0]->quad_list
[1]->material
);
5191 const RenderPassDrawQuad
* replica_quad
=
5192 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5193 EXPECT_TRUE(replica_quad
->is_replica
);
5194 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5195 replica_quad
->rect
.ToString());
5196 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5197 replica_quad
->mask_uv_rect
.ToString());
5199 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5200 host_impl_
->DidDrawAllLayers(frame
);
5203 // Applying a different contents scale to the mask layer means it will have
5204 // a larger texture, but it should use the same tex coords to cover the
5206 mask_layer
->SetContentBounds(mask_size
);
5207 mask_layer
->SetContentsScale(1.f
, 1.f
);
5208 host_impl_
->active_tree()->set_needs_update_draw_properties();
5210 LayerTreeHostImpl::FrameData frame
;
5211 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5213 ASSERT_EQ(1u, frame
.render_passes
.size());
5214 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5215 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5216 frame
.render_passes
[0]->quad_list
[1]->material
);
5217 const RenderPassDrawQuad
* replica_quad
=
5218 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5219 EXPECT_TRUE(replica_quad
->is_replica
);
5220 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5221 replica_quad
->rect
.ToString());
5222 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5223 replica_quad
->mask_uv_rect
.ToString());
5225 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5226 host_impl_
->DidDrawAllLayers(frame
);
5230 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5231 // The replica is of a layer with bounds 50x50, but it has a child that causes
5232 // the surface bounds to be larger.
5234 scoped_ptr
<LayerImpl
> scoped_root
=
5235 LayerImpl::Create(host_impl_
->active_tree(), 1);
5236 LayerImpl
* root
= scoped_root
.get();
5237 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5239 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5240 LayerImpl::Create(host_impl_
->active_tree(), 2);
5241 LayerImpl
* content_layer
= scoped_content_layer
.get();
5242 root
->AddChild(scoped_content_layer
.Pass());
5244 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5245 LayerImpl::Create(host_impl_
->active_tree(), 3);
5246 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5247 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5249 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5250 LayerImpl::Create(host_impl_
->active_tree(), 4);
5251 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5252 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5254 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5255 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5256 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5257 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5259 gfx::Size
root_size(100, 100);
5260 root
->SetBounds(root_size
);
5261 root
->SetContentBounds(root_size
);
5262 root
->SetPosition(gfx::PointF());
5264 gfx::Size
layer_size(50, 50);
5265 content_layer
->SetBounds(layer_size
);
5266 content_layer
->SetContentBounds(layer_size
);
5267 content_layer
->SetPosition(gfx::PointF());
5268 content_layer
->SetDrawsContent(true);
5270 gfx::Size
child_size(50, 50);
5271 content_child_layer
->SetBounds(child_size
);
5272 content_child_layer
->SetContentBounds(child_size
);
5273 content_child_layer
->SetPosition(gfx::Point(50, 0));
5274 content_child_layer
->SetDrawsContent(true);
5276 gfx::Size
mask_size(50, 50);
5277 mask_layer
->SetBounds(mask_size
);
5278 mask_layer
->SetContentBounds(mask_size
);
5279 mask_layer
->SetPosition(gfx::PointF());
5280 mask_layer
->SetDrawsContent(true);
5282 float device_scale_factor
= 1.f
;
5283 host_impl_
->SetViewportSize(root_size
);
5284 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5286 LayerTreeHostImpl::FrameData frame
;
5287 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5289 ASSERT_EQ(1u, frame
.render_passes
.size());
5290 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5292 // The surface is 100x50.
5293 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5294 frame
.render_passes
[0]->quad_list
[0]->material
);
5295 const RenderPassDrawQuad
* render_pass_quad
=
5296 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5297 EXPECT_FALSE(render_pass_quad
->is_replica
);
5298 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5299 render_pass_quad
->rect
.ToString());
5301 // The mask covers the owning layer only.
5302 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5303 frame
.render_passes
[0]->quad_list
[1]->material
);
5304 const RenderPassDrawQuad
* replica_quad
=
5305 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5306 EXPECT_TRUE(replica_quad
->is_replica
);
5307 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5308 replica_quad
->rect
.ToString());
5309 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
5310 replica_quad
->mask_uv_rect
.ToString());
5312 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5313 host_impl_
->DidDrawAllLayers(frame
);
5316 // Move the child to (-50, 0) instead. Now the mask should be moved to still
5317 // cover the layer being replicated.
5318 content_child_layer
->SetPosition(gfx::Point(-50, 0));
5320 LayerTreeHostImpl::FrameData frame
;
5321 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5323 ASSERT_EQ(1u, frame
.render_passes
.size());
5324 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5326 // The surface is 100x50 with its origin at (-50, 0).
5327 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5328 frame
.render_passes
[0]->quad_list
[0]->material
);
5329 const RenderPassDrawQuad
* render_pass_quad
=
5330 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5331 EXPECT_FALSE(render_pass_quad
->is_replica
);
5332 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5333 render_pass_quad
->rect
.ToString());
5335 // The mask covers the owning layer only.
5336 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5337 frame
.render_passes
[0]->quad_list
[1]->material
);
5338 const RenderPassDrawQuad
* replica_quad
=
5339 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5340 EXPECT_TRUE(replica_quad
->is_replica
);
5341 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5342 replica_quad
->rect
.ToString());
5343 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
5344 replica_quad
->mask_uv_rect
.ToString());
5346 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5347 host_impl_
->DidDrawAllLayers(frame
);
5351 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
5352 // The masked layer has bounds 50x50, but it has a child that causes
5353 // the surface bounds to be larger. It also has a parent that clips the
5354 // masked layer and its surface.
5356 scoped_ptr
<LayerImpl
> scoped_root
=
5357 LayerImpl::Create(host_impl_
->active_tree(), 1);
5358 LayerImpl
* root
= scoped_root
.get();
5359 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5361 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
5362 LayerImpl::Create(host_impl_
->active_tree(), 2);
5363 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
5364 root
->AddChild(scoped_clipping_layer
.Pass());
5366 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5367 LayerImpl::Create(host_impl_
->active_tree(), 3);
5368 LayerImpl
* content_layer
= scoped_content_layer
.get();
5369 clipping_layer
->AddChild(scoped_content_layer
.Pass());
5371 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5372 LayerImpl::Create(host_impl_
->active_tree(), 4);
5373 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5374 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5376 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5377 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
5378 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5379 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5381 gfx::Size
root_size(100, 100);
5382 root
->SetBounds(root_size
);
5383 root
->SetContentBounds(root_size
);
5384 root
->SetPosition(gfx::PointF());
5386 gfx::Rect
clipping_rect(20, 10, 10, 20);
5387 clipping_layer
->SetBounds(clipping_rect
.size());
5388 clipping_layer
->SetContentBounds(clipping_rect
.size());
5389 clipping_layer
->SetPosition(clipping_rect
.origin());
5390 clipping_layer
->SetMasksToBounds(true);
5392 gfx::Size
layer_size(50, 50);
5393 content_layer
->SetBounds(layer_size
);
5394 content_layer
->SetContentBounds(layer_size
);
5395 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
5396 content_layer
->SetDrawsContent(true);
5398 gfx::Size
child_size(50, 50);
5399 content_child_layer
->SetBounds(child_size
);
5400 content_child_layer
->SetContentBounds(child_size
);
5401 content_child_layer
->SetPosition(gfx::Point(50, 0));
5402 content_child_layer
->SetDrawsContent(true);
5404 gfx::Size
mask_size(100, 100);
5405 mask_layer
->SetBounds(mask_size
);
5406 mask_layer
->SetContentBounds(mask_size
);
5407 mask_layer
->SetPosition(gfx::PointF());
5408 mask_layer
->SetDrawsContent(true);
5410 float device_scale_factor
= 1.f
;
5411 host_impl_
->SetViewportSize(root_size
);
5412 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5414 LayerTreeHostImpl::FrameData frame
;
5415 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5417 ASSERT_EQ(1u, frame
.render_passes
.size());
5418 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5420 // The surface is clipped to 10x20.
5421 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5422 frame
.render_passes
[0]->quad_list
[0]->material
);
5423 const RenderPassDrawQuad
* render_pass_quad
=
5424 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5425 EXPECT_FALSE(render_pass_quad
->is_replica
);
5426 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5427 render_pass_quad
->rect
.ToString());
5429 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5430 // coords in the mask are scaled by 10/50 and 20/50.
5431 // The surface is clipped to (20,10) so the mask texture coords are offset
5432 // by 20/50 and 10/50
5433 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
),
5434 1.f
/ 50.f
).ToString(),
5435 render_pass_quad
->mask_uv_rect
.ToString());
5437 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5438 host_impl_
->DidDrawAllLayers(frame
);
5442 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
5444 using GLRenderer::SetupQuadForAntialiasing
;
5447 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
5448 // Due to precision issues (especially on Android), sometimes far
5449 // away quads can end up thinking they need AA.
5450 float device_scale_factor
= 4.f
/ 3.f
;
5451 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5452 gfx::Size
root_size(2000, 1000);
5453 gfx::Size device_viewport_size
=
5454 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5455 host_impl_
->SetViewportSize(device_viewport_size
);
5457 host_impl_
->CreatePendingTree();
5458 host_impl_
->pending_tree()
5459 ->SetPageScaleFactorAndLimits(1.f
, 1.f
/ 16.f
, 16.f
);
5461 scoped_ptr
<LayerImpl
> scoped_root
=
5462 LayerImpl::Create(host_impl_
->pending_tree(), 1);
5463 LayerImpl
* root
= scoped_root
.get();
5465 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
5467 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
5468 LayerImpl::Create(host_impl_
->pending_tree(), 2);
5469 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
5470 root
->AddChild(scoped_scrolling_layer
.Pass());
5472 gfx::Size
content_layer_bounds(100000, 100);
5473 gfx::Size
pile_tile_size(3000, 3000);
5474 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
5475 pile_tile_size
, content_layer_bounds
));
5477 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
5478 FakePictureLayerImpl::CreateWithPile(host_impl_
->pending_tree(), 3, pile
);
5479 LayerImpl
* content_layer
= scoped_content_layer
.get();
5480 scrolling_layer
->AddChild(scoped_content_layer
.PassAs
<LayerImpl
>());
5481 content_layer
->SetBounds(content_layer_bounds
);
5482 content_layer
->SetDrawsContent(true);
5484 root
->SetBounds(root_size
);
5486 gfx::Vector2d
scroll_offset(100000, 0);
5487 scrolling_layer
->SetScrollClipLayer(root
->id());
5488 scrolling_layer
->SetScrollOffset(scroll_offset
);
5490 host_impl_
->ActivateSyncTree();
5492 host_impl_
->active_tree()->UpdateDrawProperties();
5493 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
5495 LayerTreeHostImpl::FrameData frame
;
5496 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5498 ASSERT_EQ(1u, frame
.render_passes
.size());
5499 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
5500 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
[0];
5503 gfx::QuadF device_layer_quad
;
5505 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
5506 quad
->quadTransform(), quad
, &device_layer_quad
, edge
);
5507 EXPECT_FALSE(antialiased
);
5509 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5510 host_impl_
->DidDrawAllLayers(frame
);
5514 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
5516 CompositorFrameMetadataTest()
5517 : swap_buffers_complete_(0) {}
5519 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{
5520 swap_buffers_complete_
++;
5523 int swap_buffers_complete_
;
5526 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
5527 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5529 LayerTreeHostImpl::FrameData frame
;
5530 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5531 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
5532 host_impl_
->DidDrawAllLayers(frame
);
5534 CompositorFrameAck ack
;
5535 host_impl_
->ReclaimResources(&ack
);
5536 host_impl_
->DidSwapBuffersComplete();
5537 EXPECT_EQ(swap_buffers_complete_
, 1);
5540 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
5542 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
5544 virtual SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) OVERRIDE
{
5546 return SoftwareOutputDevice::BeginPaint(damage_rect
);
5548 virtual void EndPaint(SoftwareFrameData
* frame_data
) OVERRIDE
{
5550 SoftwareOutputDevice::EndPaint(frame_data
);
5553 int frames_began_
, frames_ended_
;
5556 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
5557 // No main thread evictions in resourceless software mode.
5558 set_reduce_memory_result(false);
5559 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
5560 bool delegated_rendering
= false;
5561 FakeOutputSurface
* output_surface
=
5562 FakeOutputSurface::CreateDeferredGL(
5563 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
5564 delegated_rendering
).release();
5565 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5566 scoped_ptr
<OutputSurface
>(output_surface
)));
5567 host_impl_
->SetViewportSize(gfx::Size(50, 50));
5569 SetupScrollAndContentsLayers(gfx::Size(100, 100));
5571 output_surface
->set_forced_draw_to_software_device(true);
5572 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5574 EXPECT_EQ(0, software_device
->frames_began_
);
5575 EXPECT_EQ(0, software_device
->frames_ended_
);
5579 EXPECT_EQ(1, software_device
->frames_began_
);
5580 EXPECT_EQ(1, software_device
->frames_ended_
);
5582 // Call other API methods that are likely to hit NULL pointer in this mode.
5583 EXPECT_TRUE(host_impl_
->AsValue());
5584 EXPECT_TRUE(host_impl_
->ActivationStateAsValue());
5587 TEST_F(LayerTreeHostImplTest
,
5588 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
5589 set_reduce_memory_result(false);
5590 bool delegated_rendering
= false;
5591 FakeOutputSurface
* output_surface
=
5592 FakeOutputSurface::CreateDeferredGL(
5593 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5594 delegated_rendering
).release();
5595 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5596 scoped_ptr
<OutputSurface
>(output_surface
)));
5598 output_surface
->set_forced_draw_to_software_device(true);
5599 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5601 // SolidColorLayerImpl will be drawn.
5602 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5603 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5605 // VideoLayerImpl will not be drawn.
5606 FakeVideoFrameProvider provider
;
5607 scoped_ptr
<VideoLayerImpl
> video_layer
=
5608 VideoLayerImpl::Create(host_impl_
->active_tree(), 2, &provider
);
5609 video_layer
->SetBounds(gfx::Size(10, 10));
5610 video_layer
->SetContentBounds(gfx::Size(10, 10));
5611 video_layer
->SetDrawsContent(true);
5612 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
5613 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5615 LayerTreeHostImpl::FrameData frame
;
5616 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5617 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5618 host_impl_
->DidDrawAllLayers(frame
);
5620 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
5621 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
5624 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
5626 virtual void SetUp() OVERRIDE
{
5627 LayerTreeHostImplTest::SetUp();
5629 set_reduce_memory_result(false);
5631 bool delegated_rendering
= false;
5632 scoped_ptr
<FakeOutputSurface
> output_surface(
5633 FakeOutputSurface::CreateDeferredGL(
5634 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5635 delegated_rendering
));
5636 output_surface_
= output_surface
.get();
5638 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5639 output_surface
.PassAs
<OutputSurface
>()));
5641 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5642 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5643 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5645 onscreen_context_provider_
= TestContextProvider::Create();
5648 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{
5649 did_update_renderer_capabilities_
= true;
5652 FakeOutputSurface
* output_surface_
;
5653 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
5654 bool did_update_renderer_capabilities_
;
5658 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
5662 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5664 // DeferredInitialize and hardware draw.
5665 did_update_renderer_capabilities_
= false;
5667 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5668 EXPECT_EQ(onscreen_context_provider_
,
5669 host_impl_
->output_surface()->context_provider());
5670 EXPECT_TRUE(did_update_renderer_capabilities_
);
5672 // Defer intialized GL draw.
5675 // Revert back to software.
5676 did_update_renderer_capabilities_
= false;
5677 output_surface_
->ReleaseGL();
5678 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5679 EXPECT_TRUE(did_update_renderer_capabilities_
);
5681 // Software draw again.
5685 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
5689 // Fail initialization of the onscreen context before the OutputSurface binds
5690 // it to the thread.
5691 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
5693 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5695 // DeferredInitialize fails.
5696 did_update_renderer_capabilities_
= false;
5698 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5699 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5700 EXPECT_FALSE(did_update_renderer_capabilities_
);
5702 // Software draw again.
5706 // Checks that we have a non-0 default allocation if we pass a context that
5707 // doesn't support memory management extensions.
5708 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
5709 LayerTreeSettings settings
;
5710 host_impl_
= LayerTreeHostImpl::Create(settings
,
5713 &stats_instrumentation_
,
5714 shared_bitmap_manager_
.get(),
5717 scoped_ptr
<OutputSurface
> output_surface(
5718 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
5719 host_impl_
->InitializeRenderer(output_surface
.Pass());
5720 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
5723 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
5724 ManagedMemoryPolicy
policy1(
5725 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
5726 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5727 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
5728 int allow_nice_to_have_cutoff_value
=
5729 ManagedMemoryPolicy::PriorityCutoffToValue(
5730 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
5731 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5732 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
5734 // GPU rasterization should be disabled by default on the tree(s)
5735 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
5736 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
5738 host_impl_
->SetVisible(true);
5739 host_impl_
->SetMemoryPolicy(policy1
);
5740 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5741 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5743 host_impl_
->SetVisible(false);
5744 EXPECT_EQ(0u, current_limit_bytes_
);
5745 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5747 host_impl_
->SetVisible(true);
5748 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5749 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5751 // Now enable GPU rasterization and test if we get nice to have cutoff,
5753 LayerTreeSettings settings
;
5754 settings
.gpu_rasterization_enabled
= true;
5755 host_impl_
= LayerTreeHostImpl::Create(
5756 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, 0);
5757 host_impl_
->SetUseGpuRasterization(true);
5758 host_impl_
->SetVisible(true);
5759 host_impl_
->SetMemoryPolicy(policy1
);
5760 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5761 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
5763 host_impl_
->SetVisible(false);
5764 EXPECT_EQ(0u, current_limit_bytes_
);
5765 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5768 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
5769 ASSERT_TRUE(host_impl_
->active_tree());
5771 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5772 host_impl_
->SetVisible(false);
5773 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5774 host_impl_
->SetVisible(true);
5775 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5776 host_impl_
->SetVisible(false);
5777 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5779 host_impl_
->CreatePendingTree();
5780 host_impl_
->ActivateSyncTree();
5782 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5783 host_impl_
->SetVisible(true);
5784 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5787 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
5788 ASSERT_TRUE(host_impl_
->active_tree());
5789 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
5791 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5792 host_impl_
->SetUseGpuRasterization(false);
5793 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5794 host_impl_
->SetUseGpuRasterization(true);
5795 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5796 host_impl_
->SetUseGpuRasterization(false);
5797 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5799 host_impl_
->CreatePendingTree();
5800 host_impl_
->ActivateSyncTree();
5802 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5803 host_impl_
->SetUseGpuRasterization(true);
5804 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5807 class LayerTreeHostImplTestManageTiles
: public LayerTreeHostImplTest
{
5809 virtual void SetUp() OVERRIDE
{
5810 LayerTreeSettings settings
;
5811 settings
.impl_side_painting
= true;
5813 fake_host_impl_
= new FakeLayerTreeHostImpl(
5814 settings
, &proxy_
, shared_bitmap_manager_
.get());
5815 host_impl_
.reset(fake_host_impl_
);
5816 host_impl_
->InitializeRenderer(CreateOutputSurface());
5817 host_impl_
->SetViewportSize(gfx::Size(10, 10));
5820 FakeLayerTreeHostImpl
* fake_host_impl_
;
5823 TEST_F(LayerTreeHostImplTestManageTiles
, ManageTilesWhenInvisible
) {
5824 fake_host_impl_
->DidModifyTilePriorities();
5825 EXPECT_TRUE(fake_host_impl_
->manage_tiles_needed());
5826 fake_host_impl_
->SetVisible(false);
5827 EXPECT_FALSE(fake_host_impl_
->manage_tiles_needed());
5830 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
5831 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5832 TestWebGraphicsContext3D::Create();
5833 TestWebGraphicsContext3D
* context3d
= context
.get();
5834 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5835 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5837 EXPECT_EQ(0u, context3d
->NumTextures());
5839 UIResourceId ui_resource_id
= 1;
5840 bool is_opaque
= false;
5841 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
5842 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5843 EXPECT_EQ(1u, context3d
->NumTextures());
5844 ResourceProvider::ResourceId id1
=
5845 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5848 // Multiple requests with the same id is allowed. The previous texture is
5850 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5851 EXPECT_EQ(1u, context3d
->NumTextures());
5852 ResourceProvider::ResourceId id2
=
5853 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5855 EXPECT_NE(id1
, id2
);
5857 // Deleting invalid UIResourceId is allowed and does not change state.
5858 host_impl_
->DeleteUIResource(-1);
5859 EXPECT_EQ(1u, context3d
->NumTextures());
5861 // Should return zero for invalid UIResourceId. Number of textures should
5863 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
5864 EXPECT_EQ(1u, context3d
->NumTextures());
5866 host_impl_
->DeleteUIResource(ui_resource_id
);
5867 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
5868 EXPECT_EQ(0u, context3d
->NumTextures());
5870 // Should not change state for multiple deletion on one UIResourceId
5871 host_impl_
->DeleteUIResource(ui_resource_id
);
5872 EXPECT_EQ(0u, context3d
->NumTextures());
5875 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
5876 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5877 TestWebGraphicsContext3D::Create();
5878 TestWebGraphicsContext3D
* context3d
= context
.get();
5879 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5880 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5882 EXPECT_EQ(0u, context3d
->NumTextures());
5884 gfx::Size
size(4, 4);
5885 // SkImageInfo has no support for ETC1. The |info| below contains the right
5886 // total pixel size for the bitmap but not the right height and width. The
5887 // correct width/height are passed directly to UIResourceBitmap.
5889 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
5890 skia::RefPtr
<SkPixelRef
> pixel_ref
=
5891 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
5892 pixel_ref
->setImmutable();
5893 UIResourceBitmap
bitmap(pixel_ref
, size
);
5894 UIResourceId ui_resource_id
= 1;
5895 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5896 EXPECT_EQ(1u, context3d
->NumTextures());
5897 ResourceProvider::ResourceId id1
=
5898 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5902 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
5905 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
5906 scoped_refptr
<TestContextProvider
> context_provider
=
5907 TestContextProvider::Create();
5911 FakeOutputSurface::Create3d(context_provider
).PassAs
<OutputSurface
>());
5913 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5915 ScopedPtrVector
<CopyOutputRequest
> requests
;
5916 requests
.push_back(CopyOutputRequest::CreateRequest(
5917 base::Bind(&ShutdownReleasesContext_Callback
)));
5919 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
5921 LayerTreeHostImpl::FrameData frame
;
5922 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5923 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5924 host_impl_
->DidDrawAllLayers(frame
);
5926 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5927 // texture in a texture mailbox.
5928 EXPECT_FALSE(context_provider
->HasOneRef());
5929 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
5933 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5934 // released, and the texture deleted.
5935 EXPECT_TRUE(context_provider
->HasOneRef());
5936 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
5939 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
5940 // When flinging via touch, only the child should scroll (we should not
5942 gfx::Size
surface_size(10, 10);
5943 gfx::Size
content_size(20, 20);
5944 scoped_ptr
<LayerImpl
> root_clip
=
5945 LayerImpl::Create(host_impl_
->active_tree(), 3);
5946 scoped_ptr
<LayerImpl
> root
=
5947 CreateScrollableLayer(1, content_size
, root_clip
.get());
5948 root
->SetIsContainerForFixedPositionLayers(true);
5949 scoped_ptr
<LayerImpl
> child
=
5950 CreateScrollableLayer(2, content_size
, root_clip
.get());
5952 root
->AddChild(child
.Pass());
5953 int root_id
= root
->id();
5954 root_clip
->AddChild(root
.Pass());
5956 host_impl_
->SetViewportSize(surface_size
);
5957 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
5958 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
5959 host_impl_
->active_tree()->DidBecomeActive();
5962 EXPECT_EQ(InputHandler::ScrollStarted
,
5963 host_impl_
->ScrollBegin(gfx::Point(),
5964 InputHandler::Gesture
));
5966 EXPECT_EQ(InputHandler::ScrollStarted
,
5967 host_impl_
->FlingScrollBegin());
5969 gfx::Vector2d
scroll_delta(0, 100);
5970 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5971 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5973 host_impl_
->ScrollEnd();
5975 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
5976 host_impl_
->ProcessScrollDeltas();
5978 // Only the child should have scrolled.
5979 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
5980 ExpectNone(*scroll_info
.get(), root_id
);
5984 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
5985 // Scroll a child layer beyond its maximum scroll range and make sure the
5986 // the scroll doesn't bubble up to the parent layer.
5987 gfx::Size
surface_size(10, 10);
5988 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
5989 scoped_ptr
<LayerImpl
> root_scrolling
=
5990 CreateScrollableLayer(2, surface_size
, root
.get());
5992 scoped_ptr
<LayerImpl
> grand_child
=
5993 CreateScrollableLayer(4, surface_size
, root
.get());
5994 grand_child
->SetScrollOffset(gfx::Vector2d(0, 2));
5996 scoped_ptr
<LayerImpl
> child
=
5997 CreateScrollableLayer(3, surface_size
, root
.get());
5998 child
->SetScrollOffset(gfx::Vector2d(0, 4));
5999 child
->AddChild(grand_child
.Pass());
6001 root_scrolling
->AddChild(child
.Pass());
6002 root
->AddChild(root_scrolling
.Pass());
6003 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
6004 host_impl_
->active_tree()->DidBecomeActive();
6005 host_impl_
->SetViewportSize(surface_size
);
6008 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
6010 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
6011 LayerImpl
* grand_child
= child
->children()[0];
6013 gfx::Vector2d
scroll_delta(0, -2);
6014 EXPECT_EQ(InputHandler::ScrollStarted
,
6015 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6016 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6018 // The grand child should have scrolled up to its limit.
6019 scroll_info
= host_impl_
->ProcessScrollDeltas();
6020 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6021 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6022 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6024 // The child should have received the bubbled delta, but the locked
6025 // scrolling layer should remain set as the grand child.
6026 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6027 scroll_info
= host_impl_
->ProcessScrollDeltas();
6028 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6029 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6030 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
6031 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6033 // The first |ScrollBy| after the fling should re-lock the scrolling
6034 // layer to the first layer that scrolled, which is the child.
6035 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6036 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6037 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6039 // The child should have scrolled up to its limit.
6040 scroll_info
= host_impl_
->ProcessScrollDeltas();
6041 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6042 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6043 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
6045 // As the locked layer is at it's limit, no further scrolling can occur.
6046 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6047 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6048 host_impl_
->ScrollEnd();
6052 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
6053 // When flinging via wheel, the root should eventually scroll (we should
6055 gfx::Size
surface_size(10, 10);
6056 gfx::Size
content_size(20, 20);
6057 scoped_ptr
<LayerImpl
> root_clip
=
6058 LayerImpl::Create(host_impl_
->active_tree(), 3);
6059 scoped_ptr
<LayerImpl
> root_scroll
=
6060 CreateScrollableLayer(1, content_size
, root_clip
.get());
6061 int root_scroll_id
= root_scroll
->id();
6062 scoped_ptr
<LayerImpl
> child
=
6063 CreateScrollableLayer(2, content_size
, root_clip
.get());
6065 root_scroll
->AddChild(child
.Pass());
6066 root_clip
->AddChild(root_scroll
.Pass());
6068 host_impl_
->SetViewportSize(surface_size
);
6069 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6070 host_impl_
->active_tree()->DidBecomeActive();
6073 EXPECT_EQ(InputHandler::ScrollStarted
,
6074 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6076 EXPECT_EQ(InputHandler::ScrollStarted
,
6077 host_impl_
->FlingScrollBegin());
6079 gfx::Vector2d
scroll_delta(0, 100);
6080 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6081 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6083 host_impl_
->ScrollEnd();
6085 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6086 host_impl_
->ProcessScrollDeltas();
6088 // The root should have scrolled.
6089 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6090 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6094 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6095 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6096 // we should return ScrollUnknown.
6097 gfx::Size
content_size(100, 100);
6098 SetupScrollAndContentsLayers(content_size
);
6100 int scroll_layer_id
= 2;
6101 LayerImpl
* scroll_layer
=
6102 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6103 scroll_layer
->SetDrawsContent(true);
6105 int page_scale_layer_id
= 5;
6106 LayerImpl
* page_scale_layer
=
6107 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6109 int occluder_layer_id
= 6;
6110 scoped_ptr
<LayerImpl
> occluder_layer
=
6111 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6112 occluder_layer
->SetDrawsContent(true);
6113 occluder_layer
->SetBounds(content_size
);
6114 occluder_layer
->SetContentBounds(content_size
);
6115 occluder_layer
->SetPosition(gfx::PointF());
6117 // The parent of the occluder is *above* the scroller.
6118 page_scale_layer
->AddChild(occluder_layer
.Pass());
6122 EXPECT_EQ(InputHandler::ScrollUnknown
,
6123 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6126 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6127 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6128 // is not the first scroller we encounter when walking up from the layer, we
6129 // should also return ScrollUnknown.
6130 gfx::Size
content_size(100, 100);
6131 SetupScrollAndContentsLayers(content_size
);
6133 int scroll_layer_id
= 2;
6134 LayerImpl
* scroll_layer
=
6135 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6136 scroll_layer
->SetDrawsContent(true);
6138 int occluder_layer_id
= 6;
6139 scoped_ptr
<LayerImpl
> occluder_layer
=
6140 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6141 occluder_layer
->SetDrawsContent(true);
6142 occluder_layer
->SetBounds(content_size
);
6143 occluder_layer
->SetContentBounds(content_size
);
6144 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6146 int child_scroll_clip_layer_id
= 7;
6147 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6148 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6150 int child_scroll_layer_id
= 8;
6151 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6152 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6154 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6156 child_scroll
->AddChild(occluder_layer
.Pass());
6157 scroll_layer
->AddChild(child_scroll
.Pass());
6161 EXPECT_EQ(InputHandler::ScrollUnknown
,
6162 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6165 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6166 gfx::Size
content_size(100, 100);
6167 SetupScrollAndContentsLayers(content_size
);
6169 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6171 int scroll_layer_id
= 2;
6172 LayerImpl
* scroll_layer
=
6173 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6175 int child_scroll_layer_id
= 7;
6176 scoped_ptr
<LayerImpl
> child_scroll
=
6177 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6178 child_scroll
->SetDrawsContent(false);
6180 scroll_layer
->AddChild(child_scroll
.Pass());
6184 // We should not have scrolled |child_scroll| even though we technically "hit"
6185 // it. The reason for this is that if the scrolling the scroll would not move
6186 // any layer that is a drawn RSLL member, then we can ignore the hit.
6188 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6189 // overscrolling the inner viewport.
6190 EXPECT_EQ(InputHandler::ScrollStarted
,
6191 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6193 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6196 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6197 // This test case is very similar to the one above with one key difference:
6198 // the invisible scroller has a scroll child that is indeed draw contents.
6199 // If we attempt to initiate a gesture scroll off of the visible scroll child
6200 // we should still start the scroll child.
6201 gfx::Size
content_size(100, 100);
6202 SetupScrollAndContentsLayers(content_size
);
6204 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6206 int scroll_layer_id
= 2;
6207 LayerImpl
* scroll_layer
=
6208 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6210 int scroll_child_id
= 6;
6211 scoped_ptr
<LayerImpl
> scroll_child
=
6212 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6213 scroll_child
->SetDrawsContent(true);
6214 scroll_child
->SetBounds(content_size
);
6215 scroll_child
->SetContentBounds(content_size
);
6216 // Move the scroll child so it's not hit by our test point.
6217 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6219 int invisible_scroll_layer_id
= 7;
6220 scoped_ptr
<LayerImpl
> invisible_scroll
=
6221 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6222 invisible_scroll
->SetDrawsContent(false);
6224 int container_id
= 8;
6225 scoped_ptr
<LayerImpl
> container
=
6226 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6228 scoped_ptr
<std::set
<LayerImpl
*> > scroll_children(new std::set
<LayerImpl
*>());
6229 scroll_children
->insert(scroll_child
.get());
6230 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6232 scroll_child
->SetScrollParent(invisible_scroll
.get());
6234 container
->AddChild(invisible_scroll
.Pass());
6235 container
->AddChild(scroll_child
.Pass());
6237 scroll_layer
->AddChild(container
.Pass());
6241 // We should not have scrolled |child_scroll| even though we technically "hit"
6242 // it. The reason for this is that if the scrolling the scroll would not move
6243 // any layer that is a drawn RSLL member, then we can ignore the hit.
6245 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6246 // overscrolling the inner viewport.
6247 EXPECT_EQ(InputHandler::ScrollStarted
,
6248 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6250 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6253 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6254 // to CompositorFrameMetadata after SwapBuffers();
6255 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6256 scoped_ptr
<SolidColorLayerImpl
> root
=
6257 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6258 root
->SetPosition(gfx::PointF());
6259 root
->SetBounds(gfx::Size(10, 10));
6260 root
->SetContentBounds(gfx::Size(10, 10));
6261 root
->SetDrawsContent(true);
6263 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6265 FakeOutputSurface
* fake_output_surface
=
6266 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6268 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6269 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6270 EXPECT_TRUE(metadata_latency_before
.empty());
6272 ui::LatencyInfo latency_info
;
6273 latency_info
.AddLatencyNumber(
6274 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6275 scoped_ptr
<SwapPromise
> swap_promise(
6276 new LatencyInfoSwapPromise(latency_info
));
6277 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
6278 host_impl_
->SetNeedsRedraw();
6280 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6281 LayerTreeHostImpl::FrameData frame
;
6282 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6283 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6284 host_impl_
->DidDrawAllLayers(frame
);
6285 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6287 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
6288 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6289 EXPECT_EQ(1u, metadata_latency_after
.size());
6290 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
6291 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
6294 TEST_F(LayerTreeHostImplTest
, SelectionBoundsPassedToCompositorFrameMetadata
) {
6295 int root_layer_id
= 1;
6296 scoped_ptr
<SolidColorLayerImpl
> root
=
6297 SolidColorLayerImpl::Create(host_impl_
->active_tree(), root_layer_id
);
6298 root
->SetPosition(gfx::PointF());
6299 root
->SetBounds(gfx::Size(10, 10));
6300 root
->SetContentBounds(gfx::Size(10, 10));
6301 root
->SetDrawsContent(true);
6303 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6305 // Ensure the default frame selection bounds are empty.
6306 FakeOutputSurface
* fake_output_surface
=
6307 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6308 const ViewportSelectionBound
& selection_anchor_before
=
6309 fake_output_surface
->last_sent_frame().metadata
.selection_anchor
;
6310 const ViewportSelectionBound
& selection_focus_before
=
6311 fake_output_surface
->last_sent_frame().metadata
.selection_focus
;
6312 EXPECT_EQ(ViewportSelectionBound(), selection_anchor_before
);
6313 EXPECT_EQ(ViewportSelectionBound(), selection_focus_before
);
6315 // Plumb the layer-local selection bounds.
6316 gfx::Rect
selection_rect(5, 0, 0, 5);
6317 LayerSelectionBound anchor
, focus
;
6318 anchor
.type
= SELECTION_BOUND_CENTER
;
6319 anchor
.layer_id
= root_layer_id
;
6320 anchor
.layer_rect
= selection_rect
;
6322 host_impl_
->active_tree()->RegisterSelection(anchor
, focus
);
6324 // Trigger a draw-swap sequence.
6325 host_impl_
->SetNeedsRedraw();
6327 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6328 LayerTreeHostImpl::FrameData frame
;
6329 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6330 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6331 host_impl_
->DidDrawAllLayers(frame
);
6332 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6334 // Ensure the selection bounds have propagated to the frame metadata.
6335 const ViewportSelectionBound
& selection_anchor_after
=
6336 fake_output_surface
->last_sent_frame().metadata
.selection_anchor
;
6337 const ViewportSelectionBound
& selection_focus_after
=
6338 fake_output_surface
->last_sent_frame().metadata
.selection_focus
;
6339 EXPECT_EQ(anchor
.type
, selection_anchor_after
.type
);
6340 EXPECT_EQ(focus
.type
, selection_focus_after
.type
);
6341 EXPECT_EQ(selection_rect
, selection_anchor_after
.viewport_rect
);
6342 EXPECT_EQ(selection_rect
, selection_anchor_after
.viewport_rect
);
6343 EXPECT_TRUE(selection_anchor_after
.visible
);
6344 EXPECT_TRUE(selection_anchor_after
.visible
);
6347 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
6349 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
6350 LayerTreeHostImpl
* layer_tree_host_impl
,
6351 int* set_needs_commit_count
,
6352 int* set_needs_redraw_count
)
6353 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
6354 set_needs_commit_count_(set_needs_commit_count
),
6355 set_needs_redraw_count_(set_needs_redraw_count
) {}
6357 virtual ~SimpleSwapPromiseMonitor() {}
6359 virtual void OnSetNeedsCommitOnMain() OVERRIDE
{
6360 (*set_needs_commit_count_
)++;
6363 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE
{
6364 (*set_needs_redraw_count_
)++;
6368 int* set_needs_commit_count_
;
6369 int* set_needs_redraw_count_
;
6372 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
6373 int set_needs_commit_count
= 0;
6374 int set_needs_redraw_count
= 0;
6377 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6378 new SimpleSwapPromiseMonitor(NULL
,
6380 &set_needs_commit_count
,
6381 &set_needs_redraw_count
));
6382 host_impl_
->SetNeedsRedraw();
6383 EXPECT_EQ(0, set_needs_commit_count
);
6384 EXPECT_EQ(1, set_needs_redraw_count
);
6387 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
6389 host_impl_
->SetNeedsRedraw();
6390 EXPECT_EQ(0, set_needs_commit_count
);
6391 EXPECT_EQ(1, set_needs_redraw_count
);
6394 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6395 new SimpleSwapPromiseMonitor(NULL
,
6397 &set_needs_commit_count
,
6398 &set_needs_redraw_count
));
6399 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
6400 EXPECT_EQ(0, set_needs_commit_count
);
6401 EXPECT_EQ(2, set_needs_redraw_count
);
6405 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6406 new SimpleSwapPromiseMonitor(NULL
,
6408 &set_needs_commit_count
,
6409 &set_needs_redraw_count
));
6410 // Empty damage rect won't signal the monitor.
6411 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
6412 EXPECT_EQ(0, set_needs_commit_count
);
6413 EXPECT_EQ(2, set_needs_redraw_count
);
6417 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
6419 virtual void SetUp() OVERRIDE
{
6420 LayerTreeSettings settings
= DefaultSettings();
6421 settings
.calculate_top_controls_position
= true;
6422 settings
.top_controls_height
= top_controls_height_
;
6423 CreateHostImpl(settings
, CreateOutputSurface());
6427 static const int top_controls_height_
;
6430 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
6432 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
6433 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6434 ->SetScrollOffset(gfx::Vector2d(0, 10));
6435 host_impl_
->Animate(base::TimeTicks());
6436 EXPECT_FALSE(did_request_redraw_
);
6439 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
6440 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6441 ->SetScrollOffset(gfx::Vector2d(0, 10));
6442 host_impl_
->DidChangeTopControlsPosition();
6443 EXPECT_TRUE(did_request_animate_
);
6444 EXPECT_TRUE(did_request_redraw_
);
6447 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
6448 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
6449 host_impl_
->SetViewportSize(gfx::Size(100, 100));
6452 EXPECT_EQ(InputHandler::ScrollStarted
,
6453 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6454 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6455 EXPECT_EQ(gfx::Vector2dF().ToString(),
6456 scroll_layer
->TotalScrollOffset().ToString());
6458 // Scroll just the top controls and verify that the scroll succeeds.
6459 const float residue
= 10;
6460 float offset
= top_controls_height_
- residue
;
6461 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6462 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->controls_top_offset());
6463 EXPECT_EQ(gfx::Vector2dF().ToString(),
6464 scroll_layer
->TotalScrollOffset().ToString());
6466 // Scroll across the boundary
6467 const float content_scroll
= 20;
6468 offset
= residue
+ content_scroll
;
6469 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6470 EXPECT_EQ(-top_controls_height_
,
6471 host_impl_
->top_controls_manager()->controls_top_offset());
6472 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
6473 scroll_layer
->TotalScrollOffset().ToString());
6475 // Now scroll back to the top of the content
6476 offset
= -content_scroll
;
6477 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6478 EXPECT_EQ(-top_controls_height_
,
6479 host_impl_
->top_controls_manager()->controls_top_offset());
6480 EXPECT_EQ(gfx::Vector2dF().ToString(),
6481 scroll_layer
->TotalScrollOffset().ToString());
6483 // And scroll the top controls completely into view
6484 offset
= -top_controls_height_
;
6485 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6486 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6487 EXPECT_EQ(gfx::Vector2dF().ToString(),
6488 scroll_layer
->TotalScrollOffset().ToString());
6490 // And attempt to scroll past the end
6491 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6492 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6493 EXPECT_EQ(gfx::Vector2dF().ToString(),
6494 scroll_layer
->TotalScrollOffset().ToString());
6496 host_impl_
->ScrollEnd();
6499 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
6501 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
6502 const gfx::Size
& outer_viewport
,
6503 const gfx::Size
& inner_viewport
) {
6504 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
6505 const int kOuterViewportClipLayerId
= 6;
6506 const int kOuterViewportScrollLayerId
= 7;
6507 const int kInnerViewportScrollLayerId
= 2;
6508 const int kInnerViewportClipLayerId
= 4;
6509 const int kPageScaleLayerId
= 5;
6511 scoped_ptr
<LayerImpl
> inner_scroll
=
6512 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
6513 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
6514 inner_scroll
->SetScrollOffset(gfx::Vector2d());
6516 scoped_ptr
<LayerImpl
> inner_clip
=
6517 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
6518 inner_clip
->SetBounds(inner_viewport
);
6520 scoped_ptr
<LayerImpl
> page_scale
=
6521 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
6523 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
6524 inner_scroll
->SetBounds(outer_viewport
);
6525 inner_scroll
->SetContentBounds(outer_viewport
);
6526 inner_scroll
->SetPosition(gfx::PointF());
6528 scoped_ptr
<LayerImpl
> outer_clip
=
6529 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
6530 outer_clip
->SetBounds(outer_viewport
);
6531 outer_clip
->SetIsContainerForFixedPositionLayers(true);
6533 scoped_ptr
<LayerImpl
> outer_scroll
=
6534 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
6535 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
6536 outer_scroll
->SetScrollOffset(gfx::Vector2d());
6537 outer_scroll
->SetBounds(content_size
);
6538 outer_scroll
->SetContentBounds(content_size
);
6539 outer_scroll
->SetPosition(gfx::PointF());
6541 scoped_ptr
<LayerImpl
> contents
=
6542 LayerImpl::Create(layer_tree_impl
, 8);
6543 contents
->SetDrawsContent(true);
6544 contents
->SetBounds(content_size
);
6545 contents
->SetContentBounds(content_size
);
6546 contents
->SetPosition(gfx::PointF());
6548 outer_scroll
->AddChild(contents
.Pass());
6549 outer_clip
->AddChild(outer_scroll
.Pass());
6550 inner_scroll
->AddChild(outer_clip
.Pass());
6551 page_scale
->AddChild(inner_scroll
.Pass());
6552 inner_clip
->AddChild(page_scale
.Pass());
6554 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
6555 layer_tree_impl
->SetViewportLayersFromIds(kPageScaleLayerId
,
6556 kInnerViewportScrollLayerId
, kOuterViewportScrollLayerId
);
6558 host_impl_
->active_tree()->DidBecomeActive();
6562 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
6563 gfx::Size content_size
= gfx::Size(100, 160);
6564 gfx::Size outer_viewport
= gfx::Size(50, 80);
6565 gfx::Size inner_viewport
= gfx::Size(25, 40);
6567 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
6569 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
6570 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
6573 gfx::Vector2dF inner_expected
;
6574 gfx::Vector2dF outer_expected
;
6575 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6576 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6578 // Make sure the fling goes to the outer viewport first
6579 EXPECT_EQ(InputHandler::ScrollStarted
,
6580 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6581 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6583 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
6584 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6585 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6587 host_impl_
->ScrollEnd();
6589 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6590 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6592 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
6593 EXPECT_EQ(InputHandler::ScrollStarted
,
6594 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6595 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6597 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6598 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6600 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6601 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6603 host_impl_
->ScrollEnd();
6605 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6606 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6610 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
6612 virtual void SetUp() OVERRIDE
{
6613 LayerTreeSettings settings
= DefaultSettings();
6614 settings
.max_memory_for_prepaint_percentage
= 50;
6615 CreateHostImpl(settings
, CreateOutputSurface());
6619 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
6620 // Set up a memory policy and percentages which could cause
6621 // 32-bit integer overflows.
6622 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
6624 // Verify implicit limits are calculated correctly with no overflows
6625 host_impl_
->SetMemoryPolicy(mem_policy
);
6626 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
6627 300u * 1024u * 1024u);
6628 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
6629 150u * 1024u * 1024u);
6632 TEST_F(LayerTreeHostImplTest
, ExternalTransformReflectedInNextDraw
) {
6633 const gfx::Size
layer_size(100, 100);
6634 gfx::Transform external_transform
;
6635 const gfx::Rect
external_viewport(layer_size
);
6636 const gfx::Rect
external_clip(layer_size
);
6637 const bool valid_for_tile_management
= true;
6638 LayerImpl
* layer
= SetupScrollAndContentsLayers(layer_size
);
6640 host_impl_
->SetExternalDrawConstraints(external_transform
,
6643 valid_for_tile_management
);
6645 EXPECT_TRANSFORMATION_MATRIX_EQ(
6646 external_transform
, layer
->draw_properties().target_space_transform
);
6648 external_transform
.Translate(20, 20);
6649 host_impl_
->SetExternalDrawConstraints(external_transform
,
6652 valid_for_tile_management
);
6654 EXPECT_TRANSFORMATION_MATRIX_EQ(
6655 external_transform
, layer
->draw_properties().target_space_transform
);