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
->SetPosition(gfx::PointF());
186 root
->SetBounds(gfx::Size(10, 10));
187 root
->SetContentBounds(gfx::Size(10, 10));
188 root
->SetDrawsContent(true);
189 root
->draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
190 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
193 static void ExpectClearedScrollDeltasRecursive(LayerImpl
* layer
) {
194 ASSERT_EQ(layer
->ScrollDelta(), gfx::Vector2d());
195 for (size_t i
= 0; i
< layer
->children().size(); ++i
)
196 ExpectClearedScrollDeltasRecursive(layer
->children()[i
]);
199 static void ExpectContains(const ScrollAndScaleSet
& scroll_info
,
201 const gfx::Vector2d
& scroll_delta
) {
202 int times_encountered
= 0;
204 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
205 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
207 EXPECT_VECTOR_EQ(scroll_delta
, scroll_info
.scrolls
[i
].scroll_delta
);
211 ASSERT_EQ(1, times_encountered
);
214 static void ExpectNone(const ScrollAndScaleSet
& scroll_info
, int id
) {
215 int times_encountered
= 0;
217 for (size_t i
= 0; i
< scroll_info
.scrolls
.size(); ++i
) {
218 if (scroll_info
.scrolls
[i
].layer_id
!= id
)
223 ASSERT_EQ(0, times_encountered
);
226 LayerImpl
* CreateScrollAndContentsLayers(LayerTreeImpl
* layer_tree_impl
,
227 const gfx::Size
& content_size
) {
228 const int kInnerViewportScrollLayerId
= 2;
229 const int kInnerViewportClipLayerId
= 4;
230 const int kPageScaleLayerId
= 5;
231 scoped_ptr
<LayerImpl
> root
=
232 LayerImpl::Create(layer_tree_impl
, 1);
233 root
->SetBounds(content_size
);
234 root
->SetContentBounds(content_size
);
235 root
->SetPosition(gfx::PointF());
237 scoped_ptr
<LayerImpl
> scroll
=
238 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
239 LayerImpl
* scroll_layer
= scroll
.get();
240 scroll
->SetIsContainerForFixedPositionLayers(true);
241 scroll
->SetScrollOffset(gfx::Vector2d());
243 scoped_ptr
<LayerImpl
> clip
=
244 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
246 gfx::Size(content_size
.width() / 2, content_size
.height() / 2));
248 scoped_ptr
<LayerImpl
> page_scale
=
249 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
251 scroll
->SetScrollClipLayer(clip
->id());
252 scroll
->SetBounds(content_size
);
253 scroll
->SetContentBounds(content_size
);
254 scroll
->SetPosition(gfx::PointF());
255 scroll
->SetIsContainerForFixedPositionLayers(true);
257 scoped_ptr
<LayerImpl
> contents
=
258 LayerImpl::Create(layer_tree_impl
, 3);
259 contents
->SetDrawsContent(true);
260 contents
->SetBounds(content_size
);
261 contents
->SetContentBounds(content_size
);
262 contents
->SetPosition(gfx::PointF());
264 scroll
->AddChild(contents
.Pass());
265 page_scale
->AddChild(scroll
.Pass());
266 clip
->AddChild(page_scale
.Pass());
267 root
->AddChild(clip
.Pass());
269 layer_tree_impl
->SetRootLayer(root
.Pass());
270 layer_tree_impl
->SetViewportLayersFromIds(
271 kPageScaleLayerId
, kInnerViewportScrollLayerId
, Layer::INVALID_ID
);
276 LayerImpl
* SetupScrollAndContentsLayers(const gfx::Size
& content_size
) {
277 LayerImpl
* scroll_layer
= CreateScrollAndContentsLayers(
278 host_impl_
->active_tree(), content_size
);
279 host_impl_
->active_tree()->DidBecomeActive();
283 // TODO(wjmaclean) Add clip-layer pointer to parameters.
284 scoped_ptr
<LayerImpl
> CreateScrollableLayer(int id
,
285 const gfx::Size
& size
,
286 LayerImpl
* clip_layer
) {
288 DCHECK(id
!= clip_layer
->id());
289 scoped_ptr
<LayerImpl
> layer
=
290 LayerImpl::Create(host_impl_
->active_tree(), id
);
291 layer
->SetScrollClipLayer(clip_layer
->id());
292 layer
->SetDrawsContent(true);
293 layer
->SetBounds(size
);
294 layer
->SetContentBounds(size
);
295 clip_layer
->SetBounds(gfx::Size(size
.width() / 2, size
.height() / 2));
300 LayerTreeHostImpl::FrameData frame
;
301 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
302 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
303 host_impl_
->DidDrawAllLayers(frame
);
306 void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor
);
307 void pinch_zoom_pan_viewport_test(float device_scale_factor
);
308 void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor
);
309 void pinch_zoom_pan_viewport_and_scroll_boundary_test(
310 float device_scale_factor
);
312 void CheckNotifyCalledIfCanDrawChanged(bool always_draw
) {
313 // Note: It is not possible to disable the renderer once it has been set,
314 // so we do not need to test that disabling the renderer notifies us
315 // that can_draw changed.
316 EXPECT_FALSE(host_impl_
->CanDraw());
317 on_can_draw_state_changed_called_
= false;
319 // Set up the root layer, which allows us to draw.
320 SetupScrollAndContentsLayers(gfx::Size(100, 100));
321 EXPECT_TRUE(host_impl_
->CanDraw());
322 EXPECT_TRUE(on_can_draw_state_changed_called_
);
323 on_can_draw_state_changed_called_
= false;
325 // Toggle the root layer to make sure it toggles can_draw
326 host_impl_
->active_tree()->SetRootLayer(scoped_ptr
<LayerImpl
>());
327 EXPECT_FALSE(host_impl_
->CanDraw());
328 EXPECT_TRUE(on_can_draw_state_changed_called_
);
329 on_can_draw_state_changed_called_
= false;
331 SetupScrollAndContentsLayers(gfx::Size(100, 100));
332 EXPECT_TRUE(host_impl_
->CanDraw());
333 EXPECT_TRUE(on_can_draw_state_changed_called_
);
334 on_can_draw_state_changed_called_
= false;
336 // Toggle the device viewport size to make sure it toggles can_draw.
337 host_impl_
->SetViewportSize(gfx::Size());
339 EXPECT_TRUE(host_impl_
->CanDraw());
341 EXPECT_FALSE(host_impl_
->CanDraw());
343 EXPECT_TRUE(on_can_draw_state_changed_called_
);
344 on_can_draw_state_changed_called_
= false;
346 host_impl_
->SetViewportSize(gfx::Size(100, 100));
347 EXPECT_TRUE(host_impl_
->CanDraw());
348 EXPECT_TRUE(on_can_draw_state_changed_called_
);
349 on_can_draw_state_changed_called_
= false;
351 // Toggle contents textures purged without causing any evictions,
352 // and make sure that it does not change can_draw.
353 set_reduce_memory_result(false);
354 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
355 host_impl_
->memory_allocation_limit_bytes() - 1));
356 EXPECT_TRUE(host_impl_
->CanDraw());
357 EXPECT_FALSE(on_can_draw_state_changed_called_
);
358 on_can_draw_state_changed_called_
= false;
360 // Toggle contents textures purged to make sure it toggles can_draw.
361 set_reduce_memory_result(true);
362 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
363 host_impl_
->memory_allocation_limit_bytes() - 1));
365 EXPECT_TRUE(host_impl_
->CanDraw());
367 EXPECT_FALSE(host_impl_
->CanDraw());
369 EXPECT_TRUE(on_can_draw_state_changed_called_
);
370 on_can_draw_state_changed_called_
= false;
372 host_impl_
->active_tree()->ResetContentsTexturesPurged();
373 EXPECT_TRUE(host_impl_
->CanDraw());
374 EXPECT_TRUE(on_can_draw_state_changed_called_
);
375 on_can_draw_state_changed_called_
= false;
378 void SetupMouseMoveAtWithDeviceScale(float device_scale_factor
);
381 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() {
382 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
385 void DrawOneFrame() {
386 LayerTreeHostImpl::FrameData frame_data
;
387 host_impl_
->PrepareToDraw(&frame_data
);
388 host_impl_
->DidDrawAllLayers(frame_data
);
392 DebugScopedSetImplThread always_impl_thread_
;
393 DebugScopedSetMainThreadBlocked always_main_thread_blocked_
;
395 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager_
;
396 scoped_ptr
<LayerTreeHostImpl
> host_impl_
;
397 FakeRenderingStatsInstrumentation stats_instrumentation_
;
398 bool on_can_draw_state_changed_called_
;
399 bool did_notify_ready_to_activate_
;
400 bool did_request_commit_
;
401 bool did_request_redraw_
;
402 bool did_request_animate_
;
403 bool did_request_manage_tiles_
;
404 bool did_upload_visible_tile_
;
405 bool reduce_memory_result_
;
406 base::Closure scrollbar_fade_start_
;
407 base::TimeDelta requested_scrollbar_animation_delay_
;
408 size_t current_limit_bytes_
;
409 int current_priority_cutoff_value_
;
412 TEST_F(LayerTreeHostImplTest
, NotifyIfCanDrawChanged
) {
413 bool always_draw
= false;
414 CheckNotifyCalledIfCanDrawChanged(always_draw
);
417 TEST_F(LayerTreeHostImplTest
, CanDrawIncompleteFrames
) {
418 scoped_ptr
<FakeOutputSurface
> output_surface(
419 FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
420 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
422 bool always_draw
= true;
423 CheckNotifyCalledIfCanDrawChanged(always_draw
);
426 TEST_F(LayerTreeHostImplTest
, ScrollDeltaNoLayers
) {
427 ASSERT_FALSE(host_impl_
->active_tree()->root_layer());
429 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
430 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
433 TEST_F(LayerTreeHostImplTest
, ScrollDeltaTreeButNoChanges
) {
435 scoped_ptr
<LayerImpl
> root
=
436 LayerImpl::Create(host_impl_
->active_tree(), 1);
437 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 2));
438 root
->AddChild(LayerImpl::Create(host_impl_
->active_tree(), 3));
439 root
->children()[1]->AddChild(
440 LayerImpl::Create(host_impl_
->active_tree(), 4));
441 root
->children()[1]->AddChild(
442 LayerImpl::Create(host_impl_
->active_tree(), 5));
443 root
->children()[1]->children()[0]->AddChild(
444 LayerImpl::Create(host_impl_
->active_tree(), 6));
445 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
447 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
449 ExpectClearedScrollDeltasRecursive(root
);
451 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
453 scroll_info
= host_impl_
->ProcessScrollDeltas();
454 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
455 ExpectClearedScrollDeltasRecursive(root
);
457 scroll_info
= host_impl_
->ProcessScrollDeltas();
458 ASSERT_EQ(scroll_info
->scrolls
.size(), 0u);
459 ExpectClearedScrollDeltasRecursive(root
);
462 TEST_F(LayerTreeHostImplTest
, ScrollDeltaRepeatedScrolls
) {
463 gfx::Vector2d
scroll_offset(20, 30);
464 gfx::Vector2d
scroll_delta(11, -15);
466 scoped_ptr
<LayerImpl
> root_clip
=
467 LayerImpl::Create(host_impl_
->active_tree(), 2);
468 scoped_ptr
<LayerImpl
> root
=
469 LayerImpl::Create(host_impl_
->active_tree(), 1);
470 root_clip
->SetBounds(gfx::Size(10, 10));
471 LayerImpl
* root_layer
= root
.get();
472 root_clip
->AddChild(root
.Pass());
473 root_layer
->SetBounds(gfx::Size(110, 110));
474 root_layer
->SetScrollClipLayer(root_clip
->id());
475 root_layer
->SetScrollOffset(scroll_offset
);
476 root_layer
->ScrollBy(scroll_delta
);
477 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
479 LayerImpl
* root
= host_impl_
->active_tree()->root_layer()->children()[0];
481 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
483 scroll_info
= host_impl_
->ProcessScrollDeltas();
484 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
485 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
);
486 ExpectContains(*scroll_info
, root
->id(), scroll_delta
);
488 gfx::Vector2d
scroll_delta2(-5, 27);
489 root
->ScrollBy(scroll_delta2
);
490 scroll_info
= host_impl_
->ProcessScrollDeltas();
491 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
492 EXPECT_VECTOR_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
493 ExpectContains(*scroll_info
, root
->id(), scroll_delta
+ scroll_delta2
);
495 root
->ScrollBy(gfx::Vector2d());
496 scroll_info
= host_impl_
->ProcessScrollDeltas();
497 EXPECT_EQ(root
->sent_scroll_delta(), scroll_delta
+ scroll_delta2
);
500 TEST_F(LayerTreeHostImplTest
, ScrollRootCallsCommitAndRedraw
) {
501 SetupScrollAndContentsLayers(gfx::Size(100, 100));
502 host_impl_
->SetViewportSize(gfx::Size(50, 50));
505 EXPECT_EQ(InputHandler::ScrollStarted
,
506 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
507 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
508 InputHandler::Wheel
));
509 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
510 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
511 InputHandler::Wheel
));
512 host_impl_
->ScrollEnd();
513 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(),
514 InputHandler::Wheel
));
515 EXPECT_TRUE(did_request_redraw_
);
516 EXPECT_TRUE(did_request_commit_
);
519 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRootLayer
) {
520 // We should not crash when trying to scroll an empty layer tree.
521 EXPECT_EQ(InputHandler::ScrollIgnored
,
522 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
525 TEST_F(LayerTreeHostImplTest
, ScrollWithoutRenderer
) {
526 scoped_ptr
<TestWebGraphicsContext3D
> context_owned
=
527 TestWebGraphicsContext3D::Create();
528 context_owned
->set_context_lost(true);
530 scoped_ptr
<FakeOutputSurface
> output_surface(FakeOutputSurface::Create3d(
531 context_owned
.Pass()));
533 // Initialization will fail.
534 EXPECT_FALSE(CreateHostImpl(DefaultSettings(),
535 output_surface
.PassAs
<OutputSurface
>()));
537 SetupScrollAndContentsLayers(gfx::Size(100, 100));
539 // We should not crash when trying to scroll after the renderer initialization
541 EXPECT_EQ(InputHandler::ScrollIgnored
,
542 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
545 TEST_F(LayerTreeHostImplTest
, ReplaceTreeWhileScrolling
) {
546 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
547 host_impl_
->SetViewportSize(gfx::Size(50, 50));
550 // We should not crash if the tree is replaced while we are scrolling.
551 EXPECT_EQ(InputHandler::ScrollStarted
,
552 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
553 host_impl_
->active_tree()->DetachLayerTree();
555 scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
557 // We should still be scrolling, because the scrolled layer also exists in the
559 gfx::Vector2d
scroll_delta(0, 10);
560 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
561 host_impl_
->ScrollEnd();
562 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
563 ExpectContains(*scroll_info
, scroll_layer
->id(), scroll_delta
);
566 TEST_F(LayerTreeHostImplTest
, ClearRootRenderSurfaceAndScroll
) {
567 SetupScrollAndContentsLayers(gfx::Size(100, 100));
568 host_impl_
->SetViewportSize(gfx::Size(50, 50));
571 // We should be able to scroll even if the root layer loses its render surface
572 // after the most recent render.
573 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
574 host_impl_
->active_tree()->set_needs_update_draw_properties();
576 EXPECT_EQ(InputHandler::ScrollStarted
,
577 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
580 TEST_F(LayerTreeHostImplTest
, WheelEventHandlers
) {
581 SetupScrollAndContentsLayers(gfx::Size(100, 100));
582 host_impl_
->SetViewportSize(gfx::Size(50, 50));
584 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
586 root
->SetHaveWheelEventHandlers(true);
588 // With registered event handlers, wheel scrolls have to go to the main
590 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
591 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
593 // But gesture scrolls can still be handled.
594 EXPECT_EQ(InputHandler::ScrollStarted
,
595 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
598 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchscreen
) {
599 SetupScrollAndContentsLayers(gfx::Size(100, 100));
600 host_impl_
->SetViewportSize(gfx::Size(50, 50));
603 // Ignore the fling since no layer is being scrolled
604 EXPECT_EQ(InputHandler::ScrollIgnored
,
605 host_impl_
->FlingScrollBegin());
607 // Start scrolling a layer
608 EXPECT_EQ(InputHandler::ScrollStarted
,
609 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
611 // Now the fling should go ahead since we've started scrolling a layer
612 EXPECT_EQ(InputHandler::ScrollStarted
,
613 host_impl_
->FlingScrollBegin());
616 TEST_F(LayerTreeHostImplTest
, FlingOnlyWhenScrollingTouchpad
) {
617 SetupScrollAndContentsLayers(gfx::Size(100, 100));
618 host_impl_
->SetViewportSize(gfx::Size(50, 50));
621 // Ignore the fling since no layer is being scrolled
622 EXPECT_EQ(InputHandler::ScrollIgnored
,
623 host_impl_
->FlingScrollBegin());
625 // Start scrolling a layer
626 EXPECT_EQ(InputHandler::ScrollStarted
,
627 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
629 // Now the fling should go ahead since we've started scrolling a layer
630 EXPECT_EQ(InputHandler::ScrollStarted
,
631 host_impl_
->FlingScrollBegin());
634 TEST_F(LayerTreeHostImplTest
, NoFlingWhenScrollingOnMain
) {
635 SetupScrollAndContentsLayers(gfx::Size(100, 100));
636 host_impl_
->SetViewportSize(gfx::Size(50, 50));
638 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
640 root
->SetShouldScrollOnMainThread(true);
642 // Start scrolling a layer
643 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
644 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
646 // The fling should be ignored since there's no layer being scrolled impl-side
647 EXPECT_EQ(InputHandler::ScrollIgnored
,
648 host_impl_
->FlingScrollBegin());
651 TEST_F(LayerTreeHostImplTest
, ShouldScrollOnMainThread
) {
652 SetupScrollAndContentsLayers(gfx::Size(100, 100));
653 host_impl_
->SetViewportSize(gfx::Size(50, 50));
655 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
657 root
->SetShouldScrollOnMainThread(true);
659 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
660 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
661 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
662 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
665 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionBasic
) {
666 SetupScrollAndContentsLayers(gfx::Size(200, 200));
667 host_impl_
->SetViewportSize(gfx::Size(100, 100));
669 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
670 root
->SetContentsScale(2.f
, 2.f
);
671 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
675 // All scroll types inside the non-fast scrollable region should fail.
676 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
677 host_impl_
->ScrollBegin(gfx::Point(25, 25),
678 InputHandler::Wheel
));
679 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
680 InputHandler::Wheel
));
681 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
682 host_impl_
->ScrollBegin(gfx::Point(25, 25),
683 InputHandler::Gesture
));
684 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
685 InputHandler::Gesture
));
687 // All scroll types outside this region should succeed.
688 EXPECT_EQ(InputHandler::ScrollStarted
,
689 host_impl_
->ScrollBegin(gfx::Point(75, 75),
690 InputHandler::Wheel
));
691 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
692 InputHandler::Gesture
));
693 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
694 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
695 InputHandler::Gesture
));
696 host_impl_
->ScrollEnd();
697 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
698 InputHandler::Gesture
));
699 EXPECT_EQ(InputHandler::ScrollStarted
,
700 host_impl_
->ScrollBegin(gfx::Point(75, 75),
701 InputHandler::Gesture
));
702 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
703 InputHandler::Gesture
));
704 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
705 host_impl_
->ScrollEnd();
706 EXPECT_FALSE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
707 InputHandler::Gesture
));
710 TEST_F(LayerTreeHostImplTest
, NonFastScrollableRegionWithOffset
) {
711 SetupScrollAndContentsLayers(gfx::Size(200, 200));
712 host_impl_
->SetViewportSize(gfx::Size(100, 100));
714 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
715 root
->SetContentsScale(2.f
, 2.f
);
716 root
->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
717 root
->SetPosition(gfx::PointF(-25.f
, 0.f
));
721 // This point would fall into the non-fast scrollable region except that we've
722 // moved the layer down by 25 pixels.
723 EXPECT_EQ(InputHandler::ScrollStarted
,
724 host_impl_
->ScrollBegin(gfx::Point(40, 10),
725 InputHandler::Wheel
));
726 EXPECT_TRUE(host_impl_
->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
727 InputHandler::Wheel
));
728 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
729 host_impl_
->ScrollEnd();
731 // This point is still inside the non-fast region.
732 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
733 host_impl_
->ScrollBegin(gfx::Point(10, 10),
734 InputHandler::Wheel
));
737 TEST_F(LayerTreeHostImplTest
, ScrollHandlerNotPresent
) {
738 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
739 EXPECT_FALSE(scroll_layer
->have_scroll_event_handlers());
740 host_impl_
->SetViewportSize(gfx::Size(50, 50));
743 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
744 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
745 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
746 host_impl_
->ScrollEnd();
747 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
750 TEST_F(LayerTreeHostImplTest
, ScrollHandlerPresent
) {
751 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
752 scroll_layer
->SetHaveScrollEventHandlers(true);
753 host_impl_
->SetViewportSize(gfx::Size(50, 50));
756 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
757 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
758 EXPECT_TRUE(host_impl_
->scroll_affects_scroll_handler());
759 host_impl_
->ScrollEnd();
760 EXPECT_FALSE(host_impl_
->scroll_affects_scroll_handler());
763 TEST_F(LayerTreeHostImplTest
, ScrollByReturnsCorrectValue
) {
764 SetupScrollAndContentsLayers(gfx::Size(200, 200));
765 host_impl_
->SetViewportSize(gfx::Size(100, 100));
769 EXPECT_EQ(InputHandler::ScrollStarted
,
770 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
772 // Trying to scroll to the left/top will not succeed.
773 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
774 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
775 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
777 // Scrolling to the right/bottom will succeed.
778 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)));
779 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)));
780 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)));
782 // Scrolling to left/top will now succeed.
783 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
784 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)));
785 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)));
787 // Scrolling diagonally against an edge will succeed.
788 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)));
789 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)));
790 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)));
792 // Trying to scroll more than the available space will also succeed.
793 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)));
796 TEST_F(LayerTreeHostImplTest
, ScrollVerticallyByPageReturnsCorrectValue
) {
797 SetupScrollAndContentsLayers(gfx::Size(200, 2000));
798 host_impl_
->SetViewportSize(gfx::Size(100, 1000));
802 EXPECT_EQ(InputHandler::ScrollStarted
,
803 host_impl_
->ScrollBegin(gfx::Point(),
804 InputHandler::Wheel
));
806 // Trying to scroll without a vertical scrollbar will fail.
807 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
808 gfx::Point(), SCROLL_FORWARD
));
809 EXPECT_FALSE(host_impl_
->ScrollVerticallyByPage(
810 gfx::Point(), SCROLL_BACKWARD
));
812 scoped_ptr
<PaintedScrollbarLayerImpl
> vertical_scrollbar(
813 PaintedScrollbarLayerImpl::Create(
814 host_impl_
->active_tree(),
817 vertical_scrollbar
->SetBounds(gfx::Size(15, 1000));
818 host_impl_
->InnerViewportScrollLayer()->AddScrollbar(
819 vertical_scrollbar
.get());
821 // Trying to scroll with a vertical scrollbar will succeed.
822 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
823 gfx::Point(), SCROLL_FORWARD
));
824 EXPECT_FLOAT_EQ(875.f
,
825 host_impl_
->InnerViewportScrollLayer()->ScrollDelta().y());
826 EXPECT_TRUE(host_impl_
->ScrollVerticallyByPage(
827 gfx::Point(), SCROLL_BACKWARD
));
830 // The user-scrollability breaks for zoomed-in pages. So disable this.
831 // http://crbug.com/322223
832 TEST_F(LayerTreeHostImplTest
, DISABLED_ScrollWithUserUnscrollableLayers
) {
833 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(200, 200));
834 host_impl_
->SetViewportSize(gfx::Size(100, 100));
836 gfx::Size
overflow_size(400, 400);
837 ASSERT_EQ(1u, scroll_layer
->children().size());
838 LayerImpl
* overflow
= scroll_layer
->children()[0];
839 overflow
->SetBounds(overflow_size
);
840 overflow
->SetContentBounds(overflow_size
);
841 overflow
->SetScrollClipLayer(scroll_layer
->parent()->id());
842 overflow
->SetScrollOffset(gfx::Vector2d());
843 overflow
->SetPosition(gfx::PointF());
846 gfx::Point
scroll_position(10, 10);
848 EXPECT_EQ(InputHandler::ScrollStarted
,
849 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
850 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
851 EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow
->TotalScrollOffset());
853 gfx::Vector2dF
scroll_delta(10, 10);
854 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
855 host_impl_
->ScrollEnd();
856 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
857 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
859 overflow
->set_user_scrollable_horizontal(false);
861 EXPECT_EQ(InputHandler::ScrollStarted
,
862 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
863 EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer
->TotalScrollOffset());
864 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow
->TotalScrollOffset());
866 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
867 host_impl_
->ScrollEnd();
868 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
869 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
871 overflow
->set_user_scrollable_vertical(false);
873 EXPECT_EQ(InputHandler::ScrollStarted
,
874 host_impl_
->ScrollBegin(scroll_position
, InputHandler::Wheel
));
875 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer
->TotalScrollOffset());
876 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
878 host_impl_
->ScrollBy(scroll_position
, scroll_delta
);
879 host_impl_
->ScrollEnd();
880 EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer
->TotalScrollOffset());
881 EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow
->TotalScrollOffset());
884 TEST_F(LayerTreeHostImplTest
,
885 ClearRootRenderSurfaceAndHitTestTouchHandlerRegion
) {
886 SetupScrollAndContentsLayers(gfx::Size(100, 100));
887 host_impl_
->SetViewportSize(gfx::Size(50, 50));
890 // We should be able to hit test for touch event handlers even if the root
891 // layer loses its render surface after the most recent render.
892 host_impl_
->active_tree()->root_layer()->ClearRenderSurface();
893 host_impl_
->active_tree()->set_needs_update_draw_properties();
895 EXPECT_EQ(host_impl_
->HaveTouchEventHandlersAt(gfx::Point()), false);
898 TEST_F(LayerTreeHostImplTest
, ImplPinchZoom
) {
899 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
900 host_impl_
->SetViewportSize(gfx::Size(50, 50));
903 EXPECT_EQ(scroll_layer
, host_impl_
->InnerViewportScrollLayer());
904 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
905 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
907 float min_page_scale
= 1.f
, max_page_scale
= 4.f
;
908 float page_scale_factor
= 1.f
;
910 // The impl-based pinch zoom should adjust the max scroll position.
912 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
913 page_scale_factor
, min_page_scale
, max_page_scale
);
914 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
915 scroll_layer
->SetScrollDelta(gfx::Vector2d());
917 float page_scale_delta
= 2.f
;
918 gfx::Vector2dF
expected_container_size_delta(
919 container_layer
->bounds().width(), container_layer
->bounds().height());
920 expected_container_size_delta
.Scale((1.f
- page_scale_delta
) /
921 (page_scale_factor
* page_scale_delta
));
923 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
924 host_impl_
->PinchGestureBegin();
925 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
926 // While the gesture is still active, the scroll layer should have a
927 // container size delta = container->bounds() * ((1.f -
928 // page_scale_delta)/())
929 EXPECT_EQ(expected_container_size_delta
,
930 scroll_layer
->FixedContainerSizeDelta());
931 host_impl_
->PinchGestureEnd();
932 host_impl_
->ScrollEnd();
933 EXPECT_FALSE(did_request_animate_
);
934 EXPECT_TRUE(did_request_redraw_
);
935 EXPECT_TRUE(did_request_commit_
);
936 EXPECT_EQ(gfx::Size(50, 50), container_layer
->bounds());
938 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
939 host_impl_
->ProcessScrollDeltas();
940 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
942 EXPECT_EQ(gfx::Vector2d(75, 75).ToString(),
943 scroll_layer
->MaxScrollOffset().ToString());
946 // Scrolling after a pinch gesture should always be in local space. The
947 // scroll deltas do not have the page scale factor applied.
949 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
950 page_scale_factor
, min_page_scale
, max_page_scale
);
951 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
952 scroll_layer
->SetScrollDelta(gfx::Vector2d());
954 float page_scale_delta
= 2.f
;
955 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
956 host_impl_
->PinchGestureBegin();
957 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
958 host_impl_
->PinchGestureEnd();
959 host_impl_
->ScrollEnd();
961 gfx::Vector2d
scroll_delta(0, 10);
962 EXPECT_EQ(InputHandler::ScrollStarted
,
963 host_impl_
->ScrollBegin(gfx::Point(5, 5),
964 InputHandler::Wheel
));
965 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
966 host_impl_
->ScrollEnd();
968 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
969 host_impl_
->ProcessScrollDeltas();
970 ExpectContains(*scroll_info
.get(),
976 TEST_F(LayerTreeHostImplTest
, MasksToBoundsDoesntClobberInnerContainerSize
) {
977 SetupScrollAndContentsLayers(gfx::Size(100, 100));
978 host_impl_
->SetViewportSize(gfx::Size(50, 50));
981 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
982 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
983 DCHECK(scroll_layer
);
985 float min_page_scale
= 1.f
;
986 float max_page_scale
= 4.f
;
987 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
991 // If the container's masks_to_bounds is false, the viewport size should
992 // overwrite the inner viewport container layer's size.
994 EXPECT_EQ(gfx::Size(50, 50),
995 container_layer
->bounds());
996 container_layer
->SetMasksToBounds(false);
998 container_layer
->SetBounds(gfx::Size(30, 25));
999 EXPECT_EQ(gfx::Size(30, 25),
1000 container_layer
->bounds());
1002 // This should cause a reset of the inner viewport container layer's bounds.
1003 host_impl_
->DidChangeTopControlsPosition();
1005 EXPECT_EQ(gfx::Size(50, 50),
1006 container_layer
->bounds());
1009 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1010 container_layer
->SetBounds(gfx::Size(50, 50));
1012 // If the container's masks_to_bounds is true, the viewport size should
1013 // *NOT* overwrite the inner viewport container layer's size.
1015 EXPECT_EQ(gfx::Size(50, 50),
1016 container_layer
->bounds());
1017 container_layer
->SetMasksToBounds(true);
1019 container_layer
->SetBounds(gfx::Size(30, 25));
1020 EXPECT_EQ(gfx::Size(30, 25),
1021 container_layer
->bounds());
1023 // This should cause a reset of the inner viewport container layer's bounds.
1024 host_impl_
->DidChangeTopControlsPosition();
1026 EXPECT_EQ(gfx::Size(30, 25),
1027 container_layer
->bounds());
1031 TEST_F(LayerTreeHostImplTest
, PinchGesture
) {
1032 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1033 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1036 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1037 DCHECK(scroll_layer
);
1039 float min_page_scale
= 1.f
;
1040 float max_page_scale
= 4.f
;
1042 // Basic pinch zoom in gesture
1044 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1047 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1049 float page_scale_delta
= 2.f
;
1050 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1051 host_impl_
->PinchGestureBegin();
1052 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1053 host_impl_
->PinchGestureEnd();
1054 host_impl_
->ScrollEnd();
1055 EXPECT_FALSE(did_request_animate_
);
1056 EXPECT_TRUE(did_request_redraw_
);
1057 EXPECT_TRUE(did_request_commit_
);
1059 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1060 host_impl_
->ProcessScrollDeltas();
1061 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1066 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1069 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1070 float page_scale_delta
= 10.f
;
1072 host_impl_
->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture
);
1073 host_impl_
->PinchGestureBegin();
1074 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(50, 50));
1075 host_impl_
->PinchGestureEnd();
1076 host_impl_
->ScrollEnd();
1078 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1079 host_impl_
->ProcessScrollDeltas();
1080 EXPECT_EQ(scroll_info
->page_scale_delta
, max_page_scale
);
1083 // Zoom-out clamping
1085 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1088 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1089 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1091 float page_scale_delta
= 0.1f
;
1092 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1093 host_impl_
->PinchGestureBegin();
1094 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point());
1095 host_impl_
->PinchGestureEnd();
1096 host_impl_
->ScrollEnd();
1098 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1099 host_impl_
->ProcessScrollDeltas();
1100 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1102 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1105 // Two-finger panning should not happen based on pinch events only
1107 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1110 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1111 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1113 float page_scale_delta
= 1.f
;
1114 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1115 host_impl_
->PinchGestureBegin();
1116 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1117 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1118 host_impl_
->PinchGestureEnd();
1119 host_impl_
->ScrollEnd();
1121 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1122 host_impl_
->ProcessScrollDeltas();
1123 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1124 EXPECT_TRUE(scroll_info
->scrolls
.empty());
1127 // Two-finger panning should work with interleaved scroll events
1129 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1132 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1133 scroll_layer
->SetScrollOffset(gfx::Vector2d(20, 20));
1135 float page_scale_delta
= 1.f
;
1136 host_impl_
->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture
);
1137 host_impl_
->PinchGestureBegin();
1138 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(10, 10));
1139 host_impl_
->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1140 host_impl_
->PinchGestureUpdate(page_scale_delta
, gfx::Point(20, 20));
1141 host_impl_
->PinchGestureEnd();
1142 host_impl_
->ScrollEnd();
1144 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1145 host_impl_
->ProcessScrollDeltas();
1146 EXPECT_EQ(scroll_info
->page_scale_delta
, page_scale_delta
);
1147 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-10, -10));
1150 // Two-finger panning should work when starting fully zoomed out.
1152 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(0.5f
,
1155 scroll_layer
->SetScrollDelta(gfx::Vector2d());
1156 scroll_layer
->SetScrollOffset(gfx::Vector2d(0, 0));
1158 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture
);
1159 host_impl_
->PinchGestureBegin();
1160 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point(0, 0));
1161 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(0, 0));
1162 host_impl_
->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1163 host_impl_
->PinchGestureUpdate(1.f
, gfx::Point(10, 10));
1164 host_impl_
->PinchGestureEnd();
1165 host_impl_
->ScrollEnd();
1167 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1168 host_impl_
->ProcessScrollDeltas();
1169 EXPECT_EQ(scroll_info
->page_scale_delta
, 2.f
);
1170 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(20, 20));
1174 TEST_F(LayerTreeHostImplTest
, PageScaleAnimation
) {
1175 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1176 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1179 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1180 DCHECK(scroll_layer
);
1182 float min_page_scale
= 0.5f
;
1183 float max_page_scale
= 4.f
;
1184 base::TimeTicks start_time
= base::TimeTicks() +
1185 base::TimeDelta::FromSeconds(1);
1186 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1187 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1188 base::TimeTicks end_time
= start_time
+ duration
;
1190 // Non-anchor zoom-in
1192 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1195 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1197 did_request_redraw_
= false;
1198 did_request_animate_
= false;
1199 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f
, duration
);
1200 EXPECT_FALSE(did_request_redraw_
);
1201 EXPECT_TRUE(did_request_animate_
);
1203 did_request_redraw_
= false;
1204 did_request_animate_
= false;
1205 host_impl_
->Animate(start_time
);
1206 EXPECT_TRUE(did_request_redraw_
);
1207 EXPECT_TRUE(did_request_animate_
);
1209 did_request_redraw_
= false;
1210 did_request_animate_
= false;
1211 host_impl_
->Animate(halfway_through_animation
);
1212 EXPECT_TRUE(did_request_redraw_
);
1213 EXPECT_TRUE(did_request_animate_
);
1215 did_request_redraw_
= false;
1216 did_request_animate_
= false;
1217 did_request_commit_
= false;
1218 host_impl_
->Animate(end_time
);
1219 EXPECT_TRUE(did_request_commit_
);
1220 EXPECT_FALSE(did_request_animate_
);
1222 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1223 host_impl_
->ProcessScrollDeltas();
1224 EXPECT_EQ(scroll_info
->page_scale_delta
, 2);
1225 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1230 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1233 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1235 did_request_redraw_
= false;
1236 did_request_animate_
= false;
1237 host_impl_
->StartPageScaleAnimation(
1238 gfx::Vector2d(25, 25), true, min_page_scale
, duration
);
1239 EXPECT_FALSE(did_request_redraw_
);
1240 EXPECT_TRUE(did_request_animate_
);
1242 did_request_redraw_
= false;
1243 did_request_animate_
= false;
1244 host_impl_
->Animate(start_time
);
1245 EXPECT_TRUE(did_request_redraw_
);
1246 EXPECT_TRUE(did_request_animate_
);
1248 did_request_redraw_
= false;
1249 did_request_commit_
= false;
1250 did_request_animate_
= false;
1251 host_impl_
->Animate(end_time
);
1252 EXPECT_TRUE(did_request_redraw_
);
1253 EXPECT_FALSE(did_request_animate_
);
1254 EXPECT_TRUE(did_request_commit_
);
1256 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1257 host_impl_
->ProcessScrollDeltas();
1258 EXPECT_EQ(scroll_info
->page_scale_delta
, min_page_scale
);
1259 // Pushed to (0,0) via clamping against contents layer size.
1260 ExpectContains(*scroll_info
, scroll_layer
->id(), gfx::Vector2d(-50, -50));
1264 TEST_F(LayerTreeHostImplTest
, PageScaleAnimationNoOp
) {
1265 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1266 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1269 LayerImpl
* scroll_layer
= host_impl_
->InnerViewportScrollLayer();
1270 DCHECK(scroll_layer
);
1272 float min_page_scale
= 0.5f
;
1273 float max_page_scale
= 4.f
;
1274 base::TimeTicks start_time
= base::TimeTicks() +
1275 base::TimeDelta::FromSeconds(1);
1276 base::TimeDelta duration
= base::TimeDelta::FromMilliseconds(100);
1277 base::TimeTicks halfway_through_animation
= start_time
+ duration
/ 2;
1278 base::TimeTicks end_time
= start_time
+ duration
;
1280 // Anchor zoom with unchanged page scale should not change scroll or scale.
1282 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
,
1285 scroll_layer
->SetScrollOffset(gfx::Vector2d(50, 50));
1287 host_impl_
->StartPageScaleAnimation(gfx::Vector2d(), true, 1.f
, duration
);
1288 host_impl_
->Animate(start_time
);
1289 host_impl_
->Animate(halfway_through_animation
);
1290 EXPECT_TRUE(did_request_redraw_
);
1291 host_impl_
->Animate(end_time
);
1292 EXPECT_TRUE(did_request_commit_
);
1294 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
1295 host_impl_
->ProcessScrollDeltas();
1296 EXPECT_EQ(scroll_info
->page_scale_delta
, 1);
1297 ExpectNone(*scroll_info
, scroll_layer
->id());
1301 class LayerTreeHostImplOverridePhysicalTime
: public LayerTreeHostImpl
{
1303 LayerTreeHostImplOverridePhysicalTime(
1304 const LayerTreeSettings
& settings
,
1305 LayerTreeHostImplClient
* client
,
1307 SharedBitmapManager
* manager
,
1308 RenderingStatsInstrumentation
* rendering_stats_instrumentation
)
1309 : LayerTreeHostImpl(settings
,
1312 rendering_stats_instrumentation
,
1316 virtual base::TimeTicks
CurrentFrameTimeTicks() OVERRIDE
{
1317 return fake_current_physical_time_
;
1320 void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now
) {
1321 fake_current_physical_time_
= fake_now
;
1325 base::TimeTicks fake_current_physical_time_
;
1328 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST() \
1329 gfx::Size viewport_size(10, 10); \
1330 gfx::Size content_size(100, 100); \
1332 LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = \
1333 new LayerTreeHostImplOverridePhysicalTime(settings, \
1336 shared_bitmap_manager_.get(), \
1337 &stats_instrumentation_); \
1338 host_impl_ = make_scoped_ptr(host_impl_override_time); \
1339 host_impl_->InitializeRenderer(CreateOutputSurface()); \
1340 host_impl_->SetViewportSize(viewport_size); \
1342 scoped_ptr<LayerImpl> root = \
1343 LayerImpl::Create(host_impl_->active_tree(), 1); \
1344 root->SetBounds(viewport_size); \
1346 scoped_ptr<LayerImpl> scroll = \
1347 LayerImpl::Create(host_impl_->active_tree(), 2); \
1348 scroll->SetScrollClipLayer(root->id()); \
1349 scroll->SetScrollOffset(gfx::Vector2d()); \
1350 root->SetBounds(viewport_size); \
1351 scroll->SetBounds(content_size); \
1352 scroll->SetContentBounds(content_size); \
1353 scroll->SetIsContainerForFixedPositionLayers(true); \
1355 scoped_ptr<LayerImpl> contents = \
1356 LayerImpl::Create(host_impl_->active_tree(), 3); \
1357 contents->SetDrawsContent(true); \
1358 contents->SetBounds(content_size); \
1359 contents->SetContentBounds(content_size); \
1361 scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar = \
1362 SolidColorScrollbarLayerImpl::Create( \
1363 host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true); \
1364 EXPECT_FLOAT_EQ(0.f, scrollbar->opacity()); \
1365 scrollbar->SetScrollLayerById(2); \
1366 scrollbar->SetClipLayerById(1); \
1368 scroll->AddChild(contents.Pass()); \
1369 root->AddChild(scroll.Pass()); \
1370 root->AddChild(scrollbar.PassAs<LayerImpl>()); \
1372 host_impl_->active_tree()->SetRootLayer(root.Pass()); \
1373 host_impl_->active_tree()->SetViewportLayersFromIds( \
1374 1, 2, Layer::INVALID_ID); \
1375 host_impl_->active_tree()->DidBecomeActive(); \
1378 TEST_F(LayerTreeHostImplTest
, ScrollbarLinearFadeScheduling
) {
1379 LayerTreeSettings settings
;
1380 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1381 settings
.scrollbar_fade_delay_ms
= 20;
1382 settings
.scrollbar_fade_duration_ms
= 20;
1384 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1386 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1388 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1389 EXPECT_FALSE(did_request_redraw_
);
1391 // If no scroll happened during a scroll gesture, it should have no effect.
1392 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1393 host_impl_
->ScrollEnd();
1394 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1395 EXPECT_FALSE(did_request_redraw_
);
1396 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1398 // After a scroll, a fade animation should be scheduled about 20ms from now.
1399 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1400 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1401 host_impl_
->ScrollEnd();
1402 did_request_redraw_
= false;
1403 did_request_animate_
= false;
1404 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1405 requested_scrollbar_animation_delay_
);
1406 EXPECT_FALSE(did_request_redraw_
);
1407 EXPECT_FALSE(did_request_animate_
);
1408 requested_scrollbar_animation_delay_
= base::TimeDelta();
1409 scrollbar_fade_start_
.Run();
1410 host_impl_
->Animate(fake_now
);
1412 // After the fade begins, we should start getting redraws instead of a
1413 // scheduled animation.
1414 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1415 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1416 EXPECT_TRUE(did_request_animate_
);
1417 did_request_animate_
= false;
1419 // Setting the scroll offset outside a scroll should also cause the scrollbar
1420 // to appear and to schedule a fade.
1421 host_impl_
->InnerViewportScrollLayer()->SetScrollOffset(gfx::Vector2d(5, 5));
1422 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1423 requested_scrollbar_animation_delay_
);
1424 EXPECT_FALSE(did_request_redraw_
);
1425 EXPECT_FALSE(did_request_animate_
);
1426 requested_scrollbar_animation_delay_
= base::TimeDelta();
1429 TEST_F(LayerTreeHostImplTest
, ScrollbarFadePinchZoomScrollbars
) {
1430 LayerTreeSettings settings
;
1431 settings
.scrollbar_animator
= LayerTreeSettings::LinearFade
;
1432 settings
.scrollbar_fade_delay_ms
= 20;
1433 settings
.scrollbar_fade_duration_ms
= 20;
1434 settings
.use_pinch_zoom_scrollbars
= true;
1436 SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1438 base::TimeTicks fake_now
= gfx::FrameTime::Now();
1440 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, 4.f
);
1442 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1443 EXPECT_FALSE(did_request_animate_
);
1445 // If no scroll happened during a scroll gesture, it should have no effect.
1446 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1447 host_impl_
->ScrollEnd();
1448 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1449 EXPECT_FALSE(did_request_animate_
);
1450 EXPECT_TRUE(scrollbar_fade_start_
.Equals(base::Closure()));
1452 // After a scroll, no fade animation should be scheduled.
1453 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1454 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1455 host_impl_
->ScrollEnd();
1456 did_request_redraw_
= false;
1457 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1458 EXPECT_FALSE(did_request_animate_
);
1459 requested_scrollbar_animation_delay_
= base::TimeDelta();
1461 // We should not see any draw requests.
1462 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1463 EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_
);
1464 EXPECT_FALSE(did_request_animate_
);
1466 // Make page scale > min so that subsequent scrolls will trigger fades.
1467 host_impl_
->active_tree()->SetPageScaleDelta(1.1f
);
1469 // After a scroll, a fade animation should be scheduled about 20ms from now.
1470 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
);
1471 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1472 host_impl_
->ScrollEnd();
1473 did_request_redraw_
= false;
1474 EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1475 requested_scrollbar_animation_delay_
);
1476 EXPECT_FALSE(did_request_animate_
);
1477 requested_scrollbar_animation_delay_
= base::TimeDelta();
1478 scrollbar_fade_start_
.Run();
1480 // After the fade begins, we should start getting redraws instead of a
1481 // scheduled animation.
1482 fake_now
+= base::TimeDelta::FromMilliseconds(25);
1483 host_impl_
->Animate(fake_now
);
1484 EXPECT_TRUE(did_request_animate_
);
1487 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1488 float device_scale_factor
) {
1489 LayerTreeSettings settings
;
1490 settings
.scrollbar_fade_delay_ms
= 500;
1491 settings
.scrollbar_fade_duration_ms
= 300;
1492 settings
.scrollbar_animator
= LayerTreeSettings::Thinning
;
1494 gfx::Size
viewport_size(300, 200);
1495 gfx::Size device_viewport_size
= gfx::ToFlooredSize(
1496 gfx::ScaleSize(viewport_size
, device_scale_factor
));
1497 gfx::Size
content_size(1000, 1000);
1499 CreateHostImpl(settings
, CreateOutputSurface());
1500 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
1501 host_impl_
->SetViewportSize(device_viewport_size
);
1503 scoped_ptr
<LayerImpl
> root
=
1504 LayerImpl::Create(host_impl_
->active_tree(), 1);
1505 root
->SetBounds(viewport_size
);
1507 scoped_ptr
<LayerImpl
> scroll
=
1508 LayerImpl::Create(host_impl_
->active_tree(), 2);
1509 scroll
->SetScrollClipLayer(root
->id());
1510 scroll
->SetScrollOffset(gfx::Vector2d());
1511 scroll
->SetBounds(content_size
);
1512 scroll
->SetContentBounds(content_size
);
1513 scroll
->SetIsContainerForFixedPositionLayers(true);
1515 scoped_ptr
<LayerImpl
> contents
=
1516 LayerImpl::Create(host_impl_
->active_tree(), 3);
1517 contents
->SetDrawsContent(true);
1518 contents
->SetBounds(content_size
);
1519 contents
->SetContentBounds(content_size
);
1521 // The scrollbar is on the right side.
1522 scoped_ptr
<PaintedScrollbarLayerImpl
> scrollbar
=
1523 PaintedScrollbarLayerImpl::Create(host_impl_
->active_tree(), 5, VERTICAL
);
1524 scrollbar
->SetDrawsContent(true);
1525 scrollbar
->SetBounds(gfx::Size(15, viewport_size
.height()));
1526 scrollbar
->SetContentBounds(gfx::Size(15, viewport_size
.height()));
1527 scrollbar
->SetPosition(gfx::Point(285, 0));
1528 scrollbar
->SetClipLayerById(1);
1529 scrollbar
->SetScrollLayerById(2);
1531 scroll
->AddChild(contents
.Pass());
1532 root
->AddChild(scroll
.Pass());
1533 root
->AddChild(scrollbar
.PassAs
<LayerImpl
>());
1535 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
1536 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
1537 host_impl_
->active_tree()->DidBecomeActive();
1540 LayerImpl
* root_scroll
=
1541 host_impl_
->active_tree()->InnerViewportScrollLayer();
1542 ASSERT_TRUE(root_scroll
->scrollbar_animation_controller());
1543 ScrollbarAnimationControllerThinning
* scrollbar_animation_controller
=
1544 static_cast<ScrollbarAnimationControllerThinning
*>(
1545 root_scroll
->scrollbar_animation_controller());
1546 scrollbar_animation_controller
->set_mouse_move_distance_for_test(100.f
);
1548 host_impl_
->MouseMoveAt(gfx::Point(1, 1));
1549 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1551 host_impl_
->MouseMoveAt(gfx::Point(200, 50));
1552 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1554 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1555 EXPECT_FALSE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1557 scrollbar_animation_controller
->set_mouse_move_distance_for_test(102.f
);
1558 host_impl_
->MouseMoveAt(gfx::Point(184, 100));
1559 EXPECT_TRUE(scrollbar_animation_controller
->mouse_is_near_scrollbar());
1561 did_request_redraw_
= false;
1562 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1563 host_impl_
->MouseMoveAt(gfx::Point(290, 100));
1564 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1565 host_impl_
->MouseMoveAt(gfx::Point(290, 120));
1566 EXPECT_EQ(2, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1567 host_impl_
->MouseMoveAt(gfx::Point(150, 120));
1568 EXPECT_EQ(0, host_impl_
->scroll_layer_id_when_mouse_over_scrollbar());
1571 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf1
) {
1572 SetupMouseMoveAtWithDeviceScale(1.f
);
1575 TEST_F(LayerTreeHostImplTest
, MouseMoveAtWithDeviceScaleOf2
) {
1576 SetupMouseMoveAtWithDeviceScale(2.f
);
1579 TEST_F(LayerTreeHostImplTest
, CompositorFrameMetadata
) {
1580 SetupScrollAndContentsLayers(gfx::Size(100, 100));
1581 host_impl_
->SetViewportSize(gfx::Size(50, 50));
1582 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
1585 CompositorFrameMetadata metadata
=
1586 host_impl_
->MakeCompositorFrameMetadata();
1587 EXPECT_EQ(gfx::Vector2dF(), metadata
.root_scroll_offset
);
1588 EXPECT_EQ(1.f
, metadata
.page_scale_factor
);
1589 EXPECT_EQ(gfx::SizeF(50.f
, 50.f
), metadata
.viewport_size
);
1590 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1591 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1592 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1595 // Scrolling should update metadata immediately.
1596 EXPECT_EQ(InputHandler::ScrollStarted
,
1597 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
1598 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1600 CompositorFrameMetadata metadata
=
1601 host_impl_
->MakeCompositorFrameMetadata();
1602 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1604 host_impl_
->ScrollEnd();
1606 CompositorFrameMetadata metadata
=
1607 host_impl_
->MakeCompositorFrameMetadata();
1608 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1611 // Page scale should update metadata correctly (shrinking only the viewport).
1612 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
1613 host_impl_
->PinchGestureBegin();
1614 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
1615 host_impl_
->PinchGestureEnd();
1616 host_impl_
->ScrollEnd();
1618 CompositorFrameMetadata metadata
=
1619 host_impl_
->MakeCompositorFrameMetadata();
1620 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1621 EXPECT_EQ(2.f
, metadata
.page_scale_factor
);
1622 EXPECT_EQ(gfx::SizeF(25.f
, 25.f
), metadata
.viewport_size
);
1623 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1624 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1625 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1628 // Likewise if set from the main thread.
1629 host_impl_
->ProcessScrollDeltas();
1630 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(4.f
, 0.5f
, 4.f
);
1631 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
1633 CompositorFrameMetadata metadata
=
1634 host_impl_
->MakeCompositorFrameMetadata();
1635 EXPECT_EQ(gfx::Vector2dF(0.f
, 10.f
), metadata
.root_scroll_offset
);
1636 EXPECT_EQ(4.f
, metadata
.page_scale_factor
);
1637 EXPECT_EQ(gfx::SizeF(12.5f
, 12.5f
), metadata
.viewport_size
);
1638 EXPECT_EQ(gfx::SizeF(100.f
, 100.f
), metadata
.root_layer_size
);
1639 EXPECT_EQ(0.5f
, metadata
.min_page_scale_factor
);
1640 EXPECT_EQ(4.f
, metadata
.max_page_scale_factor
);
1644 // TODO(enne): Convert this to PictureLayerImpl
1645 class DidDrawCheckLayer
: public TiledLayerImpl
{
1647 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
1648 return scoped_ptr
<LayerImpl
>(new DidDrawCheckLayer(tree_impl
, id
));
1651 virtual bool WillDraw(DrawMode draw_mode
, ResourceProvider
* provider
)
1653 will_draw_called_
= true;
1654 if (will_draw_returns_false_
)
1656 return TiledLayerImpl::WillDraw(draw_mode
, provider
);
1659 virtual void AppendQuads(QuadSink
* quad_sink
,
1660 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1661 append_quads_called_
= true;
1662 TiledLayerImpl::AppendQuads(quad_sink
, append_quads_data
);
1665 virtual void DidDraw(ResourceProvider
* provider
) OVERRIDE
{
1666 did_draw_called_
= true;
1667 TiledLayerImpl::DidDraw(provider
);
1670 bool will_draw_called() const { return will_draw_called_
; }
1671 bool append_quads_called() const { return append_quads_called_
; }
1672 bool did_draw_called() const { return did_draw_called_
; }
1674 void set_will_draw_returns_false() { will_draw_returns_false_
= true; }
1676 void ClearDidDrawCheck() {
1677 will_draw_called_
= false;
1678 append_quads_called_
= false;
1679 did_draw_called_
= false;
1683 DidDrawCheckLayer(LayerTreeImpl
* tree_impl
, int id
)
1684 : TiledLayerImpl(tree_impl
, id
),
1685 will_draw_returns_false_(false),
1686 will_draw_called_(false),
1687 append_quads_called_(false),
1688 did_draw_called_(false) {
1689 SetBounds(gfx::Size(10, 10));
1690 SetContentBounds(gfx::Size(10, 10));
1691 SetDrawsContent(true);
1692 set_skips_draw(false);
1693 draw_properties().visible_content_rect
= gfx::Rect(0, 0, 10, 10);
1695 scoped_ptr
<LayerTilingData
> tiler
=
1696 LayerTilingData::Create(gfx::Size(100, 100),
1697 LayerTilingData::HAS_BORDER_TEXELS
);
1698 tiler
->SetTilingRect(gfx::Rect(content_bounds()));
1699 SetTilingData(*tiler
.get());
1703 bool will_draw_returns_false_
;
1704 bool will_draw_called_
;
1705 bool append_quads_called_
;
1706 bool did_draw_called_
;
1709 TEST_F(LayerTreeHostImplTest
, WillDrawReturningFalseDoesNotCall
) {
1710 // The root layer is always drawn, so run this test on a child layer that
1711 // will be masked out by the root layer's bounds.
1712 host_impl_
->active_tree()->SetRootLayer(
1713 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1714 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1715 host_impl_
->active_tree()->root_layer());
1717 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1718 DidDrawCheckLayer
* layer
=
1719 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1722 LayerTreeHostImpl::FrameData frame
;
1723 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1724 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1725 host_impl_
->DidDrawAllLayers(frame
);
1727 EXPECT_TRUE(layer
->will_draw_called());
1728 EXPECT_TRUE(layer
->append_quads_called());
1729 EXPECT_TRUE(layer
->did_draw_called());
1732 host_impl_
->SetViewportDamage(gfx::Rect(10, 10));
1735 LayerTreeHostImpl::FrameData frame
;
1737 layer
->set_will_draw_returns_false();
1738 layer
->ClearDidDrawCheck();
1740 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1741 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1742 host_impl_
->DidDrawAllLayers(frame
);
1744 EXPECT_TRUE(layer
->will_draw_called());
1745 EXPECT_FALSE(layer
->append_quads_called());
1746 EXPECT_FALSE(layer
->did_draw_called());
1750 TEST_F(LayerTreeHostImplTest
, DidDrawNotCalledOnHiddenLayer
) {
1751 // The root layer is always drawn, so run this test on a child layer that
1752 // will be masked out by the root layer's bounds.
1753 host_impl_
->active_tree()->SetRootLayer(
1754 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1755 DidDrawCheckLayer
* root
= static_cast<DidDrawCheckLayer
*>(
1756 host_impl_
->active_tree()->root_layer());
1757 root
->SetMasksToBounds(true);
1759 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1760 DidDrawCheckLayer
* layer
=
1761 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1762 // Ensure visible_content_rect for layer is empty.
1763 layer
->SetPosition(gfx::PointF(100.f
, 100.f
));
1764 layer
->SetBounds(gfx::Size(10, 10));
1765 layer
->SetContentBounds(gfx::Size(10, 10));
1767 LayerTreeHostImpl::FrameData frame
;
1769 EXPECT_FALSE(layer
->will_draw_called());
1770 EXPECT_FALSE(layer
->did_draw_called());
1772 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1773 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1774 host_impl_
->DidDrawAllLayers(frame
);
1776 EXPECT_FALSE(layer
->will_draw_called());
1777 EXPECT_FALSE(layer
->did_draw_called());
1779 EXPECT_TRUE(layer
->visible_content_rect().IsEmpty());
1781 // Ensure visible_content_rect for layer is not empty
1782 layer
->SetPosition(gfx::PointF());
1784 EXPECT_FALSE(layer
->will_draw_called());
1785 EXPECT_FALSE(layer
->did_draw_called());
1787 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1788 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1789 host_impl_
->DidDrawAllLayers(frame
);
1791 EXPECT_TRUE(layer
->will_draw_called());
1792 EXPECT_TRUE(layer
->did_draw_called());
1794 EXPECT_FALSE(layer
->visible_content_rect().IsEmpty());
1797 TEST_F(LayerTreeHostImplTest
, WillDrawNotCalledOnOccludedLayer
) {
1798 gfx::Size
big_size(1000, 1000);
1799 host_impl_
->SetViewportSize(big_size
);
1801 host_impl_
->active_tree()->SetRootLayer(
1802 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1803 DidDrawCheckLayer
* root
=
1804 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1806 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1807 DidDrawCheckLayer
* occluded_layer
=
1808 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1810 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1811 DidDrawCheckLayer
* top_layer
=
1812 static_cast<DidDrawCheckLayer
*>(root
->children()[1]);
1813 // This layer covers the occluded_layer above. Make this layer large so it can
1815 top_layer
->SetBounds(big_size
);
1816 top_layer
->SetContentBounds(big_size
);
1817 top_layer
->SetContentsOpaque(true);
1819 LayerTreeHostImpl::FrameData frame
;
1821 EXPECT_FALSE(occluded_layer
->will_draw_called());
1822 EXPECT_FALSE(occluded_layer
->did_draw_called());
1823 EXPECT_FALSE(top_layer
->will_draw_called());
1824 EXPECT_FALSE(top_layer
->did_draw_called());
1826 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1827 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1828 host_impl_
->DidDrawAllLayers(frame
);
1830 EXPECT_FALSE(occluded_layer
->will_draw_called());
1831 EXPECT_FALSE(occluded_layer
->did_draw_called());
1832 EXPECT_TRUE(top_layer
->will_draw_called());
1833 EXPECT_TRUE(top_layer
->did_draw_called());
1836 TEST_F(LayerTreeHostImplTest
, DidDrawCalledOnAllLayers
) {
1837 host_impl_
->active_tree()->SetRootLayer(
1838 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1839 DidDrawCheckLayer
* root
=
1840 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1842 root
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 2));
1843 DidDrawCheckLayer
* layer1
=
1844 static_cast<DidDrawCheckLayer
*>(root
->children()[0]);
1846 layer1
->AddChild(DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1847 DidDrawCheckLayer
* layer2
=
1848 static_cast<DidDrawCheckLayer
*>(layer1
->children()[0]);
1850 layer1
->SetOpacity(0.3f
);
1851 layer1
->SetShouldFlattenTransform(true);
1853 EXPECT_FALSE(root
->did_draw_called());
1854 EXPECT_FALSE(layer1
->did_draw_called());
1855 EXPECT_FALSE(layer2
->did_draw_called());
1857 LayerTreeHostImpl::FrameData frame
;
1858 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1859 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1860 host_impl_
->DidDrawAllLayers(frame
);
1862 EXPECT_TRUE(root
->did_draw_called());
1863 EXPECT_TRUE(layer1
->did_draw_called());
1864 EXPECT_TRUE(layer2
->did_draw_called());
1866 EXPECT_NE(root
->render_surface(), layer1
->render_surface());
1867 EXPECT_TRUE(!!layer1
->render_surface());
1870 class MissingTextureAnimatingLayer
: public DidDrawCheckLayer
{
1872 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
1877 ResourceProvider
* resource_provider
) {
1878 return scoped_ptr
<LayerImpl
>(new MissingTextureAnimatingLayer(
1884 resource_provider
));
1887 virtual void AppendQuads(QuadSink
* quad_sink
,
1888 AppendQuadsData
* append_quads_data
) OVERRIDE
{
1889 TiledLayerImpl::AppendQuads(quad_sink
, append_quads_data
);
1891 append_quads_data
->had_incomplete_tile
= true;
1895 MissingTextureAnimatingLayer(LayerTreeImpl
* tree_impl
,
1900 ResourceProvider
* resource_provider
)
1901 : DidDrawCheckLayer(tree_impl
, id
), tile_missing_(tile_missing
) {
1902 scoped_ptr
<LayerTilingData
> tiling_data
=
1903 LayerTilingData::Create(gfx::Size(10, 10),
1904 LayerTilingData::NO_BORDER_TEXELS
);
1905 tiling_data
->SetTilingRect(gfx::Rect(bounds()));
1906 SetTilingData(*tiling_data
.get());
1907 set_skips_draw(skips_draw
);
1908 if (!tile_missing
) {
1909 ResourceProvider::ResourceId resource
=
1910 resource_provider
->CreateResource(gfx::Size(1, 1),
1912 ResourceProvider::TextureUsageAny
,
1914 resource_provider
->AllocateForTesting(resource
);
1915 PushTileProperties(0, 0, resource
, gfx::Rect(), false);
1918 AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1924 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWhenNoTexturesMissing
) {
1925 host_impl_
->active_tree()->SetRootLayer(
1926 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1927 DidDrawCheckLayer
* root
=
1928 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1930 bool tile_missing
= false;
1931 bool skips_draw
= false;
1932 bool is_animating
= false;
1934 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1939 host_impl_
->resource_provider()));
1941 LayerTreeHostImpl::FrameData frame
;
1943 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1944 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1945 host_impl_
->DidDrawAllLayers(frame
);
1948 TEST_F(LayerTreeHostImplTest
, PrepareToDrawSucceedsWithAnimatedLayer
) {
1949 host_impl_
->active_tree()->SetRootLayer(
1950 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 1));
1951 DidDrawCheckLayer
* root
=
1952 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1953 bool tile_missing
= false;
1954 bool skips_draw
= false;
1955 bool is_animating
= true;
1957 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1962 host_impl_
->resource_provider()));
1964 LayerTreeHostImpl::FrameData frame
;
1966 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1967 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1968 host_impl_
->DidDrawAllLayers(frame
);
1971 TEST_F(LayerTreeHostImplTest
,
1972 PrepareToDrawSucceedsWithNonAnimatedMissingTexture
) {
1973 // When a texture is missing and we're not animating, we draw as usual with
1975 host_impl_
->active_tree()->SetRootLayer(
1976 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 3));
1977 DidDrawCheckLayer
* root
=
1978 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
1980 bool tile_missing
= true;
1981 bool skips_draw
= false;
1982 bool is_animating
= false;
1984 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
1989 host_impl_
->resource_provider()));
1990 LayerTreeHostImpl::FrameData frame
;
1991 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
1992 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
1993 host_impl_
->DidDrawAllLayers(frame
);
1996 TEST_F(LayerTreeHostImplTest
, PrepareToDrawFailsWhenAnimationUsesCheckerboard
) {
1997 // When a texture is missing and we're animating, we don't want to draw
1999 host_impl_
->active_tree()->SetRootLayer(
2000 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 5));
2001 DidDrawCheckLayer
* root
=
2002 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2003 bool tile_missing
= true;
2004 bool skips_draw
= false;
2005 bool is_animating
= true;
2007 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2012 host_impl_
->resource_provider()));
2013 LayerTreeHostImpl::FrameData frame
;
2014 EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
,
2015 host_impl_
->PrepareToDraw(&frame
));
2016 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2017 host_impl_
->DidDrawAllLayers(frame
);
2020 TEST_F(LayerTreeHostImplTest
,
2021 PrepareToDrawSucceedsWithMissingSkippedAnimatedLayer
) {
2022 // When the layer skips draw and we're animating, we still draw the frame.
2023 host_impl_
->active_tree()->SetRootLayer(
2024 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2025 DidDrawCheckLayer
* root
=
2026 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2027 bool tile_missing
= false;
2028 bool skips_draw
= true;
2029 bool is_animating
= true;
2031 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2036 host_impl_
->resource_provider()));
2037 LayerTreeHostImpl::FrameData frame
;
2038 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2039 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2040 host_impl_
->DidDrawAllLayers(frame
);
2043 TEST_F(LayerTreeHostImplTest
,
2044 PrepareToDrawSucceedsWhenHighResRequiredButNoMissingTextures
) {
2045 // When the layer skips draw and we're animating, we still draw the frame.
2046 host_impl_
->active_tree()->SetRootLayer(
2047 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2048 DidDrawCheckLayer
* root
=
2049 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2050 bool tile_missing
= false;
2051 bool skips_draw
= false;
2052 bool is_animating
= false;
2054 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2059 host_impl_
->resource_provider()));
2060 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2061 LayerTreeHostImpl::FrameData frame
;
2062 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2063 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2064 host_impl_
->DidDrawAllLayers(frame
);
2067 TEST_F(LayerTreeHostImplTest
,
2068 PrepareToDrawFailsWhenHighResRequiredAndMissingTextures
) {
2069 // When the layer skips draw and we're animating, we still draw the frame.
2070 host_impl_
->active_tree()->SetRootLayer(
2071 DidDrawCheckLayer::Create(host_impl_
->active_tree(), 7));
2072 DidDrawCheckLayer
* root
=
2073 static_cast<DidDrawCheckLayer
*>(host_impl_
->active_tree()->root_layer());
2074 bool tile_missing
= true;
2075 bool skips_draw
= false;
2076 bool is_animating
= false;
2078 MissingTextureAnimatingLayer::Create(host_impl_
->active_tree(),
2083 host_impl_
->resource_provider()));
2084 host_impl_
->active_tree()->SetRequiresHighResToDraw();
2085 LayerTreeHostImpl::FrameData frame
;
2086 EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
,
2087 host_impl_
->PrepareToDraw(&frame
));
2088 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2089 host_impl_
->DidDrawAllLayers(frame
);
2092 TEST_F(LayerTreeHostImplTest
, ScrollRootIgnored
) {
2093 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2094 root
->SetScrollClipLayer(Layer::INVALID_ID
);
2095 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2098 // Scroll event is ignored because layer is not scrollable.
2099 EXPECT_EQ(InputHandler::ScrollIgnored
,
2100 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2101 EXPECT_FALSE(did_request_redraw_
);
2102 EXPECT_FALSE(did_request_commit_
);
2105 class LayerTreeHostImplTopControlsTest
: public LayerTreeHostImplTest
{
2107 LayerTreeHostImplTopControlsTest()
2108 // Make the clip size the same as the layer (content) size so the layer is
2110 : layer_size_(10, 10),
2111 clip_size_(layer_size_
) {
2112 settings_
.calculate_top_controls_position
= true;
2113 settings_
.top_controls_height
= 50;
2116 gfx::Size(clip_size_
.width(),
2117 clip_size_
.height() + settings_
.top_controls_height
);
2120 void SetupTopControlsAndScrollLayer() {
2121 CreateHostImpl(settings_
, CreateOutputSurface());
2123 scoped_ptr
<LayerImpl
> root
=
2124 LayerImpl::Create(host_impl_
->active_tree(), 1);
2125 scoped_ptr
<LayerImpl
> root_clip
=
2126 LayerImpl::Create(host_impl_
->active_tree(), 2);
2127 root_clip
->SetBounds(clip_size_
);
2128 root
->SetScrollClipLayer(root_clip
->id());
2129 root
->SetBounds(layer_size_
);
2130 root
->SetContentBounds(layer_size_
);
2131 root
->SetPosition(gfx::PointF());
2132 root
->SetDrawsContent(false);
2133 root
->SetIsContainerForFixedPositionLayers(true);
2134 int inner_viewport_scroll_layer_id
= root
->id();
2135 int page_scale_layer_id
= root_clip
->id();
2136 root_clip
->AddChild(root
.Pass());
2137 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2138 host_impl_
->active_tree()->SetViewportLayersFromIds(
2139 page_scale_layer_id
, inner_viewport_scroll_layer_id
, Layer::INVALID_ID
);
2140 // Set a viewport size that is large enough to contain both the top controls
2141 // and some content.
2142 host_impl_
->SetViewportSize(viewport_size_
);
2143 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2144 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2148 gfx::Size layer_size_
;
2149 gfx::Size clip_size_
;
2150 gfx::Size viewport_size_
;
2152 LayerTreeSettings settings_
;
2153 }; // class LayerTreeHostImplTopControlsTest
2155 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsByFractionalAmount
) {
2156 SetupTopControlsAndScrollLayer();
2159 EXPECT_EQ(InputHandler::ScrollStarted
,
2160 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2162 // Make the test scroll delta a fractional amount, to verify that the
2163 // fixed container size delta is (1) non-zero, and (2) fractional, and
2164 // (3) matches the movement of the top controls.
2165 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.25f
);
2166 host_impl_
->top_controls_manager()->ScrollBegin();
2167 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2168 host_impl_
->top_controls_manager()->ScrollEnd();
2170 LayerImpl
* inner_viewport_scroll_layer
=
2171 host_impl_
->active_tree()->InnerViewportScrollLayer();
2172 DCHECK(inner_viewport_scroll_layer
);
2173 host_impl_
->ScrollEnd();
2174 EXPECT_EQ(top_controls_scroll_delta
,
2175 inner_viewport_scroll_layer
->FixedContainerSizeDelta());
2178 TEST_F(LayerTreeHostImplTopControlsTest
, ScrollTopControlsWithPageScale
) {
2179 SetupTopControlsAndScrollLayer();
2182 EXPECT_EQ(InputHandler::ScrollStarted
,
2183 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2185 float page_scale
= 1.5f
;
2186 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
, 1.f
, 2.f
);
2188 gfx::Vector2dF
top_controls_scroll_delta(0.f
, 5.f
);
2189 gfx::Vector2dF expected_container_size_delta
=
2190 ScaleVector2d(top_controls_scroll_delta
, 1.f
/ page_scale
);
2191 host_impl_
->top_controls_manager()->ScrollBegin();
2192 host_impl_
->top_controls_manager()->ScrollBy(top_controls_scroll_delta
);
2193 host_impl_
->top_controls_manager()->ScrollEnd();
2195 LayerImpl
* inner_viewport_scroll_layer
=
2196 host_impl_
->active_tree()->InnerViewportScrollLayer();
2197 DCHECK(inner_viewport_scroll_layer
);
2198 host_impl_
->ScrollEnd();
2200 // Use a tolerance that requires the container size delta to be within 0.01
2202 double tolerance
= 0.0001;
2204 (expected_container_size_delta
-
2205 inner_viewport_scroll_layer
->FixedContainerSizeDelta()).LengthSquared(),
2209 TEST_F(LayerTreeHostImplTopControlsTest
,
2210 ScrollNonScrollableRootWithTopControls
) {
2211 SetupTopControlsAndScrollLayer();
2214 EXPECT_EQ(InputHandler::ScrollStarted
,
2215 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2217 host_impl_
->top_controls_manager()->ScrollBegin();
2218 host_impl_
->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f
, 50.f
));
2219 host_impl_
->top_controls_manager()->ScrollEnd();
2220 EXPECT_EQ(0.f
, host_impl_
->top_controls_manager()->content_top_offset());
2221 // Now that top controls have moved, expect the clip to resize.
2222 LayerImpl
* root_clip_ptr
= host_impl_
->active_tree()->root_layer();
2223 EXPECT_EQ(viewport_size_
, root_clip_ptr
->bounds());
2225 host_impl_
->ScrollEnd();
2227 EXPECT_EQ(InputHandler::ScrollStarted
,
2228 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2230 float scroll_increment_y
= -25.f
;
2231 host_impl_
->top_controls_manager()->ScrollBegin();
2232 host_impl_
->top_controls_manager()->ScrollBy(
2233 gfx::Vector2dF(0.f
, scroll_increment_y
));
2234 EXPECT_EQ(-scroll_increment_y
,
2235 host_impl_
->top_controls_manager()->content_top_offset());
2236 // Now that top controls have moved, expect the clip to resize.
2237 EXPECT_EQ(gfx::Size(viewport_size_
.width(),
2238 viewport_size_
.height() + scroll_increment_y
),
2239 root_clip_ptr
->bounds());
2241 host_impl_
->top_controls_manager()->ScrollBy(
2242 gfx::Vector2dF(0.f
, scroll_increment_y
));
2243 host_impl_
->top_controls_manager()->ScrollEnd();
2244 EXPECT_EQ(-2 * scroll_increment_y
,
2245 host_impl_
->top_controls_manager()->content_top_offset());
2246 // Now that top controls have moved, expect the clip to resize.
2247 EXPECT_EQ(clip_size_
, root_clip_ptr
->bounds());
2249 host_impl_
->ScrollEnd();
2251 // Verify the layer is once-again non-scrollable.
2254 host_impl_
->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2256 EXPECT_EQ(InputHandler::ScrollStarted
,
2257 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2260 TEST_F(LayerTreeHostImplTest
, ScrollNonCompositedRoot
) {
2261 // Test the configuration where a non-composited root layer is embedded in a
2262 // scrollable outer layer.
2263 gfx::Size
surface_size(10, 10);
2264 gfx::Size
contents_size(20, 20);
2266 scoped_ptr
<LayerImpl
> content_layer
=
2267 LayerImpl::Create(host_impl_
->active_tree(), 1);
2268 content_layer
->SetDrawsContent(true);
2269 content_layer
->SetPosition(gfx::PointF());
2270 content_layer
->SetBounds(contents_size
);
2271 content_layer
->SetContentBounds(contents_size
);
2272 content_layer
->SetContentsScale(2.f
, 2.f
);
2274 scoped_ptr
<LayerImpl
> scroll_clip_layer
=
2275 LayerImpl::Create(host_impl_
->active_tree(), 3);
2276 scroll_clip_layer
->SetBounds(surface_size
);
2278 scoped_ptr
<LayerImpl
> scroll_layer
=
2279 LayerImpl::Create(host_impl_
->active_tree(), 2);
2280 scroll_layer
->SetScrollClipLayer(3);
2281 scroll_layer
->SetBounds(contents_size
);
2282 scroll_layer
->SetContentBounds(contents_size
);
2283 scroll_layer
->SetPosition(gfx::PointF());
2284 scroll_layer
->AddChild(content_layer
.Pass());
2285 scroll_clip_layer
->AddChild(scroll_layer
.Pass());
2287 host_impl_
->active_tree()->SetRootLayer(scroll_clip_layer
.Pass());
2288 host_impl_
->SetViewportSize(surface_size
);
2291 EXPECT_EQ(InputHandler::ScrollStarted
,
2292 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2293 InputHandler::Wheel
));
2294 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2295 host_impl_
->ScrollEnd();
2296 EXPECT_TRUE(did_request_redraw_
);
2297 EXPECT_TRUE(did_request_commit_
);
2300 TEST_F(LayerTreeHostImplTest
, ScrollChildCallsCommitAndRedraw
) {
2301 gfx::Size
surface_size(10, 10);
2302 gfx::Size
contents_size(20, 20);
2303 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2304 root
->SetBounds(surface_size
);
2305 root
->SetContentBounds(contents_size
);
2306 root
->AddChild(CreateScrollableLayer(2, contents_size
, root
.get()));
2307 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2308 host_impl_
->SetViewportSize(surface_size
);
2311 EXPECT_EQ(InputHandler::ScrollStarted
,
2312 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2313 InputHandler::Wheel
));
2314 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2315 host_impl_
->ScrollEnd();
2316 EXPECT_TRUE(did_request_redraw_
);
2317 EXPECT_TRUE(did_request_commit_
);
2320 TEST_F(LayerTreeHostImplTest
, ScrollMissesChild
) {
2321 gfx::Size
surface_size(10, 10);
2322 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2323 root
->AddChild(CreateScrollableLayer(2, surface_size
, root
.get()));
2324 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2325 host_impl_
->SetViewportSize(surface_size
);
2328 // Scroll event is ignored because the input coordinate is outside the layer
2330 EXPECT_EQ(InputHandler::ScrollIgnored
,
2331 host_impl_
->ScrollBegin(gfx::Point(15, 5),
2332 InputHandler::Wheel
));
2333 EXPECT_FALSE(did_request_redraw_
);
2334 EXPECT_FALSE(did_request_commit_
);
2337 TEST_F(LayerTreeHostImplTest
, ScrollMissesBackfacingChild
) {
2338 gfx::Size
surface_size(10, 10);
2339 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2340 scoped_ptr
<LayerImpl
> child
=
2341 CreateScrollableLayer(2, surface_size
, root
.get());
2342 host_impl_
->SetViewportSize(surface_size
);
2344 gfx::Transform matrix
;
2345 matrix
.RotateAboutXAxis(180.0);
2346 child
->SetTransform(matrix
);
2347 child
->SetDoubleSided(false);
2349 root
->AddChild(child
.Pass());
2350 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2353 // Scroll event is ignored because the scrollable layer is not facing the
2354 // viewer and there is nothing scrollable behind it.
2355 EXPECT_EQ(InputHandler::ScrollIgnored
,
2356 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2357 InputHandler::Wheel
));
2358 EXPECT_FALSE(did_request_redraw_
);
2359 EXPECT_FALSE(did_request_commit_
);
2362 TEST_F(LayerTreeHostImplTest
, ScrollBlockedByContentLayer
) {
2363 gfx::Size
surface_size(10, 10);
2364 scoped_ptr
<LayerImpl
> clip_layer
=
2365 LayerImpl::Create(host_impl_
->active_tree(), 3);
2366 scoped_ptr
<LayerImpl
> content_layer
=
2367 CreateScrollableLayer(1, surface_size
, clip_layer
.get());
2368 content_layer
->SetShouldScrollOnMainThread(true);
2369 content_layer
->SetScrollClipLayer(Layer::INVALID_ID
);
2371 // Note: we can use the same clip layer for both since both calls to
2372 // CreateScrollableLayer() use the same surface size.
2373 scoped_ptr
<LayerImpl
> scroll_layer
=
2374 CreateScrollableLayer(2, surface_size
, clip_layer
.get());
2375 scroll_layer
->AddChild(content_layer
.Pass());
2376 clip_layer
->AddChild(scroll_layer
.Pass());
2378 host_impl_
->active_tree()->SetRootLayer(clip_layer
.Pass());
2379 host_impl_
->SetViewportSize(surface_size
);
2382 // Scrolling fails because the content layer is asking to be scrolled on the
2384 EXPECT_EQ(InputHandler::ScrollOnMainThread
,
2385 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2386 InputHandler::Wheel
));
2389 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnMainThread
) {
2390 gfx::Size
surface_size(20, 20);
2391 gfx::Size
viewport_size(10, 10);
2392 float page_scale
= 2.f
;
2393 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2394 scoped_ptr
<LayerImpl
> root_clip
=
2395 LayerImpl::Create(host_impl_
->active_tree(), 2);
2396 scoped_ptr
<LayerImpl
> root_scrolling
=
2397 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2398 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2399 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2400 root_clip
->AddChild(root_scrolling
.Pass());
2401 root
->AddChild(root_clip
.Pass());
2402 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2403 // The behaviour in this test assumes the page scale is applied at a layer
2404 // above the clip layer.
2405 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2406 host_impl_
->active_tree()->DidBecomeActive();
2407 host_impl_
->SetViewportSize(viewport_size
);
2410 LayerImpl
* root_scroll
=
2411 host_impl_
->active_tree()->InnerViewportScrollLayer();
2412 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2414 gfx::Vector2d
scroll_delta(0, 10);
2415 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2416 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2417 EXPECT_EQ(InputHandler::ScrollStarted
,
2418 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2419 InputHandler::Wheel
));
2420 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2421 host_impl_
->ScrollEnd();
2423 // Set new page scale from main thread.
2424 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2428 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2429 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2431 // The scroll range should also have been updated.
2432 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2434 // The page scale delta remains constant because the impl thread did not
2436 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2439 TEST_F(LayerTreeHostImplTest
, ScrollRootAndChangePageScaleOnImplThread
) {
2440 gfx::Size
surface_size(20, 20);
2441 gfx::Size
viewport_size(10, 10);
2442 float page_scale
= 2.f
;
2443 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2444 scoped_ptr
<LayerImpl
> root_clip
=
2445 LayerImpl::Create(host_impl_
->active_tree(), 2);
2446 scoped_ptr
<LayerImpl
> root_scrolling
=
2447 CreateScrollableLayer(3, surface_size
, root_clip
.get());
2448 EXPECT_EQ(viewport_size
, root_clip
->bounds());
2449 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2450 root_clip
->AddChild(root_scrolling
.Pass());
2451 root
->AddChild(root_clip
.Pass());
2452 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2453 // The behaviour in this test assumes the page scale is applied at a layer
2454 // above the clip layer.
2455 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID
);
2456 host_impl_
->active_tree()->DidBecomeActive();
2457 host_impl_
->SetViewportSize(viewport_size
);
2458 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 1.f
, page_scale
);
2461 LayerImpl
* root_scroll
=
2462 host_impl_
->active_tree()->InnerViewportScrollLayer();
2463 EXPECT_EQ(viewport_size
, root_scroll
->scroll_clip_layer()->bounds());
2465 gfx::Vector2d
scroll_delta(0, 10);
2466 gfx::Vector2d expected_scroll_delta
= scroll_delta
;
2467 gfx::Vector2d expected_max_scroll
= root_scroll
->MaxScrollOffset();
2468 EXPECT_EQ(InputHandler::ScrollStarted
,
2469 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2470 InputHandler::Wheel
));
2471 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2472 host_impl_
->ScrollEnd();
2474 // Set new page scale on impl thread by pinching.
2475 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2476 host_impl_
->PinchGestureBegin();
2477 host_impl_
->PinchGestureUpdate(page_scale
, gfx::Point());
2478 host_impl_
->PinchGestureEnd();
2479 host_impl_
->ScrollEnd();
2482 // The scroll delta is not scaled because the main thread did not scale.
2483 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2484 ExpectContains(*scroll_info
.get(), root_scroll
->id(), expected_scroll_delta
);
2486 // The scroll range should also have been updated.
2487 EXPECT_EQ(expected_max_scroll
, root_scroll
->MaxScrollOffset());
2489 // The page scale delta should match the new scale on the impl side.
2490 EXPECT_EQ(page_scale
, host_impl_
->active_tree()->total_page_scale_factor());
2493 TEST_F(LayerTreeHostImplTest
, PageScaleDeltaAppliedToRootScrollLayerOnly
) {
2494 gfx::Size
surface_size(10, 10);
2495 float default_page_scale
= 1.f
;
2496 gfx::Transform default_page_scale_matrix
;
2497 default_page_scale_matrix
.Scale(default_page_scale
, default_page_scale
);
2499 float new_page_scale
= 2.f
;
2500 gfx::Transform new_page_scale_matrix
;
2501 new_page_scale_matrix
.Scale(new_page_scale
, new_page_scale
);
2503 // Create a normal scrollable root layer and another scrollable child layer.
2504 LayerImpl
* scroll
= SetupScrollAndContentsLayers(surface_size
);
2505 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
2506 LayerImpl
* child
= scroll
->children()[0];
2508 scoped_ptr
<LayerImpl
> scrollable_child_clip
=
2509 LayerImpl::Create(host_impl_
->active_tree(), 6);
2510 scoped_ptr
<LayerImpl
> scrollable_child
=
2511 CreateScrollableLayer(7, surface_size
, scrollable_child_clip
.get());
2512 scrollable_child_clip
->AddChild(scrollable_child
.Pass());
2513 child
->AddChild(scrollable_child_clip
.Pass());
2514 LayerImpl
* grand_child
= child
->children()[0];
2516 // Set new page scale on impl thread by pinching.
2517 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
2518 host_impl_
->PinchGestureBegin();
2519 host_impl_
->PinchGestureUpdate(new_page_scale
, gfx::Point());
2520 host_impl_
->PinchGestureEnd();
2521 host_impl_
->ScrollEnd();
2524 EXPECT_EQ(1.f
, root
->contents_scale_x());
2525 EXPECT_EQ(1.f
, root
->contents_scale_y());
2526 EXPECT_EQ(1.f
, scroll
->contents_scale_x());
2527 EXPECT_EQ(1.f
, scroll
->contents_scale_y());
2528 EXPECT_EQ(1.f
, child
->contents_scale_x());
2529 EXPECT_EQ(1.f
, child
->contents_scale_y());
2530 EXPECT_EQ(1.f
, grand_child
->contents_scale_x());
2531 EXPECT_EQ(1.f
, grand_child
->contents_scale_y());
2533 // Make sure all the layers are drawn with the page scale delta applied, i.e.,
2534 // the page scale delta on the root layer is applied hierarchically.
2535 LayerTreeHostImpl::FrameData frame
;
2536 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
2537 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
2538 host_impl_
->DidDrawAllLayers(frame
);
2540 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(0, 0));
2541 EXPECT_EQ(1.f
, root
->draw_transform().matrix().getDouble(1, 1));
2542 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(0, 0));
2543 EXPECT_EQ(new_page_scale
, scroll
->draw_transform().matrix().getDouble(1, 1));
2544 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(0, 0));
2545 EXPECT_EQ(new_page_scale
, child
->draw_transform().matrix().getDouble(1, 1));
2546 EXPECT_EQ(new_page_scale
,
2547 grand_child
->draw_transform().matrix().getDouble(0, 0));
2548 EXPECT_EQ(new_page_scale
,
2549 grand_child
->draw_transform().matrix().getDouble(1, 1));
2552 TEST_F(LayerTreeHostImplTest
, ScrollChildAndChangePageScaleOnMainThread
) {
2553 gfx::Size
surface_size(30, 30);
2554 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2555 root
->SetBounds(gfx::Size(5, 5));
2556 scoped_ptr
<LayerImpl
> root_scrolling
=
2557 LayerImpl::Create(host_impl_
->active_tree(), 2);
2558 root_scrolling
->SetBounds(surface_size
);
2559 root_scrolling
->SetContentBounds(surface_size
);
2560 root_scrolling
->SetScrollClipLayer(root
->id());
2561 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2562 LayerImpl
* root_scrolling_ptr
= root_scrolling
.get();
2563 root
->AddChild(root_scrolling
.Pass());
2564 int child_scroll_layer_id
= 3;
2565 scoped_ptr
<LayerImpl
> child_scrolling
= CreateScrollableLayer(
2566 child_scroll_layer_id
, surface_size
, root_scrolling_ptr
);
2567 LayerImpl
* child
= child_scrolling
.get();
2568 root_scrolling_ptr
->AddChild(child_scrolling
.Pass());
2569 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2570 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2571 host_impl_
->active_tree()->DidBecomeActive();
2572 host_impl_
->SetViewportSize(surface_size
);
2575 gfx::Vector2d
scroll_delta(0, 10);
2576 gfx::Vector2d
expected_scroll_delta(scroll_delta
);
2577 gfx::Vector2d
expected_max_scroll(child
->MaxScrollOffset());
2578 EXPECT_EQ(InputHandler::ScrollStarted
,
2579 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2580 InputHandler::Wheel
));
2581 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2582 host_impl_
->ScrollEnd();
2584 float page_scale
= 2.f
;
2585 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(page_scale
,
2591 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2593 *scroll_info
.get(), child_scroll_layer_id
, expected_scroll_delta
);
2595 // The scroll range should not have changed.
2596 EXPECT_EQ(child
->MaxScrollOffset(), expected_max_scroll
);
2598 // The page scale delta remains constant because the impl thread did not
2600 EXPECT_EQ(1.f
, host_impl_
->active_tree()->page_scale_delta());
2603 TEST_F(LayerTreeHostImplTest
, ScrollChildBeyondLimit
) {
2604 // Scroll a child layer beyond its maximum scroll range and make sure the
2605 // parent layer is scrolled on the axis on which the child was unable to
2607 gfx::Size
surface_size(10, 10);
2608 gfx::Size
content_size(20, 20);
2609 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2610 root
->SetBounds(surface_size
);
2612 scoped_ptr
<LayerImpl
> grand_child
=
2613 CreateScrollableLayer(3, content_size
, root
.get());
2615 scoped_ptr
<LayerImpl
> child
=
2616 CreateScrollableLayer(2, content_size
, root
.get());
2617 LayerImpl
* grand_child_layer
= grand_child
.get();
2618 child
->AddChild(grand_child
.Pass());
2620 LayerImpl
* child_layer
= child
.get();
2621 root
->AddChild(child
.Pass());
2622 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2623 host_impl_
->active_tree()->DidBecomeActive();
2624 host_impl_
->SetViewportSize(surface_size
);
2625 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 5));
2626 child_layer
->SetScrollOffset(gfx::Vector2d(3, 0));
2630 gfx::Vector2d
scroll_delta(-8, -7);
2631 EXPECT_EQ(InputHandler::ScrollStarted
,
2632 host_impl_
->ScrollBegin(gfx::Point(),
2633 InputHandler::Wheel
));
2634 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2635 host_impl_
->ScrollEnd();
2637 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2638 host_impl_
->ProcessScrollDeltas();
2640 // The grand child should have scrolled up to its limit.
2641 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
2642 LayerImpl
* grand_child
= child
->children()[0];
2643 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -5));
2645 // The child should have only scrolled on the other axis.
2646 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(-3, 0));
2650 TEST_F(LayerTreeHostImplTest
, ScrollWithoutBubbling
) {
2651 // Scroll a child layer beyond its maximum scroll range and make sure the
2652 // the scroll doesn't bubble up to the parent layer.
2653 gfx::Size
surface_size(20, 20);
2654 gfx::Size
viewport_size(10, 10);
2655 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
2656 scoped_ptr
<LayerImpl
> root_scrolling
=
2657 CreateScrollableLayer(2, surface_size
, root
.get());
2658 root_scrolling
->SetIsContainerForFixedPositionLayers(true);
2660 scoped_ptr
<LayerImpl
> grand_child
=
2661 CreateScrollableLayer(4, surface_size
, root
.get());
2663 scoped_ptr
<LayerImpl
> child
=
2664 CreateScrollableLayer(3, surface_size
, root
.get());
2665 LayerImpl
* grand_child_layer
= grand_child
.get();
2666 child
->AddChild(grand_child
.Pass());
2668 LayerImpl
* child_layer
= child
.get();
2669 root_scrolling
->AddChild(child
.Pass());
2670 root
->AddChild(root_scrolling
.Pass());
2671 EXPECT_EQ(viewport_size
, root
->bounds());
2672 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
2673 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2674 host_impl_
->active_tree()->DidBecomeActive();
2675 host_impl_
->SetViewportSize(viewport_size
);
2677 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
2678 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
2682 gfx::Vector2d
scroll_delta(0, -10);
2683 EXPECT_EQ(InputHandler::ScrollStarted
,
2684 host_impl_
->ScrollBegin(gfx::Point(),
2685 InputHandler::NonBubblingGesture
));
2686 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2687 host_impl_
->ScrollEnd();
2689 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2690 host_impl_
->ProcessScrollDeltas();
2692 // The grand child should have scrolled up to its limit.
2694 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
2695 LayerImpl
* grand_child
= child
->children()[0];
2696 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2698 // The child should not have scrolled.
2699 ExpectNone(*scroll_info
.get(), child
->id());
2701 // The next time we scroll we should only scroll the parent.
2702 scroll_delta
= gfx::Vector2d(0, -3);
2703 EXPECT_EQ(InputHandler::ScrollStarted
,
2704 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2705 InputHandler::NonBubblingGesture
));
2706 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2707 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2708 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
2709 host_impl_
->ScrollEnd();
2711 scroll_info
= host_impl_
->ProcessScrollDeltas();
2713 // The child should have scrolled up to its limit.
2714 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2716 // The grand child should not have scrolled.
2717 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, -2));
2719 // After scrolling the parent, another scroll on the opposite direction
2720 // should still scroll the child.
2721 scroll_delta
= gfx::Vector2d(0, 7);
2722 EXPECT_EQ(InputHandler::ScrollStarted
,
2723 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2724 InputHandler::NonBubblingGesture
));
2725 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2726 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2727 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
2728 host_impl_
->ScrollEnd();
2730 scroll_info
= host_impl_
->ProcessScrollDeltas();
2732 // The grand child should have scrolled.
2733 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 5));
2735 // The child should not have scrolled.
2736 ExpectContains(*scroll_info
.get(), child
->id(), gfx::Vector2d(0, -3));
2739 // Scrolling should be adjusted from viewport space.
2740 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 2.f
, 2.f
);
2741 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
2743 scroll_delta
= gfx::Vector2d(0, -2);
2744 EXPECT_EQ(InputHandler::ScrollStarted
,
2745 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2746 InputHandler::NonBubblingGesture
));
2747 EXPECT_EQ(grand_child
, host_impl_
->CurrentlyScrollingLayer());
2748 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2749 host_impl_
->ScrollEnd();
2751 scroll_info
= host_impl_
->ProcessScrollDeltas();
2753 // Should have scrolled by half the amount in layer space (5 - 2/2)
2754 ExpectContains(*scroll_info
.get(), grand_child
->id(), gfx::Vector2d(0, 4));
2757 TEST_F(LayerTreeHostImplTest
, ScrollEventBubbling
) {
2758 // When we try to scroll a non-scrollable child layer, the scroll delta
2759 // should be applied to one of its ancestors if possible.
2760 gfx::Size
surface_size(10, 10);
2761 gfx::Size
content_size(20, 20);
2762 scoped_ptr
<LayerImpl
> root_clip
=
2763 LayerImpl::Create(host_impl_
->active_tree(), 3);
2764 scoped_ptr
<LayerImpl
> root
=
2765 CreateScrollableLayer(1, content_size
, root_clip
.get());
2766 // Make 'root' the clip layer for child: since they have the same sizes the
2767 // child will have zero max_scroll_offset and scrolls will bubble.
2768 scoped_ptr
<LayerImpl
> child
=
2769 CreateScrollableLayer(2, content_size
, root
.get());
2770 child
->SetIsContainerForFixedPositionLayers(true);
2771 root
->SetBounds(content_size
);
2773 int root_scroll_id
= root
->id();
2774 root
->AddChild(child
.Pass());
2775 root_clip
->AddChild(root
.Pass());
2777 host_impl_
->SetViewportSize(surface_size
);
2778 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2779 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID
);
2780 host_impl_
->active_tree()->DidBecomeActive();
2783 gfx::Vector2d
scroll_delta(0, 4);
2784 EXPECT_EQ(InputHandler::ScrollStarted
,
2785 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2786 InputHandler::Wheel
));
2787 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2788 host_impl_
->ScrollEnd();
2790 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2791 host_impl_
->ProcessScrollDeltas();
2793 // Only the root scroll should have scrolled.
2794 ASSERT_EQ(scroll_info
->scrolls
.size(), 1u);
2795 ExpectContains(*scroll_info
.get(), root_scroll_id
, scroll_delta
);
2799 TEST_F(LayerTreeHostImplTest
, ScrollBeforeRedraw
) {
2800 gfx::Size
surface_size(10, 10);
2801 scoped_ptr
<LayerImpl
> root_clip
=
2802 LayerImpl::Create(host_impl_
->active_tree(), 1);
2803 scoped_ptr
<LayerImpl
> root_scroll
=
2804 CreateScrollableLayer(2, surface_size
, root_clip
.get());
2805 root_scroll
->SetIsContainerForFixedPositionLayers(true);
2806 root_clip
->AddChild(root_scroll
.Pass());
2807 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
2808 host_impl_
->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID
);
2809 host_impl_
->active_tree()->DidBecomeActive();
2810 host_impl_
->SetViewportSize(surface_size
);
2812 // Draw one frame and then immediately rebuild the layer tree to mimic a tree
2815 host_impl_
->active_tree()->DetachLayerTree();
2816 scoped_ptr
<LayerImpl
> root_clip2
=
2817 LayerImpl::Create(host_impl_
->active_tree(), 3);
2818 scoped_ptr
<LayerImpl
> root_scroll2
=
2819 CreateScrollableLayer(4, surface_size
, root_clip2
.get());
2820 root_scroll2
->SetIsContainerForFixedPositionLayers(true);
2821 root_clip2
->AddChild(root_scroll2
.Pass());
2822 host_impl_
->active_tree()->SetRootLayer(root_clip2
.Pass());
2823 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID
);
2824 host_impl_
->active_tree()->DidBecomeActive();
2826 // Scrolling should still work even though we did not draw yet.
2827 EXPECT_EQ(InputHandler::ScrollStarted
,
2828 host_impl_
->ScrollBegin(gfx::Point(5, 5),
2829 InputHandler::Wheel
));
2832 TEST_F(LayerTreeHostImplTest
, ScrollAxisAlignedRotatedLayer
) {
2833 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2835 // Rotate the root layer 90 degrees counter-clockwise about its center.
2836 gfx::Transform rotate_transform
;
2837 rotate_transform
.Rotate(-90.0);
2838 host_impl_
->active_tree()->root_layer()->SetTransform(rotate_transform
);
2840 gfx::Size
surface_size(50, 50);
2841 host_impl_
->SetViewportSize(surface_size
);
2844 // Scroll to the right in screen coordinates with a gesture.
2845 gfx::Vector2d
gesture_scroll_delta(10, 0);
2846 EXPECT_EQ(InputHandler::ScrollStarted
,
2847 host_impl_
->ScrollBegin(gfx::Point(),
2848 InputHandler::Gesture
));
2849 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2850 host_impl_
->ScrollEnd();
2852 // The layer should have scrolled down in its local coordinates.
2853 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2854 ExpectContains(*scroll_info
.get(),
2856 gfx::Vector2d(0, gesture_scroll_delta
.x()));
2858 // Reset and scroll down with the wheel.
2859 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2860 gfx::Vector2d
wheel_scroll_delta(0, 10);
2861 EXPECT_EQ(InputHandler::ScrollStarted
,
2862 host_impl_
->ScrollBegin(gfx::Point(),
2863 InputHandler::Wheel
));
2864 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
2865 host_impl_
->ScrollEnd();
2867 // The layer should have scrolled down in its local coordinates.
2868 scroll_info
= host_impl_
->ProcessScrollDeltas();
2869 ExpectContains(*scroll_info
.get(),
2871 wheel_scroll_delta
);
2874 TEST_F(LayerTreeHostImplTest
, ScrollNonAxisAlignedRotatedLayer
) {
2875 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
2876 int child_clip_layer_id
= 6;
2877 int child_layer_id
= 7;
2878 float child_layer_angle
= -20.f
;
2880 // Create a child layer that is rotated to a non-axis-aligned angle.
2881 scoped_ptr
<LayerImpl
> clip_layer
=
2882 LayerImpl::Create(host_impl_
->active_tree(), child_clip_layer_id
);
2883 scoped_ptr
<LayerImpl
> child
= CreateScrollableLayer(
2884 child_layer_id
, scroll_layer
->content_bounds(), clip_layer
.get());
2885 gfx::Transform rotate_transform
;
2886 rotate_transform
.Translate(-50.0, -50.0);
2887 rotate_transform
.Rotate(child_layer_angle
);
2888 rotate_transform
.Translate(50.0, 50.0);
2889 clip_layer
->SetTransform(rotate_transform
);
2891 // Only allow vertical scrolling.
2892 clip_layer
->SetBounds(
2893 gfx::Size(child
->bounds().width(), child
->bounds().height() / 2));
2894 // The rotation depends on the layer's transform origin, and the child layer
2895 // is a different size than the clip, so make sure the clip layer's origin
2896 // lines up over the child.
2897 clip_layer
->SetTransformOrigin(gfx::Point3F(
2898 clip_layer
->bounds().width() * 0.5f
, clip_layer
->bounds().height(), 0.f
));
2899 LayerImpl
* child_ptr
= child
.get();
2900 clip_layer
->AddChild(child
.Pass());
2901 scroll_layer
->AddChild(clip_layer
.Pass());
2903 gfx::Size
surface_size(50, 50);
2904 host_impl_
->SetViewportSize(surface_size
);
2907 // Scroll down in screen coordinates with a gesture.
2908 gfx::Vector2d
gesture_scroll_delta(0, 10);
2909 EXPECT_EQ(InputHandler::ScrollStarted
,
2910 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2911 InputHandler::Gesture
));
2912 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2913 host_impl_
->ScrollEnd();
2915 // The child layer should have scrolled down in its local coordinates an
2916 // amount proportional to the angle between it and the input scroll delta.
2917 gfx::Vector2d
expected_scroll_delta(
2919 gesture_scroll_delta
.y() *
2920 std::cos(MathUtil::Deg2Rad(child_layer_angle
)));
2921 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2922 host_impl_
->ProcessScrollDeltas();
2923 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2925 // The root scroll layer should not have scrolled, because the input delta
2926 // was close to the layer's axis of movement.
2927 EXPECT_EQ(scroll_info
->scrolls
.size(), 1u);
2930 // Now reset and scroll the same amount horizontally.
2931 child_ptr
->SetScrollDelta(gfx::Vector2dF());
2932 gfx::Vector2d
gesture_scroll_delta(10, 0);
2933 EXPECT_EQ(InputHandler::ScrollStarted
,
2934 host_impl_
->ScrollBegin(gfx::Point(1, 1),
2935 InputHandler::Gesture
));
2936 host_impl_
->ScrollBy(gfx::Point(), gesture_scroll_delta
);
2937 host_impl_
->ScrollEnd();
2939 // The child layer should have scrolled down in its local coordinates an
2940 // amount proportional to the angle between it and the input scroll delta.
2941 gfx::Vector2d
expected_scroll_delta(
2943 -gesture_scroll_delta
.x() *
2944 std::sin(MathUtil::Deg2Rad(child_layer_angle
)));
2945 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
2946 host_impl_
->ProcessScrollDeltas();
2947 ExpectContains(*scroll_info
.get(), child_layer_id
, expected_scroll_delta
);
2949 // The root scroll layer should have scrolled more, since the input scroll
2950 // delta was mostly orthogonal to the child layer's vertical scroll axis.
2951 gfx::Vector2d
expected_root_scroll_delta(
2952 gesture_scroll_delta
.x() *
2953 std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle
)), 2),
2955 ExpectContains(*scroll_info
.get(),
2957 expected_root_scroll_delta
);
2961 TEST_F(LayerTreeHostImplTest
, ScrollScaledLayer
) {
2962 LayerImpl
* scroll_layer
=
2963 SetupScrollAndContentsLayers(gfx::Size(100, 100));
2965 // Scale the layer to twice its normal size.
2967 gfx::Transform scale_transform
;
2968 scale_transform
.Scale(scale
, scale
);
2969 scroll_layer
->SetTransform(scale_transform
);
2971 gfx::Size
surface_size(50, 50);
2972 host_impl_
->SetViewportSize(surface_size
);
2975 // Scroll down in screen coordinates with a gesture.
2976 gfx::Vector2d
scroll_delta(0, 10);
2977 EXPECT_EQ(InputHandler::ScrollStarted
,
2978 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
2979 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
2980 host_impl_
->ScrollEnd();
2982 // The layer should have scrolled down in its local coordinates, but half the
2984 scoped_ptr
<ScrollAndScaleSet
> scroll_info
= host_impl_
->ProcessScrollDeltas();
2985 ExpectContains(*scroll_info
.get(),
2987 gfx::Vector2d(0, scroll_delta
.y() / scale
));
2989 // Reset and scroll down with the wheel.
2990 scroll_layer
->SetScrollDelta(gfx::Vector2dF());
2991 gfx::Vector2d
wheel_scroll_delta(0, 10);
2992 EXPECT_EQ(InputHandler::ScrollStarted
,
2993 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
2994 host_impl_
->ScrollBy(gfx::Point(), wheel_scroll_delta
);
2995 host_impl_
->ScrollEnd();
2997 // The scale should not have been applied to the scroll delta.
2998 scroll_info
= host_impl_
->ProcessScrollDeltas();
2999 ExpectContains(*scroll_info
.get(),
3001 wheel_scroll_delta
);
3004 class TestScrollOffsetDelegate
: public LayerScrollOffsetDelegate
{
3006 TestScrollOffsetDelegate()
3007 : page_scale_factor_(0.f
),
3008 min_page_scale_factor_(-1.f
),
3009 max_page_scale_factor_(-1.f
) {}
3011 virtual ~TestScrollOffsetDelegate() {}
3013 virtual gfx::Vector2dF
GetTotalScrollOffset() OVERRIDE
{
3014 return getter_return_value_
;
3017 virtual bool IsExternalFlingActive() const OVERRIDE
{ return false; }
3019 virtual void UpdateRootLayerState(const gfx::Vector2dF
& total_scroll_offset
,
3020 const gfx::Vector2dF
& max_scroll_offset
,
3021 const gfx::SizeF
& scrollable_size
,
3022 float page_scale_factor
,
3023 float min_page_scale_factor
,
3024 float max_page_scale_factor
) OVERRIDE
{
3025 DCHECK(total_scroll_offset
.x() <= max_scroll_offset
.x());
3026 DCHECK(total_scroll_offset
.y() <= max_scroll_offset
.y());
3027 last_set_scroll_offset_
= total_scroll_offset
;
3028 max_scroll_offset_
= max_scroll_offset
;
3029 scrollable_size_
= scrollable_size
;
3030 page_scale_factor_
= page_scale_factor
;
3031 min_page_scale_factor_
= min_page_scale_factor
;
3032 max_page_scale_factor_
= max_page_scale_factor
;
3035 gfx::Vector2dF
last_set_scroll_offset() {
3036 return last_set_scroll_offset_
;
3039 void set_getter_return_value(const gfx::Vector2dF
& value
) {
3040 getter_return_value_
= value
;
3043 gfx::Vector2dF
max_scroll_offset() const {
3044 return max_scroll_offset_
;
3047 gfx::SizeF
scrollable_size() const {
3048 return scrollable_size_
;
3051 float page_scale_factor() const {
3052 return page_scale_factor_
;
3055 float min_page_scale_factor() const {
3056 return min_page_scale_factor_
;
3059 float max_page_scale_factor() const {
3060 return max_page_scale_factor_
;
3064 gfx::Vector2dF last_set_scroll_offset_
;
3065 gfx::Vector2dF getter_return_value_
;
3066 gfx::Vector2dF max_scroll_offset_
;
3067 gfx::SizeF scrollable_size_
;
3068 float page_scale_factor_
;
3069 float min_page_scale_factor_
;
3070 float max_page_scale_factor_
;
3073 TEST_F(LayerTreeHostImplTest
, RootLayerScrollOffsetDelegation
) {
3074 TestScrollOffsetDelegate scroll_delegate
;
3075 host_impl_
->SetViewportSize(gfx::Size(10, 20));
3076 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 100));
3077 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3078 clip_layer
->SetBounds(gfx::Size(10, 20));
3080 // Setting the delegate results in the current scroll offset being set.
3081 gfx::Vector2dF
initial_scroll_delta(10.f
, 10.f
);
3082 scroll_layer
->SetScrollOffset(gfx::Vector2d());
3083 scroll_layer
->SetScrollDelta(initial_scroll_delta
);
3084 host_impl_
->SetRootLayerScrollOffsetDelegate(&scroll_delegate
);
3085 EXPECT_EQ(initial_scroll_delta
.ToString(),
3086 scroll_delegate
.last_set_scroll_offset().ToString());
3088 // Setting the delegate results in the scrollable_size, max_scroll_offset,
3089 // page_scale_factor and {min|max}_page_scale_factor being set.
3090 EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate
.scrollable_size());
3091 EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_delegate
.max_scroll_offset());
3092 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3093 EXPECT_EQ(0.f
, scroll_delegate
.min_page_scale_factor());
3094 EXPECT_EQ(0.f
, scroll_delegate
.max_page_scale_factor());
3096 // Updating page scale immediately updates the delegate.
3097 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(2.f
, 0.5f
, 4.f
);
3098 EXPECT_EQ(2.f
, scroll_delegate
.page_scale_factor());
3099 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3100 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3101 host_impl_
->active_tree()->SetPageScaleDelta(1.5f
);
3102 EXPECT_EQ(3.f
, scroll_delegate
.page_scale_factor());
3103 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3104 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3105 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3106 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3107 EXPECT_EQ(1.f
, scroll_delegate
.page_scale_factor());
3108 EXPECT_EQ(0.5f
, scroll_delegate
.min_page_scale_factor());
3109 EXPECT_EQ(4.f
, scroll_delegate
.max_page_scale_factor());
3111 // The pinch gesture doesn't put the delegate into a state where the scroll
3112 // offset is outside of the scroll range. (this is verified by DCHECKs in the
3114 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
);
3115 host_impl_
->PinchGestureBegin();
3116 host_impl_
->PinchGestureUpdate(2.f
, gfx::Point());
3117 host_impl_
->PinchGestureUpdate(.5f
, gfx::Point());
3118 host_impl_
->PinchGestureEnd();
3119 host_impl_
->ScrollEnd();
3121 // Scrolling should be relative to the offset as returned by the delegate.
3122 gfx::Vector2dF
scroll_delta(0.f
, 10.f
);
3123 gfx::Vector2dF
current_offset(7.f
, 8.f
);
3125 scroll_delegate
.set_getter_return_value(current_offset
);
3126 EXPECT_EQ(InputHandler::ScrollStarted
,
3127 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
3129 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3130 EXPECT_EQ(current_offset
+ scroll_delta
,
3131 scroll_delegate
.last_set_scroll_offset());
3133 current_offset
= gfx::Vector2dF(42.f
, 41.f
);
3134 scroll_delegate
.set_getter_return_value(current_offset
);
3135 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3136 EXPECT_EQ(current_offset
+ scroll_delta
,
3137 scroll_delegate
.last_set_scroll_offset());
3138 host_impl_
->ScrollEnd();
3139 scroll_delegate
.set_getter_return_value(gfx::Vector2dF());
3141 // Forces a full tree synchronization and ensures that the scroll delegate
3142 // sees the correct size of the new tree.
3143 gfx::Size
new_size(42, 24);
3144 host_impl_
->CreatePendingTree();
3145 CreateScrollAndContentsLayers(host_impl_
->pending_tree(), new_size
);
3146 host_impl_
->ActivatePendingTree();
3147 EXPECT_EQ(new_size
, scroll_delegate
.scrollable_size());
3149 // Un-setting the delegate should propagate the delegate's current offset to
3150 // the root scrollable layer.
3151 current_offset
= gfx::Vector2dF(13.f
, 12.f
);
3152 scroll_delegate
.set_getter_return_value(current_offset
);
3153 host_impl_
->SetRootLayerScrollOffsetDelegate(NULL
);
3155 EXPECT_EQ(current_offset
.ToString(),
3156 scroll_layer
->TotalScrollOffset().ToString());
3159 TEST_F(LayerTreeHostImplTest
, OverscrollRoot
) {
3160 SetupScrollAndContentsLayers(gfx::Size(100, 100));
3161 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3162 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3164 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3166 // In-bounds scrolling does not affect overscroll.
3167 EXPECT_EQ(InputHandler::ScrollStarted
,
3168 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3169 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3170 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3172 // Overscroll events are reflected immediately.
3173 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3174 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3176 // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3177 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3178 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3179 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3180 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3181 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3182 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3183 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3184 EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_
->accumulated_root_overscroll());
3185 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3186 EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_
->accumulated_root_overscroll());
3187 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3188 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3190 // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3191 // as no scroll occurs.
3192 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3193 EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_
->accumulated_root_overscroll());
3194 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3195 EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_
->accumulated_root_overscroll());
3196 // Overscroll resets on valid scroll.
3197 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3198 EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_
->accumulated_root_overscroll());
3199 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3200 EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_
->accumulated_root_overscroll());
3201 host_impl_
->ScrollEnd();
3205 TEST_F(LayerTreeHostImplTest
, OverscrollChildWithoutBubbling
) {
3206 // Scroll child layers beyond their maximum scroll range and make sure root
3207 // overscroll does not accumulate.
3208 gfx::Size
surface_size(10, 10);
3209 scoped_ptr
<LayerImpl
> root_clip
=
3210 LayerImpl::Create(host_impl_
->active_tree(), 4);
3211 scoped_ptr
<LayerImpl
> root
=
3212 CreateScrollableLayer(1, surface_size
, root_clip
.get());
3214 scoped_ptr
<LayerImpl
> grand_child
=
3215 CreateScrollableLayer(3, surface_size
, root_clip
.get());
3217 scoped_ptr
<LayerImpl
> child
=
3218 CreateScrollableLayer(2, surface_size
, root_clip
.get());
3219 LayerImpl
* grand_child_layer
= grand_child
.get();
3220 child
->AddChild(grand_child
.Pass());
3222 LayerImpl
* child_layer
= child
.get();
3223 root
->AddChild(child
.Pass());
3224 root_clip
->AddChild(root
.Pass());
3225 child_layer
->SetScrollOffset(gfx::Vector2d(0, 3));
3226 grand_child_layer
->SetScrollOffset(gfx::Vector2d(0, 2));
3227 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3228 host_impl_
->active_tree()->DidBecomeActive();
3229 host_impl_
->SetViewportSize(surface_size
);
3232 gfx::Vector2d
scroll_delta(0, -10);
3233 EXPECT_EQ(InputHandler::ScrollStarted
,
3234 host_impl_
->ScrollBegin(gfx::Point(),
3235 InputHandler::NonBubblingGesture
));
3236 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3237 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3238 host_impl_
->ScrollEnd();
3240 // The next time we scroll we should only scroll the parent, but overscroll
3241 // should still not reach the root layer.
3242 scroll_delta
= gfx::Vector2d(0, -30);
3243 EXPECT_EQ(InputHandler::ScrollStarted
,
3244 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3245 InputHandler::NonBubblingGesture
));
3246 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3247 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3248 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3249 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child_layer
);
3250 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3251 host_impl_
->ScrollEnd();
3253 // After scrolling the parent, another scroll on the opposite direction
3254 // should scroll the child.
3255 scroll_delta
= gfx::Vector2d(0, 70);
3256 EXPECT_EQ(InputHandler::ScrollStarted
,
3257 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3258 InputHandler::NonBubblingGesture
));
3259 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3260 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3261 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child_layer
);
3262 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3263 host_impl_
->ScrollEnd();
3267 TEST_F(LayerTreeHostImplTest
, OverscrollChildEventBubbling
) {
3268 // When we try to scroll a non-scrollable child layer, the scroll delta
3269 // should be applied to one of its ancestors if possible. Overscroll should
3270 // be reflected only when it has bubbled up to the root scrolling layer.
3271 gfx::Size
surface_size(10, 10);
3272 gfx::Size
content_size(20, 20);
3273 scoped_ptr
<LayerImpl
> root_clip
=
3274 LayerImpl::Create(host_impl_
->active_tree(), 3);
3275 scoped_ptr
<LayerImpl
> root
=
3276 CreateScrollableLayer(1, content_size
, root_clip
.get());
3277 root
->SetIsContainerForFixedPositionLayers(true);
3278 scoped_ptr
<LayerImpl
> child
=
3279 CreateScrollableLayer(2, content_size
, root_clip
.get());
3281 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3282 root
->AddChild(child
.Pass());
3283 root_clip
->AddChild(root
.Pass());
3285 host_impl_
->SetViewportSize(surface_size
);
3286 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3287 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3288 host_impl_
->active_tree()->DidBecomeActive();
3291 gfx::Vector2d
scroll_delta(0, 8);
3292 EXPECT_EQ(InputHandler::ScrollStarted
,
3293 host_impl_
->ScrollBegin(gfx::Point(5, 5),
3294 InputHandler::Wheel
));
3295 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3296 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3297 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3298 EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_
->accumulated_root_overscroll());
3299 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
3300 EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_
->accumulated_root_overscroll());
3301 host_impl_
->ScrollEnd();
3305 TEST_F(LayerTreeHostImplTest
, OverscrollAlways
) {
3306 LayerTreeSettings settings
;
3307 CreateHostImpl(settings
, CreateOutputSurface());
3309 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(50, 50));
3310 LayerImpl
* clip_layer
= scroll_layer
->parent()->parent();
3311 clip_layer
->SetBounds(gfx::Size(50, 50));
3312 host_impl_
->SetViewportSize(gfx::Size(50, 50));
3313 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(1.f
, 0.5f
, 4.f
);
3315 EXPECT_EQ(gfx::Vector2dF(), host_impl_
->accumulated_root_overscroll());
3317 // Even though the layer can't scroll the overscroll still happens.
3318 EXPECT_EQ(InputHandler::ScrollStarted
,
3319 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
3320 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3321 EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_
->accumulated_root_overscroll());
3324 TEST_F(LayerTreeHostImplTest
, NoOverscrollOnFractionalDeviceScale
) {
3325 gfx::Size
surface_size(980, 1439);
3326 gfx::Size
content_size(980, 1438);
3327 float device_scale_factor
= 1.5f
;
3328 scoped_ptr
<LayerImpl
> root_clip
=
3329 LayerImpl::Create(host_impl_
->active_tree(), 3);
3330 scoped_ptr
<LayerImpl
> root
=
3331 CreateScrollableLayer(1, content_size
, root_clip
.get());
3332 root
->SetIsContainerForFixedPositionLayers(true);
3333 scoped_ptr
<LayerImpl
> child
=
3334 CreateScrollableLayer(2, content_size
, root_clip
.get());
3335 root
->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
3336 host_impl_
->active_tree()->SetPageScaleFactorAndLimits(
3337 0.326531f
, 0.326531f
, 5.f
);
3338 host_impl_
->active_tree()->SetPageScaleDelta(1.f
);
3339 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3340 root
->AddChild(child
.Pass());
3341 root_clip
->AddChild(root
.Pass());
3343 host_impl_
->SetViewportSize(surface_size
);
3344 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
3345 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3346 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3347 host_impl_
->active_tree()->DidBecomeActive();
3350 // Horizontal & Vertical GlowEffect should not be applied when
3351 // content size is less then view port size. For Example Horizontal &
3352 // vertical GlowEffect should not be applied in about:blank page.
3353 EXPECT_EQ(InputHandler::ScrollStarted
,
3354 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3355 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
3356 EXPECT_EQ(gfx::Vector2dF().ToString(),
3357 host_impl_
->accumulated_root_overscroll().ToString());
3359 host_impl_
->ScrollEnd();
3363 TEST_F(LayerTreeHostImplTest
, NoOverscrollWhenNotAtEdge
) {
3364 gfx::Size
surface_size(100, 100);
3365 gfx::Size
content_size(200, 200);
3366 scoped_ptr
<LayerImpl
> root_clip
=
3367 LayerImpl::Create(host_impl_
->active_tree(), 3);
3368 scoped_ptr
<LayerImpl
> root
=
3369 CreateScrollableLayer(1, content_size
, root_clip
.get());
3370 root
->SetIsContainerForFixedPositionLayers(true);
3371 scoped_ptr
<LayerImpl
> child
=
3372 CreateScrollableLayer(2, content_size
, root_clip
.get());
3374 child
->SetScrollClipLayer(Layer::INVALID_ID
);
3375 root
->AddChild(child
.Pass());
3376 root_clip
->AddChild(root
.Pass());
3378 host_impl_
->SetViewportSize(surface_size
);
3379 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
3380 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
3381 host_impl_
->active_tree()->DidBecomeActive();
3384 // Edge glow effect should be applicable only upon reaching Edges
3385 // of the content. unnecessary glow effect calls shouldn't be
3386 // called while scrolling up without reaching the edge of the content.
3387 EXPECT_EQ(InputHandler::ScrollStarted
,
3388 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3389 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
3390 EXPECT_EQ(gfx::Vector2dF().ToString(),
3391 host_impl_
->accumulated_root_overscroll().ToString());
3392 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f
));
3393 EXPECT_EQ(gfx::Vector2dF().ToString(),
3394 host_impl_
->accumulated_root_overscroll().ToString());
3395 host_impl_
->ScrollEnd();
3396 // unusedrootDelta should be subtracted from applied delta so that
3397 // unwanted glow effect calls are not called.
3398 EXPECT_EQ(InputHandler::ScrollStarted
,
3399 host_impl_
->ScrollBegin(gfx::Point(0, 0),
3400 InputHandler::NonBubblingGesture
));
3401 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
3402 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
3403 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3404 host_impl_
->accumulated_root_overscroll().ToString());
3406 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f
, -0.01f
));
3407 EXPECT_EQ(gfx::Vector2dF(0.000000f
, 17.699997f
).ToString(),
3408 host_impl_
->accumulated_root_overscroll().ToString());
3409 host_impl_
->ScrollEnd();
3410 // TestCase to check kEpsilon, which prevents minute values to trigger
3411 // gloweffect without reaching edge.
3412 EXPECT_EQ(InputHandler::ScrollStarted
,
3413 host_impl_
->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel
));
3414 host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f
, 0.1f
));
3415 EXPECT_EQ(gfx::Vector2dF().ToString(),
3416 host_impl_
->accumulated_root_overscroll().ToString());
3417 host_impl_
->ScrollEnd();
3421 class BlendStateCheckLayer
: public LayerImpl
{
3423 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
,
3425 ResourceProvider
* resource_provider
) {
3426 return scoped_ptr
<LayerImpl
>(new BlendStateCheckLayer(tree_impl
,
3428 resource_provider
));
3431 virtual void AppendQuads(QuadSink
* quad_sink
,
3432 AppendQuadsData
* append_quads_data
) OVERRIDE
{
3433 quads_appended_
= true;
3435 gfx::Rect opaque_rect
;
3436 if (contents_opaque())
3437 opaque_rect
= quad_rect_
;
3439 opaque_rect
= opaque_content_rect_
;
3440 gfx::Rect visible_quad_rect
= quad_rect_
;
3442 SharedQuadState
* shared_quad_state
= quad_sink
->CreateSharedQuadState();
3443 PopulateSharedQuadState(shared_quad_state
);
3445 scoped_ptr
<TileDrawQuad
> test_blending_draw_quad
= TileDrawQuad::Create();
3446 test_blending_draw_quad
->SetNew(shared_quad_state
,
3451 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
3454 test_blending_draw_quad
->visible_rect
= quad_visible_rect_
;
3455 EXPECT_EQ(blend_
, test_blending_draw_quad
->ShouldDrawWithBlending());
3456 EXPECT_EQ(has_render_surface_
, !!render_surface());
3457 quad_sink
->Append(test_blending_draw_quad
.PassAs
<DrawQuad
>());
3460 void SetExpectation(bool blend
, bool has_render_surface
) {
3462 has_render_surface_
= has_render_surface
;
3463 quads_appended_
= false;
3466 bool quads_appended() const { return quads_appended_
; }
3468 void SetQuadRect(const gfx::Rect
& rect
) { quad_rect_
= rect
; }
3469 void SetQuadVisibleRect(const gfx::Rect
& rect
) { quad_visible_rect_
= rect
; }
3470 void SetOpaqueContentRect(const gfx::Rect
& rect
) {
3471 opaque_content_rect_
= rect
;
3475 BlendStateCheckLayer(LayerTreeImpl
* tree_impl
,
3477 ResourceProvider
* resource_provider
)
3478 : LayerImpl(tree_impl
, id
),
3480 has_render_surface_(false),
3481 quads_appended_(false),
3482 quad_rect_(5, 5, 5, 5),
3483 quad_visible_rect_(5, 5, 5, 5),
3484 resource_id_(resource_provider
->CreateResource(
3487 ResourceProvider::TextureUsageAny
,
3489 resource_provider
->AllocateForTesting(resource_id_
);
3490 SetBounds(gfx::Size(10, 10));
3491 SetContentBounds(gfx::Size(10, 10));
3492 SetDrawsContent(true);
3496 bool has_render_surface_
;
3497 bool quads_appended_
;
3498 gfx::Rect quad_rect_
;
3499 gfx::Rect opaque_content_rect_
;
3500 gfx::Rect quad_visible_rect_
;
3501 ResourceProvider::ResourceId resource_id_
;
3504 TEST_F(LayerTreeHostImplTest
, BlendingOffWhenDrawingOpaqueLayers
) {
3506 scoped_ptr
<LayerImpl
> root
=
3507 LayerImpl::Create(host_impl_
->active_tree(), 1);
3508 root
->SetBounds(gfx::Size(10, 10));
3509 root
->SetContentBounds(root
->bounds());
3510 root
->SetDrawsContent(false);
3511 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
3513 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
3516 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3518 host_impl_
->resource_provider()));
3519 BlendStateCheckLayer
* layer1
=
3520 static_cast<BlendStateCheckLayer
*>(root
->children()[0]);
3521 layer1
->SetPosition(gfx::PointF(2.f
, 2.f
));
3523 LayerTreeHostImpl::FrameData frame
;
3525 // Opaque layer, drawn without blending.
3526 layer1
->SetContentsOpaque(true);
3527 layer1
->SetExpectation(false, false);
3528 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3529 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3530 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3531 EXPECT_TRUE(layer1
->quads_appended());
3532 host_impl_
->DidDrawAllLayers(frame
);
3534 // Layer with translucent content and painting, so drawn with blending.
3535 layer1
->SetContentsOpaque(false);
3536 layer1
->SetExpectation(true, false);
3537 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3538 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3539 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3540 EXPECT_TRUE(layer1
->quads_appended());
3541 host_impl_
->DidDrawAllLayers(frame
);
3543 // Layer with translucent opacity, drawn with blending.
3544 layer1
->SetContentsOpaque(true);
3545 layer1
->SetOpacity(0.5f
);
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 and painting, 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
);
3564 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3566 host_impl_
->resource_provider()));
3567 BlendStateCheckLayer
* layer2
=
3568 static_cast<BlendStateCheckLayer
*>(layer1
->children()[0]);
3569 layer2
->SetPosition(gfx::PointF(4.f
, 4.f
));
3571 // 2 opaque layers, drawn without blending.
3572 layer1
->SetContentsOpaque(true);
3573 layer1
->SetOpacity(1.f
);
3574 layer1
->SetExpectation(false, false);
3575 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3576 layer2
->SetContentsOpaque(true);
3577 layer2
->SetOpacity(1.f
);
3578 layer2
->SetExpectation(false, false);
3579 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3580 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3581 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3582 EXPECT_TRUE(layer1
->quads_appended());
3583 EXPECT_TRUE(layer2
->quads_appended());
3584 host_impl_
->DidDrawAllLayers(frame
);
3586 // Parent layer with translucent content, drawn with blending.
3587 // Child layer with opaque content, drawn without blending.
3588 layer1
->SetContentsOpaque(false);
3589 layer1
->SetExpectation(true, false);
3590 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3591 layer2
->SetExpectation(false, false);
3592 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3593 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3594 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3595 EXPECT_TRUE(layer1
->quads_appended());
3596 EXPECT_TRUE(layer2
->quads_appended());
3597 host_impl_
->DidDrawAllLayers(frame
);
3599 // Parent layer with translucent content but opaque painting, drawn without
3601 // Child layer with opaque content, drawn without blending.
3602 layer1
->SetContentsOpaque(true);
3603 layer1
->SetExpectation(false, false);
3604 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3605 layer2
->SetExpectation(false, false);
3606 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3607 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3608 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3609 EXPECT_TRUE(layer1
->quads_appended());
3610 EXPECT_TRUE(layer2
->quads_appended());
3611 host_impl_
->DidDrawAllLayers(frame
);
3613 // Parent layer with translucent opacity and opaque content. Since it has a
3614 // drawing child, it's drawn to a render surface which carries the opacity,
3615 // so it's itself drawn without blending.
3616 // Child layer with opaque content, drawn without blending (parent surface
3617 // carries the inherited opacity).
3618 layer1
->SetContentsOpaque(true);
3619 layer1
->SetOpacity(0.5f
);
3620 layer1
->SetExpectation(false, true);
3621 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3622 layer2
->SetExpectation(false, false);
3623 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3624 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3625 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3626 EXPECT_TRUE(layer1
->quads_appended());
3627 EXPECT_TRUE(layer2
->quads_appended());
3628 host_impl_
->DidDrawAllLayers(frame
);
3630 // Draw again, but with child non-opaque, to make sure
3631 // layer1 not culled.
3632 layer1
->SetContentsOpaque(true);
3633 layer1
->SetOpacity(1.f
);
3634 layer1
->SetExpectation(false, false);
3635 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3636 layer2
->SetContentsOpaque(true);
3637 layer2
->SetOpacity(0.5f
);
3638 layer2
->SetExpectation(true, false);
3639 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3640 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3641 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3642 EXPECT_TRUE(layer1
->quads_appended());
3643 EXPECT_TRUE(layer2
->quads_appended());
3644 host_impl_
->DidDrawAllLayers(frame
);
3646 // A second way of making the child non-opaque.
3647 layer1
->SetContentsOpaque(true);
3648 layer1
->SetOpacity(1.f
);
3649 layer1
->SetExpectation(false, false);
3650 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3651 layer2
->SetContentsOpaque(false);
3652 layer2
->SetOpacity(1.f
);
3653 layer2
->SetExpectation(true, false);
3654 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3655 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3656 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3657 EXPECT_TRUE(layer1
->quads_appended());
3658 EXPECT_TRUE(layer2
->quads_appended());
3659 host_impl_
->DidDrawAllLayers(frame
);
3661 // And when the layer says its not opaque but is painted opaque, it is not
3663 layer1
->SetContentsOpaque(true);
3664 layer1
->SetOpacity(1.f
);
3665 layer1
->SetExpectation(false, false);
3666 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3667 layer2
->SetContentsOpaque(true);
3668 layer2
->SetOpacity(1.f
);
3669 layer2
->SetExpectation(false, false);
3670 layer2
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3671 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3672 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3673 EXPECT_TRUE(layer1
->quads_appended());
3674 EXPECT_TRUE(layer2
->quads_appended());
3675 host_impl_
->DidDrawAllLayers(frame
);
3677 // Layer with partially opaque contents, drawn with blending.
3678 layer1
->SetContentsOpaque(false);
3679 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3680 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
3681 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3682 layer1
->SetExpectation(true, false);
3683 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3684 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3685 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3686 EXPECT_TRUE(layer1
->quads_appended());
3687 host_impl_
->DidDrawAllLayers(frame
);
3689 // Layer with partially opaque contents partially culled, drawn with blending.
3690 layer1
->SetContentsOpaque(false);
3691 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3692 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
3693 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3694 layer1
->SetExpectation(true, false);
3695 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3696 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3697 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3698 EXPECT_TRUE(layer1
->quads_appended());
3699 host_impl_
->DidDrawAllLayers(frame
);
3701 // Layer with partially opaque contents culled, drawn with blending.
3702 layer1
->SetContentsOpaque(false);
3703 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3704 layer1
->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
3705 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3706 layer1
->SetExpectation(true, false);
3707 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3708 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3709 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3710 EXPECT_TRUE(layer1
->quads_appended());
3711 host_impl_
->DidDrawAllLayers(frame
);
3713 // Layer with partially opaque contents and translucent contents culled, drawn
3714 // without blending.
3715 layer1
->SetContentsOpaque(false);
3716 layer1
->SetQuadRect(gfx::Rect(5, 5, 5, 5));
3717 layer1
->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
3718 layer1
->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
3719 layer1
->SetExpectation(false, false);
3720 layer1
->SetUpdateRect(gfx::RectF(layer1
->content_bounds()));
3721 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3722 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
3723 EXPECT_TRUE(layer1
->quads_appended());
3724 host_impl_
->DidDrawAllLayers(frame
);
3727 class LayerTreeHostImplViewportCoveredTest
: public LayerTreeHostImplTest
{
3729 LayerTreeHostImplViewportCoveredTest() :
3730 gutter_quad_material_(DrawQuad::SOLID_COLOR
),
3732 did_activate_pending_tree_(false) {}
3734 scoped_ptr
<OutputSurface
> CreateFakeOutputSurface(bool always_draw
) {
3736 return FakeOutputSurface::CreateAlwaysDrawAndSwap3d()
3737 .PassAs
<OutputSurface
>();
3739 return FakeOutputSurface::Create3d().PassAs
<OutputSurface
>();
3742 void SetupActiveTreeLayers() {
3743 host_impl_
->active_tree()->set_background_color(SK_ColorGRAY
);
3744 host_impl_
->active_tree()->SetRootLayer(
3745 LayerImpl::Create(host_impl_
->active_tree(), 1));
3746 host_impl_
->active_tree()->root_layer()->AddChild(
3747 BlendStateCheckLayer::Create(host_impl_
->active_tree(),
3749 host_impl_
->resource_provider()));
3750 child_
= static_cast<BlendStateCheckLayer
*>(
3751 host_impl_
->active_tree()->root_layer()->children()[0]);
3752 child_
->SetExpectation(false, false);
3753 child_
->SetContentsOpaque(true);
3756 // Expect no gutter rects.
3757 void TestLayerCoversFullViewport() {
3758 gfx::Rect
layer_rect(viewport_size_
);
3759 child_
->SetPosition(layer_rect
.origin());
3760 child_
->SetBounds(layer_rect
.size());
3761 child_
->SetContentBounds(layer_rect
.size());
3762 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3763 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3765 LayerTreeHostImpl::FrameData frame
;
3766 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3767 ASSERT_EQ(1u, frame
.render_passes
.size());
3769 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3770 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3771 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3773 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3774 host_impl_
->DidDrawAllLayers(frame
);
3777 // Expect fullscreen gutter rect.
3778 void TestEmptyLayer() {
3779 gfx::Rect
layer_rect(0, 0, 0, 0);
3780 child_
->SetPosition(layer_rect
.origin());
3781 child_
->SetBounds(layer_rect
.size());
3782 child_
->SetContentBounds(layer_rect
.size());
3783 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3784 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3786 LayerTreeHostImpl::FrameData frame
;
3787 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3788 ASSERT_EQ(1u, frame
.render_passes
.size());
3790 EXPECT_EQ(1u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3791 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3792 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3794 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3795 host_impl_
->DidDrawAllLayers(frame
);
3798 // Expect four surrounding gutter rects.
3799 void TestLayerInMiddleOfViewport() {
3800 gfx::Rect
layer_rect(500, 500, 200, 200);
3801 child_
->SetPosition(layer_rect
.origin());
3802 child_
->SetBounds(layer_rect
.size());
3803 child_
->SetContentBounds(layer_rect
.size());
3804 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3805 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3807 LayerTreeHostImpl::FrameData frame
;
3808 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3809 ASSERT_EQ(1u, frame
.render_passes
.size());
3811 EXPECT_EQ(4u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3812 EXPECT_EQ(5u, frame
.render_passes
[0]->quad_list
.size());
3813 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3815 VerifyQuadsExactlyCoverViewport(frame
.render_passes
[0]->quad_list
);
3816 host_impl_
->DidDrawAllLayers(frame
);
3819 // Expect no gutter rects.
3820 void TestLayerIsLargerThanViewport() {
3821 gfx::Rect
layer_rect(viewport_size_
.width() + 10,
3822 viewport_size_
.height() + 10);
3823 child_
->SetPosition(layer_rect
.origin());
3824 child_
->SetBounds(layer_rect
.size());
3825 child_
->SetContentBounds(layer_rect
.size());
3826 child_
->SetQuadRect(gfx::Rect(layer_rect
.size()));
3827 child_
->SetQuadVisibleRect(gfx::Rect(layer_rect
.size()));
3829 LayerTreeHostImpl::FrameData frame
;
3830 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
3831 ASSERT_EQ(1u, frame
.render_passes
.size());
3833 EXPECT_EQ(0u, CountGutterQuads(frame
.render_passes
[0]->quad_list
));
3834 EXPECT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
3835 ValidateTextureDrawQuads(frame
.render_passes
[0]->quad_list
);
3837 host_impl_
->DidDrawAllLayers(frame
);
3840 virtual void DidActivatePendingTree() OVERRIDE
{
3841 did_activate_pending_tree_
= true;
3844 void set_gutter_quad_material(DrawQuad::Material material
) {
3845 gutter_quad_material_
= material
;
3847 void set_gutter_texture_size(const gfx::Size
& gutter_texture_size
) {
3848 gutter_texture_size_
= gutter_texture_size
;
3852 size_t CountGutterQuads(const QuadList
& quad_list
) {
3853 size_t num_gutter_quads
= 0;
3854 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3855 num_gutter_quads
+= (quad_list
[i
]->material
==
3856 gutter_quad_material_
) ? 1 : 0;
3858 return num_gutter_quads
;
3861 void VerifyQuadsExactlyCoverViewport(const QuadList
& quad_list
) {
3862 LayerTestCommon::VerifyQuadsExactlyCoverRect(
3863 quad_list
, gfx::Rect(DipSizeToPixelSize(viewport_size_
)));
3866 // Make sure that the texture coordinates match their expectations.
3867 void ValidateTextureDrawQuads(const QuadList
& quad_list
) {
3868 for (size_t i
= 0; i
< quad_list
.size(); ++i
) {
3869 if (quad_list
[i
]->material
!= DrawQuad::TEXTURE_CONTENT
)
3871 const TextureDrawQuad
* quad
= TextureDrawQuad::MaterialCast(quad_list
[i
]);
3872 gfx::SizeF gutter_texture_size_pixels
= gfx::ScaleSize(
3873 gutter_texture_size_
, host_impl_
->device_scale_factor());
3874 EXPECT_EQ(quad
->uv_top_left
.x(),
3875 quad
->rect
.x() / gutter_texture_size_pixels
.width());
3876 EXPECT_EQ(quad
->uv_top_left
.y(),
3877 quad
->rect
.y() / gutter_texture_size_pixels
.height());
3878 EXPECT_EQ(quad
->uv_bottom_right
.x(),
3879 quad
->rect
.right() / gutter_texture_size_pixels
.width());
3880 EXPECT_EQ(quad
->uv_bottom_right
.y(),
3881 quad
->rect
.bottom() / gutter_texture_size_pixels
.height());
3885 gfx::Size
DipSizeToPixelSize(const gfx::Size
& size
) {
3886 return gfx::ToRoundedSize(
3887 gfx::ScaleSize(size
, host_impl_
->device_scale_factor()));
3890 DrawQuad::Material gutter_quad_material_
;
3891 gfx::Size gutter_texture_size_
;
3892 gfx::Size viewport_size_
;
3893 BlendStateCheckLayer
* child_
;
3894 bool did_activate_pending_tree_
;
3897 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCovered
) {
3898 viewport_size_
= gfx::Size(1000, 1000);
3900 bool always_draw
= false;
3901 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3903 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3904 SetupActiveTreeLayers();
3905 TestLayerCoversFullViewport();
3907 TestLayerInMiddleOfViewport();
3908 TestLayerIsLargerThanViewport();
3911 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredScaled
) {
3912 viewport_size_
= gfx::Size(1000, 1000);
3914 bool always_draw
= false;
3915 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3917 host_impl_
->SetDeviceScaleFactor(2.f
);
3918 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3919 SetupActiveTreeLayers();
3920 TestLayerCoversFullViewport();
3922 TestLayerInMiddleOfViewport();
3923 TestLayerIsLargerThanViewport();
3926 TEST_F(LayerTreeHostImplViewportCoveredTest
, ViewportCoveredOverhangBitmap
) {
3927 viewport_size_
= gfx::Size(1000, 1000);
3929 bool always_draw
= false;
3930 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3932 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3933 SetupActiveTreeLayers();
3935 // Specify an overhang bitmap to use.
3936 bool is_opaque
= false;
3937 UIResourceBitmap
ui_resource_bitmap(gfx::Size(2, 2), is_opaque
);
3938 ui_resource_bitmap
.SetWrapMode(UIResourceBitmap::REPEAT
);
3939 UIResourceId ui_resource_id
= 12345;
3940 host_impl_
->CreateUIResource(ui_resource_id
, ui_resource_bitmap
);
3941 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(32, 32));
3942 set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT
);
3943 set_gutter_texture_size(gfx::Size(32, 32));
3945 TestLayerCoversFullViewport();
3947 TestLayerInMiddleOfViewport();
3948 TestLayerIsLargerThanViewport();
3950 // Change the resource size.
3951 host_impl_
->SetOverhangUIResource(ui_resource_id
, gfx::Size(128, 16));
3952 set_gutter_texture_size(gfx::Size(128, 16));
3954 TestLayerCoversFullViewport();
3956 TestLayerInMiddleOfViewport();
3957 TestLayerIsLargerThanViewport();
3959 // Change the device scale factor
3960 host_impl_
->SetDeviceScaleFactor(2.f
);
3961 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3963 TestLayerCoversFullViewport();
3965 TestLayerInMiddleOfViewport();
3966 TestLayerIsLargerThanViewport();
3969 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeGrowViewportInvalid
) {
3970 viewport_size_
= gfx::Size(1000, 1000);
3972 bool always_draw
= true;
3973 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3975 // Pending tree to force active_tree size invalid. Not used otherwise.
3976 host_impl_
->CreatePendingTree();
3977 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
3978 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
3980 SetupActiveTreeLayers();
3982 TestLayerInMiddleOfViewport();
3983 TestLayerIsLargerThanViewport();
3986 TEST_F(LayerTreeHostImplViewportCoveredTest
, ActiveTreeShrinkViewportInvalid
) {
3987 viewport_size_
= gfx::Size(1000, 1000);
3989 bool always_draw
= true;
3990 CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw
));
3992 // Set larger viewport and activate it to active tree.
3993 host_impl_
->CreatePendingTree();
3994 gfx::Size
larger_viewport(viewport_size_
.width() + 100,
3995 viewport_size_
.height() + 100);
3996 host_impl_
->SetViewportSize(DipSizeToPixelSize(larger_viewport
));
3997 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
3998 host_impl_
->ActivatePendingTree();
3999 EXPECT_TRUE(did_activate_pending_tree_
);
4000 EXPECT_FALSE(host_impl_
->active_tree()->ViewportSizeInvalid());
4002 // Shrink pending tree viewport without activating.
4003 host_impl_
->CreatePendingTree();
4004 host_impl_
->SetViewportSize(DipSizeToPixelSize(viewport_size_
));
4005 EXPECT_TRUE(host_impl_
->active_tree()->ViewportSizeInvalid());
4007 SetupActiveTreeLayers();
4009 TestLayerInMiddleOfViewport();
4010 TestLayerIsLargerThanViewport();
4013 class FakeDrawableLayerImpl
: public LayerImpl
{
4015 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4016 return scoped_ptr
<LayerImpl
>(new FakeDrawableLayerImpl(tree_impl
, id
));
4019 FakeDrawableLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4020 : LayerImpl(tree_impl
, id
) {}
4023 // Only reshape when we know we are going to draw. Otherwise, the reshape
4024 // can leave the window at the wrong size if we never draw and the proper
4025 // viewport size is never set.
4026 TEST_F(LayerTreeHostImplTest
, ReshapeNotCalledUntilDraw
) {
4027 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4028 scoped_ptr
<OutputSurface
> output_surface(
4029 FakeOutputSurface::Create3d(provider
));
4030 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4032 scoped_ptr
<LayerImpl
> root
=
4033 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4034 root
->SetBounds(gfx::Size(10, 10));
4035 root
->SetContentBounds(gfx::Size(10, 10));
4036 root
->SetDrawsContent(true);
4037 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4038 EXPECT_FALSE(provider
->TestContext3d()->reshape_called());
4039 provider
->TestContext3d()->clear_reshape_called();
4041 LayerTreeHostImpl::FrameData frame
;
4042 host_impl_
->SetViewportSize(gfx::Size(10, 10));
4043 host_impl_
->SetDeviceScaleFactor(1.f
);
4044 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4045 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4046 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4047 EXPECT_EQ(provider
->TestContext3d()->width(), 10);
4048 EXPECT_EQ(provider
->TestContext3d()->height(), 10);
4049 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4050 host_impl_
->DidDrawAllLayers(frame
);
4051 provider
->TestContext3d()->clear_reshape_called();
4053 host_impl_
->SetViewportSize(gfx::Size(20, 30));
4054 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4055 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4056 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4057 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4058 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4059 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 1.f
);
4060 host_impl_
->DidDrawAllLayers(frame
);
4061 provider
->TestContext3d()->clear_reshape_called();
4063 host_impl_
->SetDeviceScaleFactor(2.f
);
4064 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4065 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4066 EXPECT_TRUE(provider
->TestContext3d()->reshape_called());
4067 EXPECT_EQ(provider
->TestContext3d()->width(), 20);
4068 EXPECT_EQ(provider
->TestContext3d()->height(), 30);
4069 EXPECT_EQ(provider
->TestContext3d()->scale_factor(), 2.f
);
4070 host_impl_
->DidDrawAllLayers(frame
);
4071 provider
->TestContext3d()->clear_reshape_called();
4074 // Make sure damage tracking propagates all the way to the graphics context,
4075 // where it should request to swap only the sub-buffer that is damaged.
4076 TEST_F(LayerTreeHostImplTest
, PartialSwapReceivesDamageRect
) {
4077 scoped_refptr
<TestContextProvider
> context_provider(
4078 TestContextProvider::Create());
4079 context_provider
->BindToCurrentThread();
4080 context_provider
->TestContext3d()->set_have_post_sub_buffer(true);
4082 scoped_ptr
<OutputSurface
> output_surface(
4083 FakeOutputSurface::Create3d(context_provider
));
4085 // This test creates its own LayerTreeHostImpl, so
4086 // that we can force partial swap enabled.
4087 LayerTreeSettings settings
;
4088 settings
.partial_swap_enabled
= true;
4089 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4090 new TestSharedBitmapManager());
4091 scoped_ptr
<LayerTreeHostImpl
> layer_tree_host_impl
=
4092 LayerTreeHostImpl::Create(settings
,
4095 &stats_instrumentation_
,
4096 shared_bitmap_manager
.get(),
4098 layer_tree_host_impl
->InitializeRenderer(output_surface
.Pass());
4099 layer_tree_host_impl
->SetViewportSize(gfx::Size(500, 500));
4101 scoped_ptr
<LayerImpl
> root
=
4102 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 1);
4103 scoped_ptr
<LayerImpl
> child
=
4104 FakeDrawableLayerImpl::Create(layer_tree_host_impl
->active_tree(), 2);
4105 child
->SetPosition(gfx::PointF(12.f
, 13.f
));
4106 child
->SetBounds(gfx::Size(14, 15));
4107 child
->SetContentBounds(gfx::Size(14, 15));
4108 child
->SetDrawsContent(true);
4109 root
->SetBounds(gfx::Size(500, 500));
4110 root
->SetContentBounds(gfx::Size(500, 500));
4111 root
->SetDrawsContent(true);
4112 root
->AddChild(child
.Pass());
4113 layer_tree_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4115 LayerTreeHostImpl::FrameData frame
;
4117 // First frame, the entire screen should get swapped.
4118 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4119 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4120 layer_tree_host_impl
->DidDrawAllLayers(frame
);
4121 layer_tree_host_impl
->SwapBuffers(frame
);
4122 EXPECT_EQ(TestContextSupport::SWAP
,
4123 context_provider
->support()->last_swap_type());
4125 // Second frame, only the damaged area should get swapped. Damage should be
4126 // the union of old and new child rects.
4127 // expected damage rect: gfx::Rect(26, 28);
4128 // expected swap rect: vertically flipped, with origin at bottom left corner.
4129 layer_tree_host_impl
->active_tree()->root_layer()->children()[0]->SetPosition(
4131 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4132 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4133 host_impl_
->DidDrawAllLayers(frame
);
4134 layer_tree_host_impl
->SwapBuffers(frame
);
4136 // Make sure that partial swap is constrained to the viewport dimensions
4137 // expected damage rect: gfx::Rect(500, 500);
4138 // expected swap rect: flipped damage rect, but also clamped to viewport
4139 EXPECT_EQ(TestContextSupport::PARTIAL_SWAP
,
4140 context_provider
->support()->last_swap_type());
4141 gfx::Rect
expected_swap_rect(0, 500-28, 26, 28);
4142 EXPECT_EQ(expected_swap_rect
.ToString(),
4143 context_provider
->support()->
4144 last_partial_swap_rect().ToString());
4146 layer_tree_host_impl
->SetViewportSize(gfx::Size(10, 10));
4147 // This will damage everything.
4148 layer_tree_host_impl
->active_tree()->root_layer()->SetBackgroundColor(
4150 EXPECT_EQ(DRAW_SUCCESS
, layer_tree_host_impl
->PrepareToDraw(&frame
));
4151 layer_tree_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4152 host_impl_
->DidDrawAllLayers(frame
);
4153 layer_tree_host_impl
->SwapBuffers(frame
);
4155 EXPECT_EQ(TestContextSupport::SWAP
,
4156 context_provider
->support()->last_swap_type());
4159 TEST_F(LayerTreeHostImplTest
, RootLayerDoesntCreateExtraSurface
) {
4160 scoped_ptr
<LayerImpl
> root
=
4161 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 1);
4162 scoped_ptr
<LayerImpl
> child
=
4163 FakeDrawableLayerImpl::Create(host_impl_
->active_tree(), 2);
4164 child
->SetBounds(gfx::Size(10, 10));
4165 child
->SetContentBounds(gfx::Size(10, 10));
4166 child
->SetDrawsContent(true);
4167 root
->SetBounds(gfx::Size(10, 10));
4168 root
->SetContentBounds(gfx::Size(10, 10));
4169 root
->SetDrawsContent(true);
4170 root
->SetForceRenderSurface(true);
4171 root
->AddChild(child
.Pass());
4173 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
4175 LayerTreeHostImpl::FrameData frame
;
4177 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4178 EXPECT_EQ(1u, frame
.render_surface_layer_list
->size());
4179 EXPECT_EQ(1u, frame
.render_passes
.size());
4180 host_impl_
->DidDrawAllLayers(frame
);
4183 class FakeLayerWithQuads
: public LayerImpl
{
4185 static scoped_ptr
<LayerImpl
> Create(LayerTreeImpl
* tree_impl
, int id
) {
4186 return scoped_ptr
<LayerImpl
>(new FakeLayerWithQuads(tree_impl
, id
));
4189 virtual void AppendQuads(QuadSink
* quad_sink
,
4190 AppendQuadsData
* append_quads_data
) OVERRIDE
{
4191 SharedQuadState
* shared_quad_state
= quad_sink
->CreateSharedQuadState();
4192 PopulateSharedQuadState(shared_quad_state
);
4194 SkColor gray
= SkColorSetRGB(100, 100, 100);
4195 gfx::Rect
quad_rect(content_bounds());
4196 gfx::Rect
visible_quad_rect(quad_rect
);
4197 scoped_ptr
<SolidColorDrawQuad
> my_quad
= SolidColorDrawQuad::Create();
4199 shared_quad_state
, quad_rect
, visible_quad_rect
, gray
, false);
4200 quad_sink
->Append(my_quad
.PassAs
<DrawQuad
>());
4204 FakeLayerWithQuads(LayerTreeImpl
* tree_impl
, int id
)
4205 : LayerImpl(tree_impl
, id
) {}
4208 class MockContext
: public TestWebGraphicsContext3D
{
4210 MOCK_METHOD1(useProgram
, void(GLuint program
));
4211 MOCK_METHOD5(uniform4f
, void(GLint location
,
4216 MOCK_METHOD4(uniformMatrix4fv
, void(GLint location
,
4218 GLboolean transpose
,
4219 const GLfloat
* value
));
4220 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4224 MOCK_METHOD1(enable
, void(GLenum cap
));
4225 MOCK_METHOD1(disable
, void(GLenum cap
));
4226 MOCK_METHOD4(scissor
, void(GLint x
,
4232 class MockContextHarness
{
4234 MockContext
* context_
;
4237 explicit MockContextHarness(MockContext
* context
)
4238 : context_(context
) {
4239 context_
->set_have_post_sub_buffer(true);
4241 // Catch "uninteresting" calls
4242 EXPECT_CALL(*context_
, useProgram(_
))
4245 EXPECT_CALL(*context_
, drawElements(_
, _
, _
, _
))
4248 // These are not asserted
4249 EXPECT_CALL(*context_
, uniformMatrix4fv(_
, _
, _
, _
))
4250 .WillRepeatedly(Return());
4252 EXPECT_CALL(*context_
, uniform4f(_
, _
, _
, _
, _
))
4253 .WillRepeatedly(Return());
4255 // Any un-sanctioned calls to enable() are OK
4256 EXPECT_CALL(*context_
, enable(_
))
4257 .WillRepeatedly(Return());
4259 // Any un-sanctioned calls to disable() are OK
4260 EXPECT_CALL(*context_
, disable(_
))
4261 .WillRepeatedly(Return());
4264 void MustDrawSolidQuad() {
4265 EXPECT_CALL(*context_
, drawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, 0))
4267 .RetiresOnSaturation();
4269 EXPECT_CALL(*context_
, useProgram(_
))
4271 .RetiresOnSaturation();
4274 void MustSetScissor(int x
, int y
, int width
, int height
) {
4275 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4276 .WillRepeatedly(Return());
4278 EXPECT_CALL(*context_
, scissor(x
, y
, width
, height
))
4280 .WillRepeatedly(Return());
4283 void MustSetNoScissor() {
4284 EXPECT_CALL(*context_
, disable(GL_SCISSOR_TEST
))
4285 .WillRepeatedly(Return());
4287 EXPECT_CALL(*context_
, enable(GL_SCISSOR_TEST
))
4290 EXPECT_CALL(*context_
, scissor(_
, _
, _
, _
))
4295 TEST_F(LayerTreeHostImplTest
, NoPartialSwap
) {
4296 scoped_ptr
<MockContext
> mock_context_owned(new MockContext
);
4297 MockContext
* mock_context
= mock_context_owned
.get();
4299 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4300 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4301 MockContextHarness
harness(mock_context
);
4304 LayerTreeSettings settings
= DefaultSettings();
4305 settings
.partial_swap_enabled
= false;
4306 CreateHostImpl(settings
, output_surface
.Pass());
4307 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4309 // Without partial swap, and no clipping, no scissor is set.
4310 harness
.MustDrawSolidQuad();
4311 harness
.MustSetNoScissor();
4313 LayerTreeHostImpl::FrameData frame
;
4314 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4315 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4316 host_impl_
->DidDrawAllLayers(frame
);
4318 Mock::VerifyAndClearExpectations(&mock_context
);
4320 // Without partial swap, but a layer does clip its subtree, one scissor is
4322 host_impl_
->active_tree()->root_layer()->SetMasksToBounds(true);
4323 harness
.MustDrawSolidQuad();
4324 harness
.MustSetScissor(0, 0, 10, 10);
4326 LayerTreeHostImpl::FrameData frame
;
4327 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4328 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4329 host_impl_
->DidDrawAllLayers(frame
);
4331 Mock::VerifyAndClearExpectations(&mock_context
);
4334 TEST_F(LayerTreeHostImplTest
, PartialSwap
) {
4335 scoped_ptr
<MockContext
> context_owned(new MockContext
);
4336 MockContext
* mock_context
= context_owned
.get();
4337 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4338 context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4339 MockContextHarness
harness(mock_context
);
4341 LayerTreeSettings settings
= DefaultSettings();
4342 settings
.partial_swap_enabled
= true;
4343 CreateHostImpl(settings
, output_surface
.Pass());
4344 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
4346 // The first frame is not a partially-swapped one.
4347 harness
.MustSetScissor(0, 0, 10, 10);
4348 harness
.MustDrawSolidQuad();
4350 LayerTreeHostImpl::FrameData frame
;
4351 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4352 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4353 host_impl_
->DidDrawAllLayers(frame
);
4355 Mock::VerifyAndClearExpectations(&mock_context
);
4357 // Damage a portion of the frame.
4358 host_impl_
->active_tree()->root_layer()->SetUpdateRect(
4359 gfx::Rect(0, 0, 2, 3));
4361 // The second frame will be partially-swapped (the y coordinates are flipped).
4362 harness
.MustSetScissor(0, 7, 2, 3);
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
);
4373 static scoped_ptr
<LayerTreeHostImpl
> SetupLayersForOpacity(
4375 LayerTreeHostImplClient
* client
,
4377 SharedBitmapManager
* manager
,
4378 RenderingStatsInstrumentation
* stats_instrumentation
) {
4379 scoped_refptr
<TestContextProvider
> provider(TestContextProvider::Create());
4380 scoped_ptr
<OutputSurface
> output_surface(
4381 FakeOutputSurface::Create3d(provider
));
4382 provider
->BindToCurrentThread();
4383 provider
->TestContext3d()->set_have_post_sub_buffer(true);
4385 LayerTreeSettings settings
;
4386 settings
.partial_swap_enabled
= partial_swap
;
4387 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
= LayerTreeHostImpl::Create(
4388 settings
, client
, proxy
, stats_instrumentation
, manager
, 0);
4389 my_host_impl
->InitializeRenderer(output_surface
.Pass());
4390 my_host_impl
->SetViewportSize(gfx::Size(100, 100));
4393 Layers are created as follows:
4395 +--------------------+
4399 | | +-------------------+
4401 | | +-------------------+
4406 +--------------------+
4408 Layers 1, 2 have render surfaces
4410 scoped_ptr
<LayerImpl
> root
=
4411 LayerImpl::Create(my_host_impl
->active_tree(), 1);
4412 scoped_ptr
<LayerImpl
> child
=
4413 LayerImpl::Create(my_host_impl
->active_tree(), 2);
4414 scoped_ptr
<LayerImpl
> grand_child
=
4415 FakeLayerWithQuads::Create(my_host_impl
->active_tree(), 3);
4417 gfx::Rect
root_rect(0, 0, 100, 100);
4418 gfx::Rect
child_rect(10, 10, 50, 50);
4419 gfx::Rect
grand_child_rect(5, 5, 150, 150);
4421 root
->CreateRenderSurface();
4422 root
->SetPosition(root_rect
.origin());
4423 root
->SetBounds(root_rect
.size());
4424 root
->SetContentBounds(root
->bounds());
4425 root
->draw_properties().visible_content_rect
= root_rect
;
4426 root
->SetDrawsContent(false);
4427 root
->render_surface()->SetContentRect(gfx::Rect(root_rect
.size()));
4429 child
->SetPosition(gfx::PointF(child_rect
.x(), child_rect
.y()));
4430 child
->SetOpacity(0.5f
);
4431 child
->SetBounds(gfx::Size(child_rect
.width(), child_rect
.height()));
4432 child
->SetContentBounds(child
->bounds());
4433 child
->draw_properties().visible_content_rect
= child_rect
;
4434 child
->SetDrawsContent(false);
4435 child
->SetForceRenderSurface(true);
4437 grand_child
->SetPosition(grand_child_rect
.origin());
4438 grand_child
->SetBounds(grand_child_rect
.size());
4439 grand_child
->SetContentBounds(grand_child
->bounds());
4440 grand_child
->draw_properties().visible_content_rect
= grand_child_rect
;
4441 grand_child
->SetDrawsContent(true);
4443 child
->AddChild(grand_child
.Pass());
4444 root
->AddChild(child
.Pass());
4446 my_host_impl
->active_tree()->SetRootLayer(root
.Pass());
4447 return my_host_impl
.Pass();
4450 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorPartialSwap
) {
4451 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4452 new TestSharedBitmapManager());
4453 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4454 SetupLayersForOpacity(true,
4457 shared_bitmap_manager
.get(),
4458 &stats_instrumentation_
);
4460 LayerTreeHostImpl::FrameData frame
;
4461 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4463 // Verify all quads have been computed
4464 ASSERT_EQ(2U, frame
.render_passes
.size());
4465 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4466 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4467 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4468 frame
.render_passes
[0]->quad_list
[0]->material
);
4469 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4470 frame
.render_passes
[1]->quad_list
[0]->material
);
4472 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4473 my_host_impl
->DidDrawAllLayers(frame
);
4477 TEST_F(LayerTreeHostImplTest
, ContributingLayerEmptyScissorNoPartialSwap
) {
4478 scoped_ptr
<SharedBitmapManager
> shared_bitmap_manager(
4479 new TestSharedBitmapManager());
4480 scoped_ptr
<LayerTreeHostImpl
> my_host_impl
=
4481 SetupLayersForOpacity(false,
4484 shared_bitmap_manager
.get(),
4485 &stats_instrumentation_
);
4487 LayerTreeHostImpl::FrameData frame
;
4488 EXPECT_EQ(DRAW_SUCCESS
, my_host_impl
->PrepareToDraw(&frame
));
4490 // Verify all quads have been computed
4491 ASSERT_EQ(2U, frame
.render_passes
.size());
4492 ASSERT_EQ(1U, frame
.render_passes
[0]->quad_list
.size());
4493 ASSERT_EQ(1U, frame
.render_passes
[1]->quad_list
.size());
4494 EXPECT_EQ(DrawQuad::SOLID_COLOR
,
4495 frame
.render_passes
[0]->quad_list
[0]->material
);
4496 EXPECT_EQ(DrawQuad::RENDER_PASS
,
4497 frame
.render_passes
[1]->quad_list
[0]->material
);
4499 my_host_impl
->DrawLayers(&frame
, gfx::FrameTime::Now());
4500 my_host_impl
->DidDrawAllLayers(frame
);
4504 TEST_F(LayerTreeHostImplTest
, LayersFreeTextures
) {
4505 scoped_ptr
<TestWebGraphicsContext3D
> context
=
4506 TestWebGraphicsContext3D::Create();
4507 TestWebGraphicsContext3D
* context3d
= context
.get();
4508 scoped_ptr
<OutputSurface
> output_surface(
4509 FakeOutputSurface::Create3d(context
.Pass()));
4510 CreateHostImpl(DefaultSettings(), output_surface
.Pass());
4512 scoped_ptr
<LayerImpl
> root_layer
=
4513 LayerImpl::Create(host_impl_
->active_tree(), 1);
4514 root_layer
->SetBounds(gfx::Size(10, 10));
4516 scoped_refptr
<VideoFrame
> softwareFrame
=
4517 media::VideoFrame::CreateColorFrame(
4518 gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
4519 FakeVideoFrameProvider provider
;
4520 provider
.set_frame(softwareFrame
);
4521 scoped_ptr
<VideoLayerImpl
> video_layer
=
4522 VideoLayerImpl::Create(host_impl_
->active_tree(), 4, &provider
);
4523 video_layer
->SetBounds(gfx::Size(10, 10));
4524 video_layer
->SetContentBounds(gfx::Size(10, 10));
4525 video_layer
->SetDrawsContent(true);
4526 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
4528 scoped_ptr
<IOSurfaceLayerImpl
> io_surface_layer
=
4529 IOSurfaceLayerImpl::Create(host_impl_
->active_tree(), 5);
4530 io_surface_layer
->SetBounds(gfx::Size(10, 10));
4531 io_surface_layer
->SetContentBounds(gfx::Size(10, 10));
4532 io_surface_layer
->SetDrawsContent(true);
4533 io_surface_layer
->SetIOSurfaceProperties(1, gfx::Size(10, 10));
4534 root_layer
->AddChild(io_surface_layer
.PassAs
<LayerImpl
>());
4536 host_impl_
->active_tree()->SetRootLayer(root_layer
.Pass());
4538 EXPECT_EQ(0u, context3d
->NumTextures());
4540 LayerTreeHostImpl::FrameData frame
;
4541 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4542 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4543 host_impl_
->DidDrawAllLayers(frame
);
4544 host_impl_
->SwapBuffers(frame
);
4546 EXPECT_GT(context3d
->NumTextures(), 0u);
4548 // Kill the layer tree.
4549 host_impl_
->active_tree()->SetRootLayer(
4550 LayerImpl::Create(host_impl_
->active_tree(), 100));
4551 // There should be no textures left in use after.
4552 EXPECT_EQ(0u, context3d
->NumTextures());
4555 class MockDrawQuadsToFillScreenContext
: public TestWebGraphicsContext3D
{
4557 MOCK_METHOD1(useProgram
, void(GLuint program
));
4558 MOCK_METHOD4(drawElements
, void(GLenum mode
,
4564 TEST_F(LayerTreeHostImplTest
, HasTransparentBackground
) {
4565 scoped_ptr
<MockDrawQuadsToFillScreenContext
> mock_context_owned(
4566 new MockDrawQuadsToFillScreenContext
);
4567 MockDrawQuadsToFillScreenContext
* mock_context
= mock_context_owned
.get();
4569 scoped_ptr
<OutputSurface
> output_surface(FakeOutputSurface::Create3d(
4570 mock_context_owned
.PassAs
<TestWebGraphicsContext3D
>()));
4573 LayerTreeSettings settings
= DefaultSettings();
4574 settings
.partial_swap_enabled
= false;
4575 CreateHostImpl(settings
, output_surface
.Pass());
4576 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
4577 host_impl_
->active_tree()->set_background_color(SK_ColorWHITE
);
4579 // Verify one quad is drawn when transparent background set is not set.
4580 host_impl_
->active_tree()->set_has_transparent_background(false);
4581 EXPECT_CALL(*mock_context
, useProgram(_
))
4583 EXPECT_CALL(*mock_context
, drawElements(_
, _
, _
, _
))
4585 LayerTreeHostImpl::FrameData frame
;
4586 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4587 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4588 host_impl_
->DidDrawAllLayers(frame
);
4589 Mock::VerifyAndClearExpectations(&mock_context
);
4591 // Verify no quads are drawn when transparent background is set.
4592 host_impl_
->active_tree()->set_has_transparent_background(true);
4593 host_impl_
->SetFullRootLayerDamage();
4594 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4595 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4596 host_impl_
->DidDrawAllLayers(frame
);
4597 Mock::VerifyAndClearExpectations(&mock_context
);
4600 TEST_F(LayerTreeHostImplTest
, ReleaseContentsTextureShouldTriggerCommit
) {
4601 set_reduce_memory_result(false);
4603 // If changing the memory limit wouldn't result in changing what was
4604 // committed, then no commit should be requested.
4605 set_reduce_memory_result(false);
4606 host_impl_
->set_max_memory_needed_bytes(
4607 host_impl_
->memory_allocation_limit_bytes() - 1);
4608 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4609 host_impl_
->memory_allocation_limit_bytes() - 1));
4610 EXPECT_FALSE(did_request_commit_
);
4611 did_request_commit_
= false;
4613 // If changing the memory limit would result in changing what was
4614 // committed, then a commit should be requested, even though nothing was
4616 set_reduce_memory_result(false);
4617 host_impl_
->set_max_memory_needed_bytes(
4618 host_impl_
->memory_allocation_limit_bytes());
4619 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4620 host_impl_
->memory_allocation_limit_bytes() - 1));
4621 EXPECT_TRUE(did_request_commit_
);
4622 did_request_commit_
= false;
4624 // Especially if changing the memory limit caused evictions, we need
4626 set_reduce_memory_result(true);
4627 host_impl_
->set_max_memory_needed_bytes(1);
4628 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4629 host_impl_
->memory_allocation_limit_bytes() - 1));
4630 EXPECT_TRUE(did_request_commit_
);
4631 did_request_commit_
= false;
4633 // But if we set it to the same value that it was before, we shouldn't
4635 host_impl_
->SetMemoryPolicy(ManagedMemoryPolicy(
4636 host_impl_
->memory_allocation_limit_bytes()));
4637 EXPECT_FALSE(did_request_commit_
);
4640 class LayerTreeHostImplTestWithDelegatingRenderer
4641 : public LayerTreeHostImplTest
{
4643 virtual scoped_ptr
<OutputSurface
> CreateOutputSurface() OVERRIDE
{
4644 return FakeOutputSurface::CreateDelegating3d().PassAs
<OutputSurface
>();
4647 void DrawFrameAndTestDamage(const gfx::RectF
& expected_damage
) {
4648 bool expect_to_draw
= !expected_damage
.IsEmpty();
4650 LayerTreeHostImpl::FrameData frame
;
4651 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4653 if (!expect_to_draw
) {
4654 // With no damage, we don't draw, and no quads are created.
4655 ASSERT_EQ(0u, frame
.render_passes
.size());
4657 ASSERT_EQ(1u, frame
.render_passes
.size());
4659 // Verify the damage rect for the root render pass.
4660 const RenderPass
* root_render_pass
= frame
.render_passes
.back();
4661 EXPECT_RECT_EQ(expected_damage
, root_render_pass
->damage_rect
);
4663 // Verify the root and child layers' quads are generated and not being
4665 ASSERT_EQ(2u, root_render_pass
->quad_list
.size());
4667 LayerImpl
* child
= host_impl_
->active_tree()->root_layer()->children()[0];
4668 gfx::RectF
expected_child_visible_rect(child
->content_bounds());
4669 EXPECT_RECT_EQ(expected_child_visible_rect
,
4670 root_render_pass
->quad_list
[0]->visible_rect
);
4672 LayerImpl
* root
= host_impl_
->active_tree()->root_layer();
4673 gfx::RectF
expected_root_visible_rect(root
->content_bounds());
4674 EXPECT_RECT_EQ(expected_root_visible_rect
,
4675 root_render_pass
->quad_list
[1]->visible_rect
);
4678 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4679 host_impl_
->DidDrawAllLayers(frame
);
4680 EXPECT_EQ(expect_to_draw
, host_impl_
->SwapBuffers(frame
));
4684 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, FrameIncludesDamageRect
) {
4685 scoped_ptr
<SolidColorLayerImpl
> root
=
4686 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
4687 root
->SetPosition(gfx::PointF());
4688 root
->SetBounds(gfx::Size(10, 10));
4689 root
->SetContentBounds(gfx::Size(10, 10));
4690 root
->SetDrawsContent(true);
4692 // Child layer is in the bottom right corner.
4693 scoped_ptr
<SolidColorLayerImpl
> child
=
4694 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 2);
4695 child
->SetPosition(gfx::PointF(9.f
, 9.f
));
4696 child
->SetBounds(gfx::Size(1, 1));
4697 child
->SetContentBounds(gfx::Size(1, 1));
4698 child
->SetDrawsContent(true);
4699 root
->AddChild(child
.PassAs
<LayerImpl
>());
4701 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
4703 // Draw a frame. In the first frame, the entire viewport should be damaged.
4704 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
4705 DrawFrameAndTestDamage(full_frame_damage
);
4707 // The second frame has damage that doesn't touch the child layer. Its quads
4708 // should still be generated.
4709 gfx::Rect small_damage
= gfx::Rect(0, 0, 1, 1);
4710 host_impl_
->active_tree()->root_layer()->SetUpdateRect(small_damage
);
4711 DrawFrameAndTestDamage(small_damage
);
4713 // The third frame should have no damage, so no quads should be generated.
4714 gfx::Rect no_damage
;
4715 DrawFrameAndTestDamage(no_damage
);
4718 // TODO(reveman): Remove this test and the ability to prevent on demand raster
4719 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
4720 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer
, PreventRasterizeOnDemand
) {
4721 LayerTreeSettings settings
;
4722 CreateHostImpl(settings
, CreateOutputSurface());
4723 EXPECT_FALSE(host_impl_
->GetRendererCapabilities().allow_rasterize_on_demand
);
4726 class FakeMaskLayerImpl
: public LayerImpl
{
4728 static scoped_ptr
<FakeMaskLayerImpl
> Create(LayerTreeImpl
* tree_impl
,
4730 return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl
, id
));
4733 virtual ResourceProvider::ResourceId
ContentsResourceId() const OVERRIDE
{
4738 FakeMaskLayerImpl(LayerTreeImpl
* tree_impl
, int id
)
4739 : LayerImpl(tree_impl
, id
) {}
4742 TEST_F(LayerTreeHostImplTest
, MaskLayerWithScaling
) {
4743 LayerTreeSettings settings
;
4744 settings
.layer_transforms_should_scale_layer_contents
= true;
4745 CreateHostImpl(settings
, CreateOutputSurface());
4749 // +-- Scaling Layer (adds a 2x scale)
4751 // +-- Content Layer
4753 scoped_ptr
<LayerImpl
> scoped_root
=
4754 LayerImpl::Create(host_impl_
->active_tree(), 1);
4755 LayerImpl
* root
= scoped_root
.get();
4756 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4758 scoped_ptr
<LayerImpl
> scoped_scaling_layer
=
4759 LayerImpl::Create(host_impl_
->active_tree(), 2);
4760 LayerImpl
* scaling_layer
= scoped_scaling_layer
.get();
4761 root
->AddChild(scoped_scaling_layer
.Pass());
4763 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4764 LayerImpl::Create(host_impl_
->active_tree(), 3);
4765 LayerImpl
* content_layer
= scoped_content_layer
.get();
4766 scaling_layer
->AddChild(scoped_content_layer
.Pass());
4768 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4769 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4770 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4771 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4773 gfx::Size
root_size(100, 100);
4774 root
->SetBounds(root_size
);
4775 root
->SetContentBounds(root_size
);
4776 root
->SetPosition(gfx::PointF());
4778 gfx::Size
scaling_layer_size(50, 50);
4779 scaling_layer
->SetBounds(scaling_layer_size
);
4780 scaling_layer
->SetContentBounds(scaling_layer_size
);
4781 scaling_layer
->SetPosition(gfx::PointF());
4782 gfx::Transform scale
;
4783 scale
.Scale(2.f
, 2.f
);
4784 scaling_layer
->SetTransform(scale
);
4786 content_layer
->SetBounds(scaling_layer_size
);
4787 content_layer
->SetContentBounds(scaling_layer_size
);
4788 content_layer
->SetPosition(gfx::PointF());
4789 content_layer
->SetDrawsContent(true);
4791 mask_layer
->SetBounds(scaling_layer_size
);
4792 mask_layer
->SetContentBounds(scaling_layer_size
);
4793 mask_layer
->SetPosition(gfx::PointF());
4794 mask_layer
->SetDrawsContent(true);
4797 // Check that the tree scaling is correctly taken into account for the mask,
4798 // that should fully map onto the quad.
4799 float device_scale_factor
= 1.f
;
4800 host_impl_
->SetViewportSize(root_size
);
4801 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4803 LayerTreeHostImpl::FrameData frame
;
4804 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4806 ASSERT_EQ(1u, frame
.render_passes
.size());
4807 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4808 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4809 frame
.render_passes
[0]->quad_list
[0]->material
);
4810 const RenderPassDrawQuad
* render_pass_quad
=
4811 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4812 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4813 render_pass_quad
->rect
.ToString());
4814 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4815 render_pass_quad
->mask_uv_rect
.ToString());
4817 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4818 host_impl_
->DidDrawAllLayers(frame
);
4822 // Applying a DSF should change the render surface size, but won't affect
4823 // which part of the mask is used.
4824 device_scale_factor
= 2.f
;
4825 gfx::Size device_viewport
=
4826 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4827 host_impl_
->SetViewportSize(device_viewport
);
4828 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4829 host_impl_
->active_tree()->set_needs_update_draw_properties();
4831 LayerTreeHostImpl::FrameData frame
;
4832 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4834 ASSERT_EQ(1u, frame
.render_passes
.size());
4835 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4836 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4837 frame
.render_passes
[0]->quad_list
[0]->material
);
4838 const RenderPassDrawQuad
* render_pass_quad
=
4839 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4840 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4841 render_pass_quad
->rect
.ToString());
4842 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4843 render_pass_quad
->mask_uv_rect
.ToString());
4845 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4846 host_impl_
->DidDrawAllLayers(frame
);
4850 // Applying an equivalent content scale on the content layer and the mask
4851 // should still result in the same part of the mask being used.
4852 gfx::Size content_bounds
=
4853 gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size
,
4854 device_scale_factor
));
4855 content_layer
->SetContentBounds(content_bounds
);
4856 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4857 mask_layer
->SetContentBounds(content_bounds
);
4858 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4859 host_impl_
->active_tree()->set_needs_update_draw_properties();
4861 LayerTreeHostImpl::FrameData frame
;
4862 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4864 ASSERT_EQ(1u, frame
.render_passes
.size());
4865 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4866 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4867 frame
.render_passes
[0]->quad_list
[0]->material
);
4868 const RenderPassDrawQuad
* render_pass_quad
=
4869 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4870 EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
4871 render_pass_quad
->rect
.ToString());
4872 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4873 render_pass_quad
->mask_uv_rect
.ToString());
4875 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4876 host_impl_
->DidDrawAllLayers(frame
);
4880 TEST_F(LayerTreeHostImplTest
, MaskLayerWithDifferentBounds
) {
4881 // The mask layer has bounds 100x100 but is attached to a layer with bounds
4884 scoped_ptr
<LayerImpl
> scoped_root
=
4885 LayerImpl::Create(host_impl_
->active_tree(), 1);
4886 LayerImpl
* root
= scoped_root
.get();
4887 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
4889 scoped_ptr
<LayerImpl
> scoped_content_layer
=
4890 LayerImpl::Create(host_impl_
->active_tree(), 3);
4891 LayerImpl
* content_layer
= scoped_content_layer
.get();
4892 root
->AddChild(scoped_content_layer
.Pass());
4894 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
4895 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
4896 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
4897 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
4899 gfx::Size
root_size(100, 100);
4900 root
->SetBounds(root_size
);
4901 root
->SetContentBounds(root_size
);
4902 root
->SetPosition(gfx::PointF());
4904 gfx::Size
layer_size(50, 50);
4905 content_layer
->SetBounds(layer_size
);
4906 content_layer
->SetContentBounds(layer_size
);
4907 content_layer
->SetPosition(gfx::PointF());
4908 content_layer
->SetDrawsContent(true);
4910 gfx::Size
mask_size(100, 100);
4911 mask_layer
->SetBounds(mask_size
);
4912 mask_layer
->SetContentBounds(mask_size
);
4913 mask_layer
->SetPosition(gfx::PointF());
4914 mask_layer
->SetDrawsContent(true);
4916 // Check that the mask fills the surface.
4917 float device_scale_factor
= 1.f
;
4918 host_impl_
->SetViewportSize(root_size
);
4919 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4921 LayerTreeHostImpl::FrameData frame
;
4922 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4924 ASSERT_EQ(1u, frame
.render_passes
.size());
4925 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4926 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4927 frame
.render_passes
[0]->quad_list
[0]->material
);
4928 const RenderPassDrawQuad
* render_pass_quad
=
4929 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4930 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
4931 render_pass_quad
->rect
.ToString());
4932 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4933 render_pass_quad
->mask_uv_rect
.ToString());
4935 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4936 host_impl_
->DidDrawAllLayers(frame
);
4939 // Applying a DSF should change the render surface size, but won't affect
4940 // which part of the mask is used.
4941 device_scale_factor
= 2.f
;
4942 gfx::Size device_viewport
=
4943 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
4944 host_impl_
->SetViewportSize(device_viewport
);
4945 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
4946 host_impl_
->active_tree()->set_needs_update_draw_properties();
4948 LayerTreeHostImpl::FrameData frame
;
4949 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
4951 ASSERT_EQ(1u, frame
.render_passes
.size());
4952 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
4953 ASSERT_EQ(DrawQuad::RENDER_PASS
,
4954 frame
.render_passes
[0]->quad_list
[0]->material
);
4955 const RenderPassDrawQuad
* render_pass_quad
=
4956 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
4957 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
4958 render_pass_quad
->rect
.ToString());
4959 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
4960 render_pass_quad
->mask_uv_rect
.ToString());
4962 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
4963 host_impl_
->DidDrawAllLayers(frame
);
4966 // Applying an equivalent content scale on the content layer and the mask
4967 // should still result in the same part of the mask being used.
4968 gfx::Size layer_size_large
=
4969 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
4970 content_layer
->SetContentBounds(layer_size_large
);
4971 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
4972 gfx::Size mask_size_large
=
4973 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
4974 mask_layer
->SetContentBounds(mask_size_large
);
4975 mask_layer
->SetContentsScale(device_scale_factor
, 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 a different contents scale to the mask layer means it will have
4997 // a larger texture, but it should use the same tex coords to cover the
4999 mask_layer
->SetContentBounds(mask_size
);
5000 mask_layer
->SetContentsScale(1.f
, 1.f
);
5001 host_impl_
->active_tree()->set_needs_update_draw_properties();
5003 LayerTreeHostImpl::FrameData frame
;
5004 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5006 ASSERT_EQ(1u, frame
.render_passes
.size());
5007 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5008 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5009 frame
.render_passes
[0]->quad_list
[0]->material
);
5010 const RenderPassDrawQuad
* render_pass_quad
=
5011 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5012 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5013 render_pass_quad
->rect
.ToString());
5014 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5015 render_pass_quad
->mask_uv_rect
.ToString());
5017 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5018 host_impl_
->DidDrawAllLayers(frame
);
5022 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerWithDifferentBounds
) {
5023 // The replica's mask layer has bounds 100x100 but the replica is of a
5024 // layer with bounds 50x50.
5026 scoped_ptr
<LayerImpl
> scoped_root
=
5027 LayerImpl::Create(host_impl_
->active_tree(), 1);
5028 LayerImpl
* root
= scoped_root
.get();
5029 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5031 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5032 LayerImpl::Create(host_impl_
->active_tree(), 3);
5033 LayerImpl
* content_layer
= scoped_content_layer
.get();
5034 root
->AddChild(scoped_content_layer
.Pass());
5036 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5037 LayerImpl::Create(host_impl_
->active_tree(), 2);
5038 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5039 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5041 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5042 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 4);
5043 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5044 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5046 gfx::Size
root_size(100, 100);
5047 root
->SetBounds(root_size
);
5048 root
->SetContentBounds(root_size
);
5049 root
->SetPosition(gfx::PointF());
5051 gfx::Size
layer_size(50, 50);
5052 content_layer
->SetBounds(layer_size
);
5053 content_layer
->SetContentBounds(layer_size
);
5054 content_layer
->SetPosition(gfx::PointF());
5055 content_layer
->SetDrawsContent(true);
5057 gfx::Size
mask_size(100, 100);
5058 mask_layer
->SetBounds(mask_size
);
5059 mask_layer
->SetContentBounds(mask_size
);
5060 mask_layer
->SetPosition(gfx::PointF());
5061 mask_layer
->SetDrawsContent(true);
5063 // Check that the mask fills the surface.
5064 float device_scale_factor
= 1.f
;
5065 host_impl_
->SetViewportSize(root_size
);
5066 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5068 LayerTreeHostImpl::FrameData frame
;
5069 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5071 ASSERT_EQ(1u, frame
.render_passes
.size());
5072 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5073 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5074 frame
.render_passes
[0]->quad_list
[1]->material
);
5075 const RenderPassDrawQuad
* replica_quad
=
5076 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5077 EXPECT_TRUE(replica_quad
->is_replica
);
5078 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5079 replica_quad
->rect
.ToString());
5080 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5081 replica_quad
->mask_uv_rect
.ToString());
5083 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5084 host_impl_
->DidDrawAllLayers(frame
);
5087 // Applying a DSF should change the render surface size, but won't affect
5088 // which part of the mask is used.
5089 device_scale_factor
= 2.f
;
5090 gfx::Size device_viewport
=
5091 gfx::ToFlooredSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5092 host_impl_
->SetViewportSize(device_viewport
);
5093 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5094 host_impl_
->active_tree()->set_needs_update_draw_properties();
5096 LayerTreeHostImpl::FrameData frame
;
5097 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5099 ASSERT_EQ(1u, frame
.render_passes
.size());
5100 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5101 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5102 frame
.render_passes
[0]->quad_list
[1]->material
);
5103 const RenderPassDrawQuad
* replica_quad
=
5104 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5105 EXPECT_TRUE(replica_quad
->is_replica
);
5106 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5107 replica_quad
->rect
.ToString());
5108 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5109 replica_quad
->mask_uv_rect
.ToString());
5111 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5112 host_impl_
->DidDrawAllLayers(frame
);
5115 // Applying an equivalent content scale on the content layer and the mask
5116 // should still result in the same part of the mask being used.
5117 gfx::Size layer_size_large
=
5118 gfx::ToRoundedSize(gfx::ScaleSize(layer_size
, device_scale_factor
));
5119 content_layer
->SetContentBounds(layer_size_large
);
5120 content_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5121 gfx::Size mask_size_large
=
5122 gfx::ToRoundedSize(gfx::ScaleSize(mask_size
, device_scale_factor
));
5123 mask_layer
->SetContentBounds(mask_size_large
);
5124 mask_layer
->SetContentsScale(device_scale_factor
, device_scale_factor
);
5125 host_impl_
->active_tree()->set_needs_update_draw_properties();
5127 LayerTreeHostImpl::FrameData frame
;
5128 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5130 ASSERT_EQ(1u, frame
.render_passes
.size());
5131 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5132 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5133 frame
.render_passes
[0]->quad_list
[1]->material
);
5134 const RenderPassDrawQuad
* replica_quad
=
5135 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5136 EXPECT_TRUE(replica_quad
->is_replica
);
5137 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5138 replica_quad
->rect
.ToString());
5139 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5140 replica_quad
->mask_uv_rect
.ToString());
5142 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5143 host_impl_
->DidDrawAllLayers(frame
);
5146 // Applying a different contents scale to the mask layer means it will have
5147 // a larger texture, but it should use the same tex coords to cover the
5149 mask_layer
->SetContentBounds(mask_size
);
5150 mask_layer
->SetContentsScale(1.f
, 1.f
);
5151 host_impl_
->active_tree()->set_needs_update_draw_properties();
5153 LayerTreeHostImpl::FrameData frame
;
5154 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5156 ASSERT_EQ(1u, frame
.render_passes
.size());
5157 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5158 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5159 frame
.render_passes
[0]->quad_list
[1]->material
);
5160 const RenderPassDrawQuad
* replica_quad
=
5161 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5162 EXPECT_TRUE(replica_quad
->is_replica
);
5163 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5164 replica_quad
->rect
.ToString());
5165 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
).ToString(),
5166 replica_quad
->mask_uv_rect
.ToString());
5168 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5169 host_impl_
->DidDrawAllLayers(frame
);
5173 TEST_F(LayerTreeHostImplTest
, ReflectionMaskLayerForSurfaceWithUnclippedChild
) {
5174 // The replica is of a layer with bounds 50x50, but it has a child that causes
5175 // the surface bounds to be larger.
5177 scoped_ptr
<LayerImpl
> scoped_root
=
5178 LayerImpl::Create(host_impl_
->active_tree(), 1);
5179 LayerImpl
* root
= scoped_root
.get();
5180 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5182 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5183 LayerImpl::Create(host_impl_
->active_tree(), 2);
5184 LayerImpl
* content_layer
= scoped_content_layer
.get();
5185 root
->AddChild(scoped_content_layer
.Pass());
5187 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5188 LayerImpl::Create(host_impl_
->active_tree(), 3);
5189 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5190 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5192 scoped_ptr
<LayerImpl
> scoped_replica_layer
=
5193 LayerImpl::Create(host_impl_
->active_tree(), 4);
5194 LayerImpl
* replica_layer
= scoped_replica_layer
.get();
5195 content_layer
->SetReplicaLayer(scoped_replica_layer
.Pass());
5197 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5198 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 5);
5199 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5200 replica_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5202 gfx::Size
root_size(100, 100);
5203 root
->SetBounds(root_size
);
5204 root
->SetContentBounds(root_size
);
5205 root
->SetPosition(gfx::PointF());
5207 gfx::Size
layer_size(50, 50);
5208 content_layer
->SetBounds(layer_size
);
5209 content_layer
->SetContentBounds(layer_size
);
5210 content_layer
->SetPosition(gfx::PointF());
5211 content_layer
->SetDrawsContent(true);
5213 gfx::Size
child_size(50, 50);
5214 content_child_layer
->SetBounds(child_size
);
5215 content_child_layer
->SetContentBounds(child_size
);
5216 content_child_layer
->SetPosition(gfx::Point(50, 0));
5217 content_child_layer
->SetDrawsContent(true);
5219 gfx::Size
mask_size(50, 50);
5220 mask_layer
->SetBounds(mask_size
);
5221 mask_layer
->SetContentBounds(mask_size
);
5222 mask_layer
->SetPosition(gfx::PointF());
5223 mask_layer
->SetDrawsContent(true);
5225 float device_scale_factor
= 1.f
;
5226 host_impl_
->SetViewportSize(root_size
);
5227 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5229 LayerTreeHostImpl::FrameData frame
;
5230 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5232 ASSERT_EQ(1u, frame
.render_passes
.size());
5233 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5235 // The surface is 100x50.
5236 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5237 frame
.render_passes
[0]->quad_list
[0]->material
);
5238 const RenderPassDrawQuad
* render_pass_quad
=
5239 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5240 EXPECT_FALSE(render_pass_quad
->is_replica
);
5241 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5242 render_pass_quad
->rect
.ToString());
5244 // The mask covers the owning layer only.
5245 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5246 frame
.render_passes
[0]->quad_list
[1]->material
);
5247 const RenderPassDrawQuad
* replica_quad
=
5248 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5249 EXPECT_TRUE(replica_quad
->is_replica
);
5250 EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5251 replica_quad
->rect
.ToString());
5252 EXPECT_EQ(gfx::RectF(0.f
, 0.f
, 2.f
, 1.f
).ToString(),
5253 replica_quad
->mask_uv_rect
.ToString());
5255 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5256 host_impl_
->DidDrawAllLayers(frame
);
5259 // Move the child to (-50, 0) instead. Now the mask should be moved to still
5260 // cover the layer being replicated.
5261 content_child_layer
->SetPosition(gfx::Point(-50, 0));
5263 LayerTreeHostImpl::FrameData frame
;
5264 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5266 ASSERT_EQ(1u, frame
.render_passes
.size());
5267 ASSERT_EQ(2u, frame
.render_passes
[0]->quad_list
.size());
5269 // The surface is 100x50 with its origin at (-50, 0).
5270 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5271 frame
.render_passes
[0]->quad_list
[0]->material
);
5272 const RenderPassDrawQuad
* render_pass_quad
=
5273 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5274 EXPECT_FALSE(render_pass_quad
->is_replica
);
5275 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5276 render_pass_quad
->rect
.ToString());
5278 // The mask covers the owning layer only.
5279 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5280 frame
.render_passes
[0]->quad_list
[1]->material
);
5281 const RenderPassDrawQuad
* replica_quad
=
5282 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[1]);
5283 EXPECT_TRUE(replica_quad
->is_replica
);
5284 EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
5285 replica_quad
->rect
.ToString());
5286 EXPECT_EQ(gfx::RectF(-1.f
, 0.f
, 2.f
, 1.f
).ToString(),
5287 replica_quad
->mask_uv_rect
.ToString());
5289 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5290 host_impl_
->DidDrawAllLayers(frame
);
5294 TEST_F(LayerTreeHostImplTest
, MaskLayerForSurfaceWithClippedLayer
) {
5295 // The masked layer has bounds 50x50, but it has a child that causes
5296 // the surface bounds to be larger. It also has a parent that clips the
5297 // masked layer and its surface.
5299 scoped_ptr
<LayerImpl
> scoped_root
=
5300 LayerImpl::Create(host_impl_
->active_tree(), 1);
5301 LayerImpl
* root
= scoped_root
.get();
5302 host_impl_
->active_tree()->SetRootLayer(scoped_root
.Pass());
5304 scoped_ptr
<LayerImpl
> scoped_clipping_layer
=
5305 LayerImpl::Create(host_impl_
->active_tree(), 2);
5306 LayerImpl
* clipping_layer
= scoped_clipping_layer
.get();
5307 root
->AddChild(scoped_clipping_layer
.Pass());
5309 scoped_ptr
<LayerImpl
> scoped_content_layer
=
5310 LayerImpl::Create(host_impl_
->active_tree(), 3);
5311 LayerImpl
* content_layer
= scoped_content_layer
.get();
5312 clipping_layer
->AddChild(scoped_content_layer
.Pass());
5314 scoped_ptr
<LayerImpl
> scoped_content_child_layer
=
5315 LayerImpl::Create(host_impl_
->active_tree(), 4);
5316 LayerImpl
* content_child_layer
= scoped_content_child_layer
.get();
5317 content_layer
->AddChild(scoped_content_child_layer
.Pass());
5319 scoped_ptr
<FakeMaskLayerImpl
> scoped_mask_layer
=
5320 FakeMaskLayerImpl::Create(host_impl_
->active_tree(), 6);
5321 FakeMaskLayerImpl
* mask_layer
= scoped_mask_layer
.get();
5322 content_layer
->SetMaskLayer(scoped_mask_layer
.PassAs
<LayerImpl
>());
5324 gfx::Size
root_size(100, 100);
5325 root
->SetBounds(root_size
);
5326 root
->SetContentBounds(root_size
);
5327 root
->SetPosition(gfx::PointF());
5329 gfx::Rect
clipping_rect(20, 10, 10, 20);
5330 clipping_layer
->SetBounds(clipping_rect
.size());
5331 clipping_layer
->SetContentBounds(clipping_rect
.size());
5332 clipping_layer
->SetPosition(clipping_rect
.origin());
5333 clipping_layer
->SetMasksToBounds(true);
5335 gfx::Size
layer_size(50, 50);
5336 content_layer
->SetBounds(layer_size
);
5337 content_layer
->SetContentBounds(layer_size
);
5338 content_layer
->SetPosition(gfx::Point() - clipping_rect
.OffsetFromOrigin());
5339 content_layer
->SetDrawsContent(true);
5341 gfx::Size
child_size(50, 50);
5342 content_child_layer
->SetBounds(child_size
);
5343 content_child_layer
->SetContentBounds(child_size
);
5344 content_child_layer
->SetPosition(gfx::Point(50, 0));
5345 content_child_layer
->SetDrawsContent(true);
5347 gfx::Size
mask_size(100, 100);
5348 mask_layer
->SetBounds(mask_size
);
5349 mask_layer
->SetContentBounds(mask_size
);
5350 mask_layer
->SetPosition(gfx::PointF());
5351 mask_layer
->SetDrawsContent(true);
5353 float device_scale_factor
= 1.f
;
5354 host_impl_
->SetViewportSize(root_size
);
5355 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5357 LayerTreeHostImpl::FrameData frame
;
5358 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5360 ASSERT_EQ(1u, frame
.render_passes
.size());
5361 ASSERT_EQ(1u, frame
.render_passes
[0]->quad_list
.size());
5363 // The surface is clipped to 10x20.
5364 ASSERT_EQ(DrawQuad::RENDER_PASS
,
5365 frame
.render_passes
[0]->quad_list
[0]->material
);
5366 const RenderPassDrawQuad
* render_pass_quad
=
5367 RenderPassDrawQuad::MaterialCast(frame
.render_passes
[0]->quad_list
[0]);
5368 EXPECT_FALSE(render_pass_quad
->is_replica
);
5369 EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
5370 render_pass_quad
->rect
.ToString());
5372 // The masked layer is 50x50, but the surface size is 10x20. So the texture
5373 // coords in the mask are scaled by 10/50 and 20/50.
5374 // The surface is clipped to (20,10) so the mask texture coords are offset
5375 // by 20/50 and 10/50
5376 EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f
, 10.f
, 10.f
, 20.f
),
5377 1.f
/ 50.f
).ToString(),
5378 render_pass_quad
->mask_uv_rect
.ToString());
5380 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5381 host_impl_
->DidDrawAllLayers(frame
);
5385 class GLRendererWithSetupQuadForAntialiasing
: public GLRenderer
{
5387 using GLRenderer::SetupQuadForAntialiasing
;
5390 TEST_F(LayerTreeHostImplTest
, FarAwayQuadsDontNeedAA
) {
5391 // Due to precision issues (especially on Android), sometimes far
5392 // away quads can end up thinking they need AA.
5393 float device_scale_factor
= 4.f
/ 3.f
;
5394 host_impl_
->SetDeviceScaleFactor(device_scale_factor
);
5395 gfx::Size
root_size(2000, 1000);
5396 gfx::Size device_viewport_size
=
5397 gfx::ToCeiledSize(gfx::ScaleSize(root_size
, device_scale_factor
));
5398 host_impl_
->SetViewportSize(device_viewport_size
);
5400 host_impl_
->CreatePendingTree();
5401 host_impl_
->pending_tree()
5402 ->SetPageScaleFactorAndLimits(1.f
, 1.f
/ 16.f
, 16.f
);
5404 scoped_ptr
<LayerImpl
> scoped_root
=
5405 LayerImpl::Create(host_impl_
->pending_tree(), 1);
5406 LayerImpl
* root
= scoped_root
.get();
5408 host_impl_
->pending_tree()->SetRootLayer(scoped_root
.Pass());
5410 scoped_ptr
<LayerImpl
> scoped_scrolling_layer
=
5411 LayerImpl::Create(host_impl_
->pending_tree(), 2);
5412 LayerImpl
* scrolling_layer
= scoped_scrolling_layer
.get();
5413 root
->AddChild(scoped_scrolling_layer
.Pass());
5415 gfx::Size
content_layer_bounds(100000, 100);
5416 gfx::Size
pile_tile_size(3000, 3000);
5417 scoped_refptr
<FakePicturePileImpl
> pile(FakePicturePileImpl::CreateFilledPile(
5418 pile_tile_size
, content_layer_bounds
));
5420 scoped_ptr
<FakePictureLayerImpl
> scoped_content_layer
=
5421 FakePictureLayerImpl::CreateWithPile(host_impl_
->pending_tree(), 3, pile
);
5422 LayerImpl
* content_layer
= scoped_content_layer
.get();
5423 scrolling_layer
->AddChild(scoped_content_layer
.PassAs
<LayerImpl
>());
5424 content_layer
->SetBounds(content_layer_bounds
);
5425 content_layer
->SetDrawsContent(true);
5427 root
->SetBounds(root_size
);
5429 gfx::Vector2d
scroll_offset(100000, 0);
5430 scrolling_layer
->SetScrollClipLayer(root
->id());
5431 scrolling_layer
->SetScrollOffset(scroll_offset
);
5433 host_impl_
->ActivatePendingTree();
5435 host_impl_
->active_tree()->UpdateDrawProperties();
5436 ASSERT_EQ(1u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
5438 LayerTreeHostImpl::FrameData frame
;
5439 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5441 ASSERT_EQ(1u, frame
.render_passes
.size());
5442 ASSERT_LE(1u, frame
.render_passes
[0]->quad_list
.size());
5443 const DrawQuad
* quad
= frame
.render_passes
[0]->quad_list
[0];
5446 gfx::QuadF device_layer_quad
;
5448 GLRendererWithSetupQuadForAntialiasing::SetupQuadForAntialiasing(
5449 quad
->quadTransform(), quad
, &device_layer_quad
, edge
);
5450 EXPECT_FALSE(antialiased
);
5452 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5453 host_impl_
->DidDrawAllLayers(frame
);
5457 class CompositorFrameMetadataTest
: public LayerTreeHostImplTest
{
5459 CompositorFrameMetadataTest()
5460 : swap_buffers_complete_(0) {}
5462 virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE
{
5463 swap_buffers_complete_
++;
5466 int swap_buffers_complete_
;
5469 TEST_F(CompositorFrameMetadataTest
, CompositorFrameAckCountsAsSwapComplete
) {
5470 SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_
->active_tree(), 1));
5472 LayerTreeHostImpl::FrameData frame
;
5473 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5474 host_impl_
->DrawLayers(&frame
, base::TimeTicks());
5475 host_impl_
->DidDrawAllLayers(frame
);
5477 CompositorFrameAck ack
;
5478 host_impl_
->ReclaimResources(&ack
);
5479 host_impl_
->DidSwapBuffersComplete();
5480 EXPECT_EQ(swap_buffers_complete_
, 1);
5483 class CountingSoftwareDevice
: public SoftwareOutputDevice
{
5485 CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
5487 virtual SkCanvas
* BeginPaint(const gfx::Rect
& damage_rect
) OVERRIDE
{
5489 return SoftwareOutputDevice::BeginPaint(damage_rect
);
5491 virtual void EndPaint(SoftwareFrameData
* frame_data
) OVERRIDE
{
5493 SoftwareOutputDevice::EndPaint(frame_data
);
5496 int frames_began_
, frames_ended_
;
5499 TEST_F(LayerTreeHostImplTest
, ForcedDrawToSoftwareDeviceBasicRender
) {
5500 // No main thread evictions in resourceless software mode.
5501 set_reduce_memory_result(false);
5502 CountingSoftwareDevice
* software_device
= new CountingSoftwareDevice();
5503 bool delegated_rendering
= false;
5504 FakeOutputSurface
* output_surface
=
5505 FakeOutputSurface::CreateDeferredGL(
5506 scoped_ptr
<SoftwareOutputDevice
>(software_device
),
5507 delegated_rendering
).release();
5508 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5509 scoped_ptr
<OutputSurface
>(output_surface
)));
5510 host_impl_
->SetViewportSize(gfx::Size(50, 50));
5512 SetupScrollAndContentsLayers(gfx::Size(100, 100));
5514 output_surface
->set_forced_draw_to_software_device(true);
5515 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5517 EXPECT_EQ(0, software_device
->frames_began_
);
5518 EXPECT_EQ(0, software_device
->frames_ended_
);
5522 EXPECT_EQ(1, software_device
->frames_began_
);
5523 EXPECT_EQ(1, software_device
->frames_ended_
);
5525 // Call other API methods that are likely to hit NULL pointer in this mode.
5526 EXPECT_TRUE(host_impl_
->AsValue());
5527 EXPECT_TRUE(host_impl_
->ActivationStateAsValue());
5530 TEST_F(LayerTreeHostImplTest
,
5531 ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers
) {
5532 set_reduce_memory_result(false);
5533 bool delegated_rendering
= false;
5534 FakeOutputSurface
* output_surface
=
5535 FakeOutputSurface::CreateDeferredGL(
5536 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5537 delegated_rendering
).release();
5538 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5539 scoped_ptr
<OutputSurface
>(output_surface
)));
5541 output_surface
->set_forced_draw_to_software_device(true);
5542 EXPECT_TRUE(output_surface
->ForcedDrawToSoftwareDevice());
5544 // SolidColorLayerImpl will be drawn.
5545 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5546 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5548 // VideoLayerImpl will not be drawn.
5549 FakeVideoFrameProvider provider
;
5550 scoped_ptr
<VideoLayerImpl
> video_layer
=
5551 VideoLayerImpl::Create(host_impl_
->active_tree(), 2, &provider
);
5552 video_layer
->SetBounds(gfx::Size(10, 10));
5553 video_layer
->SetContentBounds(gfx::Size(10, 10));
5554 video_layer
->SetDrawsContent(true);
5555 root_layer
->AddChild(video_layer
.PassAs
<LayerImpl
>());
5556 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5558 LayerTreeHostImpl::FrameData frame
;
5559 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5560 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5561 host_impl_
->DidDrawAllLayers(frame
);
5563 EXPECT_EQ(1u, frame
.will_draw_layers
.size());
5564 EXPECT_EQ(host_impl_
->active_tree()->root_layer(), frame
.will_draw_layers
[0]);
5567 class LayerTreeHostImplTestDeferredInitialize
: public LayerTreeHostImplTest
{
5569 virtual void SetUp() OVERRIDE
{
5570 LayerTreeHostImplTest::SetUp();
5572 set_reduce_memory_result(false);
5574 bool delegated_rendering
= false;
5575 scoped_ptr
<FakeOutputSurface
> output_surface(
5576 FakeOutputSurface::CreateDeferredGL(
5577 scoped_ptr
<SoftwareOutputDevice
>(new CountingSoftwareDevice()),
5578 delegated_rendering
));
5579 output_surface_
= output_surface
.get();
5581 EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
5582 output_surface
.PassAs
<OutputSurface
>()));
5584 scoped_ptr
<SolidColorLayerImpl
> root_layer
=
5585 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
5586 SetupRootLayerImpl(root_layer
.PassAs
<LayerImpl
>());
5588 onscreen_context_provider_
= TestContextProvider::Create();
5591 virtual void UpdateRendererCapabilitiesOnImplThread() OVERRIDE
{
5592 did_update_renderer_capabilities_
= true;
5595 FakeOutputSurface
* output_surface_
;
5596 scoped_refptr
<TestContextProvider
> onscreen_context_provider_
;
5597 bool did_update_renderer_capabilities_
;
5601 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Success
) {
5605 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5607 // DeferredInitialize and hardware draw.
5608 did_update_renderer_capabilities_
= false;
5610 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5611 EXPECT_EQ(onscreen_context_provider_
,
5612 host_impl_
->output_surface()->context_provider());
5613 EXPECT_TRUE(did_update_renderer_capabilities_
);
5615 // Defer intialized GL draw.
5618 // Revert back to software.
5619 did_update_renderer_capabilities_
= false;
5620 output_surface_
->ReleaseGL();
5621 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5622 EXPECT_TRUE(did_update_renderer_capabilities_
);
5624 // Software draw again.
5628 TEST_F(LayerTreeHostImplTestDeferredInitialize
, Fails
) {
5632 // Fail initialization of the onscreen context before the OutputSurface binds
5633 // it to the thread.
5634 onscreen_context_provider_
->UnboundTestContext3d()->set_context_lost(true);
5636 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5638 // DeferredInitialize fails.
5639 did_update_renderer_capabilities_
= false;
5641 output_surface_
->InitializeAndSetContext3d(onscreen_context_provider_
));
5642 EXPECT_FALSE(host_impl_
->output_surface()->context_provider());
5643 EXPECT_FALSE(did_update_renderer_capabilities_
);
5645 // Software draw again.
5649 // Checks that we have a non-0 default allocation if we pass a context that
5650 // doesn't support memory management extensions.
5651 TEST_F(LayerTreeHostImplTest
, DefaultMemoryAllocation
) {
5652 LayerTreeSettings settings
;
5653 host_impl_
= LayerTreeHostImpl::Create(settings
,
5656 &stats_instrumentation_
,
5657 shared_bitmap_manager_
.get(),
5660 scoped_ptr
<OutputSurface
> output_surface(
5661 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
5662 host_impl_
->InitializeRenderer(output_surface
.Pass());
5663 EXPECT_LT(0ul, host_impl_
->memory_allocation_limit_bytes());
5666 TEST_F(LayerTreeHostImplTest
, MemoryPolicy
) {
5667 ManagedMemoryPolicy
policy1(
5668 456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
, 1000);
5669 int everything_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5670 gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING
);
5671 int allow_nice_to_have_cutoff_value
=
5672 ManagedMemoryPolicy::PriorityCutoffToValue(
5673 gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE
);
5674 int nothing_cutoff_value
= ManagedMemoryPolicy::PriorityCutoffToValue(
5675 gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING
);
5677 // GPU rasterization should be disabled by default on the tree(s)
5678 EXPECT_FALSE(host_impl_
->active_tree()->use_gpu_rasterization());
5679 EXPECT_TRUE(host_impl_
->pending_tree() == NULL
);
5681 host_impl_
->SetVisible(true);
5682 host_impl_
->SetMemoryPolicy(policy1
);
5683 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5684 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5686 host_impl_
->SetVisible(false);
5687 EXPECT_EQ(0u, current_limit_bytes_
);
5688 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5690 host_impl_
->SetVisible(true);
5691 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5692 EXPECT_EQ(everything_cutoff_value
, current_priority_cutoff_value_
);
5694 // Now enable GPU rasterization and test if we get nice to have cutoff,
5696 LayerTreeSettings settings
;
5697 settings
.gpu_rasterization_enabled
= true;
5698 host_impl_
= LayerTreeHostImpl::Create(
5699 settings
, this, &proxy_
, &stats_instrumentation_
, NULL
, 0);
5700 host_impl_
->SetUseGpuRasterization(true);
5701 host_impl_
->SetVisible(true);
5702 host_impl_
->SetMemoryPolicy(policy1
);
5703 EXPECT_EQ(policy1
.bytes_limit_when_visible
, current_limit_bytes_
);
5704 EXPECT_EQ(allow_nice_to_have_cutoff_value
, current_priority_cutoff_value_
);
5706 host_impl_
->SetVisible(false);
5707 EXPECT_EQ(0u, current_limit_bytes_
);
5708 EXPECT_EQ(nothing_cutoff_value
, current_priority_cutoff_value_
);
5711 TEST_F(LayerTreeHostImplTest
, RequireHighResWhenVisible
) {
5712 ASSERT_TRUE(host_impl_
->active_tree());
5714 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5715 host_impl_
->SetVisible(false);
5716 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5717 host_impl_
->SetVisible(true);
5718 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5719 host_impl_
->SetVisible(false);
5720 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5722 host_impl_
->CreatePendingTree();
5723 host_impl_
->ActivatePendingTree();
5725 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5726 host_impl_
->SetVisible(true);
5727 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5730 TEST_F(LayerTreeHostImplTest
, RequireHighResAfterGpuRasterizationToggles
) {
5731 ASSERT_TRUE(host_impl_
->active_tree());
5732 EXPECT_FALSE(host_impl_
->use_gpu_rasterization());
5734 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5735 host_impl_
->SetUseGpuRasterization(false);
5736 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5737 host_impl_
->SetUseGpuRasterization(true);
5738 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5739 host_impl_
->SetUseGpuRasterization(false);
5740 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5742 host_impl_
->CreatePendingTree();
5743 host_impl_
->ActivatePendingTree();
5745 EXPECT_FALSE(host_impl_
->active_tree()->RequiresHighResToDraw());
5746 host_impl_
->SetUseGpuRasterization(true);
5747 EXPECT_TRUE(host_impl_
->active_tree()->RequiresHighResToDraw());
5750 class LayerTreeHostImplTestManageTiles
: public LayerTreeHostImplTest
{
5752 virtual void SetUp() OVERRIDE
{
5753 LayerTreeSettings settings
;
5754 settings
.impl_side_painting
= true;
5756 fake_host_impl_
= new FakeLayerTreeHostImpl(
5757 settings
, &proxy_
, shared_bitmap_manager_
.get());
5758 host_impl_
.reset(fake_host_impl_
);
5759 host_impl_
->InitializeRenderer(CreateOutputSurface());
5760 host_impl_
->SetViewportSize(gfx::Size(10, 10));
5763 FakeLayerTreeHostImpl
* fake_host_impl_
;
5766 TEST_F(LayerTreeHostImplTestManageTiles
, ManageTilesWhenInvisible
) {
5767 fake_host_impl_
->DidModifyTilePriorities();
5768 EXPECT_TRUE(fake_host_impl_
->manage_tiles_needed());
5769 fake_host_impl_
->SetVisible(false);
5770 EXPECT_FALSE(fake_host_impl_
->manage_tiles_needed());
5773 TEST_F(LayerTreeHostImplTest
, UIResourceManagement
) {
5774 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5775 TestWebGraphicsContext3D::Create();
5776 TestWebGraphicsContext3D
* context3d
= context
.get();
5777 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5778 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5780 EXPECT_EQ(0u, context3d
->NumTextures());
5782 UIResourceId ui_resource_id
= 1;
5783 bool is_opaque
= false;
5784 UIResourceBitmap
bitmap(gfx::Size(1, 1), is_opaque
);
5785 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5786 EXPECT_EQ(1u, context3d
->NumTextures());
5787 ResourceProvider::ResourceId id1
=
5788 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5791 // Multiple requests with the same id is allowed. The previous texture is
5793 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5794 EXPECT_EQ(1u, context3d
->NumTextures());
5795 ResourceProvider::ResourceId id2
=
5796 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5798 EXPECT_NE(id1
, id2
);
5800 // Deleting invalid UIResourceId is allowed and does not change state.
5801 host_impl_
->DeleteUIResource(-1);
5802 EXPECT_EQ(1u, context3d
->NumTextures());
5804 // Should return zero for invalid UIResourceId. Number of textures should
5806 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(-1));
5807 EXPECT_EQ(1u, context3d
->NumTextures());
5809 host_impl_
->DeleteUIResource(ui_resource_id
);
5810 EXPECT_EQ(0u, host_impl_
->ResourceIdForUIResource(ui_resource_id
));
5811 EXPECT_EQ(0u, context3d
->NumTextures());
5813 // Should not change state for multiple deletion on one UIResourceId
5814 host_impl_
->DeleteUIResource(ui_resource_id
);
5815 EXPECT_EQ(0u, context3d
->NumTextures());
5818 TEST_F(LayerTreeHostImplTest
, CreateETC1UIResource
) {
5819 scoped_ptr
<TestWebGraphicsContext3D
> context
=
5820 TestWebGraphicsContext3D::Create();
5821 TestWebGraphicsContext3D
* context3d
= context
.get();
5822 scoped_ptr
<FakeOutputSurface
> output_surface
= FakeOutputSurface::Create3d();
5823 CreateHostImpl(DefaultSettings(), output_surface
.PassAs
<OutputSurface
>());
5825 EXPECT_EQ(0u, context3d
->NumTextures());
5827 gfx::Size
size(4, 4);
5828 // SkImageInfo has no support for ETC1. The |info| below contains the right
5829 // total pixel size for the bitmap but not the right height and width. The
5830 // correct width/height are passed directly to UIResourceBitmap.
5832 SkImageInfo::Make(4, 2, kAlpha_8_SkColorType
, kPremul_SkAlphaType
);
5833 skia::RefPtr
<SkPixelRef
> pixel_ref
=
5834 skia::AdoptRef(SkMallocPixelRef::NewAllocate(info
, 0, 0));
5835 pixel_ref
->setImmutable();
5836 UIResourceBitmap
bitmap(pixel_ref
, size
);
5837 UIResourceId ui_resource_id
= 1;
5838 host_impl_
->CreateUIResource(ui_resource_id
, bitmap
);
5839 EXPECT_EQ(1u, context3d
->NumTextures());
5840 ResourceProvider::ResourceId id1
=
5841 host_impl_
->ResourceIdForUIResource(ui_resource_id
);
5845 void ShutdownReleasesContext_Callback(scoped_ptr
<CopyOutputResult
> result
) {
5848 TEST_F(LayerTreeHostImplTest
, ShutdownReleasesContext
) {
5849 scoped_refptr
<TestContextProvider
> context_provider
=
5850 TestContextProvider::Create();
5854 FakeOutputSurface::Create3d(context_provider
).PassAs
<OutputSurface
>());
5856 SetupRootLayerImpl(LayerImpl::Create(host_impl_
->active_tree(), 1));
5858 ScopedPtrVector
<CopyOutputRequest
> requests
;
5859 requests
.push_back(CopyOutputRequest::CreateRequest(
5860 base::Bind(&ShutdownReleasesContext_Callback
)));
5862 host_impl_
->active_tree()->root_layer()->PassCopyRequests(&requests
);
5864 LayerTreeHostImpl::FrameData frame
;
5865 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
5866 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
5867 host_impl_
->DidDrawAllLayers(frame
);
5869 // The CopyOutputResult's callback has a ref on the ContextProvider and a
5870 // texture in a texture mailbox.
5871 EXPECT_FALSE(context_provider
->HasOneRef());
5872 EXPECT_EQ(1u, context_provider
->TestContext3d()->NumTextures());
5876 // The CopyOutputResult's callback was cancelled, the CopyOutputResult
5877 // released, and the texture deleted.
5878 EXPECT_TRUE(context_provider
->HasOneRef());
5879 EXPECT_EQ(0u, context_provider
->TestContext3d()->NumTextures());
5882 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldNotBubble
) {
5883 // When flinging via touch, only the child should scroll (we should not
5885 gfx::Size
surface_size(10, 10);
5886 gfx::Size
content_size(20, 20);
5887 scoped_ptr
<LayerImpl
> root_clip
=
5888 LayerImpl::Create(host_impl_
->active_tree(), 3);
5889 scoped_ptr
<LayerImpl
> root
=
5890 CreateScrollableLayer(1, content_size
, root_clip
.get());
5891 root
->SetIsContainerForFixedPositionLayers(true);
5892 scoped_ptr
<LayerImpl
> child
=
5893 CreateScrollableLayer(2, content_size
, root_clip
.get());
5895 root
->AddChild(child
.Pass());
5896 int root_id
= root
->id();
5897 root_clip
->AddChild(root
.Pass());
5899 host_impl_
->SetViewportSize(surface_size
);
5900 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
5901 host_impl_
->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID
);
5902 host_impl_
->active_tree()->DidBecomeActive();
5905 EXPECT_EQ(InputHandler::ScrollStarted
,
5906 host_impl_
->ScrollBegin(gfx::Point(),
5907 InputHandler::Gesture
));
5909 EXPECT_EQ(InputHandler::ScrollStarted
,
5910 host_impl_
->FlingScrollBegin());
5912 gfx::Vector2d
scroll_delta(0, 100);
5913 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5914 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
5916 host_impl_
->ScrollEnd();
5918 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
5919 host_impl_
->ProcessScrollDeltas();
5921 // Only the child should have scrolled.
5922 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
5923 ExpectNone(*scroll_info
.get(), root_id
);
5927 TEST_F(LayerTreeHostImplTest
, TouchFlingShouldLockToFirstScrolledLayer
) {
5928 // Scroll a child layer beyond its maximum scroll range and make sure the
5929 // the scroll doesn't bubble up to the parent layer.
5930 gfx::Size
surface_size(10, 10);
5931 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->active_tree(), 1);
5932 scoped_ptr
<LayerImpl
> root_scrolling
=
5933 CreateScrollableLayer(2, surface_size
, root
.get());
5935 scoped_ptr
<LayerImpl
> grand_child
=
5936 CreateScrollableLayer(4, surface_size
, root
.get());
5937 grand_child
->SetScrollOffset(gfx::Vector2d(0, 2));
5939 scoped_ptr
<LayerImpl
> child
=
5940 CreateScrollableLayer(3, surface_size
, root
.get());
5941 child
->SetScrollOffset(gfx::Vector2d(0, 4));
5942 child
->AddChild(grand_child
.Pass());
5944 root_scrolling
->AddChild(child
.Pass());
5945 root
->AddChild(root_scrolling
.Pass());
5946 host_impl_
->active_tree()->SetRootLayer(root
.Pass());
5947 host_impl_
->active_tree()->DidBecomeActive();
5948 host_impl_
->SetViewportSize(surface_size
);
5951 scoped_ptr
<ScrollAndScaleSet
> scroll_info
;
5953 host_impl_
->active_tree()->root_layer()->children()[0]->children()[0];
5954 LayerImpl
* grand_child
= child
->children()[0];
5956 gfx::Vector2d
scroll_delta(0, -2);
5957 EXPECT_EQ(InputHandler::ScrollStarted
,
5958 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
5959 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
5961 // The grand child should have scrolled up to its limit.
5962 scroll_info
= host_impl_
->ProcessScrollDeltas();
5963 ASSERT_EQ(1u, scroll_info
->scrolls
.size());
5964 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
5965 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
5967 // The child should have received the bubbled delta, but the locked
5968 // scrolling layer should remain set as the grand child.
5969 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
5970 scroll_info
= host_impl_
->ProcessScrollDeltas();
5971 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
5972 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
5973 ExpectContains(*scroll_info
, child
->id(), scroll_delta
);
5974 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), grand_child
);
5976 // The first |ScrollBy| after the fling should re-lock the scrolling
5977 // layer to the first layer that scrolled, which is the child.
5978 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
5979 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
5980 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
5982 // The child should have scrolled up to its limit.
5983 scroll_info
= host_impl_
->ProcessScrollDeltas();
5984 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
5985 ExpectContains(*scroll_info
, grand_child
->id(), scroll_delta
);
5986 ExpectContains(*scroll_info
, child
->id(), scroll_delta
+ scroll_delta
);
5988 // As the locked layer is at it's limit, no further scrolling can occur.
5989 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), scroll_delta
));
5990 EXPECT_EQ(host_impl_
->CurrentlyScrollingLayer(), child
);
5991 host_impl_
->ScrollEnd();
5995 TEST_F(LayerTreeHostImplTest
, WheelFlingShouldBubble
) {
5996 // When flinging via wheel, the root should eventually scroll (we should
5998 gfx::Size
surface_size(10, 10);
5999 gfx::Size
content_size(20, 20);
6000 scoped_ptr
<LayerImpl
> root_clip
=
6001 LayerImpl::Create(host_impl_
->active_tree(), 3);
6002 scoped_ptr
<LayerImpl
> root_scroll
=
6003 CreateScrollableLayer(1, content_size
, root_clip
.get());
6004 int root_scroll_id
= root_scroll
->id();
6005 scoped_ptr
<LayerImpl
> child
=
6006 CreateScrollableLayer(2, content_size
, root_clip
.get());
6008 root_scroll
->AddChild(child
.Pass());
6009 root_clip
->AddChild(root_scroll
.Pass());
6011 host_impl_
->SetViewportSize(surface_size
);
6012 host_impl_
->active_tree()->SetRootLayer(root_clip
.Pass());
6013 host_impl_
->active_tree()->DidBecomeActive();
6016 EXPECT_EQ(InputHandler::ScrollStarted
,
6017 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6019 EXPECT_EQ(InputHandler::ScrollStarted
,
6020 host_impl_
->FlingScrollBegin());
6022 gfx::Vector2d
scroll_delta(0, 100);
6023 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6024 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6026 host_impl_
->ScrollEnd();
6028 scoped_ptr
<ScrollAndScaleSet
> scroll_info
=
6029 host_impl_
->ProcessScrollDeltas();
6031 // The root should have scrolled.
6032 ASSERT_EQ(2u, scroll_info
->scrolls
.size());
6033 ExpectContains(*scroll_info
.get(), root_scroll_id
, gfx::Vector2d(0, 10));
6037 TEST_F(LayerTreeHostImplTest
, ScrollUnknownNotOnAncestorChain
) {
6038 // If we ray cast a scroller that is not on the first layer's ancestor chain,
6039 // we should return ScrollUnknown.
6040 gfx::Size
content_size(100, 100);
6041 SetupScrollAndContentsLayers(content_size
);
6043 int scroll_layer_id
= 2;
6044 LayerImpl
* scroll_layer
=
6045 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6046 scroll_layer
->SetDrawsContent(true);
6048 int page_scale_layer_id
= 5;
6049 LayerImpl
* page_scale_layer
=
6050 host_impl_
->active_tree()->LayerById(page_scale_layer_id
);
6052 int occluder_layer_id
= 6;
6053 scoped_ptr
<LayerImpl
> occluder_layer
=
6054 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6055 occluder_layer
->SetDrawsContent(true);
6056 occluder_layer
->SetBounds(content_size
);
6057 occluder_layer
->SetContentBounds(content_size
);
6058 occluder_layer
->SetPosition(gfx::PointF());
6060 // The parent of the occluder is *above* the scroller.
6061 page_scale_layer
->AddChild(occluder_layer
.Pass());
6065 EXPECT_EQ(InputHandler::ScrollUnknown
,
6066 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6069 TEST_F(LayerTreeHostImplTest
, ScrollUnknownScrollAncestorMismatch
) {
6070 // If we ray cast a scroller this is on the first layer's ancestor chain, but
6071 // is not the first scroller we encounter when walking up from the layer, we
6072 // should also return ScrollUnknown.
6073 gfx::Size
content_size(100, 100);
6074 SetupScrollAndContentsLayers(content_size
);
6076 int scroll_layer_id
= 2;
6077 LayerImpl
* scroll_layer
=
6078 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6079 scroll_layer
->SetDrawsContent(true);
6081 int occluder_layer_id
= 6;
6082 scoped_ptr
<LayerImpl
> occluder_layer
=
6083 LayerImpl::Create(host_impl_
->active_tree(), occluder_layer_id
);
6084 occluder_layer
->SetDrawsContent(true);
6085 occluder_layer
->SetBounds(content_size
);
6086 occluder_layer
->SetContentBounds(content_size
);
6087 occluder_layer
->SetPosition(gfx::PointF(-10.f
, -10.f
));
6089 int child_scroll_clip_layer_id
= 7;
6090 scoped_ptr
<LayerImpl
> child_scroll_clip
=
6091 LayerImpl::Create(host_impl_
->active_tree(), child_scroll_clip_layer_id
);
6093 int child_scroll_layer_id
= 8;
6094 scoped_ptr
<LayerImpl
> child_scroll
= CreateScrollableLayer(
6095 child_scroll_layer_id
, content_size
, child_scroll_clip
.get());
6097 child_scroll
->SetPosition(gfx::PointF(10.f
, 10.f
));
6099 child_scroll
->AddChild(occluder_layer
.Pass());
6100 scroll_layer
->AddChild(child_scroll
.Pass());
6104 EXPECT_EQ(InputHandler::ScrollUnknown
,
6105 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6108 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScroller
) {
6109 gfx::Size
content_size(100, 100);
6110 SetupScrollAndContentsLayers(content_size
);
6112 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6114 int scroll_layer_id
= 2;
6115 LayerImpl
* scroll_layer
=
6116 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6118 int child_scroll_layer_id
= 7;
6119 scoped_ptr
<LayerImpl
> child_scroll
=
6120 CreateScrollableLayer(child_scroll_layer_id
, content_size
, root
);
6121 child_scroll
->SetDrawsContent(false);
6123 scroll_layer
->AddChild(child_scroll
.Pass());
6127 // We should not have scrolled |child_scroll| even though we technically "hit"
6128 // it. The reason for this is that if the scrolling the scroll would not move
6129 // any layer that is a drawn RSLL member, then we can ignore the hit.
6131 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6132 // overscrolling the inner viewport.
6133 EXPECT_EQ(InputHandler::ScrollStarted
,
6134 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6136 EXPECT_EQ(2, host_impl_
->CurrentlyScrollingLayer()->id());
6139 TEST_F(LayerTreeHostImplTest
, ScrollInvisibleScrollerWithVisibleScrollChild
) {
6140 // This test case is very similar to the one above with one key difference:
6141 // the invisible scroller has a scroll child that is indeed draw contents.
6142 // If we attempt to initiate a gesture scroll off of the visible scroll child
6143 // we should still start the scroll child.
6144 gfx::Size
content_size(100, 100);
6145 SetupScrollAndContentsLayers(content_size
);
6147 LayerImpl
* root
= host_impl_
->active_tree()->LayerById(1);
6149 int scroll_layer_id
= 2;
6150 LayerImpl
* scroll_layer
=
6151 host_impl_
->active_tree()->LayerById(scroll_layer_id
);
6153 int scroll_child_id
= 6;
6154 scoped_ptr
<LayerImpl
> scroll_child
=
6155 LayerImpl::Create(host_impl_
->active_tree(), scroll_child_id
);
6156 scroll_child
->SetDrawsContent(true);
6157 scroll_child
->SetBounds(content_size
);
6158 scroll_child
->SetContentBounds(content_size
);
6159 // Move the scroll child so it's not hit by our test point.
6160 scroll_child
->SetPosition(gfx::PointF(10.f
, 10.f
));
6162 int invisible_scroll_layer_id
= 7;
6163 scoped_ptr
<LayerImpl
> invisible_scroll
=
6164 CreateScrollableLayer(invisible_scroll_layer_id
, content_size
, root
);
6165 invisible_scroll
->SetDrawsContent(false);
6167 int container_id
= 8;
6168 scoped_ptr
<LayerImpl
> container
=
6169 LayerImpl::Create(host_impl_
->active_tree(), container_id
);
6171 scoped_ptr
<std::set
<LayerImpl
*> > scroll_children(new std::set
<LayerImpl
*>());
6172 scroll_children
->insert(scroll_child
.get());
6173 invisible_scroll
->SetScrollChildren(scroll_children
.release());
6175 scroll_child
->SetScrollParent(invisible_scroll
.get());
6177 container
->AddChild(invisible_scroll
.Pass());
6178 container
->AddChild(scroll_child
.Pass());
6180 scroll_layer
->AddChild(container
.Pass());
6184 // We should not have scrolled |child_scroll| even though we technically "hit"
6185 // it. The reason for this is that if the scrolling the scroll would not move
6186 // any layer that is a drawn RSLL member, then we can ignore the hit.
6188 // Why ScrollStarted? In this case, it's because we've bubbled out and started
6189 // overscrolling the inner viewport.
6190 EXPECT_EQ(InputHandler::ScrollStarted
,
6191 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Wheel
));
6193 EXPECT_EQ(7, host_impl_
->CurrentlyScrollingLayer()->id());
6196 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6197 // to CompositorFrameMetadata after SwapBuffers();
6198 TEST_F(LayerTreeHostImplTest
, LatencyInfoPassedToCompositorFrameMetadata
) {
6199 scoped_ptr
<SolidColorLayerImpl
> root
=
6200 SolidColorLayerImpl::Create(host_impl_
->active_tree(), 1);
6201 root
->SetPosition(gfx::PointF());
6202 root
->SetBounds(gfx::Size(10, 10));
6203 root
->SetContentBounds(gfx::Size(10, 10));
6204 root
->SetDrawsContent(true);
6206 host_impl_
->active_tree()->SetRootLayer(root
.PassAs
<LayerImpl
>());
6208 FakeOutputSurface
* fake_output_surface
=
6209 static_cast<FakeOutputSurface
*>(host_impl_
->output_surface());
6211 const std::vector
<ui::LatencyInfo
>& metadata_latency_before
=
6212 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6213 EXPECT_TRUE(metadata_latency_before
.empty());
6215 ui::LatencyInfo latency_info
;
6216 latency_info
.AddLatencyNumber(
6217 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, 0);
6218 scoped_ptr
<SwapPromise
> swap_promise(
6219 new LatencyInfoSwapPromise(latency_info
));
6220 host_impl_
->active_tree()->QueueSwapPromise(swap_promise
.Pass());
6221 host_impl_
->SetNeedsRedraw();
6223 gfx::Rect
full_frame_damage(host_impl_
->DrawViewportSize());
6224 LayerTreeHostImpl::FrameData frame
;
6225 EXPECT_EQ(DRAW_SUCCESS
, host_impl_
->PrepareToDraw(&frame
));
6226 host_impl_
->DrawLayers(&frame
, gfx::FrameTime::Now());
6227 host_impl_
->DidDrawAllLayers(frame
);
6228 EXPECT_TRUE(host_impl_
->SwapBuffers(frame
));
6230 const std::vector
<ui::LatencyInfo
>& metadata_latency_after
=
6231 fake_output_surface
->last_sent_frame().metadata
.latency_info
;
6232 EXPECT_EQ(1u, metadata_latency_after
.size());
6233 EXPECT_TRUE(metadata_latency_after
[0].FindLatency(
6234 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT
, 0, NULL
));
6237 class SimpleSwapPromiseMonitor
: public SwapPromiseMonitor
{
6239 SimpleSwapPromiseMonitor(LayerTreeHost
* layer_tree_host
,
6240 LayerTreeHostImpl
* layer_tree_host_impl
,
6241 int* set_needs_commit_count
,
6242 int* set_needs_redraw_count
)
6243 : SwapPromiseMonitor(layer_tree_host
, layer_tree_host_impl
),
6244 set_needs_commit_count_(set_needs_commit_count
),
6245 set_needs_redraw_count_(set_needs_redraw_count
) {}
6247 virtual ~SimpleSwapPromiseMonitor() {}
6249 virtual void OnSetNeedsCommitOnMain() OVERRIDE
{
6250 (*set_needs_commit_count_
)++;
6253 virtual void OnSetNeedsRedrawOnImpl() OVERRIDE
{
6254 (*set_needs_redraw_count_
)++;
6258 int* set_needs_commit_count_
;
6259 int* set_needs_redraw_count_
;
6262 TEST_F(LayerTreeHostImplTest
, SimpleSwapPromiseMonitor
) {
6263 int set_needs_commit_count
= 0;
6264 int set_needs_redraw_count
= 0;
6267 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6268 new SimpleSwapPromiseMonitor(NULL
,
6270 &set_needs_commit_count
,
6271 &set_needs_redraw_count
));
6272 host_impl_
->SetNeedsRedraw();
6273 EXPECT_EQ(0, set_needs_commit_count
);
6274 EXPECT_EQ(1, set_needs_redraw_count
);
6277 // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
6279 host_impl_
->SetNeedsRedraw();
6280 EXPECT_EQ(0, set_needs_commit_count
);
6281 EXPECT_EQ(1, set_needs_redraw_count
);
6284 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6285 new SimpleSwapPromiseMonitor(NULL
,
6287 &set_needs_commit_count
,
6288 &set_needs_redraw_count
));
6289 host_impl_
->SetNeedsRedrawRect(gfx::Rect(10, 10));
6290 EXPECT_EQ(0, set_needs_commit_count
);
6291 EXPECT_EQ(2, set_needs_redraw_count
);
6295 scoped_ptr
<SimpleSwapPromiseMonitor
> swap_promise_monitor(
6296 new SimpleSwapPromiseMonitor(NULL
,
6298 &set_needs_commit_count
,
6299 &set_needs_redraw_count
));
6300 // Empty damage rect won't signal the monitor.
6301 host_impl_
->SetNeedsRedrawRect(gfx::Rect());
6302 EXPECT_EQ(0, set_needs_commit_count
);
6303 EXPECT_EQ(2, set_needs_redraw_count
);
6307 class LayerTreeHostImplWithTopControlsTest
: public LayerTreeHostImplTest
{
6309 virtual void SetUp() OVERRIDE
{
6310 LayerTreeSettings settings
= DefaultSettings();
6311 settings
.calculate_top_controls_position
= true;
6312 settings
.top_controls_height
= top_controls_height_
;
6313 CreateHostImpl(settings
, CreateOutputSurface());
6317 static const int top_controls_height_
;
6320 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_
= 50;
6322 TEST_F(LayerTreeHostImplWithTopControlsTest
, NoIdleAnimations
) {
6323 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6324 ->SetScrollOffset(gfx::Vector2d(0, 10));
6325 host_impl_
->Animate(base::TimeTicks());
6326 EXPECT_FALSE(did_request_redraw_
);
6329 TEST_F(LayerTreeHostImplWithTopControlsTest
, TopControlsAnimationScheduling
) {
6330 SetupScrollAndContentsLayers(gfx::Size(100, 100))
6331 ->SetScrollOffset(gfx::Vector2d(0, 10));
6332 host_impl_
->DidChangeTopControlsPosition();
6333 EXPECT_TRUE(did_request_animate_
);
6334 EXPECT_TRUE(did_request_redraw_
);
6337 TEST_F(LayerTreeHostImplWithTopControlsTest
, ScrollHandledByTopControls
) {
6338 LayerImpl
* scroll_layer
= SetupScrollAndContentsLayers(gfx::Size(100, 200));
6339 host_impl_
->SetViewportSize(gfx::Size(100, 100));
6342 EXPECT_EQ(InputHandler::ScrollStarted
,
6343 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6344 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6345 EXPECT_EQ(gfx::Vector2dF().ToString(),
6346 scroll_layer
->TotalScrollOffset().ToString());
6348 // Scroll just the top controls and verify that the scroll succeeds.
6349 const float residue
= 10;
6350 float offset
= top_controls_height_
- residue
;
6351 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6352 EXPECT_EQ(-offset
, host_impl_
->top_controls_manager()->controls_top_offset());
6353 EXPECT_EQ(gfx::Vector2dF().ToString(),
6354 scroll_layer
->TotalScrollOffset().ToString());
6356 // Scroll across the boundary
6357 const float content_scroll
= 20;
6358 offset
= residue
+ content_scroll
;
6359 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6360 EXPECT_EQ(-top_controls_height_
,
6361 host_impl_
->top_controls_manager()->controls_top_offset());
6362 EXPECT_EQ(gfx::Vector2dF(0, content_scroll
).ToString(),
6363 scroll_layer
->TotalScrollOffset().ToString());
6365 // Now scroll back to the top of the content
6366 offset
= -content_scroll
;
6367 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6368 EXPECT_EQ(-top_controls_height_
,
6369 host_impl_
->top_controls_manager()->controls_top_offset());
6370 EXPECT_EQ(gfx::Vector2dF().ToString(),
6371 scroll_layer
->TotalScrollOffset().ToString());
6373 // And scroll the top controls completely into view
6374 offset
= -top_controls_height_
;
6375 EXPECT_TRUE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6376 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6377 EXPECT_EQ(gfx::Vector2dF().ToString(),
6378 scroll_layer
->TotalScrollOffset().ToString());
6380 // And attempt to scroll past the end
6381 EXPECT_FALSE(host_impl_
->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset
)));
6382 EXPECT_EQ(0, host_impl_
->top_controls_manager()->controls_top_offset());
6383 EXPECT_EQ(gfx::Vector2dF().ToString(),
6384 scroll_layer
->TotalScrollOffset().ToString());
6386 host_impl_
->ScrollEnd();
6389 class LayerTreeHostImplVirtualViewportTest
: public LayerTreeHostImplTest
{
6391 void SetupVirtualViewportLayers(const gfx::Size
& content_size
,
6392 const gfx::Size
& outer_viewport
,
6393 const gfx::Size
& inner_viewport
) {
6394 LayerTreeImpl
* layer_tree_impl
= host_impl_
->active_tree();
6395 const int kOuterViewportClipLayerId
= 6;
6396 const int kOuterViewportScrollLayerId
= 7;
6397 const int kInnerViewportScrollLayerId
= 2;
6398 const int kInnerViewportClipLayerId
= 4;
6399 const int kPageScaleLayerId
= 5;
6401 scoped_ptr
<LayerImpl
> inner_scroll
=
6402 LayerImpl::Create(layer_tree_impl
, kInnerViewportScrollLayerId
);
6403 inner_scroll
->SetIsContainerForFixedPositionLayers(true);
6404 inner_scroll
->SetScrollOffset(gfx::Vector2d());
6406 scoped_ptr
<LayerImpl
> inner_clip
=
6407 LayerImpl::Create(layer_tree_impl
, kInnerViewportClipLayerId
);
6408 inner_clip
->SetBounds(inner_viewport
);
6410 scoped_ptr
<LayerImpl
> page_scale
=
6411 LayerImpl::Create(layer_tree_impl
, kPageScaleLayerId
);
6413 inner_scroll
->SetScrollClipLayer(inner_clip
->id());
6414 inner_scroll
->SetBounds(outer_viewport
);
6415 inner_scroll
->SetContentBounds(outer_viewport
);
6416 inner_scroll
->SetPosition(gfx::PointF());
6418 scoped_ptr
<LayerImpl
> outer_clip
=
6419 LayerImpl::Create(layer_tree_impl
, kOuterViewportClipLayerId
);
6420 outer_clip
->SetBounds(outer_viewport
);
6421 outer_clip
->SetIsContainerForFixedPositionLayers(true);
6423 scoped_ptr
<LayerImpl
> outer_scroll
=
6424 LayerImpl::Create(layer_tree_impl
, kOuterViewportScrollLayerId
);
6425 outer_scroll
->SetScrollClipLayer(outer_clip
->id());
6426 outer_scroll
->SetScrollOffset(gfx::Vector2d());
6427 outer_scroll
->SetBounds(content_size
);
6428 outer_scroll
->SetContentBounds(content_size
);
6429 outer_scroll
->SetPosition(gfx::PointF());
6431 scoped_ptr
<LayerImpl
> contents
=
6432 LayerImpl::Create(layer_tree_impl
, 8);
6433 contents
->SetDrawsContent(true);
6434 contents
->SetBounds(content_size
);
6435 contents
->SetContentBounds(content_size
);
6436 contents
->SetPosition(gfx::PointF());
6438 outer_scroll
->AddChild(contents
.Pass());
6439 outer_clip
->AddChild(outer_scroll
.Pass());
6440 inner_scroll
->AddChild(outer_clip
.Pass());
6441 page_scale
->AddChild(inner_scroll
.Pass());
6442 inner_clip
->AddChild(page_scale
.Pass());
6444 layer_tree_impl
->SetRootLayer(inner_clip
.Pass());
6445 layer_tree_impl
->SetViewportLayersFromIds(kPageScaleLayerId
,
6446 kInnerViewportScrollLayerId
, kOuterViewportScrollLayerId
);
6448 host_impl_
->active_tree()->DidBecomeActive();
6452 TEST_F(LayerTreeHostImplVirtualViewportTest
, FlingScrollBubblesToInner
) {
6453 gfx::Size content_size
= gfx::Size(100, 160);
6454 gfx::Size outer_viewport
= gfx::Size(50, 80);
6455 gfx::Size inner_viewport
= gfx::Size(25, 40);
6457 SetupVirtualViewportLayers(content_size
, outer_viewport
, inner_viewport
);
6459 LayerImpl
* outer_scroll
= host_impl_
->OuterViewportScrollLayer();
6460 LayerImpl
* inner_scroll
= host_impl_
->InnerViewportScrollLayer();
6463 gfx::Vector2dF inner_expected
;
6464 gfx::Vector2dF outer_expected
;
6465 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6466 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6468 // Make sure the fling goes to the outer viewport first
6469 EXPECT_EQ(InputHandler::ScrollStarted
,
6470 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6471 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6473 gfx::Vector2d
scroll_delta(inner_viewport
.width(), inner_viewport
.height());
6474 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6475 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6477 host_impl_
->ScrollEnd();
6479 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6480 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6482 // Fling past the outer viewport boundry, make sure inner viewport scrolls.
6483 EXPECT_EQ(InputHandler::ScrollStarted
,
6484 host_impl_
->ScrollBegin(gfx::Point(), InputHandler::Gesture
));
6485 EXPECT_EQ(InputHandler::ScrollStarted
, host_impl_
->FlingScrollBegin());
6487 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6488 outer_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6490 host_impl_
->ScrollBy(gfx::Point(), scroll_delta
);
6491 inner_expected
+= gfx::Vector2dF(scroll_delta
.x(), scroll_delta
.y());
6493 host_impl_
->ScrollEnd();
6495 EXPECT_VECTOR_EQ(inner_expected
, inner_scroll
->TotalScrollOffset());
6496 EXPECT_VECTOR_EQ(outer_expected
, outer_scroll
->TotalScrollOffset());
6500 class LayerTreeHostImplWithImplicitLimitsTest
: public LayerTreeHostImplTest
{
6502 virtual void SetUp() OVERRIDE
{
6503 LayerTreeSettings settings
= DefaultSettings();
6504 settings
.max_memory_for_prepaint_percentage
= 50;
6505 CreateHostImpl(settings
, CreateOutputSurface());
6509 TEST_F(LayerTreeHostImplWithImplicitLimitsTest
, ImplicitMemoryLimits
) {
6510 // Set up a memory policy and percentages which could cause
6511 // 32-bit integer overflows.
6512 ManagedMemoryPolicy
mem_policy(300 * 1024 * 1024); // 300MB
6514 // Verify implicit limits are calculated correctly with no overflows
6515 host_impl_
->SetMemoryPolicy(mem_policy
);
6516 EXPECT_EQ(host_impl_
->global_tile_state().hard_memory_limit_in_bytes
,
6517 300u * 1024u * 1024u);
6518 EXPECT_EQ(host_impl_
->global_tile_state().soft_memory_limit_in_bytes
,
6519 150u * 1024u * 1024u);
6522 TEST_F(LayerTreeHostImplTest
, UpdateTilesForMasksWithNoVisibleContent
) {
6523 gfx::Size
bounds(100000, 100);
6525 host_impl_
->CreatePendingTree();
6527 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl_
->pending_tree(), 1);
6529 scoped_ptr
<FakePictureLayerImpl
> layer_with_mask
=
6530 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 2);
6532 layer_with_mask
->SetBounds(bounds
);
6534 scoped_ptr
<FakePictureLayerImpl
> mask
=
6535 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 3);
6537 mask
->SetIsMask(true);
6538 mask
->SetBounds(bounds
);
6540 FakePictureLayerImpl
* pending_mask_content
= mask
.get();
6541 layer_with_mask
->SetMaskLayer(mask
.PassAs
<LayerImpl
>());
6543 scoped_ptr
<FakePictureLayerImpl
> child_of_layer_with_mask
=
6544 FakePictureLayerImpl::Create(host_impl_
->pending_tree(), 4);
6546 child_of_layer_with_mask
->SetBounds(bounds
);
6547 child_of_layer_with_mask
->SetDrawsContent(true);
6549 layer_with_mask
->AddChild(child_of_layer_with_mask
.PassAs
<LayerImpl
>());
6551 root
->AddChild(layer_with_mask
.PassAs
<LayerImpl
>());
6553 host_impl_
->pending_tree()->SetRootLayer(root
.Pass());
6555 gfx::Rect r1
= pending_mask_content
->visible_rect_for_tile_priority();
6556 ASSERT_EQ(0, r1
.x());
6557 ASSERT_EQ(0, r1
.y());
6558 ASSERT_EQ(0, r1
.width());
6559 ASSERT_EQ(0, r1
.height());
6561 host_impl_
->ActivatePendingTree();
6563 host_impl_
->active_tree()->UpdateDrawProperties();
6565 ASSERT_EQ(2u, host_impl_
->active_tree()->RenderSurfaceLayerList().size());
6567 FakePictureLayerImpl
* active_mask_content
=
6568 static_cast<FakePictureLayerImpl
*>(
6569 host_impl_
->active_tree()->root_layer()->children()[0]->mask_layer());
6570 gfx::Rect r2
= active_mask_content
->visible_rect_for_tile_priority();
6572 ASSERT_TRUE(!r2
.IsEmpty());