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/quad_sink.h"
24 #include "cc/layers/render_surface_impl.h"
25 #include "cc/layers/solid_color_layer_impl.h"
26 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
27 #include "cc/layers/texture_layer_impl.h"
28 #include "cc/layers/tiled_layer_impl.h"
29 #include "cc/layers/video_layer_impl.h"
30 #include "cc/output/begin_frame_args.h"
31 #include "cc/output/compositor_frame_ack.h"
32 #include "cc/output/compositor_frame_metadata.h"
33 #include "cc/output/copy_output_request.h"
34 #include "cc/output/copy_output_result.h"
35 #include "cc/output/gl_renderer.h"
36 #include "cc/quads/render_pass_draw_quad.h"
37 #include "cc/quads/solid_color_draw_quad.h"
38 #include "cc/quads/texture_draw_quad.h"
39 #include "cc/quads/tile_draw_quad.h"
40 #include "cc/resources/layer_tiling_data.h"
41 #include "cc/test/animation_test_common.h"
42 #include "cc/test/fake_layer_tree_host_impl.h"
43 #include "cc/test/fake_output_surface.h"
44 #include "cc/test/fake_output_surface_client.h"
45 #include "cc/test/fake_picture_layer_impl.h"
46 #include "cc/test/fake_picture_pile_impl.h"
47 #include "cc/test/fake_proxy.h"
48 #include "cc/test/fake_rendering_stats_instrumentation.h"
49 #include "cc/test/fake_video_frame_provider.h"
50 #include "cc/test/geometry_test_utils.h"
51 #include "cc/test/layer_test_common.h"
52 #include "cc/test/render_pass_test_common.h"
53 #include "cc/test/test_shared_bitmap_manager.h"
54 #include "cc/test/test_web_graphics_context_3d.h"
55 #include "cc/trees/layer_tree_impl.h"
56 #include "cc/trees/single_thread_proxy.h"
57 #include "media/base/media.h"
58 #include "testing/gmock/include/gmock/gmock.h"
59 #include "testing/gtest/include/gtest/gtest.h"
60 #include "third_party/skia/include/core/SkMallocPixelRef.h"
61 #include "ui/gfx/frame_time.h"
62 #include "ui/gfx/rect_conversions.h"
63 #include "ui/gfx/size_conversions.h"
64 #include "ui/gfx/vector2d_conversions.h"
66 using ::testing::Mock
;
67 using ::testing::Return
;
68 using ::testing::AnyNumber
;
69 using ::testing::AtLeast
;
71 using media::VideoFrame
;
76 class LayerTreeHostImplTest
: public testing::Test
,
77 public LayerTreeHostImplClient
{
79 LayerTreeHostImplTest()
80 : proxy_(base::MessageLoopProxy::current()),
81 always_impl_thread_(&proxy_
),
82 always_main_thread_blocked_(&proxy_
),
83 shared_bitmap_manager_(new TestSharedBitmapManager()),
84 on_can_draw_state_changed_called_(false),
85 did_notify_ready_to_activate_(false),
86 did_request_commit_(false),
87 did_request_redraw_(false),
88 did_request_animate_(false),
89 did_request_manage_tiles_(false),
90 did_upload_visible_tile_(false),
91 reduce_memory_result_(true),
92 current_limit_bytes_(0),
93 current_priority_cutoff_value_(0) {
94 media::InitializeMediaLibraryForTesting();
97 LayerTreeSettings
DefaultSettings() {
98 LayerTreeSettings settings
;
99 settings
.minimum_occlusion_tracking_size
= gfx::Size();
100 settings
.impl_side_painting
= true;
101 settings
.texture_id_allocation_chunk_size
= 1;
102 settings
.report_overscroll_only_for_scrollable_axes
= true;
106 virtual void SetUp() OVERRIDE
{
107 CreateHostImpl(DefaultSettings(), CreateOutputSurface());
110 virtual void TearDown() OVERRIDE
{}
112 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{}
113 virtual void DidLoseOutputSurfaceOnImplThread() OVERRIDE
{}
114 virtual void CommitVSyncParameters(base::TimeTicks timebase
,
115 base::TimeDelta interval
) OVERRIDE
{}
116 virtual void SetEstimatedParentDrawTime(base::TimeDelta draw_time
) OVERRIDE
{}
117 virtual void SetMaxSwapsPendingOnImplThread(int max
) OVERRIDE
{}
118 virtual void DidSwapBuffersOnImplThread() OVERRIDE
{}
119 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{}
120 virtual void BeginFrame(const BeginFrameArgs
& args
) OVERRIDE
{}
121 virtual void OnCanDrawStateChanged(bool can_draw
) OVERRIDE
{
122 on_can_draw_state_changed_called_
= true;
124 virtual void NotifyReadyToActivate() OVERRIDE
{
125 did_notify_ready_to_activate_
= true;
126 host_impl_
->ActivatePendingTree();
128 virtual void SetNeedsRedrawOnImplThread() OVERRIDE
{
129 did_request_redraw_
= true;
131 virtual void SetNeedsRedrawRectOnImplThread(
132 const gfx::Rect
& damage_rect
) OVERRIDE
{
133 did_request_redraw_
= true;
135 virtual void SetNeedsAnimateOnImplThread() OVERRIDE
{
136 did_request_animate_
= true;
138 virtual void SetNeedsManageTilesOnImplThread() OVERRIDE
{
139 did_request_manage_tiles_
= true;
141 virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE
{
142 did_upload_visible_tile_
= true;
144 virtual void SetNeedsCommitOnImplThread() OVERRIDE
{
145 did_request_commit_
= true;
147 virtual void PostAnimationEventsToMainThreadOnImplThread(
148 scoped_ptr
<AnimationEventsVector
> events
) OVERRIDE
{}
149 virtual bool ReduceContentsTextureMemoryOnImplThread(
150 size_t limit_bytes
, int priority_cutoff
) OVERRIDE
{
151 current_limit_bytes_
= limit_bytes
;
152 current_priority_cutoff_value_
= priority_cutoff
;
153 return reduce_memory_result_
;
155 virtual void SendManagedMemoryStats() OVERRIDE
{}
156 virtual bool IsInsideDraw() OVERRIDE
{ return false; }
157 virtual void RenewTreePriority() OVERRIDE
{}
158 virtual void PostDelayedScrollbarFadeOnImplThread(
159 const base::Closure
& start_fade
,
160 base::TimeDelta delay
) OVERRIDE
{
161 scrollbar_fade_start_
= start_fade
;
162 requested_scrollbar_animation_delay_
= delay
;
164 virtual void DidActivatePendingTree() OVERRIDE
{}
165 virtual void DidManageTiles() OVERRIDE
{}
167 void set_reduce_memory_result(bool reduce_memory_result
) {
168 reduce_memory_result_
= reduce_memory_result
;
171 bool CreateHostImpl(const LayerTreeSettings
& settings
,
172 scoped_ptr
<OutputSurface
> output_surface
) {
173 host_impl_
= LayerTreeHostImpl::Create(settings
,
176 &stats_instrumentation_
,
177 shared_bitmap_manager_
.get(),
179 bool init
= host_impl_
->InitializeRenderer(output_surface
.Pass());
180 host_impl_
->SetViewportSize(gfx::Size(10, 10));
184 void SetupRootLayerImpl(scoped_ptr
<LayerImpl
> root
) {
185 root
->SetAnchorPoint(gfx::PointF());
186 root
->SetPosition(gfx::PointF());
187 root
->SetBounds(gfx::Size(10, 10));
188 root
->SetContentBounds(gfx::Size(10, 10));
189 root
->SetDrawsContent(true);
190 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
191 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
194 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
195 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
196 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
197 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
200 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
202 const gfx::Vector2d
& scroll_delta
) {
203 int times_encountered
= 0;
205 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
206 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
208 EXPECT_VECTOR_EQ(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
);
212 ASSERT_EQ(1, times_encountered
);
215 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
216 int times_encountered
= 0;
218 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
219 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
224 ASSERT_EQ(0, times_encountered
);
227 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
228 const gfx::Size
& content_size
) {
229 const int kInnerViewportScrollLayerId
= 2;
230 const int kInnerViewportClipLayerId
= 4;
231 const int kPageScaleLayerId
= 5;
232 scoped_ptr
<LayerImpl
> root
=
233 LayerImpl::Create(layer_tree_impl
, 1);
234 root
->SetBounds(content_size
);
235 root
->SetContentBounds(content_size
);
236 root
->SetPosition(gfx::PointF());
237 root
->SetAnchorPoint(gfx::PointF());
239 scoped_ptr
<LayerImpl
> scroll
=
240 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
241 LayerImpl
* scroll_layer
= scroll
.get();
242 scroll
->SetIsContainerForFixedPositionLayers(true);
243 scroll
->SetScrollOffset(gfx::Vector2d());
245 scoped_ptr
<LayerImpl
> clip
=
246 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
248 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
250 scoped_ptr
<LayerImpl
> page_scale
=
251 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
253 scroll
->SetScrollClipLayer(clip
->id());
254 scroll
->SetBounds(content_size
);
255 scroll
->SetContentBounds(content_size
);
256 scroll
->SetPosition(gfx::PointF());
257 scroll
->SetAnchorPoint(gfx::PointF());
258 scroll
->SetIsContainerForFixedPositionLayers(true);
260 scoped_ptr
<LayerImpl
> contents
=
261 LayerImpl::Create(layer_tree_impl
, 3);
262 contents
->SetDrawsContent(true);
263 contents
->SetBounds(content_size
);
264 contents
->SetContentBounds(content_size
);
265 contents
->SetPosition(gfx::PointF());
266 contents
->SetAnchorPoint(gfx::PointF());
268 scroll
->AddChild(contents
.Pass());
269 page_scale
->AddChild(scroll
.Pass());
270 clip
->AddChild(page_scale
.Pass());
271 root
->AddChild(clip
.Pass());
273 layer_tree_impl
->SetRootLayer(root
.Pass());
274 layer_tree_impl
->SetViewportLayersFromIds(
275 kPageScaleLayerId
, kInnerViewportScrollLayerId
, Layer::INVALID_ID
);
280 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
281 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
282 host_impl_
->active_tree(), content_size
);
283 host_impl_
->active_tree()->DidBecomeActive();
287 // TODO(wjmaclean) Add clip-layer pointer to parameters.
288 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
289 const gfx::Size
& size
,
290 LayerImpl
* clip_layer
) {
292 DCHECK(id
!= clip_layer
->id());
293 scoped_ptr
<LayerImpl
> layer
=
294 LayerImpl::Create(host_impl_
->active_tree(), id
);
295 layer
->SetScrollClipLayer(clip_layer
->id());
296 layer
->SetDrawsContent(true);
297 layer
->SetBounds(size
);
298 layer
->SetContentBounds(size
);
299 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
304 LayerTreeHostImpl::FrameData frame
;
305 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
306 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
307 host_impl_
->DidDrawAllLayers(frame
);
310 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
311 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
312 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
313 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
314 float device_scale_factor
);
316 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
317 // Note: It is not possible to disable the renderer once it has been set,
318 // so we do not need to test that disabling the renderer notifies us
319 // that can_draw changed.
320 EXPECT_FALSE(host_impl_
->CanDraw());
321 on_can_draw_state_changed_called_
= false;
323 // Set up the root layer, which allows us to draw.
324 SetupScrollAndContentsLayers(gfx::Size(100, 100));
325 EXPECT_TRUE(host_impl_
->CanDraw());
326 EXPECT_TRUE(on_can_draw_state_changed_called_
);
327 on_can_draw_state_changed_called_
= false;
329 // Toggle the root layer to make sure it toggles can_draw
330 host_impl_
->active_tree()->SetRootLayer(scoped_ptr
<LayerImpl
>());
331 EXPECT_FALSE(host_impl_
->CanDraw());
332 EXPECT_TRUE(on_can_draw_state_changed_called_
);
333 on_can_draw_state_changed_called_
= false;
335 SetupScrollAndContentsLayers(gfx::Size(100, 100));
336 EXPECT_TRUE(host_impl_
->CanDraw());
337 EXPECT_TRUE(on_can_draw_state_changed_called_
);
338 on_can_draw_state_changed_called_
= false;
340 // Toggle the device viewport size to make sure it toggles can_draw.
341 host_impl_
->SetViewportSize(gfx::Size());
343 EXPECT_TRUE(host_impl_
->CanDraw());
345 EXPECT_FALSE(host_impl_
->CanDraw());
347 EXPECT_TRUE(on_can_draw_state_changed_called_
);
348 on_can_draw_state_changed_called_
= false;
350 host_impl_
->SetViewportSize(gfx::Size(100, 100));
351 EXPECT_TRUE(host_impl_
->CanDraw());
352 EXPECT_TRUE(on_can_draw_state_changed_called_
);
353 on_can_draw_state_changed_called_
= false;
355 // Toggle contents textures purged without causing any evictions,
356 // and make sure that it does not change can_draw.
357 set_reduce_memory_result(false);
358 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
359 host_impl_
->memory_allocation_limit_bytes() - 1));
360 EXPECT_TRUE(host_impl_
->CanDraw());
361 EXPECT_FALSE(on_can_draw_state_changed_called_
);
362 on_can_draw_state_changed_called_
= false;
364 // Toggle contents textures purged to make sure it toggles can_draw.
365 set_reduce_memory_result(true);
366 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
367 host_impl_
->memory_allocation_limit_bytes() - 1));
369 EXPECT_TRUE(host_impl_
->CanDraw());
371 EXPECT_FALSE(host_impl_
->CanDraw());
373 EXPECT_TRUE(on_can_draw_state_changed_called_
);
374 on_can_draw_state_changed_called_
= false;
376 host_impl_
->active_tree()->ResetContentsTexturesPurged();
377 EXPECT_TRUE(host_impl_
->CanDraw());
378 EXPECT_TRUE(on_can_draw_state_changed_called_
);
379 on_can_draw_state_changed_called_
= false;
382 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
385 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
386 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
389 void DrawOneFrame() {
390 LayerTreeHostImpl::FrameData frame_data
;
391 host_impl_
->PrepareToDraw(&frame_data
);
392 host_impl_
->DidDrawAllLayers(frame_data
);
396 DebugScopedSetImplThread always_impl_thread_
;
397 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
399 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
400 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
401 FakeRenderingStatsInstrumentation stats_instrumentation_
;
402 bool on_can_draw_state_changed_called_
;
403 bool did_notify_ready_to_activate_
;
404 bool did_request_commit_
;
405 bool did_request_redraw_
;
406 bool did_request_animate_
;
407 bool did_request_manage_tiles_
;
408 bool did_upload_visible_tile_
;
409 bool reduce_memory_result_
;
410 base::Closure scrollbar_fade_start_
;
411 base::TimeDelta requested_scrollbar_animation_delay_
;
412 size_t current_limit_bytes_
;
413 int current_priority_cutoff_value_
;
416 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
417 bool always_draw
= false;
418 CheckNotifyCalledIfCanDrawChanged(always_draw
);
421 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
422 scoped_ptr
<FakeOutputSurface
> output_surface(
423 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
424 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
426 bool always_draw
= true;
427 CheckNotifyCalledIfCanDrawChanged(always_draw
);
430 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
431 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
433 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
434 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
437 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
439 scoped_ptr
<LayerImpl
> root
=
440 LayerImpl::Create(host_impl_
->active_tree(), 1);
441 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
442 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
443 root
->children()[1]->AddChild(
444 LayerImpl::Create(host_impl_
->active_tree(), 4));
445 root
->children()[1]->AddChild(
446 LayerImpl::Create(host_impl_
->active_tree(), 5));
447 root
->children()[1]->children()[0]->AddChild(
448 LayerImpl::Create(host_impl_
->active_tree(), 6));
449 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
451 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
453 ExpectClearedScrollDeltasRecursive(root
);
455 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
457 scroll_info
= host_impl_
->ProcessScrollDeltas();
458 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
459 ExpectClearedScrollDeltasRecursive(root
);
461 scroll_info
= host_impl_
->ProcessScrollDeltas();
462 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
463 ExpectClearedScrollDeltasRecursive(root
);
466 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
467 gfx::Vector2d
scroll_offset(20, 30);
468 gfx::Vector2d
scroll_delta(11, -15);
470 scoped_ptr
<LayerImpl
> root_clip
=
471 LayerImpl::Create(host_impl_
->active_tree(), 2);
472 scoped_ptr
<LayerImpl
> root
=
473 LayerImpl::Create(host_impl_
->active_tree(), 1);
474 root_clip
->SetBounds(gfx::Size(10, 10));
475 LayerImpl
* root_layer
= root
.get();
476 root_clip
->AddChild(root
.Pass());
477 root_layer
->SetBounds(gfx::Size(110, 110));
478 root_layer
->SetScrollClipLayer(root_clip
->id());
479 root_layer
->SetScrollOffset(scroll_offset
);
480 root_layer
->ScrollBy(scroll_delta
);
481 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
483 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
485 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
487 scroll_info
= host_impl_
->ProcessScrollDeltas();
488 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
489 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
);
490 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
492 gfx::Vector2d
scroll_delta2(-5, 27);
493 root
->ScrollBy(scroll_delta2
);
494 scroll_info
= host_impl_
->ProcessScrollDeltas();
495 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
496 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
497 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
499 root
->ScrollBy(gfx::Vector2d());
500 scroll_info
= host_impl_
->ProcessScrollDeltas();
501 EXPECT_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
504 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
505 SetupScrollAndContentsLayers(gfx::Size(100, 100));
506 host_impl_
->SetViewportSize(gfx::Size(50, 50));
509 EXPECT_EQ(InputHandler::ScrollStarted
,
510 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
511 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
512 InputHandler::Wheel
));
513 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
514 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
515 InputHandler::Wheel
));
516 host_impl_
->ScrollEnd();
517 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
518 InputHandler::Wheel
));
519 EXPECT_TRUE(did_request_redraw_
);
520 EXPECT_TRUE(did_request_commit_
);
523 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
524 // We should not crash when trying to scroll an empty layer tree.
525 EXPECT_EQ(InputHandler::ScrollIgnored
,
526 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
529 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
530 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
531 TestWebGraphicsContext3D::Create();
532 context_owned
->set_context_lost(true);
534 scoped_ptr
<FakeOutputSurface
> output_surface(FakeOutputSurface::Create3d(
535 context_owned
.Pass()));
537 // Initialization will fail.
538 EXPECT_FALSE(CreateHostImpl(DefaultSettings(),
539 output_surface
.PassAs
<OutputSurface
>()));
541 SetupScrollAndContentsLayers(gfx::Size(100, 100));
543 // We should not crash when trying to scroll after the renderer initialization
545 EXPECT_EQ(InputHandler::ScrollIgnored
,
546 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
549 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
550 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
551 host_impl_
->SetViewportSize(gfx::Size(50, 50));
554 // We should not crash if the tree is replaced while we are scrolling.
555 EXPECT_EQ(InputHandler::ScrollStarted
,
556 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
557 host_impl_
->active_tree()->DetachLayerTree();
559 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
561 // We should still be scrolling, because the scrolled layer also exists in the
563 gfx::Vector2d
scroll_delta(0, 10);
564 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
565 host_impl_
->ScrollEnd();
566 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
567 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
570 TEST_F(LayerTreeHostImplTest
, ClearRootRenderSurfaceAndScroll
) {
571 SetupScrollAndContentsLayers(gfx::Size(100, 100));
572 host_impl_
->SetViewportSize(gfx::Size(50, 50));
575 // We should be able to scroll even if the root layer loses its render surface
576 // after the most recent render.
577 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
578 host_impl_
->active_tree()->set_needs_update_draw_properties();
580 EXPECT_EQ(InputHandler::ScrollStarted
,
581 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
584 TEST_F(LayerTreeHostImplTest
, WheelEventHandlers
) {
585 SetupScrollAndContentsLayers(gfx::Size(100, 100));
586 host_impl_
->SetViewportSize(gfx::Size(50, 50));
588 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
590 root
->SetHaveWheelEventHandlers(true);
592 // With registered event handlers, wheel scrolls have to go to the main
594 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
595 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
597 // But gesture scrolls can still be handled.
598 EXPECT_EQ(InputHandler::ScrollStarted
,
599 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
602 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
603 SetupScrollAndContentsLayers(gfx::Size(100, 100));
604 host_impl_
->SetViewportSize(gfx::Size(50, 50));
607 // Ignore the fling since no layer is being scrolled
608 EXPECT_EQ(InputHandler::ScrollIgnored
,
609 host_impl_
->FlingScrollBegin());
611 // Start scrolling a layer
612 EXPECT_EQ(InputHandler::ScrollStarted
,
613 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
615 // Now the fling should go ahead since we've started scrolling a layer
616 EXPECT_EQ(InputHandler::ScrollStarted
,
617 host_impl_
->FlingScrollBegin());
620 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
621 SetupScrollAndContentsLayers(gfx::Size(100, 100));
622 host_impl_
->SetViewportSize(gfx::Size(50, 50));
625 // Ignore the fling since no layer is being scrolled
626 EXPECT_EQ(InputHandler::ScrollIgnored
,
627 host_impl_
->FlingScrollBegin());
629 // Start scrolling a layer
630 EXPECT_EQ(InputHandler::ScrollStarted
,
631 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
633 // Now the fling should go ahead since we've started scrolling a layer
634 EXPECT_EQ(InputHandler::ScrollStarted
,
635 host_impl_
->FlingScrollBegin());
638 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
639 SetupScrollAndContentsLayers(gfx::Size(100, 100));
640 host_impl_
->SetViewportSize(gfx::Size(50, 50));
642 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
644 root
->SetShouldScrollOnMainThread(true);
646 // Start scrolling a layer
647 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
648 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
650 // The fling should be ignored since there's no layer being scrolled impl-side
651 EXPECT_EQ(InputHandler::ScrollIgnored
,
652 host_impl_
->FlingScrollBegin());
655 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
656 SetupScrollAndContentsLayers(gfx::Size(100, 100));
657 host_impl_
->SetViewportSize(gfx::Size(50, 50));
659 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
661 root
->SetShouldScrollOnMainThread(true);
663 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
664 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
665 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
666 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
669 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
670 SetupScrollAndContentsLayers(gfx::Size(200, 200));
671 host_impl_
->SetViewportSize(gfx::Size(100, 100));
673 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
674 root
->SetContentsScale(2.f
, 2.f
);
675 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
679 // All scroll types inside the non-fast scrollable region should fail.
680 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
681 host_impl_
->ScrollBegin(gfx::Point(25, 25),
682 InputHandler::Wheel
));
683 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
684 InputHandler::Wheel
));
685 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
686 host_impl_
->ScrollBegin(gfx::Point(25, 25),
687 InputHandler::Gesture
));
688 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
689 InputHandler::Gesture
));
691 // All scroll types outside this region should succeed.
692 EXPECT_EQ(InputHandler::ScrollStarted
,
693 host_impl_
->ScrollBegin(gfx::Point(75, 75),
694 InputHandler::Wheel
));
695 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
696 InputHandler::Gesture
));
697 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
698 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
699 InputHandler::Gesture
));
700 host_impl_
->ScrollEnd();
701 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
702 InputHandler::Gesture
));
703 EXPECT_EQ(InputHandler::ScrollStarted
,
704 host_impl_
->ScrollBegin(gfx::Point(75, 75),
705 InputHandler::Gesture
));
706 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
707 InputHandler::Gesture
));
708 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
709 host_impl_
->ScrollEnd();
710 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
711 InputHandler::Gesture
));
714 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
715 SetupScrollAndContentsLayers(gfx::Size(200, 200));
716 host_impl_
->SetViewportSize(gfx::Size(100, 100));
718 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
719 root
->SetContentsScale(2.f
, 2.f
);
720 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
721 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
725 // This point would fall into the non-fast scrollable region except that we've
726 // moved the layer down by 25 pixels.
727 EXPECT_EQ(InputHandler::ScrollStarted
,
728 host_impl_
->ScrollBegin(gfx::Point(40, 10),
729 InputHandler::Wheel
));
730 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
731 InputHandler::Wheel
));
732 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
733 host_impl_
->ScrollEnd();
735 // This point is still inside the non-fast region.
736 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
737 host_impl_
->ScrollBegin(gfx::Point(10, 10),
738 InputHandler::Wheel
));
741 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
742 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
743 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
744 host_impl_
->SetViewportSize(gfx::Size(50, 50));
747 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
748 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
749 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
750 host_impl_
->ScrollEnd();
751 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
754 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
755 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
756 scroll_layer
->SetHaveScrollEventHandlers(true);
757 host_impl_
->SetViewportSize(gfx::Size(50, 50));
760 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
761 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
762 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
763 host_impl_
->ScrollEnd();
764 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
767 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
768 SetupScrollAndContentsLayers(gfx::Size(200, 200));
769 host_impl_
->SetViewportSize(gfx::Size(100, 100));
773 EXPECT_EQ(InputHandler::ScrollStarted
,
774 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
776 // Trying to scroll to the left/top will not succeed.
777 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
778 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
779 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
781 // Scrolling to the right/bottom will succeed.
782 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
783 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
784 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
786 // Scrolling to left/top will now succeed.
787 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
788 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
789 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
791 // Scrolling diagonally against an edge will succeed.
792 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
793 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
794 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
796 // Trying to scroll more than the available space will also succeed.
797 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
800 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
801 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
802 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
806 EXPECT_EQ(InputHandler::ScrollStarted
,
807 host_impl_
->ScrollBegin(gfx::Point(),
808 InputHandler::Wheel
));
810 // Trying to scroll without a vertical scrollbar will fail.
811 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
812 gfx::Point(), SCROLL_FORWARD
));
813 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
814 gfx::Point(), SCROLL_BACKWARD
));
816 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
817 PaintedScrollbarLayerImpl::Create(
818 host_impl_
->active_tree(),
821 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
822 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
823 vertical_scrollbar
.get());
825 // Trying to scroll with a vertical scrollbar will succeed.
826 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
827 gfx::Point(), SCROLL_FORWARD
));
828 EXPECT_FLOAT_EQ(875.f
,
829 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
830 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
831 gfx::Point(), SCROLL_BACKWARD
));
834 // The user-scrollability breaks for zoomed-in pages. So disable this.
835 // http://crbug.com/322223
836 TEST_F(LayerTreeHostImplTest
, DISABLED_ScrollWithUserUnscrollableLayers
) {
837 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
838 host_impl_
->SetViewportSize(gfx::Size(100, 100));
840 gfx::Size
overflow_size(400, 400);
841 ASSERT_EQ(1u, scroll_layer
->children().size());
842 LayerImpl
* overflow
= scroll_layer
->children()[0];
843 overflow
->SetBounds(overflow_size
);
844 overflow
->SetContentBounds(overflow_size
);
845 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
846 overflow
->SetScrollOffset(gfx::Vector2d());
847 overflow
->SetPosition(gfx::PointF());
848 overflow
->SetAnchorPoint(gfx::PointF());
851 gfx::Point
scroll_position(10, 10);
853 EXPECT_EQ(InputHandler::ScrollStarted
,
854 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
855 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
856 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->TotalScrollOffset());
858 gfx::Vector2dF
scroll_delta(10, 10);
859 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
860 host_impl_
->ScrollEnd();
861 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
862 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
864 overflow
->set_user_scrollable_horizontal(false);
866 EXPECT_EQ(InputHandler::ScrollStarted
,
867 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
868 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
869 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
871 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
872 host_impl_
->ScrollEnd();
873 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
874 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
876 overflow
->set_user_scrollable_vertical(false);
878 EXPECT_EQ(InputHandler::ScrollStarted
,
879 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
880 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
881 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
883 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
884 host_impl_
->ScrollEnd();
885 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->TotalScrollOffset());
886 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
889 TEST_F(LayerTreeHostImplTest
,
890 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion
) {
891 SetupScrollAndContentsLayers(gfx::Size(100, 100));
892 host_impl_
->SetViewportSize(gfx::Size(50, 50));
895 // We should be able to hit test for touch event handlers even if the root
896 // layer loses its render surface after the most recent render.
897 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
898 host_impl_
->active_tree()->set_needs_update_draw_properties();
900 EXPECT_EQ(host_impl_
->HaveTouchEventHandlersAt(gfx::Point()), false);
903 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
904 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
905 host_impl_
->SetViewportSize(gfx::Size(50, 50));
908 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
909 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
910 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
912 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
913 float page_scale_factor
= 1.f
;
915 // The impl-based pinch zoom should adjust the max scroll position.
917 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
918 page_scale_factor
, min_page_scale
, max_page_scale
);
919 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
920 scroll_layer
->SetScrollDelta(gfx::Vector2d());
922 float page_scale_delta
= 2.f
;
923 gfx::Vector2dF
expected_container_size_delta(
924 container_layer
->bounds().width(), container_layer
->bounds().height());
925 expected_container_size_delta
.Scale((1.f
- page_scale_delta
) /
926 (page_scale_factor
* page_scale_delta
));
928 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
929 host_impl_
->PinchGestureBegin();
930 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
931 // While the gesture is still active, the scroll layer should have a
932 // container size delta = container->bounds() * ((1.f -
933 // page_scale_delta)/())
934 EXPECT_EQ(expected_container_size_delta
,
935 scroll_layer
->FixedContainerSizeDelta());
936 host_impl_
->PinchGestureEnd();
937 host_impl_
->ScrollEnd();
938 EXPECT_FALSE(did_request_animate_
);
939 EXPECT_TRUE(did_request_redraw_
);
940 EXPECT_TRUE(did_request_commit_
);
941 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
943 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
944 host_impl_
->ProcessScrollDeltas();
945 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
947 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
948 scroll_layer
->MaxScrollOffset().ToString());
951 // Scrolling after a pinch gesture should always be in local space. The
952 // scroll deltas do not have the page scale factor applied.
954 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
955 page_scale_factor
, min_page_scale
, max_page_scale
);
956 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
957 scroll_layer
->SetScrollDelta(gfx::Vector2d());
959 float page_scale_delta
= 2.f
;
960 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
961 host_impl_
->PinchGestureBegin();
962 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
963 host_impl_
->PinchGestureEnd();
964 host_impl_
->ScrollEnd();
966 gfx::Vector2d
scroll_delta(0, 10);
967 EXPECT_EQ(InputHandler::ScrollStarted
,
968 host_impl_
->ScrollBegin(gfx::Point(5, 5),
969 InputHandler::Wheel
));
970 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
971 host_impl_
->ScrollEnd();
973 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
974 host_impl_
->ProcessScrollDeltas();
975 ExpectContains(*scroll_info
.get(),
981 TEST_F(LayerTreeHostImplTest
, MasksToBoundsDoesntClobberInnerContainerSize
) {
982 SetupScrollAndContentsLayers(gfx::Size(100, 100));
983 host_impl_
->SetViewportSize(gfx::Size(50, 50));
986 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
987 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
988 DCHECK(scroll_layer
);
990 float min_page_scale
= 1.f
;
991 float max_page_scale
= 4.f
;
992 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
996 // If the container's masks_to_bounds is false, the viewport size should
997 // overwrite the inner viewport container layer's size.
999 EXPECT_EQ(gfx::Size(50, 50),
1000 container_layer
->bounds());
1001 container_layer
->SetMasksToBounds(false);
1003 container_layer
->SetBounds(gfx::Size(30, 25));
1004 EXPECT_EQ(gfx::Size(30, 25),
1005 container_layer
->bounds());
1007 // This should cause a reset of the inner viewport container layer's bounds.
1008 host_impl_
->DidChangeTopControlsPosition();
1010 EXPECT_EQ(gfx::Size(50, 50),
1011 container_layer
->bounds());
1014 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1015 container_layer
->SetBounds(gfx::Size(50, 50));
1017 // If the container's masks_to_bounds is true, the viewport size should
1018 // *NOT* overwrite the inner viewport container layer's size.
1020 EXPECT_EQ(gfx::Size(50, 50),
1021 container_layer
->bounds());
1022 container_layer
->SetMasksToBounds(true);
1024 container_layer
->SetBounds(gfx::Size(30, 25));
1025 EXPECT_EQ(gfx::Size(30, 25),
1026 container_layer
->bounds());
1028 // This should cause a reset of the inner viewport container layer's bounds.
1029 host_impl_
->DidChangeTopControlsPosition();
1031 EXPECT_EQ(gfx::Size(30, 25),
1032 container_layer
->bounds());
1036 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1037 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1038 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1041 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1042 DCHECK(scroll_layer
);
1044 float min_page_scale
= 1.f
;
1045 float max_page_scale
= 4.f
;
1047 // Basic pinch zoom in gesture
1049 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1052 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1054 float page_scale_delta
= 2.f
;
1055 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1056 host_impl_
->PinchGestureBegin();
1057 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1058 host_impl_
->PinchGestureEnd();
1059 host_impl_
->ScrollEnd();
1060 EXPECT_FALSE(did_request_animate_
);
1061 EXPECT_TRUE(did_request_redraw_
);
1062 EXPECT_TRUE(did_request_commit_
);
1064 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1065 host_impl_
->ProcessScrollDeltas();
1066 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1071 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1074 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1075 float page_scale_delta
= 10.f
;
1077 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1078 host_impl_
->PinchGestureBegin();
1079 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1080 host_impl_
->PinchGestureEnd();
1081 host_impl_
->ScrollEnd();
1083 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1084 host_impl_
->ProcessScrollDeltas();
1085 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1088 // Zoom-out clamping
1090 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1093 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1094 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1096 float page_scale_delta
= 0.1f
;
1097 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1098 host_impl_
->PinchGestureBegin();
1099 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1100 host_impl_
->PinchGestureEnd();
1101 host_impl_
->ScrollEnd();
1103 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1104 host_impl_
->ProcessScrollDeltas();
1105 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1107 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1110 // Two-finger panning should not happen based on pinch events only
1112 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1115 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1116 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1118 float page_scale_delta
= 1.f
;
1119 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1120 host_impl_
->PinchGestureBegin();
1121 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1122 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1123 host_impl_
->PinchGestureEnd();
1124 host_impl_
->ScrollEnd();
1126 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1127 host_impl_
->ProcessScrollDeltas();
1128 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1129 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1132 // Two-finger panning should work with interleaved scroll events
1134 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1137 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1138 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1140 float page_scale_delta
= 1.f
;
1141 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1142 host_impl_
->PinchGestureBegin();
1143 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1144 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1145 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1146 host_impl_
->PinchGestureEnd();
1147 host_impl_
->ScrollEnd();
1149 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1150 host_impl_
->ProcessScrollDeltas();
1151 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1152 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1155 // Two-finger panning should work when starting fully zoomed out.
1157 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(0.5f
,
1160 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1161 scroll_layer
->SetScrollOffset(gfx::Vector2d(0, 0));
1163 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1164 host_impl_
->PinchGestureBegin();
1165 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1166 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1167 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1168 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1169 host_impl_
->PinchGestureEnd();
1170 host_impl_
->ScrollEnd();
1172 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1173 host_impl_
->ProcessScrollDeltas();
1174 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1175 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1179 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1180 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1181 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1184 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1185 DCHECK(scroll_layer
);
1187 float min_page_scale
= 0.5f
;
1188 float max_page_scale
= 4.f
;
1189 base::TimeTicks start_time
= base::TimeTicks() +
1190 base::TimeDelta::FromSeconds(1);
1191 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1192 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1193 base::TimeTicks end_time
= start_time
+ duration
;
1195 // Non-anchor zoom-in
1197 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1200 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1202 did_request_redraw_
= false;
1203 did_request_animate_
= false;
1204 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f
, duration
);
1205 EXPECT_FALSE(did_request_redraw_
);
1206 EXPECT_TRUE(did_request_animate_
);
1208 did_request_redraw_
= false;
1209 did_request_animate_
= false;
1210 host_impl_
->Animate(start_time
);
1211 EXPECT_TRUE(did_request_redraw_
);
1212 EXPECT_TRUE(did_request_animate_
);
1214 did_request_redraw_
= false;
1215 did_request_animate_
= false;
1216 host_impl_
->Animate(halfway_through_animation
);
1217 EXPECT_TRUE(did_request_redraw_
);
1218 EXPECT_TRUE(did_request_animate_
);
1220 did_request_redraw_
= false;
1221 did_request_animate_
= false;
1222 did_request_commit_
= false;
1223 host_impl_
->Animate(end_time
);
1224 EXPECT_TRUE(did_request_commit_
);
1225 EXPECT_FALSE(did_request_animate_
);
1227 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1228 host_impl_
->ProcessScrollDeltas();
1229 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1230 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1235 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1238 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1240 did_request_redraw_
= false;
1241 did_request_animate_
= false;
1242 host_impl_
->StartPageScaleAnimation(
1243 gfx::Vector2d(25, 25), true, min_page_scale
, duration
);
1244 EXPECT_FALSE(did_request_redraw_
);
1245 EXPECT_TRUE(did_request_animate_
);
1247 did_request_redraw_
= false;
1248 did_request_animate_
= false;
1249 host_impl_
->Animate(start_time
);
1250 EXPECT_TRUE(did_request_redraw_
);
1251 EXPECT_TRUE(did_request_animate_
);
1253 did_request_redraw_
= false;
1254 did_request_commit_
= false;
1255 did_request_animate_
= false;
1256 host_impl_
->Animate(end_time
);
1257 EXPECT_TRUE(did_request_redraw_
);
1258 EXPECT_FALSE(did_request_animate_
);
1259 EXPECT_TRUE(did_request_commit_
);
1261 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1262 host_impl_
->ProcessScrollDeltas();
1263 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1264 // Pushed to (0,0) via clamping against contents layer size.
1265 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1269 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1270 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1271 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1274 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1275 DCHECK(scroll_layer
);
1277 float min_page_scale
= 0.5f
;
1278 float max_page_scale
= 4.f
;
1279 base::TimeTicks start_time
= base::TimeTicks() +
1280 base::TimeDelta::FromSeconds(1);
1281 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1282 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1283 base::TimeTicks end_time
= start_time
+ duration
;
1285 // Anchor zoom with unchanged page scale should not change scroll or scale.
1287 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1290 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1292 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f
, duration
);
1293 host_impl_
->Animate(start_time
);
1294 host_impl_
->Animate(halfway_through_animation
);
1295 EXPECT_TRUE(did_request_redraw_
);
1296 host_impl_
->Animate(end_time
);
1297 EXPECT_TRUE(did_request_commit_
);
1299 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1300 host_impl_
->ProcessScrollDeltas();
1301 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1302 ExpectNone(*scroll_info
, scroll_layer
->id());
1306 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1308 LayerTreeHostImplOverridePhysicalTime(
1309 const LayerTreeSettings
& settings
,
1310 LayerTreeHostImplClient
* client
,
1312 SharedBitmapManager
* manager
,
1313 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1314 : LayerTreeHostImpl(settings
,
1317 rendering_stats_instrumentation
,
1321 virtual base::TimeTicks
CurrentFrameTimeTicks() OVERRIDE
{
1322 return fake_current_physical_time_
;
1325 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1326 fake_current_physical_time_
= fake_now
;
1330 base::TimeTicks fake_current_physical_time_
;
1333 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1334 gfx::Size viewport_size(10, 10); \
1335 gfx::Size content_size(100, 100); \
1337 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1338 new LayerTreeHostImplOverridePhysicalTime(settings, \
1341 shared_bitmap_manager_.get(), \
1342 &stats_instrumentation_); \
1343 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1344 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1345 host_impl_->SetViewportSize(viewport_size); \
1347 scoped_ptr<LayerImpl> root = \
1348 LayerImpl::Create(host_impl_->active_tree(), 1); \
1349 root->SetBounds(viewport_size); \
1351 scoped_ptr<LayerImpl> scroll = \
1352 LayerImpl::Create(host_impl_->active_tree(), 2); \
1353 scroll->SetScrollClipLayer(root->id()); \
1354 scroll->SetScrollOffset(gfx::Vector2d()); \
1355 root->SetBounds(viewport_size); \
1356 scroll->SetBounds(content_size); \
1357 scroll->SetContentBounds(content_size); \
1358 scroll->SetIsContainerForFixedPositionLayers(true); \
1360 scoped_ptr<LayerImpl> contents = \
1361 LayerImpl::Create(host_impl_->active_tree(), 3); \
1362 contents->SetDrawsContent(true); \
1363 contents->SetBounds(content_size); \
1364 contents->SetContentBounds(content_size); \
1366 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1367 SolidColorScrollbarLayerImpl::Create( \
1368 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \
1369 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1370 scrollbar->SetScrollLayerById(2); \
1371 scrollbar->SetClipLayerById(1); \
1373 scroll->AddChild(contents.Pass()); \
1374 root->AddChild(scroll.Pass()); \
1375 root->AddChild(scrollbar.PassAs<LayerImpl>()); \
1377 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1378 host_impl_->active_tree()->SetViewportLayersFromIds( \
1379 1, 2, Layer::INVALID_ID); \
1380 host_impl_->active_tree()->DidBecomeActive(); \
1383 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1384 LayerTreeSettings settings
;
1385 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1386 settings
.scrollbar_fade_delay_ms
= 20;
1387 settings
.scrollbar_fade_duration_ms
= 20;
1389 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1391 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1393 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1394 EXPECT_FALSE(did_request_redraw_
);
1396 // If no scroll happened during a scroll gesture, it should have no effect.
1397 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1398 host_impl_
->ScrollEnd();
1399 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1400 EXPECT_FALSE(did_request_redraw_
);
1401 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1403 // After a scroll, a fade animation should be scheduled about 20ms from now.
1404 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1405 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1406 host_impl_
->ScrollEnd();
1407 did_request_redraw_
= false;
1408 did_request_animate_
= false;
1409 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1410 requested_scrollbar_animation_delay_
);
1411 EXPECT_FALSE(did_request_redraw_
);
1412 EXPECT_FALSE(did_request_animate_
);
1413 requested_scrollbar_animation_delay_
= base::TimeDelta();
1414 scrollbar_fade_start_
.Run();
1415 host_impl_
->Animate(fake_now
);
1417 // After the fade begins, we should start getting redraws instead of a
1418 // scheduled animation.
1419 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1420 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1421 EXPECT_TRUE(did_request_animate_
);
1422 did_request_animate_
= false;
1424 // Setting the scroll offset outside a scroll should also cause the scrollbar
1425 // to appear and to schedule a fade.
1426 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1427 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1428 requested_scrollbar_animation_delay_
);
1429 EXPECT_FALSE(did_request_redraw_
);
1430 EXPECT_FALSE(did_request_animate_
);
1431 requested_scrollbar_animation_delay_
= base::TimeDelta();
1434 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1435 LayerTreeSettings settings
;
1436 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1437 settings
.scrollbar_fade_delay_ms
= 20;
1438 settings
.scrollbar_fade_duration_ms
= 20;
1439 settings
.use_pinch_zoom_scrollbars
= true;
1441 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1443 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1445 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, 4.f
);
1447 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1448 EXPECT_FALSE(did_request_animate_
);
1450 // If no scroll happened during a scroll gesture, it should have no effect.
1451 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1452 host_impl_
->ScrollEnd();
1453 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1454 EXPECT_FALSE(did_request_animate_
);
1455 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1457 // After a scroll, no fade animation should be scheduled.
1458 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1459 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1460 host_impl_
->ScrollEnd();
1461 did_request_redraw_
= false;
1462 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1463 EXPECT_FALSE(did_request_animate_
);
1464 requested_scrollbar_animation_delay_
= base::TimeDelta();
1466 // We should not see any draw requests.
1467 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1468 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1469 EXPECT_FALSE(did_request_animate_
);
1471 // Make page scale > min so that subsequent scrolls will trigger fades.
1472 host_impl_
->active_tree()->SetPageScaleDelta(1.1f
);
1474 // After a scroll, a fade animation should be scheduled about 20ms from now.
1475 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1476 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1477 host_impl_
->ScrollEnd();
1478 did_request_redraw_
= false;
1479 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1480 requested_scrollbar_animation_delay_
);
1481 EXPECT_FALSE(did_request_animate_
);
1482 requested_scrollbar_animation_delay_
= base::TimeDelta();
1483 scrollbar_fade_start_
.Run();
1485 // After the fade begins, we should start getting redraws instead of a
1486 // scheduled animation.
1487 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1488 host_impl_
->Animate(fake_now
);
1489 EXPECT_TRUE(did_request_animate_
);
1492 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1493 float device_scale_factor
) {
1494 LayerTreeSettings settings
;
1495 settings
.scrollbar_fade_delay_ms
= 500;
1496 settings
.scrollbar_fade_duration_ms
= 300;
1497 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1499 gfx::Size
viewport_size(300, 200);
1500 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1501 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1502 gfx::Size
content_size(1000, 1000);
1504 CreateHostImpl(settings
, CreateOutputSurface());
1505 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1506 host_impl_
->SetViewportSize(device_viewport_size
);
1508 scoped_ptr
<LayerImpl
> root
=
1509 LayerImpl::Create(host_impl_
->active_tree(), 1);
1510 root
->SetBounds(viewport_size
);
1512 scoped_ptr
<LayerImpl
> scroll
=
1513 LayerImpl::Create(host_impl_
->active_tree(), 2);
1514 scroll
->SetScrollClipLayer(root
->id());
1515 scroll
->SetScrollOffset(gfx::Vector2d());
1516 scroll
->SetBounds(content_size
);
1517 scroll
->SetContentBounds(content_size
);
1518 scroll
->SetIsContainerForFixedPositionLayers(true);
1520 scoped_ptr
<LayerImpl
> contents
=
1521 LayerImpl::Create(host_impl_
->active_tree(), 3);
1522 contents
->SetDrawsContent(true);
1523 contents
->SetBounds(content_size
);
1524 contents
->SetContentBounds(content_size
);
1526 // The scrollbar is on the right side.
1527 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1528 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1529 scrollbar
->SetDrawsContent(true);
1530 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1531 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1532 scrollbar
->SetPosition(gfx::Point(285, 0));
1533 scrollbar
->SetClipLayerById(1);
1534 scrollbar
->SetScrollLayerById(2);
1536 scroll
->AddChild(contents
.Pass());
1537 root
->AddChild(scroll
.Pass());
1538 root
->AddChild(scrollbar
.PassAs
<LayerImpl
>());
1540 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1541 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
1542 host_impl_
->active_tree()->DidBecomeActive();
1545 LayerImpl
* root_scroll
=
1546 host_impl_
->active_tree()->InnerViewportScrollLayer();
1547 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1548 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1549 static_cast<ScrollbarAnimationControllerThinning
*>(
1550 root_scroll
->scrollbar_animation_controller());
1551 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1553 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1554 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1556 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1557 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1559 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1560 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1562 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1563 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1564 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1566 did_request_redraw_
= false;
1567 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1568 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1569 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1570 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1571 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1572 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1573 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1576 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1577 SetupMouseMoveAtWithDeviceScale(1.f
);
1580 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1581 SetupMouseMoveAtWithDeviceScale(2.f
);
1584 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1585 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1586 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1587 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
1590 CompositorFrameMetadata metadata
=
1591 host_impl_
->MakeCompositorFrameMetadata();
1592 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1593 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1594 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.viewport_size
);
1595 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1596 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1597 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1600 // Scrolling should update metadata immediately.
1601 EXPECT_EQ(InputHandler::ScrollStarted
,
1602 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1603 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1605 CompositorFrameMetadata metadata
=
1606 host_impl_
->MakeCompositorFrameMetadata();
1607 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1609 host_impl_
->ScrollEnd();
1611 CompositorFrameMetadata metadata
=
1612 host_impl_
->MakeCompositorFrameMetadata();
1613 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1616 // Page scale should update metadata correctly (shrinking only the viewport).
1617 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1618 host_impl_
->PinchGestureBegin();
1619 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1620 host_impl_
->PinchGestureEnd();
1621 host_impl_
->ScrollEnd();
1623 CompositorFrameMetadata metadata
=
1624 host_impl_
->MakeCompositorFrameMetadata();
1625 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1626 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1627 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.viewport_size
);
1628 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1629 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1630 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1633 // Likewise if set from the main thread.
1634 host_impl_
->ProcessScrollDeltas();
1635 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(4.f
, 0.5f
, 4.f
);
1636 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
1638 CompositorFrameMetadata metadata
=
1639 host_impl_
->MakeCompositorFrameMetadata();
1640 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1641 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1642 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.viewport_size
);
1643 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1644 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1645 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1649 // TODO(enne): Convert this to PictureLayerImpl
1650 class DidDrawCheckLayer
: public TiledLayerImpl
{
1652 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1653 return scoped_ptr
<LayerImpl
>(new DidDrawCheckLayer(tree_impl
, id
));
1656 virtual bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
)
1658 will_draw_called_
= true;
1659 if (will_draw_returns_false_
)
1661 return TiledLayerImpl::WillDraw(draw_mode
, provider
);
1664 virtual void AppendQuads(QuadSink
* quad_sink
,
1665 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1666 append_quads_called_
= true;
1667 TiledLayerImpl::AppendQuads(quad_sink
, append_quads_data
);
1670 virtual void DidDraw(ResourceProvider
* provider
) OVERRIDE
{
1671 did_draw_called_
= true;
1672 TiledLayerImpl::DidDraw(provider
);
1675 bool will_draw_called() const { return will_draw_called_
; }
1676 bool append_quads_called() const { return append_quads_called_
; }
1677 bool did_draw_called() const { return did_draw_called_
; }
1679 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1681 void ClearDidDrawCheck() {
1682 will_draw_called_
= false;
1683 append_quads_called_
= false;
1684 did_draw_called_
= false;
1688 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1689 : TiledLayerImpl(tree_impl
, id
),
1690 will_draw_returns_false_(false),
1691 will_draw_called_(false),
1692 append_quads_called_(false),
1693 did_draw_called_(false) {
1694 SetAnchorPoint(gfx::PointF());
1695 SetBounds(gfx::Size(10, 10));
1696 SetContentBounds(gfx::Size(10, 10));
1697 SetDrawsContent(true);
1698 set_skips_draw(false);
1699 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1701 scoped_ptr
<LayerTilingData
> tiler
=
1702 LayerTilingData::Create(gfx::Size(100, 100),
1703 LayerTilingData::HAS_BORDER_TEXELS
);
1704 tiler
->SetTilingRect(gfx::Rect(content_bounds()));
1705 SetTilingData(*tiler
.get());
1709 bool will_draw_returns_false_
;
1710 bool will_draw_called_
;
1711 bool append_quads_called_
;
1712 bool did_draw_called_
;
1715 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1716 // The root layer is always drawn, so run this test on a child layer that
1717 // will be masked out by the root layer's bounds.
1718 host_impl_
->active_tree()->SetRootLayer(
1719 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1720 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1721 host_impl_
->active_tree()->root_layer());
1723 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1724 DidDrawCheckLayer
* layer
=
1725 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1728 LayerTreeHostImpl::FrameData frame
;
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_TRUE(layer
->append_quads_called());
1735 EXPECT_TRUE(layer
->did_draw_called());
1738 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1741 LayerTreeHostImpl::FrameData frame
;
1743 layer
->set_will_draw_returns_false();
1744 layer
->ClearDidDrawCheck();
1746 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1747 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1748 host_impl_
->DidDrawAllLayers(frame
);
1750 EXPECT_TRUE(layer
->will_draw_called());
1751 EXPECT_FALSE(layer
->append_quads_called());
1752 EXPECT_FALSE(layer
->did_draw_called());
1756 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1757 // The root layer is always drawn, so run this test on a child layer that
1758 // will be masked out by the root layer's bounds.
1759 host_impl_
->active_tree()->SetRootLayer(
1760 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1761 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1762 host_impl_
->active_tree()->root_layer());
1763 root
->SetMasksToBounds(true);
1765 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1766 DidDrawCheckLayer
* layer
=
1767 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1768 // Ensure visible_content_rect for layer is empty.
1769 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1770 layer
->SetBounds(gfx::Size(10, 10));
1771 layer
->SetContentBounds(gfx::Size(10, 10));
1773 LayerTreeHostImpl::FrameData frame
;
1775 EXPECT_FALSE(layer
->will_draw_called());
1776 EXPECT_FALSE(layer
->did_draw_called());
1778 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1779 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1780 host_impl_
->DidDrawAllLayers(frame
);
1782 EXPECT_FALSE(layer
->will_draw_called());
1783 EXPECT_FALSE(layer
->did_draw_called());
1785 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1787 // Ensure visible_content_rect for layer is not empty
1788 layer
->SetPosition(gfx::PointF());
1790 EXPECT_FALSE(layer
->will_draw_called());
1791 EXPECT_FALSE(layer
->did_draw_called());
1793 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1794 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1795 host_impl_
->DidDrawAllLayers(frame
);
1797 EXPECT_TRUE(layer
->will_draw_called());
1798 EXPECT_TRUE(layer
->did_draw_called());
1800 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1803 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1804 gfx::Size
big_size(1000, 1000);
1805 host_impl_
->SetViewportSize(big_size
);
1807 host_impl_
->active_tree()->SetRootLayer(
1808 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1809 DidDrawCheckLayer
* root
=
1810 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1812 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1813 DidDrawCheckLayer
* occluded_layer
=
1814 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1816 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1817 DidDrawCheckLayer
* top_layer
=
1818 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1819 // This layer covers the occluded_layer above. Make this layer large so it can
1821 top_layer
->SetBounds(big_size
);
1822 top_layer
->SetContentBounds(big_size
);
1823 top_layer
->SetContentsOpaque(true);
1825 LayerTreeHostImpl::FrameData frame
;
1827 EXPECT_FALSE(occluded_layer
->will_draw_called());
1828 EXPECT_FALSE(occluded_layer
->did_draw_called());
1829 EXPECT_FALSE(top_layer
->will_draw_called());
1830 EXPECT_FALSE(top_layer
->did_draw_called());
1832 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1833 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1834 host_impl_
->DidDrawAllLayers(frame
);
1836 EXPECT_FALSE(occluded_layer
->will_draw_called());
1837 EXPECT_FALSE(occluded_layer
->did_draw_called());
1838 EXPECT_TRUE(top_layer
->will_draw_called());
1839 EXPECT_TRUE(top_layer
->did_draw_called());
1842 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1843 host_impl_
->active_tree()->SetRootLayer(
1844 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1845 DidDrawCheckLayer
* root
=
1846 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1848 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1849 DidDrawCheckLayer
* layer1
=
1850 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1852 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1853 DidDrawCheckLayer
* layer2
=
1854 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1856 layer1
->SetOpacity(0.3f
);
1857 layer1
->SetShouldFlattenTransform(true);
1859 EXPECT_FALSE(root
->did_draw_called());
1860 EXPECT_FALSE(layer1
->did_draw_called());
1861 EXPECT_FALSE(layer2
->did_draw_called());
1863 LayerTreeHostImpl::FrameData frame
;
1864 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1865 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1866 host_impl_
->DidDrawAllLayers(frame
);
1868 EXPECT_TRUE(root
->did_draw_called());
1869 EXPECT_TRUE(layer1
->did_draw_called());
1870 EXPECT_TRUE(layer2
->did_draw_called());
1872 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1873 EXPECT_TRUE(!!layer1
->render_surface());
1876 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1878 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1883 ResourceProvider
* resource_provider
) {
1884 return scoped_ptr
<LayerImpl
>(new MissingTextureAnimatingLayer(
1890 resource_provider
));
1893 virtual void AppendQuads(QuadSink
* quad_sink
,
1894 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1895 TiledLayerImpl::AppendQuads(quad_sink
, append_quads_data
);
1897 append_quads_data
->had_incomplete_tile
= true;
1901 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1906 ResourceProvider
* resource_provider
)
1907 : DidDrawCheckLayer(tree_impl
, id
), tile_missing_(tile_missing
) {
1908 scoped_ptr
<LayerTilingData
> tiling_data
=
1909 LayerTilingData::Create(gfx::Size(10, 10),
1910 LayerTilingData::NO_BORDER_TEXELS
);
1911 tiling_data
->SetTilingRect(gfx::Rect(bounds()));
1912 SetTilingData(*tiling_data
.get());
1913 set_skips_draw(skips_draw
);
1914 if (!tile_missing
) {
1915 ResourceProvider::ResourceId resource
=
1916 resource_provider
->CreateResource(gfx::Size(1, 1),
1918 ResourceProvider::TextureUsageAny
,
1920 resource_provider
->AllocateForTesting(resource
);
1921 PushTileProperties(0, 0, resource
, gfx::Rect(), false);
1924 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1930 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenNoTexturesMissing
) {
1931 host_impl_
->active_tree()->SetRootLayer(
1932 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1933 DidDrawCheckLayer
* root
=
1934 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1936 bool tile_missing
= false;
1937 bool skips_draw
= false;
1938 bool is_animating
= false;
1940 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1945 host_impl_
->resource_provider()));
1947 LayerTreeHostImpl::FrameData frame
;
1949 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1950 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1951 host_impl_
->DidDrawAllLayers(frame
);
1954 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
1955 host_impl_
->active_tree()->SetRootLayer(
1956 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1957 DidDrawCheckLayer
* root
=
1958 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1959 bool tile_missing
= false;
1960 bool skips_draw
= false;
1961 bool is_animating
= true;
1963 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1968 host_impl_
->resource_provider()));
1970 LayerTreeHostImpl::FrameData frame
;
1972 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1973 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1974 host_impl_
->DidDrawAllLayers(frame
);
1977 TEST_F(LayerTreeHostImplTest
,
1978 PrepareToDrawSucceedsWithNonAnimatedMissingTexture
) {
1979 // When a texture is missing and we're not animating, we draw as usual with
1981 host_impl_
->active_tree()->SetRootLayer(
1982 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1983 DidDrawCheckLayer
* root
=
1984 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1986 bool tile_missing
= true;
1987 bool skips_draw
= false;
1988 bool is_animating
= false;
1990 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1995 host_impl_
->resource_provider()));
1996 LayerTreeHostImpl::FrameData frame
;
1997 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1998 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1999 host_impl_
->DidDrawAllLayers(frame
);
2002 TEST_F(LayerTreeHostImplTest
, PrepareToDrawFailsWhenAnimationUsesCheckerboard
) {
2003 // When a texture is missing and we're animating, we don't want to draw
2005 host_impl_
->active_tree()->SetRootLayer(
2006 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2007 DidDrawCheckLayer
* root
=
2008 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2009 bool tile_missing
= true;
2010 bool skips_draw
= false;
2011 bool is_animating
= true;
2013 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2018 host_impl_
->resource_provider()));
2019 LayerTreeHostImpl::FrameData frame
;
2020 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2021 host_impl_
->PrepareToDraw(&frame
));
2022 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2023 host_impl_
->DidDrawAllLayers(frame
);
2026 TEST_F(LayerTreeHostImplTest
,
2027 PrepareToDrawSucceedsWithMissingSkippedAnimatedLayer
) {
2028 // When the layer skips draw and we're animating, we still draw the frame.
2029 host_impl_
->active_tree()->SetRootLayer(
2030 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2031 DidDrawCheckLayer
* root
=
2032 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2033 bool tile_missing
= false;
2034 bool skips_draw
= true;
2035 bool is_animating
= true;
2037 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2042 host_impl_
->resource_provider()));
2043 LayerTreeHostImpl::FrameData frame
;
2044 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2045 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2046 host_impl_
->DidDrawAllLayers(frame
);
2049 TEST_F(LayerTreeHostImplTest
,
2050 PrepareToDrawSucceedsWhenHighResRequiredButNoMissingTextures
) {
2051 // When the layer skips draw and we're animating, we still draw the frame.
2052 host_impl_
->active_tree()->SetRootLayer(
2053 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2054 DidDrawCheckLayer
* root
=
2055 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2056 bool tile_missing
= false;
2057 bool skips_draw
= false;
2058 bool is_animating
= false;
2060 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2065 host_impl_
->resource_provider()));
2066 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2067 LayerTreeHostImpl::FrameData frame
;
2068 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2069 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2070 host_impl_
->DidDrawAllLayers(frame
);
2073 TEST_F(LayerTreeHostImplTest
,
2074 PrepareToDrawFailsWhenHighResRequiredAndMissingTextures
) {
2075 // When the layer skips draw and we're animating, we still draw the frame.
2076 host_impl_
->active_tree()->SetRootLayer(
2077 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2078 DidDrawCheckLayer
* root
=
2079 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2080 bool tile_missing
= true;
2081 bool skips_draw
= false;
2082 bool is_animating
= false;
2084 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2089 host_impl_
->resource_provider()));
2090 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2091 LayerTreeHostImpl::FrameData frame
;
2092 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2093 host_impl_
->PrepareToDraw(&frame
));
2094 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2095 host_impl_
->DidDrawAllLayers(frame
);
2098 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2099 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2100 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2101 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2104 // Scroll event is ignored because layer is not scrollable.
2105 EXPECT_EQ(InputHandler::ScrollIgnored
,
2106 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2107 EXPECT_FALSE(did_request_redraw_
);
2108 EXPECT_FALSE(did_request_commit_
);
2111 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2113 LayerTreeHostImplTopControlsTest()
2114 // Make the clip size the same as the layer (content) size so the layer is
2116 : layer_size_(10, 10),
2117 clip_size_(layer_size_
) {
2118 settings_
.calculate_top_controls_position
= true;
2119 settings_
.top_controls_height
= 50;
2122 gfx::Size(clip_size_
.width(),
2123 clip_size_
.height() + settings_
.top_controls_height
);
2126 void SetupTopControlsAndScrollLayer() {
2127 CreateHostImpl(settings_
, CreateOutputSurface());
2129 scoped_ptr
<LayerImpl
> root
=
2130 LayerImpl::Create(host_impl_
->active_tree(), 1);
2131 scoped_ptr
<LayerImpl
> root_clip
=
2132 LayerImpl::Create(host_impl_
->active_tree(), 2);
2133 root_clip
->SetBounds(clip_size_
);
2134 root
->SetScrollClipLayer(root_clip
->id());
2135 root
->SetBounds(layer_size_
);
2136 root
->SetContentBounds(layer_size_
);
2137 root
->SetPosition(gfx::PointF());
2138 root
->SetAnchorPoint(gfx::PointF());
2139 root
->SetDrawsContent(false);
2140 root
->SetIsContainerForFixedPositionLayers(true);
2141 int inner_viewport_scroll_layer_id
= root
->id();
2142 int page_scale_layer_id
= root_clip
->id();
2143 root_clip
->AddChild(root
.Pass());
2144 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2145 host_impl_
->active_tree()->SetViewportLayersFromIds(
2146 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2147 // Set a viewport size that is large enough to contain both the top controls
2148 // and some content.
2149 host_impl_
->SetViewportSize(viewport_size_
);
2150 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2151 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2155 gfx::Size layer_size_
;
2156 gfx::Size clip_size_
;
2157 gfx::Size viewport_size_
;
2159 LayerTreeSettings settings_
;
2160 }; // class LayerTreeHostImplTopControlsTest
2162 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2163 SetupTopControlsAndScrollLayer();
2166 EXPECT_EQ(InputHandler::ScrollStarted
,
2167 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2169 // Make the test scroll delta a fractional amount, to verify that the
2170 // fixed container size delta is (1) non-zero, and (2) fractional, and
2171 // (3) matches the movement of the top controls.
2172 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2173 host_impl_
->top_controls_manager()->ScrollBegin();
2174 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2175 host_impl_
->top_controls_manager()->ScrollEnd();
2177 LayerImpl
* inner_viewport_scroll_layer
=
2178 host_impl_
->active_tree()->InnerViewportScrollLayer();
2179 DCHECK(inner_viewport_scroll_layer
);
2180 host_impl_
->ScrollEnd();
2181 EXPECT_EQ(top_controls_scroll_delta
,
2182 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2185 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsWithPageScale
) {
2186 SetupTopControlsAndScrollLayer();
2189 EXPECT_EQ(InputHandler::ScrollStarted
,
2190 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2192 float page_scale
= 1.5f
;
2193 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
, 1.f
, 2.f
);
2195 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.f
);
2196 gfx::Vector2dF expected_container_size_delta
=
2197 ScaleVector2d(top_controls_scroll_delta
, 1.f
/ page_scale
);
2198 host_impl_
->top_controls_manager()->ScrollBegin();
2199 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2200 host_impl_
->top_controls_manager()->ScrollEnd();
2202 LayerImpl
* inner_viewport_scroll_layer
=
2203 host_impl_
->active_tree()->InnerViewportScrollLayer();
2204 DCHECK(inner_viewport_scroll_layer
);
2205 host_impl_
->ScrollEnd();
2207 // Use a tolerance that requires the container size delta to be within 0.01
2209 double tolerance
= 0.0001;
2211 (expected_container_size_delta
-
2212 inner_viewport_scroll_layer
->FixedContainerSizeDelta()).LengthSquared(),
2216 TEST_F(LayerTreeHostImplTopControlsTest
,
2217 ScrollNonScrollableRootWithTopControls
) {
2218 SetupTopControlsAndScrollLayer();
2221 EXPECT_EQ(InputHandler::ScrollStarted
,
2222 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2224 host_impl_
->top_controls_manager()->ScrollBegin();
2225 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2226 host_impl_
->top_controls_manager()->ScrollEnd();
2227 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->content_top_offset());
2228 // Now that top controls have moved, expect the clip to resize.
2229 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2230 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2232 host_impl_
->ScrollEnd();
2234 EXPECT_EQ(InputHandler::ScrollStarted
,
2235 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2237 float scroll_increment_y
= -25.f
;
2238 host_impl_
->top_controls_manager()->ScrollBegin();
2239 host_impl_
->top_controls_manager()->ScrollBy(
2240 gfx::Vector2dF(0.f
, scroll_increment_y
));
2241 EXPECT_EQ(-scroll_increment_y
,
2242 host_impl_
->top_controls_manager()->content_top_offset());
2243 // Now that top controls have moved, expect the clip to resize.
2244 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2245 viewport_size_
.height() + scroll_increment_y
),
2246 root_clip_ptr
->bounds());
2248 host_impl_
->top_controls_manager()->ScrollBy(
2249 gfx::Vector2dF(0.f
, scroll_increment_y
));
2250 host_impl_
->top_controls_manager()->ScrollEnd();
2251 EXPECT_EQ(-2 * 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(clip_size_
, root_clip_ptr
->bounds());
2256 host_impl_
->ScrollEnd();
2258 // Verify the layer is once-again non-scrollable.
2261 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2263 EXPECT_EQ(InputHandler::ScrollStarted
,
2264 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2267 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2268 // Test the configuration where a non-composited root layer is embedded in a
2269 // scrollable outer layer.
2270 gfx::Size
surface_size(10, 10);
2271 gfx::Size
contents_size(20, 20);
2273 scoped_ptr
<LayerImpl
> content_layer
=
2274 LayerImpl::Create(host_impl_
->active_tree(), 1);
2275 content_layer
->SetDrawsContent(true);
2276 content_layer
->SetPosition(gfx::PointF());
2277 content_layer
->SetAnchorPoint(gfx::PointF());
2278 content_layer
->SetBounds(contents_size
);
2279 content_layer
->SetContentBounds(contents_size
);
2280 content_layer
->SetContentsScale(2.f
, 2.f
);
2282 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2283 LayerImpl::Create(host_impl_
->active_tree(), 3);
2284 scroll_clip_layer
->SetBounds(surface_size
);
2286 scoped_ptr
<LayerImpl
> scroll_layer
=
2287 LayerImpl::Create(host_impl_
->active_tree(), 2);
2288 scroll_layer
->SetScrollClipLayer(3);
2289 scroll_layer
->SetBounds(contents_size
);
2290 scroll_layer
->SetContentBounds(contents_size
);
2291 scroll_layer
->SetPosition(gfx::PointF());
2292 scroll_layer
->SetAnchorPoint(gfx::PointF());
2293 scroll_layer
->AddChild(content_layer
.Pass());
2294 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2296 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2297 host_impl_
->SetViewportSize(surface_size
);
2300 EXPECT_EQ(InputHandler::ScrollStarted
,
2301 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2302 InputHandler::Wheel
));
2303 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2304 host_impl_
->ScrollEnd();
2305 EXPECT_TRUE(did_request_redraw_
);
2306 EXPECT_TRUE(did_request_commit_
);
2309 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2310 gfx::Size
surface_size(10, 10);
2311 gfx::Size
contents_size(20, 20);
2312 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2313 root
->SetBounds(surface_size
);
2314 root
->SetContentBounds(contents_size
);
2315 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2316 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2317 host_impl_
->SetViewportSize(surface_size
);
2320 EXPECT_EQ(InputHandler::ScrollStarted
,
2321 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2322 InputHandler::Wheel
));
2323 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2324 host_impl_
->ScrollEnd();
2325 EXPECT_TRUE(did_request_redraw_
);
2326 EXPECT_TRUE(did_request_commit_
);
2329 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2330 gfx::Size
surface_size(10, 10);
2331 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2332 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2333 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2334 host_impl_
->SetViewportSize(surface_size
);
2337 // Scroll event is ignored because the input coordinate is outside the layer
2339 EXPECT_EQ(InputHandler::ScrollIgnored
,
2340 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2341 InputHandler::Wheel
));
2342 EXPECT_FALSE(did_request_redraw_
);
2343 EXPECT_FALSE(did_request_commit_
);
2346 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2347 gfx::Size
surface_size(10, 10);
2348 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2349 scoped_ptr
<LayerImpl
> child
=
2350 CreateScrollableLayer(2, surface_size
, root
.get());
2351 host_impl_
->SetViewportSize(surface_size
);
2353 gfx::Transform matrix
;
2354 matrix
.RotateAboutXAxis(180.0);
2355 child
->SetTransform(matrix
);
2356 child
->SetDoubleSided(false);
2358 root
->AddChild(child
.Pass());
2359 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2362 // Scroll event is ignored because the scrollable layer is not facing the
2363 // viewer and there is nothing scrollable behind it.
2364 EXPECT_EQ(InputHandler::ScrollIgnored
,
2365 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2366 InputHandler::Wheel
));
2367 EXPECT_FALSE(did_request_redraw_
);
2368 EXPECT_FALSE(did_request_commit_
);
2371 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2372 gfx::Size
surface_size(10, 10);
2373 scoped_ptr
<LayerImpl
> clip_layer
=
2374 LayerImpl::Create(host_impl_
->active_tree(), 3);
2375 scoped_ptr
<LayerImpl
> content_layer
=
2376 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2377 content_layer
->SetShouldScrollOnMainThread(true);
2378 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2380 // Note: we can use the same clip layer for both since both calls to
2381 // CreateScrollableLayer() use the same surface size.
2382 scoped_ptr
<LayerImpl
> scroll_layer
=
2383 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2384 scroll_layer
->AddChild(content_layer
.Pass());
2385 clip_layer
->AddChild(scroll_layer
.Pass());
2387 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2388 host_impl_
->SetViewportSize(surface_size
);
2391 // Scrolling fails because the content layer is asking to be scrolled on the
2393 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2394 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2395 InputHandler::Wheel
));
2398 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2399 gfx::Size
surface_size(20, 20);
2400 gfx::Size
viewport_size(10, 10);
2401 float page_scale
= 2.f
;
2402 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2403 scoped_ptr
<LayerImpl
> root_clip
=
2404 LayerImpl::Create(host_impl_
->active_tree(), 2);
2405 scoped_ptr
<LayerImpl
> root_scrolling
=
2406 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2407 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2408 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2409 root_clip
->AddChild(root_scrolling
.Pass());
2410 root
->AddChild(root_clip
.Pass());
2411 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2412 // The behaviour in this test assumes the page scale is applied at a layer
2413 // above the clip layer.
2414 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2415 host_impl_
->active_tree()->DidBecomeActive();
2416 host_impl_
->SetViewportSize(viewport_size
);
2419 LayerImpl
* root_scroll
=
2420 host_impl_
->active_tree()->InnerViewportScrollLayer();
2421 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2423 gfx::Vector2d
scroll_delta(0, 10);
2424 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2425 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2426 EXPECT_EQ(InputHandler::ScrollStarted
,
2427 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2428 InputHandler::Wheel
));
2429 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2430 host_impl_
->ScrollEnd();
2432 // Set new page scale from main thread.
2433 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2437 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2438 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2440 // The scroll range should also have been updated.
2441 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2443 // The page scale delta remains constant because the impl thread did not
2445 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2448 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
2449 gfx::Size
surface_size(20, 20);
2450 gfx::Size
viewport_size(10, 10);
2451 float page_scale
= 2.f
;
2452 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2453 scoped_ptr
<LayerImpl
> root_clip
=
2454 LayerImpl::Create(host_impl_
->active_tree(), 2);
2455 scoped_ptr
<LayerImpl
> root_scrolling
=
2456 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2457 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2458 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2459 root_clip
->AddChild(root_scrolling
.Pass());
2460 root
->AddChild(root_clip
.Pass());
2461 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2462 // The behaviour in this test assumes the page scale is applied at a layer
2463 // above the clip layer.
2464 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2465 host_impl_
->active_tree()->DidBecomeActive();
2466 host_impl_
->SetViewportSize(viewport_size
);
2467 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, page_scale
);
2470 LayerImpl
* root_scroll
=
2471 host_impl_
->active_tree()->InnerViewportScrollLayer();
2472 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2474 gfx::Vector2d
scroll_delta(0, 10);
2475 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2476 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2477 EXPECT_EQ(InputHandler::ScrollStarted
,
2478 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2479 InputHandler::Wheel
));
2480 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2481 host_impl_
->ScrollEnd();
2483 // Set new page scale on impl thread by pinching.
2484 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2485 host_impl_
->PinchGestureBegin();
2486 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
2487 host_impl_
->PinchGestureEnd();
2488 host_impl_
->ScrollEnd();
2491 // The scroll delta is not scaled because the main thread did not scale.
2492 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2493 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2495 // The scroll range should also have been updated.
2496 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2498 // The page scale delta should match the new scale on the impl side.
2499 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->total_page_scale_factor());
2502 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
2503 gfx::Size
surface_size(10, 10);
2504 float default_page_scale
= 1.f
;
2505 gfx::Transform default_page_scale_matrix
;
2506 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
2508 float new_page_scale
= 2.f
;
2509 gfx::Transform new_page_scale_matrix
;
2510 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
2512 // Create a normal scrollable root layer and another scrollable child layer.
2513 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
2514 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
2515 LayerImpl
* child
= scroll
->children()[0];
2517 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
2518 LayerImpl::Create(host_impl_
->active_tree(), 6);
2519 scoped_ptr
<LayerImpl
> scrollable_child
=
2520 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
2521 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
2522 child
->AddChild(scrollable_child_clip
.Pass());
2523 LayerImpl
* grand_child
= child
->children()[0];
2525 // Set new page scale on impl thread by pinching.
2526 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2527 host_impl_
->PinchGestureBegin();
2528 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
2529 host_impl_
->PinchGestureEnd();
2530 host_impl_
->ScrollEnd();
2533 EXPECT_EQ(1.f
, root
->contents_scale_x());
2534 EXPECT_EQ(1.f
, root
->contents_scale_y());
2535 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
2536 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
2537 EXPECT_EQ(1.f
, child
->contents_scale_x());
2538 EXPECT_EQ(1.f
, child
->contents_scale_y());
2539 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
2540 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
2542 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2543 // the page scale delta on the root layer is applied hierarchically.
2544 LayerTreeHostImpl::FrameData frame
;
2545 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2546 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2547 host_impl_
->DidDrawAllLayers(frame
);
2549 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
2550 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
2551 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
2552 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
2553 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
2554 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
2555 EXPECT_EQ(new_page_scale
,
2556 grand_child
->draw_transform().matrix().getDouble(0, 0));
2557 EXPECT_EQ(new_page_scale
,
2558 grand_child
->draw_transform().matrix().getDouble(1, 1));
2561 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
2562 gfx::Size
surface_size(30, 30);
2563 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2564 root
->SetBounds(gfx::Size(5, 5));
2565 scoped_ptr
<LayerImpl
> root_scrolling
=
2566 LayerImpl::Create(host_impl_
->active_tree(), 2);
2567 root_scrolling
->SetBounds(surface_size
);
2568 root_scrolling
->SetContentBounds(surface_size
);
2569 root_scrolling
->SetScrollClipLayer(root
->id());
2570 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2571 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
2572 root
->AddChild(root_scrolling
.Pass());
2573 int child_scroll_layer_id
= 3;
2574 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
2575 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
2576 LayerImpl
* child
= child_scrolling
.get();
2577 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
2578 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2579 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2580 host_impl_
->active_tree()->DidBecomeActive();
2581 host_impl_
->SetViewportSize(surface_size
);
2584 gfx::Vector2d
scroll_delta(0, 10);
2585 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
2586 gfx::Vector2d
expected_max_scroll(child
->MaxScrollOffset());
2587 EXPECT_EQ(InputHandler::ScrollStarted
,
2588 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2589 InputHandler::Wheel
));
2590 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2591 host_impl_
->ScrollEnd();
2593 float page_scale
= 2.f
;
2594 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2600 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2602 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
2604 // The scroll range should not have changed.
2605 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
2607 // The page scale delta remains constant because the impl thread did not
2609 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2612 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
2613 // Scroll a child layer beyond its maximum scroll range and make sure the
2614 // parent layer is scrolled on the axis on which the child was unable to
2616 gfx::Size
surface_size(10, 10);
2617 gfx::Size
content_size(20, 20);
2618 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2619 root
->SetBounds(surface_size
);
2621 scoped_ptr
<LayerImpl
> grand_child
=
2622 CreateScrollableLayer(3, content_size
, root
.get());
2624 scoped_ptr
<LayerImpl
> child
=
2625 CreateScrollableLayer(2, content_size
, root
.get());
2626 LayerImpl
* grand_child_layer
= grand_child
.get();
2627 child
->AddChild(grand_child
.Pass());
2629 LayerImpl
* child_layer
= child
.get();
2630 root
->AddChild(child
.Pass());
2631 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2632 host_impl_
->active_tree()->DidBecomeActive();
2633 host_impl_
->SetViewportSize(surface_size
);
2634 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 5));
2635 child_layer
->SetScrollOffset(gfx::Vector2d(3, 0));
2639 gfx::Vector2d
scroll_delta(-8, -7);
2640 EXPECT_EQ(InputHandler::ScrollStarted
,
2641 host_impl_
->ScrollBegin(gfx::Point(),
2642 InputHandler::Wheel
));
2643 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2644 host_impl_
->ScrollEnd();
2646 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2647 host_impl_
->ProcessScrollDeltas();
2649 // The grand child should have scrolled up to its limit.
2650 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
2651 LayerImpl
* grand_child
= child
->children()[0];
2652 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
2654 // The child should have only scrolled on the other axis.
2655 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
2659 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
2660 // Scroll a child layer beyond its maximum scroll range and make sure the
2661 // the scroll doesn't bubble up to the parent layer.
2662 gfx::Size
surface_size(20, 20);
2663 gfx::Size
viewport_size(10, 10);
2664 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2665 scoped_ptr
<LayerImpl
> root_scrolling
=
2666 CreateScrollableLayer(2, surface_size
, root
.get());
2667 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2669 scoped_ptr
<LayerImpl
> grand_child
=
2670 CreateScrollableLayer(4, surface_size
, root
.get());
2672 scoped_ptr
<LayerImpl
> child
=
2673 CreateScrollableLayer(3, surface_size
, root
.get());
2674 LayerImpl
* grand_child_layer
= grand_child
.get();
2675 child
->AddChild(grand_child
.Pass());
2677 LayerImpl
* child_layer
= child
.get();
2678 root_scrolling
->AddChild(child
.Pass());
2679 root
->AddChild(root_scrolling
.Pass());
2680 EXPECT_EQ(viewport_size
, root
->bounds());
2681 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2682 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2683 host_impl_
->active_tree()->DidBecomeActive();
2684 host_impl_
->SetViewportSize(viewport_size
);
2686 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
2687 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
2691 gfx::Vector2d
scroll_delta(0, -10);
2692 EXPECT_EQ(InputHandler::ScrollStarted
,
2693 host_impl_
->ScrollBegin(gfx::Point(),
2694 InputHandler::NonBubblingGesture
));
2695 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2696 host_impl_
->ScrollEnd();
2698 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2699 host_impl_
->ProcessScrollDeltas();
2701 // The grand child should have scrolled up to its limit.
2703 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
2704 LayerImpl
* grand_child
= child
->children()[0];
2705 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2707 // The child should not have scrolled.
2708 ExpectNone(*scroll_info
.get(), child
->id());
2710 // The next time we scroll we should only scroll the parent.
2711 scroll_delta
= gfx::Vector2d(0, -3);
2712 EXPECT_EQ(InputHandler::ScrollStarted
,
2713 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2714 InputHandler::NonBubblingGesture
));
2715 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2716 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2717 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
2718 host_impl_
->ScrollEnd();
2720 scroll_info
= host_impl_
->ProcessScrollDeltas();
2722 // The child should have scrolled up to its limit.
2723 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2725 // The grand child should not have scrolled.
2726 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2728 // After scrolling the parent, another scroll on the opposite direction
2729 // should still scroll the child.
2730 scroll_delta
= gfx::Vector2d(0, 7);
2731 EXPECT_EQ(InputHandler::ScrollStarted
,
2732 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2733 InputHandler::NonBubblingGesture
));
2734 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2735 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2736 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2737 host_impl_
->ScrollEnd();
2739 scroll_info
= host_impl_
->ProcessScrollDeltas();
2741 // The grand child should have scrolled.
2742 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
2744 // The child should not have scrolled.
2745 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2748 // Scrolling should be adjusted from viewport space.
2749 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 2.f
, 2.f
);
2750 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
2752 scroll_delta
= gfx::Vector2d(0, -2);
2753 EXPECT_EQ(InputHandler::ScrollStarted
,
2754 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2755 InputHandler::NonBubblingGesture
));
2756 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
2757 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2758 host_impl_
->ScrollEnd();
2760 scroll_info
= host_impl_
->ProcessScrollDeltas();
2762 // Should have scrolled by half the amount in layer space (5 - 2/2)
2763 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
2766 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
2767 // When we try to scroll a non-scrollable child layer, the scroll delta
2768 // should be applied to one of its ancestors if possible.
2769 gfx::Size
surface_size(10, 10);
2770 gfx::Size
content_size(20, 20);
2771 scoped_ptr
<LayerImpl
> root_clip
=
2772 LayerImpl::Create(host_impl_
->active_tree(), 3);
2773 scoped_ptr
<LayerImpl
> root
=
2774 CreateScrollableLayer(1, content_size
, root_clip
.get());
2775 // Make 'root' the clip layer for child: since they have the same sizes the
2776 // child will have zero max_scroll_offset and scrolls will bubble.
2777 scoped_ptr
<LayerImpl
> child
=
2778 CreateScrollableLayer(2, content_size
, root
.get());
2779 child
->SetIsContainerForFixedPositionLayers(true);
2780 root
->SetBounds(content_size
);
2782 int root_scroll_id
= root
->id();
2783 root
->AddChild(child
.Pass());
2784 root_clip
->AddChild(root
.Pass());
2786 host_impl_
->SetViewportSize(surface_size
);
2787 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2788 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID
);
2789 host_impl_
->active_tree()->DidBecomeActive();
2792 gfx::Vector2d
scroll_delta(0, 4);
2793 EXPECT_EQ(InputHandler::ScrollStarted
,
2794 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2795 InputHandler::Wheel
));
2796 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2797 host_impl_
->ScrollEnd();
2799 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2800 host_impl_
->ProcessScrollDeltas();
2802 // Only the root scroll should have scrolled.
2803 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
2804 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
2808 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
2809 gfx::Size
surface_size(10, 10);
2810 scoped_ptr
<LayerImpl
> root_clip
=
2811 LayerImpl::Create(host_impl_
->active_tree(), 1);
2812 scoped_ptr
<LayerImpl
> root_scroll
=
2813 CreateScrollableLayer(2, surface_size
, root_clip
.get());
2814 root_scroll
->SetIsContainerForFixedPositionLayers(true);
2815 root_clip
->AddChild(root_scroll
.Pass());
2816 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2817 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2818 host_impl_
->active_tree()->DidBecomeActive();
2819 host_impl_
->SetViewportSize(surface_size
);
2821 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2824 host_impl_
->active_tree()->DetachLayerTree();
2825 scoped_ptr
<LayerImpl
> root_clip2
=
2826 LayerImpl::Create(host_impl_
->active_tree(), 3);
2827 scoped_ptr
<LayerImpl
> root_scroll2
=
2828 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
2829 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
2830 root_clip2
->AddChild(root_scroll2
.Pass());
2831 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
2832 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID
);
2833 host_impl_
->active_tree()->DidBecomeActive();
2835 // Scrolling should still work even though we did not draw yet.
2836 EXPECT_EQ(InputHandler::ScrollStarted
,
2837 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2838 InputHandler::Wheel
));
2841 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
2842 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2844 // Rotate the root layer 90 degrees counter-clockwise about its center.
2845 gfx::Transform rotate_transform
;
2846 rotate_transform
.Rotate(-90.0);
2847 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
2849 gfx::Size
surface_size(50, 50);
2850 host_impl_
->SetViewportSize(surface_size
);
2853 // Scroll to the right in screen coordinates with a gesture.
2854 gfx::Vector2d
gesture_scroll_delta(10, 0);
2855 EXPECT_EQ(InputHandler::ScrollStarted
,
2856 host_impl_
->ScrollBegin(gfx::Point(),
2857 InputHandler::Gesture
));
2858 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2859 host_impl_
->ScrollEnd();
2861 // The layer should have scrolled down in its local coordinates.
2862 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2863 ExpectContains(*scroll_info
.get(),
2865 gfx::Vector2d(0, gesture_scroll_delta
.x()));
2867 // Reset and scroll down with the wheel.
2868 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2869 gfx::Vector2d
wheel_scroll_delta(0, 10);
2870 EXPECT_EQ(InputHandler::ScrollStarted
,
2871 host_impl_
->ScrollBegin(gfx::Point(),
2872 InputHandler::Wheel
));
2873 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
2874 host_impl_
->ScrollEnd();
2876 // The layer should have scrolled down in its local coordinates.
2877 scroll_info
= host_impl_
->ProcessScrollDeltas();
2878 ExpectContains(*scroll_info
.get(),
2880 wheel_scroll_delta
);
2883 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
2884 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2885 int child_clip_layer_id
= 6;
2886 int child_layer_id
= 7;
2887 float child_layer_angle
= -20.f
;
2889 // Create a child layer that is rotated to a non-axis-aligned angle.
2890 scoped_ptr
<LayerImpl
> clip_layer
=
2891 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
2892 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
2893 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
2894 gfx::Transform rotate_transform
;
2895 rotate_transform
.Translate(-50.0, -50.0);
2896 rotate_transform
.Rotate(child_layer_angle
);
2897 rotate_transform
.Translate(50.0, 50.0);
2898 clip_layer
->SetTransform(rotate_transform
);
2900 // Only allow vertical scrolling.
2901 clip_layer
->SetBounds(
2902 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
2903 // The rotation depends on the layer's anchor point, and the child layer is a
2904 // different size than the clip, so make sure the clip layer's anchor lines
2905 // up over the child.
2906 clip_layer
->SetAnchorPoint(gfx::PointF(0.5, 1.0));
2907 LayerImpl
* child_ptr
= child
.get();
2908 clip_layer
->AddChild(child
.Pass());
2909 scroll_layer
->AddChild(clip_layer
.Pass());
2911 gfx::Size
surface_size(50, 50);
2912 host_impl_
->SetViewportSize(surface_size
);
2915 // Scroll down in screen coordinates with a gesture.
2916 gfx::Vector2d
gesture_scroll_delta(0, 10);
2917 EXPECT_EQ(InputHandler::ScrollStarted
,
2918 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2919 InputHandler::Gesture
));
2920 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2921 host_impl_
->ScrollEnd();
2923 // The child layer should have scrolled down in its local coordinates an
2924 // amount proportional to the angle between it and the input scroll delta.
2925 gfx::Vector2d
expected_scroll_delta(
2927 gesture_scroll_delta
.y() *
2928 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
2929 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2930 host_impl_
->ProcessScrollDeltas();
2931 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2933 // The root scroll layer should not have scrolled, because the input delta
2934 // was close to the layer's axis of movement.
2935 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
2938 // Now reset and scroll the same amount horizontally.
2939 child_ptr
->SetScrollDelta(gfx::Vector2dF());
2940 gfx::Vector2d
gesture_scroll_delta(10, 0);
2941 EXPECT_EQ(InputHandler::ScrollStarted
,
2942 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2943 InputHandler::Gesture
));
2944 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2945 host_impl_
->ScrollEnd();
2947 // The child layer should have scrolled down in its local coordinates an
2948 // amount proportional to the angle between it and the input scroll delta.
2949 gfx::Vector2d
expected_scroll_delta(
2951 -gesture_scroll_delta
.x() *
2952 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
2953 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2954 host_impl_
->ProcessScrollDeltas();
2955 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2957 // The root scroll layer should have scrolled more, since the input scroll
2958 // delta was mostly orthogonal to the child layer's vertical scroll axis.
2959 gfx::Vector2d
expected_root_scroll_delta(
2960 gesture_scroll_delta
.x() *
2961 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
2963 ExpectContains(*scroll_info
.get(),
2965 expected_root_scroll_delta
);
2969 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
2970 LayerImpl
* scroll_layer
=
2971 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2973 // Scale the layer to twice its normal size.
2975 gfx::Transform scale_transform
;
2976 scale_transform
.Scale(scale
, scale
);
2977 scroll_layer
->SetTransform(scale_transform
);
2979 gfx::Size
surface_size(50, 50);
2980 host_impl_
->SetViewportSize(surface_size
);
2983 // Scroll down in screen coordinates with a gesture.
2984 gfx::Vector2d
scroll_delta(0, 10);
2985 EXPECT_EQ(InputHandler::ScrollStarted
,
2986 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2987 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2988 host_impl_
->ScrollEnd();
2990 // The layer should have scrolled down in its local coordinates, but half the
2992 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2993 ExpectContains(*scroll_info
.get(),
2995 gfx::Vector2d(0, scroll_delta
.y() / scale
));
2997 // Reset and scroll down with the wheel.
2998 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2999 gfx::Vector2d
wheel_scroll_delta(0, 10);
3000 EXPECT_EQ(InputHandler::ScrollStarted
,
3001 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3002 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
3003 host_impl_
->ScrollEnd();
3005 // The scale should not have been applied to the scroll delta.
3006 scroll_info
= host_impl_
->ProcessScrollDeltas();
3007 ExpectContains(*scroll_info
.get(),
3009 wheel_scroll_delta
);
3012 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3014 TestScrollOffsetDelegate()
3015 : page_scale_factor_(0.f
),
3016 min_page_scale_factor_(-1.f
),
3017 max_page_scale_factor_(-1.f
) {}
3019 virtual ~TestScrollOffsetDelegate() {}
3021 virtual gfx::Vector2dF
GetTotalScrollOffset() OVERRIDE
{
3022 return getter_return_value_
;
3025 virtual bool IsExternalFlingActive() const OVERRIDE
{ return false; }
3027 virtual void UpdateRootLayerState(const gfx::Vector2dF
& total_scroll_offset
,
3028 const gfx::Vector2dF
& max_scroll_offset
,
3029 const gfx::SizeF
& scrollable_size
,
3030 float page_scale_factor
,
3031 float min_page_scale_factor
,
3032 float max_page_scale_factor
) OVERRIDE
{
3033 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3034 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3035 last_set_scroll_offset_
= total_scroll_offset
;
3036 max_scroll_offset_
= max_scroll_offset
;
3037 scrollable_size_
= scrollable_size
;
3038 page_scale_factor_
= page_scale_factor
;
3039 min_page_scale_factor_
= min_page_scale_factor
;
3040 max_page_scale_factor_
= max_page_scale_factor
;
3043 gfx::Vector2dF
last_set_scroll_offset() {
3044 return last_set_scroll_offset_
;
3047 void set_getter_return_value(const gfx::Vector2dF
& value
) {
3048 getter_return_value_
= value
;
3051 gfx::Vector2dF
max_scroll_offset() const {
3052 return max_scroll_offset_
;
3055 gfx::SizeF
scrollable_size() const {
3056 return scrollable_size_
;
3059 float page_scale_factor() const {
3060 return page_scale_factor_
;
3063 float min_page_scale_factor() const {
3064 return min_page_scale_factor_
;
3067 float max_page_scale_factor() const {
3068 return max_page_scale_factor_
;
3072 gfx::Vector2dF last_set_scroll_offset_
;
3073 gfx::Vector2dF getter_return_value_
;
3074 gfx::Vector2dF max_scroll_offset_
;
3075 gfx::SizeF scrollable_size_
;
3076 float page_scale_factor_
;
3077 float min_page_scale_factor_
;
3078 float max_page_scale_factor_
;
3081 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3082 TestScrollOffsetDelegate scroll_delegate
;
3083 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3084 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3085 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3086 clip_layer
->SetBounds(gfx::Size(10, 20));
3088 // Setting the delegate results in the current scroll offset being set.
3089 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3090 scroll_layer
->SetScrollOffset(gfx::Vector2d());
3091 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3092 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3093 EXPECT_EQ(initial_scroll_delta
.ToString(),
3094 scroll_delegate
.last_set_scroll_offset().ToString());
3096 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3097 // page_scale_factor and {min|max}_page_scale_factor being set.
3098 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3099 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate
.max_scroll_offset());
3100 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3101 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3102 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3104 // Updating page scale immediately updates the delegate.
3105 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 0.5f
, 4.f
);
3106 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3107 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3108 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3109 host_impl_
->active_tree()->SetPageScaleDelta(1.5f
);
3110 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3111 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3112 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3113 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3114 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3115 EXPECT_EQ(1.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());
3119 // The pinch gesture doesn't put the delegate into a state where the scroll
3120 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3122 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3123 host_impl_
->PinchGestureBegin();
3124 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3125 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3126 host_impl_
->PinchGestureEnd();
3127 host_impl_
->ScrollEnd();
3129 // Scrolling should be relative to the offset as returned by the delegate.
3130 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3131 gfx::Vector2dF
current_offset(7.f
, 8.f
);
3133 scroll_delegate
.set_getter_return_value(current_offset
);
3134 EXPECT_EQ(InputHandler::ScrollStarted
,
3135 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3137 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3138 EXPECT_EQ(current_offset
+ scroll_delta
,
3139 scroll_delegate
.last_set_scroll_offset());
3141 current_offset
= gfx::Vector2dF(42.f
, 41.f
);
3142 scroll_delegate
.set_getter_return_value(current_offset
);
3143 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3144 EXPECT_EQ(current_offset
+ scroll_delta
,
3145 scroll_delegate
.last_set_scroll_offset());
3146 host_impl_
->ScrollEnd();
3147 scroll_delegate
.set_getter_return_value(gfx::Vector2dF());
3149 // Forces a full tree synchronization and ensures that the scroll delegate
3150 // sees the correct size of the new tree.
3151 gfx::Size
new_size(42, 24);
3152 host_impl_
->CreatePendingTree();
3153 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3154 host_impl_
->ActivatePendingTree();
3155 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3157 // Un-setting the delegate should propagate the delegate's current offset to
3158 // the root scrollable layer.
3159 current_offset
= gfx::Vector2dF(13.f
, 12.f
);
3160 scroll_delegate
.set_getter_return_value(current_offset
);
3161 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3163 EXPECT_EQ(current_offset
.ToString(),
3164 scroll_layer
->TotalScrollOffset().ToString());
3167 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3168 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3169 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3170 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3172 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3174 // In-bounds scrolling does not affect overscroll.
3175 EXPECT_EQ(InputHandler::ScrollStarted
,
3176 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3177 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3178 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3180 // Overscroll events are reflected immediately.
3181 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3182 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3184 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3185 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3186 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3187 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3188 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3189 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3190 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3191 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3192 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3193 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3194 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3195 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3196 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3198 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3199 // as no scroll occurs.
3200 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3201 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3202 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3203 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3204 // Overscroll resets on valid scroll.
3205 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3206 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3207 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3208 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3209 host_impl_
->ScrollEnd();
3213 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3214 // Scroll child layers beyond their maximum scroll range and make sure root
3215 // overscroll does not accumulate.
3216 gfx::Size
surface_size(10, 10);
3217 scoped_ptr
<LayerImpl
> root_clip
=
3218 LayerImpl::Create(host_impl_
->active_tree(), 4);
3219 scoped_ptr
<LayerImpl
> root
=
3220 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3222 scoped_ptr
<LayerImpl
> grand_child
=
3223 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3225 scoped_ptr
<LayerImpl
> child
=
3226 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3227 LayerImpl
* grand_child_layer
= grand_child
.get();
3228 child
->AddChild(grand_child
.Pass());
3230 LayerImpl
* child_layer
= child
.get();
3231 root
->AddChild(child
.Pass());
3232 root_clip
->AddChild(root
.Pass());
3233 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
3234 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
3235 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3236 host_impl_
->active_tree()->DidBecomeActive();
3237 host_impl_
->SetViewportSize(surface_size
);
3240 gfx::Vector2d
scroll_delta(0, -10);
3241 EXPECT_EQ(InputHandler::ScrollStarted
,
3242 host_impl_
->ScrollBegin(gfx::Point(),
3243 InputHandler::NonBubblingGesture
));
3244 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3245 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3246 host_impl_
->ScrollEnd();
3248 // The next time we scroll we should only scroll the parent, but overscroll
3249 // should still not reach the root layer.
3250 scroll_delta
= gfx::Vector2d(0, -30);
3251 EXPECT_EQ(InputHandler::ScrollStarted
,
3252 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3253 InputHandler::NonBubblingGesture
));
3254 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3255 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3256 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3257 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3258 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3259 host_impl_
->ScrollEnd();
3261 // After scrolling the parent, another scroll on the opposite direction
3262 // should scroll the child.
3263 scroll_delta
= gfx::Vector2d(0, 70);
3264 EXPECT_EQ(InputHandler::ScrollStarted
,
3265 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3266 InputHandler::NonBubblingGesture
));
3267 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3268 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3269 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3270 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3271 host_impl_
->ScrollEnd();
3275 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3276 // When we try to scroll a non-scrollable child layer, the scroll delta
3277 // should be applied to one of its ancestors if possible. Overscroll should
3278 // be reflected only when it has bubbled up to the root scrolling layer.
3279 gfx::Size
surface_size(10, 10);
3280 gfx::Size
content_size(20, 20);
3281 scoped_ptr
<LayerImpl
> root_clip
=
3282 LayerImpl::Create(host_impl_
->active_tree(), 3);
3283 scoped_ptr
<LayerImpl
> root
=
3284 CreateScrollableLayer(1, content_size
, root_clip
.get());
3285 root
->SetIsContainerForFixedPositionLayers(true);
3286 scoped_ptr
<LayerImpl
> child
=
3287 CreateScrollableLayer(2, content_size
, root_clip
.get());
3289 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3290 root
->AddChild(child
.Pass());
3291 root_clip
->AddChild(root
.Pass());
3293 host_impl_
->SetViewportSize(surface_size
);
3294 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3295 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3296 host_impl_
->active_tree()->DidBecomeActive();
3299 gfx::Vector2d
scroll_delta(0, 8);
3300 EXPECT_EQ(InputHandler::ScrollStarted
,
3301 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3302 InputHandler::Wheel
));
3303 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3304 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3305 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3306 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
3307 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3308 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
3309 host_impl_
->ScrollEnd();
3313 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
3314 LayerTreeSettings settings
;
3315 CreateHostImpl(settings
, CreateOutputSurface());
3317 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
3318 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3319 clip_layer
->SetBounds(gfx::Size(50, 50));
3320 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3321 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3323 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3325 // Even though the layer can't scroll the overscroll still happens.
3326 EXPECT_EQ(InputHandler::ScrollStarted
,
3327 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3328 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3329 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3332 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
3333 gfx::Size
surface_size(980, 1439);
3334 gfx::Size
content_size(980, 1438);
3335 float device_scale_factor
= 1.5f
;
3336 scoped_ptr
<LayerImpl
> root_clip
=
3337 LayerImpl::Create(host_impl_
->active_tree(), 3);
3338 scoped_ptr
<LayerImpl
> root
=
3339 CreateScrollableLayer(1, content_size
, root_clip
.get());
3340 root
->SetIsContainerForFixedPositionLayers(true);
3341 scoped_ptr
<LayerImpl
> child
=
3342 CreateScrollableLayer(2, content_size
, root_clip
.get());
3343 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
3344 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
3345 0.326531f
, 0.326531f
, 5.f
);
3346 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3347 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3348 root
->AddChild(child
.Pass());
3349 root_clip
->AddChild(root
.Pass());
3351 host_impl_
->SetViewportSize(surface_size
);
3352 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
3353 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3354 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3355 host_impl_
->active_tree()->DidBecomeActive();
3358 // Horizontal & Vertical GlowEffect should not be applied when
3359 // content size is less then view port size. For Example Horizontal &
3360 // vertical GlowEffect should not be applied in about:blank page.
3361 EXPECT_EQ(InputHandler::ScrollStarted
,
3362 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3363 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
3364 EXPECT_EQ(gfx::Vector2dF().ToString(),
3365 host_impl_
->accumulated_root_overscroll().ToString());
3367 host_impl_
->ScrollEnd();
3371 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
3372 gfx::Size
surface_size(100, 100);
3373 gfx::Size
content_size(200, 200);
3374 scoped_ptr
<LayerImpl
> root_clip
=
3375 LayerImpl::Create(host_impl_
->active_tree(), 3);
3376 scoped_ptr
<LayerImpl
> root
=
3377 CreateScrollableLayer(1, content_size
, root_clip
.get());
3378 root
->SetIsContainerForFixedPositionLayers(true);
3379 scoped_ptr
<LayerImpl
> child
=
3380 CreateScrollableLayer(2, content_size
, root_clip
.get());
3382 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3383 root
->AddChild(child
.Pass());
3384 root_clip
->AddChild(root
.Pass());
3386 host_impl_
->SetViewportSize(surface_size
);
3387 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3388 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3389 host_impl_
->active_tree()->DidBecomeActive();
3392 // Edge glow effect should be applicable only upon reaching Edges
3393 // of the content. unnecessary glow effect calls shouldn't be
3394 // called while scrolling up without reaching the edge of the content.
3395 EXPECT_EQ(InputHandler::ScrollStarted
,
3396 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3397 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
3398 EXPECT_EQ(gfx::Vector2dF().ToString(),
3399 host_impl_
->accumulated_root_overscroll().ToString());
3400 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
3401 EXPECT_EQ(gfx::Vector2dF().ToString(),
3402 host_impl_
->accumulated_root_overscroll().ToString());
3403 host_impl_
->ScrollEnd();
3404 // unusedrootDelta should be subtracted from applied delta so that
3405 // unwanted glow effect calls are not called.
3406 EXPECT_EQ(InputHandler::ScrollStarted
,
3407 host_impl_
->ScrollBegin(gfx::Point(0, 0),
3408 InputHandler::NonBubblingGesture
));
3409 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
3410 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
3411 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3412 host_impl_
->accumulated_root_overscroll().ToString());
3414 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
3415 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3416 host_impl_
->accumulated_root_overscroll().ToString());
3417 host_impl_
->ScrollEnd();
3418 // TestCase to check kEpsilon, which prevents minute values to trigger
3419 // gloweffect without reaching edge.
3420 EXPECT_EQ(InputHandler::ScrollStarted
,
3421 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3422 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
3423 EXPECT_EQ(gfx::Vector2dF().ToString(),
3424 host_impl_
->accumulated_root_overscroll().ToString());
3425 host_impl_
->ScrollEnd();
3429 class BlendStateCheckLayer
: public LayerImpl
{
3431 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
3433 ResourceProvider
* resource_provider
) {
3434 return scoped_ptr
<LayerImpl
>(new BlendStateCheckLayer(tree_impl
,
3436 resource_provider
));
3439 virtual void AppendQuads(QuadSink
* quad_sink
,
3440 AppendQuadsData
* append_quads_data
) OVERRIDE
{
3441 quads_appended_
= true;
3443 gfx::Rect opaque_rect
;
3444 if (contents_opaque())
3445 opaque_rect
= quad_rect_
;
3447 opaque_rect
= opaque_content_rect_
;
3448 gfx::Rect visible_quad_rect
= quad_rect_
;
3450 SharedQuadState
* shared_quad_state
= quad_sink
->CreateSharedQuadState();
3451 PopulateSharedQuadState(shared_quad_state
);
3453 scoped_ptr
<TileDrawQuad
> test_blending_draw_quad
= TileDrawQuad::Create();
3454 test_blending_draw_quad
->SetNew(shared_quad_state
,
3459 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
3462 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
3463 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
3464 EXPECT_EQ(has_render_surface_
, !!render_surface());
3465 quad_sink
->Append(test_blending_draw_quad
.PassAs
<DrawQuad
>());
3468 void SetExpectation(bool blend
, bool has_render_surface
) {
3470 has_render_surface_
= has_render_surface
;
3471 quads_appended_
= false;
3474 bool quads_appended() const { return quads_appended_
; }
3476 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
3477 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
3478 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
3479 opaque_content_rect_
= rect
;
3483 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
3485 ResourceProvider
* resource_provider
)
3486 : LayerImpl(tree_impl
, id
),
3488 has_render_surface_(false),
3489 quads_appended_(false),
3490 quad_rect_(5, 5, 5, 5),
3491 quad_visible_rect_(5, 5, 5, 5),
3492 resource_id_(resource_provider
->CreateResource(
3495 ResourceProvider::TextureUsageAny
,
3497 resource_provider
->AllocateForTesting(resource_id_
);
3498 SetAnchorPoint(gfx::PointF());
3499 SetBounds(gfx::Size(10, 10));
3500 SetContentBounds(gfx::Size(10, 10));
3501 SetDrawsContent(true);
3505 bool has_render_surface_
;
3506 bool quads_appended_
;
3507 gfx::Rect quad_rect_
;
3508 gfx::Rect opaque_content_rect_
;
3509 gfx::Rect quad_visible_rect_
;
3510 ResourceProvider::ResourceId resource_id_
;
3513 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
3515 scoped_ptr
<LayerImpl
> root
=
3516 LayerImpl::Create(host_impl_
->active_tree(), 1);
3517 root
->SetAnchorPoint(gfx::PointF());
3518 root
->SetBounds(gfx::Size(10, 10));
3519 root
->SetContentBounds(root
->bounds());
3520 root
->SetDrawsContent(false);
3521 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3523 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3526 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3528 host_impl_
->resource_provider()));
3529 BlendStateCheckLayer
* layer1
=
3530 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
3531 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
3533 LayerTreeHostImpl::FrameData frame
;
3535 // Opaque layer, drawn without blending.
3536 layer1
->SetContentsOpaque(true);
3537 layer1
->SetExpectation(false, false);
3538 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3539 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3540 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3541 EXPECT_TRUE(layer1
->quads_appended());
3542 host_impl_
->DidDrawAllLayers(frame
);
3544 // Layer with translucent content and painting, so drawn with blending.
3545 layer1
->SetContentsOpaque(false);
3546 layer1
->SetExpectation(true, false);
3547 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3548 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3549 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3550 EXPECT_TRUE(layer1
->quads_appended());
3551 host_impl_
->DidDrawAllLayers(frame
);
3553 // Layer with translucent opacity, drawn with blending.
3554 layer1
->SetContentsOpaque(true);
3555 layer1
->SetOpacity(0.5f
);
3556 layer1
->SetExpectation(true, false);
3557 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3558 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3559 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3560 EXPECT_TRUE(layer1
->quads_appended());
3561 host_impl_
->DidDrawAllLayers(frame
);
3563 // Layer with translucent opacity and painting, drawn with blending.
3564 layer1
->SetContentsOpaque(true);
3565 layer1
->SetOpacity(0.5f
);
3566 layer1
->SetExpectation(true, false);
3567 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3568 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3569 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3570 EXPECT_TRUE(layer1
->quads_appended());
3571 host_impl_
->DidDrawAllLayers(frame
);
3574 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3576 host_impl_
->resource_provider()));
3577 BlendStateCheckLayer
* layer2
=
3578 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
3579 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
3581 // 2 opaque layers, drawn without blending.
3582 layer1
->SetContentsOpaque(true);
3583 layer1
->SetOpacity(1.f
);
3584 layer1
->SetExpectation(false, false);
3585 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3586 layer2
->SetContentsOpaque(true);
3587 layer2
->SetOpacity(1.f
);
3588 layer2
->SetExpectation(false, false);
3589 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3590 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3591 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3592 EXPECT_TRUE(layer1
->quads_appended());
3593 EXPECT_TRUE(layer2
->quads_appended());
3594 host_impl_
->DidDrawAllLayers(frame
);
3596 // Parent layer with translucent content, drawn with blending.
3597 // Child layer with opaque content, drawn without blending.
3598 layer1
->SetContentsOpaque(false);
3599 layer1
->SetExpectation(true, false);
3600 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3601 layer2
->SetExpectation(false, false);
3602 layer2
->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 EXPECT_TRUE(layer2
->quads_appended());
3607 host_impl_
->DidDrawAllLayers(frame
);
3609 // Parent layer with translucent content but opaque painting, drawn without
3611 // Child layer with opaque content, drawn without blending.
3612 layer1
->SetContentsOpaque(true);
3613 layer1
->SetExpectation(false, false);
3614 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3615 layer2
->SetExpectation(false, false);
3616 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3617 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3618 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3619 EXPECT_TRUE(layer1
->quads_appended());
3620 EXPECT_TRUE(layer2
->quads_appended());
3621 host_impl_
->DidDrawAllLayers(frame
);
3623 // Parent layer with translucent opacity and opaque content. Since it has a
3624 // drawing child, it's drawn to a render surface which carries the opacity,
3625 // so it's itself drawn without blending.
3626 // Child layer with opaque content, drawn without blending (parent surface
3627 // carries the inherited opacity).
3628 layer1
->SetContentsOpaque(true);
3629 layer1
->SetOpacity(0.5f
);
3630 layer1
->SetExpectation(false, true);
3631 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3632 layer2
->SetExpectation(false, false);
3633 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3634 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3635 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3636 EXPECT_TRUE(layer1
->quads_appended());
3637 EXPECT_TRUE(layer2
->quads_appended());
3638 host_impl_
->DidDrawAllLayers(frame
);
3640 // Draw again, but with child non-opaque, to make sure
3641 // layer1 not culled.
3642 layer1
->SetContentsOpaque(true);
3643 layer1
->SetOpacity(1.f
);
3644 layer1
->SetExpectation(false, false);
3645 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3646 layer2
->SetContentsOpaque(true);
3647 layer2
->SetOpacity(0.5f
);
3648 layer2
->SetExpectation(true, false);
3649 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3650 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3651 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3652 EXPECT_TRUE(layer1
->quads_appended());
3653 EXPECT_TRUE(layer2
->quads_appended());
3654 host_impl_
->DidDrawAllLayers(frame
);
3656 // A second way of making the child non-opaque.
3657 layer1
->SetContentsOpaque(true);
3658 layer1
->SetOpacity(1.f
);
3659 layer1
->SetExpectation(false, false);
3660 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3661 layer2
->SetContentsOpaque(false);
3662 layer2
->SetOpacity(1.f
);
3663 layer2
->SetExpectation(true, false);
3664 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3665 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3666 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3667 EXPECT_TRUE(layer1
->quads_appended());
3668 EXPECT_TRUE(layer2
->quads_appended());
3669 host_impl_
->DidDrawAllLayers(frame
);
3671 // And when the layer says its not opaque but is painted opaque, it is not
3673 layer1
->SetContentsOpaque(true);
3674 layer1
->SetOpacity(1.f
);
3675 layer1
->SetExpectation(false, false);
3676 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3677 layer2
->SetContentsOpaque(true);
3678 layer2
->SetOpacity(1.f
);
3679 layer2
->SetExpectation(false, false);
3680 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3681 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3682 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3683 EXPECT_TRUE(layer1
->quads_appended());
3684 EXPECT_TRUE(layer2
->quads_appended());
3685 host_impl_
->DidDrawAllLayers(frame
);
3687 // Layer with partially opaque contents, drawn with blending.
3688 layer1
->SetContentsOpaque(false);
3689 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3690 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
3691 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3692 layer1
->SetExpectation(true, false);
3693 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3694 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3695 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3696 EXPECT_TRUE(layer1
->quads_appended());
3697 host_impl_
->DidDrawAllLayers(frame
);
3699 // Layer with partially opaque contents partially culled, drawn with blending.
3700 layer1
->SetContentsOpaque(false);
3701 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3702 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3703 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3704 layer1
->SetExpectation(true, false);
3705 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3706 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3707 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3708 EXPECT_TRUE(layer1
->quads_appended());
3709 host_impl_
->DidDrawAllLayers(frame
);
3711 // Layer with partially opaque contents culled, drawn with blending.
3712 layer1
->SetContentsOpaque(false);
3713 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3714 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3715 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3716 layer1
->SetExpectation(true, false);
3717 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3718 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3719 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3720 EXPECT_TRUE(layer1
->quads_appended());
3721 host_impl_
->DidDrawAllLayers(frame
);
3723 // Layer with partially opaque contents and translucent contents culled, drawn
3724 // without blending.
3725 layer1
->SetContentsOpaque(false);
3726 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3727 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3728 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3729 layer1
->SetExpectation(false, false);
3730 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3731 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3732 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3733 EXPECT_TRUE(layer1
->quads_appended());
3734 host_impl_
->DidDrawAllLayers(frame
);
3737 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
3739 LayerTreeHostImplViewportCoveredTest() :
3740 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
3742 did_activate_pending_tree_(false) {}
3744 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
3746 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d()
3747 .PassAs
<OutputSurface
>();
3749 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
3752 void SetupActiveTreeLayers() {
3753 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
3754 host_impl_
->active_tree()->SetRootLayer(
3755 LayerImpl::Create(host_impl_
->active_tree(), 1));
3756 host_impl_
->active_tree()->root_layer()->AddChild(
3757 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3759 host_impl_
->resource_provider()));
3760 child_
= static_cast<BlendStateCheckLayer
*>(
3761 host_impl_
->active_tree()->root_layer()->children()[0]);
3762 child_
->SetExpectation(false, false);
3763 child_
->SetContentsOpaque(true);
3766 // Expect no gutter rects.
3767 void TestLayerCoversFullViewport() {
3768 gfx::Rect
layer_rect(viewport_size_
);
3769 child_
->SetPosition(layer_rect
.origin());
3770 child_
->SetBounds(layer_rect
.size());
3771 child_
->SetContentBounds(layer_rect
.size());
3772 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3773 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3775 LayerTreeHostImpl::FrameData frame
;
3776 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3777 ASSERT_EQ(1u, frame
.render_passes
.size());
3779 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3780 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3781 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3783 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3784 host_impl_
->DidDrawAllLayers(frame
);
3787 // Expect fullscreen gutter rect.
3788 void TestEmptyLayer() {
3789 gfx::Rect
layer_rect(0, 0, 0, 0);
3790 child_
->SetPosition(layer_rect
.origin());
3791 child_
->SetBounds(layer_rect
.size());
3792 child_
->SetContentBounds(layer_rect
.size());
3793 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3794 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3796 LayerTreeHostImpl::FrameData frame
;
3797 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3798 ASSERT_EQ(1u, frame
.render_passes
.size());
3800 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3801 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3802 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3804 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3805 host_impl_
->DidDrawAllLayers(frame
);
3808 // Expect four surrounding gutter rects.
3809 void TestLayerInMiddleOfViewport() {
3810 gfx::Rect
layer_rect(500, 500, 200, 200);
3811 child_
->SetPosition(layer_rect
.origin());
3812 child_
->SetBounds(layer_rect
.size());
3813 child_
->SetContentBounds(layer_rect
.size());
3814 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3815 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3817 LayerTreeHostImpl::FrameData frame
;
3818 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3819 ASSERT_EQ(1u, frame
.render_passes
.size());
3821 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3822 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
3823 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3825 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3826 host_impl_
->DidDrawAllLayers(frame
);
3829 // Expect no gutter rects.
3830 void TestLayerIsLargerThanViewport() {
3831 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
3832 viewport_size_
.height() + 10);
3833 child_
->SetPosition(layer_rect
.origin());
3834 child_
->SetBounds(layer_rect
.size());
3835 child_
->SetContentBounds(layer_rect
.size());
3836 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3837 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3839 LayerTreeHostImpl::FrameData frame
;
3840 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3841 ASSERT_EQ(1u, frame
.render_passes
.size());
3843 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3844 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3845 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3847 host_impl_
->DidDrawAllLayers(frame
);
3850 virtual void DidActivatePendingTree() OVERRIDE
{
3851 did_activate_pending_tree_
= true;
3854 void set_gutter_quad_material(DrawQuad::Material material
) {
3855 gutter_quad_material_
= material
;
3857 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
3858 gutter_texture_size_
= gutter_texture_size
;
3862 size_t CountGutterQuads(const QuadList
& quad_list
) {
3863 size_t num_gutter_quads
= 0;
3864 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3865 num_gutter_quads
+= (quad_list
[i
]->material
==
3866 gutter_quad_material_
) ? 1 : 0;
3868 return num_gutter_quads
;
3871 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
3872 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3873 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
3876 // Make sure that the texture coordinates match their expectations.
3877 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
3878 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3879 if (quad_list
[i
]->material
!= DrawQuad::TEXTURE_CONTENT
)
3881 const TextureDrawQuad
* quad
= TextureDrawQuad::MaterialCast(quad_list
[i
]);
3882 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
3883 gutter_texture_size_
, host_impl_
->device_scale_factor());
3884 EXPECT_EQ(quad
->uv_top_left
.x(),
3885 quad
->rect
.x() / gutter_texture_size_pixels
.width());
3886 EXPECT_EQ(quad
->uv_top_left
.y(),
3887 quad
->rect
.y() / gutter_texture_size_pixels
.height());
3888 EXPECT_EQ(quad
->uv_bottom_right
.x(),
3889 quad
->rect
.right() / gutter_texture_size_pixels
.width());
3890 EXPECT_EQ(quad
->uv_bottom_right
.y(),
3891 quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
3895 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
3896 return gfx::ToRoundedSize(
3897 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
3900 DrawQuad::Material gutter_quad_material_
;
3901 gfx::Size gutter_texture_size_
;
3902 gfx::Size viewport_size_
;
3903 BlendStateCheckLayer
* child_
;
3904 bool did_activate_pending_tree_
;
3907 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
3908 viewport_size_
= gfx::Size(1000, 1000);
3910 bool always_draw
= false;
3911 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3913 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3914 SetupActiveTreeLayers();
3915 TestLayerCoversFullViewport();
3917 TestLayerInMiddleOfViewport();
3918 TestLayerIsLargerThanViewport();
3921 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
3922 viewport_size_
= gfx::Size(1000, 1000);
3924 bool always_draw
= false;
3925 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3927 host_impl_
->SetDeviceScaleFactor(2.f
);
3928 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3929 SetupActiveTreeLayers();
3930 TestLayerCoversFullViewport();
3932 TestLayerInMiddleOfViewport();
3933 TestLayerIsLargerThanViewport();
3936 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
3937 viewport_size_
= gfx::Size(1000, 1000);
3939 bool always_draw
= false;
3940 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3942 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3943 SetupActiveTreeLayers();
3945 // Specify an overhang bitmap to use.
3946 bool is_opaque
= false;
3947 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
3948 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
3949 UIResourceId ui_resource_id
= 12345;
3950 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
3951 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
3952 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
3953 set_gutter_texture_size(gfx::Size(32, 32));
3955 TestLayerCoversFullViewport();
3957 TestLayerInMiddleOfViewport();
3958 TestLayerIsLargerThanViewport();
3960 // Change the resource size.
3961 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
3962 set_gutter_texture_size(gfx::Size(128, 16));
3964 TestLayerCoversFullViewport();
3966 TestLayerInMiddleOfViewport();
3967 TestLayerIsLargerThanViewport();
3969 // Change the device scale factor
3970 host_impl_
->SetDeviceScaleFactor(2.f
);
3971 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3973 TestLayerCoversFullViewport();
3975 TestLayerInMiddleOfViewport();
3976 TestLayerIsLargerThanViewport();
3979 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
3980 viewport_size_
= gfx::Size(1000, 1000);
3982 bool always_draw
= true;
3983 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3985 // Pending tree to force active_tree size invalid. Not used otherwise.
3986 host_impl_
->CreatePendingTree();
3987 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3988 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
3990 SetupActiveTreeLayers();
3992 TestLayerInMiddleOfViewport();
3993 TestLayerIsLargerThanViewport();
3996 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
3997 viewport_size_
= gfx::Size(1000, 1000);
3999 bool always_draw
= true;
4000 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
4002 // Set larger viewport and activate it to active tree.
4003 host_impl_
->CreatePendingTree();
4004 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
4005 viewport_size_
.height() + 100);
4006 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
4007 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4008 host_impl_
->ActivatePendingTree();
4009 EXPECT_TRUE(did_activate_pending_tree_
);
4010 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4012 // Shrink pending tree viewport without activating.
4013 host_impl_
->CreatePendingTree();
4014 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4015 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4017 SetupActiveTreeLayers();
4019 TestLayerInMiddleOfViewport();
4020 TestLayerIsLargerThanViewport();
4023 class FakeDrawableLayerImpl
: public LayerImpl
{
4025 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4026 return scoped_ptr
<LayerImpl
>(new FakeDrawableLayerImpl(tree_impl
, id
));
4029 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4030 : LayerImpl(tree_impl
, id
) {}
4033 // Only reshape when we know we are going to draw. Otherwise, the reshape
4034 // can leave the window at the wrong size if we never draw and the proper
4035 // viewport size is never set.
4036 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4037 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4038 scoped_ptr
<OutputSurface
> output_surface(
4039 FakeOutputSurface::Create3d(provider
));
4040 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4042 scoped_ptr
<LayerImpl
> root
=
4043 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4044 root
->SetAnchorPoint(gfx::PointF());
4045 root
->SetBounds(gfx::Size(10, 10));
4046 root
->SetContentBounds(gfx::Size(10, 10));
4047 root
->SetDrawsContent(true);
4048 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4049 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4050 provider
->TestContext3d()->clear_reshape_called();
4052 LayerTreeHostImpl::FrameData frame
;
4053 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4054 host_impl_
->SetDeviceScaleFactor(1.f
);
4055 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4056 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4057 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4058 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4059 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4060 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4061 host_impl_
->DidDrawAllLayers(frame
);
4062 provider
->TestContext3d()->clear_reshape_called();
4064 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4065 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4066 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4067 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4068 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4069 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4070 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4071 host_impl_
->DidDrawAllLayers(frame
);
4072 provider
->TestContext3d()->clear_reshape_called();
4074 host_impl_
->SetDeviceScaleFactor(2.f
);
4075 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4076 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4077 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4078 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4079 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4080 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4081 host_impl_
->DidDrawAllLayers(frame
);
4082 provider
->TestContext3d()->clear_reshape_called();
4085 // Make sure damage tracking propagates all the way to the graphics context,
4086 // where it should request to swap only the sub-buffer that is damaged.
4087 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4088 scoped_refptr
<TestContextProvider
> context_provider(
4089 TestContextProvider::Create());
4090 context_provider
->BindToCurrentThread();
4091 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4093 scoped_ptr
<OutputSurface
> output_surface(
4094 FakeOutputSurface::Create3d(context_provider
));
4096 // This test creates its own LayerTreeHostImpl, so
4097 // that we can force partial swap enabled.
4098 LayerTreeSettings settings
;
4099 settings
.partial_swap_enabled
= true;
4100 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4101 new TestSharedBitmapManager());
4102 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4103 LayerTreeHostImpl::Create(settings
,
4106 &stats_instrumentation_
,
4107 shared_bitmap_manager
.get(),
4109 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4110 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4112 scoped_ptr
<LayerImpl
> root
=
4113 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4114 scoped_ptr
<LayerImpl
> child
=
4115 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4116 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4117 child
->SetAnchorPoint(gfx::PointF());
4118 child
->SetBounds(gfx::Size(14, 15));
4119 child
->SetContentBounds(gfx::Size(14, 15));
4120 child
->SetDrawsContent(true);
4121 root
->SetAnchorPoint(gfx::PointF());
4122 root
->SetBounds(gfx::Size(500, 500));
4123 root
->SetContentBounds(gfx::Size(500, 500));
4124 root
->SetDrawsContent(true);
4125 root
->AddChild(child
.Pass());
4126 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4128 LayerTreeHostImpl::FrameData frame
;
4130 // First frame, the entire screen should get swapped.
4131 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4132 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4133 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4134 layer_tree_host_impl
->SwapBuffers(frame
);
4135 EXPECT_EQ(TestContextSupport::SWAP
,
4136 context_provider
->support()->last_swap_type());
4138 // Second frame, only the damaged area should get swapped. Damage should be
4139 // the union of old and new child rects.
4140 // expected damage rect: gfx::Rect(26, 28);
4141 // expected swap rect: vertically flipped, with origin at bottom left corner.
4142 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4144 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4145 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4146 host_impl_
->DidDrawAllLayers(frame
);
4147 layer_tree_host_impl
->SwapBuffers(frame
);
4149 // Make sure that partial swap is constrained to the viewport dimensions
4150 // expected damage rect: gfx::Rect(500, 500);
4151 // expected swap rect: flipped damage rect, but also clamped to viewport
4152 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP
,
4153 context_provider
->support()->last_swap_type());
4154 gfx::Rect
expected_swap_rect(0, 500-28, 26, 28);
4155 EXPECT_EQ(expected_swap_rect
.ToString(),
4156 context_provider
->support()->
4157 last_partial_swap_rect().ToString());
4159 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4160 // This will damage everything.
4161 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4163 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4164 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4165 host_impl_
->DidDrawAllLayers(frame
);
4166 layer_tree_host_impl
->SwapBuffers(frame
);
4168 EXPECT_EQ(TestContextSupport::SWAP
,
4169 context_provider
->support()->last_swap_type());
4172 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4173 scoped_ptr
<LayerImpl
> root
=
4174 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4175 scoped_ptr
<LayerImpl
> child
=
4176 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4177 child
->SetAnchorPoint(gfx::PointF());
4178 child
->SetBounds(gfx::Size(10, 10));
4179 child
->SetContentBounds(gfx::Size(10, 10));
4180 child
->SetDrawsContent(true);
4181 root
->SetAnchorPoint(gfx::PointF());
4182 root
->SetBounds(gfx::Size(10, 10));
4183 root
->SetContentBounds(gfx::Size(10, 10));
4184 root
->SetDrawsContent(true);
4185 root
->SetForceRenderSurface(true);
4186 root
->AddChild(child
.Pass());
4188 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4190 LayerTreeHostImpl::FrameData frame
;
4192 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4193 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4194 EXPECT_EQ(1u, frame
.render_passes
.size());
4195 host_impl_
->DidDrawAllLayers(frame
);
4198 class FakeLayerWithQuads
: public LayerImpl
{
4200 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4201 return scoped_ptr
<LayerImpl
>(new FakeLayerWithQuads(tree_impl
, id
));
4204 virtual void AppendQuads(QuadSink
* quad_sink
,
4205 AppendQuadsData
* append_quads_data
) OVERRIDE
{
4206 SharedQuadState
* shared_quad_state
= quad_sink
->CreateSharedQuadState();
4207 PopulateSharedQuadState(shared_quad_state
);
4209 SkColor gray
= SkColorSetRGB(100, 100, 100);
4210 gfx::Rect
quad_rect(content_bounds());
4211 gfx::Rect
visible_quad_rect(quad_rect
);
4212 scoped_ptr
<SolidColorDrawQuad
> my_quad
= SolidColorDrawQuad::Create();
4214 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4215 quad_sink
->Append(my_quad
.PassAs
<DrawQuad
>());
4219 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4220 : LayerImpl(tree_impl
, id
) {}
4223 class MockContext
: public TestWebGraphicsContext3D
{
4225 MOCK_METHOD1(useProgram
, void(GLuint program
));
4226 MOCK_METHOD5(uniform4f
, void(GLint location
,
4231 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4233 GLboolean transpose
,
4234 const GLfloat
* value
));
4235 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4239 MOCK_METHOD1(enable
, void(GLenum cap
));
4240 MOCK_METHOD1(disable
, void(GLenum cap
));
4241 MOCK_METHOD4(scissor
, void(GLint x
,
4247 class MockContextHarness
{
4249 MockContext
* context_
;
4252 explicit MockContextHarness(MockContext
* context
)
4253 : context_(context
) {
4254 context_
->set_have_post_sub_buffer(true);
4256 // Catch "uninteresting" calls
4257 EXPECT_CALL(*context_
, useProgram(_
))
4260 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4263 // These are not asserted
4264 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4265 .WillRepeatedly(Return());
4267 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4268 .WillRepeatedly(Return());
4270 // Any un-sanctioned calls to enable() are OK
4271 EXPECT_CALL(*context_
, enable(_
))
4272 .WillRepeatedly(Return());
4274 // Any un-sanctioned calls to disable() are OK
4275 EXPECT_CALL(*context_
, disable(_
))
4276 .WillRepeatedly(Return());
4279 void MustDrawSolidQuad() {
4280 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
4282 .RetiresOnSaturation();
4284 EXPECT_CALL(*context_
, useProgram(_
))
4286 .RetiresOnSaturation();
4289 void MustSetScissor(int x
, int y
, int width
, int height
) {
4290 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4291 .WillRepeatedly(Return());
4293 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
4295 .WillRepeatedly(Return());
4298 void MustSetNoScissor() {
4299 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
4300 .WillRepeatedly(Return());
4302 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4305 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
4310 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
4311 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
4312 MockContext
* mock_context
= mock_context_owned
.get();
4314 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4315 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4316 MockContextHarness
harness(mock_context
);
4319 LayerTreeSettings settings
= DefaultSettings();
4320 settings
.partial_swap_enabled
= false;
4321 CreateHostImpl(settings
, output_surface
.Pass());
4322 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4324 // Without partial swap, and no clipping, no scissor is set.
4325 harness
.MustDrawSolidQuad();
4326 harness
.MustSetNoScissor();
4328 LayerTreeHostImpl::FrameData frame
;
4329 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4330 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4331 host_impl_
->DidDrawAllLayers(frame
);
4333 Mock::VerifyAndClearExpectations(&mock_context
);
4335 // Without partial swap, but a layer does clip its subtree, one scissor is
4337 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
4338 harness
.MustDrawSolidQuad();
4339 harness
.MustSetScissor(0, 0, 10, 10);
4341 LayerTreeHostImpl::FrameData frame
;
4342 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4343 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4344 host_impl_
->DidDrawAllLayers(frame
);
4346 Mock::VerifyAndClearExpectations(&mock_context
);
4349 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
4350 scoped_ptr
<MockContext
> context_owned(new MockContext
);
4351 MockContext
* mock_context
= context_owned
.get();
4352 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4353 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4354 MockContextHarness
harness(mock_context
);
4356 LayerTreeSettings settings
= DefaultSettings();
4357 settings
.partial_swap_enabled
= true;
4358 CreateHostImpl(settings
, output_surface
.Pass());
4359 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4361 // The first frame is not a partially-swapped one.
4362 harness
.MustSetScissor(0, 0, 10, 10);
4363 harness
.MustDrawSolidQuad();
4365 LayerTreeHostImpl::FrameData frame
;
4366 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4367 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4368 host_impl_
->DidDrawAllLayers(frame
);
4370 Mock::VerifyAndClearExpectations(&mock_context
);
4372 // Damage a portion of the frame.
4373 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
4374 gfx::Rect(0, 0, 2, 3));
4376 // The second frame will be partially-swapped (the y coordinates are flipped).
4377 harness
.MustSetScissor(0, 7, 2, 3);
4378 harness
.MustDrawSolidQuad();
4380 LayerTreeHostImpl::FrameData frame
;
4381 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4382 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4383 host_impl_
->DidDrawAllLayers(frame
);
4385 Mock::VerifyAndClearExpectations(&mock_context
);
4388 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
4390 LayerTreeHostImplClient
* client
,
4392 SharedBitmapManager
* manager
,
4393 RenderingStatsInstrumentation
* stats_instrumentation
) {
4394 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4395 scoped_ptr
<OutputSurface
> output_surface(
4396 FakeOutputSurface::Create3d(provider
));
4397 provider
->BindToCurrentThread();
4398 provider
->TestContext3d()->set_have_post_sub_buffer(true);
4400 LayerTreeSettings settings
;
4401 settings
.partial_swap_enabled
= partial_swap
;
4402 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
4403 settings
, client
, proxy
, stats_instrumentation
, manager
, 0);
4404 my_host_impl
->InitializeRenderer(output_surface
.Pass());
4405 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
4408 Layers are created as follows:
4410 +--------------------+
4414 | | +-------------------+
4416 | | +-------------------+
4421 +--------------------+
4423 Layers 1, 2 have render surfaces
4425 scoped_ptr
<LayerImpl
> root
=
4426 LayerImpl::Create(my_host_impl
->active_tree(), 1);
4427 scoped_ptr
<LayerImpl
> child
=
4428 LayerImpl::Create(my_host_impl
->active_tree(), 2);
4429 scoped_ptr
<LayerImpl
> grand_child
=
4430 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
4432 gfx::Rect
root_rect(0, 0, 100, 100);
4433 gfx::Rect
child_rect(10, 10, 50, 50);
4434 gfx::Rect
grand_child_rect(5, 5, 150, 150);
4436 root
->CreateRenderSurface();
4437 root
->SetAnchorPoint(gfx::PointF());
4438 root
->SetPosition(root_rect
.origin());
4439 root
->SetBounds(root_rect
.size());
4440 root
->SetContentBounds(root
->bounds());
4441 root
->draw_properties().visible_content_rect
= root_rect
;
4442 root
->SetDrawsContent(false);
4443 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
4445 child
->SetAnchorPoint(gfx::PointF());
4446 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
4447 child
->SetOpacity(0.5f
);
4448 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
4449 child
->SetContentBounds(child
->bounds());
4450 child
->draw_properties().visible_content_rect
= child_rect
;
4451 child
->SetDrawsContent(false);
4452 child
->SetForceRenderSurface(true);
4454 grand_child
->SetAnchorPoint(gfx::PointF());
4455 grand_child
->SetPosition(grand_child_rect
.origin());
4456 grand_child
->SetBounds(grand_child_rect
.size());
4457 grand_child
->SetContentBounds(grand_child
->bounds());
4458 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
4459 grand_child
->SetDrawsContent(true);
4461 child
->AddChild(grand_child
.Pass());
4462 root
->AddChild(child
.Pass());
4464 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4465 return my_host_impl
.Pass();
4468 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
4469 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4470 new TestSharedBitmapManager());
4471 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4472 SetupLayersForOpacity(true,
4475 shared_bitmap_manager
.get(),
4476 &stats_instrumentation_
);
4478 LayerTreeHostImpl::FrameData frame
;
4479 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4481 // Verify all quads have been computed
4482 ASSERT_EQ(2U, frame
.render_passes
.size());
4483 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4484 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4485 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4486 frame
.render_passes
[0]->quad_list
[0]->material
);
4487 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4488 frame
.render_passes
[1]->quad_list
[0]->material
);
4490 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4491 my_host_impl
->DidDrawAllLayers(frame
);
4495 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
4496 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4497 new TestSharedBitmapManager());
4498 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4499 SetupLayersForOpacity(false,
4502 shared_bitmap_manager
.get(),
4503 &stats_instrumentation_
);
4505 LayerTreeHostImpl::FrameData frame
;
4506 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4508 // Verify all quads have been computed
4509 ASSERT_EQ(2U, frame
.render_passes
.size());
4510 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4511 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4512 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4513 frame
.render_passes
[0]->quad_list
[0]->material
);
4514 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4515 frame
.render_passes
[1]->quad_list
[0]->material
);
4517 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4518 my_host_impl
->DidDrawAllLayers(frame
);
4522 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
4523 scoped_ptr
<TestWebGraphicsContext3D
> context
=
4524 TestWebGraphicsContext3D::Create();
4525 TestWebGraphicsContext3D
* context3d
= context
.get();
4526 scoped_ptr
<OutputSurface
> output_surface(
4527 FakeOutputSurface::Create3d(context
.Pass()));
4528 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4530 scoped_ptr
<LayerImpl
> root_layer
=
4531 LayerImpl::Create(host_impl_
->active_tree(), 1);
4532 root_layer
->SetBounds(gfx::Size(10, 10));
4533 root_layer
->SetAnchorPoint(gfx::PointF());
4535 scoped_refptr
<VideoFrame
> softwareFrame
=
4536 media::VideoFrame::CreateColorFrame(
4537 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
4538 FakeVideoFrameProvider provider
;
4539 provider
.set_frame(softwareFrame
);
4540 scoped_ptr
<VideoLayerImpl
> video_layer
=
4541 VideoLayerImpl::Create(host_impl_
->active_tree(), 4, &provider
);
4542 video_layer
->SetBounds(gfx::Size(10, 10));
4543 video_layer
->SetAnchorPoint(gfx::PointF());
4544 video_layer
->SetContentBounds(gfx::Size(10, 10));
4545 video_layer
->SetDrawsContent(true);
4546 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
4548 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
4549 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
4550 io_surface_layer
->SetBounds(gfx::Size(10, 10));
4551 io_surface_layer
->SetAnchorPoint(gfx::PointF());
4552 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
4553 io_surface_layer
->SetDrawsContent(true);
4554 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
4555 root_layer
->AddChild(io_surface_layer
.PassAs
<LayerImpl
>());
4557 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
4559 EXPECT_EQ(0u, context3d
->NumTextures());
4561 LayerTreeHostImpl::FrameData frame
;
4562 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4563 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4564 host_impl_
->DidDrawAllLayers(frame
);
4565 host_impl_
->SwapBuffers(frame
);
4567 EXPECT_GT(context3d
->NumTextures(), 0u);
4569 // Kill the layer tree.
4570 host_impl_
->active_tree()->SetRootLayer(
4571 LayerImpl::Create(host_impl_
->active_tree(), 100));
4572 // There should be no textures left in use after.
4573 EXPECT_EQ(0u, context3d
->NumTextures());
4576 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
4578 MOCK_METHOD1(useProgram
, void(GLuint program
));
4579 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4585 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
4586 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
4587 new MockDrawQuadsToFillScreenContext
);
4588 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
4590 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4591 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4594 LayerTreeSettings settings
= DefaultSettings();
4595 settings
.partial_swap_enabled
= false;
4596 CreateHostImpl(settings
, output_surface
.Pass());
4597 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
4598 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
4600 // Verify one quad is drawn when transparent background set is not set.
4601 host_impl_
->active_tree()->set_has_transparent_background(false);
4602 EXPECT_CALL(*mock_context
, useProgram(_
))
4604 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
4606 LayerTreeHostImpl::FrameData frame
;
4607 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4608 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4609 host_impl_
->DidDrawAllLayers(frame
);
4610 Mock::VerifyAndClearExpectations(&mock_context
);
4612 // Verify no quads are drawn when transparent background is set.
4613 host_impl_
->active_tree()->set_has_transparent_background(true);
4614 host_impl_
->SetFullRootLayerDamage();
4615 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4616 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4617 host_impl_
->DidDrawAllLayers(frame
);
4618 Mock::VerifyAndClearExpectations(&mock_context
);
4621 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
4622 set_reduce_memory_result(false);
4624 // If changing the memory limit wouldn't result in changing what was
4625 // committed, then no commit should be requested.
4626 set_reduce_memory_result(false);
4627 host_impl_
->set_max_memory_needed_bytes(
4628 host_impl_
->memory_allocation_limit_bytes() - 1);
4629 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4630 host_impl_
->memory_allocation_limit_bytes() - 1));
4631 EXPECT_FALSE(did_request_commit_
);
4632 did_request_commit_
= false;
4634 // If changing the memory limit would result in changing what was
4635 // committed, then a commit should be requested, even though nothing was
4637 set_reduce_memory_result(false);
4638 host_impl_
->set_max_memory_needed_bytes(
4639 host_impl_
->memory_allocation_limit_bytes());
4640 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4641 host_impl_
->memory_allocation_limit_bytes() - 1));
4642 EXPECT_TRUE(did_request_commit_
);
4643 did_request_commit_
= false;
4645 // Especially if changing the memory limit caused evictions, we need
4647 set_reduce_memory_result(true);
4648 host_impl_
->set_max_memory_needed_bytes(1);
4649 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4650 host_impl_
->memory_allocation_limit_bytes() - 1));
4651 EXPECT_TRUE(did_request_commit_
);
4652 did_request_commit_
= false;
4654 // But if we set it to the same value that it was before, we shouldn't
4656 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4657 host_impl_
->memory_allocation_limit_bytes()));
4658 EXPECT_FALSE(did_request_commit_
);
4661 class LayerTreeHostImplTestWithDelegatingRenderer
4662 : public LayerTreeHostImplTest
{
4664 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
4665 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
4668 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
4669 bool expect_to_draw
= !expected_damage
.IsEmpty();
4671 LayerTreeHostImpl::FrameData frame
;
4672 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4674 if (!expect_to_draw
) {
4675 // With no damage, we don't draw, and no quads are created.
4676 ASSERT_EQ(0u, frame
.render_passes
.size());
4678 ASSERT_EQ(1u, frame
.render_passes
.size());
4680 // Verify the damage rect for the root render pass.
4681 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
4682 EXPECT_RECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
4684 // Verify the root and child layers' quads are generated and not being
4686 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
4688 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
4689 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
4690 EXPECT_RECT_EQ(expected_child_visible_rect
,
4691 root_render_pass
->quad_list
[0]->visible_rect
);
4693 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4694 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
4695 EXPECT_RECT_EQ(expected_root_visible_rect
,
4696 root_render_pass
->quad_list
[1]->visible_rect
);
4699 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4700 host_impl_
->DidDrawAllLayers(frame
);
4701 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
4705 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
4706 scoped_ptr
<SolidColorLayerImpl
> root
=
4707 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
4708 root
->SetAnchorPoint(gfx::PointF());
4709 root
->SetPosition(gfx::PointF());
4710 root
->SetBounds(gfx::Size(10, 10));
4711 root
->SetContentBounds(gfx::Size(10, 10));
4712 root
->SetDrawsContent(true);
4714 // Child layer is in the bottom right corner.
4715 scoped_ptr
<SolidColorLayerImpl
> child
=
4716 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
4717 child
->SetAnchorPoint(gfx::PointF(0.f
, 0.f
));
4718 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
4719 child
->SetBounds(gfx::Size(1, 1));
4720 child
->SetContentBounds(gfx::Size(1, 1));
4721 child
->SetDrawsContent(true);
4722 root
->AddChild(child
.PassAs
<LayerImpl
>());
4724 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
4726 // Draw a frame. In the first frame, the entire viewport should be damaged.
4727 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
4728 DrawFrameAndTestDamage(full_frame_damage
);
4730 // The second frame has damage that doesn't touch the child layer. Its quads
4731 // should still be generated.
4732 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
4733 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
4734 DrawFrameAndTestDamage(small_damage
);
4736 // The third frame should have no damage, so no quads should be generated.
4737 gfx::Rect no_damage
;
4738 DrawFrameAndTestDamage(no_damage
);
4741 // TODO(reveman): Remove this test and the ability to prevent on demand raster
4742 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
4743 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
4744 LayerTreeSettings settings
;
4745 CreateHostImpl(settings
, CreateOutputSurface());
4746 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
4749 class FakeMaskLayerImpl
: public LayerImpl
{
4751 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4753 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
4756 virtual ResourceProvider::ResourceId
ContentsResourceId() const OVERRIDE
{
4761 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4762 : LayerImpl(tree_impl
, id
) {}
4765 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
4766 LayerTreeSettings settings
;
4767 settings
.layer_transforms_should_scale_layer_contents
= true;
4768 CreateHostImpl(settings
, CreateOutputSurface());
4772 // +-- Scaling Layer (adds a 2x scale)
4774 // +-- Content Layer
4776 scoped_ptr
<LayerImpl
> scoped_root
=
4777 LayerImpl::Create(host_impl_
->active_tree(), 1);
4778 LayerImpl
* root
= scoped_root
.get();
4779 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4781 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
4782 LayerImpl::Create(host_impl_
->active_tree(), 2);
4783 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
4784 root
->AddChild(scoped_scaling_layer
.Pass());
4786 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4787 LayerImpl::Create(host_impl_
->active_tree(), 3);
4788 LayerImpl
* content_layer
= scoped_content_layer
.get();
4789 scaling_layer
->AddChild(scoped_content_layer
.Pass());
4791 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4792 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4793 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4794 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4796 gfx::Size
root_size(100, 100);
4797 root
->SetBounds(root_size
);
4798 root
->SetContentBounds(root_size
);
4799 root
->SetPosition(gfx::PointF());
4800 root
->SetAnchorPoint(gfx::PointF());
4802 gfx::Size
scaling_layer_size(50, 50);
4803 scaling_layer
->SetBounds(scaling_layer_size
);
4804 scaling_layer
->SetContentBounds(scaling_layer_size
);
4805 scaling_layer
->SetPosition(gfx::PointF());
4806 scaling_layer
->SetAnchorPoint(gfx::PointF());
4807 gfx::Transform scale
;
4808 scale
.Scale(2.f
, 2.f
);
4809 scaling_layer
->SetTransform(scale
);
4811 content_layer
->SetBounds(scaling_layer_size
);
4812 content_layer
->SetContentBounds(scaling_layer_size
);
4813 content_layer
->SetPosition(gfx::PointF());
4814 content_layer
->SetAnchorPoint(gfx::PointF());
4815 content_layer
->SetDrawsContent(true);
4817 mask_layer
->SetBounds(scaling_layer_size
);
4818 mask_layer
->SetContentBounds(scaling_layer_size
);
4819 mask_layer
->SetPosition(gfx::PointF());
4820 mask_layer
->SetAnchorPoint(gfx::PointF());
4821 mask_layer
->SetDrawsContent(true);
4824 // Check that the tree scaling is correctly taken into account for the mask,
4825 // that should fully map onto the quad.
4826 float device_scale_factor
= 1.f
;
4827 host_impl_
->SetViewportSize(root_size
);
4828 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4830 LayerTreeHostImpl::FrameData frame
;
4831 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4833 ASSERT_EQ(1u, frame
.render_passes
.size());
4834 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4835 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4836 frame
.render_passes
[0]->quad_list
[0]->material
);
4837 const RenderPassDrawQuad
* render_pass_quad
=
4838 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4839 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4840 render_pass_quad
->rect
.ToString());
4841 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4842 render_pass_quad
->mask_uv_rect
.ToString());
4844 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4845 host_impl_
->DidDrawAllLayers(frame
);
4849 // Applying a DSF should change the render surface size, but won't affect
4850 // which part of the mask is used.
4851 device_scale_factor
= 2.f
;
4852 gfx::Size device_viewport
=
4853 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4854 host_impl_
->SetViewportSize(device_viewport
);
4855 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4856 host_impl_
->active_tree()->set_needs_update_draw_properties();
4858 LayerTreeHostImpl::FrameData frame
;
4859 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4861 ASSERT_EQ(1u, frame
.render_passes
.size());
4862 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4863 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4864 frame
.render_passes
[0]->quad_list
[0]->material
);
4865 const RenderPassDrawQuad
* render_pass_quad
=
4866 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4867 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4868 render_pass_quad
->rect
.ToString());
4869 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4870 render_pass_quad
->mask_uv_rect
.ToString());
4872 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4873 host_impl_
->DidDrawAllLayers(frame
);
4877 // Applying an equivalent content scale on the content layer and the mask
4878 // should still result in the same part of the mask being used.
4879 gfx::Size content_bounds
=
4880 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
4881 device_scale_factor
));
4882 content_layer
->SetContentBounds(content_bounds
);
4883 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4884 mask_layer
->SetContentBounds(content_bounds
);
4885 mask_layer
->SetContentsScale(device_scale_factor
, 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 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
4908 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4911 scoped_ptr
<LayerImpl
> scoped_root
=
4912 LayerImpl::Create(host_impl_
->active_tree(), 1);
4913 LayerImpl
* root
= scoped_root
.get();
4914 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4916 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4917 LayerImpl::Create(host_impl_
->active_tree(), 3);
4918 LayerImpl
* content_layer
= scoped_content_layer
.get();
4919 root
->AddChild(scoped_content_layer
.Pass());
4921 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4922 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4923 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4924 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4926 gfx::Size
root_size(100, 100);
4927 root
->SetBounds(root_size
);
4928 root
->SetContentBounds(root_size
);
4929 root
->SetPosition(gfx::PointF());
4930 root
->SetAnchorPoint(gfx::PointF());
4932 gfx::Size
layer_size(50, 50);
4933 content_layer
->SetBounds(layer_size
);
4934 content_layer
->SetContentBounds(layer_size
);
4935 content_layer
->SetPosition(gfx::PointF());
4936 content_layer
->SetAnchorPoint(gfx::PointF());
4937 content_layer
->SetDrawsContent(true);
4939 gfx::Size
mask_size(100, 100);
4940 mask_layer
->SetBounds(mask_size
);
4941 mask_layer
->SetContentBounds(mask_size
);
4942 mask_layer
->SetPosition(gfx::PointF());
4943 mask_layer
->SetAnchorPoint(gfx::PointF());
4944 mask_layer
->SetDrawsContent(true);
4946 // Check that the mask fills the surface.
4947 float device_scale_factor
= 1.f
;
4948 host_impl_
->SetViewportSize(root_size
);
4949 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4951 LayerTreeHostImpl::FrameData frame
;
4952 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4954 ASSERT_EQ(1u, frame
.render_passes
.size());
4955 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4956 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4957 frame
.render_passes
[0]->quad_list
[0]->material
);
4958 const RenderPassDrawQuad
* render_pass_quad
=
4959 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4960 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4961 render_pass_quad
->rect
.ToString());
4962 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4963 render_pass_quad
->mask_uv_rect
.ToString());
4965 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4966 host_impl_
->DidDrawAllLayers(frame
);
4969 // Applying a DSF should change the render surface size, but won't affect
4970 // which part of the mask is used.
4971 device_scale_factor
= 2.f
;
4972 gfx::Size device_viewport
=
4973 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4974 host_impl_
->SetViewportSize(device_viewport
);
4975 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4976 host_impl_
->active_tree()->set_needs_update_draw_properties();
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, 100, 100).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 an equivalent content scale on the content layer and the mask
4997 // should still result in the same part of the mask being used.
4998 gfx::Size layer_size_large
=
4999 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5000 content_layer
->SetContentBounds(layer_size_large
);
5001 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5002 gfx::Size mask_size_large
=
5003 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5004 mask_layer
->SetContentBounds(mask_size_large
);
5005 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5006 host_impl_
->active_tree()->set_needs_update_draw_properties();
5008 LayerTreeHostImpl::FrameData frame
;
5009 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5011 ASSERT_EQ(1u, frame
.render_passes
.size());
5012 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5013 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5014 frame
.render_passes
[0]->quad_list
[0]->material
);
5015 const RenderPassDrawQuad
* render_pass_quad
=
5016 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5017 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5018 render_pass_quad
->rect
.ToString());
5019 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5020 render_pass_quad
->mask_uv_rect
.ToString());
5022 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5023 host_impl_
->DidDrawAllLayers(frame
);
5026 // Applying a different contents scale to the mask layer means it will have
5027 // a larger texture, but it should use the same tex coords to cover the
5029 mask_layer
->SetContentBounds(mask_size
);
5030 mask_layer
->SetContentsScale(1.f
, 1.f
);
5031 host_impl_
->active_tree()->set_needs_update_draw_properties();
5033 LayerTreeHostImpl::FrameData frame
;
5034 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5036 ASSERT_EQ(1u, frame
.render_passes
.size());
5037 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5038 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5039 frame
.render_passes
[0]->quad_list
[0]->material
);
5040 const RenderPassDrawQuad
* render_pass_quad
=
5041 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5042 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5043 render_pass_quad
->rect
.ToString());
5044 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5045 render_pass_quad
->mask_uv_rect
.ToString());
5047 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5048 host_impl_
->DidDrawAllLayers(frame
);
5052 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5053 // The replica's mask layer has bounds 100x100 but the replica is of a
5054 // layer with bounds 50x50.
5056 scoped_ptr
<LayerImpl
> scoped_root
=
5057 LayerImpl::Create(host_impl_
->active_tree(), 1);
5058 LayerImpl
* root
= scoped_root
.get();
5059 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5061 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5062 LayerImpl::Create(host_impl_
->active_tree(), 3);
5063 LayerImpl
* content_layer
= scoped_content_layer
.get();
5064 root
->AddChild(scoped_content_layer
.Pass());
5066 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5067 LayerImpl::Create(host_impl_
->active_tree(), 2);
5068 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5069 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5071 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5072 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5073 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5074 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5076 gfx::Size
root_size(100, 100);
5077 root
->SetBounds(root_size
);
5078 root
->SetContentBounds(root_size
);
5079 root
->SetPosition(gfx::PointF());
5080 root
->SetAnchorPoint(gfx::PointF());
5082 gfx::Size
layer_size(50, 50);
5083 content_layer
->SetBounds(layer_size
);
5084 content_layer
->SetContentBounds(layer_size
);
5085 content_layer
->SetPosition(gfx::PointF());
5086 content_layer
->SetAnchorPoint(gfx::PointF());
5087 content_layer
->SetDrawsContent(true);
5089 gfx::Size
mask_size(100, 100);
5090 mask_layer
->SetBounds(mask_size
);
5091 mask_layer
->SetContentBounds(mask_size
);
5092 mask_layer
->SetPosition(gfx::PointF());
5093 mask_layer
->SetAnchorPoint(gfx::PointF());
5094 mask_layer
->SetDrawsContent(true);
5096 // Check that the mask fills the surface.
5097 float device_scale_factor
= 1.f
;
5098 host_impl_
->SetViewportSize(root_size
);
5099 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5101 LayerTreeHostImpl::FrameData frame
;
5102 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5104 ASSERT_EQ(1u, frame
.render_passes
.size());
5105 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5106 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5107 frame
.render_passes
[0]->quad_list
[1]->material
);
5108 const RenderPassDrawQuad
* replica_quad
=
5109 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5110 EXPECT_TRUE(replica_quad
->is_replica
);
5111 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5112 replica_quad
->rect
.ToString());
5113 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5114 replica_quad
->mask_uv_rect
.ToString());
5116 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5117 host_impl_
->DidDrawAllLayers(frame
);
5120 // Applying a DSF should change the render surface size, but won't affect
5121 // which part of the mask is used.
5122 device_scale_factor
= 2.f
;
5123 gfx::Size device_viewport
=
5124 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5125 host_impl_
->SetViewportSize(device_viewport
);
5126 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5127 host_impl_
->active_tree()->set_needs_update_draw_properties();
5129 LayerTreeHostImpl::FrameData frame
;
5130 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5132 ASSERT_EQ(1u, frame
.render_passes
.size());
5133 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5134 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5135 frame
.render_passes
[0]->quad_list
[1]->material
);
5136 const RenderPassDrawQuad
* replica_quad
=
5137 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5138 EXPECT_TRUE(replica_quad
->is_replica
);
5139 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5140 replica_quad
->rect
.ToString());
5141 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5142 replica_quad
->mask_uv_rect
.ToString());
5144 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5145 host_impl_
->DidDrawAllLayers(frame
);
5148 // Applying an equivalent content scale on the content layer and the mask
5149 // should still result in the same part of the mask being used.
5150 gfx::Size layer_size_large
=
5151 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5152 content_layer
->SetContentBounds(layer_size_large
);
5153 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5154 gfx::Size mask_size_large
=
5155 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5156 mask_layer
->SetContentBounds(mask_size_large
);
5157 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5158 host_impl_
->active_tree()->set_needs_update_draw_properties();
5160 LayerTreeHostImpl::FrameData frame
;
5161 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5163 ASSERT_EQ(1u, frame
.render_passes
.size());
5164 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5165 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5166 frame
.render_passes
[0]->quad_list
[1]->material
);
5167 const RenderPassDrawQuad
* replica_quad
=
5168 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5169 EXPECT_TRUE(replica_quad
->is_replica
);
5170 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5171 replica_quad
->rect
.ToString());
5172 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5173 replica_quad
->mask_uv_rect
.ToString());
5175 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5176 host_impl_
->DidDrawAllLayers(frame
);
5179 // Applying a different contents scale to the mask layer means it will have
5180 // a larger texture, but it should use the same tex coords to cover the
5182 mask_layer
->SetContentBounds(mask_size
);
5183 mask_layer
->SetContentsScale(1.f
, 1.f
);
5184 host_impl_
->active_tree()->set_needs_update_draw_properties();
5186 LayerTreeHostImpl::FrameData frame
;
5187 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5189 ASSERT_EQ(1u, frame
.render_passes
.size());
5190 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5191 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5192 frame
.render_passes
[0]->quad_list
[1]->material
);
5193 const RenderPassDrawQuad
* replica_quad
=
5194 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5195 EXPECT_TRUE(replica_quad
->is_replica
);
5196 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5197 replica_quad
->rect
.ToString());
5198 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5199 replica_quad
->mask_uv_rect
.ToString());
5201 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5202 host_impl_
->DidDrawAllLayers(frame
);
5206 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5207 // The replica is of a layer with bounds 50x50, but it has a child that causes
5208 // the surface bounds to be larger.
5210 scoped_ptr
<LayerImpl
> scoped_root
=
5211 LayerImpl::Create(host_impl_
->active_tree(), 1);
5212 LayerImpl
* root
= scoped_root
.get();
5213 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5215 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5216 LayerImpl::Create(host_impl_
->active_tree(), 2);
5217 LayerImpl
* content_layer
= scoped_content_layer
.get();
5218 root
->AddChild(scoped_content_layer
.Pass());
5220 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5221 LayerImpl::Create(host_impl_
->active_tree(), 3);
5222 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5223 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5225 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5226 LayerImpl::Create(host_impl_
->active_tree(), 4);
5227 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5228 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5230 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5231 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5232 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5233 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5235 gfx::Size
root_size(100, 100);
5236 root
->SetBounds(root_size
);
5237 root
->SetContentBounds(root_size
);
5238 root
->SetPosition(gfx::PointF());
5239 root
->SetAnchorPoint(gfx::PointF());
5241 gfx::Size
layer_size(50, 50);
5242 content_layer
->SetBounds(layer_size
);
5243 content_layer
->SetContentBounds(layer_size
);
5244 content_layer
->SetPosition(gfx::PointF());
5245 content_layer
->SetAnchorPoint(gfx::PointF());
5246 content_layer
->SetDrawsContent(true);
5248 gfx::Size
child_size(50, 50);
5249 content_child_layer
->SetBounds(child_size
);
5250 content_child_layer
->SetContentBounds(child_size
);
5251 content_child_layer
->SetPosition(gfx::Point(50, 0));
5252 content_child_layer
->SetAnchorPoint(gfx::PointF());
5253 content_child_layer
->SetDrawsContent(true);
5255 gfx::Size
mask_size(50, 50);
5256 mask_layer
->SetBounds(mask_size
);
5257 mask_layer
->SetContentBounds(mask_size
);
5258 mask_layer
->SetPosition(gfx::PointF());
5259 mask_layer
->SetAnchorPoint(gfx::PointF());
5260 mask_layer
->SetDrawsContent(true);
5262 float device_scale_factor
= 1.f
;
5263 host_impl_
->SetViewportSize(root_size
);
5264 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5266 LayerTreeHostImpl::FrameData frame
;
5267 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5269 ASSERT_EQ(1u, frame
.render_passes
.size());
5270 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5272 // The surface is 100x50.
5273 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5274 frame
.render_passes
[0]->quad_list
[0]->material
);
5275 const RenderPassDrawQuad
* render_pass_quad
=
5276 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5277 EXPECT_FALSE(render_pass_quad
->is_replica
);
5278 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5279 render_pass_quad
->rect
.ToString());
5281 // The mask covers the owning layer only.
5282 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5283 frame
.render_passes
[0]->quad_list
[1]->material
);
5284 const RenderPassDrawQuad
* replica_quad
=
5285 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5286 EXPECT_TRUE(replica_quad
->is_replica
);
5287 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5288 replica_quad
->rect
.ToString());
5289 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
5290 replica_quad
->mask_uv_rect
.ToString());
5292 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5293 host_impl_
->DidDrawAllLayers(frame
);
5296 // Move the child to (-50, 0) instead. Now the mask should be moved to still
5297 // cover the layer being replicated.
5298 content_child_layer
->SetPosition(gfx::Point(-50, 0));
5300 LayerTreeHostImpl::FrameData frame
;
5301 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5303 ASSERT_EQ(1u, frame
.render_passes
.size());
5304 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5306 // The surface is 100x50 with its origin at (-50, 0).
5307 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5308 frame
.render_passes
[0]->quad_list
[0]->material
);
5309 const RenderPassDrawQuad
* render_pass_quad
=
5310 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5311 EXPECT_FALSE(render_pass_quad
->is_replica
);
5312 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5313 render_pass_quad
->rect
.ToString());
5315 // The mask covers the owning layer only.
5316 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5317 frame
.render_passes
[0]->quad_list
[1]->material
);
5318 const RenderPassDrawQuad
* replica_quad
=
5319 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5320 EXPECT_TRUE(replica_quad
->is_replica
);
5321 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5322 replica_quad
->rect
.ToString());
5323 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
5324 replica_quad
->mask_uv_rect
.ToString());
5326 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5327 host_impl_
->DidDrawAllLayers(frame
);
5331 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
5332 // The masked layer has bounds 50x50, but it has a child that causes
5333 // the surface bounds to be larger. It also has a parent that clips the
5334 // masked layer and its surface.
5336 scoped_ptr
<LayerImpl
> scoped_root
=
5337 LayerImpl::Create(host_impl_
->active_tree(), 1);
5338 LayerImpl
* root
= scoped_root
.get();
5339 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5341 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
5342 LayerImpl::Create(host_impl_
->active_tree(), 2);
5343 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
5344 root
->AddChild(scoped_clipping_layer
.Pass());
5346 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5347 LayerImpl::Create(host_impl_
->active_tree(), 3);
5348 LayerImpl
* content_layer
= scoped_content_layer
.get();
5349 clipping_layer
->AddChild(scoped_content_layer
.Pass());
5351 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5352 LayerImpl::Create(host_impl_
->active_tree(), 4);
5353 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5354 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5356 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5357 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
5358 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5359 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5361 gfx::Size
root_size(100, 100);
5362 root
->SetBounds(root_size
);
5363 root
->SetContentBounds(root_size
);
5364 root
->SetPosition(gfx::PointF());
5365 root
->SetAnchorPoint(gfx::PointF());
5367 gfx::Rect
clipping_rect(20, 10, 10, 20);
5368 clipping_layer
->SetBounds(clipping_rect
.size());
5369 clipping_layer
->SetContentBounds(clipping_rect
.size());
5370 clipping_layer
->SetPosition(clipping_rect
.origin());
5371 clipping_layer
->SetAnchorPoint(gfx::PointF());
5372 clipping_layer
->SetMasksToBounds(true);
5374 gfx::Size
layer_size(50, 50);
5375 content_layer
->SetBounds(layer_size
);
5376 content_layer
->SetContentBounds(layer_size
);
5377 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
5378 content_layer
->SetAnchorPoint(gfx::PointF());
5379 content_layer
->SetDrawsContent(true);
5381 gfx::Size
child_size(50, 50);
5382 content_child_layer
->SetBounds(child_size
);
5383 content_child_layer
->SetContentBounds(child_size
);
5384 content_child_layer
->SetPosition(gfx::Point(50, 0));
5385 content_child_layer
->SetAnchorPoint(gfx::PointF());
5386 content_child_layer
->SetDrawsContent(true);
5388 gfx::Size
mask_size(100, 100);
5389 mask_layer
->SetBounds(mask_size
);
5390 mask_layer
->SetContentBounds(mask_size
);
5391 mask_layer
->SetPosition(gfx::PointF());
5392 mask_layer
->SetAnchorPoint(gfx::PointF());
5393 mask_layer
->SetDrawsContent(true);
5395 float device_scale_factor
= 1.f
;
5396 host_impl_
->SetViewportSize(root_size
);
5397 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5399 LayerTreeHostImpl::FrameData frame
;
5400 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5402 ASSERT_EQ(1u, frame
.render_passes
.size());
5403 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5405 // The surface is clipped to 10x20.
5406 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5407 frame
.render_passes
[0]->quad_list
[0]->material
);
5408 const RenderPassDrawQuad
* render_pass_quad
=
5409 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5410 EXPECT_FALSE(render_pass_quad
->is_replica
);
5411 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5412 render_pass_quad
->rect
.ToString());
5414 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5415 // coords in the mask are scaled by 10/50 and 20/50.
5416 // The surface is clipped to (20,10) so the mask texture coords are offset
5417 // by 20/50 and 10/50
5418 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
),
5419 1.f
/ 50.f
).ToString(),
5420 render_pass_quad
->mask_uv_rect
.ToString());
5422 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5423 host_impl_
->DidDrawAllLayers(frame
);
5427 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
5429 using GLRenderer::SetupQuadForAntialiasing
;
5432 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
5433 // Due to precision issues (especially on Android), sometimes far
5434 // away quads can end up thinking they need AA.
5435 float device_scale_factor
= 4.f
/ 3.f
;
5436 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5437 gfx::Size
root_size(2000, 1000);
5438 gfx::Size device_viewport_size
=
5439 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5440 host_impl_
->SetViewportSize(device_viewport_size
);
5442 host_impl_
->CreatePendingTree();
5443 host_impl_
->pending_tree()
5444 ->SetPageScaleFactorAndLimits(1.f
, 1.f
/ 16.f
, 16.f
);
5446 scoped_ptr
<LayerImpl
> scoped_root
=
5447 LayerImpl::Create(host_impl_
->pending_tree(), 1);
5448 LayerImpl
* root
= scoped_root
.get();
5450 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
5452 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
5453 LayerImpl::Create(host_impl_
->pending_tree(), 2);
5454 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
5455 root
->AddChild(scoped_scrolling_layer
.Pass());
5457 gfx::Size
content_layer_bounds(100000, 100);
5458 gfx::Size
pile_tile_size(3000, 3000);
5459 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
5460 pile_tile_size
, content_layer_bounds
));
5462 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
5463 FakePictureLayerImpl::CreateWithPile(host_impl_
->pending_tree(), 3, pile
);
5464 LayerImpl
* content_layer
= scoped_content_layer
.get();
5465 scrolling_layer
->AddChild(scoped_content_layer
.PassAs
<LayerImpl
>());
5466 content_layer
->SetBounds(content_layer_bounds
);
5467 content_layer
->SetDrawsContent(true);
5469 root
->SetBounds(root_size
);
5471 gfx::Vector2d
scroll_offset(100000, 0);
5472 scrolling_layer
->SetScrollClipLayer(root
->id());
5473 scrolling_layer
->SetScrollOffset(scroll_offset
);
5475 host_impl_
->ActivatePendingTree();
5477 host_impl_
->active_tree()->UpdateDrawProperties();
5478 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
5480 LayerTreeHostImpl::FrameData frame
;
5481 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5483 ASSERT_EQ(1u, frame
.render_passes
.size());
5484 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
5485 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
[0];
5488 gfx::QuadF device_layer_quad
;
5490 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
5491 quad
->quadTransform(), quad
, &device_layer_quad
, edge
);
5492 EXPECT_FALSE(antialiased
);
5494 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5495 host_impl_
->DidDrawAllLayers(frame
);
5499 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
5501 CompositorFrameMetadataTest()
5502 : swap_buffers_complete_(0) {}
5504 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{
5505 swap_buffers_complete_
++;
5508 int swap_buffers_complete_
;
5511 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
5512 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5514 LayerTreeHostImpl::FrameData frame
;
5515 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5516 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
5517 host_impl_
->DidDrawAllLayers(frame
);
5519 CompositorFrameAck ack
;
5520 host_impl_
->ReclaimResources(&ack
);
5521 host_impl_
->DidSwapBuffersComplete();
5522 EXPECT_EQ(swap_buffers_complete_
, 1);
5525 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
5527 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
5529 virtual SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) OVERRIDE
{
5531 return SoftwareOutputDevice::BeginPaint(damage_rect
);
5533 virtual void EndPaint(SoftwareFrameData
* frame_data
) OVERRIDE
{
5535 SoftwareOutputDevice::EndPaint(frame_data
);
5538 int frames_began_
, frames_ended_
;
5541 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
5542 // No main thread evictions in resourceless software mode.
5543 set_reduce_memory_result(false);
5544 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
5545 bool delegated_rendering
= false;
5546 FakeOutputSurface
* output_surface
=
5547 FakeOutputSurface::CreateDeferredGL(
5548 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
5549 delegated_rendering
).release();
5550 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5551 scoped_ptr
<OutputSurface
>(output_surface
)));
5552 host_impl_
->SetViewportSize(gfx::Size(50, 50));
5554 SetupScrollAndContentsLayers(gfx::Size(100, 100));
5556 output_surface
->set_forced_draw_to_software_device(true);
5557 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5559 EXPECT_EQ(0, software_device
->frames_began_
);
5560 EXPECT_EQ(0, software_device
->frames_ended_
);
5564 EXPECT_EQ(1, software_device
->frames_began_
);
5565 EXPECT_EQ(1, software_device
->frames_ended_
);
5567 // Call other API methods that are likely to hit NULL pointer in this mode.
5568 EXPECT_TRUE(host_impl_
->AsValue());
5569 EXPECT_TRUE(host_impl_
->ActivationStateAsValue());
5572 TEST_F(LayerTreeHostImplTest
,
5573 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
5574 set_reduce_memory_result(false);
5575 bool delegated_rendering
= false;
5576 FakeOutputSurface
* output_surface
=
5577 FakeOutputSurface::CreateDeferredGL(
5578 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5579 delegated_rendering
).release();
5580 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5581 scoped_ptr
<OutputSurface
>(output_surface
)));
5583 output_surface
->set_forced_draw_to_software_device(true);
5584 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5586 // SolidColorLayerImpl will be drawn.
5587 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5588 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5590 // VideoLayerImpl will not be drawn.
5591 FakeVideoFrameProvider provider
;
5592 scoped_ptr
<VideoLayerImpl
> video_layer
=
5593 VideoLayerImpl::Create(host_impl_
->active_tree(), 2, &provider
);
5594 video_layer
->SetBounds(gfx::Size(10, 10));
5595 video_layer
->SetContentBounds(gfx::Size(10, 10));
5596 video_layer
->SetDrawsContent(true);
5597 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
5598 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5600 LayerTreeHostImpl::FrameData frame
;
5601 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5602 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5603 host_impl_
->DidDrawAllLayers(frame
);
5605 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
5606 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
5609 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
5611 virtual void SetUp() OVERRIDE
{
5612 LayerTreeHostImplTest::SetUp();
5614 set_reduce_memory_result(false);
5616 bool delegated_rendering
= false;
5617 scoped_ptr
<FakeOutputSurface
> output_surface(
5618 FakeOutputSurface::CreateDeferredGL(
5619 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5620 delegated_rendering
));
5621 output_surface_
= output_surface
.get();
5623 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5624 output_surface
.PassAs
<OutputSurface
>()));
5626 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5627 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5628 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5630 onscreen_context_provider_
= TestContextProvider::Create();
5633 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{
5634 did_update_renderer_capabilities_
= true;
5637 FakeOutputSurface
* output_surface_
;
5638 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
5639 bool did_update_renderer_capabilities_
;
5643 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
5647 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5649 // DeferredInitialize and hardware draw.
5650 did_update_renderer_capabilities_
= false;
5652 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5653 EXPECT_EQ(onscreen_context_provider_
,
5654 host_impl_
->output_surface()->context_provider());
5655 EXPECT_TRUE(did_update_renderer_capabilities_
);
5657 // Defer intialized GL draw.
5660 // Revert back to software.
5661 did_update_renderer_capabilities_
= false;
5662 output_surface_
->ReleaseGL();
5663 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5664 EXPECT_TRUE(did_update_renderer_capabilities_
);
5666 // Software draw again.
5670 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
5674 // Fail initialization of the onscreen context before the OutputSurface binds
5675 // it to the thread.
5676 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
5678 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5680 // DeferredInitialize fails.
5681 did_update_renderer_capabilities_
= false;
5683 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5684 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5685 EXPECT_FALSE(did_update_renderer_capabilities_
);
5687 // Software draw again.
5691 // Checks that we have a non-0 default allocation if we pass a context that
5692 // doesn't support memory management extensions.
5693 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
5694 LayerTreeSettings settings
;
5695 host_impl_
= LayerTreeHostImpl::Create(settings
,
5698 &stats_instrumentation_
,
5699 shared_bitmap_manager_
.get(),
5702 scoped_ptr
<OutputSurface
> output_surface(
5703 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
5704 host_impl_
->InitializeRenderer(output_surface
.Pass());
5705 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
5708 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
5709 ManagedMemoryPolicy
policy1(
5710 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
5711 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5712 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
5713 int allow_nice_to_have_cutoff_value
=
5714 ManagedMemoryPolicy::PriorityCutoffToValue(
5715 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
5716 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5717 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
5719 // GPU rasterization should be disabled by default on the tree(s)
5720 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
5721 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
5723 host_impl_
->SetVisible(true);
5724 host_impl_
->SetMemoryPolicy(policy1
);
5725 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5726 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5728 host_impl_
->SetVisible(false);
5729 EXPECT_EQ(0u, current_limit_bytes_
);
5730 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5732 host_impl_
->SetVisible(true);
5733 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5734 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5736 // Now enable GPU rasterization and test if we get nice to have cutoff,
5738 LayerTreeSettings settings
;
5739 settings
.gpu_rasterization_enabled
= true;
5740 host_impl_
= LayerTreeHostImpl::Create(
5741 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, 0);
5742 host_impl_
->SetUseGpuRasterization(true);
5743 host_impl_
->SetVisible(true);
5744 host_impl_
->SetMemoryPolicy(policy1
);
5745 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5746 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
5748 host_impl_
->SetVisible(false);
5749 EXPECT_EQ(0u, current_limit_bytes_
);
5750 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5753 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
5754 ASSERT_TRUE(host_impl_
->active_tree());
5756 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5757 host_impl_
->SetVisible(false);
5758 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5759 host_impl_
->SetVisible(true);
5760 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5761 host_impl_
->SetVisible(false);
5762 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5764 host_impl_
->CreatePendingTree();
5765 host_impl_
->ActivatePendingTree();
5767 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5768 host_impl_
->SetVisible(true);
5769 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5772 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
5773 ASSERT_TRUE(host_impl_
->active_tree());
5774 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
5776 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5777 host_impl_
->SetUseGpuRasterization(false);
5778 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5779 host_impl_
->SetUseGpuRasterization(true);
5780 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5781 host_impl_
->SetUseGpuRasterization(false);
5782 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5784 host_impl_
->CreatePendingTree();
5785 host_impl_
->ActivatePendingTree();
5787 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5788 host_impl_
->SetUseGpuRasterization(true);
5789 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5792 class LayerTreeHostImplTestManageTiles
: public LayerTreeHostImplTest
{
5794 virtual void SetUp() OVERRIDE
{
5795 LayerTreeSettings settings
;
5796 settings
.impl_side_painting
= true;
5798 fake_host_impl_
= new FakeLayerTreeHostImpl(
5799 settings
, &proxy_
, shared_bitmap_manager_
.get());
5800 host_impl_
.reset(fake_host_impl_
);
5801 host_impl_
->InitializeRenderer(CreateOutputSurface());
5802 host_impl_
->SetViewportSize(gfx::Size(10, 10));
5805 FakeLayerTreeHostImpl
* fake_host_impl_
;
5808 TEST_F(LayerTreeHostImplTestManageTiles
, ManageTilesWhenInvisible
) {
5809 fake_host_impl_
->DidModifyTilePriorities();
5810 EXPECT_TRUE(fake_host_impl_
->manage_tiles_needed());
5811 fake_host_impl_
->SetVisible(false);
5812 EXPECT_FALSE(fake_host_impl_
->manage_tiles_needed());
5815 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
5816 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5817 TestWebGraphicsContext3D::Create();
5818 TestWebGraphicsContext3D
* context3d
= context
.get();
5819 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5820 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5822 EXPECT_EQ(0u, context3d
->NumTextures());
5824 UIResourceId ui_resource_id
= 1;
5825 bool is_opaque
= false;
5826 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
5827 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5828 EXPECT_EQ(1u, context3d
->NumTextures());
5829 ResourceProvider::ResourceId id1
=
5830 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5833 // Multiple requests with the same id is allowed. The previous texture is
5835 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5836 EXPECT_EQ(1u, context3d
->NumTextures());
5837 ResourceProvider::ResourceId id2
=
5838 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5840 EXPECT_NE(id1
, id2
);
5842 // Deleting invalid UIResourceId is allowed and does not change state.
5843 host_impl_
->DeleteUIResource(-1);
5844 EXPECT_EQ(1u, context3d
->NumTextures());
5846 // Should return zero for invalid UIResourceId. Number of textures should
5848 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
5849 EXPECT_EQ(1u, context3d
->NumTextures());
5851 host_impl_
->DeleteUIResource(ui_resource_id
);
5852 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
5853 EXPECT_EQ(0u, context3d
->NumTextures());
5855 // Should not change state for multiple deletion on one UIResourceId
5856 host_impl_
->DeleteUIResource(ui_resource_id
);
5857 EXPECT_EQ(0u, context3d
->NumTextures());
5860 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
5861 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5862 TestWebGraphicsContext3D::Create();
5863 TestWebGraphicsContext3D
* context3d
= context
.get();
5864 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5865 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5867 EXPECT_EQ(0u, context3d
->NumTextures());
5869 gfx::Size
size(4, 4);
5870 // SkImageInfo has no support for ETC1. The |info| below contains the right
5871 // total pixel size for the bitmap but not the right height and width. The
5872 // correct width/height are passed directly to UIResourceBitmap.
5874 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
5875 skia::RefPtr
<SkPixelRef
> pixel_ref
=
5876 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
5877 pixel_ref
->setImmutable();
5878 UIResourceBitmap
bitmap(pixel_ref
, size
);
5879 UIResourceId ui_resource_id
= 1;
5880 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5881 EXPECT_EQ(1u, context3d
->NumTextures());
5882 ResourceProvider::ResourceId id1
=
5883 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5887 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
5890 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
5891 scoped_refptr
<TestContextProvider
> context_provider
=
5892 TestContextProvider::Create();
5896 FakeOutputSurface::Create3d(context_provider
).PassAs
<OutputSurface
>());
5898 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5900 ScopedPtrVector
<CopyOutputRequest
> requests
;
5901 requests
.push_back(CopyOutputRequest::CreateRequest(
5902 base::Bind(&ShutdownReleasesContext_Callback
)));
5904 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
5906 LayerTreeHostImpl::FrameData frame
;
5907 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5908 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5909 host_impl_
->DidDrawAllLayers(frame
);
5911 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5912 // texture in a texture mailbox.
5913 EXPECT_FALSE(context_provider
->HasOneRef());
5914 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
5918 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5919 // released, and the texture deleted.
5920 EXPECT_TRUE(context_provider
->HasOneRef());
5921 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
5924 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
5925 // When flinging via touch, only the child should scroll (we should not
5927 gfx::Size
surface_size(10, 10);
5928 gfx::Size
content_size(20, 20);
5929 scoped_ptr
<LayerImpl
> root_clip
=
5930 LayerImpl::Create(host_impl_
->active_tree(), 3);
5931 scoped_ptr
<LayerImpl
> root
=
5932 CreateScrollableLayer(1, content_size
, root_clip
.get());
5933 root
->SetIsContainerForFixedPositionLayers(true);
5934 scoped_ptr
<LayerImpl
> child
=
5935 CreateScrollableLayer(2, content_size
, root_clip
.get());
5937 root
->AddChild(child
.Pass());
5938 int root_id
= root
->id();
5939 root_clip
->AddChild(root
.Pass());
5941 host_impl_
->SetViewportSize(surface_size
);
5942 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
5943 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
5944 host_impl_
->active_tree()->DidBecomeActive();
5947 EXPECT_EQ(InputHandler::ScrollStarted
,
5948 host_impl_
->ScrollBegin(gfx::Point(),
5949 InputHandler::Gesture
));
5951 EXPECT_EQ(InputHandler::ScrollStarted
,
5952 host_impl_
->FlingScrollBegin());
5954 gfx::Vector2d
scroll_delta(0, 100);
5955 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5956 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5958 host_impl_
->ScrollEnd();
5960 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
5961 host_impl_
->ProcessScrollDeltas();
5963 // Only the child should have scrolled.
5964 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
5965 ExpectNone(*scroll_info
.get(), root_id
);
5969 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
5970 // Scroll a child layer beyond its maximum scroll range and make sure the
5971 // the scroll doesn't bubble up to the parent layer.
5972 gfx::Size
surface_size(10, 10);
5973 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
5974 scoped_ptr
<LayerImpl
> root_scrolling
=
5975 CreateScrollableLayer(2, surface_size
, root
.get());
5977 scoped_ptr
<LayerImpl
> grand_child
=
5978 CreateScrollableLayer(4, surface_size
, root
.get());
5979 grand_child
->SetScrollOffset(gfx::Vector2d(0, 2));
5981 scoped_ptr
<LayerImpl
> child
=
5982 CreateScrollableLayer(3, surface_size
, root
.get());
5983 child
->SetScrollOffset(gfx::Vector2d(0, 4));
5984 child
->AddChild(grand_child
.Pass());
5986 root_scrolling
->AddChild(child
.Pass());
5987 root
->AddChild(root_scrolling
.Pass());
5988 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5989 host_impl_
->active_tree()->DidBecomeActive();
5990 host_impl_
->SetViewportSize(surface_size
);
5993 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
5995 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
5996 LayerImpl
* grand_child
= child
->children()[0];
5998 gfx::Vector2d
scroll_delta(0, -2);
5999 EXPECT_EQ(InputHandler::ScrollStarted
,
6000 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6001 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6003 // The grand child should have scrolled up to its limit.
6004 scroll_info
= host_impl_
->ProcessScrollDeltas();
6005 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
6006 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6007 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6009 // The child should have received the bubbled delta, but the locked
6010 // scrolling layer should remain set as the grand child.
6011 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6012 scroll_info
= host_impl_
->ProcessScrollDeltas();
6013 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6014 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6015 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
6016 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
6018 // The first |ScrollBy| after the fling should re-lock the scrolling
6019 // layer to the first layer that scrolled, which is the child.
6020 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6021 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6022 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6024 // The child should have scrolled up to its limit.
6025 scroll_info
= host_impl_
->ProcessScrollDeltas();
6026 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6027 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
6028 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
6030 // As the locked layer is at it's limit, no further scrolling can occur.
6031 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
6032 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
6033 host_impl_
->ScrollEnd();
6037 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
6038 // When flinging via wheel, the root should eventually scroll (we should
6040 gfx::Size
surface_size(10, 10);
6041 gfx::Size
content_size(20, 20);
6042 scoped_ptr
<LayerImpl
> root_clip
=
6043 LayerImpl::Create(host_impl_
->active_tree(), 3);
6044 scoped_ptr
<LayerImpl
> root_scroll
=
6045 CreateScrollableLayer(1, content_size
, root_clip
.get());
6046 int root_scroll_id
= root_scroll
->id();
6047 scoped_ptr
<LayerImpl
> child
=
6048 CreateScrollableLayer(2, content_size
, root_clip
.get());
6050 root_scroll
->AddChild(child
.Pass());
6051 root_clip
->AddChild(root_scroll
.Pass());
6053 host_impl_
->SetViewportSize(surface_size
);
6054 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6055 host_impl_
->active_tree()->DidBecomeActive();
6058 EXPECT_EQ(InputHandler::ScrollStarted
,
6059 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6061 EXPECT_EQ(InputHandler::ScrollStarted
,
6062 host_impl_
->FlingScrollBegin());
6064 gfx::Vector2d
scroll_delta(0, 100);
6065 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6066 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6068 host_impl_
->ScrollEnd();
6070 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6071 host_impl_
->ProcessScrollDeltas();
6073 // The root should have scrolled.
6074 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6075 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6079 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6080 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6081 // we should return ScrollUnknown.
6082 gfx::Size
content_size(100, 100);
6083 SetupScrollAndContentsLayers(content_size
);
6085 int scroll_layer_id
= 2;
6086 LayerImpl
* scroll_layer
=
6087 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6088 scroll_layer
->SetDrawsContent(true);
6090 int page_scale_layer_id
= 5;
6091 LayerImpl
* page_scale_layer
=
6092 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6094 int occluder_layer_id
= 6;
6095 scoped_ptr
<LayerImpl
> occluder_layer
=
6096 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6097 occluder_layer
->SetDrawsContent(true);
6098 occluder_layer
->SetBounds(content_size
);
6099 occluder_layer
->SetContentBounds(content_size
);
6100 occluder_layer
->SetPosition(gfx::PointF());
6101 occluder_layer
->SetAnchorPoint(gfx::PointF());
6103 // The parent of the occluder is *above* the scroller.
6104 page_scale_layer
->AddChild(occluder_layer
.Pass());
6108 EXPECT_EQ(InputHandler::ScrollUnknown
,
6109 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6112 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6113 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6114 // is not the first scroller we encounter when walking up from the layer, we
6115 // should also return ScrollUnknown.
6116 gfx::Size
content_size(100, 100);
6117 SetupScrollAndContentsLayers(content_size
);
6119 int scroll_layer_id
= 2;
6120 LayerImpl
* scroll_layer
=
6121 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6122 scroll_layer
->SetDrawsContent(true);
6124 int occluder_layer_id
= 6;
6125 scoped_ptr
<LayerImpl
> occluder_layer
=
6126 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6127 occluder_layer
->SetDrawsContent(true);
6128 occluder_layer
->SetBounds(content_size
);
6129 occluder_layer
->SetContentBounds(content_size
);
6130 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6131 occluder_layer
->SetAnchorPoint(gfx::PointF());
6133 int child_scroll_clip_layer_id
= 7;
6134 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6135 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6137 int child_scroll_layer_id
= 8;
6138 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6139 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6141 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6143 child_scroll
->AddChild(occluder_layer
.Pass());
6144 scroll_layer
->AddChild(child_scroll
.Pass());
6148 EXPECT_EQ(InputHandler::ScrollUnknown
,
6149 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6152 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6153 gfx::Size
content_size(100, 100);
6154 SetupScrollAndContentsLayers(content_size
);
6156 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6158 int scroll_layer_id
= 2;
6159 LayerImpl
* scroll_layer
=
6160 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6162 int child_scroll_layer_id
= 7;
6163 scoped_ptr
<LayerImpl
> child_scroll
=
6164 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6165 child_scroll
->SetDrawsContent(false);
6167 scroll_layer
->AddChild(child_scroll
.Pass());
6171 // We should not have scrolled |child_scroll| even though we technically "hit"
6172 // it. The reason for this is that if the scrolling the scroll would not move
6173 // any layer that is a drawn RSLL member, then we can ignore the hit.
6175 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6176 // overscrolling the inner viewport.
6177 EXPECT_EQ(InputHandler::ScrollStarted
,
6178 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6180 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6183 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6184 // This test case is very similar to the one above with one key difference:
6185 // the invisible scroller has a scroll child that is indeed draw contents.
6186 // If we attempt to initiate a gesture scroll off of the visible scroll child
6187 // we should still start the scroll child.
6188 gfx::Size
content_size(100, 100);
6189 SetupScrollAndContentsLayers(content_size
);
6191 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6193 int scroll_layer_id
= 2;
6194 LayerImpl
* scroll_layer
=
6195 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6197 int scroll_child_id
= 6;
6198 scoped_ptr
<LayerImpl
> scroll_child
=
6199 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6200 scroll_child
->SetDrawsContent(true);
6201 scroll_child
->SetBounds(content_size
);
6202 scroll_child
->SetContentBounds(content_size
);
6203 // Move the scroll child so it's not hit by our test point.
6204 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6205 scroll_child
->SetAnchorPoint(gfx::PointF());
6207 int invisible_scroll_layer_id
= 7;
6208 scoped_ptr
<LayerImpl
> invisible_scroll
=
6209 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6210 invisible_scroll
->SetDrawsContent(false);
6212 int container_id
= 8;
6213 scoped_ptr
<LayerImpl
> container
=
6214 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6216 scoped_ptr
<std::set
<LayerImpl
*> > scroll_children(new std::set
<LayerImpl
*>());
6217 scroll_children
->insert(scroll_child
.get());
6218 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6220 scroll_child
->SetScrollParent(invisible_scroll
.get());
6222 container
->AddChild(invisible_scroll
.Pass());
6223 container
->AddChild(scroll_child
.Pass());
6225 scroll_layer
->AddChild(container
.Pass());
6229 // We should not have scrolled |child_scroll| even though we technically "hit"
6230 // it. The reason for this is that if the scrolling the scroll would not move
6231 // any layer that is a drawn RSLL member, then we can ignore the hit.
6233 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6234 // overscrolling the inner viewport.
6235 EXPECT_EQ(InputHandler::ScrollStarted
,
6236 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6238 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6241 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6242 // to CompositorFrameMetadata after SwapBuffers();
6243 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6244 scoped_ptr
<SolidColorLayerImpl
> root
=
6245 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6246 root
->SetAnchorPoint(gfx::PointF());
6247 root
->SetPosition(gfx::PointF());
6248 root
->SetBounds(gfx::Size(10, 10));
6249 root
->SetContentBounds(gfx::Size(10, 10));
6250 root
->SetDrawsContent(true);
6252 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6254 FakeOutputSurface
* fake_output_surface
=
6255 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6257 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6258 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6259 EXPECT_TRUE(metadata_latency_before
.empty());
6261 ui::LatencyInfo latency_info
;
6262 latency_info
.AddLatencyNumber(
6263 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6264 scoped_ptr
<SwapPromise
> swap_promise(
6265 new LatencyInfoSwapPromise(latency_info
));
6266 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
6267 host_impl_
->SetNeedsRedraw();
6269 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6270 LayerTreeHostImpl::FrameData frame
;
6271 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6272 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6273 host_impl_
->DidDrawAllLayers(frame
);
6274 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6276 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
6277 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6278 EXPECT_EQ(1u, metadata_latency_after
.size());
6279 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
6280 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
6283 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
6285 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
6286 LayerTreeHostImpl
* layer_tree_host_impl
,
6287 int* set_needs_commit_count
,
6288 int* set_needs_redraw_count
)
6289 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
6290 set_needs_commit_count_(set_needs_commit_count
),
6291 set_needs_redraw_count_(set_needs_redraw_count
) {}
6293 virtual ~SimpleSwapPromiseMonitor() {}
6295 virtual void OnSetNeedsCommitOnMain() OVERRIDE
{
6296 (*set_needs_commit_count_
)++;
6299 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE
{
6300 (*set_needs_redraw_count_
)++;
6304 int* set_needs_commit_count_
;
6305 int* set_needs_redraw_count_
;
6308 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
6309 int set_needs_commit_count
= 0;
6310 int set_needs_redraw_count
= 0;
6313 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6314 new SimpleSwapPromiseMonitor(NULL
,
6316 &set_needs_commit_count
,
6317 &set_needs_redraw_count
));
6318 host_impl_
->SetNeedsRedraw();
6319 EXPECT_EQ(0, set_needs_commit_count
);
6320 EXPECT_EQ(1, set_needs_redraw_count
);
6323 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
6325 host_impl_
->SetNeedsRedraw();
6326 EXPECT_EQ(0, set_needs_commit_count
);
6327 EXPECT_EQ(1, set_needs_redraw_count
);
6330 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6331 new SimpleSwapPromiseMonitor(NULL
,
6333 &set_needs_commit_count
,
6334 &set_needs_redraw_count
));
6335 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
6336 EXPECT_EQ(0, set_needs_commit_count
);
6337 EXPECT_EQ(2, set_needs_redraw_count
);
6341 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6342 new SimpleSwapPromiseMonitor(NULL
,
6344 &set_needs_commit_count
,
6345 &set_needs_redraw_count
));
6346 // Empty damage rect won't signal the monitor.
6347 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
6348 EXPECT_EQ(0, set_needs_commit_count
);
6349 EXPECT_EQ(2, set_needs_redraw_count
);
6353 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
6355 virtual void SetUp() OVERRIDE
{
6356 LayerTreeSettings settings
= DefaultSettings();
6357 settings
.calculate_top_controls_position
= true;
6358 settings
.top_controls_height
= top_controls_height_
;
6359 CreateHostImpl(settings
, CreateOutputSurface());
6363 static const int top_controls_height_
;
6366 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
6368 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
6369 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6370 ->SetScrollOffset(gfx::Vector2d(0, 10));
6371 host_impl_
->Animate(base::TimeTicks());
6372 EXPECT_FALSE(did_request_redraw_
);
6375 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
6376 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6377 ->SetScrollOffset(gfx::Vector2d(0, 10));
6378 host_impl_
->DidChangeTopControlsPosition();
6379 EXPECT_TRUE(did_request_animate_
);
6380 EXPECT_TRUE(did_request_redraw_
);
6383 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
6384 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
6385 host_impl_
->SetViewportSize(gfx::Size(100, 100));
6388 EXPECT_EQ(InputHandler::ScrollStarted
,
6389 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6390 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6391 EXPECT_EQ(gfx::Vector2dF().ToString(),
6392 scroll_layer
->TotalScrollOffset().ToString());
6394 // Scroll just the top controls and verify that the scroll succeeds.
6395 const float residue
= 10;
6396 float offset
= top_controls_height_
- residue
;
6397 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6398 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->controls_top_offset());
6399 EXPECT_EQ(gfx::Vector2dF().ToString(),
6400 scroll_layer
->TotalScrollOffset().ToString());
6402 // Scroll across the boundary
6403 const float content_scroll
= 20;
6404 offset
= residue
+ content_scroll
;
6405 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6406 EXPECT_EQ(-top_controls_height_
,
6407 host_impl_
->top_controls_manager()->controls_top_offset());
6408 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
6409 scroll_layer
->TotalScrollOffset().ToString());
6411 // Now scroll back to the top of the content
6412 offset
= -content_scroll
;
6413 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6414 EXPECT_EQ(-top_controls_height_
,
6415 host_impl_
->top_controls_manager()->controls_top_offset());
6416 EXPECT_EQ(gfx::Vector2dF().ToString(),
6417 scroll_layer
->TotalScrollOffset().ToString());
6419 // And scroll the top controls completely into view
6420 offset
= -top_controls_height_
;
6421 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6422 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6423 EXPECT_EQ(gfx::Vector2dF().ToString(),
6424 scroll_layer
->TotalScrollOffset().ToString());
6426 // And attempt to scroll past the end
6427 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6428 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6429 EXPECT_EQ(gfx::Vector2dF().ToString(),
6430 scroll_layer
->TotalScrollOffset().ToString());
6432 host_impl_
->ScrollEnd();
6435 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
6437 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
6438 const gfx::Size
& outer_viewport
,
6439 const gfx::Size
& inner_viewport
) {
6440 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
6441 const int kOuterViewportClipLayerId
= 6;
6442 const int kOuterViewportScrollLayerId
= 7;
6443 const int kInnerViewportScrollLayerId
= 2;
6444 const int kInnerViewportClipLayerId
= 4;
6445 const int kPageScaleLayerId
= 5;
6447 scoped_ptr
<LayerImpl
> inner_scroll
=
6448 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
6449 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
6450 inner_scroll
->SetScrollOffset(gfx::Vector2d());
6452 scoped_ptr
<LayerImpl
> inner_clip
=
6453 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
6454 inner_clip
->SetBounds(inner_viewport
);
6456 scoped_ptr
<LayerImpl
> page_scale
=
6457 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
6459 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
6460 inner_scroll
->SetBounds(outer_viewport
);
6461 inner_scroll
->SetContentBounds(outer_viewport
);
6462 inner_scroll
->SetPosition(gfx::PointF());
6463 inner_scroll
->SetAnchorPoint(gfx::PointF());
6465 scoped_ptr
<LayerImpl
> outer_clip
=
6466 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
6467 outer_clip
->SetBounds(outer_viewport
);
6468 outer_clip
->SetIsContainerForFixedPositionLayers(true);
6470 scoped_ptr
<LayerImpl
> outer_scroll
=
6471 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
6472 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
6473 outer_scroll
->SetScrollOffset(gfx::Vector2d());
6474 outer_scroll
->SetBounds(content_size
);
6475 outer_scroll
->SetContentBounds(content_size
);
6476 outer_scroll
->SetPosition(gfx::PointF());
6477 outer_scroll
->SetAnchorPoint(gfx::PointF());
6479 scoped_ptr
<LayerImpl
> contents
=
6480 LayerImpl::Create(layer_tree_impl
, 8);
6481 contents
->SetDrawsContent(true);
6482 contents
->SetBounds(content_size
);
6483 contents
->SetContentBounds(content_size
);
6484 contents
->SetPosition(gfx::PointF());
6485 contents
->SetAnchorPoint(gfx::PointF());
6487 outer_scroll
->AddChild(contents
.Pass());
6488 outer_clip
->AddChild(outer_scroll
.Pass());
6489 inner_scroll
->AddChild(outer_clip
.Pass());
6490 page_scale
->AddChild(inner_scroll
.Pass());
6491 inner_clip
->AddChild(page_scale
.Pass());
6493 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
6494 layer_tree_impl
->SetViewportLayersFromIds(kPageScaleLayerId
,
6495 kInnerViewportScrollLayerId
, kOuterViewportScrollLayerId
);
6497 host_impl_
->active_tree()->DidBecomeActive();
6501 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
6502 gfx::Size content_size
= gfx::Size(100, 160);
6503 gfx::Size outer_viewport
= gfx::Size(50, 80);
6504 gfx::Size inner_viewport
= gfx::Size(25, 40);
6506 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
6508 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
6509 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
6512 gfx::Vector2dF inner_expected
;
6513 gfx::Vector2dF outer_expected
;
6514 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6515 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6517 // Make sure the fling goes to the outer viewport first
6518 EXPECT_EQ(InputHandler::ScrollStarted
,
6519 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6520 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6522 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
6523 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6524 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6526 host_impl_
->ScrollEnd();
6528 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6529 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6531 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
6532 EXPECT_EQ(InputHandler::ScrollStarted
,
6533 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6534 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6536 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6537 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6539 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6540 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6542 host_impl_
->ScrollEnd();
6544 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6545 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6549 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
6551 virtual void SetUp() OVERRIDE
{
6552 LayerTreeSettings settings
= DefaultSettings();
6553 settings
.max_memory_for_prepaint_percentage
= 50;
6554 CreateHostImpl(settings
, CreateOutputSurface());
6558 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
6559 // Set up a memory policy and percentages which could cause
6560 // 32-bit integer overflows.
6561 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
6563 // Verify implicit limits are calculated correctly with no overflows
6564 host_impl_
->SetMemoryPolicy(mem_policy
);
6565 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
6566 300u * 1024u * 1024u);
6567 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
6568 150u * 1024u * 1024u);
6571 TEST_F(LayerTreeHostImplTest
, UpdateTilesForMasksWithNoVisibleContent
) {
6572 gfx::Size
bounds(100000, 100);
6574 host_impl_
->CreatePendingTree();
6576 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->pending_tree(), 1);
6578 scoped_ptr
<FakePictureLayerImpl
> layer_with_mask
=
6579 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 2);
6581 layer_with_mask
->SetBounds(bounds
);
6583 scoped_ptr
<FakePictureLayerImpl
> mask
=
6584 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 3);
6586 mask
->SetIsMask(true);
6587 mask
->SetBounds(bounds
);
6589 FakePictureLayerImpl
* pending_mask_content
= mask
.get();
6590 layer_with_mask
->SetMaskLayer(mask
.PassAs
<LayerImpl
>());
6592 scoped_ptr
<FakePictureLayerImpl
> child_of_layer_with_mask
=
6593 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 4);
6595 child_of_layer_with_mask
->SetBounds(bounds
);
6596 child_of_layer_with_mask
->SetDrawsContent(true);
6598 layer_with_mask
->AddChild(child_of_layer_with_mask
.PassAs
<LayerImpl
>());
6600 root
->AddChild(layer_with_mask
.PassAs
<LayerImpl
>());
6602 host_impl_
->pending_tree()->SetRootLayer(root
.Pass());
6604 gfx::Rect r1
= pending_mask_content
->visible_rect_for_tile_priority();
6605 ASSERT_EQ(0, r1
.x());
6606 ASSERT_EQ(0, r1
.y());
6607 ASSERT_EQ(0, r1
.width());
6608 ASSERT_EQ(0, r1
.height());
6610 host_impl_
->ActivatePendingTree();
6612 host_impl_
->active_tree()->UpdateDrawProperties();
6614 ASSERT_EQ(2u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
6616 FakePictureLayerImpl
* active_mask_content
=
6617 static_cast<FakePictureLayerImpl
*>(
6618 host_impl_
->active_tree()->root_layer()->children()[0]->mask_layer());
6619 gfx::Rect r2
= active_mask_content
->visible_rect_for_tile_priority();
6621 ASSERT_TRUE(!r2
.IsEmpty());