Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / trees / layer_tree_host_impl_unittest.cc
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.
4
5 #include "cc/trees/layer_tree_host_impl.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/containers/scoped_ptr_hash_map.h"
14 #include "cc/animation/scrollbar_animation_controller_thinning.h"
15 #include "cc/base/latency_info_swap_promise.h"
16 #include "cc/base/math_util.h"
17 #include "cc/input/page_scale_animation.h"
18 #include "cc/input/top_controls_manager.h"
19 #include "cc/layers/append_quads_data.h"
20 #include "cc/layers/delegated_renderer_layer_impl.h"
21 #include "cc/layers/heads_up_display_layer_impl.h"
22 #include "cc/layers/io_surface_layer_impl.h"
23 #include "cc/layers/layer_impl.h"
24 #include "cc/layers/painted_scrollbar_layer_impl.h"
25 #include "cc/layers/render_surface_impl.h"
26 #include "cc/layers/solid_color_layer_impl.h"
27 #include "cc/layers/solid_color_scrollbar_layer_impl.h"
28 #include "cc/layers/texture_layer_impl.h"
29 #include "cc/layers/tiled_layer_impl.h"
30 #include "cc/layers/video_layer_impl.h"
31 #include "cc/output/begin_frame_args.h"
32 #include "cc/output/compositor_frame_ack.h"
33 #include "cc/output/compositor_frame_metadata.h"
34 #include "cc/output/copy_output_request.h"
35 #include "cc/output/copy_output_result.h"
36 #include "cc/output/gl_renderer.h"
37 #include "cc/quads/render_pass_draw_quad.h"
38 #include "cc/quads/solid_color_draw_quad.h"
39 #include "cc/quads/texture_draw_quad.h"
40 #include "cc/quads/tile_draw_quad.h"
41 #include "cc/resources/layer_tiling_data.h"
42 #include "cc/test/animation_test_common.h"
43 #include "cc/test/begin_frame_args_test.h"
44 #include "cc/test/fake_layer_tree_host_impl.h"
45 #include "cc/test/fake_output_surface.h"
46 #include "cc/test/fake_output_surface_client.h"
47 #include "cc/test/fake_picture_layer_impl.h"
48 #include "cc/test/fake_picture_pile_impl.h"
49 #include "cc/test/fake_proxy.h"
50 #include "cc/test/fake_video_frame_provider.h"
51 #include "cc/test/geometry_test_utils.h"
52 #include "cc/test/layer_test_common.h"
53 #include "cc/test/render_pass_test_common.h"
54 #include "cc/test/test_gpu_memory_buffer_manager.h"
55 #include "cc/test/test_shared_bitmap_manager.h"
56 #include "cc/test/test_web_graphics_context_3d.h"
57 #include "cc/trees/layer_tree_impl.h"
58 #include "cc/trees/single_thread_proxy.h"
59 #include "media/base/media.h"
60 #include "testing/gmock/include/gmock/gmock.h"
61 #include "testing/gtest/include/gtest/gtest.h"
62 #include "third_party/skia/include/core/SkMallocPixelRef.h"
63 #include "ui/gfx/frame_time.h"
64 #include "ui/gfx/geometry/rect_conversions.h"
65 #include "ui/gfx/geometry/size_conversions.h"
66 #include "ui/gfx/geometry/vector2d_conversions.h"
67
68 using ::testing::Mock;
69 using ::testing::Return;
70 using ::testing::AnyNumber;
71 using ::testing::AtLeast;
72 using ::testing::_;
73 using media::VideoFrame;
74
75 namespace cc {
76 namespace {
77
78 class LayerTreeHostImplTest : public testing::Test,
79                               public LayerTreeHostImplClient {
80  public:
81   LayerTreeHostImplTest()
82       : proxy_(base::MessageLoopProxy::current(),
83                base::MessageLoopProxy::current()),
84         always_impl_thread_(&proxy_),
85         always_main_thread_blocked_(&proxy_),
86         shared_bitmap_manager_(new TestSharedBitmapManager),
87         gpu_memory_buffer_manager_(new TestGpuMemoryBufferManager),
88         on_can_draw_state_changed_called_(false),
89         did_notify_ready_to_activate_(false),
90         did_request_commit_(false),
91         did_request_redraw_(false),
92         did_request_animate_(false),
93         did_request_manage_tiles_(false),
94         did_upload_visible_tile_(false),
95         reduce_memory_result_(true),
96         current_limit_bytes_(0),
97         current_priority_cutoff_value_(0) {
98     media::InitializeMediaLibraryForTesting();
99   }
100
101   LayerTreeSettings DefaultSettings() {
102     LayerTreeSettings settings;
103     settings.minimum_occlusion_tracking_size = gfx::Size();
104     settings.impl_side_painting = true;
105     settings.texture_id_allocation_chunk_size = 1;
106     settings.report_overscroll_only_for_scrollable_axes = true;
107     settings.use_pinch_virtual_viewport = true;
108     return settings;
109   }
110
111   virtual void SetUp() override {
112     CreateHostImpl(DefaultSettings(), CreateOutputSurface());
113   }
114
115   virtual void TearDown() override {}
116
117   void UpdateRendererCapabilitiesOnImplThread() override {}
118   void DidLoseOutputSurfaceOnImplThread() override {}
119   void CommitVSyncParameters(base::TimeTicks timebase,
120                              base::TimeDelta interval) override {}
121   void SetEstimatedParentDrawTime(base::TimeDelta draw_time) override {}
122   void SetMaxSwapsPendingOnImplThread(int max) override {}
123   void DidSwapBuffersOnImplThread() override {}
124   void DidSwapBuffersCompleteOnImplThread() override {}
125   void OnCanDrawStateChanged(bool can_draw) override {
126     on_can_draw_state_changed_called_ = true;
127   }
128   void NotifyReadyToActivate() override {
129     did_notify_ready_to_activate_ = true;
130     host_impl_->ActivateSyncTree();
131   }
132   void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; }
133   void SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) override {
134     did_request_redraw_ = true;
135   }
136   void SetNeedsAnimateOnImplThread() override { did_request_animate_ = true; }
137   void SetNeedsManageTilesOnImplThread() override {
138     did_request_manage_tiles_ = true;
139   }
140   void DidInitializeVisibleTileOnImplThread() override {
141     did_upload_visible_tile_ = true;
142   }
143   void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; }
144   void PostAnimationEventsToMainThreadOnImplThread(
145       scoped_ptr<AnimationEventsVector> events) override {}
146   bool ReduceContentsTextureMemoryOnImplThread(size_t limit_bytes,
147                                                int priority_cutoff) override {
148     current_limit_bytes_ = limit_bytes;
149     current_priority_cutoff_value_ = priority_cutoff;
150     return reduce_memory_result_;
151   }
152   bool IsInsideDraw() override { return false; }
153   void RenewTreePriority() override {}
154   void PostDelayedScrollbarFadeOnImplThread(const base::Closure& start_fade,
155                                             base::TimeDelta delay) override {
156     scrollbar_fade_start_ = start_fade;
157     requested_scrollbar_animation_delay_ = delay;
158   }
159   void DidActivateSyncTree() override {}
160   void DidManageTiles() override {}
161
162   void set_reduce_memory_result(bool reduce_memory_result) {
163     reduce_memory_result_ = reduce_memory_result;
164   }
165
166   bool CreateHostImpl(const LayerTreeSettings& settings,
167                       scoped_ptr<OutputSurface> output_surface) {
168     host_impl_ = LayerTreeHostImpl::Create(settings,
169                                            this,
170                                            &proxy_,
171                                            &stats_instrumentation_,
172                                            shared_bitmap_manager_.get(),
173                                            gpu_memory_buffer_manager_.get(),
174                                            0);
175     bool init = host_impl_->InitializeRenderer(output_surface.Pass());
176     host_impl_->SetViewportSize(gfx::Size(10, 10));
177     return init;
178   }
179
180   void SetupRootLayerImpl(scoped_ptr<LayerImpl> root) {
181     root->SetPosition(gfx::PointF());
182     root->SetBounds(gfx::Size(10, 10));
183     root->SetContentBounds(gfx::Size(10, 10));
184     root->SetDrawsContent(true);
185     root->draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
186     host_impl_->active_tree()->SetRootLayer(root.Pass());
187   }
188
189   static void ExpectClearedScrollDeltasRecursive(LayerImpl* layer) {
190     ASSERT_EQ(layer->ScrollDelta(), gfx::Vector2d());
191     for (size_t i = 0; i < layer->children().size(); ++i)
192       ExpectClearedScrollDeltasRecursive(layer->children()[i]);
193   }
194
195   static void ExpectContains(const ScrollAndScaleSet& scroll_info,
196                              int id,
197                              const gfx::Vector2d& scroll_delta) {
198     int times_encountered = 0;
199
200     for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
201       if (scroll_info.scrolls[i].layer_id != id)
202         continue;
203       EXPECT_VECTOR_EQ(scroll_delta, scroll_info.scrolls[i].scroll_delta);
204       times_encountered++;
205     }
206
207     ASSERT_EQ(1, times_encountered);
208   }
209
210   static void ExpectNone(const ScrollAndScaleSet& scroll_info, int id) {
211     int times_encountered = 0;
212
213     for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) {
214       if (scroll_info.scrolls[i].layer_id != id)
215         continue;
216       times_encountered++;
217     }
218
219     ASSERT_EQ(0, times_encountered);
220   }
221
222   LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl,
223                                            const gfx::Size& content_size) {
224     const int kInnerViewportScrollLayerId = 2;
225     const int kInnerViewportClipLayerId = 4;
226     const int kPageScaleLayerId = 5;
227     scoped_ptr<LayerImpl> root =
228         LayerImpl::Create(layer_tree_impl, 1);
229     root->SetBounds(content_size);
230     root->SetContentBounds(content_size);
231     root->SetPosition(gfx::PointF());
232
233     scoped_ptr<LayerImpl> scroll =
234         LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
235     LayerImpl* scroll_layer = scroll.get();
236     scroll->SetIsContainerForFixedPositionLayers(true);
237     scroll->SetScrollOffset(gfx::ScrollOffset());
238
239     scoped_ptr<LayerImpl> clip =
240         LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
241     clip->SetBounds(
242         gfx::Size(content_size.width() / 2, content_size.height() / 2));
243
244     scoped_ptr<LayerImpl> page_scale =
245         LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
246
247     scroll->SetScrollClipLayer(clip->id());
248     scroll->SetBounds(content_size);
249     scroll->SetContentBounds(content_size);
250     scroll->SetPosition(gfx::PointF());
251     scroll->SetIsContainerForFixedPositionLayers(true);
252
253     scoped_ptr<LayerImpl> contents =
254         LayerImpl::Create(layer_tree_impl, 3);
255     contents->SetDrawsContent(true);
256     contents->SetBounds(content_size);
257     contents->SetContentBounds(content_size);
258     contents->SetPosition(gfx::PointF());
259
260     scroll->AddChild(contents.Pass());
261     page_scale->AddChild(scroll.Pass());
262     clip->AddChild(page_scale.Pass());
263     root->AddChild(clip.Pass());
264
265     layer_tree_impl->SetRootLayer(root.Pass());
266     layer_tree_impl->SetViewportLayersFromIds(
267         kPageScaleLayerId, kInnerViewportScrollLayerId, Layer::INVALID_ID);
268
269     return scroll_layer;
270   }
271
272   LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) {
273     LayerImpl* scroll_layer = CreateScrollAndContentsLayers(
274         host_impl_->active_tree(), content_size);
275     host_impl_->active_tree()->DidBecomeActive();
276     return scroll_layer;
277   }
278
279   // TODO(wjmaclean) Add clip-layer pointer to parameters.
280   scoped_ptr<LayerImpl> CreateScrollableLayer(int id,
281                                               const gfx::Size& size,
282                                               LayerImpl* clip_layer) {
283     DCHECK(clip_layer);
284     DCHECK(id != clip_layer->id());
285     scoped_ptr<LayerImpl> layer =
286         LayerImpl::Create(host_impl_->active_tree(), id);
287     layer->SetScrollClipLayer(clip_layer->id());
288     layer->SetDrawsContent(true);
289     layer->SetBounds(size);
290     layer->SetContentBounds(size);
291     clip_layer->SetBounds(gfx::Size(size.width() / 2, size.height() / 2));
292     return layer.Pass();
293   }
294
295   void DrawFrame() {
296     LayerTreeHostImpl::FrameData frame;
297     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
298     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
299     host_impl_->DidDrawAllLayers(frame);
300   }
301
302   void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor);
303   void pinch_zoom_pan_viewport_test(float device_scale_factor);
304   void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor);
305   void pinch_zoom_pan_viewport_and_scroll_boundary_test(
306       float device_scale_factor);
307
308   void CheckNotifyCalledIfCanDrawChanged(bool always_draw) {
309     // Note: It is not possible to disable the renderer once it has been set,
310     // so we do not need to test that disabling the renderer notifies us
311     // that can_draw changed.
312     EXPECT_FALSE(host_impl_->CanDraw());
313     on_can_draw_state_changed_called_ = false;
314
315     // Set up the root layer, which allows us to draw.
316     SetupScrollAndContentsLayers(gfx::Size(100, 100));
317     EXPECT_TRUE(host_impl_->CanDraw());
318     EXPECT_TRUE(on_can_draw_state_changed_called_);
319     on_can_draw_state_changed_called_ = false;
320
321     // Toggle the root layer to make sure it toggles can_draw
322     host_impl_->active_tree()->SetRootLayer(nullptr);
323     EXPECT_FALSE(host_impl_->CanDraw());
324     EXPECT_TRUE(on_can_draw_state_changed_called_);
325     on_can_draw_state_changed_called_ = false;
326
327     SetupScrollAndContentsLayers(gfx::Size(100, 100));
328     EXPECT_TRUE(host_impl_->CanDraw());
329     EXPECT_TRUE(on_can_draw_state_changed_called_);
330     on_can_draw_state_changed_called_ = false;
331
332     // Toggle the device viewport size to make sure it toggles can_draw.
333     host_impl_->SetViewportSize(gfx::Size());
334     if (always_draw) {
335       EXPECT_TRUE(host_impl_->CanDraw());
336     } else {
337       EXPECT_FALSE(host_impl_->CanDraw());
338     }
339     EXPECT_TRUE(on_can_draw_state_changed_called_);
340     on_can_draw_state_changed_called_ = false;
341
342     host_impl_->SetViewportSize(gfx::Size(100, 100));
343     EXPECT_TRUE(host_impl_->CanDraw());
344     EXPECT_TRUE(on_can_draw_state_changed_called_);
345     on_can_draw_state_changed_called_ = false;
346
347     // Toggle contents textures purged without causing any evictions,
348     // and make sure that it does not change can_draw.
349     set_reduce_memory_result(false);
350     host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
351         host_impl_->memory_allocation_limit_bytes() - 1));
352     EXPECT_TRUE(host_impl_->CanDraw());
353     EXPECT_FALSE(on_can_draw_state_changed_called_);
354     on_can_draw_state_changed_called_ = false;
355
356     // Toggle contents textures purged to make sure it toggles can_draw.
357     set_reduce_memory_result(true);
358     host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
359         host_impl_->memory_allocation_limit_bytes() - 1));
360     if (always_draw) {
361       EXPECT_TRUE(host_impl_->CanDraw());
362     } else {
363       EXPECT_FALSE(host_impl_->CanDraw());
364     }
365     EXPECT_TRUE(on_can_draw_state_changed_called_);
366     on_can_draw_state_changed_called_ = false;
367
368     host_impl_->active_tree()->ResetContentsTexturesPurged();
369     EXPECT_TRUE(host_impl_->CanDraw());
370     EXPECT_TRUE(on_can_draw_state_changed_called_);
371     on_can_draw_state_changed_called_ = false;
372   }
373
374   void SetupMouseMoveAtWithDeviceScale(float device_scale_factor);
375
376  protected:
377   virtual scoped_ptr<OutputSurface> CreateOutputSurface() {
378     return FakeOutputSurface::Create3d();
379   }
380
381   void DrawOneFrame() {
382     LayerTreeHostImpl::FrameData frame_data;
383     host_impl_->PrepareToDraw(&frame_data);
384     host_impl_->DidDrawAllLayers(frame_data);
385   }
386
387   FakeProxy proxy_;
388   DebugScopedSetImplThread always_impl_thread_;
389   DebugScopedSetMainThreadBlocked always_main_thread_blocked_;
390
391   scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
392   scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
393   scoped_ptr<LayerTreeHostImpl> host_impl_;
394   FakeRenderingStatsInstrumentation stats_instrumentation_;
395   bool on_can_draw_state_changed_called_;
396   bool did_notify_ready_to_activate_;
397   bool did_request_commit_;
398   bool did_request_redraw_;
399   bool did_request_animate_;
400   bool did_request_manage_tiles_;
401   bool did_upload_visible_tile_;
402   bool reduce_memory_result_;
403   base::Closure scrollbar_fade_start_;
404   base::TimeDelta requested_scrollbar_animation_delay_;
405   size_t current_limit_bytes_;
406   int current_priority_cutoff_value_;
407 };
408
409 TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) {
410   bool always_draw = false;
411   CheckNotifyCalledIfCanDrawChanged(always_draw);
412 }
413
414 TEST_F(LayerTreeHostImplTest, CanDrawIncompleteFrames) {
415   CreateHostImpl(DefaultSettings(),
416                  FakeOutputSurface::CreateAlwaysDrawAndSwap3d());
417
418   bool always_draw = true;
419   CheckNotifyCalledIfCanDrawChanged(always_draw);
420 }
421
422 TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) {
423   ASSERT_FALSE(host_impl_->active_tree()->root_layer());
424
425   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
426   ASSERT_EQ(scroll_info->scrolls.size(), 0u);
427 }
428
429 TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) {
430   {
431     scoped_ptr<LayerImpl> root =
432         LayerImpl::Create(host_impl_->active_tree(), 1);
433     root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 2));
434     root->AddChild(LayerImpl::Create(host_impl_->active_tree(), 3));
435     root->children()[1]->AddChild(
436         LayerImpl::Create(host_impl_->active_tree(), 4));
437     root->children()[1]->AddChild(
438         LayerImpl::Create(host_impl_->active_tree(), 5));
439     root->children()[1]->children()[0]->AddChild(
440         LayerImpl::Create(host_impl_->active_tree(), 6));
441     host_impl_->active_tree()->SetRootLayer(root.Pass());
442   }
443   LayerImpl* root = host_impl_->active_tree()->root_layer();
444
445   ExpectClearedScrollDeltasRecursive(root);
446
447   scoped_ptr<ScrollAndScaleSet> scroll_info;
448
449   scroll_info = host_impl_->ProcessScrollDeltas();
450   ASSERT_EQ(scroll_info->scrolls.size(), 0u);
451   ExpectClearedScrollDeltasRecursive(root);
452
453   scroll_info = host_impl_->ProcessScrollDeltas();
454   ASSERT_EQ(scroll_info->scrolls.size(), 0u);
455   ExpectClearedScrollDeltasRecursive(root);
456 }
457
458 TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
459   gfx::ScrollOffset scroll_offset(20, 30);
460   gfx::Vector2d scroll_delta(11, -15);
461   {
462     scoped_ptr<LayerImpl> root_clip =
463         LayerImpl::Create(host_impl_->active_tree(), 2);
464     scoped_ptr<LayerImpl> root =
465         LayerImpl::Create(host_impl_->active_tree(), 1);
466     root_clip->SetBounds(gfx::Size(10, 10));
467     LayerImpl* root_layer = root.get();
468     root_clip->AddChild(root.Pass());
469     root_layer->SetBounds(gfx::Size(110, 110));
470     root_layer->SetScrollClipLayer(root_clip->id());
471     root_layer->SetScrollOffset(scroll_offset);
472     root_layer->ScrollBy(scroll_delta);
473     host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
474   }
475   LayerImpl* root = host_impl_->active_tree()->root_layer()->children()[0];
476
477   scoped_ptr<ScrollAndScaleSet> scroll_info;
478
479   scroll_info = host_impl_->ProcessScrollDeltas();
480   ASSERT_EQ(scroll_info->scrolls.size(), 1u);
481   EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta);
482   ExpectContains(*scroll_info, root->id(), scroll_delta);
483
484   gfx::Vector2d scroll_delta2(-5, 27);
485   root->ScrollBy(scroll_delta2);
486   scroll_info = host_impl_->ProcessScrollDeltas();
487   ASSERT_EQ(scroll_info->scrolls.size(), 1u);
488   EXPECT_VECTOR_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
489   ExpectContains(*scroll_info, root->id(), scroll_delta + scroll_delta2);
490
491   root->ScrollBy(gfx::Vector2d());
492   scroll_info = host_impl_->ProcessScrollDeltas();
493   EXPECT_EQ(root->sent_scroll_delta(), scroll_delta + scroll_delta2);
494 }
495
496 TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
497   SetupScrollAndContentsLayers(gfx::Size(100, 100));
498   host_impl_->SetViewportSize(gfx::Size(50, 50));
499   DrawFrame();
500
501   EXPECT_EQ(InputHandler::ScrollStarted,
502             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
503   EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
504                                                       InputHandler::Wheel));
505   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
506   EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10),
507                                                       InputHandler::Wheel));
508   host_impl_->ScrollEnd();
509   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(),
510                                                        InputHandler::Wheel));
511   EXPECT_TRUE(did_request_redraw_);
512   EXPECT_TRUE(did_request_commit_);
513 }
514
515 TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) {
516   SetupScrollAndContentsLayers(gfx::Size(100, 100));
517   host_impl_->SetViewportSize(gfx::Size(50, 50));
518   DrawFrame();
519
520   EXPECT_EQ(InputHandler::ScrollStarted,
521             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
522   EXPECT_FALSE(host_impl_->IsActivelyScrolling());
523   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
524   EXPECT_TRUE(host_impl_->IsActivelyScrolling());
525   host_impl_->ScrollEnd();
526   EXPECT_FALSE(host_impl_->IsActivelyScrolling());
527 }
528
529 TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
530   // We should not crash when trying to scroll an empty layer tree.
531   EXPECT_EQ(InputHandler::ScrollIgnored,
532             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
533 }
534
535 TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
536   scoped_ptr<TestWebGraphicsContext3D> context_owned =
537       TestWebGraphicsContext3D::Create();
538   context_owned->set_context_lost(true);
539
540   // Initialization will fail.
541   EXPECT_FALSE(CreateHostImpl(
542       DefaultSettings(), FakeOutputSurface::Create3d(context_owned.Pass())));
543
544   SetupScrollAndContentsLayers(gfx::Size(100, 100));
545
546   // We should not crash when trying to scroll after the renderer initialization
547   // fails.
548   EXPECT_EQ(InputHandler::ScrollStarted,
549             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
550 }
551
552 TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
553   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
554   host_impl_->SetViewportSize(gfx::Size(50, 50));
555   DrawFrame();
556
557   // We should not crash if the tree is replaced while we are scrolling.
558   EXPECT_EQ(InputHandler::ScrollStarted,
559             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
560   host_impl_->active_tree()->DetachLayerTree();
561
562   scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
563
564   // We should still be scrolling, because the scrolled layer also exists in the
565   // new tree.
566   gfx::Vector2d scroll_delta(0, 10);
567   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
568   host_impl_->ScrollEnd();
569   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
570   ExpectContains(*scroll_info, scroll_layer->id(), scroll_delta);
571 }
572
573 TEST_F(LayerTreeHostImplTest, ClearRootRenderSurfaceAndScroll) {
574   SetupScrollAndContentsLayers(gfx::Size(100, 100));
575   host_impl_->SetViewportSize(gfx::Size(50, 50));
576   DrawFrame();
577
578   // We should be able to scroll even if the root layer loses its render surface
579   // after the most recent render.
580   host_impl_->active_tree()->root_layer()->ClearRenderSurface();
581   host_impl_->active_tree()->set_needs_update_draw_properties();
582
583   EXPECT_EQ(InputHandler::ScrollStarted,
584             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
585 }
586
587 TEST_F(LayerTreeHostImplTest, WheelEventHandlers) {
588   SetupScrollAndContentsLayers(gfx::Size(100, 100));
589   host_impl_->SetViewportSize(gfx::Size(50, 50));
590   DrawFrame();
591   LayerImpl* root = host_impl_->active_tree()->root_layer();
592
593   root->SetHaveWheelEventHandlers(true);
594
595   // With registered event handlers, wheel scrolls have to go to the main
596   // thread.
597   EXPECT_EQ(InputHandler::ScrollOnMainThread,
598             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
599
600   // But gesture scrolls can still be handled.
601   EXPECT_EQ(InputHandler::ScrollStarted,
602             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
603 }
604
605 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchscreen) {
606   SetupScrollAndContentsLayers(gfx::Size(100, 100));
607   host_impl_->SetViewportSize(gfx::Size(50, 50));
608   DrawFrame();
609
610   // Ignore the fling since no layer is being scrolled
611   EXPECT_EQ(InputHandler::ScrollIgnored,
612             host_impl_->FlingScrollBegin());
613
614   // Start scrolling a layer
615   EXPECT_EQ(InputHandler::ScrollStarted,
616             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
617
618   // Now the fling should go ahead since we've started scrolling a layer
619   EXPECT_EQ(InputHandler::ScrollStarted,
620             host_impl_->FlingScrollBegin());
621 }
622
623 TEST_F(LayerTreeHostImplTest, FlingOnlyWhenScrollingTouchpad) {
624   SetupScrollAndContentsLayers(gfx::Size(100, 100));
625   host_impl_->SetViewportSize(gfx::Size(50, 50));
626   DrawFrame();
627
628   // Ignore the fling since no layer is being scrolled
629   EXPECT_EQ(InputHandler::ScrollIgnored,
630             host_impl_->FlingScrollBegin());
631
632   // Start scrolling a layer
633   EXPECT_EQ(InputHandler::ScrollStarted,
634             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
635
636   // Now the fling should go ahead since we've started scrolling a layer
637   EXPECT_EQ(InputHandler::ScrollStarted,
638             host_impl_->FlingScrollBegin());
639 }
640
641 TEST_F(LayerTreeHostImplTest, NoFlingWhenScrollingOnMain) {
642   SetupScrollAndContentsLayers(gfx::Size(100, 100));
643   host_impl_->SetViewportSize(gfx::Size(50, 50));
644   DrawFrame();
645   LayerImpl* root = host_impl_->active_tree()->root_layer();
646
647   root->SetShouldScrollOnMainThread(true);
648
649   // Start scrolling a layer
650   EXPECT_EQ(InputHandler::ScrollOnMainThread,
651             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
652
653   // The fling should be ignored since there's no layer being scrolled impl-side
654   EXPECT_EQ(InputHandler::ScrollIgnored,
655             host_impl_->FlingScrollBegin());
656 }
657
658 TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
659   SetupScrollAndContentsLayers(gfx::Size(100, 100));
660   host_impl_->SetViewportSize(gfx::Size(50, 50));
661   DrawFrame();
662   LayerImpl* root = host_impl_->active_tree()->root_layer();
663
664   root->SetShouldScrollOnMainThread(true);
665
666   EXPECT_EQ(InputHandler::ScrollOnMainThread,
667             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
668   EXPECT_EQ(InputHandler::ScrollOnMainThread,
669             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
670 }
671
672 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
673   SetupScrollAndContentsLayers(gfx::Size(200, 200));
674   host_impl_->SetViewportSize(gfx::Size(100, 100));
675
676   LayerImpl* root = host_impl_->active_tree()->root_layer();
677   root->SetContentsScale(2.f, 2.f);
678   root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
679
680   DrawFrame();
681
682   // All scroll types inside the non-fast scrollable region should fail.
683   EXPECT_EQ(InputHandler::ScrollOnMainThread,
684             host_impl_->ScrollBegin(gfx::Point(25, 25),
685                                     InputHandler::Wheel));
686   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
687                                                        InputHandler::Wheel));
688   EXPECT_EQ(InputHandler::ScrollOnMainThread,
689             host_impl_->ScrollBegin(gfx::Point(25, 25),
690                                     InputHandler::Gesture));
691   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
692                                                        InputHandler::Gesture));
693
694   // All scroll types outside this region should succeed.
695   EXPECT_EQ(InputHandler::ScrollStarted,
696             host_impl_->ScrollBegin(gfx::Point(75, 75),
697                                     InputHandler::Wheel));
698   EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
699                                                       InputHandler::Gesture));
700   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
701   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25),
702                                                        InputHandler::Gesture));
703   host_impl_->ScrollEnd();
704   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
705                                                        InputHandler::Gesture));
706   EXPECT_EQ(InputHandler::ScrollStarted,
707             host_impl_->ScrollBegin(gfx::Point(75, 75),
708                                     InputHandler::Gesture));
709   EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
710                                                       InputHandler::Gesture));
711   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
712   host_impl_->ScrollEnd();
713   EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75),
714                                                        InputHandler::Gesture));
715 }
716
717 TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
718   SetupScrollAndContentsLayers(gfx::Size(200, 200));
719   host_impl_->SetViewportSize(gfx::Size(100, 100));
720
721   LayerImpl* root = host_impl_->active_tree()->root_layer();
722   root->SetContentsScale(2.f, 2.f);
723   root->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
724   root->SetPosition(gfx::PointF(-25.f, 0.f));
725
726   DrawFrame();
727
728   // This point would fall into the non-fast scrollable region except that we've
729   // moved the layer down by 25 pixels.
730   EXPECT_EQ(InputHandler::ScrollStarted,
731             host_impl_->ScrollBegin(gfx::Point(40, 10),
732                                     InputHandler::Wheel));
733   EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10),
734                                                       InputHandler::Wheel));
735   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 1));
736   host_impl_->ScrollEnd();
737
738   // This point is still inside the non-fast region.
739   EXPECT_EQ(InputHandler::ScrollOnMainThread,
740             host_impl_->ScrollBegin(gfx::Point(10, 10),
741                                     InputHandler::Wheel));
742 }
743
744 TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) {
745   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
746   EXPECT_FALSE(scroll_layer->have_scroll_event_handlers());
747   host_impl_->SetViewportSize(gfx::Size(50, 50));
748   DrawFrame();
749
750   EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
751   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
752   EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
753   host_impl_->ScrollEnd();
754   EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
755 }
756
757 TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) {
758   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
759   scroll_layer->SetHaveScrollEventHandlers(true);
760   host_impl_->SetViewportSize(gfx::Size(50, 50));
761   DrawFrame();
762
763   EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
764   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
765   EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler());
766   host_impl_->ScrollEnd();
767   EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
768 }
769
770 TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
771   SetupScrollAndContentsLayers(gfx::Size(200, 200));
772   host_impl_->SetViewportSize(gfx::Size(100, 100));
773
774   DrawFrame();
775
776   EXPECT_EQ(InputHandler::ScrollStarted,
777             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
778
779   // Trying to scroll to the left/top will not succeed.
780   EXPECT_FALSE(
781       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll);
782   EXPECT_FALSE(
783       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll);
784   EXPECT_FALSE(
785       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll);
786
787   // Scrolling to the right/bottom will succeed.
788   EXPECT_TRUE(
789       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0)).did_scroll);
790   EXPECT_TRUE(
791       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll);
792   EXPECT_TRUE(
793       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 10)).did_scroll);
794
795   // Scrolling to left/top will now succeed.
796   EXPECT_TRUE(
797       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll);
798   EXPECT_TRUE(
799       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10)).did_scroll);
800   EXPECT_TRUE(
801       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, -10)).did_scroll);
802
803   // Scrolling diagonally against an edge will succeed.
804   EXPECT_TRUE(
805       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -10)).did_scroll);
806   EXPECT_TRUE(
807       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 0)).did_scroll);
808   EXPECT_TRUE(
809       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-10, 10)).did_scroll);
810
811   // Trying to scroll more than the available space will also succeed.
812   EXPECT_TRUE(
813       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(5000, 5000)).did_scroll);
814 }
815
816 TEST_F(LayerTreeHostImplTest, ScrollVerticallyByPageReturnsCorrectValue) {
817   SetupScrollAndContentsLayers(gfx::Size(200, 2000));
818   host_impl_->SetViewportSize(gfx::Size(100, 1000));
819
820   DrawFrame();
821
822   EXPECT_EQ(InputHandler::ScrollStarted,
823             host_impl_->ScrollBegin(gfx::Point(),
824                                     InputHandler::Wheel));
825
826   // Trying to scroll without a vertical scrollbar will fail.
827   EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
828       gfx::Point(), SCROLL_FORWARD));
829   EXPECT_FALSE(host_impl_->ScrollVerticallyByPage(
830       gfx::Point(), SCROLL_BACKWARD));
831
832   scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar(
833       PaintedScrollbarLayerImpl::Create(
834           host_impl_->active_tree(),
835           20,
836           VERTICAL));
837   vertical_scrollbar->SetBounds(gfx::Size(15, 1000));
838   host_impl_->InnerViewportScrollLayer()->AddScrollbar(
839       vertical_scrollbar.get());
840
841   // Trying to scroll with a vertical scrollbar will succeed.
842   EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
843       gfx::Point(), SCROLL_FORWARD));
844   EXPECT_FLOAT_EQ(875.f,
845                   host_impl_->InnerViewportScrollLayer()->ScrollDelta().y());
846   EXPECT_TRUE(host_impl_->ScrollVerticallyByPage(
847       gfx::Point(), SCROLL_BACKWARD));
848 }
849
850 TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
851   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(200, 200));
852   host_impl_->SetViewportSize(gfx::Size(100, 100));
853
854   gfx::Size overflow_size(400, 400);
855   ASSERT_EQ(1u, scroll_layer->children().size());
856   LayerImpl* overflow = scroll_layer->children()[0];
857   overflow->SetBounds(overflow_size);
858   overflow->SetContentBounds(overflow_size);
859   overflow->SetScrollClipLayer(scroll_layer->parent()->id());
860   overflow->SetScrollOffset(gfx::ScrollOffset());
861   overflow->SetPosition(gfx::PointF());
862
863   DrawFrame();
864   gfx::Point scroll_position(10, 10);
865
866   EXPECT_EQ(InputHandler::ScrollStarted,
867             host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
868   EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
869   EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->TotalScrollOffset());
870
871   gfx::Vector2dF scroll_delta(10, 10);
872   host_impl_->ScrollBy(scroll_position, scroll_delta);
873   host_impl_->ScrollEnd();
874   EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
875   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
876
877   overflow->set_user_scrollable_horizontal(false);
878
879   EXPECT_EQ(InputHandler::ScrollStarted,
880             host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
881   EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->TotalScrollOffset());
882   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->TotalScrollOffset());
883
884   host_impl_->ScrollBy(scroll_position, scroll_delta);
885   host_impl_->ScrollEnd();
886   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
887   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
888
889   overflow->set_user_scrollable_vertical(false);
890
891   EXPECT_EQ(InputHandler::ScrollStarted,
892             host_impl_->ScrollBegin(scroll_position, InputHandler::Wheel));
893   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 0), scroll_layer->TotalScrollOffset());
894   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
895
896   host_impl_->ScrollBy(scroll_position, scroll_delta);
897   host_impl_->ScrollEnd();
898   EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 10), scroll_layer->TotalScrollOffset());
899   EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->TotalScrollOffset());
900 }
901
902 TEST_F(LayerTreeHostImplTest,
903        ClearRootRenderSurfaceAndHitTestTouchHandlerRegion) {
904   SetupScrollAndContentsLayers(gfx::Size(100, 100));
905   host_impl_->SetViewportSize(gfx::Size(50, 50));
906   DrawFrame();
907
908   // We should be able to hit test for touch event handlers even if the root
909   // layer loses its render surface after the most recent render.
910   host_impl_->active_tree()->root_layer()->ClearRenderSurface();
911   host_impl_->active_tree()->set_needs_update_draw_properties();
912
913   EXPECT_EQ(host_impl_->HaveTouchEventHandlersAt(gfx::Point()), false);
914 }
915
916 TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
917   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
918   host_impl_->SetViewportSize(gfx::Size(50, 50));
919   DrawFrame();
920
921   EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer());
922   LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
923   EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
924
925   float min_page_scale = 1.f, max_page_scale = 4.f;
926   float page_scale_factor = 1.f;
927
928   // The impl-based pinch zoom should adjust the max scroll position.
929   {
930     host_impl_->active_tree()->SetPageScaleFactorAndLimits(
931         page_scale_factor, min_page_scale, max_page_scale);
932     host_impl_->active_tree()->SetPageScaleDelta(1.f);
933     scroll_layer->SetScrollDelta(gfx::Vector2d());
934
935     float page_scale_delta = 2.f;
936
937     host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
938     host_impl_->PinchGestureBegin();
939     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
940     host_impl_->PinchGestureEnd();
941     host_impl_->ScrollEnd();
942     EXPECT_FALSE(did_request_animate_);
943     EXPECT_TRUE(did_request_redraw_);
944     EXPECT_TRUE(did_request_commit_);
945     EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
946
947     scoped_ptr<ScrollAndScaleSet> scroll_info =
948         host_impl_->ProcessScrollDeltas();
949     EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
950
951     EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0).ToString(),
952               scroll_layer->MaxScrollOffset().ToString());
953   }
954
955   // Scrolling after a pinch gesture should always be in local space.  The
956   // scroll deltas do not have the page scale factor applied.
957   {
958     host_impl_->active_tree()->SetPageScaleFactorAndLimits(
959         page_scale_factor, min_page_scale, max_page_scale);
960     host_impl_->active_tree()->SetPageScaleDelta(1.f);
961     scroll_layer->SetScrollDelta(gfx::Vector2d());
962
963     float page_scale_delta = 2.f;
964     host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
965     host_impl_->PinchGestureBegin();
966     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
967     host_impl_->PinchGestureEnd();
968     host_impl_->ScrollEnd();
969
970     gfx::Vector2d scroll_delta(0, 10);
971     EXPECT_EQ(InputHandler::ScrollStarted,
972               host_impl_->ScrollBegin(gfx::Point(5, 5),
973                                       InputHandler::Wheel));
974     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
975     host_impl_->ScrollEnd();
976
977     scoped_ptr<ScrollAndScaleSet> scroll_info =
978         host_impl_->ProcessScrollDeltas();
979     ExpectContains(*scroll_info.get(),
980                    scroll_layer->id(),
981                    scroll_delta);
982   }
983 }
984
985 TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
986   ui::LatencyInfo latency_info;
987   latency_info.trace_id = 1234;
988   scoped_ptr<SwapPromise> swap_promise(
989       new LatencyInfoSwapPromise(latency_info));
990
991   SetupScrollAndContentsLayers(gfx::Size(100, 100));
992   EXPECT_EQ(InputHandler::ScrollStarted,
993             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
994   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
995   host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(swap_promise.Pass());
996   host_impl_->ScrollEnd();
997
998   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
999   EXPECT_EQ(1u, scroll_info->swap_promises.size());
1000   EXPECT_EQ(latency_info.trace_id, scroll_info->swap_promises[0]->TraceId());
1001 }
1002
1003 TEST_F(LayerTreeHostImplTest, PinchGesture) {
1004   SetupScrollAndContentsLayers(gfx::Size(100, 100));
1005   host_impl_->SetViewportSize(gfx::Size(50, 50));
1006   DrawFrame();
1007
1008   LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
1009   DCHECK(scroll_layer);
1010
1011   float min_page_scale = 1.f;
1012   float max_page_scale = 4.f;
1013
1014   // Basic pinch zoom in gesture
1015   {
1016     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1017                                                            min_page_scale,
1018                                                            max_page_scale);
1019     scroll_layer->SetScrollDelta(gfx::Vector2d());
1020
1021     float page_scale_delta = 2.f;
1022     host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
1023     host_impl_->PinchGestureBegin();
1024     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
1025     host_impl_->PinchGestureEnd();
1026     host_impl_->ScrollEnd();
1027     EXPECT_FALSE(did_request_animate_);
1028     EXPECT_TRUE(did_request_redraw_);
1029     EXPECT_TRUE(did_request_commit_);
1030
1031     scoped_ptr<ScrollAndScaleSet> scroll_info =
1032         host_impl_->ProcessScrollDeltas();
1033     EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1034   }
1035
1036   // Zoom-in clamping
1037   {
1038     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1039                                                            min_page_scale,
1040                                                            max_page_scale);
1041     scroll_layer->SetScrollDelta(gfx::Vector2d());
1042     float page_scale_delta = 10.f;
1043
1044     host_impl_->ScrollBegin(gfx::Point(50, 50), InputHandler::Gesture);
1045     host_impl_->PinchGestureBegin();
1046     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
1047     host_impl_->PinchGestureEnd();
1048     host_impl_->ScrollEnd();
1049
1050     scoped_ptr<ScrollAndScaleSet> scroll_info =
1051         host_impl_->ProcessScrollDeltas();
1052     EXPECT_EQ(scroll_info->page_scale_delta, max_page_scale);
1053   }
1054
1055   // Zoom-out clamping
1056   {
1057     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1058                                                            min_page_scale,
1059                                                            max_page_scale);
1060     scroll_layer->SetScrollDelta(gfx::Vector2d());
1061     scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
1062
1063     float page_scale_delta = 0.1f;
1064     host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
1065     host_impl_->PinchGestureBegin();
1066     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
1067     host_impl_->PinchGestureEnd();
1068     host_impl_->ScrollEnd();
1069
1070     scoped_ptr<ScrollAndScaleSet> scroll_info =
1071         host_impl_->ProcessScrollDeltas();
1072     EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
1073
1074     EXPECT_TRUE(scroll_info->scrolls.empty());
1075   }
1076
1077   // Two-finger panning should not happen based on pinch events only
1078   {
1079     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1080                                                            min_page_scale,
1081                                                            max_page_scale);
1082     scroll_layer->SetScrollDelta(gfx::Vector2d());
1083     scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20));
1084
1085     float page_scale_delta = 1.f;
1086     host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
1087     host_impl_->PinchGestureBegin();
1088     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
1089     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
1090     host_impl_->PinchGestureEnd();
1091     host_impl_->ScrollEnd();
1092
1093     scoped_ptr<ScrollAndScaleSet> scroll_info =
1094         host_impl_->ProcessScrollDeltas();
1095     EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1096     EXPECT_TRUE(scroll_info->scrolls.empty());
1097   }
1098
1099   // Two-finger panning should work with interleaved scroll events
1100   {
1101     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1102                                                            min_page_scale,
1103                                                            max_page_scale);
1104     scroll_layer->SetScrollDelta(gfx::Vector2d());
1105     scroll_layer->SetScrollOffset(gfx::ScrollOffset(20, 20));
1106
1107     float page_scale_delta = 1.f;
1108     host_impl_->ScrollBegin(gfx::Point(10, 10), InputHandler::Gesture);
1109     host_impl_->PinchGestureBegin();
1110     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
1111     host_impl_->ScrollBy(gfx::Point(10, 10), gfx::Vector2d(-10, -10));
1112     host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
1113     host_impl_->PinchGestureEnd();
1114     host_impl_->ScrollEnd();
1115
1116     scoped_ptr<ScrollAndScaleSet> scroll_info =
1117         host_impl_->ProcessScrollDeltas();
1118     EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta);
1119     ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-10, -10));
1120   }
1121
1122   // Two-finger panning should work when starting fully zoomed out.
1123   {
1124     host_impl_->active_tree()->SetPageScaleFactorAndLimits(0.5f,
1125                                                            0.5f,
1126                                                            4.f);
1127     scroll_layer->SetScrollDelta(gfx::Vector2d());
1128     scroll_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
1129
1130     host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Gesture);
1131     host_impl_->PinchGestureBegin();
1132     host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
1133     host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
1134     host_impl_->ScrollBy(gfx::Point(0, 0), gfx::Vector2d(10, 10));
1135     host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
1136     host_impl_->PinchGestureEnd();
1137     host_impl_->ScrollEnd();
1138
1139     scoped_ptr<ScrollAndScaleSet> scroll_info =
1140         host_impl_->ProcessScrollDeltas();
1141     EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
1142     ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(20, 20));
1143   }
1144 }
1145
1146 TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
1147   SetupScrollAndContentsLayers(gfx::Size(100, 100));
1148   host_impl_->SetViewportSize(gfx::Size(50, 50));
1149   DrawFrame();
1150
1151   LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
1152   DCHECK(scroll_layer);
1153
1154   float min_page_scale = 0.5f;
1155   float max_page_scale = 4.f;
1156   base::TimeTicks start_time = base::TimeTicks() +
1157                                base::TimeDelta::FromSeconds(1);
1158   base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1159   base::TimeTicks halfway_through_animation = start_time + duration / 2;
1160   base::TimeTicks end_time = start_time + duration;
1161
1162   // Non-anchor zoom-in
1163   {
1164     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1165                                                            min_page_scale,
1166                                                            max_page_scale);
1167     scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
1168
1169     did_request_redraw_ = false;
1170     did_request_animate_ = false;
1171     host_impl_->active_tree()->SetPageScaleAnimation(
1172         gfx::Vector2d(),
1173         false,
1174         2.f,
1175         duration);
1176     host_impl_->ActivateSyncTree();
1177     EXPECT_FALSE(did_request_redraw_);
1178     EXPECT_TRUE(did_request_animate_);
1179
1180     did_request_redraw_ = false;
1181     did_request_animate_ = false;
1182     host_impl_->Animate(start_time);
1183     EXPECT_TRUE(did_request_redraw_);
1184     EXPECT_TRUE(did_request_animate_);
1185
1186     did_request_redraw_ = false;
1187     did_request_animate_ = false;
1188     host_impl_->Animate(halfway_through_animation);
1189     EXPECT_TRUE(did_request_redraw_);
1190     EXPECT_TRUE(did_request_animate_);
1191
1192     did_request_redraw_ = false;
1193     did_request_animate_ = false;
1194     did_request_commit_ = false;
1195     host_impl_->Animate(end_time);
1196     EXPECT_TRUE(did_request_commit_);
1197     EXPECT_FALSE(did_request_animate_);
1198
1199     scoped_ptr<ScrollAndScaleSet> scroll_info =
1200         host_impl_->ProcessScrollDeltas();
1201     EXPECT_EQ(scroll_info->page_scale_delta, 2);
1202     ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1203   }
1204
1205   // Anchor zoom-out
1206   {
1207     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1208                                                            min_page_scale,
1209                                                            max_page_scale);
1210     scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
1211
1212     did_request_redraw_ = false;
1213     did_request_animate_ = false;
1214     host_impl_->active_tree()->SetPageScaleAnimation(
1215         gfx::Vector2d(25, 25), true, min_page_scale, duration);
1216     host_impl_->ActivateSyncTree();
1217     EXPECT_FALSE(did_request_redraw_);
1218     EXPECT_TRUE(did_request_animate_);
1219
1220     did_request_redraw_ = false;
1221     did_request_animate_ = false;
1222     host_impl_->Animate(start_time);
1223     EXPECT_TRUE(did_request_redraw_);
1224     EXPECT_TRUE(did_request_animate_);
1225
1226     did_request_redraw_ = false;
1227     did_request_commit_ = false;
1228     did_request_animate_ = false;
1229     host_impl_->Animate(end_time);
1230     EXPECT_TRUE(did_request_redraw_);
1231     EXPECT_FALSE(did_request_animate_);
1232     EXPECT_TRUE(did_request_commit_);
1233
1234     scoped_ptr<ScrollAndScaleSet> scroll_info =
1235         host_impl_->ProcessScrollDeltas();
1236     EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale);
1237     // Pushed to (0,0) via clamping against contents layer size.
1238     ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1239   }
1240 }
1241
1242 TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
1243   SetupScrollAndContentsLayers(gfx::Size(100, 100));
1244   host_impl_->SetViewportSize(gfx::Size(50, 50));
1245   DrawFrame();
1246
1247   LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
1248   DCHECK(scroll_layer);
1249
1250   float min_page_scale = 0.5f;
1251   float max_page_scale = 4.f;
1252   base::TimeTicks start_time = base::TimeTicks() +
1253                                base::TimeDelta::FromSeconds(1);
1254   base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1255   base::TimeTicks halfway_through_animation = start_time + duration / 2;
1256   base::TimeTicks end_time = start_time + duration;
1257
1258   // Anchor zoom with unchanged page scale should not change scroll or scale.
1259   {
1260     host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f,
1261                                                            min_page_scale,
1262                                                            max_page_scale);
1263     scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
1264
1265     host_impl_->active_tree()->SetPageScaleAnimation(
1266         gfx::Vector2d(),
1267         true,
1268         1.f,
1269         duration);
1270     host_impl_->ActivateSyncTree();
1271     host_impl_->Animate(start_time);
1272     host_impl_->Animate(halfway_through_animation);
1273     EXPECT_TRUE(did_request_redraw_);
1274     host_impl_->Animate(end_time);
1275     EXPECT_TRUE(did_request_commit_);
1276
1277     scoped_ptr<ScrollAndScaleSet> scroll_info =
1278         host_impl_->ProcessScrollDeltas();
1279     EXPECT_EQ(scroll_info->page_scale_delta, 1);
1280     ExpectNone(*scroll_info, scroll_layer->id());
1281   }
1282 }
1283
1284 TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
1285   host_impl_->CreatePendingTree();
1286   CreateScrollAndContentsLayers(
1287       host_impl_->pending_tree(),
1288       gfx::Size(100, 100));
1289   host_impl_->ActivateSyncTree();
1290   DrawFrame();
1291
1292   LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer();
1293   DCHECK(scroll_layer);
1294
1295   float min_page_scale = 0.5f;
1296   float max_page_scale = 4.f;
1297   host_impl_->sync_tree()->SetPageScaleFactorAndLimits(1.f,
1298                                                        min_page_scale,
1299                                                        max_page_scale);
1300   host_impl_->ActivateSyncTree();
1301
1302   base::TimeTicks start_time = base::TimeTicks() +
1303                                base::TimeDelta::FromSeconds(1);
1304   base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
1305   base::TimeTicks third_through_animation = start_time + duration / 3;
1306   base::TimeTicks halfway_through_animation = start_time + duration / 2;
1307   base::TimeTicks end_time = start_time + duration;
1308   float target_scale = 2.f;
1309
1310   scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
1311
1312   // Make sure TakePageScaleAnimation works properly.
1313   host_impl_->sync_tree()->SetPageScaleAnimation(
1314       gfx::Vector2d(),
1315       false,
1316       target_scale,
1317       duration);
1318   scoped_ptr<PageScaleAnimation> psa =
1319       host_impl_->sync_tree()->TakePageScaleAnimation();
1320   EXPECT_EQ(target_scale, psa->target_page_scale_factor());
1321   EXPECT_EQ(duration, psa->duration());
1322   EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation());
1323
1324   // Recreate the PSA. Nothing should happen here since the tree containing the
1325   // PSA hasn't been activated yet.
1326   did_request_redraw_ = false;
1327   did_request_animate_ = false;
1328   host_impl_->sync_tree()->SetPageScaleAnimation(
1329       gfx::Vector2d(),
1330       false,
1331       target_scale,
1332       duration);
1333   host_impl_->Animate(halfway_through_animation);
1334   EXPECT_FALSE(did_request_animate_);
1335   EXPECT_FALSE(did_request_redraw_);
1336
1337   // Activate the sync tree. This should cause the animation to become enabled.
1338   // It should also clear the pointer on the sync tree.
1339   host_impl_->ActivateSyncTree();
1340   EXPECT_EQ(nullptr, host_impl_->sync_tree()->TakePageScaleAnimation().get());
1341   EXPECT_FALSE(did_request_redraw_);
1342   EXPECT_TRUE(did_request_animate_);
1343
1344   // From here on, make sure the animation runs as normal.
1345   did_request_redraw_ = false;
1346   did_request_animate_ = false;
1347   host_impl_->Animate(start_time);
1348   EXPECT_TRUE(did_request_redraw_);
1349   EXPECT_TRUE(did_request_animate_);
1350
1351   did_request_redraw_ = false;
1352   did_request_animate_ = false;
1353   host_impl_->Animate(third_through_animation);
1354   EXPECT_TRUE(did_request_redraw_);
1355   EXPECT_TRUE(did_request_animate_);
1356
1357   // Another activation shouldn't have any effect on the animation.
1358   host_impl_->ActivateSyncTree();
1359
1360   did_request_redraw_ = false;
1361   did_request_animate_ = false;
1362   host_impl_->Animate(halfway_through_animation);
1363   EXPECT_TRUE(did_request_redraw_);
1364   EXPECT_TRUE(did_request_animate_);
1365
1366   did_request_redraw_ = false;
1367   did_request_animate_ = false;
1368   did_request_commit_ = false;
1369   host_impl_->Animate(end_time);
1370   EXPECT_TRUE(did_request_commit_);
1371   EXPECT_FALSE(did_request_animate_);
1372
1373   scoped_ptr<ScrollAndScaleSet> scroll_info =
1374       host_impl_->ProcessScrollDeltas();
1375   EXPECT_EQ(scroll_info->page_scale_delta, target_scale);
1376   ExpectContains(*scroll_info, scroll_layer->id(), gfx::Vector2d(-50, -50));
1377 }
1378
1379 class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
1380  public:
1381   LayerTreeHostImplOverridePhysicalTime(
1382       const LayerTreeSettings& settings,
1383       LayerTreeHostImplClient* client,
1384       Proxy* proxy,
1385       SharedBitmapManager* manager,
1386       RenderingStatsInstrumentation* rendering_stats_instrumentation)
1387       : LayerTreeHostImpl(settings,
1388                           client,
1389                           proxy,
1390                           rendering_stats_instrumentation,
1391                           manager,
1392                           NULL,
1393                           0) {}
1394
1395   BeginFrameArgs CurrentBeginFrameArgs() const override {
1396     return CreateBeginFrameArgsForTesting(fake_current_physical_time_);
1397   }
1398
1399   void SetCurrentPhysicalTimeTicksForTest(base::TimeTicks fake_now) {
1400     fake_current_physical_time_ = fake_now;
1401   }
1402
1403  private:
1404   base::TimeTicks fake_current_physical_time_;
1405 };
1406
1407 #define SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST()                           \
1408   gfx::Size viewport_size(10, 10);                                            \
1409   gfx::Size content_size(100, 100);                                           \
1410                                                                               \
1411   LayerTreeHostImplOverridePhysicalTime* host_impl_override_time =            \
1412       new LayerTreeHostImplOverridePhysicalTime(settings,                     \
1413                                                 this,                         \
1414                                                 &proxy_,                      \
1415                                                 shared_bitmap_manager_.get(), \
1416                                                 &stats_instrumentation_);     \
1417   host_impl_ = make_scoped_ptr(host_impl_override_time);                      \
1418   host_impl_->InitializeRenderer(CreateOutputSurface());                      \
1419   host_impl_->SetViewportSize(viewport_size);                                 \
1420                                                                               \
1421   scoped_ptr<LayerImpl> root =                                                \
1422       LayerImpl::Create(host_impl_->active_tree(), 1);                        \
1423   root->SetBounds(viewport_size);                                             \
1424                                                                               \
1425   scoped_ptr<LayerImpl> scroll =                                              \
1426       LayerImpl::Create(host_impl_->active_tree(), 2);                        \
1427   scroll->SetScrollClipLayer(root->id());                                     \
1428   scroll->SetScrollOffset(gfx::ScrollOffset());                               \
1429   root->SetBounds(viewport_size);                                             \
1430   scroll->SetBounds(content_size);                                            \
1431   scroll->SetContentBounds(content_size);                                     \
1432   scroll->SetIsContainerForFixedPositionLayers(true);                         \
1433                                                                               \
1434   scoped_ptr<LayerImpl> contents =                                            \
1435       LayerImpl::Create(host_impl_->active_tree(), 3);                        \
1436   contents->SetDrawsContent(true);                                            \
1437   contents->SetBounds(content_size);                                          \
1438   contents->SetContentBounds(content_size);                                   \
1439                                                                               \
1440   scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar =                        \
1441       SolidColorScrollbarLayerImpl::Create(                                   \
1442           host_impl_->active_tree(), 4, VERTICAL, 10, 0, false, true);        \
1443   EXPECT_FLOAT_EQ(0.f, scrollbar->opacity());                                 \
1444                                                                               \
1445   scroll->AddChild(contents.Pass());                                          \
1446   root->AddChild(scroll.Pass());                                              \
1447   scrollbar->SetScrollLayerAndClipLayerByIds(2, 1);                           \
1448   root->AddChild(scrollbar.Pass());                                           \
1449                                                                               \
1450   host_impl_->active_tree()->SetRootLayer(root.Pass());                       \
1451   host_impl_->active_tree()->SetViewportLayersFromIds(                        \
1452       1, 2, Layer::INVALID_ID);                                               \
1453   host_impl_->active_tree()->DidBecomeActive();                               \
1454   DrawFrame();
1455
1456 TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
1457   LayerTreeSettings settings;
1458   settings.scrollbar_animator = LayerTreeSettings::LinearFade;
1459   settings.scrollbar_fade_delay_ms = 20;
1460   settings.scrollbar_fade_duration_ms = 20;
1461
1462   SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1463
1464   base::TimeTicks fake_now = gfx::FrameTime::Now();
1465
1466   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1467   EXPECT_FALSE(did_request_redraw_);
1468
1469   // If no scroll happened during a scroll gesture, it should have no effect.
1470   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1471   host_impl_->ScrollEnd();
1472   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1473   EXPECT_FALSE(did_request_redraw_);
1474   EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
1475
1476   // After a scroll, a fade animation should be scheduled about 20ms from now.
1477   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1478   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 5));
1479   host_impl_->ScrollEnd();
1480   did_request_redraw_ = false;
1481   did_request_animate_ = false;
1482   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1483             requested_scrollbar_animation_delay_);
1484   EXPECT_FALSE(did_request_redraw_);
1485   EXPECT_FALSE(did_request_animate_);
1486   requested_scrollbar_animation_delay_ = base::TimeDelta();
1487   scrollbar_fade_start_.Run();
1488   host_impl_->Animate(fake_now);
1489
1490   // After the fade begins, we should start getting redraws instead of a
1491   // scheduled animation.
1492   fake_now += base::TimeDelta::FromMilliseconds(25);
1493   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1494   EXPECT_TRUE(did_request_animate_);
1495   did_request_animate_ = false;
1496
1497   // Setting the scroll offset outside a scroll should also cause the scrollbar
1498   // to appear and to schedule a fade.
1499   host_impl_->InnerViewportScrollLayer()->SetScrollOffset(
1500       gfx::ScrollOffset(5, 5));
1501   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1502             requested_scrollbar_animation_delay_);
1503   EXPECT_FALSE(did_request_redraw_);
1504   EXPECT_FALSE(did_request_animate_);
1505   requested_scrollbar_animation_delay_ = base::TimeDelta();
1506
1507   // Unnecessarily Fade animation of solid color scrollbar is not triggered.
1508   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1509   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1510   host_impl_->ScrollEnd();
1511   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1512 }
1513
1514 TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
1515   LayerTreeSettings settings;
1516   settings.scrollbar_animator = LayerTreeSettings::LinearFade;
1517   settings.scrollbar_fade_delay_ms = 20;
1518   settings.scrollbar_fade_duration_ms = 20;
1519   settings.use_pinch_zoom_scrollbars = true;
1520
1521   SETUP_LAYERS_FOR_SCROLLBAR_ANIMATION_TEST();
1522
1523   base::TimeTicks fake_now = gfx::FrameTime::Now();
1524
1525   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f);
1526
1527   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1528   EXPECT_FALSE(did_request_animate_);
1529
1530   // If no scroll happened during a scroll gesture, it should have no effect.
1531   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1532   host_impl_->ScrollEnd();
1533   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1534   EXPECT_FALSE(did_request_animate_);
1535   EXPECT_TRUE(scrollbar_fade_start_.Equals(base::Closure()));
1536
1537   // After a scroll, no fade animation should be scheduled.
1538   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1539   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1540   host_impl_->ScrollEnd();
1541   did_request_redraw_ = false;
1542   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1543   EXPECT_FALSE(did_request_animate_);
1544   requested_scrollbar_animation_delay_ = base::TimeDelta();
1545
1546   // We should not see any draw requests.
1547   fake_now += base::TimeDelta::FromMilliseconds(25);
1548   EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
1549   EXPECT_FALSE(did_request_animate_);
1550
1551   // Make page scale > min so that subsequent scrolls will trigger fades.
1552   host_impl_->active_tree()->SetPageScaleDelta(1.1f);
1553
1554   // After a scroll, a fade animation should be scheduled about 20ms from now.
1555   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
1556   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
1557   host_impl_->ScrollEnd();
1558   did_request_redraw_ = false;
1559   EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
1560             requested_scrollbar_animation_delay_);
1561   EXPECT_FALSE(did_request_animate_);
1562   requested_scrollbar_animation_delay_ = base::TimeDelta();
1563   scrollbar_fade_start_.Run();
1564
1565   // After the fade begins, we should start getting redraws instead of a
1566   // scheduled animation.
1567   fake_now += base::TimeDelta::FromMilliseconds(25);
1568   host_impl_->Animate(fake_now);
1569   EXPECT_TRUE(did_request_animate_);
1570 }
1571
1572 void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
1573     float device_scale_factor) {
1574   LayerTreeSettings settings;
1575   settings.scrollbar_fade_delay_ms = 500;
1576   settings.scrollbar_fade_duration_ms = 300;
1577   settings.scrollbar_animator = LayerTreeSettings::Thinning;
1578
1579   gfx::Size viewport_size(300, 200);
1580   gfx::Size device_viewport_size = gfx::ToFlooredSize(
1581       gfx::ScaleSize(viewport_size, device_scale_factor));
1582   gfx::Size content_size(1000, 1000);
1583
1584   CreateHostImpl(settings, CreateOutputSurface());
1585   host_impl_->SetDeviceScaleFactor(device_scale_factor);
1586   host_impl_->SetViewportSize(device_viewport_size);
1587
1588   scoped_ptr<LayerImpl> root =
1589       LayerImpl::Create(host_impl_->active_tree(), 1);
1590   root->SetBounds(viewport_size);
1591
1592   scoped_ptr<LayerImpl> scroll =
1593       LayerImpl::Create(host_impl_->active_tree(), 2);
1594   scroll->SetScrollClipLayer(root->id());
1595   scroll->SetScrollOffset(gfx::ScrollOffset());
1596   scroll->SetBounds(content_size);
1597   scroll->SetContentBounds(content_size);
1598   scroll->SetIsContainerForFixedPositionLayers(true);
1599
1600   scoped_ptr<LayerImpl> contents =
1601       LayerImpl::Create(host_impl_->active_tree(), 3);
1602   contents->SetDrawsContent(true);
1603   contents->SetBounds(content_size);
1604   contents->SetContentBounds(content_size);
1605
1606   // The scrollbar is on the right side.
1607   scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
1608       PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
1609   scrollbar->SetDrawsContent(true);
1610   scrollbar->SetBounds(gfx::Size(15, viewport_size.height()));
1611   scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
1612   scrollbar->SetPosition(gfx::Point(285, 0));
1613
1614   scroll->AddChild(contents.Pass());
1615   root->AddChild(scroll.Pass());
1616   scrollbar->SetScrollLayerAndClipLayerByIds(2, 1);
1617   root->AddChild(scrollbar.Pass());
1618
1619   host_impl_->active_tree()->SetRootLayer(root.Pass());
1620   host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID);
1621   host_impl_->active_tree()->DidBecomeActive();
1622   DrawFrame();
1623
1624   LayerImpl* root_scroll =
1625       host_impl_->active_tree()->InnerViewportScrollLayer();
1626   ASSERT_TRUE(root_scroll->scrollbar_animation_controller());
1627   ScrollbarAnimationControllerThinning* scrollbar_animation_controller =
1628       static_cast<ScrollbarAnimationControllerThinning*>(
1629           root_scroll->scrollbar_animation_controller());
1630   scrollbar_animation_controller->set_mouse_move_distance_for_test(100.f);
1631
1632   host_impl_->MouseMoveAt(gfx::Point(1, 1));
1633   EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
1634
1635   host_impl_->MouseMoveAt(gfx::Point(200, 50));
1636   EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
1637
1638   host_impl_->MouseMoveAt(gfx::Point(184, 100));
1639   EXPECT_FALSE(scrollbar_animation_controller->mouse_is_near_scrollbar());
1640
1641   scrollbar_animation_controller->set_mouse_move_distance_for_test(102.f);
1642   host_impl_->MouseMoveAt(gfx::Point(184, 100));
1643   EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar());
1644
1645   did_request_redraw_ = false;
1646   EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1647   host_impl_->MouseMoveAt(gfx::Point(290, 100));
1648   EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1649   host_impl_->MouseMoveAt(gfx::Point(290, 120));
1650   EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1651   host_impl_->MouseMoveAt(gfx::Point(150, 120));
1652   EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
1653 }
1654
1655 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
1656   SetupMouseMoveAtWithDeviceScale(1.f);
1657 }
1658
1659 TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
1660   SetupMouseMoveAtWithDeviceScale(2.f);
1661 }
1662
1663 TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
1664   SetupScrollAndContentsLayers(gfx::Size(100, 100));
1665   host_impl_->SetViewportSize(gfx::Size(50, 50));
1666   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
1667   DrawFrame();
1668   {
1669     CompositorFrameMetadata metadata =
1670         host_impl_->MakeCompositorFrameMetadata();
1671     EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
1672     EXPECT_EQ(1.f, metadata.page_scale_factor);
1673     EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size);
1674     EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1675     EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1676     EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1677   }
1678
1679   // Scrolling should update metadata immediately.
1680   EXPECT_EQ(InputHandler::ScrollStarted,
1681             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
1682   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
1683   {
1684     CompositorFrameMetadata metadata =
1685         host_impl_->MakeCompositorFrameMetadata();
1686     EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1687   }
1688   host_impl_->ScrollEnd();
1689   {
1690     CompositorFrameMetadata metadata =
1691         host_impl_->MakeCompositorFrameMetadata();
1692     EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1693   }
1694
1695   // Page scale should update metadata correctly (shrinking only the viewport).
1696   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
1697   host_impl_->PinchGestureBegin();
1698   host_impl_->PinchGestureUpdate(2.f, gfx::Point());
1699   host_impl_->PinchGestureEnd();
1700   host_impl_->ScrollEnd();
1701   {
1702     CompositorFrameMetadata metadata =
1703         host_impl_->MakeCompositorFrameMetadata();
1704     EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1705     EXPECT_EQ(2.f, metadata.page_scale_factor);
1706     EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size);
1707     EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1708     EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1709     EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1710   }
1711
1712   // Likewise if set from the main thread.
1713   host_impl_->ProcessScrollDeltas();
1714   host_impl_->active_tree()->SetPageScaleFactorAndLimits(4.f, 0.5f, 4.f);
1715   host_impl_->active_tree()->SetPageScaleDelta(1.f);
1716   {
1717     CompositorFrameMetadata metadata =
1718         host_impl_->MakeCompositorFrameMetadata();
1719     EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
1720     EXPECT_EQ(4.f, metadata.page_scale_factor);
1721     EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size);
1722     EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
1723     EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
1724     EXPECT_EQ(4.f, metadata.max_page_scale_factor);
1725   }
1726 }
1727
1728 class DidDrawCheckLayer : public LayerImpl {
1729  public:
1730   static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
1731     return make_scoped_ptr(new DidDrawCheckLayer(tree_impl, id));
1732   }
1733
1734   bool WillDraw(DrawMode draw_mode, ResourceProvider* provider) override {
1735     will_draw_called_ = true;
1736     if (will_draw_returns_false_)
1737       return false;
1738     return LayerImpl::WillDraw(draw_mode, provider);
1739   }
1740
1741   void AppendQuads(RenderPass* render_pass,
1742                    const Occlusion& occlusion_in_content_space,
1743                    AppendQuadsData* append_quads_data) override {
1744     append_quads_called_ = true;
1745     LayerImpl::AppendQuads(
1746         render_pass, occlusion_in_content_space, append_quads_data);
1747   }
1748
1749   void DidDraw(ResourceProvider* provider) override {
1750     did_draw_called_ = true;
1751     LayerImpl::DidDraw(provider);
1752   }
1753
1754   bool will_draw_called() const { return will_draw_called_; }
1755   bool append_quads_called() const { return append_quads_called_; }
1756   bool did_draw_called() const { return did_draw_called_; }
1757
1758   void set_will_draw_returns_false() { will_draw_returns_false_ = true; }
1759
1760   void ClearDidDrawCheck() {
1761     will_draw_called_ = false;
1762     append_quads_called_ = false;
1763     did_draw_called_ = false;
1764   }
1765
1766  protected:
1767   DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id)
1768       : LayerImpl(tree_impl, id),
1769         will_draw_returns_false_(false),
1770         will_draw_called_(false),
1771         append_quads_called_(false),
1772         did_draw_called_(false) {
1773     SetBounds(gfx::Size(10, 10));
1774     SetContentBounds(gfx::Size(10, 10));
1775     SetDrawsContent(true);
1776     draw_properties().visible_content_rect = gfx::Rect(0, 0, 10, 10);
1777   }
1778
1779  private:
1780   bool will_draw_returns_false_;
1781   bool will_draw_called_;
1782   bool append_quads_called_;
1783   bool did_draw_called_;
1784 };
1785
1786 TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) {
1787   // The root layer is always drawn, so run this test on a child layer that
1788   // will be masked out by the root layer's bounds.
1789   host_impl_->active_tree()->SetRootLayer(
1790       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1791   DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1792       host_impl_->active_tree()->root_layer());
1793
1794   root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1795   DidDrawCheckLayer* layer =
1796       static_cast<DidDrawCheckLayer*>(root->children()[0]);
1797
1798   {
1799     LayerTreeHostImpl::FrameData frame;
1800     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1801     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1802     host_impl_->DidDrawAllLayers(frame);
1803
1804     EXPECT_TRUE(layer->will_draw_called());
1805     EXPECT_TRUE(layer->append_quads_called());
1806     EXPECT_TRUE(layer->did_draw_called());
1807   }
1808
1809   host_impl_->SetViewportDamage(gfx::Rect(10, 10));
1810
1811   {
1812     LayerTreeHostImpl::FrameData frame;
1813
1814     layer->set_will_draw_returns_false();
1815     layer->ClearDidDrawCheck();
1816
1817     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1818     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1819     host_impl_->DidDrawAllLayers(frame);
1820
1821     EXPECT_TRUE(layer->will_draw_called());
1822     EXPECT_FALSE(layer->append_quads_called());
1823     EXPECT_FALSE(layer->did_draw_called());
1824   }
1825 }
1826
1827 TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
1828   // The root layer is always drawn, so run this test on a child layer that
1829   // will be masked out by the root layer's bounds.
1830   host_impl_->active_tree()->SetRootLayer(
1831       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1832   DidDrawCheckLayer* root = static_cast<DidDrawCheckLayer*>(
1833       host_impl_->active_tree()->root_layer());
1834   root->SetMasksToBounds(true);
1835
1836   root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1837   DidDrawCheckLayer* layer =
1838       static_cast<DidDrawCheckLayer*>(root->children()[0]);
1839   // Ensure visible_content_rect for layer is empty.
1840   layer->SetPosition(gfx::PointF(100.f, 100.f));
1841   layer->SetBounds(gfx::Size(10, 10));
1842   layer->SetContentBounds(gfx::Size(10, 10));
1843
1844   LayerTreeHostImpl::FrameData frame;
1845
1846   EXPECT_FALSE(layer->will_draw_called());
1847   EXPECT_FALSE(layer->did_draw_called());
1848
1849   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1850   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1851   host_impl_->DidDrawAllLayers(frame);
1852
1853   EXPECT_FALSE(layer->will_draw_called());
1854   EXPECT_FALSE(layer->did_draw_called());
1855
1856   EXPECT_TRUE(layer->visible_content_rect().IsEmpty());
1857
1858   // Ensure visible_content_rect for layer is not empty
1859   layer->SetPosition(gfx::PointF());
1860
1861   EXPECT_FALSE(layer->will_draw_called());
1862   EXPECT_FALSE(layer->did_draw_called());
1863
1864   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1865   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1866   host_impl_->DidDrawAllLayers(frame);
1867
1868   EXPECT_TRUE(layer->will_draw_called());
1869   EXPECT_TRUE(layer->did_draw_called());
1870
1871   EXPECT_FALSE(layer->visible_content_rect().IsEmpty());
1872 }
1873
1874 TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) {
1875   gfx::Size big_size(1000, 1000);
1876   host_impl_->SetViewportSize(big_size);
1877
1878   host_impl_->active_tree()->SetRootLayer(
1879       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1880   DidDrawCheckLayer* root =
1881       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1882
1883   root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1884   DidDrawCheckLayer* occluded_layer =
1885       static_cast<DidDrawCheckLayer*>(root->children()[0]);
1886
1887   root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1888   DidDrawCheckLayer* top_layer =
1889       static_cast<DidDrawCheckLayer*>(root->children()[1]);
1890   // This layer covers the occluded_layer above. Make this layer large so it can
1891   // occlude.
1892   top_layer->SetBounds(big_size);
1893   top_layer->SetContentBounds(big_size);
1894   top_layer->SetContentsOpaque(true);
1895
1896   LayerTreeHostImpl::FrameData frame;
1897
1898   EXPECT_FALSE(occluded_layer->will_draw_called());
1899   EXPECT_FALSE(occluded_layer->did_draw_called());
1900   EXPECT_FALSE(top_layer->will_draw_called());
1901   EXPECT_FALSE(top_layer->did_draw_called());
1902
1903   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1904   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1905   host_impl_->DidDrawAllLayers(frame);
1906
1907   EXPECT_FALSE(occluded_layer->will_draw_called());
1908   EXPECT_FALSE(occluded_layer->did_draw_called());
1909   EXPECT_TRUE(top_layer->will_draw_called());
1910   EXPECT_TRUE(top_layer->did_draw_called());
1911 }
1912
1913 TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) {
1914   host_impl_->active_tree()->SetRootLayer(
1915       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1916   DidDrawCheckLayer* root =
1917       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1918
1919   root->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 2));
1920   DidDrawCheckLayer* layer1 =
1921       static_cast<DidDrawCheckLayer*>(root->children()[0]);
1922
1923   layer1->AddChild(DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
1924   DidDrawCheckLayer* layer2 =
1925       static_cast<DidDrawCheckLayer*>(layer1->children()[0]);
1926
1927   layer1->SetOpacity(0.3f);
1928   layer1->SetShouldFlattenTransform(true);
1929
1930   EXPECT_FALSE(root->did_draw_called());
1931   EXPECT_FALSE(layer1->did_draw_called());
1932   EXPECT_FALSE(layer2->did_draw_called());
1933
1934   LayerTreeHostImpl::FrameData frame;
1935   FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
1936       host_impl_->active_tree()->root_layer());
1937   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
1938   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
1939   host_impl_->DidDrawAllLayers(frame);
1940
1941   EXPECT_TRUE(root->did_draw_called());
1942   EXPECT_TRUE(layer1->did_draw_called());
1943   EXPECT_TRUE(layer2->did_draw_called());
1944
1945   EXPECT_NE(root->render_surface(), layer1->render_surface());
1946   EXPECT_TRUE(!!layer1->render_surface());
1947 }
1948
1949 class MissingTextureAnimatingLayer : public DidDrawCheckLayer {
1950  public:
1951   static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
1952                                       int id,
1953                                       bool tile_missing,
1954                                       bool had_incomplete_tile,
1955                                       bool animating,
1956                                       ResourceProvider* resource_provider) {
1957     return make_scoped_ptr(new MissingTextureAnimatingLayer(tree_impl,
1958                                                             id,
1959                                                             tile_missing,
1960                                                             had_incomplete_tile,
1961                                                             animating,
1962                                                             resource_provider));
1963   }
1964
1965   void AppendQuads(RenderPass* render_pass,
1966                    const Occlusion& occlusion_in_content_space,
1967                    AppendQuadsData* append_quads_data) override {
1968     LayerImpl::AppendQuads(
1969         render_pass, occlusion_in_content_space, append_quads_data);
1970     if (had_incomplete_tile_)
1971       append_quads_data->num_incomplete_tiles++;
1972     if (tile_missing_)
1973       append_quads_data->num_missing_tiles++;
1974   }
1975
1976  private:
1977   MissingTextureAnimatingLayer(LayerTreeImpl* tree_impl,
1978                                int id,
1979                                bool tile_missing,
1980                                bool had_incomplete_tile,
1981                                bool animating,
1982                                ResourceProvider* resource_provider)
1983       : DidDrawCheckLayer(tree_impl, id),
1984         tile_missing_(tile_missing),
1985         had_incomplete_tile_(had_incomplete_tile) {
1986     if (animating)
1987       AddAnimatedTransformToLayer(this, 10.0, 3, 0);
1988   }
1989
1990   bool tile_missing_;
1991   bool had_incomplete_tile_;
1992 };
1993
1994 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsOnDefault) {
1995   host_impl_->active_tree()->SetRootLayer(
1996       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
1997   DidDrawCheckLayer* root =
1998       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
1999
2000   bool tile_missing = false;
2001   bool had_incomplete_tile = false;
2002   bool is_animating = false;
2003   root->AddChild(
2004       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2005                                            2,
2006                                            tile_missing,
2007                                            had_incomplete_tile,
2008                                            is_animating,
2009                                            host_impl_->resource_provider()));
2010
2011   LayerTreeHostImpl::FrameData frame;
2012
2013   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2014   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2015   host_impl_->DidDrawAllLayers(frame);
2016 }
2017
2018 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithAnimatedLayer) {
2019   host_impl_->active_tree()->SetRootLayer(
2020       DidDrawCheckLayer::Create(host_impl_->active_tree(), 1));
2021   DidDrawCheckLayer* root =
2022       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2023   bool tile_missing = false;
2024   bool had_incomplete_tile = false;
2025   bool is_animating = true;
2026   root->AddChild(
2027       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2028                                            2,
2029                                            tile_missing,
2030                                            had_incomplete_tile,
2031                                            is_animating,
2032                                            host_impl_->resource_provider()));
2033
2034   LayerTreeHostImpl::FrameData frame;
2035
2036   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2037   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2038   host_impl_->DidDrawAllLayers(frame);
2039 }
2040
2041 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithMissingTiles) {
2042   host_impl_->active_tree()->SetRootLayer(
2043       DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
2044   DidDrawCheckLayer* root =
2045       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2046
2047   LayerTreeHostImpl::FrameData frame;
2048   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2049   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2050   host_impl_->DidDrawAllLayers(frame);
2051   host_impl_->SwapBuffers(frame);
2052
2053   bool tile_missing = true;
2054   bool had_incomplete_tile = false;
2055   bool is_animating = false;
2056   root->AddChild(
2057       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2058                                            4,
2059                                            tile_missing,
2060                                            had_incomplete_tile,
2061                                            is_animating,
2062                                            host_impl_->resource_provider()));
2063   LayerTreeHostImpl::FrameData frame2;
2064   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2));
2065   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2066   host_impl_->DidDrawAllLayers(frame2);
2067 }
2068
2069 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWithIncompleteTile) {
2070   host_impl_->active_tree()->SetRootLayer(
2071       DidDrawCheckLayer::Create(host_impl_->active_tree(), 3));
2072   DidDrawCheckLayer* root =
2073       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2074
2075   LayerTreeHostImpl::FrameData frame;
2076   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2077   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2078   host_impl_->DidDrawAllLayers(frame);
2079   host_impl_->SwapBuffers(frame);
2080
2081   bool tile_missing = false;
2082   bool had_incomplete_tile = true;
2083   bool is_animating = false;
2084   root->AddChild(
2085       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2086                                            4,
2087                                            tile_missing,
2088                                            had_incomplete_tile,
2089                                            is_animating,
2090                                            host_impl_->resource_provider()));
2091   LayerTreeHostImpl::FrameData frame2;
2092   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2));
2093   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2094   host_impl_->DidDrawAllLayers(frame2);
2095 }
2096
2097 TEST_F(LayerTreeHostImplTest,
2098        PrepareToDrawFailsWithAnimationAndMissingTilesUsesCheckerboard) {
2099   host_impl_->active_tree()->SetRootLayer(
2100       DidDrawCheckLayer::Create(host_impl_->active_tree(), 5));
2101   DidDrawCheckLayer* root =
2102       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2103
2104   LayerTreeHostImpl::FrameData frame;
2105   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2106   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2107   host_impl_->DidDrawAllLayers(frame);
2108   host_impl_->SwapBuffers(frame);
2109
2110   bool tile_missing = true;
2111   bool had_incomplete_tile = false;
2112   bool is_animating = true;
2113   root->AddChild(
2114       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2115                                            6,
2116                                            tile_missing,
2117                                            had_incomplete_tile,
2118                                            is_animating,
2119                                            host_impl_->resource_provider()));
2120   LayerTreeHostImpl::FrameData frame2;
2121   EXPECT_EQ(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS,
2122             host_impl_->PrepareToDraw(&frame2));
2123   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2124   host_impl_->DidDrawAllLayers(frame2);
2125 }
2126
2127 TEST_F(LayerTreeHostImplTest,
2128        PrepareToDrawSucceedsWithAnimationAndIncompleteTiles) {
2129   host_impl_->active_tree()->SetRootLayer(
2130       DidDrawCheckLayer::Create(host_impl_->active_tree(), 5));
2131   DidDrawCheckLayer* root =
2132       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2133
2134   LayerTreeHostImpl::FrameData frame;
2135   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2136   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2137   host_impl_->DidDrawAllLayers(frame);
2138   host_impl_->SwapBuffers(frame);
2139
2140   bool tile_missing = false;
2141   bool had_incomplete_tile = true;
2142   bool is_animating = true;
2143   root->AddChild(
2144       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2145                                            6,
2146                                            tile_missing,
2147                                            had_incomplete_tile,
2148                                            is_animating,
2149                                            host_impl_->resource_provider()));
2150   LayerTreeHostImpl::FrameData frame2;
2151   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2));
2152   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2153   host_impl_->DidDrawAllLayers(frame2);
2154 }
2155
2156 TEST_F(LayerTreeHostImplTest, PrepareToDrawSucceedsWhenHighResRequired) {
2157   host_impl_->active_tree()->SetRootLayer(
2158       DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
2159   DidDrawCheckLayer* root =
2160       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2161
2162   LayerTreeHostImpl::FrameData frame;
2163   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2164   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2165   host_impl_->DidDrawAllLayers(frame);
2166   host_impl_->SwapBuffers(frame);
2167
2168   bool tile_missing = false;
2169   bool had_incomplete_tile = false;
2170   bool is_animating = false;
2171   root->AddChild(
2172       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2173                                            8,
2174                                            tile_missing,
2175                                            had_incomplete_tile,
2176                                            is_animating,
2177                                            host_impl_->resource_provider()));
2178   host_impl_->SetRequiresHighResToDraw();
2179   LayerTreeHostImpl::FrameData frame2;
2180   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2));
2181   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2182   host_impl_->DidDrawAllLayers(frame2);
2183 }
2184
2185 TEST_F(LayerTreeHostImplTest,
2186        PrepareToDrawFailsWhenHighResRequiredAndIncompleteTiles) {
2187   host_impl_->active_tree()->SetRootLayer(
2188       DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
2189   DidDrawCheckLayer* root =
2190       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2191
2192   LayerTreeHostImpl::FrameData frame;
2193   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2194   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2195   host_impl_->DidDrawAllLayers(frame);
2196   host_impl_->SwapBuffers(frame);
2197
2198   bool tile_missing = false;
2199   bool had_incomplete_tile = true;
2200   bool is_animating = false;
2201   root->AddChild(
2202       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2203                                            8,
2204                                            tile_missing,
2205                                            had_incomplete_tile,
2206                                            is_animating,
2207                                            host_impl_->resource_provider()));
2208   host_impl_->SetRequiresHighResToDraw();
2209   LayerTreeHostImpl::FrameData frame2;
2210   EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT,
2211             host_impl_->PrepareToDraw(&frame2));
2212   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2213   host_impl_->DidDrawAllLayers(frame2);
2214 }
2215
2216 TEST_F(LayerTreeHostImplTest,
2217        PrepareToDrawFailsWhenHighResRequiredAndMissingTile) {
2218   host_impl_->active_tree()->SetRootLayer(
2219       DidDrawCheckLayer::Create(host_impl_->active_tree(), 7));
2220   DidDrawCheckLayer* root =
2221       static_cast<DidDrawCheckLayer*>(host_impl_->active_tree()->root_layer());
2222
2223   LayerTreeHostImpl::FrameData frame;
2224   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
2225   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
2226   host_impl_->DidDrawAllLayers(frame);
2227   host_impl_->SwapBuffers(frame);
2228
2229   bool tile_missing = true;
2230   bool had_incomplete_tile = false;
2231   bool is_animating = false;
2232   root->AddChild(
2233       MissingTextureAnimatingLayer::Create(host_impl_->active_tree(),
2234                                            8,
2235                                            tile_missing,
2236                                            had_incomplete_tile,
2237                                            is_animating,
2238                                            host_impl_->resource_provider()));
2239   host_impl_->SetRequiresHighResToDraw();
2240   LayerTreeHostImpl::FrameData frame2;
2241   EXPECT_EQ(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT,
2242             host_impl_->PrepareToDraw(&frame2));
2243   host_impl_->DrawLayers(&frame2, gfx::FrameTime::Now());
2244   host_impl_->DidDrawAllLayers(frame2);
2245 }
2246
2247 TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
2248   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2249   root->SetScrollClipLayer(Layer::INVALID_ID);
2250   host_impl_->active_tree()->SetRootLayer(root.Pass());
2251   DrawFrame();
2252
2253   // Scroll event is ignored because layer is not scrollable.
2254   EXPECT_EQ(InputHandler::ScrollIgnored,
2255             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
2256   EXPECT_FALSE(did_request_redraw_);
2257   EXPECT_FALSE(did_request_commit_);
2258 }
2259
2260 // TODO(bokan): Convert these tests to create inner and outer viewports.
2261 class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest {
2262  public:
2263   LayerTreeHostImplTopControlsTest()
2264       // Make the clip size the same as the layer (content) size so the layer is
2265       // non-scrollable.
2266       : layer_size_(10, 10),
2267         clip_size_(layer_size_) {
2268     settings_.calculate_top_controls_position = true;
2269     settings_.top_controls_height = 50;
2270     settings_.use_pinch_virtual_viewport = true;
2271
2272     viewport_size_ =
2273         gfx::Size(clip_size_.width(),
2274                   clip_size_.height() + settings_.top_controls_height);
2275   }
2276
2277   void SetupTopControlsAndScrollLayer() {
2278     scoped_ptr<LayerImpl> root =
2279         LayerImpl::Create(host_impl_->active_tree(), 1);
2280     scoped_ptr<LayerImpl> root_clip =
2281         LayerImpl::Create(host_impl_->active_tree(), 2);
2282     root_clip->SetBounds(clip_size_);
2283     root->SetScrollClipLayer(root_clip->id());
2284     root->SetBounds(layer_size_);
2285     root->SetContentBounds(layer_size_);
2286     root->SetPosition(gfx::PointF());
2287     root->SetDrawsContent(false);
2288     root->SetIsContainerForFixedPositionLayers(true);
2289     int inner_viewport_scroll_layer_id = root->id();
2290     int page_scale_layer_id = root_clip->id();
2291     root_clip->AddChild(root.Pass());
2292     host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
2293     host_impl_->active_tree()->SetViewportLayersFromIds(
2294         page_scale_layer_id, inner_viewport_scroll_layer_id, Layer::INVALID_ID);
2295     // Set a viewport size that is large enough to contain both the top controls
2296     // and some content.
2297     host_impl_->SetViewportSize(viewport_size_);
2298     host_impl_->SetTopControlsLayoutHeight(
2299         settings_.top_controls_height);
2300
2301     host_impl_->CreatePendingTree();
2302     root =
2303         LayerImpl::Create(host_impl_->sync_tree(), 1);
2304     root_clip =
2305         LayerImpl::Create(host_impl_->sync_tree(), 2);
2306     root_clip->SetBounds(clip_size_);
2307     root->SetScrollClipLayer(root_clip->id());
2308     root->SetBounds(layer_size_);
2309     root->SetContentBounds(layer_size_);
2310     root->SetPosition(gfx::PointF());
2311     root->SetDrawsContent(false);
2312     root->SetIsContainerForFixedPositionLayers(true);
2313     inner_viewport_scroll_layer_id = root->id();
2314     page_scale_layer_id = root_clip->id();
2315     root_clip->AddChild(root.Pass());
2316     host_impl_->sync_tree()->SetRootLayer(root_clip.Pass());
2317     host_impl_->sync_tree()->SetViewportLayersFromIds(
2318         page_scale_layer_id, inner_viewport_scroll_layer_id, Layer::INVALID_ID);
2319     // Set a viewport size that is large enough to contain both the top controls
2320     // and some content.
2321     host_impl_->SetViewportSize(viewport_size_);
2322     host_impl_->sync_tree()->set_top_controls_layout_height(
2323         settings_.top_controls_height);
2324   }
2325
2326   void SetupTopControlsAndScrollLayerWithVirtualViewport(
2327       const gfx::Size& inner_viewport_size,
2328       const gfx::Size& outer_viewport_size,
2329       const gfx::Size& scroll_layer_size) {
2330     CreateHostImpl(settings_, CreateOutputSurface());
2331     host_impl_->SetTopControlsLayoutHeight(
2332         settings_.top_controls_height);
2333
2334     scoped_ptr<LayerImpl> root =
2335         LayerImpl::Create(host_impl_->active_tree(), 1);
2336     scoped_ptr<LayerImpl> root_clip =
2337         LayerImpl::Create(host_impl_->active_tree(), 2);
2338     scoped_ptr<LayerImpl> page_scale =
2339         LayerImpl::Create(host_impl_->active_tree(), 3);
2340
2341     scoped_ptr<LayerImpl> outer_scroll =
2342         LayerImpl::Create(host_impl_->active_tree(), 4);
2343     scoped_ptr<LayerImpl> outer_clip =
2344         LayerImpl::Create(host_impl_->active_tree(), 5);
2345
2346     root_clip->SetBounds(inner_viewport_size);
2347     root->SetScrollClipLayer(root_clip->id());
2348     root->SetBounds(outer_viewport_size);
2349     root->SetContentBounds(outer_viewport_size);
2350     root->SetPosition(gfx::PointF());
2351     root->SetDrawsContent(false);
2352     root->SetIsContainerForFixedPositionLayers(true);
2353
2354     outer_clip->SetBounds(outer_viewport_size);
2355     outer_scroll->SetScrollClipLayer(outer_clip->id());
2356     outer_scroll->SetBounds(scroll_layer_size);
2357     outer_scroll->SetContentBounds(scroll_layer_size);
2358     outer_scroll->SetPosition(gfx::PointF());
2359     outer_scroll->SetDrawsContent(false);
2360     outer_scroll->SetIsContainerForFixedPositionLayers(true);
2361
2362     int inner_viewport_scroll_layer_id = root->id();
2363     int outer_viewport_scroll_layer_id = outer_scroll->id();
2364     int page_scale_layer_id = page_scale->id();
2365
2366     outer_clip->AddChild(outer_scroll.Pass());
2367     root->AddChild(outer_clip.Pass());
2368     page_scale->AddChild(root.Pass());
2369     root_clip->AddChild(page_scale.Pass());
2370
2371     host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
2372     host_impl_->active_tree()->SetViewportLayersFromIds(
2373         page_scale_layer_id,
2374         inner_viewport_scroll_layer_id,
2375         outer_viewport_scroll_layer_id);
2376
2377     host_impl_->SetViewportSize(inner_viewport_size);
2378     LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
2379     EXPECT_EQ(inner_viewport_size, root_clip_ptr->bounds());
2380   }
2381
2382  protected:
2383   gfx::Size layer_size_;
2384   gfx::Size clip_size_;
2385   gfx::Size viewport_size_;
2386
2387   LayerTreeSettings settings_;
2388 };  // class LayerTreeHostImplTopControlsTest
2389
2390 TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) {
2391   SetupTopControlsAndScrollLayerWithVirtualViewport(
2392       gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
2393   DrawFrame();
2394
2395   EXPECT_EQ(InputHandler::ScrollStarted,
2396             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2397
2398   // Make the test scroll delta a fractional amount, to verify that the
2399   // fixed container size delta is (1) non-zero, and (2) fractional, and
2400   // (3) matches the movement of the top controls.
2401   gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f);
2402   host_impl_->top_controls_manager()->ScrollBegin();
2403   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
2404   host_impl_->top_controls_manager()->ScrollEnd();
2405
2406   LayerImpl* inner_viewport_scroll_layer =
2407       host_impl_->active_tree()->InnerViewportScrollLayer();
2408   DCHECK(inner_viewport_scroll_layer);
2409   host_impl_->ScrollEnd();
2410   EXPECT_EQ(top_controls_scroll_delta,
2411             inner_viewport_scroll_layer->FixedContainerSizeDelta());
2412 }
2413
2414 // In this test, the outer viewport is initially unscrollable. We test that a
2415 // scroll initiated on the inner viewport, causing the top controls to show and
2416 // thus making the outer viewport scrollable, still scrolls the outer viewport.
2417 TEST_F(LayerTreeHostImplTopControlsTest,
2418     TopControlsOuterViewportBecomesScrollable) {
2419   SetupTopControlsAndScrollLayerWithVirtualViewport(
2420       gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100));
2421   DrawFrame();
2422
2423   LayerImpl *inner_scroll =
2424       host_impl_->active_tree()->InnerViewportScrollLayer();
2425   LayerImpl *inner_container =
2426       host_impl_->active_tree()->InnerViewportContainerLayer();
2427   LayerImpl *outer_scroll =
2428       host_impl_->active_tree()->OuterViewportScrollLayer();
2429   LayerImpl *outer_container =
2430       host_impl_->active_tree()->OuterViewportContainerLayer();
2431
2432   // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
2433   outer_scroll->SetDrawsContent(true);
2434   host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 1.f, 2.f);
2435
2436   EXPECT_EQ(InputHandler::ScrollStarted,
2437             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2438   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 50.f));
2439
2440   // The entire scroll delta should have been used to hide the top controls.
2441   // The viewport layers should be resized back to their full sizes.
2442   EXPECT_EQ(0.f,
2443       host_impl_->active_tree()->total_top_controls_content_offset());
2444   EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
2445   EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height());
2446   EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height());
2447
2448   // The inner viewport should be scrollable by 50px * page_scale.
2449   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, 100.f));
2450   EXPECT_EQ(50.f, inner_scroll->TotalScrollOffset().y());
2451   EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
2452   EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
2453
2454   host_impl_->ScrollEnd();
2455
2456   EXPECT_EQ(InputHandler::ScrollStarted,
2457             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2458   EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
2459
2460   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
2461
2462   // The entire scroll delta should have been used to show the top controls.
2463   // The outer viewport should be resized to accomodate and scrolled to the
2464   // bottom of the document to keep the viewport in place.
2465   EXPECT_EQ(50.f,
2466       host_impl_->active_tree()->total_top_controls_content_offset());
2467   EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height());
2468   EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height());
2469   EXPECT_EQ(25.f, outer_scroll->TotalScrollOffset().y());
2470   EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
2471
2472   // Now when we continue scrolling, make sure the outer viewport gets scrolled
2473   // since it wasn't scrollable when the scroll began.
2474   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -20.f));
2475   EXPECT_EQ(15.f, outer_scroll->TotalScrollOffset().y());
2476   EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
2477
2478   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -30.f));
2479   EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
2480   EXPECT_EQ(25.f, inner_scroll->TotalScrollOffset().y());
2481
2482   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.f, -50.f));
2483   host_impl_->ScrollEnd();
2484
2485   EXPECT_EQ(0.f, outer_scroll->TotalScrollOffset().y());
2486   EXPECT_EQ(0.f, inner_scroll->TotalScrollOffset().y());
2487 }
2488
2489 // Test that the fixed position container delta is appropriately adjusted
2490 // by the top controls showing/hiding and page scale doesn't affect it.
2491 TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) {
2492   SetupTopControlsAndScrollLayerWithVirtualViewport(
2493       gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100));
2494   DrawFrame();
2495
2496   float page_scale = 1.5f;
2497   float top_controls_height = settings_.top_controls_height;
2498   LayerImpl* outer_viewport_scroll_layer =
2499       host_impl_->active_tree()->OuterViewportScrollLayer();
2500
2501   // Zoom in, since the fixed container is the outer viewport, the delta should
2502   // not be scaled.
2503   host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale, 1.f, 2.f);
2504
2505   EXPECT_EQ(InputHandler::ScrollStarted,
2506             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2507
2508   // Scroll down, the top controls hiding should expand the viewport size so
2509   // the delta should be equal to the scroll distance.
2510   gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f);
2511   host_impl_->top_controls_manager()->ScrollBegin();
2512   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
2513   EXPECT_EQ(top_controls_height - top_controls_scroll_delta.y(),
2514             host_impl_->top_controls_manager()->ContentTopOffset());
2515   EXPECT_VECTOR_EQ(top_controls_scroll_delta,
2516                    outer_viewport_scroll_layer->FixedContainerSizeDelta());
2517   host_impl_->ScrollEnd();
2518
2519   // Scroll past the maximum extent. The delta shouldn't be greater than the
2520   // top controls height.
2521   host_impl_->top_controls_manager()->ScrollBegin();
2522   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
2523   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
2524   host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta);
2525   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2526   EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height),
2527                    outer_viewport_scroll_layer->FixedContainerSizeDelta());
2528   host_impl_->ScrollEnd();
2529
2530   // Scroll in the direction to make the top controls show.
2531   host_impl_->top_controls_manager()->ScrollBegin();
2532   host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta);
2533   EXPECT_EQ(top_controls_scroll_delta.y(),
2534             host_impl_->top_controls_manager()->ContentTopOffset());
2535   EXPECT_VECTOR_EQ(
2536       gfx::Vector2dF(0, top_controls_height - top_controls_scroll_delta.y()),
2537       outer_viewport_scroll_layer->FixedContainerSizeDelta());
2538   host_impl_->top_controls_manager()->ScrollEnd();
2539 }
2540
2541 // Ensure setting the top controls position explicitly using the setters on the
2542 // TreeImpl correctly affects the top controls manager and viewport bounds.
2543 TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) {
2544   CreateHostImpl(settings_, CreateOutputSurface());
2545   SetupTopControlsAndScrollLayer();
2546   DrawFrame();
2547
2548   host_impl_->active_tree()->set_top_controls_delta(0.f);
2549   host_impl_->active_tree()->set_top_controls_content_offset(30.f);
2550   EXPECT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset());
2551   EXPECT_EQ(-20.f, host_impl_->top_controls_manager()->ControlsTopOffset());
2552
2553   host_impl_->active_tree()->set_top_controls_delta(-30.f);
2554   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2555   EXPECT_EQ(-50.f, host_impl_->top_controls_manager()->ControlsTopOffset());
2556
2557   host_impl_->DidChangeTopControlsPosition();
2558
2559   // Now that top controls have moved, expect the clip to resize.
2560   LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
2561   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2562 }
2563
2564 // Test that the top_controls delta and sent delta are appropriately
2565 // applied on sync tree activation. The total top controls offset shouldn't
2566 // change after the activation.
2567 TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) {
2568   CreateHostImpl(settings_, CreateOutputSurface());
2569   SetupTopControlsAndScrollLayer();
2570   DrawFrame();
2571
2572   host_impl_->sync_tree()->set_top_controls_content_offset(15.f);
2573
2574   host_impl_->active_tree()->set_top_controls_content_offset(20.f);
2575   host_impl_->active_tree()->set_top_controls_delta(-20.f);
2576   host_impl_->active_tree()->set_sent_top_controls_delta(-5.f);
2577
2578   host_impl_->DidChangeTopControlsPosition();
2579   LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
2580   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2581   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2582   EXPECT_EQ(0.f,
2583       host_impl_->active_tree()->total_top_controls_content_offset());
2584
2585   host_impl_->ActivateSyncTree();
2586
2587   root_clip_ptr = host_impl_->active_tree()->root_layer();
2588   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2589   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2590
2591   EXPECT_EQ(0.f, host_impl_->active_tree()->sent_top_controls_delta());
2592   EXPECT_EQ(-15.f, host_impl_->active_tree()->top_controls_delta());
2593   EXPECT_EQ(15.f, host_impl_->active_tree()->top_controls_content_offset());
2594   EXPECT_EQ(0.f,
2595       host_impl_->active_tree()->total_top_controls_content_offset());
2596 }
2597
2598 // Test that changing the top controls layout height is correctly applied to
2599 // the inner viewport container bounds. That is, the top controls layout
2600 // height is the amount that the inner viewport container was shrunk outside
2601 // the compositor to accommodate the top controls.
2602 TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) {
2603   CreateHostImpl(settings_, CreateOutputSurface());
2604   SetupTopControlsAndScrollLayer();
2605   DrawFrame();
2606
2607   host_impl_->sync_tree()->set_top_controls_content_offset(15.f);
2608   host_impl_->sync_tree()->set_top_controls_layout_height(15.f);
2609
2610   host_impl_->active_tree()->set_top_controls_content_offset(20.f);
2611   host_impl_->active_tree()->set_top_controls_delta(-20.f);
2612   host_impl_->active_tree()->set_sent_top_controls_delta(-5.f);
2613
2614   host_impl_->DidChangeTopControlsPosition();
2615   LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
2616   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2617   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2618
2619   host_impl_->sync_tree()->root_layer()->SetBounds(
2620       gfx::Size(root_clip_ptr->bounds().width(),
2621                 root_clip_ptr->bounds().height() - 15.f));
2622
2623   host_impl_->ActivateSyncTree();
2624
2625   root_clip_ptr = host_impl_->active_tree()->root_layer();
2626   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2627
2628   // The total bounds should remain unchanged since the bounds delta should
2629   // account for the difference between the layout height and the current
2630   // top controls offset.
2631   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2632   EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 15.f), root_clip_ptr->bounds_delta());
2633
2634   host_impl_->active_tree()->set_top_controls_delta(0.f);
2635   host_impl_->DidChangeTopControlsPosition();
2636
2637   EXPECT_EQ(15.f, host_impl_->top_controls_manager()->ContentTopOffset());
2638   EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), root_clip_ptr->bounds_delta());
2639   EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height()-15.f),
2640             root_clip_ptr->bounds());
2641 }
2642
2643 // Test that showing/hiding the top controls when the viewport is fully scrolled
2644 // doesn't incorrectly change the viewport offset due to clamping from changing
2645 // viewport bounds.
2646 TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) {
2647   SetupTopControlsAndScrollLayerWithVirtualViewport(
2648       gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2649   DrawFrame();
2650
2651   EXPECT_EQ(settings_.top_controls_height,
2652             host_impl_->active_tree()->total_top_controls_content_offset());
2653
2654   LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
2655   LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
2656
2657   // Scroll the viewports to max scroll offset.
2658   outer_scroll->SetScrollDelta(gfx::Vector2dF(0, 200.f));
2659   inner_scroll->SetScrollDelta(gfx::Vector2dF(100, 100.f));
2660
2661   gfx::ScrollOffset viewport_offset =
2662       host_impl_->active_tree()->TotalScrollOffset();
2663   EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset);
2664
2665   // Hide the top controls by 25px.
2666   gfx::Vector2dF scroll_delta(0.f, 25.f);
2667   EXPECT_EQ(InputHandler::ScrollStarted,
2668             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2669   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2670   host_impl_->ScrollEnd();
2671
2672   EXPECT_EQ(scroll_delta.y(),
2673             settings_.top_controls_height -
2674                 host_impl_->active_tree()->total_top_controls_content_offset());
2675
2676   inner_scroll->ClampScrollToMaxScrollOffset();
2677   outer_scroll->ClampScrollToMaxScrollOffset();
2678
2679   // We should still be fully scrolled.
2680   EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
2681             host_impl_->active_tree()->TotalScrollOffset());
2682
2683   viewport_offset = host_impl_->active_tree()->TotalScrollOffset();
2684
2685   // Bring the top controls down by 25px.
2686   scroll_delta = gfx::Vector2dF(0.f, -25.f);
2687   EXPECT_EQ(InputHandler::ScrollStarted,
2688             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2689   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2690   host_impl_->ScrollEnd();
2691
2692   // The viewport offset shouldn't have changed.
2693   EXPECT_EQ(viewport_offset,
2694             host_impl_->active_tree()->TotalScrollOffset());
2695
2696   // Scroll the viewports to max scroll offset.
2697   outer_scroll->SetScrollDelta(gfx::Vector2dF(0, 200.f));
2698   inner_scroll->SetScrollDelta(gfx::Vector2dF(100, 100.f));
2699   EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
2700             host_impl_->active_tree()->TotalScrollOffset());
2701 }
2702
2703 // Test that the top controls coming in and out maintains the same aspect ratio
2704 // between the inner and outer viewports.
2705 TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) {
2706   SetupTopControlsAndScrollLayerWithVirtualViewport(
2707       gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2708   DrawFrame();
2709
2710   EXPECT_EQ(settings_.top_controls_height,
2711             host_impl_->active_tree()->total_top_controls_content_offset());
2712
2713   gfx::Vector2dF scroll_delta(0.f, 25.f);
2714   EXPECT_EQ(InputHandler::ScrollStarted,
2715             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2716   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2717   host_impl_->ScrollEnd();
2718
2719   EXPECT_EQ(scroll_delta.y(),
2720             settings_.top_controls_height -
2721                 host_impl_->active_tree()->total_top_controls_content_offset());
2722
2723   // Top controls were hidden by 25px so the inner viewport should have expanded
2724   // by that much.
2725   LayerImpl* outer_container =
2726             host_impl_->active_tree()->OuterViewportContainerLayer();
2727   LayerImpl* inner_container =
2728             host_impl_->active_tree()->InnerViewportContainerLayer();
2729   EXPECT_EQ(gfx::Size(100, 100+25), inner_container->BoundsForScrolling());
2730
2731   // Outer viewport should match inner's aspect ratio. The bounds are ceiled.
2732   float aspect_ratio = inner_container->BoundsForScrolling().width() /
2733                        inner_container->BoundsForScrolling().height();
2734   gfx::Size expected = gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio));
2735   EXPECT_EQ(expected, outer_container->BoundsForScrolling());
2736   EXPECT_EQ(expected,
2737             host_impl_->InnerViewportScrollLayer()->BoundsForScrolling());
2738 }
2739
2740 // Test that scrolling the outer viewport affects the top controls.
2741 TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) {
2742   SetupTopControlsAndScrollLayerWithVirtualViewport(
2743       gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
2744   DrawFrame();
2745
2746   EXPECT_EQ(settings_.top_controls_height,
2747             host_impl_->active_tree()->total_top_controls_content_offset());
2748
2749   // Send a gesture scroll that will scroll the outer viewport, make sure the
2750   // top controls get scrolled.
2751   gfx::Vector2dF scroll_delta(0.f, 15.f);
2752   EXPECT_EQ(InputHandler::ScrollStarted,
2753             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2754   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2755   EXPECT_EQ(host_impl_->OuterViewportScrollLayer(),
2756             host_impl_->CurrentlyScrollingLayer());
2757   host_impl_->ScrollEnd();
2758
2759   EXPECT_EQ(scroll_delta.y(),
2760             settings_.top_controls_height -
2761                 host_impl_->active_tree()->total_top_controls_content_offset());
2762
2763   scroll_delta = gfx::Vector2dF(0.f, 50.f);
2764   EXPECT_EQ(InputHandler::ScrollStarted,
2765             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2766   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2767
2768   EXPECT_EQ(0, host_impl_->active_tree()->total_top_controls_content_offset());
2769   EXPECT_EQ(host_impl_->OuterViewportScrollLayer(),
2770             host_impl_->CurrentlyScrollingLayer());
2771
2772   host_impl_->ScrollEnd();
2773
2774   // Position the viewports such that the inner viewport will be scrolled.
2775   gfx::Vector2dF inner_viewport_offset(0.f, 25.f);
2776   host_impl_->OuterViewportScrollLayer()->SetScrollDelta(gfx::Vector2dF());
2777   host_impl_->InnerViewportScrollLayer()->SetScrollDelta(inner_viewport_offset);
2778
2779   scroll_delta = gfx::Vector2dF(0.f, -65.f);
2780   EXPECT_EQ(InputHandler::ScrollStarted,
2781             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2782   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
2783
2784   EXPECT_EQ(settings_.top_controls_height,
2785             host_impl_->active_tree()->total_top_controls_content_offset());
2786   EXPECT_EQ(inner_viewport_offset.y() +
2787                 (scroll_delta.y() + settings_.top_controls_height),
2788             host_impl_->InnerViewportScrollLayer()->ScrollDelta().y());
2789
2790   host_impl_->ScrollEnd();
2791 }
2792
2793 TEST_F(LayerTreeHostImplTopControlsTest,
2794        ScrollNonScrollableRootWithTopControls) {
2795   CreateHostImpl(settings_, CreateOutputSurface());
2796   SetupTopControlsAndScrollLayer();
2797   DrawFrame();
2798
2799   EXPECT_EQ(InputHandler::ScrollStarted,
2800             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2801
2802   host_impl_->top_controls_manager()->ScrollBegin();
2803   host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
2804   host_impl_->top_controls_manager()->ScrollEnd();
2805   EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset());
2806   // Now that top controls have moved, expect the clip to resize.
2807   LayerImpl* root_clip_ptr = host_impl_->active_tree()->root_layer();
2808   EXPECT_EQ(viewport_size_, root_clip_ptr->bounds());
2809
2810   host_impl_->ScrollEnd();
2811
2812   EXPECT_EQ(InputHandler::ScrollStarted,
2813             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2814
2815   float scroll_increment_y = -25.f;
2816   host_impl_->top_controls_manager()->ScrollBegin();
2817   host_impl_->top_controls_manager()->ScrollBy(
2818       gfx::Vector2dF(0.f, scroll_increment_y));
2819   EXPECT_EQ(-scroll_increment_y,
2820             host_impl_->top_controls_manager()->ContentTopOffset());
2821   // Now that top controls have moved, expect the clip to resize.
2822   EXPECT_EQ(gfx::Size(viewport_size_.width(),
2823                       viewport_size_.height() + scroll_increment_y),
2824             root_clip_ptr->bounds());
2825
2826   host_impl_->top_controls_manager()->ScrollBy(
2827       gfx::Vector2dF(0.f, scroll_increment_y));
2828   host_impl_->top_controls_manager()->ScrollEnd();
2829   EXPECT_EQ(-2 * scroll_increment_y,
2830             host_impl_->top_controls_manager()->ContentTopOffset());
2831   // Now that top controls have moved, expect the clip to resize.
2832   EXPECT_EQ(clip_size_, root_clip_ptr->bounds());
2833
2834   host_impl_->ScrollEnd();
2835
2836   // Verify the layer is once-again non-scrollable.
2837   EXPECT_EQ(
2838       gfx::ScrollOffset(),
2839       host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset());
2840
2841   EXPECT_EQ(InputHandler::ScrollStarted,
2842             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
2843 }
2844
2845 TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
2846   // Test the configuration where a non-composited root layer is embedded in a
2847   // scrollable outer layer.
2848   gfx::Size surface_size(10, 10);
2849   gfx::Size contents_size(20, 20);
2850
2851   scoped_ptr<LayerImpl> content_layer =
2852       LayerImpl::Create(host_impl_->active_tree(), 1);
2853   content_layer->SetDrawsContent(true);
2854   content_layer->SetPosition(gfx::PointF());
2855   content_layer->SetBounds(contents_size);
2856   content_layer->SetContentBounds(contents_size);
2857   content_layer->SetContentsScale(2.f, 2.f);
2858
2859   scoped_ptr<LayerImpl> scroll_clip_layer =
2860       LayerImpl::Create(host_impl_->active_tree(), 3);
2861   scroll_clip_layer->SetBounds(surface_size);
2862
2863   scoped_ptr<LayerImpl> scroll_layer =
2864       LayerImpl::Create(host_impl_->active_tree(), 2);
2865   scroll_layer->SetScrollClipLayer(3);
2866   scroll_layer->SetBounds(contents_size);
2867   scroll_layer->SetContentBounds(contents_size);
2868   scroll_layer->SetPosition(gfx::PointF());
2869   scroll_layer->AddChild(content_layer.Pass());
2870   scroll_clip_layer->AddChild(scroll_layer.Pass());
2871
2872   host_impl_->active_tree()->SetRootLayer(scroll_clip_layer.Pass());
2873   host_impl_->SetViewportSize(surface_size);
2874   DrawFrame();
2875
2876   EXPECT_EQ(InputHandler::ScrollStarted,
2877             host_impl_->ScrollBegin(gfx::Point(5, 5),
2878                                     InputHandler::Wheel));
2879   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2880   host_impl_->ScrollEnd();
2881   EXPECT_TRUE(did_request_redraw_);
2882   EXPECT_TRUE(did_request_commit_);
2883 }
2884
2885 TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
2886   gfx::Size surface_size(10, 10);
2887   gfx::Size contents_size(20, 20);
2888   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2889   root->SetBounds(surface_size);
2890   root->SetContentBounds(contents_size);
2891   root->AddChild(CreateScrollableLayer(2, contents_size, root.get()));
2892   host_impl_->active_tree()->SetRootLayer(root.Pass());
2893   host_impl_->SetViewportSize(surface_size);
2894   DrawFrame();
2895
2896   EXPECT_EQ(InputHandler::ScrollStarted,
2897             host_impl_->ScrollBegin(gfx::Point(5, 5),
2898                                     InputHandler::Wheel));
2899   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
2900   host_impl_->ScrollEnd();
2901   EXPECT_TRUE(did_request_redraw_);
2902   EXPECT_TRUE(did_request_commit_);
2903 }
2904
2905 TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
2906   gfx::Size surface_size(10, 10);
2907   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2908   root->AddChild(CreateScrollableLayer(2, surface_size, root.get()));
2909   host_impl_->active_tree()->SetRootLayer(root.Pass());
2910   host_impl_->SetViewportSize(surface_size);
2911   DrawFrame();
2912
2913   // Scroll event is ignored because the input coordinate is outside the layer
2914   // boundaries.
2915   EXPECT_EQ(InputHandler::ScrollIgnored,
2916             host_impl_->ScrollBegin(gfx::Point(15, 5),
2917                                     InputHandler::Wheel));
2918   EXPECT_FALSE(did_request_redraw_);
2919   EXPECT_FALSE(did_request_commit_);
2920 }
2921
2922 TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
2923   gfx::Size surface_size(10, 10);
2924   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2925   scoped_ptr<LayerImpl> child =
2926       CreateScrollableLayer(2, surface_size, root.get());
2927   host_impl_->SetViewportSize(surface_size);
2928
2929   gfx::Transform matrix;
2930   matrix.RotateAboutXAxis(180.0);
2931   child->SetTransform(matrix);
2932   child->SetDoubleSided(false);
2933
2934   root->AddChild(child.Pass());
2935   host_impl_->active_tree()->SetRootLayer(root.Pass());
2936   DrawFrame();
2937
2938   // Scroll event is ignored because the scrollable layer is not facing the
2939   // viewer and there is nothing scrollable behind it.
2940   EXPECT_EQ(InputHandler::ScrollIgnored,
2941             host_impl_->ScrollBegin(gfx::Point(5, 5),
2942                                     InputHandler::Wheel));
2943   EXPECT_FALSE(did_request_redraw_);
2944   EXPECT_FALSE(did_request_commit_);
2945 }
2946
2947 TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
2948   gfx::Size surface_size(10, 10);
2949   scoped_ptr<LayerImpl> clip_layer =
2950       LayerImpl::Create(host_impl_->active_tree(), 3);
2951   scoped_ptr<LayerImpl> content_layer =
2952       CreateScrollableLayer(1, surface_size, clip_layer.get());
2953   content_layer->SetShouldScrollOnMainThread(true);
2954   content_layer->SetScrollClipLayer(Layer::INVALID_ID);
2955
2956   // Note: we can use the same clip layer for both since both calls to
2957   // CreateScrollableLayer() use the same surface size.
2958   scoped_ptr<LayerImpl> scroll_layer =
2959       CreateScrollableLayer(2, surface_size, clip_layer.get());
2960   scroll_layer->AddChild(content_layer.Pass());
2961   clip_layer->AddChild(scroll_layer.Pass());
2962
2963   host_impl_->active_tree()->SetRootLayer(clip_layer.Pass());
2964   host_impl_->SetViewportSize(surface_size);
2965   DrawFrame();
2966
2967   // Scrolling fails because the content layer is asking to be scrolled on the
2968   // main thread.
2969   EXPECT_EQ(InputHandler::ScrollOnMainThread,
2970             host_impl_->ScrollBegin(gfx::Point(5, 5),
2971                                     InputHandler::Wheel));
2972 }
2973
2974 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
2975   gfx::Size surface_size(20, 20);
2976   gfx::Size viewport_size(10, 10);
2977   float page_scale = 2.f;
2978   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
2979   scoped_ptr<LayerImpl> root_clip =
2980       LayerImpl::Create(host_impl_->active_tree(), 2);
2981   scoped_ptr<LayerImpl> root_scrolling =
2982       CreateScrollableLayer(3, surface_size, root_clip.get());
2983   EXPECT_EQ(viewport_size, root_clip->bounds());
2984   root_scrolling->SetIsContainerForFixedPositionLayers(true);
2985   root_clip->AddChild(root_scrolling.Pass());
2986   root->AddChild(root_clip.Pass());
2987   host_impl_->active_tree()->SetRootLayer(root.Pass());
2988   // The behaviour in this test assumes the page scale is applied at a layer
2989   // above the clip layer.
2990   host_impl_->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID);
2991   host_impl_->active_tree()->DidBecomeActive();
2992   host_impl_->SetViewportSize(viewport_size);
2993   DrawFrame();
2994
2995   LayerImpl* root_scroll =
2996       host_impl_->active_tree()->InnerViewportScrollLayer();
2997   EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
2998
2999   gfx::Vector2d scroll_delta(0, 10);
3000   gfx::Vector2d expected_scroll_delta = scroll_delta;
3001   gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
3002   EXPECT_EQ(InputHandler::ScrollStarted,
3003             host_impl_->ScrollBegin(gfx::Point(5, 5),
3004                                     InputHandler::Wheel));
3005   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3006   host_impl_->ScrollEnd();
3007
3008   // Set new page scale from main thread.
3009   host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
3010                                                          page_scale,
3011                                                          page_scale);
3012
3013   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
3014   ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
3015
3016   // The scroll range should also have been updated.
3017   EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
3018
3019   // The page scale delta remains constant because the impl thread did not
3020   // scale.
3021   EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
3022 }
3023
3024 TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
3025   gfx::Size surface_size(20, 20);
3026   gfx::Size viewport_size(10, 10);
3027   float page_scale = 2.f;
3028   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
3029   scoped_ptr<LayerImpl> root_clip =
3030       LayerImpl::Create(host_impl_->active_tree(), 2);
3031   scoped_ptr<LayerImpl> root_scrolling =
3032       CreateScrollableLayer(3, surface_size, root_clip.get());
3033   EXPECT_EQ(viewport_size, root_clip->bounds());
3034   root_scrolling->SetIsContainerForFixedPositionLayers(true);
3035   root_clip->AddChild(root_scrolling.Pass());
3036   root->AddChild(root_clip.Pass());
3037   host_impl_->active_tree()->SetRootLayer(root.Pass());
3038   // The behaviour in this test assumes the page scale is applied at a layer
3039   // above the clip layer.
3040   host_impl_->active_tree()->SetViewportLayersFromIds(1, 3, Layer::INVALID_ID);
3041   host_impl_->active_tree()->DidBecomeActive();
3042   host_impl_->SetViewportSize(viewport_size);
3043   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 1.f, page_scale);
3044   DrawFrame();
3045
3046   LayerImpl* root_scroll =
3047       host_impl_->active_tree()->InnerViewportScrollLayer();
3048   EXPECT_EQ(viewport_size, root_scroll->scroll_clip_layer()->bounds());
3049
3050   gfx::Vector2d scroll_delta(0, 10);
3051   gfx::Vector2d expected_scroll_delta = scroll_delta;
3052   gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset();
3053   EXPECT_EQ(InputHandler::ScrollStarted,
3054             host_impl_->ScrollBegin(gfx::Point(5, 5),
3055                                     InputHandler::Wheel));
3056   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3057   host_impl_->ScrollEnd();
3058
3059   // Set new page scale on impl thread by pinching.
3060   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
3061   host_impl_->PinchGestureBegin();
3062   host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
3063   host_impl_->PinchGestureEnd();
3064   host_impl_->ScrollEnd();
3065   DrawOneFrame();
3066
3067   // The scroll delta is not scaled because the main thread did not scale.
3068   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
3069   ExpectContains(*scroll_info.get(), root_scroll->id(), expected_scroll_delta);
3070
3071   // The scroll range should also have been updated.
3072   EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset());
3073
3074   // The page scale delta should match the new scale on the impl side.
3075   EXPECT_EQ(page_scale, host_impl_->active_tree()->total_page_scale_factor());
3076 }
3077
3078 TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
3079   gfx::Size surface_size(10, 10);
3080   float default_page_scale = 1.f;
3081   gfx::Transform default_page_scale_matrix;
3082   default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
3083
3084   float new_page_scale = 2.f;
3085   gfx::Transform new_page_scale_matrix;
3086   new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
3087
3088   // Create a normal scrollable root layer and another scrollable child layer.
3089   LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size);
3090   LayerImpl* root = host_impl_->active_tree()->root_layer();
3091   LayerImpl* child = scroll->children()[0];
3092
3093   scoped_ptr<LayerImpl> scrollable_child_clip =
3094       LayerImpl::Create(host_impl_->active_tree(), 6);
3095   scoped_ptr<LayerImpl> scrollable_child =
3096       CreateScrollableLayer(7, surface_size, scrollable_child_clip.get());
3097   scrollable_child_clip->AddChild(scrollable_child.Pass());
3098   child->AddChild(scrollable_child_clip.Pass());
3099   LayerImpl* grand_child = child->children()[0];
3100
3101   // Set new page scale on impl thread by pinching.
3102   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
3103   host_impl_->PinchGestureBegin();
3104   host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
3105   host_impl_->PinchGestureEnd();
3106   host_impl_->ScrollEnd();
3107   DrawOneFrame();
3108
3109   EXPECT_EQ(1.f, root->contents_scale_x());
3110   EXPECT_EQ(1.f, root->contents_scale_y());
3111   EXPECT_EQ(1.f, scroll->contents_scale_x());
3112   EXPECT_EQ(1.f, scroll->contents_scale_y());
3113   EXPECT_EQ(1.f, child->contents_scale_x());
3114   EXPECT_EQ(1.f, child->contents_scale_y());
3115   EXPECT_EQ(1.f, grand_child->contents_scale_x());
3116   EXPECT_EQ(1.f, grand_child->contents_scale_y());
3117
3118   // Make sure all the layers are drawn with the page scale delta applied, i.e.,
3119   // the page scale delta on the root layer is applied hierarchically.
3120   LayerTreeHostImpl::FrameData frame;
3121   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
3122   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
3123   host_impl_->DidDrawAllLayers(frame);
3124
3125   EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(0, 0));
3126   EXPECT_EQ(1.f, root->draw_transform().matrix().getDouble(1, 1));
3127   EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(0, 0));
3128   EXPECT_EQ(new_page_scale, scroll->draw_transform().matrix().getDouble(1, 1));
3129   EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(0, 0));
3130   EXPECT_EQ(new_page_scale, child->draw_transform().matrix().getDouble(1, 1));
3131   EXPECT_EQ(new_page_scale,
3132             grand_child->draw_transform().matrix().getDouble(0, 0));
3133   EXPECT_EQ(new_page_scale,
3134             grand_child->draw_transform().matrix().getDouble(1, 1));
3135 }
3136
3137 TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
3138   gfx::Size surface_size(30, 30);
3139   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
3140   root->SetBounds(gfx::Size(5, 5));
3141   scoped_ptr<LayerImpl> root_scrolling =
3142       LayerImpl::Create(host_impl_->active_tree(), 2);
3143   root_scrolling->SetBounds(surface_size);
3144   root_scrolling->SetContentBounds(surface_size);
3145   root_scrolling->SetScrollClipLayer(root->id());
3146   root_scrolling->SetIsContainerForFixedPositionLayers(true);
3147   LayerImpl* root_scrolling_ptr = root_scrolling.get();
3148   root->AddChild(root_scrolling.Pass());
3149   int child_scroll_layer_id = 3;
3150   scoped_ptr<LayerImpl> child_scrolling = CreateScrollableLayer(
3151       child_scroll_layer_id, surface_size, root_scrolling_ptr);
3152   LayerImpl* child = child_scrolling.get();
3153   root_scrolling_ptr->AddChild(child_scrolling.Pass());
3154   host_impl_->active_tree()->SetRootLayer(root.Pass());
3155   host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID);
3156   host_impl_->active_tree()->DidBecomeActive();
3157   host_impl_->SetViewportSize(surface_size);
3158   DrawFrame();
3159
3160   gfx::Vector2d scroll_delta(0, 10);
3161   gfx::Vector2d expected_scroll_delta(scroll_delta);
3162   gfx::ScrollOffset expected_max_scroll(child->MaxScrollOffset());
3163   EXPECT_EQ(InputHandler::ScrollStarted,
3164             host_impl_->ScrollBegin(gfx::Point(5, 5),
3165                                     InputHandler::Wheel));
3166   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3167   host_impl_->ScrollEnd();
3168
3169   float page_scale = 2.f;
3170   host_impl_->active_tree()->SetPageScaleFactorAndLimits(page_scale,
3171                                                          1.f,
3172                                                          page_scale);
3173
3174   DrawOneFrame();
3175
3176   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
3177   ExpectContains(
3178       *scroll_info.get(), child_scroll_layer_id, expected_scroll_delta);
3179
3180   // The scroll range should not have changed.
3181   EXPECT_EQ(child->MaxScrollOffset(), expected_max_scroll);
3182
3183   // The page scale delta remains constant because the impl thread did not
3184   // scale.
3185   EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
3186 }
3187
3188 TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
3189   // Scroll a child layer beyond its maximum scroll range and make sure the
3190   // parent layer is scrolled on the axis on which the child was unable to
3191   // scroll.
3192   gfx::Size surface_size(10, 10);
3193   gfx::Size content_size(20, 20);
3194   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
3195   root->SetBounds(surface_size);
3196
3197   scoped_ptr<LayerImpl> grand_child =
3198       CreateScrollableLayer(3, content_size, root.get());
3199
3200   scoped_ptr<LayerImpl> child =
3201       CreateScrollableLayer(2, content_size, root.get());
3202   LayerImpl* grand_child_layer = grand_child.get();
3203   child->AddChild(grand_child.Pass());
3204
3205   LayerImpl* child_layer = child.get();
3206   root->AddChild(child.Pass());
3207   host_impl_->active_tree()->SetRootLayer(root.Pass());
3208   host_impl_->active_tree()->DidBecomeActive();
3209   host_impl_->SetViewportSize(surface_size);
3210   grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 5));
3211   child_layer->SetScrollOffset(gfx::ScrollOffset(3, 0));
3212
3213   DrawFrame();
3214   {
3215     gfx::Vector2d scroll_delta(-8, -7);
3216     EXPECT_EQ(InputHandler::ScrollStarted,
3217               host_impl_->ScrollBegin(gfx::Point(),
3218                                       InputHandler::Wheel));
3219     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3220     host_impl_->ScrollEnd();
3221
3222     scoped_ptr<ScrollAndScaleSet> scroll_info =
3223         host_impl_->ProcessScrollDeltas();
3224
3225     // The grand child should have scrolled up to its limit.
3226     LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
3227     LayerImpl* grand_child = child->children()[0];
3228     ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -5));
3229
3230     // The child should have only scrolled on the other axis.
3231     ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(-3, 0));
3232   }
3233 }
3234
3235 TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
3236   // Scroll a child layer beyond its maximum scroll range and make sure the
3237   // the scroll doesn't bubble up to the parent layer.
3238   gfx::Size surface_size(20, 20);
3239   gfx::Size viewport_size(10, 10);
3240   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
3241   scoped_ptr<LayerImpl> root_scrolling =
3242       CreateScrollableLayer(2, surface_size, root.get());
3243   root_scrolling->SetIsContainerForFixedPositionLayers(true);
3244
3245   scoped_ptr<LayerImpl> grand_child =
3246       CreateScrollableLayer(4, surface_size, root.get());
3247
3248   scoped_ptr<LayerImpl> child =
3249       CreateScrollableLayer(3, surface_size, root.get());
3250   LayerImpl* grand_child_layer = grand_child.get();
3251   child->AddChild(grand_child.Pass());
3252
3253   LayerImpl* child_layer = child.get();
3254   root_scrolling->AddChild(child.Pass());
3255   root->AddChild(root_scrolling.Pass());
3256   EXPECT_EQ(viewport_size, root->bounds());
3257   host_impl_->active_tree()->SetRootLayer(root.Pass());
3258   host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID);
3259   host_impl_->active_tree()->DidBecomeActive();
3260   host_impl_->SetViewportSize(viewport_size);
3261
3262   grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 2));
3263   child_layer->SetScrollOffset(gfx::ScrollOffset(0, 3));
3264
3265   DrawFrame();
3266   {
3267     gfx::Vector2d scroll_delta(0, -10);
3268     EXPECT_EQ(InputHandler::ScrollStarted,
3269               host_impl_->ScrollBegin(gfx::Point(),
3270                                       InputHandler::NonBubblingGesture));
3271     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3272     host_impl_->ScrollEnd();
3273
3274     scoped_ptr<ScrollAndScaleSet> scroll_info =
3275         host_impl_->ProcessScrollDeltas();
3276
3277     // The grand child should have scrolled up to its limit.
3278     LayerImpl* child =
3279         host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
3280     LayerImpl* grand_child = child->children()[0];
3281     ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
3282
3283     // The child should not have scrolled.
3284     ExpectNone(*scroll_info.get(), child->id());
3285
3286     // The next time we scroll we should only scroll the parent.
3287     scroll_delta = gfx::Vector2d(0, -3);
3288     EXPECT_EQ(InputHandler::ScrollStarted,
3289               host_impl_->ScrollBegin(gfx::Point(5, 5),
3290                                       InputHandler::NonBubblingGesture));
3291     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
3292     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3293     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
3294     host_impl_->ScrollEnd();
3295
3296     scroll_info = host_impl_->ProcessScrollDeltas();
3297
3298     // The child should have scrolled up to its limit.
3299     ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
3300
3301     // The grand child should not have scrolled.
3302     ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, -2));
3303
3304     // After scrolling the parent, another scroll on the opposite direction
3305     // should still scroll the child.
3306     scroll_delta = gfx::Vector2d(0, 7);
3307     EXPECT_EQ(InputHandler::ScrollStarted,
3308               host_impl_->ScrollBegin(gfx::Point(5, 5),
3309                                       InputHandler::NonBubblingGesture));
3310     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
3311     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3312     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
3313     host_impl_->ScrollEnd();
3314
3315     scroll_info = host_impl_->ProcessScrollDeltas();
3316
3317     // The grand child should have scrolled.
3318     ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 5));
3319
3320     // The child should not have scrolled.
3321     ExpectContains(*scroll_info.get(), child->id(), gfx::Vector2d(0, -3));
3322
3323
3324     // Scrolling should be adjusted from viewport space.
3325     host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 2.f, 2.f);
3326     host_impl_->active_tree()->SetPageScaleDelta(1.f);
3327
3328     scroll_delta = gfx::Vector2d(0, -2);
3329     EXPECT_EQ(InputHandler::ScrollStarted,
3330               host_impl_->ScrollBegin(gfx::Point(1, 1),
3331                                       InputHandler::NonBubblingGesture));
3332     EXPECT_EQ(grand_child, host_impl_->CurrentlyScrollingLayer());
3333     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3334     host_impl_->ScrollEnd();
3335
3336     scroll_info = host_impl_->ProcessScrollDeltas();
3337
3338     // Should have scrolled by half the amount in layer space (5 - 2/2)
3339     ExpectContains(*scroll_info.get(), grand_child->id(), gfx::Vector2d(0, 4));
3340   }
3341 }
3342 TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
3343   // When we try to scroll a non-scrollable child layer, the scroll delta
3344   // should be applied to one of its ancestors if possible.
3345   gfx::Size surface_size(10, 10);
3346   gfx::Size content_size(20, 20);
3347   scoped_ptr<LayerImpl> root_clip =
3348       LayerImpl::Create(host_impl_->active_tree(), 3);
3349   scoped_ptr<LayerImpl> root =
3350       CreateScrollableLayer(1, content_size, root_clip.get());
3351   // Make 'root' the clip layer for child: since they have the same sizes the
3352   // child will have zero max_scroll_offset and scrolls will bubble.
3353   scoped_ptr<LayerImpl> child =
3354       CreateScrollableLayer(2, content_size, root.get());
3355   child->SetIsContainerForFixedPositionLayers(true);
3356   root->SetBounds(content_size);
3357
3358   int root_scroll_id = root->id();
3359   root->AddChild(child.Pass());
3360   root_clip->AddChild(root.Pass());
3361
3362   host_impl_->SetViewportSize(surface_size);
3363   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
3364   host_impl_->active_tree()->SetViewportLayersFromIds(3, 2, Layer::INVALID_ID);
3365   host_impl_->active_tree()->DidBecomeActive();
3366   DrawFrame();
3367   {
3368     gfx::Vector2d scroll_delta(0, 4);
3369     EXPECT_EQ(InputHandler::ScrollStarted,
3370               host_impl_->ScrollBegin(gfx::Point(5, 5),
3371                                       InputHandler::Wheel));
3372     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3373     host_impl_->ScrollEnd();
3374
3375     scoped_ptr<ScrollAndScaleSet> scroll_info =
3376         host_impl_->ProcessScrollDeltas();
3377
3378     // Only the root scroll should have scrolled.
3379     ASSERT_EQ(scroll_info->scrolls.size(), 1u);
3380     ExpectContains(*scroll_info.get(), root_scroll_id, scroll_delta);
3381   }
3382 }
3383
3384 TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
3385   gfx::Size surface_size(10, 10);
3386   scoped_ptr<LayerImpl> root_clip =
3387       LayerImpl::Create(host_impl_->active_tree(), 1);
3388   scoped_ptr<LayerImpl> root_scroll =
3389       CreateScrollableLayer(2, surface_size, root_clip.get());
3390   root_scroll->SetIsContainerForFixedPositionLayers(true);
3391   root_clip->AddChild(root_scroll.Pass());
3392   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
3393   host_impl_->active_tree()->SetViewportLayersFromIds(1, 2, Layer::INVALID_ID);
3394   host_impl_->active_tree()->DidBecomeActive();
3395   host_impl_->SetViewportSize(surface_size);
3396
3397   // Draw one frame and then immediately rebuild the layer tree to mimic a tree
3398   // synchronization.
3399   DrawFrame();
3400   host_impl_->active_tree()->DetachLayerTree();
3401   scoped_ptr<LayerImpl> root_clip2 =
3402       LayerImpl::Create(host_impl_->active_tree(), 3);
3403   scoped_ptr<LayerImpl> root_scroll2 =
3404       CreateScrollableLayer(4, surface_size, root_clip2.get());
3405   root_scroll2->SetIsContainerForFixedPositionLayers(true);
3406   root_clip2->AddChild(root_scroll2.Pass());
3407   host_impl_->active_tree()->SetRootLayer(root_clip2.Pass());
3408   host_impl_->active_tree()->SetViewportLayersFromIds(3, 4, Layer::INVALID_ID);
3409   host_impl_->active_tree()->DidBecomeActive();
3410
3411   // Scrolling should still work even though we did not draw yet.
3412   EXPECT_EQ(InputHandler::ScrollStarted,
3413             host_impl_->ScrollBegin(gfx::Point(5, 5),
3414                                     InputHandler::Wheel));
3415 }
3416
3417 TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
3418   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
3419
3420   // Rotate the root layer 90 degrees counter-clockwise about its center.
3421   gfx::Transform rotate_transform;
3422   rotate_transform.Rotate(-90.0);
3423   host_impl_->active_tree()->root_layer()->SetTransform(rotate_transform);
3424
3425   gfx::Size surface_size(50, 50);
3426   host_impl_->SetViewportSize(surface_size);
3427   DrawFrame();
3428
3429   // Scroll to the right in screen coordinates with a gesture.
3430   gfx::Vector2d gesture_scroll_delta(10, 0);
3431   EXPECT_EQ(InputHandler::ScrollStarted,
3432             host_impl_->ScrollBegin(gfx::Point(),
3433                                     InputHandler::Gesture));
3434   host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
3435   host_impl_->ScrollEnd();
3436
3437   // The layer should have scrolled down in its local coordinates.
3438   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
3439   ExpectContains(*scroll_info.get(),
3440                  scroll_layer->id(),
3441                  gfx::Vector2d(0, gesture_scroll_delta.x()));
3442
3443   // Reset and scroll down with the wheel.
3444   scroll_layer->SetScrollDelta(gfx::Vector2dF());
3445   gfx::Vector2d wheel_scroll_delta(0, 10);
3446   EXPECT_EQ(InputHandler::ScrollStarted,
3447             host_impl_->ScrollBegin(gfx::Point(),
3448                                     InputHandler::Wheel));
3449   host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
3450   host_impl_->ScrollEnd();
3451
3452   // The layer should have scrolled down in its local coordinates.
3453   scroll_info = host_impl_->ProcessScrollDeltas();
3454   ExpectContains(*scroll_info.get(),
3455                  scroll_layer->id(),
3456                  wheel_scroll_delta);
3457 }
3458
3459 TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
3460   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
3461   int child_clip_layer_id = 6;
3462   int child_layer_id = 7;
3463   float child_layer_angle = -20.f;
3464
3465   // Create a child layer that is rotated to a non-axis-aligned angle.
3466   scoped_ptr<LayerImpl> clip_layer =
3467       LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id);
3468   scoped_ptr<LayerImpl> child = CreateScrollableLayer(
3469       child_layer_id, scroll_layer->content_bounds(), clip_layer.get());
3470   gfx::Transform rotate_transform;
3471   rotate_transform.Translate(-50.0, -50.0);
3472   rotate_transform.Rotate(child_layer_angle);
3473   rotate_transform.Translate(50.0, 50.0);
3474   clip_layer->SetTransform(rotate_transform);
3475
3476   // Only allow vertical scrolling.
3477   clip_layer->SetBounds(
3478       gfx::Size(child->bounds().width(), child->bounds().height() / 2));
3479   // The rotation depends on the layer's transform origin, and the child layer
3480   // is a different size than the clip, so make sure the clip layer's origin
3481   // lines up over the child.
3482   clip_layer->SetTransformOrigin(gfx::Point3F(
3483       clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f));
3484   LayerImpl* child_ptr = child.get();
3485   clip_layer->AddChild(child.Pass());
3486   scroll_layer->AddChild(clip_layer.Pass());
3487
3488   gfx::Size surface_size(50, 50);
3489   host_impl_->SetViewportSize(surface_size);
3490   DrawFrame();
3491   {
3492     // Scroll down in screen coordinates with a gesture.
3493     gfx::Vector2d gesture_scroll_delta(0, 10);
3494     EXPECT_EQ(InputHandler::ScrollStarted,
3495               host_impl_->ScrollBegin(gfx::Point(1, 1),
3496                                       InputHandler::Gesture));
3497     host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
3498     host_impl_->ScrollEnd();
3499
3500     // The child layer should have scrolled down in its local coordinates an
3501     // amount proportional to the angle between it and the input scroll delta.
3502     gfx::Vector2d expected_scroll_delta(
3503         0,
3504         gesture_scroll_delta.y() *
3505             std::cos(MathUtil::Deg2Rad(child_layer_angle)));
3506     scoped_ptr<ScrollAndScaleSet> scroll_info =
3507         host_impl_->ProcessScrollDeltas();
3508     ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
3509
3510     // The root scroll layer should not have scrolled, because the input delta
3511     // was close to the layer's axis of movement.
3512     EXPECT_EQ(scroll_info->scrolls.size(), 1u);
3513   }
3514   {
3515     // Now reset and scroll the same amount horizontally.
3516     child_ptr->SetScrollDelta(gfx::Vector2dF());
3517     gfx::Vector2d gesture_scroll_delta(10, 0);
3518     EXPECT_EQ(InputHandler::ScrollStarted,
3519               host_impl_->ScrollBegin(gfx::Point(1, 1),
3520                                       InputHandler::Gesture));
3521     host_impl_->ScrollBy(gfx::Point(), gesture_scroll_delta);
3522     host_impl_->ScrollEnd();
3523
3524     // The child layer should have scrolled down in its local coordinates an
3525     // amount proportional to the angle between it and the input scroll delta.
3526     gfx::Vector2d expected_scroll_delta(
3527         0,
3528         -gesture_scroll_delta.x() *
3529             std::sin(MathUtil::Deg2Rad(child_layer_angle)));
3530     scoped_ptr<ScrollAndScaleSet> scroll_info =
3531         host_impl_->ProcessScrollDeltas();
3532     ExpectContains(*scroll_info.get(), child_layer_id, expected_scroll_delta);
3533
3534     // The root scroll layer should have scrolled more, since the input scroll
3535     // delta was mostly orthogonal to the child layer's vertical scroll axis.
3536     gfx::Vector2d expected_root_scroll_delta(
3537         gesture_scroll_delta.x() *
3538             std::pow(std::cos(MathUtil::Deg2Rad(child_layer_angle)), 2),
3539         0);
3540     ExpectContains(*scroll_info.get(),
3541                    scroll_layer->id(),
3542                    expected_root_scroll_delta);
3543   }
3544 }
3545
3546 TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
3547   LayerImpl* scroll_layer =
3548       SetupScrollAndContentsLayers(gfx::Size(100, 100));
3549
3550   // Scale the layer to twice its normal size.
3551   int scale = 2;
3552   gfx::Transform scale_transform;
3553   scale_transform.Scale(scale, scale);
3554   scroll_layer->SetTransform(scale_transform);
3555
3556   gfx::Size surface_size(50, 50);
3557   host_impl_->SetViewportSize(surface_size);
3558   DrawFrame();
3559
3560   // Scroll down in screen coordinates with a gesture.
3561   gfx::Vector2d scroll_delta(0, 10);
3562   EXPECT_EQ(InputHandler::ScrollStarted,
3563             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
3564   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3565   host_impl_->ScrollEnd();
3566
3567   // The layer should have scrolled down in its local coordinates, but half the
3568   // amount.
3569   scoped_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas();
3570   ExpectContains(*scroll_info.get(),
3571                  scroll_layer->id(),
3572                  gfx::Vector2d(0, scroll_delta.y() / scale));
3573
3574   // Reset and scroll down with the wheel.
3575   scroll_layer->SetScrollDelta(gfx::Vector2dF());
3576   gfx::Vector2d wheel_scroll_delta(0, 10);
3577   EXPECT_EQ(InputHandler::ScrollStarted,
3578             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
3579   host_impl_->ScrollBy(gfx::Point(), wheel_scroll_delta);
3580   host_impl_->ScrollEnd();
3581
3582   // The scale should not have been applied to the scroll delta.
3583   scroll_info = host_impl_->ProcessScrollDeltas();
3584   ExpectContains(*scroll_info.get(),
3585                  scroll_layer->id(),
3586                  wheel_scroll_delta);
3587 }
3588
3589 TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
3590   int width = 332;
3591   int height = 20;
3592   int scale = 3;
3593   SetupScrollAndContentsLayers(gfx::Size(width, height));
3594   host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds(
3595       gfx::Size(width * scale - 1, height * scale));
3596   host_impl_->SetDeviceScaleFactor(scale);
3597   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
3598
3599   LayerImpl* inner_viewport_scroll_layer =
3600       host_impl_->active_tree()->InnerViewportScrollLayer();
3601   EXPECT_EQ(gfx::ScrollOffset(0, 0),
3602             inner_viewport_scroll_layer->MaxScrollOffset());
3603 }
3604
3605 class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
3606  public:
3607   TestScrollOffsetDelegate()
3608       : page_scale_factor_(0.f),
3609         min_page_scale_factor_(-1.f),
3610         max_page_scale_factor_(-1.f) {}
3611
3612   ~TestScrollOffsetDelegate() override {}
3613
3614   gfx::ScrollOffset GetTotalScrollOffset() override {
3615     return getter_return_value_;
3616   }
3617
3618   bool IsExternalFlingActive() const override { return false; }
3619
3620   void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
3621                             const gfx::ScrollOffset& max_scroll_offset,
3622                             const gfx::SizeF& scrollable_size,
3623                             float page_scale_factor,
3624                             float min_page_scale_factor,
3625                             float max_page_scale_factor) override {
3626     DCHECK(total_scroll_offset.x() <= max_scroll_offset.x());
3627     DCHECK(total_scroll_offset.y() <= max_scroll_offset.y());
3628     last_set_scroll_offset_ = total_scroll_offset;
3629     max_scroll_offset_ = max_scroll_offset;
3630     scrollable_size_ = scrollable_size;
3631     page_scale_factor_ = page_scale_factor;
3632     min_page_scale_factor_ = min_page_scale_factor;
3633     max_page_scale_factor_ = max_page_scale_factor;
3634   }
3635
3636   gfx::ScrollOffset last_set_scroll_offset() {
3637     return last_set_scroll_offset_;
3638   }
3639
3640   void set_getter_return_value(const gfx::ScrollOffset& value) {
3641     getter_return_value_ = value;
3642   }
3643
3644   gfx::ScrollOffset max_scroll_offset() const {
3645     return max_scroll_offset_;
3646   }
3647
3648   gfx::SizeF scrollable_size() const {
3649     return scrollable_size_;
3650   }
3651
3652   float page_scale_factor() const {
3653     return page_scale_factor_;
3654   }
3655
3656   float min_page_scale_factor() const {
3657     return min_page_scale_factor_;
3658   }
3659
3660   float max_page_scale_factor() const {
3661     return max_page_scale_factor_;
3662   }
3663
3664  private:
3665   gfx::ScrollOffset last_set_scroll_offset_;
3666   gfx::ScrollOffset getter_return_value_;
3667   gfx::ScrollOffset max_scroll_offset_;
3668   gfx::SizeF scrollable_size_;
3669   float page_scale_factor_;
3670   float min_page_scale_factor_;
3671   float max_page_scale_factor_;
3672 };
3673
3674 TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
3675   TestScrollOffsetDelegate scroll_delegate;
3676   host_impl_->SetViewportSize(gfx::Size(10, 20));
3677   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
3678   LayerImpl* clip_layer = scroll_layer->parent()->parent();
3679   clip_layer->SetBounds(gfx::Size(10, 20));
3680
3681   // Setting the delegate results in the current scroll offset being set.
3682   gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
3683   scroll_layer->SetScrollOffset(gfx::ScrollOffset());
3684   scroll_layer->SetScrollDelta(initial_scroll_delta);
3685   host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
3686   EXPECT_EQ(initial_scroll_delta.ToString(),
3687             scroll_delegate.last_set_scroll_offset().ToString());
3688
3689   // Setting the delegate results in the scrollable_size, max_scroll_offset,
3690   // page_scale_factor and {min|max}_page_scale_factor being set.
3691   EXPECT_EQ(gfx::SizeF(100, 100), scroll_delegate.scrollable_size());
3692   EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_delegate.max_scroll_offset());
3693   EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
3694   EXPECT_EQ(0.f, scroll_delegate.min_page_scale_factor());
3695   EXPECT_EQ(0.f, scroll_delegate.max_page_scale_factor());
3696
3697   // Updating page scale immediately updates the delegate.
3698   host_impl_->active_tree()->SetPageScaleFactorAndLimits(2.f, 0.5f, 4.f);
3699   EXPECT_EQ(2.f, scroll_delegate.page_scale_factor());
3700   EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
3701   EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
3702   host_impl_->active_tree()->SetPageScaleDelta(1.5f);
3703   EXPECT_EQ(3.f, scroll_delegate.page_scale_factor());
3704   EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
3705   EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
3706   host_impl_->active_tree()->SetPageScaleDelta(1.f);
3707   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
3708   EXPECT_EQ(1.f, scroll_delegate.page_scale_factor());
3709   EXPECT_EQ(0.5f, scroll_delegate.min_page_scale_factor());
3710   EXPECT_EQ(4.f, scroll_delegate.max_page_scale_factor());
3711
3712   // The pinch gesture doesn't put the delegate into a state where the scroll
3713   // offset is outside of the scroll range.  (this is verified by DCHECKs in the
3714   // delegate).
3715   host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture);
3716   host_impl_->PinchGestureBegin();
3717   host_impl_->PinchGestureUpdate(2.f, gfx::Point());
3718   host_impl_->PinchGestureUpdate(.5f, gfx::Point());
3719   host_impl_->PinchGestureEnd();
3720   host_impl_->ScrollEnd();
3721
3722   // Scrolling should be relative to the offset as returned by the delegate.
3723   gfx::Vector2dF scroll_delta(0.f, 10.f);
3724   gfx::ScrollOffset current_offset(7.f, 8.f);
3725
3726   scroll_delegate.set_getter_return_value(current_offset);
3727   EXPECT_EQ(InputHandler::ScrollStarted,
3728             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
3729
3730   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3731   EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
3732             scroll_delegate.last_set_scroll_offset());
3733
3734   current_offset = gfx::ScrollOffset(42.f, 41.f);
3735   scroll_delegate.set_getter_return_value(current_offset);
3736   host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3737   EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
3738             scroll_delegate.last_set_scroll_offset());
3739   host_impl_->ScrollEnd();
3740   scroll_delegate.set_getter_return_value(gfx::ScrollOffset());
3741
3742   // Forces a full tree synchronization and ensures that the scroll delegate
3743   // sees the correct size of the new tree.
3744   gfx::Size new_size(42, 24);
3745   host_impl_->CreatePendingTree();
3746   CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size);
3747   host_impl_->ActivateSyncTree();
3748   EXPECT_EQ(new_size, scroll_delegate.scrollable_size());
3749
3750   // Un-setting the delegate should propagate the delegate's current offset to
3751   // the root scrollable layer.
3752   current_offset = gfx::ScrollOffset(13.f, 12.f);
3753   scroll_delegate.set_getter_return_value(current_offset);
3754   host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
3755
3756   EXPECT_EQ(current_offset.ToString(),
3757             scroll_layer->TotalScrollOffset().ToString());
3758 }
3759
3760 void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) {
3761   const gfx::Transform target_space_transform =
3762       layer->draw_properties().target_space_transform;
3763   EXPECT_TRUE(target_space_transform.IsScaleOrTranslation());
3764   gfx::Point translated_point;
3765   target_space_transform.TransformPoint(&translated_point);
3766   gfx::Point expected_point = gfx::Point() - ToRoundedVector2d(scroll_delta);
3767   EXPECT_EQ(expected_point.ToString(), translated_point.ToString());
3768 }
3769
3770 TEST_F(LayerTreeHostImplTest,
3771        ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) {
3772   TestScrollOffsetDelegate scroll_delegate;
3773   host_impl_->SetViewportSize(gfx::Size(10, 20));
3774   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
3775   LayerImpl* clip_layer = scroll_layer->parent()->parent();
3776   clip_layer->SetBounds(gfx::Size(10, 20));
3777   host_impl_->SetRootLayerScrollOffsetDelegate(&scroll_delegate);
3778
3779   // Draw first frame to clear any pending draws and check scroll.
3780   DrawFrame();
3781   CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f));
3782   EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
3783
3784   // Set external scroll delta on delegate and notify LayerTreeHost.
3785   gfx::ScrollOffset scroll_offset(10.f, 10.f);
3786   scroll_delegate.set_getter_return_value(scroll_offset);
3787   host_impl_->OnRootLayerDelegatedScrollOffsetChanged();
3788
3789   // Check scroll delta reflected in layer.
3790   LayerTreeHostImpl::FrameData frame;
3791   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
3792   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
3793   host_impl_->DidDrawAllLayers(frame);
3794   EXPECT_FALSE(frame.has_no_damage);
3795   CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset));
3796
3797   host_impl_->SetRootLayerScrollOffsetDelegate(NULL);
3798 }
3799
3800 TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
3801   InputHandlerScrollResult scroll_result;
3802   SetupScrollAndContentsLayers(gfx::Size(100, 100));
3803   host_impl_->SetViewportSize(gfx::Size(50, 50));
3804   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
3805   DrawFrame();
3806   EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3807
3808   // In-bounds scrolling does not affect overscroll.
3809   EXPECT_EQ(InputHandler::ScrollStarted,
3810             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
3811   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3812   EXPECT_TRUE(scroll_result.did_scroll);
3813   EXPECT_FALSE(scroll_result.did_overscroll_root);
3814   EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
3815   EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3816
3817   // Overscroll events are reflected immediately.
3818   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 50));
3819   EXPECT_TRUE(scroll_result.did_scroll);
3820   EXPECT_TRUE(scroll_result.did_overscroll_root);
3821   EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
3822   EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
3823   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3824             host_impl_->accumulated_root_overscroll());
3825
3826   // In-bounds scrolling resets accumulated overscroll for the scrolled axes.
3827   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -50));
3828   EXPECT_TRUE(scroll_result.did_scroll);
3829   EXPECT_FALSE(scroll_result.did_overscroll_root);
3830   EXPECT_EQ(gfx::Vector2dF(), scroll_result.unused_scroll_delta);
3831   EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
3832   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3833             host_impl_->accumulated_root_overscroll());
3834
3835   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -10));
3836   EXPECT_FALSE(scroll_result.did_scroll);
3837   EXPECT_TRUE(scroll_result.did_overscroll_root);
3838   EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
3839   EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
3840   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3841             host_impl_->accumulated_root_overscroll());
3842
3843   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, 0));
3844   EXPECT_TRUE(scroll_result.did_scroll);
3845   EXPECT_FALSE(scroll_result.did_overscroll_root);
3846   EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
3847   EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
3848   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3849             host_impl_->accumulated_root_overscroll());
3850
3851   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(-15, 0));
3852   EXPECT_TRUE(scroll_result.did_scroll);
3853   EXPECT_TRUE(scroll_result.did_overscroll_root);
3854   EXPECT_EQ(gfx::Vector2dF(-5, 0), scroll_result.unused_scroll_delta);
3855   EXPECT_EQ(gfx::Vector2dF(-5, -10), host_impl_->accumulated_root_overscroll());
3856   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3857             host_impl_->accumulated_root_overscroll());
3858
3859   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 60));
3860   EXPECT_TRUE(scroll_result.did_scroll);
3861   EXPECT_TRUE(scroll_result.did_overscroll_root);
3862   EXPECT_EQ(gfx::Vector2dF(0, 10), scroll_result.unused_scroll_delta);
3863   EXPECT_EQ(gfx::Vector2dF(-5, 10), host_impl_->accumulated_root_overscroll());
3864   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3865             host_impl_->accumulated_root_overscroll());
3866
3867   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(10, -60));
3868   EXPECT_TRUE(scroll_result.did_scroll);
3869   EXPECT_TRUE(scroll_result.did_overscroll_root);
3870   EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
3871   EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
3872   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3873             host_impl_->accumulated_root_overscroll());
3874
3875   // Overscroll accumulates within the scope of ScrollBegin/ScrollEnd as long
3876   // as no scroll occurs.
3877   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3878   EXPECT_FALSE(scroll_result.did_scroll);
3879   EXPECT_TRUE(scroll_result.did_overscroll_root);
3880   EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
3881   EXPECT_EQ(gfx::Vector2dF(0, -30), host_impl_->accumulated_root_overscroll());
3882   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3883             host_impl_->accumulated_root_overscroll());
3884
3885   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3886   EXPECT_FALSE(scroll_result.did_scroll);
3887   EXPECT_TRUE(scroll_result.did_overscroll_root);
3888   EXPECT_EQ(gfx::Vector2dF(0, -20), scroll_result.unused_scroll_delta);
3889   EXPECT_EQ(gfx::Vector2dF(0, -50), host_impl_->accumulated_root_overscroll());
3890   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3891             host_impl_->accumulated_root_overscroll());
3892
3893   // Overscroll resets on valid scroll.
3894   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
3895   EXPECT_TRUE(scroll_result.did_scroll);
3896   EXPECT_FALSE(scroll_result.did_overscroll_root);
3897   EXPECT_EQ(gfx::Vector2dF(0, 0), scroll_result.unused_scroll_delta);
3898   EXPECT_EQ(gfx::Vector2dF(0, 0), host_impl_->accumulated_root_overscroll());
3899   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3900             host_impl_->accumulated_root_overscroll());
3901
3902   scroll_result = host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, -20));
3903   EXPECT_TRUE(scroll_result.did_scroll);
3904   EXPECT_TRUE(scroll_result.did_overscroll_root);
3905   EXPECT_EQ(gfx::Vector2dF(0, -10), scroll_result.unused_scroll_delta);
3906   EXPECT_EQ(gfx::Vector2dF(0, -10), host_impl_->accumulated_root_overscroll());
3907   EXPECT_EQ(scroll_result.accumulated_root_overscroll,
3908             host_impl_->accumulated_root_overscroll());
3909
3910   host_impl_->ScrollEnd();
3911 }
3912
3913
3914 TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
3915   // Scroll child layers beyond their maximum scroll range and make sure root
3916   // overscroll does not accumulate.
3917   gfx::Size surface_size(10, 10);
3918   scoped_ptr<LayerImpl> root_clip =
3919       LayerImpl::Create(host_impl_->active_tree(), 4);
3920   scoped_ptr<LayerImpl> root =
3921       CreateScrollableLayer(1, surface_size, root_clip.get());
3922
3923   scoped_ptr<LayerImpl> grand_child =
3924       CreateScrollableLayer(3, surface_size, root_clip.get());
3925
3926   scoped_ptr<LayerImpl> child =
3927       CreateScrollableLayer(2, surface_size, root_clip.get());
3928   LayerImpl* grand_child_layer = grand_child.get();
3929   child->AddChild(grand_child.Pass());
3930
3931   LayerImpl* child_layer = child.get();
3932   root->AddChild(child.Pass());
3933   root_clip->AddChild(root.Pass());
3934   child_layer->SetScrollOffset(gfx::ScrollOffset(0, 3));
3935   grand_child_layer->SetScrollOffset(gfx::ScrollOffset(0, 2));
3936   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
3937   host_impl_->active_tree()->DidBecomeActive();
3938   host_impl_->SetViewportSize(surface_size);
3939   DrawFrame();
3940   {
3941     gfx::Vector2d scroll_delta(0, -10);
3942     EXPECT_EQ(InputHandler::ScrollStarted,
3943               host_impl_->ScrollBegin(gfx::Point(),
3944                                       InputHandler::NonBubblingGesture));
3945     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3946     EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3947     host_impl_->ScrollEnd();
3948
3949     // The next time we scroll we should only scroll the parent, but overscroll
3950     // should still not reach the root layer.
3951     scroll_delta = gfx::Vector2d(0, -30);
3952     EXPECT_EQ(InputHandler::ScrollStarted,
3953               host_impl_->ScrollBegin(gfx::Point(5, 5),
3954                                       InputHandler::NonBubblingGesture));
3955     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
3956     EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3957     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3958     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer);
3959     EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3960     host_impl_->ScrollEnd();
3961
3962     // After scrolling the parent, another scroll on the opposite direction
3963     // should scroll the child.
3964     scroll_delta = gfx::Vector2d(0, 70);
3965     EXPECT_EQ(InputHandler::ScrollStarted,
3966               host_impl_->ScrollBegin(gfx::Point(5, 5),
3967                                       InputHandler::NonBubblingGesture));
3968     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
3969     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
3970     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer);
3971     EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
3972     host_impl_->ScrollEnd();
3973   }
3974 }
3975
3976 TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
3977   // When we try to scroll a non-scrollable child layer, the scroll delta
3978   // should be applied to one of its ancestors if possible. Overscroll should
3979   // be reflected only when it has bubbled up to the root scrolling layer.
3980   gfx::Size surface_size(10, 10);
3981   gfx::Size content_size(20, 20);
3982   scoped_ptr<LayerImpl> root_clip =
3983       LayerImpl::Create(host_impl_->active_tree(), 3);
3984   scoped_ptr<LayerImpl> root =
3985       CreateScrollableLayer(1, content_size, root_clip.get());
3986   root->SetIsContainerForFixedPositionLayers(true);
3987   scoped_ptr<LayerImpl> child =
3988       CreateScrollableLayer(2, content_size, root_clip.get());
3989
3990   child->SetScrollClipLayer(Layer::INVALID_ID);
3991   root->AddChild(child.Pass());
3992   root_clip->AddChild(root.Pass());
3993
3994   host_impl_->SetViewportSize(surface_size);
3995   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
3996   host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID);
3997   host_impl_->active_tree()->DidBecomeActive();
3998   DrawFrame();
3999   {
4000     gfx::Vector2d scroll_delta(0, 8);
4001     EXPECT_EQ(InputHandler::ScrollStarted,
4002               host_impl_->ScrollBegin(gfx::Point(5, 5),
4003                                       InputHandler::Wheel));
4004     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
4005     EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
4006     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
4007     EXPECT_EQ(gfx::Vector2dF(0, 6), host_impl_->accumulated_root_overscroll());
4008     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
4009     EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
4010     host_impl_->ScrollEnd();
4011   }
4012 }
4013
4014 TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
4015   LayerTreeSettings settings;
4016   CreateHostImpl(settings, CreateOutputSurface());
4017
4018   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50));
4019   LayerImpl* clip_layer = scroll_layer->parent()->parent();
4020   clip_layer->SetBounds(gfx::Size(50, 50));
4021   host_impl_->SetViewportSize(gfx::Size(50, 50));
4022   host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
4023   DrawFrame();
4024   EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
4025
4026   // Even though the layer can't scroll the overscroll still happens.
4027   EXPECT_EQ(InputHandler::ScrollStarted,
4028             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
4029   host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10));
4030   EXPECT_EQ(gfx::Vector2dF(0, 10), host_impl_->accumulated_root_overscroll());
4031 }
4032
4033 TEST_F(LayerTreeHostImplTest, NoOverscrollOnFractionalDeviceScale) {
4034   gfx::Size surface_size(980, 1439);
4035   gfx::Size content_size(980, 1438);
4036   float device_scale_factor = 1.5f;
4037   scoped_ptr<LayerImpl> root_clip =
4038       LayerImpl::Create(host_impl_->active_tree(), 3);
4039   scoped_ptr<LayerImpl> root =
4040       CreateScrollableLayer(1, content_size, root_clip.get());
4041   root->SetIsContainerForFixedPositionLayers(true);
4042   scoped_ptr<LayerImpl> child =
4043       CreateScrollableLayer(2, content_size, root_clip.get());
4044   root->scroll_clip_layer()->SetBounds(gfx::Size(320, 469));
4045   host_impl_->active_tree()->SetPageScaleFactorAndLimits(
4046       0.326531f, 0.326531f, 5.f);
4047   host_impl_->active_tree()->SetPageScaleDelta(1.f);
4048   child->SetScrollClipLayer(Layer::INVALID_ID);
4049   root->AddChild(child.Pass());
4050   root_clip->AddChild(root.Pass());
4051
4052   host_impl_->SetViewportSize(surface_size);
4053   host_impl_->SetDeviceScaleFactor(device_scale_factor);
4054   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
4055   host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID);
4056   host_impl_->active_tree()->DidBecomeActive();
4057   DrawFrame();
4058   {
4059     // Horizontal & Vertical GlowEffect should not be applied when
4060     // content size is less then view port size. For Example Horizontal &
4061     // vertical GlowEffect should not be applied in about:blank page.
4062     EXPECT_EQ(InputHandler::ScrollStarted,
4063               host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel));
4064     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -1));
4065     EXPECT_EQ(gfx::Vector2dF().ToString(),
4066               host_impl_->accumulated_root_overscroll().ToString());
4067
4068     host_impl_->ScrollEnd();
4069   }
4070 }
4071
4072 TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
4073   gfx::Size surface_size(100, 100);
4074   gfx::Size content_size(200, 200);
4075   scoped_ptr<LayerImpl> root_clip =
4076       LayerImpl::Create(host_impl_->active_tree(), 3);
4077   scoped_ptr<LayerImpl> root =
4078       CreateScrollableLayer(1, content_size, root_clip.get());
4079   root->SetIsContainerForFixedPositionLayers(true);
4080   scoped_ptr<LayerImpl> child =
4081       CreateScrollableLayer(2, content_size, root_clip.get());
4082
4083   child->SetScrollClipLayer(Layer::INVALID_ID);
4084   root->AddChild(child.Pass());
4085   root_clip->AddChild(root.Pass());
4086
4087   host_impl_->SetViewportSize(surface_size);
4088   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
4089   host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID);
4090   host_impl_->active_tree()->DidBecomeActive();
4091   DrawFrame();
4092   {
4093     // Edge glow effect should be applicable only upon reaching Edges
4094     // of the content. unnecessary glow effect calls shouldn't be
4095     // called while scrolling up without reaching the edge of the content.
4096     EXPECT_EQ(InputHandler::ScrollStarted,
4097               host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel));
4098     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 100));
4099     EXPECT_EQ(gfx::Vector2dF().ToString(),
4100               host_impl_->accumulated_root_overscroll().ToString());
4101     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, -2.30f));
4102     EXPECT_EQ(gfx::Vector2dF().ToString(),
4103               host_impl_->accumulated_root_overscroll().ToString());
4104     host_impl_->ScrollEnd();
4105     // unusedrootDelta should be subtracted from applied delta so that
4106     // unwanted glow effect calls are not called.
4107     EXPECT_EQ(InputHandler::ScrollStarted,
4108               host_impl_->ScrollBegin(gfx::Point(0, 0),
4109                                       InputHandler::NonBubblingGesture));
4110     EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
4111     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0, 20));
4112     EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
4113               host_impl_->accumulated_root_overscroll().ToString());
4114
4115     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(0.02f, -0.01f));
4116     EXPECT_EQ(gfx::Vector2dF(0.000000f, 17.699997f).ToString(),
4117               host_impl_->accumulated_root_overscroll().ToString());
4118     host_impl_->ScrollEnd();
4119     // TestCase to check  kEpsilon, which prevents minute values to trigger
4120     // gloweffect without reaching edge.
4121     EXPECT_EQ(InputHandler::ScrollStarted,
4122               host_impl_->ScrollBegin(gfx::Point(0, 0), InputHandler::Wheel));
4123     host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f));
4124     EXPECT_EQ(gfx::Vector2dF().ToString(),
4125               host_impl_->accumulated_root_overscroll().ToString());
4126     host_impl_->ScrollEnd();
4127   }
4128 }
4129
4130 class BlendStateCheckLayer : public LayerImpl {
4131  public:
4132   static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl,
4133                                       int id,
4134                                       ResourceProvider* resource_provider) {
4135     return make_scoped_ptr(
4136         new BlendStateCheckLayer(tree_impl, id, resource_provider));
4137   }
4138
4139   void AppendQuads(RenderPass* render_pass,
4140                    const Occlusion& occlusion_in_content_space,
4141                    AppendQuadsData* append_quads_data) override {
4142     quads_appended_ = true;
4143
4144     gfx::Rect opaque_rect;
4145     if (contents_opaque())
4146       opaque_rect = quad_rect_;
4147     else
4148       opaque_rect = opaque_content_rect_;
4149     gfx::Rect visible_quad_rect = quad_rect_;
4150
4151     SharedQuadState* shared_quad_state =
4152         render_pass->CreateAndAppendSharedQuadState();
4153     PopulateSharedQuadState(shared_quad_state);
4154
4155     TileDrawQuad* test_blending_draw_quad =
4156         render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
4157     test_blending_draw_quad->SetNew(shared_quad_state,
4158                                     quad_rect_,
4159                                     opaque_rect,
4160                                     visible_quad_rect,
4161                                     resource_id_,
4162                                     gfx::RectF(0.f, 0.f, 1.f, 1.f),
4163                                     gfx::Size(1, 1),
4164                                     false);
4165     test_blending_draw_quad->visible_rect = quad_visible_rect_;
4166     EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
4167     EXPECT_EQ(has_render_surface_, !!render_surface());
4168   }
4169
4170   void SetExpectation(bool blend, bool has_render_surface) {
4171     blend_ = blend;
4172     has_render_surface_ = has_render_surface;
4173     quads_appended_ = false;
4174   }
4175
4176   bool quads_appended() const { return quads_appended_; }
4177
4178   void SetQuadRect(const gfx::Rect& rect) { quad_rect_ = rect; }
4179   void SetQuadVisibleRect(const gfx::Rect& rect) { quad_visible_rect_ = rect; }
4180   void SetOpaqueContentRect(const gfx::Rect& rect) {
4181     opaque_content_rect_ = rect;
4182   }
4183
4184  private:
4185   BlendStateCheckLayer(LayerTreeImpl* tree_impl,
4186                        int id,
4187                        ResourceProvider* resource_provider)
4188       : LayerImpl(tree_impl, id),
4189         blend_(false),
4190         has_render_surface_(false),
4191         quads_appended_(false),
4192         quad_rect_(5, 5, 5, 5),
4193         quad_visible_rect_(5, 5, 5, 5),
4194         resource_id_(resource_provider->CreateResource(
4195             gfx::Size(1, 1),
4196             GL_CLAMP_TO_EDGE,
4197             ResourceProvider::TextureHintImmutable,
4198             RGBA_8888)) {
4199     resource_provider->AllocateForTesting(resource_id_);
4200     SetBounds(gfx::Size(10, 10));
4201     SetContentBounds(gfx::Size(10, 10));
4202     SetDrawsContent(true);
4203   }
4204
4205   bool blend_;
4206   bool has_render_surface_;
4207   bool quads_appended_;
4208   gfx::Rect quad_rect_;
4209   gfx::Rect opaque_content_rect_;
4210   gfx::Rect quad_visible_rect_;
4211   ResourceProvider::ResourceId resource_id_;
4212 };
4213
4214 TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
4215   {
4216     scoped_ptr<LayerImpl> root =
4217         LayerImpl::Create(host_impl_->active_tree(), 1);
4218     root->SetBounds(gfx::Size(10, 10));
4219     root->SetContentBounds(root->bounds());
4220     root->SetDrawsContent(false);
4221     host_impl_->active_tree()->SetRootLayer(root.Pass());
4222   }
4223   LayerImpl* root = host_impl_->active_tree()->root_layer();
4224
4225   root->AddChild(
4226       BlendStateCheckLayer::Create(host_impl_->active_tree(),
4227                                    2,
4228                                    host_impl_->resource_provider()));
4229   BlendStateCheckLayer* layer1 =
4230       static_cast<BlendStateCheckLayer*>(root->children()[0]);
4231   layer1->SetPosition(gfx::PointF(2.f, 2.f));
4232
4233   LayerTreeHostImpl::FrameData frame;
4234
4235   // Opaque layer, drawn without blending.
4236   layer1->SetContentsOpaque(true);
4237   layer1->SetExpectation(false, false);
4238   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4239   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4240   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4241   EXPECT_TRUE(layer1->quads_appended());
4242   host_impl_->DidDrawAllLayers(frame);
4243
4244   // Layer with translucent content and painting, so drawn with blending.
4245   layer1->SetContentsOpaque(false);
4246   layer1->SetExpectation(true, false);
4247   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4248   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4249   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4250   EXPECT_TRUE(layer1->quads_appended());
4251   host_impl_->DidDrawAllLayers(frame);
4252
4253   // Layer with translucent opacity, drawn with blending.
4254   layer1->SetContentsOpaque(true);
4255   layer1->SetOpacity(0.5f);
4256   layer1->SetExpectation(true, false);
4257   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4258   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4259   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4260   EXPECT_TRUE(layer1->quads_appended());
4261   host_impl_->DidDrawAllLayers(frame);
4262
4263   // Layer with translucent opacity and painting, drawn with blending.
4264   layer1->SetContentsOpaque(true);
4265   layer1->SetOpacity(0.5f);
4266   layer1->SetExpectation(true, false);
4267   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4268   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4269   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4270   EXPECT_TRUE(layer1->quads_appended());
4271   host_impl_->DidDrawAllLayers(frame);
4272
4273   layer1->AddChild(
4274       BlendStateCheckLayer::Create(host_impl_->active_tree(),
4275                                    3,
4276                                    host_impl_->resource_provider()));
4277   BlendStateCheckLayer* layer2 =
4278       static_cast<BlendStateCheckLayer*>(layer1->children()[0]);
4279   layer2->SetPosition(gfx::PointF(4.f, 4.f));
4280
4281   // 2 opaque layers, drawn without blending.
4282   layer1->SetContentsOpaque(true);
4283   layer1->SetOpacity(1.f);
4284   layer1->SetExpectation(false, false);
4285   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4286   layer2->SetContentsOpaque(true);
4287   layer2->SetOpacity(1.f);
4288   layer2->SetExpectation(false, false);
4289   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4290   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4291   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4292   EXPECT_TRUE(layer1->quads_appended());
4293   EXPECT_TRUE(layer2->quads_appended());
4294   host_impl_->DidDrawAllLayers(frame);
4295
4296   // Parent layer with translucent content, drawn with blending.
4297   // Child layer with opaque content, drawn without blending.
4298   layer1->SetContentsOpaque(false);
4299   layer1->SetExpectation(true, false);
4300   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4301   layer2->SetExpectation(false, false);
4302   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4303   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4304   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4305   EXPECT_TRUE(layer1->quads_appended());
4306   EXPECT_TRUE(layer2->quads_appended());
4307   host_impl_->DidDrawAllLayers(frame);
4308
4309   // Parent layer with translucent content but opaque painting, drawn without
4310   // blending.
4311   // Child layer with opaque content, drawn without blending.
4312   layer1->SetContentsOpaque(true);
4313   layer1->SetExpectation(false, false);
4314   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4315   layer2->SetExpectation(false, false);
4316   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4317   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4318   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4319   EXPECT_TRUE(layer1->quads_appended());
4320   EXPECT_TRUE(layer2->quads_appended());
4321   host_impl_->DidDrawAllLayers(frame);
4322
4323   // Parent layer with translucent opacity and opaque content. Since it has a
4324   // drawing child, it's drawn to a render surface which carries the opacity,
4325   // so it's itself drawn without blending.
4326   // Child layer with opaque content, drawn without blending (parent surface
4327   // carries the inherited opacity).
4328   layer1->SetContentsOpaque(true);
4329   layer1->SetOpacity(0.5f);
4330   layer1->SetExpectation(false, true);
4331   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4332   layer2->SetExpectation(false, false);
4333   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4334   FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(
4335       host_impl_->active_tree()->root_layer());
4336   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4337   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4338   EXPECT_TRUE(layer1->quads_appended());
4339   EXPECT_TRUE(layer2->quads_appended());
4340   host_impl_->DidDrawAllLayers(frame);
4341
4342   // Draw again, but with child non-opaque, to make sure
4343   // layer1 not culled.
4344   layer1->SetContentsOpaque(true);
4345   layer1->SetOpacity(1.f);
4346   layer1->SetExpectation(false, false);
4347   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4348   layer2->SetContentsOpaque(true);
4349   layer2->SetOpacity(0.5f);
4350   layer2->SetExpectation(true, false);
4351   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4352   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4353   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4354   EXPECT_TRUE(layer1->quads_appended());
4355   EXPECT_TRUE(layer2->quads_appended());
4356   host_impl_->DidDrawAllLayers(frame);
4357
4358   // A second way of making the child non-opaque.
4359   layer1->SetContentsOpaque(true);
4360   layer1->SetOpacity(1.f);
4361   layer1->SetExpectation(false, false);
4362   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4363   layer2->SetContentsOpaque(false);
4364   layer2->SetOpacity(1.f);
4365   layer2->SetExpectation(true, false);
4366   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4367   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4368   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4369   EXPECT_TRUE(layer1->quads_appended());
4370   EXPECT_TRUE(layer2->quads_appended());
4371   host_impl_->DidDrawAllLayers(frame);
4372
4373   // And when the layer says its not opaque but is painted opaque, it is not
4374   // blended.
4375   layer1->SetContentsOpaque(true);
4376   layer1->SetOpacity(1.f);
4377   layer1->SetExpectation(false, false);
4378   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4379   layer2->SetContentsOpaque(true);
4380   layer2->SetOpacity(1.f);
4381   layer2->SetExpectation(false, false);
4382   layer2->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4383   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4384   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4385   EXPECT_TRUE(layer1->quads_appended());
4386   EXPECT_TRUE(layer2->quads_appended());
4387   host_impl_->DidDrawAllLayers(frame);
4388
4389   // Layer with partially opaque contents, drawn with blending.
4390   layer1->SetContentsOpaque(false);
4391   layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4392   layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
4393   layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4394   layer1->SetExpectation(true, false);
4395   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4396   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4397   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4398   EXPECT_TRUE(layer1->quads_appended());
4399   host_impl_->DidDrawAllLayers(frame);
4400
4401   // Layer with partially opaque contents partially culled, drawn with blending.
4402   layer1->SetContentsOpaque(false);
4403   layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4404   layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
4405   layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4406   layer1->SetExpectation(true, false);
4407   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4408   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4409   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4410   EXPECT_TRUE(layer1->quads_appended());
4411   host_impl_->DidDrawAllLayers(frame);
4412
4413   // Layer with partially opaque contents culled, drawn with blending.
4414   layer1->SetContentsOpaque(false);
4415   layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4416   layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
4417   layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4418   layer1->SetExpectation(true, false);
4419   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4420   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4421   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4422   EXPECT_TRUE(layer1->quads_appended());
4423   host_impl_->DidDrawAllLayers(frame);
4424
4425   // Layer with partially opaque contents and translucent contents culled, drawn
4426   // without blending.
4427   layer1->SetContentsOpaque(false);
4428   layer1->SetQuadRect(gfx::Rect(5, 5, 5, 5));
4429   layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
4430   layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
4431   layer1->SetExpectation(false, false);
4432   layer1->SetUpdateRect(gfx::Rect(layer1->content_bounds()));
4433   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4434   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4435   EXPECT_TRUE(layer1->quads_appended());
4436   host_impl_->DidDrawAllLayers(frame);
4437 }
4438
4439 class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest {
4440  protected:
4441   LayerTreeHostImplViewportCoveredTest() :
4442       gutter_quad_material_(DrawQuad::SOLID_COLOR),
4443       child_(NULL),
4444       did_activate_pending_tree_(false) {}
4445
4446   scoped_ptr<OutputSurface> CreateFakeOutputSurface(bool always_draw) {
4447     if (always_draw) {
4448       return FakeOutputSurface::CreateAlwaysDrawAndSwap3d();
4449     }
4450     return FakeOutputSurface::Create3d();
4451   }
4452
4453   void SetupActiveTreeLayers() {
4454     host_impl_->active_tree()->set_background_color(SK_ColorGRAY);
4455     host_impl_->active_tree()->SetRootLayer(
4456         LayerImpl::Create(host_impl_->active_tree(), 1));
4457     host_impl_->active_tree()->root_layer()->AddChild(
4458         BlendStateCheckLayer::Create(host_impl_->active_tree(),
4459                                      2,
4460                                      host_impl_->resource_provider()));
4461     child_ = static_cast<BlendStateCheckLayer*>(
4462         host_impl_->active_tree()->root_layer()->children()[0]);
4463     child_->SetExpectation(false, false);
4464     child_->SetContentsOpaque(true);
4465   }
4466
4467   // Expect no gutter rects.
4468   void TestLayerCoversFullViewport() {
4469     gfx::Rect layer_rect(viewport_size_);
4470     child_->SetPosition(layer_rect.origin());
4471     child_->SetBounds(layer_rect.size());
4472     child_->SetContentBounds(layer_rect.size());
4473     child_->SetQuadRect(gfx::Rect(layer_rect.size()));
4474     child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
4475
4476     LayerTreeHostImpl::FrameData frame;
4477     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4478     ASSERT_EQ(1u, frame.render_passes.size());
4479
4480     EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
4481     EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
4482     ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
4483
4484     VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
4485     host_impl_->DidDrawAllLayers(frame);
4486   }
4487
4488   // Expect fullscreen gutter rect.
4489   void TestEmptyLayer() {
4490     gfx::Rect layer_rect(0, 0, 0, 0);
4491     child_->SetPosition(layer_rect.origin());
4492     child_->SetBounds(layer_rect.size());
4493     child_->SetContentBounds(layer_rect.size());
4494     child_->SetQuadRect(gfx::Rect(layer_rect.size()));
4495     child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
4496
4497     LayerTreeHostImpl::FrameData frame;
4498     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4499     ASSERT_EQ(1u, frame.render_passes.size());
4500
4501     EXPECT_EQ(1u, CountGutterQuads(frame.render_passes[0]->quad_list));
4502     EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
4503     ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
4504
4505     VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
4506     host_impl_->DidDrawAllLayers(frame);
4507   }
4508
4509   // Expect four surrounding gutter rects.
4510   void TestLayerInMiddleOfViewport() {
4511     gfx::Rect layer_rect(500, 500, 200, 200);
4512     child_->SetPosition(layer_rect.origin());
4513     child_->SetBounds(layer_rect.size());
4514     child_->SetContentBounds(layer_rect.size());
4515     child_->SetQuadRect(gfx::Rect(layer_rect.size()));
4516     child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
4517
4518     LayerTreeHostImpl::FrameData frame;
4519     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4520     ASSERT_EQ(1u, frame.render_passes.size());
4521
4522     EXPECT_EQ(4u, CountGutterQuads(frame.render_passes[0]->quad_list));
4523     EXPECT_EQ(5u, frame.render_passes[0]->quad_list.size());
4524     ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
4525
4526     VerifyQuadsExactlyCoverViewport(frame.render_passes[0]->quad_list);
4527     host_impl_->DidDrawAllLayers(frame);
4528   }
4529
4530   // Expect no gutter rects.
4531   void TestLayerIsLargerThanViewport() {
4532     gfx::Rect layer_rect(viewport_size_.width() + 10,
4533                          viewport_size_.height() + 10);
4534     child_->SetPosition(layer_rect.origin());
4535     child_->SetBounds(layer_rect.size());
4536     child_->SetContentBounds(layer_rect.size());
4537     child_->SetQuadRect(gfx::Rect(layer_rect.size()));
4538     child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size()));
4539
4540     LayerTreeHostImpl::FrameData frame;
4541     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4542     ASSERT_EQ(1u, frame.render_passes.size());
4543
4544     EXPECT_EQ(0u, CountGutterQuads(frame.render_passes[0]->quad_list));
4545     EXPECT_EQ(1u, frame.render_passes[0]->quad_list.size());
4546     ValidateTextureDrawQuads(frame.render_passes[0]->quad_list);
4547
4548     host_impl_->DidDrawAllLayers(frame);
4549   }
4550
4551   void DidActivateSyncTree() override { did_activate_pending_tree_ = true; }
4552
4553   void set_gutter_quad_material(DrawQuad::Material material) {
4554     gutter_quad_material_ = material;
4555   }
4556   void set_gutter_texture_size(const gfx::Size& gutter_texture_size) {
4557     gutter_texture_size_ = gutter_texture_size;
4558   }
4559
4560  protected:
4561   size_t CountGutterQuads(const QuadList& quad_list) {
4562     size_t num_gutter_quads = 0;
4563     for (const auto& quad : quad_list) {
4564       num_gutter_quads += (quad->material == gutter_quad_material_) ? 1 : 0;
4565     }
4566     return num_gutter_quads;
4567   }
4568
4569   void VerifyQuadsExactlyCoverViewport(const QuadList& quad_list) {
4570     LayerTestCommon::VerifyQuadsExactlyCoverRect(
4571         quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_)));
4572   }
4573
4574   // Make sure that the texture coordinates match their expectations.
4575   void ValidateTextureDrawQuads(const QuadList& quad_list) {
4576     for (const auto& quad : quad_list) {
4577       if (quad->material != DrawQuad::TEXTURE_CONTENT)
4578         continue;
4579       const TextureDrawQuad* texture_quad = TextureDrawQuad::MaterialCast(quad);
4580       gfx::SizeF gutter_texture_size_pixels = gfx::ScaleSize(
4581           gutter_texture_size_, host_impl_->device_scale_factor());
4582       EXPECT_EQ(texture_quad->uv_top_left.x(),
4583                 texture_quad->rect.x() / gutter_texture_size_pixels.width());
4584       EXPECT_EQ(texture_quad->uv_top_left.y(),
4585                 texture_quad->rect.y() / gutter_texture_size_pixels.height());
4586       EXPECT_EQ(
4587           texture_quad->uv_bottom_right.x(),
4588           texture_quad->rect.right() / gutter_texture_size_pixels.width());
4589       EXPECT_EQ(
4590           texture_quad->uv_bottom_right.y(),
4591           texture_quad->rect.bottom() / gutter_texture_size_pixels.height());
4592     }
4593   }
4594
4595   gfx::Size DipSizeToPixelSize(const gfx::Size& size) {
4596     return gfx::ToRoundedSize(
4597         gfx::ScaleSize(size, host_impl_->device_scale_factor()));
4598   }
4599
4600   DrawQuad::Material gutter_quad_material_;
4601   gfx::Size gutter_texture_size_;
4602   gfx::Size viewport_size_;
4603   BlendStateCheckLayer* child_;
4604   bool did_activate_pending_tree_;
4605 };
4606
4607 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) {
4608   viewport_size_ = gfx::Size(1000, 1000);
4609
4610   bool always_draw = false;
4611   CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
4612
4613   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4614   SetupActiveTreeLayers();
4615   TestLayerCoversFullViewport();
4616   TestEmptyLayer();
4617   TestLayerInMiddleOfViewport();
4618   TestLayerIsLargerThanViewport();
4619 }
4620
4621 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
4622   viewport_size_ = gfx::Size(1000, 1000);
4623
4624   bool always_draw = false;
4625   CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
4626
4627   host_impl_->SetDeviceScaleFactor(2.f);
4628   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4629   SetupActiveTreeLayers();
4630   TestLayerCoversFullViewport();
4631   TestEmptyLayer();
4632   TestLayerInMiddleOfViewport();
4633   TestLayerIsLargerThanViewport();
4634 }
4635
4636 TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredOverhangBitmap) {
4637   viewport_size_ = gfx::Size(1000, 1000);
4638
4639   bool always_draw = false;
4640   CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
4641
4642   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4643   SetupActiveTreeLayers();
4644
4645   // Specify an overhang bitmap to use.
4646   bool is_opaque = false;
4647   UIResourceBitmap ui_resource_bitmap(gfx::Size(2, 2), is_opaque);
4648   ui_resource_bitmap.SetWrapMode(UIResourceBitmap::REPEAT);
4649   UIResourceId ui_resource_id = 12345;
4650   host_impl_->CreateUIResource(ui_resource_id, ui_resource_bitmap);
4651   host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(32, 32));
4652   set_gutter_quad_material(DrawQuad::TEXTURE_CONTENT);
4653   set_gutter_texture_size(gfx::Size(32, 32));
4654
4655   TestLayerCoversFullViewport();
4656   TestEmptyLayer();
4657   TestLayerInMiddleOfViewport();
4658   TestLayerIsLargerThanViewport();
4659
4660   // Change the resource size.
4661   host_impl_->SetOverhangUIResource(ui_resource_id, gfx::Size(128, 16));
4662   set_gutter_texture_size(gfx::Size(128, 16));
4663
4664   TestLayerCoversFullViewport();
4665   TestEmptyLayer();
4666   TestLayerInMiddleOfViewport();
4667   TestLayerIsLargerThanViewport();
4668
4669   // Change the device scale factor
4670   host_impl_->SetDeviceScaleFactor(2.f);
4671   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4672
4673   TestLayerCoversFullViewport();
4674   TestEmptyLayer();
4675   TestLayerInMiddleOfViewport();
4676   TestLayerIsLargerThanViewport();
4677 }
4678
4679 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) {
4680   viewport_size_ = gfx::Size(1000, 1000);
4681
4682   bool always_draw = true;
4683   CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
4684
4685   // Pending tree to force active_tree size invalid. Not used otherwise.
4686   host_impl_->CreatePendingTree();
4687   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4688   EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
4689
4690   SetupActiveTreeLayers();
4691   TestEmptyLayer();
4692   TestLayerInMiddleOfViewport();
4693   TestLayerIsLargerThanViewport();
4694 }
4695
4696 TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeShrinkViewportInvalid) {
4697   viewport_size_ = gfx::Size(1000, 1000);
4698
4699   bool always_draw = true;
4700   CreateHostImpl(DefaultSettings(), CreateFakeOutputSurface(always_draw));
4701
4702   // Set larger viewport and activate it to active tree.
4703   host_impl_->CreatePendingTree();
4704   gfx::Size larger_viewport(viewport_size_.width() + 100,
4705                             viewport_size_.height() + 100);
4706   host_impl_->SetViewportSize(DipSizeToPixelSize(larger_viewport));
4707   EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
4708   host_impl_->ActivateSyncTree();
4709   EXPECT_TRUE(did_activate_pending_tree_);
4710   EXPECT_FALSE(host_impl_->active_tree()->ViewportSizeInvalid());
4711
4712   // Shrink pending tree viewport without activating.
4713   host_impl_->CreatePendingTree();
4714   host_impl_->SetViewportSize(DipSizeToPixelSize(viewport_size_));
4715   EXPECT_TRUE(host_impl_->active_tree()->ViewportSizeInvalid());
4716
4717   SetupActiveTreeLayers();
4718   TestEmptyLayer();
4719   TestLayerInMiddleOfViewport();
4720   TestLayerIsLargerThanViewport();
4721 }
4722
4723 class FakeDrawableLayerImpl: public LayerImpl {
4724  public:
4725   static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
4726     return make_scoped_ptr(new FakeDrawableLayerImpl(tree_impl, id));
4727   }
4728  protected:
4729   FakeDrawableLayerImpl(LayerTreeImpl* tree_impl, int id)
4730       : LayerImpl(tree_impl, id) {}
4731 };
4732
4733 // Only reshape when we know we are going to draw. Otherwise, the reshape
4734 // can leave the window at the wrong size if we never draw and the proper
4735 // viewport size is never set.
4736 TEST_F(LayerTreeHostImplTest, ReshapeNotCalledUntilDraw) {
4737   scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
4738   scoped_ptr<OutputSurface> output_surface(
4739       FakeOutputSurface::Create3d(provider));
4740   CreateHostImpl(DefaultSettings(), output_surface.Pass());
4741
4742   scoped_ptr<LayerImpl> root =
4743       FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
4744   root->SetBounds(gfx::Size(10, 10));
4745   root->SetContentBounds(gfx::Size(10, 10));
4746   root->SetDrawsContent(true);
4747   host_impl_->active_tree()->SetRootLayer(root.Pass());
4748   EXPECT_FALSE(provider->TestContext3d()->reshape_called());
4749   provider->TestContext3d()->clear_reshape_called();
4750
4751   LayerTreeHostImpl::FrameData frame;
4752   host_impl_->SetViewportSize(gfx::Size(10, 10));
4753   host_impl_->SetDeviceScaleFactor(1.f);
4754   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4755   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4756   EXPECT_TRUE(provider->TestContext3d()->reshape_called());
4757   EXPECT_EQ(provider->TestContext3d()->width(), 10);
4758   EXPECT_EQ(provider->TestContext3d()->height(), 10);
4759   EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
4760   host_impl_->DidDrawAllLayers(frame);
4761   provider->TestContext3d()->clear_reshape_called();
4762
4763   host_impl_->SetViewportSize(gfx::Size(20, 30));
4764   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4765   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4766   EXPECT_TRUE(provider->TestContext3d()->reshape_called());
4767   EXPECT_EQ(provider->TestContext3d()->width(), 20);
4768   EXPECT_EQ(provider->TestContext3d()->height(), 30);
4769   EXPECT_EQ(provider->TestContext3d()->scale_factor(), 1.f);
4770   host_impl_->DidDrawAllLayers(frame);
4771   provider->TestContext3d()->clear_reshape_called();
4772
4773   host_impl_->SetDeviceScaleFactor(2.f);
4774   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4775   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
4776   EXPECT_TRUE(provider->TestContext3d()->reshape_called());
4777   EXPECT_EQ(provider->TestContext3d()->width(), 20);
4778   EXPECT_EQ(provider->TestContext3d()->height(), 30);
4779   EXPECT_EQ(provider->TestContext3d()->scale_factor(), 2.f);
4780   host_impl_->DidDrawAllLayers(frame);
4781   provider->TestContext3d()->clear_reshape_called();
4782 }
4783
4784 // Make sure damage tracking propagates all the way to the graphics context,
4785 // where it should request to swap only the sub-buffer that is damaged.
4786 TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
4787   scoped_refptr<TestContextProvider> context_provider(
4788       TestContextProvider::Create());
4789   context_provider->BindToCurrentThread();
4790   context_provider->TestContext3d()->set_have_post_sub_buffer(true);
4791
4792   scoped_ptr<FakeOutputSurface> output_surface(
4793       FakeOutputSurface::Create3d(context_provider));
4794   FakeOutputSurface* fake_output_surface = output_surface.get();
4795
4796   // This test creates its own LayerTreeHostImpl, so
4797   // that we can force partial swap enabled.
4798   LayerTreeSettings settings;
4799   settings.partial_swap_enabled = true;
4800   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
4801       new TestSharedBitmapManager());
4802   scoped_ptr<LayerTreeHostImpl> layer_tree_host_impl =
4803       LayerTreeHostImpl::Create(settings,
4804                                 this,
4805                                 &proxy_,
4806                                 &stats_instrumentation_,
4807                                 shared_bitmap_manager.get(),
4808                                 NULL,
4809                                 0);
4810   layer_tree_host_impl->InitializeRenderer(output_surface.Pass());
4811   layer_tree_host_impl->SetViewportSize(gfx::Size(500, 500));
4812
4813   scoped_ptr<LayerImpl> root =
4814       FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1);
4815   scoped_ptr<LayerImpl> child =
4816       FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2);
4817   child->SetPosition(gfx::PointF(12.f, 13.f));
4818   child->SetBounds(gfx::Size(14, 15));
4819   child->SetContentBounds(gfx::Size(14, 15));
4820   child->SetDrawsContent(true);
4821   root->SetBounds(gfx::Size(500, 500));
4822   root->SetContentBounds(gfx::Size(500, 500));
4823   root->SetDrawsContent(true);
4824   root->AddChild(child.Pass());
4825   layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass());
4826
4827   LayerTreeHostImpl::FrameData frame;
4828
4829   // First frame, the entire screen should get swapped.
4830   EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
4831   layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
4832   layer_tree_host_impl->DidDrawAllLayers(frame);
4833   layer_tree_host_impl->SwapBuffers(frame);
4834   gfx::Rect expected_swap_rect(0, 0, 500, 500);
4835   EXPECT_EQ(expected_swap_rect.ToString(),
4836             fake_output_surface->last_swap_rect().ToString());
4837
4838   // Second frame, only the damaged area should get swapped. Damage should be
4839   // the union of old and new child rects.
4840   // expected damage rect: gfx::Rect(26, 28);
4841   // expected swap rect: vertically flipped, with origin at bottom left corner.
4842   layer_tree_host_impl->active_tree()->root_layer()->children()[0]->SetPosition(
4843       gfx::PointF());
4844   EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
4845   layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
4846   host_impl_->DidDrawAllLayers(frame);
4847   layer_tree_host_impl->SwapBuffers(frame);
4848
4849   // Make sure that partial swap is constrained to the viewport dimensions
4850   // expected damage rect: gfx::Rect(500, 500);
4851   // expected swap rect: flipped damage rect, but also clamped to viewport
4852   expected_swap_rect = gfx::Rect(0, 500-28, 26, 28);
4853   EXPECT_EQ(expected_swap_rect.ToString(),
4854             fake_output_surface->last_swap_rect().ToString());
4855
4856   layer_tree_host_impl->SetViewportSize(gfx::Size(10, 10));
4857   // This will damage everything.
4858   layer_tree_host_impl->active_tree()->root_layer()->SetBackgroundColor(
4859       SK_ColorBLACK);
4860   EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
4861   layer_tree_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
4862   host_impl_->DidDrawAllLayers(frame);
4863   layer_tree_host_impl->SwapBuffers(frame);
4864
4865   expected_swap_rect = gfx::Rect(0, 0, 10, 10);
4866   EXPECT_EQ(expected_swap_rect.ToString(),
4867             fake_output_surface->last_swap_rect().ToString());
4868 }
4869
4870 TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) {
4871   scoped_ptr<LayerImpl> root =
4872       FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1);
4873   scoped_ptr<LayerImpl> child =
4874       FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2);
4875   child->SetBounds(gfx::Size(10, 10));
4876   child->SetContentBounds(gfx::Size(10, 10));
4877   child->SetDrawsContent(true);
4878   root->SetBounds(gfx::Size(10, 10));
4879   root->SetContentBounds(gfx::Size(10, 10));
4880   root->SetDrawsContent(true);
4881   root->SetForceRenderSurface(true);
4882   root->AddChild(child.Pass());
4883
4884   host_impl_->active_tree()->SetRootLayer(root.Pass());
4885
4886   LayerTreeHostImpl::FrameData frame;
4887
4888   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
4889   EXPECT_EQ(1u, frame.render_surface_layer_list->size());
4890   EXPECT_EQ(1u, frame.render_passes.size());
4891   host_impl_->DidDrawAllLayers(frame);
4892 }
4893
4894 class FakeLayerWithQuads : public LayerImpl {
4895  public:
4896   static scoped_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) {
4897     return make_scoped_ptr(new FakeLayerWithQuads(tree_impl, id));
4898   }
4899
4900   void AppendQuads(RenderPass* render_pass,
4901                    const Occlusion& occlusion_in_content_space,
4902                    AppendQuadsData* append_quads_data) override {
4903     SharedQuadState* shared_quad_state =
4904         render_pass->CreateAndAppendSharedQuadState();
4905     PopulateSharedQuadState(shared_quad_state);
4906
4907     SkColor gray = SkColorSetRGB(100, 100, 100);
4908     gfx::Rect quad_rect(content_bounds());
4909     gfx::Rect visible_quad_rect(quad_rect);
4910     SolidColorDrawQuad* my_quad =
4911         render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
4912     my_quad->SetNew(
4913         shared_quad_state, quad_rect, visible_quad_rect, gray, false);
4914   }
4915
4916  private:
4917   FakeLayerWithQuads(LayerTreeImpl* tree_impl, int id)
4918       : LayerImpl(tree_impl, id) {}
4919 };
4920
4921 class MockContext : public TestWebGraphicsContext3D {
4922  public:
4923   MOCK_METHOD1(useProgram, void(GLuint program));
4924   MOCK_METHOD5(uniform4f, void(GLint location,
4925                                GLfloat x,
4926                                GLfloat y,
4927                                GLfloat z,
4928                                GLfloat w));
4929   MOCK_METHOD4(uniformMatrix4fv, void(GLint location,
4930                                       GLsizei count,
4931                                       GLboolean transpose,
4932                                       const GLfloat* value));
4933   MOCK_METHOD4(drawElements, void(GLenum mode,
4934                                   GLsizei count,
4935                                   GLenum type,
4936                                   GLintptr offset));
4937   MOCK_METHOD1(enable, void(GLenum cap));
4938   MOCK_METHOD1(disable, void(GLenum cap));
4939   MOCK_METHOD4(scissor, void(GLint x,
4940                              GLint y,
4941                              GLsizei width,
4942                              GLsizei height));
4943 };
4944
4945 class MockContextHarness {
4946  private:
4947   MockContext* context_;
4948
4949  public:
4950   explicit MockContextHarness(MockContext* context)
4951       : context_(context) {
4952     context_->set_have_post_sub_buffer(true);
4953
4954     // Catch "uninteresting" calls
4955     EXPECT_CALL(*context_, useProgram(_))
4956         .Times(0);
4957
4958     EXPECT_CALL(*context_, drawElements(_, _, _, _))
4959         .Times(0);
4960
4961     // These are not asserted
4962     EXPECT_CALL(*context_, uniformMatrix4fv(_, _, _, _))
4963         .WillRepeatedly(Return());
4964
4965     EXPECT_CALL(*context_, uniform4f(_, _, _, _, _))
4966         .WillRepeatedly(Return());
4967
4968     // Any un-sanctioned calls to enable() are OK
4969     EXPECT_CALL(*context_, enable(_))
4970         .WillRepeatedly(Return());
4971
4972     // Any un-sanctioned calls to disable() are OK
4973     EXPECT_CALL(*context_, disable(_))
4974         .WillRepeatedly(Return());
4975   }
4976
4977   void MustDrawSolidQuad() {
4978     EXPECT_CALL(*context_, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0))
4979         .WillOnce(Return())
4980         .RetiresOnSaturation();
4981
4982     EXPECT_CALL(*context_, useProgram(_))
4983         .WillOnce(Return())
4984         .RetiresOnSaturation();
4985   }
4986
4987   void MustSetScissor(int x, int y, int width, int height) {
4988     EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
4989         .WillRepeatedly(Return());
4990
4991     EXPECT_CALL(*context_, scissor(x, y, width, height))
4992         .Times(AtLeast(1))
4993         .WillRepeatedly(Return());
4994   }
4995
4996   void MustSetNoScissor() {
4997     EXPECT_CALL(*context_, disable(GL_SCISSOR_TEST))
4998         .WillRepeatedly(Return());
4999
5000     EXPECT_CALL(*context_, enable(GL_SCISSOR_TEST))
5001         .Times(0);
5002
5003     EXPECT_CALL(*context_, scissor(_, _, _, _))
5004         .Times(0);
5005   }
5006 };
5007
5008 TEST_F(LayerTreeHostImplTest, NoPartialSwap) {
5009   scoped_ptr<MockContext> mock_context_owned(new MockContext);
5010   MockContext* mock_context = mock_context_owned.get();
5011   MockContextHarness harness(mock_context);
5012
5013   // Run test case
5014   LayerTreeSettings settings = DefaultSettings();
5015   settings.partial_swap_enabled = false;
5016   CreateHostImpl(settings,
5017                  FakeOutputSurface::Create3d(mock_context_owned.Pass()));
5018   SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
5019
5020   // Without partial swap, and no clipping, no scissor is set.
5021   harness.MustDrawSolidQuad();
5022   harness.MustSetNoScissor();
5023   {
5024     LayerTreeHostImpl::FrameData frame;
5025     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5026     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5027     host_impl_->DidDrawAllLayers(frame);
5028   }
5029   Mock::VerifyAndClearExpectations(&mock_context);
5030
5031   // Without partial swap, but a layer does clip its subtree, one scissor is
5032   // set.
5033   host_impl_->active_tree()->root_layer()->SetMasksToBounds(true);
5034   harness.MustDrawSolidQuad();
5035   harness.MustSetScissor(0, 0, 10, 10);
5036   {
5037     LayerTreeHostImpl::FrameData frame;
5038     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5039     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5040     host_impl_->DidDrawAllLayers(frame);
5041   }
5042   Mock::VerifyAndClearExpectations(&mock_context);
5043 }
5044
5045 TEST_F(LayerTreeHostImplTest, PartialSwap) {
5046   scoped_ptr<MockContext> context_owned(new MockContext);
5047   MockContext* mock_context = context_owned.get();
5048   MockContextHarness harness(mock_context);
5049
5050   LayerTreeSettings settings = DefaultSettings();
5051   settings.partial_swap_enabled = true;
5052   CreateHostImpl(settings, FakeOutputSurface::Create3d(context_owned.Pass()));
5053   SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
5054
5055   // The first frame is not a partially-swapped one.
5056   harness.MustSetScissor(0, 0, 10, 10);
5057   harness.MustDrawSolidQuad();
5058   {
5059     LayerTreeHostImpl::FrameData frame;
5060     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5061     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5062     host_impl_->DidDrawAllLayers(frame);
5063   }
5064   Mock::VerifyAndClearExpectations(&mock_context);
5065
5066   // Damage a portion of the frame.
5067   host_impl_->active_tree()->root_layer()->SetUpdateRect(
5068       gfx::Rect(0, 0, 2, 3));
5069
5070   // The second frame will be partially-swapped (the y coordinates are flipped).
5071   harness.MustSetScissor(0, 7, 2, 3);
5072   harness.MustDrawSolidQuad();
5073   {
5074     LayerTreeHostImpl::FrameData frame;
5075     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5076     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5077     host_impl_->DidDrawAllLayers(frame);
5078   }
5079   Mock::VerifyAndClearExpectations(&mock_context);
5080 }
5081
5082 static scoped_ptr<LayerTreeHostImpl> SetupLayersForOpacity(
5083     bool partial_swap,
5084     LayerTreeHostImplClient* client,
5085     Proxy* proxy,
5086     SharedBitmapManager* manager,
5087     RenderingStatsInstrumentation* stats_instrumentation) {
5088   scoped_refptr<TestContextProvider> provider(TestContextProvider::Create());
5089   scoped_ptr<OutputSurface> output_surface(
5090       FakeOutputSurface::Create3d(provider));
5091   provider->BindToCurrentThread();
5092   provider->TestContext3d()->set_have_post_sub_buffer(true);
5093
5094   LayerTreeSettings settings;
5095   settings.partial_swap_enabled = partial_swap;
5096   scoped_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create(
5097       settings, client, proxy, stats_instrumentation, manager, NULL, 0);
5098   my_host_impl->InitializeRenderer(output_surface.Pass());
5099   my_host_impl->SetViewportSize(gfx::Size(100, 100));
5100
5101   /*
5102     Layers are created as follows:
5103
5104     +--------------------+
5105     |                  1 |
5106     |  +-----------+     |
5107     |  |         2 |     |
5108     |  | +-------------------+
5109     |  | |   3               |
5110     |  | +-------------------+
5111     |  |           |     |
5112     |  +-----------+     |
5113     |                    |
5114     |                    |
5115     +--------------------+
5116
5117     Layers 1, 2 have render surfaces
5118   */
5119   scoped_ptr<LayerImpl> root =
5120       LayerImpl::Create(my_host_impl->active_tree(), 1);
5121   scoped_ptr<LayerImpl> child =
5122       LayerImpl::Create(my_host_impl->active_tree(), 2);
5123   scoped_ptr<LayerImpl> grand_child =
5124       FakeLayerWithQuads::Create(my_host_impl->active_tree(), 3);
5125
5126   gfx::Rect root_rect(0, 0, 100, 100);
5127   gfx::Rect child_rect(10, 10, 50, 50);
5128   gfx::Rect grand_child_rect(5, 5, 150, 150);
5129
5130   root->CreateRenderSurface();
5131   root->SetPosition(root_rect.origin());
5132   root->SetBounds(root_rect.size());
5133   root->SetContentBounds(root->bounds());
5134   root->draw_properties().visible_content_rect = root_rect;
5135   root->SetDrawsContent(false);
5136   root->render_surface()->SetContentRect(gfx::Rect(root_rect.size()));
5137
5138   child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y()));
5139   child->SetOpacity(0.5f);
5140   child->SetBounds(gfx::Size(child_rect.width(), child_rect.height()));
5141   child->SetContentBounds(child->bounds());
5142   child->draw_properties().visible_content_rect = child_rect;
5143   child->SetDrawsContent(false);
5144   child->SetForceRenderSurface(true);
5145
5146   grand_child->SetPosition(grand_child_rect.origin());
5147   grand_child->SetBounds(grand_child_rect.size());
5148   grand_child->SetContentBounds(grand_child->bounds());
5149   grand_child->draw_properties().visible_content_rect = grand_child_rect;
5150   grand_child->SetDrawsContent(true);
5151
5152   child->AddChild(grand_child.Pass());
5153   root->AddChild(child.Pass());
5154
5155   my_host_impl->active_tree()->SetRootLayer(root.Pass());
5156   return my_host_impl.Pass();
5157 }
5158
5159 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) {
5160   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
5161       new TestSharedBitmapManager());
5162   scoped_ptr<LayerTreeHostImpl> my_host_impl =
5163       SetupLayersForOpacity(true,
5164                             this,
5165                             &proxy_,
5166                             shared_bitmap_manager.get(),
5167                             &stats_instrumentation_);
5168   {
5169     LayerTreeHostImpl::FrameData frame;
5170     EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
5171
5172     // Verify all quads have been computed
5173     ASSERT_EQ(2U, frame.render_passes.size());
5174     ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
5175     ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
5176     EXPECT_EQ(DrawQuad::SOLID_COLOR,
5177               frame.render_passes[0]->quad_list.front()->material);
5178     EXPECT_EQ(DrawQuad::RENDER_PASS,
5179               frame.render_passes[1]->quad_list.front()->material);
5180
5181     my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
5182     my_host_impl->DidDrawAllLayers(frame);
5183   }
5184 }
5185
5186 TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) {
5187   scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
5188       new TestSharedBitmapManager());
5189   scoped_ptr<LayerTreeHostImpl> my_host_impl =
5190       SetupLayersForOpacity(false,
5191                             this,
5192                             &proxy_,
5193                             shared_bitmap_manager.get(),
5194                             &stats_instrumentation_);
5195   {
5196     LayerTreeHostImpl::FrameData frame;
5197     EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame));
5198
5199     // Verify all quads have been computed
5200     ASSERT_EQ(2U, frame.render_passes.size());
5201     ASSERT_EQ(1U, frame.render_passes[0]->quad_list.size());
5202     ASSERT_EQ(1U, frame.render_passes[1]->quad_list.size());
5203     EXPECT_EQ(DrawQuad::SOLID_COLOR,
5204               frame.render_passes[0]->quad_list.front()->material);
5205     EXPECT_EQ(DrawQuad::RENDER_PASS,
5206               frame.render_passes[1]->quad_list.front()->material);
5207
5208     my_host_impl->DrawLayers(&frame, gfx::FrameTime::Now());
5209     my_host_impl->DidDrawAllLayers(frame);
5210   }
5211 }
5212
5213 TEST_F(LayerTreeHostImplTest, LayersFreeTextures) {
5214   scoped_ptr<TestWebGraphicsContext3D> context =
5215       TestWebGraphicsContext3D::Create();
5216   TestWebGraphicsContext3D* context3d = context.get();
5217   scoped_ptr<OutputSurface> output_surface(
5218       FakeOutputSurface::Create3d(context.Pass()));
5219   CreateHostImpl(DefaultSettings(), output_surface.Pass());
5220
5221   scoped_ptr<LayerImpl> root_layer =
5222       LayerImpl::Create(host_impl_->active_tree(), 1);
5223   root_layer->SetBounds(gfx::Size(10, 10));
5224
5225   scoped_refptr<VideoFrame> softwareFrame =
5226       media::VideoFrame::CreateColorFrame(
5227           gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta());
5228   FakeVideoFrameProvider provider;
5229   provider.set_frame(softwareFrame);
5230   scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
5231       host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0);
5232   video_layer->SetBounds(gfx::Size(10, 10));
5233   video_layer->SetContentBounds(gfx::Size(10, 10));
5234   video_layer->SetDrawsContent(true);
5235   root_layer->AddChild(video_layer.Pass());
5236
5237   scoped_ptr<IOSurfaceLayerImpl> io_surface_layer =
5238       IOSurfaceLayerImpl::Create(host_impl_->active_tree(), 5);
5239   io_surface_layer->SetBounds(gfx::Size(10, 10));
5240   io_surface_layer->SetContentBounds(gfx::Size(10, 10));
5241   io_surface_layer->SetDrawsContent(true);
5242   io_surface_layer->SetIOSurfaceProperties(1, gfx::Size(10, 10));
5243   root_layer->AddChild(io_surface_layer.Pass());
5244
5245   host_impl_->active_tree()->SetRootLayer(root_layer.Pass());
5246
5247   EXPECT_EQ(0u, context3d->NumTextures());
5248
5249   LayerTreeHostImpl::FrameData frame;
5250   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5251   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5252   host_impl_->DidDrawAllLayers(frame);
5253   host_impl_->SwapBuffers(frame);
5254
5255   EXPECT_GT(context3d->NumTextures(), 0u);
5256
5257   // Kill the layer tree.
5258   host_impl_->active_tree()->SetRootLayer(
5259       LayerImpl::Create(host_impl_->active_tree(), 100));
5260   // There should be no textures left in use after.
5261   EXPECT_EQ(0u, context3d->NumTextures());
5262 }
5263
5264 class MockDrawQuadsToFillScreenContext : public TestWebGraphicsContext3D {
5265  public:
5266   MOCK_METHOD1(useProgram, void(GLuint program));
5267   MOCK_METHOD4(drawElements, void(GLenum mode,
5268                                   GLsizei count,
5269                                   GLenum type,
5270                                   GLintptr offset));
5271 };
5272
5273 TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
5274   scoped_ptr<MockDrawQuadsToFillScreenContext> mock_context_owned(
5275       new MockDrawQuadsToFillScreenContext);
5276   MockDrawQuadsToFillScreenContext* mock_context = mock_context_owned.get();
5277
5278   // Run test case
5279   LayerTreeSettings settings = DefaultSettings();
5280   settings.partial_swap_enabled = false;
5281   CreateHostImpl(settings,
5282                  FakeOutputSurface::Create3d(mock_context_owned.Pass()));
5283   SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
5284   host_impl_->active_tree()->set_background_color(SK_ColorWHITE);
5285
5286   // Verify one quad is drawn when transparent background set is not set.
5287   host_impl_->active_tree()->set_has_transparent_background(false);
5288   EXPECT_CALL(*mock_context, useProgram(_))
5289       .Times(1);
5290   EXPECT_CALL(*mock_context, drawElements(_, _, _, _))
5291       .Times(1);
5292   LayerTreeHostImpl::FrameData frame;
5293   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5294   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5295   host_impl_->DidDrawAllLayers(frame);
5296   Mock::VerifyAndClearExpectations(&mock_context);
5297
5298   // Verify no quads are drawn when transparent background is set.
5299   host_impl_->active_tree()->set_has_transparent_background(true);
5300   host_impl_->SetFullRootLayerDamage();
5301   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5302   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5303   host_impl_->DidDrawAllLayers(frame);
5304   Mock::VerifyAndClearExpectations(&mock_context);
5305 }
5306
5307 TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
5308   set_reduce_memory_result(false);
5309
5310   // If changing the memory limit wouldn't result in changing what was
5311   // committed, then no commit should be requested.
5312   set_reduce_memory_result(false);
5313   host_impl_->set_max_memory_needed_bytes(
5314       host_impl_->memory_allocation_limit_bytes() - 1);
5315   host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
5316       host_impl_->memory_allocation_limit_bytes() - 1));
5317   EXPECT_FALSE(did_request_commit_);
5318   did_request_commit_ = false;
5319
5320   // If changing the memory limit would result in changing what was
5321   // committed, then a commit should be requested, even though nothing was
5322   // evicted.
5323   set_reduce_memory_result(false);
5324   host_impl_->set_max_memory_needed_bytes(
5325       host_impl_->memory_allocation_limit_bytes());
5326   host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
5327       host_impl_->memory_allocation_limit_bytes() - 1));
5328   EXPECT_TRUE(did_request_commit_);
5329   did_request_commit_ = false;
5330
5331   // Especially if changing the memory limit caused evictions, we need
5332   // to re-commit.
5333   set_reduce_memory_result(true);
5334   host_impl_->set_max_memory_needed_bytes(1);
5335   host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
5336       host_impl_->memory_allocation_limit_bytes() - 1));
5337   EXPECT_TRUE(did_request_commit_);
5338   did_request_commit_ = false;
5339
5340   // But if we set it to the same value that it was before, we shouldn't
5341   // re-commit.
5342   host_impl_->SetMemoryPolicy(ManagedMemoryPolicy(
5343       host_impl_->memory_allocation_limit_bytes()));
5344   EXPECT_FALSE(did_request_commit_);
5345 }
5346
5347 class LayerTreeHostImplTestWithDelegatingRenderer
5348     : public LayerTreeHostImplTest {
5349  protected:
5350   scoped_ptr<OutputSurface> CreateOutputSurface() override {
5351     return FakeOutputSurface::CreateDelegating3d();
5352   }
5353
5354   void DrawFrameAndTestDamage(const gfx::RectF& expected_damage) {
5355     bool expect_to_draw = !expected_damage.IsEmpty();
5356
5357     LayerTreeHostImpl::FrameData frame;
5358     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5359
5360     if (!expect_to_draw) {
5361       // With no damage, we don't draw, and no quads are created.
5362       ASSERT_EQ(0u, frame.render_passes.size());
5363     } else {
5364       ASSERT_EQ(1u, frame.render_passes.size());
5365
5366       // Verify the damage rect for the root render pass.
5367       const RenderPass* root_render_pass = frame.render_passes.back();
5368       EXPECT_RECT_EQ(expected_damage, root_render_pass->damage_rect);
5369
5370       // Verify the root and child layers' quads are generated and not being
5371       // culled.
5372       ASSERT_EQ(2u, root_render_pass->quad_list.size());
5373
5374       LayerImpl* child = host_impl_->active_tree()->root_layer()->children()[0];
5375       gfx::RectF expected_child_visible_rect(child->content_bounds());
5376       EXPECT_RECT_EQ(expected_child_visible_rect,
5377                      root_render_pass->quad_list.front()->visible_rect);
5378
5379       LayerImpl* root = host_impl_->active_tree()->root_layer();
5380       gfx::RectF expected_root_visible_rect(root->content_bounds());
5381       EXPECT_RECT_EQ(expected_root_visible_rect,
5382                      root_render_pass->quad_list.ElementAt(1)->visible_rect);
5383     }
5384
5385     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5386     host_impl_->DidDrawAllLayers(frame);
5387     EXPECT_EQ(expect_to_draw, host_impl_->SwapBuffers(frame));
5388   }
5389 };
5390
5391 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, FrameIncludesDamageRect) {
5392   scoped_ptr<SolidColorLayerImpl> root =
5393       SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
5394   root->SetPosition(gfx::PointF());
5395   root->SetBounds(gfx::Size(10, 10));
5396   root->SetContentBounds(gfx::Size(10, 10));
5397   root->SetDrawsContent(true);
5398
5399   // Child layer is in the bottom right corner.
5400   scoped_ptr<SolidColorLayerImpl> child =
5401       SolidColorLayerImpl::Create(host_impl_->active_tree(), 2);
5402   child->SetPosition(gfx::PointF(9.f, 9.f));
5403   child->SetBounds(gfx::Size(1, 1));
5404   child->SetContentBounds(gfx::Size(1, 1));
5405   child->SetDrawsContent(true);
5406   root->AddChild(child.Pass());
5407
5408   host_impl_->active_tree()->SetRootLayer(root.Pass());
5409
5410   // Draw a frame. In the first frame, the entire viewport should be damaged.
5411   gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
5412   DrawFrameAndTestDamage(full_frame_damage);
5413
5414   // The second frame has damage that doesn't touch the child layer. Its quads
5415   // should still be generated.
5416   gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
5417   host_impl_->active_tree()->root_layer()->SetUpdateRect(small_damage);
5418   DrawFrameAndTestDamage(small_damage);
5419
5420   // The third frame should have no damage, so no quads should be generated.
5421   gfx::Rect no_damage;
5422   DrawFrameAndTestDamage(no_damage);
5423 }
5424
5425 // TODO(reveman): Remove this test and the ability to prevent on demand raster
5426 // when delegating renderer supports PictureDrawQuads. crbug.com/342121
5427 TEST_F(LayerTreeHostImplTestWithDelegatingRenderer, PreventRasterizeOnDemand) {
5428   LayerTreeSettings settings;
5429   CreateHostImpl(settings, CreateOutputSurface());
5430   EXPECT_FALSE(host_impl_->GetRendererCapabilities().allow_rasterize_on_demand);
5431 }
5432
5433 class FakeMaskLayerImpl : public LayerImpl {
5434  public:
5435   static scoped_ptr<FakeMaskLayerImpl> Create(LayerTreeImpl* tree_impl,
5436                                               int id) {
5437     return make_scoped_ptr(new FakeMaskLayerImpl(tree_impl, id));
5438   }
5439
5440   void GetContentsResourceId(ResourceProvider::ResourceId* resource_id,
5441                              gfx::Size* resource_size) const override {
5442     *resource_id = 0;
5443   }
5444
5445  private:
5446   FakeMaskLayerImpl(LayerTreeImpl* tree_impl, int id)
5447       : LayerImpl(tree_impl, id) {}
5448 };
5449
5450 TEST_F(LayerTreeHostImplTest, MaskLayerWithScaling) {
5451   LayerTreeSettings settings;
5452   settings.layer_transforms_should_scale_layer_contents = true;
5453   CreateHostImpl(settings, CreateOutputSurface());
5454
5455   // Root
5456   //  |
5457   //  +-- Scaling Layer (adds a 2x scale)
5458   //       |
5459   //       +-- Content Layer
5460   //             +--Mask
5461   scoped_ptr<LayerImpl> scoped_root =
5462       LayerImpl::Create(host_impl_->active_tree(), 1);
5463   LayerImpl* root = scoped_root.get();
5464   host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5465
5466   scoped_ptr<LayerImpl> scoped_scaling_layer =
5467       LayerImpl::Create(host_impl_->active_tree(), 2);
5468   LayerImpl* scaling_layer = scoped_scaling_layer.get();
5469   root->AddChild(scoped_scaling_layer.Pass());
5470
5471   scoped_ptr<LayerImpl> scoped_content_layer =
5472       LayerImpl::Create(host_impl_->active_tree(), 3);
5473   LayerImpl* content_layer = scoped_content_layer.get();
5474   scaling_layer->AddChild(scoped_content_layer.Pass());
5475
5476   scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5477       FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5478   FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5479   content_layer->SetMaskLayer(scoped_mask_layer.Pass());
5480
5481   gfx::Size root_size(100, 100);
5482   root->SetBounds(root_size);
5483   root->SetContentBounds(root_size);
5484   root->SetPosition(gfx::PointF());
5485
5486   gfx::Size scaling_layer_size(50, 50);
5487   scaling_layer->SetBounds(scaling_layer_size);
5488   scaling_layer->SetContentBounds(scaling_layer_size);
5489   scaling_layer->SetPosition(gfx::PointF());
5490   gfx::Transform scale;
5491   scale.Scale(2.f, 2.f);
5492   scaling_layer->SetTransform(scale);
5493
5494   content_layer->SetBounds(scaling_layer_size);
5495   content_layer->SetContentBounds(scaling_layer_size);
5496   content_layer->SetPosition(gfx::PointF());
5497   content_layer->SetDrawsContent(true);
5498
5499   mask_layer->SetBounds(scaling_layer_size);
5500   mask_layer->SetContentBounds(scaling_layer_size);
5501   mask_layer->SetPosition(gfx::PointF());
5502   mask_layer->SetDrawsContent(true);
5503
5504
5505   // Check that the tree scaling is correctly taken into account for the mask,
5506   // that should fully map onto the quad.
5507   float device_scale_factor = 1.f;
5508   host_impl_->SetViewportSize(root_size);
5509   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5510   {
5511     LayerTreeHostImpl::FrameData frame;
5512     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5513
5514     ASSERT_EQ(1u, frame.render_passes.size());
5515     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5516     ASSERT_EQ(DrawQuad::RENDER_PASS,
5517               frame.render_passes[0]->quad_list.front()->material);
5518     const RenderPassDrawQuad* render_pass_quad =
5519         RenderPassDrawQuad::MaterialCast(
5520             frame.render_passes[0]->quad_list.front());
5521     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5522               render_pass_quad->rect.ToString());
5523     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5524               render_pass_quad->MaskUVRect().ToString());
5525     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5526               render_pass_quad->mask_uv_scale.ToString());
5527
5528     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5529     host_impl_->DidDrawAllLayers(frame);
5530   }
5531
5532
5533   // Applying a DSF should change the render surface size, but won't affect
5534   // which part of the mask is used.
5535   device_scale_factor = 2.f;
5536   gfx::Size device_viewport =
5537       gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
5538   host_impl_->SetViewportSize(device_viewport);
5539   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5540   host_impl_->active_tree()->set_needs_update_draw_properties();
5541   {
5542     LayerTreeHostImpl::FrameData frame;
5543     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5544
5545     ASSERT_EQ(1u, frame.render_passes.size());
5546     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5547     ASSERT_EQ(DrawQuad::RENDER_PASS,
5548               frame.render_passes[0]->quad_list.front()->material);
5549     const RenderPassDrawQuad* render_pass_quad =
5550         RenderPassDrawQuad::MaterialCast(
5551             frame.render_passes[0]->quad_list.front());
5552     EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5553               render_pass_quad->rect.ToString());
5554     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5555               render_pass_quad->MaskUVRect().ToString());
5556     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5557               render_pass_quad->mask_uv_scale.ToString());
5558
5559     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5560     host_impl_->DidDrawAllLayers(frame);
5561   }
5562
5563
5564   // Applying an equivalent content scale on the content layer and the mask
5565   // should still result in the same part of the mask being used.
5566   gfx::Size content_bounds =
5567       gfx::ToRoundedSize(gfx::ScaleSize(scaling_layer_size,
5568                                         device_scale_factor));
5569   content_layer->SetContentBounds(content_bounds);
5570   content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5571   mask_layer->SetContentBounds(content_bounds);
5572   mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5573   host_impl_->active_tree()->set_needs_update_draw_properties();
5574   {
5575     LayerTreeHostImpl::FrameData frame;
5576     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5577
5578     ASSERT_EQ(1u, frame.render_passes.size());
5579     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5580     ASSERT_EQ(DrawQuad::RENDER_PASS,
5581               frame.render_passes[0]->quad_list.front()->material);
5582     const RenderPassDrawQuad* render_pass_quad =
5583         RenderPassDrawQuad::MaterialCast(
5584             frame.render_passes[0]->quad_list.front());
5585     EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(),
5586               render_pass_quad->rect.ToString());
5587     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5588               render_pass_quad->MaskUVRect().ToString());
5589     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5590               render_pass_quad->mask_uv_scale.ToString());
5591
5592     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5593     host_impl_->DidDrawAllLayers(frame);
5594   }
5595 }
5596
5597 TEST_F(LayerTreeHostImplTest, MaskLayerWithDifferentBounds) {
5598   // The mask layer has bounds 100x100 but is attached to a layer with bounds
5599   // 50x50.
5600
5601   scoped_ptr<LayerImpl> scoped_root =
5602       LayerImpl::Create(host_impl_->active_tree(), 1);
5603   LayerImpl* root = scoped_root.get();
5604   host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5605
5606   scoped_ptr<LayerImpl> scoped_content_layer =
5607       LayerImpl::Create(host_impl_->active_tree(), 3);
5608   LayerImpl* content_layer = scoped_content_layer.get();
5609   root->AddChild(scoped_content_layer.Pass());
5610
5611   scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5612       FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5613   FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5614   content_layer->SetMaskLayer(scoped_mask_layer.Pass());
5615
5616   gfx::Size root_size(100, 100);
5617   root->SetBounds(root_size);
5618   root->SetContentBounds(root_size);
5619   root->SetPosition(gfx::PointF());
5620
5621   gfx::Size layer_size(50, 50);
5622   content_layer->SetBounds(layer_size);
5623   content_layer->SetContentBounds(layer_size);
5624   content_layer->SetPosition(gfx::PointF());
5625   content_layer->SetDrawsContent(true);
5626
5627   gfx::Size mask_size(100, 100);
5628   mask_layer->SetBounds(mask_size);
5629   mask_layer->SetContentBounds(mask_size);
5630   mask_layer->SetPosition(gfx::PointF());
5631   mask_layer->SetDrawsContent(true);
5632
5633   // Check that the mask fills the surface.
5634   float device_scale_factor = 1.f;
5635   host_impl_->SetViewportSize(root_size);
5636   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5637   {
5638     LayerTreeHostImpl::FrameData frame;
5639     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5640
5641     ASSERT_EQ(1u, frame.render_passes.size());
5642     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5643     ASSERT_EQ(DrawQuad::RENDER_PASS,
5644               frame.render_passes[0]->quad_list.front()->material);
5645     const RenderPassDrawQuad* render_pass_quad =
5646         RenderPassDrawQuad::MaterialCast(
5647             frame.render_passes[0]->quad_list.front());
5648     EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5649               render_pass_quad->rect.ToString());
5650     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5651               render_pass_quad->MaskUVRect().ToString());
5652     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5653               render_pass_quad->mask_uv_scale.ToString());
5654
5655     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5656     host_impl_->DidDrawAllLayers(frame);
5657   }
5658
5659   // Applying a DSF should change the render surface size, but won't affect
5660   // which part of the mask is used.
5661   device_scale_factor = 2.f;
5662   gfx::Size device_viewport =
5663       gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
5664   host_impl_->SetViewportSize(device_viewport);
5665   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5666   host_impl_->active_tree()->set_needs_update_draw_properties();
5667   {
5668     LayerTreeHostImpl::FrameData frame;
5669     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5670
5671     ASSERT_EQ(1u, frame.render_passes.size());
5672     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5673     ASSERT_EQ(DrawQuad::RENDER_PASS,
5674               frame.render_passes[0]->quad_list.front()->material);
5675     const RenderPassDrawQuad* render_pass_quad =
5676         RenderPassDrawQuad::MaterialCast(
5677             frame.render_passes[0]->quad_list.front());
5678     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5679               render_pass_quad->rect.ToString());
5680     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5681               render_pass_quad->MaskUVRect().ToString());
5682     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5683               render_pass_quad->mask_uv_scale.ToString());
5684
5685     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5686     host_impl_->DidDrawAllLayers(frame);
5687   }
5688
5689   // Applying an equivalent content scale on the content layer and the mask
5690   // should still result in the same part of the mask being used.
5691   gfx::Size layer_size_large =
5692       gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
5693   content_layer->SetContentBounds(layer_size_large);
5694   content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5695   gfx::Size mask_size_large =
5696       gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
5697   mask_layer->SetContentBounds(mask_size_large);
5698   mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5699   host_impl_->active_tree()->set_needs_update_draw_properties();
5700   {
5701     LayerTreeHostImpl::FrameData frame;
5702     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5703
5704     ASSERT_EQ(1u, frame.render_passes.size());
5705     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5706     ASSERT_EQ(DrawQuad::RENDER_PASS,
5707               frame.render_passes[0]->quad_list.front()->material);
5708     const RenderPassDrawQuad* render_pass_quad =
5709         RenderPassDrawQuad::MaterialCast(
5710             frame.render_passes[0]->quad_list.front());
5711     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5712               render_pass_quad->rect.ToString());
5713     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5714               render_pass_quad->MaskUVRect().ToString());
5715     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5716               render_pass_quad->mask_uv_scale.ToString());
5717
5718     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5719     host_impl_->DidDrawAllLayers(frame);
5720   }
5721
5722   // Applying a different contents scale to the mask layer means it will have
5723   // a larger texture, but it should use the same tex coords to cover the
5724   // layer it masks.
5725   mask_layer->SetContentBounds(mask_size);
5726   mask_layer->SetContentsScale(1.f, 1.f);
5727   host_impl_->active_tree()->set_needs_update_draw_properties();
5728   {
5729     LayerTreeHostImpl::FrameData frame;
5730     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5731
5732     ASSERT_EQ(1u, frame.render_passes.size());
5733     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
5734     ASSERT_EQ(DrawQuad::RENDER_PASS,
5735               frame.render_passes[0]->quad_list.front()->material);
5736     const RenderPassDrawQuad* render_pass_quad =
5737         RenderPassDrawQuad::MaterialCast(
5738             frame.render_passes[0]->quad_list.front());
5739     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5740               render_pass_quad->rect.ToString());
5741     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5742               render_pass_quad->MaskUVRect().ToString());
5743     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5744               render_pass_quad->mask_uv_scale.ToString());
5745
5746     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5747     host_impl_->DidDrawAllLayers(frame);
5748   }
5749 }
5750
5751 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerWithDifferentBounds) {
5752   // The replica's mask layer has bounds 100x100 but the replica is of a
5753   // layer with bounds 50x50.
5754
5755   scoped_ptr<LayerImpl> scoped_root =
5756       LayerImpl::Create(host_impl_->active_tree(), 1);
5757   LayerImpl* root = scoped_root.get();
5758   host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5759
5760   scoped_ptr<LayerImpl> scoped_content_layer =
5761       LayerImpl::Create(host_impl_->active_tree(), 3);
5762   LayerImpl* content_layer = scoped_content_layer.get();
5763   root->AddChild(scoped_content_layer.Pass());
5764
5765   scoped_ptr<LayerImpl> scoped_replica_layer =
5766       LayerImpl::Create(host_impl_->active_tree(), 2);
5767   LayerImpl* replica_layer = scoped_replica_layer.get();
5768   content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
5769
5770   scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5771       FakeMaskLayerImpl::Create(host_impl_->active_tree(), 4);
5772   FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5773   replica_layer->SetMaskLayer(scoped_mask_layer.Pass());
5774
5775   gfx::Size root_size(100, 100);
5776   root->SetBounds(root_size);
5777   root->SetContentBounds(root_size);
5778   root->SetPosition(gfx::PointF());
5779
5780   gfx::Size layer_size(50, 50);
5781   content_layer->SetBounds(layer_size);
5782   content_layer->SetContentBounds(layer_size);
5783   content_layer->SetPosition(gfx::PointF());
5784   content_layer->SetDrawsContent(true);
5785
5786   gfx::Size mask_size(100, 100);
5787   mask_layer->SetBounds(mask_size);
5788   mask_layer->SetContentBounds(mask_size);
5789   mask_layer->SetPosition(gfx::PointF());
5790   mask_layer->SetDrawsContent(true);
5791
5792   // Check that the mask fills the surface.
5793   float device_scale_factor = 1.f;
5794   host_impl_->SetViewportSize(root_size);
5795   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5796   {
5797     LayerTreeHostImpl::FrameData frame;
5798     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5799
5800     ASSERT_EQ(1u, frame.render_passes.size());
5801     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5802     ASSERT_EQ(DrawQuad::RENDER_PASS,
5803               frame.render_passes[0]->quad_list.ElementAt(1)->material);
5804     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
5805         frame.render_passes[0]->quad_list.ElementAt(1));
5806     EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
5807               replica_quad->rect.ToString());
5808     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5809               replica_quad->MaskUVRect().ToString());
5810     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5811               replica_quad->mask_uv_scale.ToString());
5812
5813     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5814     host_impl_->DidDrawAllLayers(frame);
5815   }
5816
5817   // Applying a DSF should change the render surface size, but won't affect
5818   // which part of the mask is used.
5819   device_scale_factor = 2.f;
5820   gfx::Size device_viewport =
5821       gfx::ToFlooredSize(gfx::ScaleSize(root_size, device_scale_factor));
5822   host_impl_->SetViewportSize(device_viewport);
5823   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5824   host_impl_->active_tree()->set_needs_update_draw_properties();
5825   {
5826     LayerTreeHostImpl::FrameData frame;
5827     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5828
5829     ASSERT_EQ(1u, frame.render_passes.size());
5830     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5831     ASSERT_EQ(DrawQuad::RENDER_PASS,
5832               frame.render_passes[0]->quad_list.ElementAt(1)->material);
5833     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
5834         frame.render_passes[0]->quad_list.ElementAt(1));
5835     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5836               replica_quad->rect.ToString());
5837     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5838               replica_quad->MaskUVRect().ToString());
5839     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5840               replica_quad->mask_uv_scale.ToString());
5841
5842     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5843     host_impl_->DidDrawAllLayers(frame);
5844   }
5845
5846   // Applying an equivalent content scale on the content layer and the mask
5847   // should still result in the same part of the mask being used.
5848   gfx::Size layer_size_large =
5849       gfx::ToRoundedSize(gfx::ScaleSize(layer_size, device_scale_factor));
5850   content_layer->SetContentBounds(layer_size_large);
5851   content_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5852   gfx::Size mask_size_large =
5853       gfx::ToRoundedSize(gfx::ScaleSize(mask_size, device_scale_factor));
5854   mask_layer->SetContentBounds(mask_size_large);
5855   mask_layer->SetContentsScale(device_scale_factor, device_scale_factor);
5856   host_impl_->active_tree()->set_needs_update_draw_properties();
5857   {
5858     LayerTreeHostImpl::FrameData frame;
5859     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5860
5861     ASSERT_EQ(1u, frame.render_passes.size());
5862     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5863     ASSERT_EQ(DrawQuad::RENDER_PASS,
5864               frame.render_passes[0]->quad_list.ElementAt(1)->material);
5865     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
5866         frame.render_passes[0]->quad_list.ElementAt(1));
5867     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5868               replica_quad->rect.ToString());
5869     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5870               replica_quad->MaskUVRect().ToString());
5871     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5872               replica_quad->mask_uv_scale.ToString());
5873
5874     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5875     host_impl_->DidDrawAllLayers(frame);
5876   }
5877
5878   // Applying a different contents scale to the mask layer means it will have
5879   // a larger texture, but it should use the same tex coords to cover the
5880   // layer it masks.
5881   mask_layer->SetContentBounds(mask_size);
5882   mask_layer->SetContentsScale(1.f, 1.f);
5883   host_impl_->active_tree()->set_needs_update_draw_properties();
5884   {
5885     LayerTreeHostImpl::FrameData frame;
5886     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5887
5888     ASSERT_EQ(1u, frame.render_passes.size());
5889     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5890     ASSERT_EQ(DrawQuad::RENDER_PASS,
5891               frame.render_passes[0]->quad_list.ElementAt(1)->material);
5892     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
5893         frame.render_passes[0]->quad_list.ElementAt(1));
5894     EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
5895               replica_quad->rect.ToString());
5896     EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(),
5897               replica_quad->MaskUVRect().ToString());
5898     EXPECT_EQ(gfx::Vector2dF(1.f, 1.f).ToString(),
5899               replica_quad->mask_uv_scale.ToString());
5900
5901     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5902     host_impl_->DidDrawAllLayers(frame);
5903   }
5904 }
5905
5906 TEST_F(LayerTreeHostImplTest, ReflectionMaskLayerForSurfaceWithUnclippedChild) {
5907   // The replica is of a layer with bounds 50x50, but it has a child that causes
5908   // the surface bounds to be larger.
5909
5910   scoped_ptr<LayerImpl> scoped_root =
5911       LayerImpl::Create(host_impl_->active_tree(), 1);
5912   LayerImpl* root = scoped_root.get();
5913   host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
5914
5915   scoped_ptr<LayerImpl> scoped_content_layer =
5916       LayerImpl::Create(host_impl_->active_tree(), 2);
5917   LayerImpl* content_layer = scoped_content_layer.get();
5918   root->AddChild(scoped_content_layer.Pass());
5919
5920   scoped_ptr<LayerImpl> scoped_content_child_layer =
5921       LayerImpl::Create(host_impl_->active_tree(), 3);
5922   LayerImpl* content_child_layer = scoped_content_child_layer.get();
5923   content_layer->AddChild(scoped_content_child_layer.Pass());
5924
5925   scoped_ptr<LayerImpl> scoped_replica_layer =
5926       LayerImpl::Create(host_impl_->active_tree(), 4);
5927   LayerImpl* replica_layer = scoped_replica_layer.get();
5928   content_layer->SetReplicaLayer(scoped_replica_layer.Pass());
5929
5930   scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
5931       FakeMaskLayerImpl::Create(host_impl_->active_tree(), 5);
5932   FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
5933   replica_layer->SetMaskLayer(scoped_mask_layer.Pass());
5934
5935   gfx::Size root_size(100, 100);
5936   root->SetBounds(root_size);
5937   root->SetContentBounds(root_size);
5938   root->SetPosition(gfx::PointF());
5939
5940   gfx::Size layer_size(50, 50);
5941   content_layer->SetBounds(layer_size);
5942   content_layer->SetContentBounds(layer_size);
5943   content_layer->SetPosition(gfx::PointF());
5944   content_layer->SetDrawsContent(true);
5945
5946   gfx::Size child_size(50, 50);
5947   content_child_layer->SetBounds(child_size);
5948   content_child_layer->SetContentBounds(child_size);
5949   content_child_layer->SetPosition(gfx::Point(50, 0));
5950   content_child_layer->SetDrawsContent(true);
5951
5952   gfx::Size mask_size(50, 50);
5953   mask_layer->SetBounds(mask_size);
5954   mask_layer->SetContentBounds(mask_size);
5955   mask_layer->SetPosition(gfx::PointF());
5956   mask_layer->SetDrawsContent(true);
5957
5958   float device_scale_factor = 1.f;
5959   host_impl_->SetViewportSize(root_size);
5960   host_impl_->SetDeviceScaleFactor(device_scale_factor);
5961   {
5962     LayerTreeHostImpl::FrameData frame;
5963     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5964
5965     ASSERT_EQ(1u, frame.render_passes.size());
5966     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
5967
5968     // The surface is 100x50.
5969     ASSERT_EQ(DrawQuad::RENDER_PASS,
5970               frame.render_passes[0]->quad_list.front()->material);
5971     const RenderPassDrawQuad* render_pass_quad =
5972         RenderPassDrawQuad::MaterialCast(
5973             frame.render_passes[0]->quad_list.front());
5974     EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5975               render_pass_quad->rect.ToString());
5976
5977     // The mask covers the owning layer only.
5978     ASSERT_EQ(DrawQuad::RENDER_PASS,
5979               frame.render_passes[0]->quad_list.ElementAt(1)->material);
5980     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
5981         frame.render_passes[0]->quad_list.ElementAt(1));
5982     EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(),
5983               replica_quad->rect.ToString());
5984     EXPECT_EQ(gfx::RectF(0.f, 0.f, 2.f, 1.f).ToString(),
5985               replica_quad->MaskUVRect().ToString());
5986     EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
5987               replica_quad->mask_uv_scale.ToString());
5988
5989     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
5990     host_impl_->DidDrawAllLayers(frame);
5991   }
5992
5993   // Move the child to (-50, 0) instead. Now the mask should be moved to still
5994   // cover the layer being replicated.
5995   content_child_layer->SetPosition(gfx::Point(-50, 0));
5996   {
5997     LayerTreeHostImpl::FrameData frame;
5998     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
5999
6000     ASSERT_EQ(1u, frame.render_passes.size());
6001     ASSERT_EQ(2u, frame.render_passes[0]->quad_list.size());
6002
6003     // The surface is 100x50 with its origin at (-50, 0).
6004     ASSERT_EQ(DrawQuad::RENDER_PASS,
6005               frame.render_passes[0]->quad_list.front()->material);
6006     const RenderPassDrawQuad* render_pass_quad =
6007         RenderPassDrawQuad::MaterialCast(
6008             frame.render_passes[0]->quad_list.front());
6009     EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6010               render_pass_quad->rect.ToString());
6011
6012     // The mask covers the owning layer only.
6013     ASSERT_EQ(DrawQuad::RENDER_PASS,
6014               frame.render_passes[0]->quad_list.ElementAt(1)->material);
6015     const RenderPassDrawQuad* replica_quad = RenderPassDrawQuad::MaterialCast(
6016         frame.render_passes[0]->quad_list.ElementAt(1));
6017     EXPECT_EQ(gfx::Rect(-50, 0, 100, 50).ToString(),
6018               replica_quad->rect.ToString());
6019     EXPECT_EQ(gfx::RectF(-1.f, 0.f, 2.f, 1.f).ToString(),
6020               replica_quad->MaskUVRect().ToString());
6021     EXPECT_EQ(gfx::Vector2dF(2.f, 1.f).ToString(),
6022               replica_quad->mask_uv_scale.ToString());
6023
6024     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6025     host_impl_->DidDrawAllLayers(frame);
6026   }
6027 }
6028
6029 TEST_F(LayerTreeHostImplTest, MaskLayerForSurfaceWithClippedLayer) {
6030   // The masked layer has bounds 50x50, but it has a child that causes
6031   // the surface bounds to be larger. It also has a parent that clips the
6032   // masked layer and its surface.
6033
6034   scoped_ptr<LayerImpl> scoped_root =
6035       LayerImpl::Create(host_impl_->active_tree(), 1);
6036   LayerImpl* root = scoped_root.get();
6037   host_impl_->active_tree()->SetRootLayer(scoped_root.Pass());
6038
6039   scoped_ptr<LayerImpl> scoped_clipping_layer =
6040       LayerImpl::Create(host_impl_->active_tree(), 2);
6041   LayerImpl* clipping_layer = scoped_clipping_layer.get();
6042   root->AddChild(scoped_clipping_layer.Pass());
6043
6044   scoped_ptr<LayerImpl> scoped_content_layer =
6045       LayerImpl::Create(host_impl_->active_tree(), 3);
6046   LayerImpl* content_layer = scoped_content_layer.get();
6047   clipping_layer->AddChild(scoped_content_layer.Pass());
6048
6049   scoped_ptr<LayerImpl> scoped_content_child_layer =
6050       LayerImpl::Create(host_impl_->active_tree(), 4);
6051   LayerImpl* content_child_layer = scoped_content_child_layer.get();
6052   content_layer->AddChild(scoped_content_child_layer.Pass());
6053
6054   scoped_ptr<FakeMaskLayerImpl> scoped_mask_layer =
6055       FakeMaskLayerImpl::Create(host_impl_->active_tree(), 6);
6056   FakeMaskLayerImpl* mask_layer = scoped_mask_layer.get();
6057   content_layer->SetMaskLayer(scoped_mask_layer.Pass());
6058
6059   gfx::Size root_size(100, 100);
6060   root->SetBounds(root_size);
6061   root->SetContentBounds(root_size);
6062   root->SetPosition(gfx::PointF());
6063
6064   gfx::Rect clipping_rect(20, 10, 10, 20);
6065   clipping_layer->SetBounds(clipping_rect.size());
6066   clipping_layer->SetContentBounds(clipping_rect.size());
6067   clipping_layer->SetPosition(clipping_rect.origin());
6068   clipping_layer->SetMasksToBounds(true);
6069
6070   gfx::Size layer_size(50, 50);
6071   content_layer->SetBounds(layer_size);
6072   content_layer->SetContentBounds(layer_size);
6073   content_layer->SetPosition(gfx::Point() - clipping_rect.OffsetFromOrigin());
6074   content_layer->SetDrawsContent(true);
6075
6076   gfx::Size child_size(50, 50);
6077   content_child_layer->SetBounds(child_size);
6078   content_child_layer->SetContentBounds(child_size);
6079   content_child_layer->SetPosition(gfx::Point(50, 0));
6080   content_child_layer->SetDrawsContent(true);
6081
6082   gfx::Size mask_size(100, 100);
6083   mask_layer->SetBounds(mask_size);
6084   mask_layer->SetContentBounds(mask_size);
6085   mask_layer->SetPosition(gfx::PointF());
6086   mask_layer->SetDrawsContent(true);
6087
6088   float device_scale_factor = 1.f;
6089   host_impl_->SetViewportSize(root_size);
6090   host_impl_->SetDeviceScaleFactor(device_scale_factor);
6091   {
6092     LayerTreeHostImpl::FrameData frame;
6093     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6094
6095     ASSERT_EQ(1u, frame.render_passes.size());
6096     ASSERT_EQ(1u, frame.render_passes[0]->quad_list.size());
6097
6098     // The surface is clipped to 10x20.
6099     ASSERT_EQ(DrawQuad::RENDER_PASS,
6100               frame.render_passes[0]->quad_list.front()->material);
6101     const RenderPassDrawQuad* render_pass_quad =
6102         RenderPassDrawQuad::MaterialCast(
6103             frame.render_passes[0]->quad_list.front());
6104     EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(),
6105               render_pass_quad->rect.ToString());
6106     // The masked layer is 50x50, but the surface size is 10x20. So the texture
6107     // coords in the mask are scaled by 10/50 and 20/50.
6108     // The surface is clipped to (20,10) so the mask texture coords are offset
6109     // by 20/50 and 10/50
6110     EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f)
6111                   .ToString(),
6112               render_pass_quad->MaskUVRect().ToString());
6113     EXPECT_EQ(gfx::Vector2dF(10.f / 50.f, 20.f / 50.f).ToString(),
6114               render_pass_quad->mask_uv_scale.ToString());
6115
6116     host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6117     host_impl_->DidDrawAllLayers(frame);
6118   }
6119 }
6120
6121 class GLRendererWithSetupQuadForAntialiasing : public GLRenderer {
6122  public:
6123   using GLRenderer::ShouldAntialiasQuad;
6124 };
6125
6126 TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
6127   // Due to precision issues (especially on Android), sometimes far
6128   // away quads can end up thinking they need AA.
6129   float device_scale_factor = 4.f / 3.f;
6130   host_impl_->SetDeviceScaleFactor(device_scale_factor);
6131   gfx::Size root_size(2000, 1000);
6132   gfx::Size device_viewport_size =
6133       gfx::ToCeiledSize(gfx::ScaleSize(root_size, device_scale_factor));
6134   host_impl_->SetViewportSize(device_viewport_size);
6135
6136   host_impl_->CreatePendingTree();
6137   host_impl_->pending_tree()
6138       ->SetPageScaleFactorAndLimits(1.f, 1.f / 16.f, 16.f);
6139
6140   scoped_ptr<LayerImpl> scoped_root =
6141       LayerImpl::Create(host_impl_->pending_tree(), 1);
6142   LayerImpl* root = scoped_root.get();
6143
6144   host_impl_->pending_tree()->SetRootLayer(scoped_root.Pass());
6145
6146   scoped_ptr<LayerImpl> scoped_scrolling_layer =
6147       LayerImpl::Create(host_impl_->pending_tree(), 2);
6148   LayerImpl* scrolling_layer = scoped_scrolling_layer.get();
6149   root->AddChild(scoped_scrolling_layer.Pass());
6150
6151   gfx::Size content_layer_bounds(100000, 100);
6152   gfx::Size pile_tile_size(3000, 3000);
6153   scoped_refptr<FakePicturePileImpl> pile(FakePicturePileImpl::CreateFilledPile(
6154       pile_tile_size, content_layer_bounds));
6155
6156   scoped_ptr<FakePictureLayerImpl> scoped_content_layer =
6157       FakePictureLayerImpl::CreateWithPile(host_impl_->pending_tree(), 3, pile);
6158   LayerImpl* content_layer = scoped_content_layer.get();
6159   scrolling_layer->AddChild(scoped_content_layer.Pass());
6160   content_layer->SetBounds(content_layer_bounds);
6161   content_layer->SetDrawsContent(true);
6162
6163   root->SetBounds(root_size);
6164
6165   gfx::ScrollOffset scroll_offset(100000, 0);
6166   scrolling_layer->SetScrollClipLayer(root->id());
6167   scrolling_layer->SetScrollOffset(scroll_offset);
6168
6169   host_impl_->ActivateSyncTree();
6170
6171   host_impl_->active_tree()->UpdateDrawProperties();
6172   ASSERT_EQ(1u, host_impl_->active_tree()->RenderSurfaceLayerList().size());
6173
6174   LayerTreeHostImpl::FrameData frame;
6175   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6176
6177   ASSERT_EQ(1u, frame.render_passes.size());
6178   ASSERT_LE(1u, frame.render_passes[0]->quad_list.size());
6179   const DrawQuad* quad = frame.render_passes[0]->quad_list.front();
6180
6181   bool antialiased =
6182       GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad(
6183           quad->quadTransform(), quad, false);
6184   EXPECT_FALSE(antialiased);
6185
6186   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6187   host_impl_->DidDrawAllLayers(frame);
6188 }
6189
6190
6191 class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
6192  public:
6193   CompositorFrameMetadataTest()
6194       : swap_buffers_complete_(0) {}
6195
6196   void DidSwapBuffersCompleteOnImplThread() override {
6197     swap_buffers_complete_++;
6198   }
6199
6200   int swap_buffers_complete_;
6201 };
6202
6203 TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) {
6204   SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1));
6205   {
6206     LayerTreeHostImpl::FrameData frame;
6207     EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6208     host_impl_->DrawLayers(&frame, base::TimeTicks());
6209     host_impl_->DidDrawAllLayers(frame);
6210   }
6211   CompositorFrameAck ack;
6212   host_impl_->ReclaimResources(&ack);
6213   host_impl_->DidSwapBuffersComplete();
6214   EXPECT_EQ(swap_buffers_complete_, 1);
6215 }
6216
6217 class CountingSoftwareDevice : public SoftwareOutputDevice {
6218  public:
6219   CountingSoftwareDevice() : frames_began_(0), frames_ended_(0) {}
6220
6221   SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override {
6222     ++frames_began_;
6223     return SoftwareOutputDevice::BeginPaint(damage_rect);
6224   }
6225   void EndPaint(SoftwareFrameData* frame_data) override {
6226     ++frames_ended_;
6227     SoftwareOutputDevice::EndPaint(frame_data);
6228   }
6229
6230   int frames_began_, frames_ended_;
6231 };
6232
6233 TEST_F(LayerTreeHostImplTest, ForcedDrawToSoftwareDeviceBasicRender) {
6234   // No main thread evictions in resourceless software mode.
6235   set_reduce_memory_result(false);
6236   CountingSoftwareDevice* software_device = new CountingSoftwareDevice();
6237   bool delegated_rendering = false;
6238   FakeOutputSurface* output_surface =
6239       FakeOutputSurface::CreateDeferredGL(
6240           scoped_ptr<SoftwareOutputDevice>(software_device),
6241           delegated_rendering).release();
6242   EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6243                              scoped_ptr<OutputSurface>(output_surface)));
6244   host_impl_->SetViewportSize(gfx::Size(50, 50));
6245
6246   SetupScrollAndContentsLayers(gfx::Size(100, 100));
6247
6248   const gfx::Transform external_transform;
6249   const gfx::Rect external_viewport;
6250   const gfx::Rect external_clip;
6251   const bool resourceless_software_draw = true;
6252   host_impl_->SetExternalDrawConstraints(external_transform,
6253                                          external_viewport,
6254                                          external_clip,
6255                                          external_viewport,
6256                                          external_transform,
6257                                          resourceless_software_draw);
6258
6259   EXPECT_EQ(0, software_device->frames_began_);
6260   EXPECT_EQ(0, software_device->frames_ended_);
6261
6262   DrawFrame();
6263
6264   EXPECT_EQ(1, software_device->frames_began_);
6265   EXPECT_EQ(1, software_device->frames_ended_);
6266
6267   // Call other API methods that are likely to hit NULL pointer in this mode.
6268   EXPECT_TRUE(host_impl_->AsValue().get());
6269   EXPECT_TRUE(host_impl_->ActivationStateAsValue().get());
6270 }
6271
6272 TEST_F(LayerTreeHostImplTest,
6273        ForcedDrawToSoftwareDeviceSkipsUnsupportedLayers) {
6274   set_reduce_memory_result(false);
6275   bool delegated_rendering = false;
6276   FakeOutputSurface* output_surface =
6277       FakeOutputSurface::CreateDeferredGL(
6278           scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice()),
6279           delegated_rendering).release();
6280   EXPECT_TRUE(CreateHostImpl(DefaultSettings(),
6281                              scoped_ptr<OutputSurface>(output_surface)));
6282
6283   const gfx::Transform external_transform;
6284   const gfx::Rect external_viewport;
6285   const gfx::Rect external_clip;
6286   const bool resourceless_software_draw = true;
6287   host_impl_->SetExternalDrawConstraints(external_transform,
6288                                          external_viewport,
6289                                          external_clip,
6290                                          external_viewport,
6291                                          external_transform,
6292                                          resourceless_software_draw);
6293
6294   // SolidColorLayerImpl will be drawn.
6295   scoped_ptr<SolidColorLayerImpl> root_layer =
6296       SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
6297
6298   // VideoLayerImpl will not be drawn.
6299   FakeVideoFrameProvider provider;
6300   scoped_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create(
6301       host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0);
6302   video_layer->SetBounds(gfx::Size(10, 10));
6303   video_layer->SetContentBounds(gfx::Size(10, 10));
6304   video_layer->SetDrawsContent(true);
6305   root_layer->AddChild(video_layer.Pass());
6306   SetupRootLayerImpl(root_layer.Pass());
6307
6308   LayerTreeHostImpl::FrameData frame;
6309   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6310   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6311   host_impl_->DidDrawAllLayers(frame);
6312
6313   EXPECT_EQ(1u, frame.will_draw_layers.size());
6314   EXPECT_EQ(host_impl_->active_tree()->root_layer(), frame.will_draw_layers[0]);
6315 }
6316
6317 class LayerTreeHostImplTestDeferredInitialize : public LayerTreeHostImplTest {
6318  protected:
6319   virtual void SetUp() override {
6320     LayerTreeHostImplTest::SetUp();
6321
6322     set_reduce_memory_result(false);
6323
6324     bool delegated_rendering = false;
6325     scoped_ptr<FakeOutputSurface> output_surface(
6326         FakeOutputSurface::CreateDeferredGL(
6327             scoped_ptr<SoftwareOutputDevice>(new CountingSoftwareDevice()),
6328             delegated_rendering));
6329     output_surface_ = output_surface.get();
6330
6331     EXPECT_TRUE(CreateHostImpl(DefaultSettings(), output_surface.Pass()));
6332
6333     scoped_ptr<SolidColorLayerImpl> root_layer =
6334         SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
6335     SetupRootLayerImpl(root_layer.Pass());
6336
6337     onscreen_context_provider_ = TestContextProvider::Create();
6338   }
6339
6340   void UpdateRendererCapabilitiesOnImplThread() override {
6341     did_update_renderer_capabilities_ = true;
6342   }
6343
6344   FakeOutputSurface* output_surface_;
6345   scoped_refptr<TestContextProvider> onscreen_context_provider_;
6346   bool did_update_renderer_capabilities_;
6347 };
6348
6349
6350 TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) {
6351   // Software draw.
6352   DrawFrame();
6353
6354   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6355
6356   // DeferredInitialize and hardware draw.
6357   did_update_renderer_capabilities_ = false;
6358   EXPECT_TRUE(
6359       output_surface_->InitializeAndSetContext3d(onscreen_context_provider_));
6360   EXPECT_EQ(onscreen_context_provider_.get(),
6361             host_impl_->output_surface()->context_provider());
6362   EXPECT_TRUE(did_update_renderer_capabilities_);
6363
6364   // Defer intialized GL draw.
6365   DrawFrame();
6366
6367   // Revert back to software.
6368   did_update_renderer_capabilities_ = false;
6369   output_surface_->ReleaseGL();
6370   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6371   EXPECT_TRUE(did_update_renderer_capabilities_);
6372
6373   // Software draw again.
6374   DrawFrame();
6375 }
6376
6377 TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails) {
6378   // Software draw.
6379   DrawFrame();
6380
6381   // Fail initialization of the onscreen context before the OutputSurface binds
6382   // it to the thread.
6383   onscreen_context_provider_->UnboundTestContext3d()->set_context_lost(true);
6384
6385   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6386
6387   // DeferredInitialize fails.
6388   did_update_renderer_capabilities_ = false;
6389   EXPECT_FALSE(
6390       output_surface_->InitializeAndSetContext3d(onscreen_context_provider_));
6391   EXPECT_FALSE(host_impl_->output_surface()->context_provider());
6392   EXPECT_FALSE(did_update_renderer_capabilities_);
6393
6394   // Software draw again.
6395   DrawFrame();
6396 }
6397
6398 // Checks that we have a non-0 default allocation if we pass a context that
6399 // doesn't support memory management extensions.
6400 TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) {
6401   LayerTreeSettings settings;
6402   host_impl_ = LayerTreeHostImpl::Create(settings,
6403                                          this,
6404                                          &proxy_,
6405                                          &stats_instrumentation_,
6406                                          shared_bitmap_manager_.get(),
6407                                          gpu_memory_buffer_manager_.get(),
6408                                          0);
6409
6410   scoped_ptr<OutputSurface> output_surface(
6411       FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()));
6412   host_impl_->InitializeRenderer(output_surface.Pass());
6413   EXPECT_LT(0ul, host_impl_->memory_allocation_limit_bytes());
6414 }
6415
6416 TEST_F(LayerTreeHostImplTest, MemoryPolicy) {
6417   ManagedMemoryPolicy policy1(
6418       456, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 1000);
6419   int everything_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
6420       gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING);
6421   int allow_nice_to_have_cutoff_value =
6422       ManagedMemoryPolicy::PriorityCutoffToValue(
6423           gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE);
6424   int nothing_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue(
6425       gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
6426
6427   // GPU rasterization should be disabled by default on the tree(s)
6428   EXPECT_FALSE(host_impl_->active_tree()->use_gpu_rasterization());
6429   EXPECT_TRUE(host_impl_->pending_tree() == NULL);
6430
6431   host_impl_->SetVisible(true);
6432   host_impl_->SetMemoryPolicy(policy1);
6433   EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
6434   EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
6435
6436   host_impl_->SetVisible(false);
6437   EXPECT_EQ(0u, current_limit_bytes_);
6438   EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
6439
6440   host_impl_->SetVisible(true);
6441   EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
6442   EXPECT_EQ(everything_cutoff_value, current_priority_cutoff_value_);
6443
6444   // Now enable GPU rasterization and test if we get nice to have cutoff,
6445   // when visible.
6446   LayerTreeSettings settings;
6447   settings.gpu_rasterization_enabled = true;
6448   host_impl_ = LayerTreeHostImpl::Create(
6449       settings, this, &proxy_, &stats_instrumentation_, NULL, NULL, 0);
6450   host_impl_->SetUseGpuRasterization(true);
6451   host_impl_->SetVisible(true);
6452   host_impl_->SetMemoryPolicy(policy1);
6453   EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_);
6454   EXPECT_EQ(allow_nice_to_have_cutoff_value, current_priority_cutoff_value_);
6455
6456   host_impl_->SetVisible(false);
6457   EXPECT_EQ(0u, current_limit_bytes_);
6458   EXPECT_EQ(nothing_cutoff_value, current_priority_cutoff_value_);
6459 }
6460
6461 TEST_F(LayerTreeHostImplTest, RequireHighResWhenVisible) {
6462   ASSERT_TRUE(host_impl_->active_tree());
6463
6464   // RequiresHighResToDraw is set when new output surface is used.
6465   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6466
6467   host_impl_->ResetRequiresHighResToDraw();
6468
6469   host_impl_->SetVisible(false);
6470   EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
6471   host_impl_->SetVisible(true);
6472   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6473   host_impl_->SetVisible(false);
6474   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6475
6476   host_impl_->ResetRequiresHighResToDraw();
6477
6478   EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
6479   host_impl_->SetVisible(true);
6480   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6481 }
6482
6483 TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) {
6484   ASSERT_TRUE(host_impl_->active_tree());
6485   EXPECT_FALSE(host_impl_->use_gpu_rasterization());
6486
6487   // RequiresHighResToDraw is set when new output surface is used.
6488   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6489
6490   host_impl_->ResetRequiresHighResToDraw();
6491
6492   host_impl_->SetUseGpuRasterization(false);
6493   EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
6494   host_impl_->SetUseGpuRasterization(true);
6495   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6496   host_impl_->SetUseGpuRasterization(false);
6497   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6498
6499   host_impl_->ResetRequiresHighResToDraw();
6500
6501   EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
6502   host_impl_->SetUseGpuRasterization(true);
6503   EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
6504 }
6505
6506 class LayerTreeHostImplTestManageTiles : public LayerTreeHostImplTest {
6507  public:
6508   virtual void SetUp() override {
6509     LayerTreeSettings settings;
6510     settings.impl_side_painting = true;
6511
6512     fake_host_impl_ = new FakeLayerTreeHostImpl(
6513         settings, &proxy_, shared_bitmap_manager_.get());
6514     host_impl_.reset(fake_host_impl_);
6515     host_impl_->InitializeRenderer(CreateOutputSurface());
6516     host_impl_->SetViewportSize(gfx::Size(10, 10));
6517   }
6518
6519   FakeLayerTreeHostImpl* fake_host_impl_;
6520 };
6521
6522 TEST_F(LayerTreeHostImplTestManageTiles, ManageTilesWhenInvisible) {
6523   fake_host_impl_->DidModifyTilePriorities();
6524   EXPECT_TRUE(fake_host_impl_->manage_tiles_needed());
6525   fake_host_impl_->SetVisible(false);
6526   EXPECT_FALSE(fake_host_impl_->manage_tiles_needed());
6527 }
6528
6529 TEST_F(LayerTreeHostImplTest, UIResourceManagement) {
6530   scoped_ptr<TestWebGraphicsContext3D> context =
6531       TestWebGraphicsContext3D::Create();
6532   TestWebGraphicsContext3D* context3d = context.get();
6533   scoped_ptr<FakeOutputSurface> output_surface = FakeOutputSurface::Create3d();
6534   CreateHostImpl(DefaultSettings(), output_surface.Pass());
6535
6536   EXPECT_EQ(0u, context3d->NumTextures());
6537
6538   UIResourceId ui_resource_id = 1;
6539   bool is_opaque = false;
6540   UIResourceBitmap bitmap(gfx::Size(1, 1), is_opaque);
6541   host_impl_->CreateUIResource(ui_resource_id, bitmap);
6542   EXPECT_EQ(1u, context3d->NumTextures());
6543   ResourceProvider::ResourceId id1 =
6544       host_impl_->ResourceIdForUIResource(ui_resource_id);
6545   EXPECT_NE(0u, id1);
6546
6547   // Multiple requests with the same id is allowed.  The previous texture is
6548   // deleted.
6549   host_impl_->CreateUIResource(ui_resource_id, bitmap);
6550   EXPECT_EQ(1u, context3d->NumTextures());
6551   ResourceProvider::ResourceId id2 =
6552       host_impl_->ResourceIdForUIResource(ui_resource_id);
6553   EXPECT_NE(0u, id2);
6554   EXPECT_NE(id1, id2);
6555
6556   // Deleting invalid UIResourceId is allowed and does not change state.
6557   host_impl_->DeleteUIResource(-1);
6558   EXPECT_EQ(1u, context3d->NumTextures());
6559
6560   // Should return zero for invalid UIResourceId.  Number of textures should
6561   // not change.
6562   EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(-1));
6563   EXPECT_EQ(1u, context3d->NumTextures());
6564
6565   host_impl_->DeleteUIResource(ui_resource_id);
6566   EXPECT_EQ(0u, host_impl_->ResourceIdForUIResource(ui_resource_id));
6567   EXPECT_EQ(0u, context3d->NumTextures());
6568
6569   // Should not change state for multiple deletion on one UIResourceId
6570   host_impl_->DeleteUIResource(ui_resource_id);
6571   EXPECT_EQ(0u, context3d->NumTextures());
6572 }
6573
6574 TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
6575   scoped_ptr<TestWebGraphicsContext3D> context =
6576       TestWebGraphicsContext3D::Create();
6577   TestWebGraphicsContext3D* context3d = context.get();
6578   CreateHostImpl(DefaultSettings(), FakeOutputSurface::Create3d());
6579
6580   EXPECT_EQ(0u, context3d->NumTextures());
6581
6582   gfx::Size size(4, 4);
6583   // SkImageInfo has no support for ETC1.  The |info| below contains the right
6584   // total pixel size for the bitmap but not the right height and width.  The
6585   // correct width/height are passed directly to UIResourceBitmap.
6586   SkImageInfo info =
6587       SkImageInfo::Make(4, 2, kAlpha_8_SkColorType, kPremul_SkAlphaType);
6588   skia::RefPtr<SkPixelRef> pixel_ref =
6589       skia::AdoptRef(SkMallocPixelRef::NewAllocate(info, 0, 0));
6590   pixel_ref->setImmutable();
6591   UIResourceBitmap bitmap(pixel_ref, size);
6592   UIResourceId ui_resource_id = 1;
6593   host_impl_->CreateUIResource(ui_resource_id, bitmap);
6594   EXPECT_EQ(1u, context3d->NumTextures());
6595   ResourceProvider::ResourceId id1 =
6596       host_impl_->ResourceIdForUIResource(ui_resource_id);
6597   EXPECT_NE(0u, id1);
6598 }
6599
6600 void ShutdownReleasesContext_Callback(scoped_ptr<CopyOutputResult> result) {
6601 }
6602
6603 TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) {
6604   scoped_refptr<TestContextProvider> context_provider =
6605       TestContextProvider::Create();
6606
6607   CreateHostImpl(DefaultSettings(),
6608                  FakeOutputSurface::Create3d(context_provider));
6609
6610   SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1));
6611
6612   ScopedPtrVector<CopyOutputRequest> requests;
6613   requests.push_back(CopyOutputRequest::CreateRequest(
6614       base::Bind(&ShutdownReleasesContext_Callback)));
6615
6616   host_impl_->active_tree()->root_layer()->PassCopyRequests(&requests);
6617
6618   LayerTreeHostImpl::FrameData frame;
6619   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6620   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6621   host_impl_->DidDrawAllLayers(frame);
6622
6623   // The CopyOutputResult's callback has a ref on the ContextProvider and a
6624   // texture in a texture mailbox.
6625   EXPECT_FALSE(context_provider->HasOneRef());
6626   EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
6627
6628   host_impl_ = nullptr;
6629
6630   // The CopyOutputResult's callback was cancelled, the CopyOutputResult
6631   // released, and the texture deleted.
6632   EXPECT_TRUE(context_provider->HasOneRef());
6633   EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
6634 }
6635
6636 TEST_F(LayerTreeHostImplTest, TouchFlingShouldNotBubble) {
6637   // When flinging via touch, only the child should scroll (we should not
6638   // bubble).
6639   gfx::Size surface_size(10, 10);
6640   gfx::Size content_size(20, 20);
6641   scoped_ptr<LayerImpl> root_clip =
6642       LayerImpl::Create(host_impl_->active_tree(), 3);
6643   scoped_ptr<LayerImpl> root =
6644       CreateScrollableLayer(1, content_size, root_clip.get());
6645   root->SetIsContainerForFixedPositionLayers(true);
6646   scoped_ptr<LayerImpl> child =
6647       CreateScrollableLayer(2, content_size, root_clip.get());
6648
6649   root->AddChild(child.Pass());
6650   int root_id = root->id();
6651   root_clip->AddChild(root.Pass());
6652
6653   host_impl_->SetViewportSize(surface_size);
6654   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
6655   host_impl_->active_tree()->SetViewportLayersFromIds(3, 1, Layer::INVALID_ID);
6656   host_impl_->active_tree()->DidBecomeActive();
6657   DrawFrame();
6658   {
6659     EXPECT_EQ(InputHandler::ScrollStarted,
6660               host_impl_->ScrollBegin(gfx::Point(),
6661                                       InputHandler::Gesture));
6662
6663     EXPECT_EQ(InputHandler::ScrollStarted,
6664               host_impl_->FlingScrollBegin());
6665
6666     gfx::Vector2d scroll_delta(0, 100);
6667     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
6668     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
6669
6670     host_impl_->ScrollEnd();
6671
6672     scoped_ptr<ScrollAndScaleSet> scroll_info =
6673         host_impl_->ProcessScrollDeltas();
6674
6675     // Only the child should have scrolled.
6676     ASSERT_EQ(1u, scroll_info->scrolls.size());
6677     ExpectNone(*scroll_info.get(), root_id);
6678   }
6679 }
6680
6681 TEST_F(LayerTreeHostImplTest, TouchFlingShouldLockToFirstScrolledLayer) {
6682   // Scroll a child layer beyond its maximum scroll range and make sure the
6683   // the scroll doesn't bubble up to the parent layer.
6684   gfx::Size surface_size(10, 10);
6685   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl_->active_tree(), 1);
6686   scoped_ptr<LayerImpl> root_scrolling =
6687       CreateScrollableLayer(2, surface_size, root.get());
6688
6689   scoped_ptr<LayerImpl> grand_child =
6690       CreateScrollableLayer(4, surface_size, root.get());
6691   grand_child->SetScrollOffset(gfx::ScrollOffset(0, 2));
6692
6693   scoped_ptr<LayerImpl> child =
6694       CreateScrollableLayer(3, surface_size, root.get());
6695   child->SetScrollOffset(gfx::ScrollOffset(0, 4));
6696   child->AddChild(grand_child.Pass());
6697
6698   root_scrolling->AddChild(child.Pass());
6699   root->AddChild(root_scrolling.Pass());
6700   host_impl_->active_tree()->SetRootLayer(root.Pass());
6701   host_impl_->active_tree()->DidBecomeActive();
6702   host_impl_->SetViewportSize(surface_size);
6703   DrawFrame();
6704   {
6705     scoped_ptr<ScrollAndScaleSet> scroll_info;
6706     LayerImpl* child =
6707         host_impl_->active_tree()->root_layer()->children()[0]->children()[0];
6708     LayerImpl* grand_child = child->children()[0];
6709
6710     gfx::Vector2d scroll_delta(0, -2);
6711     EXPECT_EQ(InputHandler::ScrollStarted,
6712               host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
6713     EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
6714
6715     // The grand child should have scrolled up to its limit.
6716     scroll_info = host_impl_->ProcessScrollDeltas();
6717     ASSERT_EQ(1u, scroll_info->scrolls.size());
6718     ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
6719     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
6720
6721     // The child should have received the bubbled delta, but the locked
6722     // scrolling layer should remain set as the grand child.
6723     EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
6724     scroll_info = host_impl_->ProcessScrollDeltas();
6725     ASSERT_EQ(2u, scroll_info->scrolls.size());
6726     ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
6727     ExpectContains(*scroll_info, child->id(), scroll_delta);
6728     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child);
6729
6730     // The first |ScrollBy| after the fling should re-lock the scrolling
6731     // layer to the first layer that scrolled, which is the child.
6732     EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
6733     EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
6734     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
6735
6736     // The child should have scrolled up to its limit.
6737     scroll_info = host_impl_->ProcessScrollDeltas();
6738     ASSERT_EQ(2u, scroll_info->scrolls.size());
6739     ExpectContains(*scroll_info, grand_child->id(), scroll_delta);
6740     ExpectContains(*scroll_info, child->id(), scroll_delta + scroll_delta);
6741
6742     // As the locked layer is at it's limit, no further scrolling can occur.
6743     EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
6744     EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child);
6745     host_impl_->ScrollEnd();
6746   }
6747 }
6748
6749 TEST_F(LayerTreeHostImplTest, WheelFlingShouldBubble) {
6750   // When flinging via wheel, the root should eventually scroll (we should
6751   // bubble).
6752   gfx::Size surface_size(10, 10);
6753   gfx::Size content_size(20, 20);
6754   scoped_ptr<LayerImpl> root_clip =
6755       LayerImpl::Create(host_impl_->active_tree(), 3);
6756   scoped_ptr<LayerImpl> root_scroll =
6757       CreateScrollableLayer(1, content_size, root_clip.get());
6758   int root_scroll_id = root_scroll->id();
6759   scoped_ptr<LayerImpl> child =
6760       CreateScrollableLayer(2, content_size, root_clip.get());
6761
6762   root_scroll->AddChild(child.Pass());
6763   root_clip->AddChild(root_scroll.Pass());
6764
6765   host_impl_->SetViewportSize(surface_size);
6766   host_impl_->active_tree()->SetRootLayer(root_clip.Pass());
6767   host_impl_->active_tree()->DidBecomeActive();
6768   DrawFrame();
6769   {
6770     EXPECT_EQ(InputHandler::ScrollStarted,
6771               host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
6772
6773     EXPECT_EQ(InputHandler::ScrollStarted,
6774               host_impl_->FlingScrollBegin());
6775
6776     gfx::Vector2d scroll_delta(0, 100);
6777     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
6778     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
6779
6780     host_impl_->ScrollEnd();
6781
6782     scoped_ptr<ScrollAndScaleSet> scroll_info =
6783         host_impl_->ProcessScrollDeltas();
6784
6785     // The root should have scrolled.
6786     ASSERT_EQ(2u, scroll_info->scrolls.size());
6787     ExpectContains(*scroll_info.get(), root_scroll_id, gfx::Vector2d(0, 10));
6788   }
6789 }
6790
6791 TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
6792   // If we ray cast a scroller that is not on the first layer's ancestor chain,
6793   // we should return ScrollUnknown.
6794   gfx::Size content_size(100, 100);
6795   SetupScrollAndContentsLayers(content_size);
6796
6797   int scroll_layer_id = 2;
6798   LayerImpl* scroll_layer =
6799       host_impl_->active_tree()->LayerById(scroll_layer_id);
6800   scroll_layer->SetDrawsContent(true);
6801
6802   int page_scale_layer_id = 5;
6803   LayerImpl* page_scale_layer =
6804       host_impl_->active_tree()->LayerById(page_scale_layer_id);
6805
6806   int occluder_layer_id = 6;
6807   scoped_ptr<LayerImpl> occluder_layer =
6808       LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
6809   occluder_layer->SetDrawsContent(true);
6810   occluder_layer->SetBounds(content_size);
6811   occluder_layer->SetContentBounds(content_size);
6812   occluder_layer->SetPosition(gfx::PointF());
6813
6814   // The parent of the occluder is *above* the scroller.
6815   page_scale_layer->AddChild(occluder_layer.Pass());
6816
6817   DrawFrame();
6818
6819   EXPECT_EQ(InputHandler::ScrollUnknown,
6820             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
6821 }
6822
6823 TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
6824   // If we ray cast a scroller this is on the first layer's ancestor chain, but
6825   // is not the first scroller we encounter when walking up from the layer, we
6826   // should also return ScrollUnknown.
6827   gfx::Size content_size(100, 100);
6828   SetupScrollAndContentsLayers(content_size);
6829
6830   int scroll_layer_id = 2;
6831   LayerImpl* scroll_layer =
6832       host_impl_->active_tree()->LayerById(scroll_layer_id);
6833   scroll_layer->SetDrawsContent(true);
6834
6835   int occluder_layer_id = 6;
6836   scoped_ptr<LayerImpl> occluder_layer =
6837       LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id);
6838   occluder_layer->SetDrawsContent(true);
6839   occluder_layer->SetBounds(content_size);
6840   occluder_layer->SetContentBounds(content_size);
6841   occluder_layer->SetPosition(gfx::PointF(-10.f, -10.f));
6842
6843   int child_scroll_clip_layer_id = 7;
6844   scoped_ptr<LayerImpl> child_scroll_clip =
6845       LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id);
6846
6847   int child_scroll_layer_id = 8;
6848   scoped_ptr<LayerImpl> child_scroll = CreateScrollableLayer(
6849       child_scroll_layer_id, content_size, child_scroll_clip.get());
6850
6851   child_scroll->SetPosition(gfx::PointF(10.f, 10.f));
6852
6853   child_scroll->AddChild(occluder_layer.Pass());
6854   scroll_layer->AddChild(child_scroll.Pass());
6855
6856   DrawFrame();
6857
6858   EXPECT_EQ(InputHandler::ScrollUnknown,
6859             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
6860 }
6861
6862 TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) {
6863   gfx::Size content_size(100, 100);
6864   SetupScrollAndContentsLayers(content_size);
6865
6866   LayerImpl* root = host_impl_->active_tree()->LayerById(1);
6867
6868   int scroll_layer_id = 2;
6869   LayerImpl* scroll_layer =
6870       host_impl_->active_tree()->LayerById(scroll_layer_id);
6871
6872   int child_scroll_layer_id = 7;
6873   scoped_ptr<LayerImpl> child_scroll =
6874       CreateScrollableLayer(child_scroll_layer_id, content_size, root);
6875   child_scroll->SetDrawsContent(false);
6876
6877   scroll_layer->AddChild(child_scroll.Pass());
6878
6879   DrawFrame();
6880
6881   // We should not have scrolled |child_scroll| even though we technically "hit"
6882   // it. The reason for this is that if the scrolling the scroll would not move
6883   // any layer that is a drawn RSLL member, then we can ignore the hit.
6884   //
6885   // Why ScrollStarted? In this case, it's because we've bubbled out and started
6886   // overscrolling the inner viewport.
6887   EXPECT_EQ(InputHandler::ScrollStarted,
6888             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
6889
6890   EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id());
6891 }
6892
6893 TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) {
6894   // This test case is very similar to the one above with one key difference:
6895   // the invisible scroller has a scroll child that is indeed draw contents.
6896   // If we attempt to initiate a gesture scroll off of the visible scroll child
6897   // we should still start the scroll child.
6898   gfx::Size content_size(100, 100);
6899   SetupScrollAndContentsLayers(content_size);
6900
6901   LayerImpl* root = host_impl_->active_tree()->LayerById(1);
6902
6903   int scroll_layer_id = 2;
6904   LayerImpl* scroll_layer =
6905       host_impl_->active_tree()->LayerById(scroll_layer_id);
6906
6907   int scroll_child_id = 6;
6908   scoped_ptr<LayerImpl> scroll_child =
6909       LayerImpl::Create(host_impl_->active_tree(), scroll_child_id);
6910   scroll_child->SetDrawsContent(true);
6911   scroll_child->SetBounds(content_size);
6912   scroll_child->SetContentBounds(content_size);
6913   // Move the scroll child so it's not hit by our test point.
6914   scroll_child->SetPosition(gfx::PointF(10.f, 10.f));
6915
6916   int invisible_scroll_layer_id = 7;
6917   scoped_ptr<LayerImpl> invisible_scroll =
6918       CreateScrollableLayer(invisible_scroll_layer_id, content_size, root);
6919   invisible_scroll->SetDrawsContent(false);
6920
6921   int container_id = 8;
6922   scoped_ptr<LayerImpl> container =
6923       LayerImpl::Create(host_impl_->active_tree(), container_id);
6924
6925   scoped_ptr<std::set<LayerImpl*>> scroll_children(new std::set<LayerImpl*>);
6926   scroll_children->insert(scroll_child.get());
6927   invisible_scroll->SetScrollChildren(scroll_children.release());
6928
6929   scroll_child->SetScrollParent(invisible_scroll.get());
6930
6931   container->AddChild(invisible_scroll.Pass());
6932   container->AddChild(scroll_child.Pass());
6933
6934   scroll_layer->AddChild(container.Pass());
6935
6936   DrawFrame();
6937
6938   // We should not have scrolled |child_scroll| even though we technically "hit"
6939   // it. The reason for this is that if the scrolling the scroll would not move
6940   // any layer that is a drawn RSLL member, then we can ignore the hit.
6941   //
6942   // Why ScrollStarted? In this case, it's because we've bubbled out and started
6943   // overscrolling the inner viewport.
6944   EXPECT_EQ(InputHandler::ScrollStarted,
6945             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel));
6946
6947   EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id());
6948 }
6949
6950 // Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed
6951 // to CompositorFrameMetadata after SwapBuffers();
6952 TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) {
6953   scoped_ptr<SolidColorLayerImpl> root =
6954       SolidColorLayerImpl::Create(host_impl_->active_tree(), 1);
6955   root->SetPosition(gfx::PointF());
6956   root->SetBounds(gfx::Size(10, 10));
6957   root->SetContentBounds(gfx::Size(10, 10));
6958   root->SetDrawsContent(true);
6959
6960   host_impl_->active_tree()->SetRootLayer(root.Pass());
6961
6962   FakeOutputSurface* fake_output_surface =
6963       static_cast<FakeOutputSurface*>(host_impl_->output_surface());
6964
6965   const std::vector<ui::LatencyInfo>& metadata_latency_before =
6966       fake_output_surface->last_sent_frame().metadata.latency_info;
6967   EXPECT_TRUE(metadata_latency_before.empty());
6968
6969   ui::LatencyInfo latency_info;
6970   latency_info.AddLatencyNumber(
6971       ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, 0);
6972   scoped_ptr<SwapPromise> swap_promise(
6973       new LatencyInfoSwapPromise(latency_info));
6974   host_impl_->active_tree()->QueueSwapPromise(swap_promise.Pass());
6975   host_impl_->SetNeedsRedraw();
6976
6977   gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
6978   LayerTreeHostImpl::FrameData frame;
6979   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
6980   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
6981   host_impl_->DidDrawAllLayers(frame);
6982   EXPECT_TRUE(host_impl_->SwapBuffers(frame));
6983
6984   const std::vector<ui::LatencyInfo>& metadata_latency_after =
6985       fake_output_surface->last_sent_frame().metadata.latency_info;
6986   EXPECT_EQ(1u, metadata_latency_after.size());
6987   EXPECT_TRUE(metadata_latency_after[0].FindLatency(
6988       ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 0, NULL));
6989 }
6990
6991 TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
6992   int root_layer_id = 1;
6993   scoped_ptr<SolidColorLayerImpl> root =
6994       SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id);
6995   root->SetPosition(gfx::PointF());
6996   root->SetBounds(gfx::Size(10, 10));
6997   root->SetContentBounds(gfx::Size(10, 10));
6998   root->SetDrawsContent(true);
6999
7000   host_impl_->active_tree()->SetRootLayer(root.Pass());
7001
7002   // Ensure the default frame selection bounds are empty.
7003   FakeOutputSurface* fake_output_surface =
7004       static_cast<FakeOutputSurface*>(host_impl_->output_surface());
7005   const ViewportSelectionBound& selection_start_before =
7006       fake_output_surface->last_sent_frame().metadata.selection_start;
7007   const ViewportSelectionBound& selection_end_before =
7008       fake_output_surface->last_sent_frame().metadata.selection_end;
7009   EXPECT_EQ(ViewportSelectionBound(), selection_start_before);
7010   EXPECT_EQ(ViewportSelectionBound(), selection_end_before);
7011
7012   // Plumb the layer-local selection bounds.
7013   gfx::PointF selection_top(5, 0);
7014   gfx::PointF selection_bottom(5, 5);
7015   LayerSelectionBound start, end;
7016   start.type = SELECTION_BOUND_CENTER;
7017   start.layer_id = root_layer_id;
7018   start.edge_bottom = selection_bottom;
7019   start.edge_top = selection_top;
7020   end = start;
7021   host_impl_->active_tree()->RegisterSelection(start, end);
7022
7023   // Trigger a draw-swap sequence.
7024   host_impl_->SetNeedsRedraw();
7025
7026   gfx::Rect full_frame_damage(host_impl_->DrawViewportSize());
7027   LayerTreeHostImpl::FrameData frame;
7028   EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
7029   host_impl_->DrawLayers(&frame, gfx::FrameTime::Now());
7030   host_impl_->DidDrawAllLayers(frame);
7031   EXPECT_TRUE(host_impl_->SwapBuffers(frame));
7032
7033   // Ensure the selection bounds have propagated to the frame metadata.
7034   const ViewportSelectionBound& selection_start_after =
7035       fake_output_surface->last_sent_frame().metadata.selection_start;
7036   const ViewportSelectionBound& selection_end_after =
7037       fake_output_surface->last_sent_frame().metadata.selection_end;
7038   EXPECT_EQ(start.type, selection_start_after.type);
7039   EXPECT_EQ(end.type, selection_end_after.type);
7040   EXPECT_EQ(selection_bottom, selection_start_after.edge_bottom);
7041   EXPECT_EQ(selection_top, selection_start_after.edge_top);
7042   EXPECT_TRUE(selection_start_after.visible);
7043   EXPECT_TRUE(selection_start_after.visible);
7044 }
7045
7046 class SimpleSwapPromiseMonitor : public SwapPromiseMonitor {
7047  public:
7048   SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host,
7049                            LayerTreeHostImpl* layer_tree_host_impl,
7050                            int* set_needs_commit_count,
7051                            int* set_needs_redraw_count,
7052                            int* forward_to_main_count)
7053       : SwapPromiseMonitor(layer_tree_host, layer_tree_host_impl),
7054         set_needs_commit_count_(set_needs_commit_count),
7055         set_needs_redraw_count_(set_needs_redraw_count),
7056         forward_to_main_count_(forward_to_main_count) {}
7057
7058   ~SimpleSwapPromiseMonitor() override {}
7059
7060   void OnSetNeedsCommitOnMain() override { (*set_needs_commit_count_)++; }
7061
7062   void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; }
7063
7064   void OnForwardScrollUpdateToMainThreadOnImpl() override {
7065     (*forward_to_main_count_)++;
7066   }
7067
7068  private:
7069   int* set_needs_commit_count_;
7070   int* set_needs_redraw_count_;
7071   int* forward_to_main_count_;
7072 };
7073
7074 TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
7075   int set_needs_commit_count = 0;
7076   int set_needs_redraw_count = 0;
7077   int forward_to_main_count = 0;
7078
7079   {
7080     scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
7081         new SimpleSwapPromiseMonitor(NULL,
7082                                      host_impl_.get(),
7083                                      &set_needs_commit_count,
7084                                      &set_needs_redraw_count,
7085                                      &forward_to_main_count));
7086     host_impl_->SetNeedsRedraw();
7087     EXPECT_EQ(0, set_needs_commit_count);
7088     EXPECT_EQ(1, set_needs_redraw_count);
7089     EXPECT_EQ(0, forward_to_main_count);
7090   }
7091
7092   // Now the monitor is destroyed, SetNeedsRedraw() is no longer being
7093   // monitored.
7094   host_impl_->SetNeedsRedraw();
7095   EXPECT_EQ(0, set_needs_commit_count);
7096   EXPECT_EQ(1, set_needs_redraw_count);
7097   EXPECT_EQ(0, forward_to_main_count);
7098
7099   {
7100     scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
7101         new SimpleSwapPromiseMonitor(NULL,
7102                                      host_impl_.get(),
7103                                      &set_needs_commit_count,
7104                                      &set_needs_redraw_count,
7105                                      &forward_to_main_count));
7106     host_impl_->SetNeedsRedrawRect(gfx::Rect(10, 10));
7107     EXPECT_EQ(0, set_needs_commit_count);
7108     EXPECT_EQ(2, set_needs_redraw_count);
7109     EXPECT_EQ(0, forward_to_main_count);
7110   }
7111
7112   {
7113     scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
7114         new SimpleSwapPromiseMonitor(NULL,
7115                                      host_impl_.get(),
7116                                      &set_needs_commit_count,
7117                                      &set_needs_redraw_count,
7118                                      &forward_to_main_count));
7119     // Empty damage rect won't signal the monitor.
7120     host_impl_->SetNeedsRedrawRect(gfx::Rect());
7121     EXPECT_EQ(0, set_needs_commit_count);
7122     EXPECT_EQ(2, set_needs_redraw_count);
7123     EXPECT_EQ(0, forward_to_main_count);
7124   }
7125
7126   {
7127     set_needs_commit_count = 0;
7128     set_needs_redraw_count = 0;
7129     forward_to_main_count = 0;
7130     scoped_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor(
7131         new SimpleSwapPromiseMonitor(NULL,
7132                                      host_impl_.get(),
7133                                      &set_needs_commit_count,
7134                                      &set_needs_redraw_count,
7135                                      &forward_to_main_count));
7136     LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100));
7137
7138     // Scrolling normally should not trigger any forwarding.
7139     EXPECT_EQ(InputHandler::ScrollStarted,
7140               host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7141     EXPECT_TRUE(
7142         host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll);
7143     host_impl_->ScrollEnd();
7144
7145     EXPECT_EQ(0, set_needs_commit_count);
7146     EXPECT_EQ(1, set_needs_redraw_count);
7147     EXPECT_EQ(0, forward_to_main_count);
7148
7149     // Scrolling with a scroll handler should defer the swap to the main
7150     // thread.
7151     scroll_layer->SetHaveScrollEventHandlers(true);
7152     EXPECT_EQ(InputHandler::ScrollStarted,
7153               host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7154     EXPECT_TRUE(
7155         host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, 10)).did_scroll);
7156     host_impl_->ScrollEnd();
7157
7158     EXPECT_EQ(0, set_needs_commit_count);
7159     EXPECT_EQ(2, set_needs_redraw_count);
7160     EXPECT_EQ(1, forward_to_main_count);
7161   }
7162 }
7163
7164 class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest {
7165  public:
7166   virtual void SetUp() override {
7167     LayerTreeSettings settings = DefaultSettings();
7168     settings.calculate_top_controls_position = true;
7169     settings.top_controls_height = top_controls_height_;
7170     CreateHostImpl(settings, CreateOutputSurface());
7171   }
7172
7173  protected:
7174   static const int top_controls_height_;
7175 };
7176
7177 const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50;
7178
7179 TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) {
7180   SetupScrollAndContentsLayers(gfx::Size(100, 100))
7181       ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7182   host_impl_->Animate(base::TimeTicks());
7183   EXPECT_FALSE(did_request_redraw_);
7184 }
7185
7186 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) {
7187   SetupScrollAndContentsLayers(gfx::Size(100, 100))
7188       ->SetScrollOffset(gfx::ScrollOffset(0, 10));
7189   host_impl_->DidChangeTopControlsPosition();
7190   EXPECT_TRUE(did_request_animate_);
7191   EXPECT_TRUE(did_request_redraw_);
7192 }
7193
7194 TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) {
7195   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
7196   host_impl_->SetViewportSize(gfx::Size(100, 100));
7197   host_impl_->top_controls_manager()->UpdateTopControlsState(
7198       BOTH, SHOWN, false);
7199   DrawFrame();
7200
7201   EXPECT_EQ(InputHandler::ScrollStarted,
7202             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7203   EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
7204   EXPECT_EQ(gfx::Vector2dF().ToString(),
7205             scroll_layer->TotalScrollOffset().ToString());
7206
7207   // Scroll just the top controls and verify that the scroll succeeds.
7208   const float residue = 10;
7209   float offset = top_controls_height_ - residue;
7210   EXPECT_TRUE(
7211       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7212   EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
7213   EXPECT_EQ(gfx::Vector2dF().ToString(),
7214             scroll_layer->TotalScrollOffset().ToString());
7215
7216   // Scroll across the boundary
7217   const float content_scroll = 20;
7218   offset = residue + content_scroll;
7219   EXPECT_TRUE(
7220       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7221   EXPECT_EQ(-top_controls_height_,
7222             host_impl_->top_controls_manager()->ControlsTopOffset());
7223   EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(),
7224             scroll_layer->TotalScrollOffset().ToString());
7225
7226   // Now scroll back to the top of the content
7227   offset = -content_scroll;
7228   EXPECT_TRUE(
7229       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7230   EXPECT_EQ(-top_controls_height_,
7231             host_impl_->top_controls_manager()->ControlsTopOffset());
7232   EXPECT_EQ(gfx::Vector2dF().ToString(),
7233             scroll_layer->TotalScrollOffset().ToString());
7234
7235   // And scroll the top controls completely into view
7236   offset = -top_controls_height_;
7237   EXPECT_TRUE(
7238       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7239   EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
7240   EXPECT_EQ(gfx::Vector2dF().ToString(),
7241             scroll_layer->TotalScrollOffset().ToString());
7242
7243   // And attempt to scroll past the end
7244   EXPECT_FALSE(
7245       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7246   EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
7247   EXPECT_EQ(gfx::Vector2dF().ToString(),
7248             scroll_layer->TotalScrollOffset().ToString());
7249
7250   host_impl_->ScrollEnd();
7251 }
7252
7253 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) {
7254   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
7255   host_impl_->SetViewportSize(gfx::Size(100, 200));
7256   host_impl_->top_controls_manager()->UpdateTopControlsState(
7257       BOTH, SHOWN, false);
7258   DrawFrame();
7259
7260   EXPECT_EQ(InputHandler::ScrollStarted,
7261             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7262   EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
7263   EXPECT_EQ(gfx::Vector2dF().ToString(),
7264             scroll_layer->TotalScrollOffset().ToString());
7265
7266   // Scroll the top controls partially.
7267   const float residue = 35;
7268   float offset = top_controls_height_ - residue;
7269   EXPECT_TRUE(
7270       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7271   EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
7272   EXPECT_EQ(gfx::Vector2dF().ToString(),
7273             scroll_layer->TotalScrollOffset().ToString());
7274
7275   did_request_redraw_ = false;
7276   did_request_animate_ = false;
7277   did_request_commit_ = false;
7278
7279   // End the scroll while the controls are still offset from their limit.
7280   host_impl_->ScrollEnd();
7281   ASSERT_TRUE(host_impl_->top_controls_manager()->animation());
7282   EXPECT_TRUE(did_request_animate_);
7283   EXPECT_TRUE(did_request_redraw_);
7284   EXPECT_FALSE(did_request_commit_);
7285
7286   // The top controls should properly animate until finished, despite the scroll
7287   // offset being at the origin.
7288   base::TimeTicks animation_time = gfx::FrameTime::Now();
7289   while (did_request_animate_) {
7290     did_request_redraw_ = false;
7291     did_request_animate_ = false;
7292     did_request_commit_ = false;
7293
7294     float old_offset =
7295         host_impl_->top_controls_manager()->ControlsTopOffset();
7296
7297     animation_time += base::TimeDelta::FromMilliseconds(5);
7298     host_impl_->Animate(animation_time);
7299     EXPECT_EQ(gfx::Vector2dF().ToString(),
7300               scroll_layer->TotalScrollOffset().ToString());
7301
7302     float new_offset =
7303         host_impl_->top_controls_manager()->ControlsTopOffset();
7304
7305     // No commit is needed as the controls are animating the content offset,
7306     // not the scroll offset.
7307     EXPECT_FALSE(did_request_commit_);
7308
7309     if (new_offset != old_offset)
7310       EXPECT_TRUE(did_request_redraw_);
7311
7312     if (new_offset != 0) {
7313       EXPECT_TRUE(host_impl_->top_controls_manager()->animation());
7314       EXPECT_TRUE(did_request_animate_);
7315     }
7316   }
7317   EXPECT_FALSE(host_impl_->top_controls_manager()->animation());
7318 }
7319
7320 TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) {
7321   LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200));
7322   host_impl_->SetViewportSize(gfx::Size(100, 100));
7323   host_impl_->top_controls_manager()->UpdateTopControlsState(
7324       BOTH, SHOWN, false);
7325   float initial_scroll_offset = 50;
7326   scroll_layer->SetScrollOffset(gfx::ScrollOffset(0, initial_scroll_offset));
7327   DrawFrame();
7328
7329   EXPECT_EQ(InputHandler::ScrollStarted,
7330             host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7331   EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset());
7332   EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
7333             scroll_layer->TotalScrollOffset().ToString());
7334
7335   // Scroll the top controls partially.
7336   const float residue = 15;
7337   float offset = top_controls_height_ - residue;
7338   EXPECT_TRUE(
7339       host_impl_->ScrollBy(gfx::Point(), gfx::Vector2d(0, offset)).did_scroll);
7340   EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset());
7341   EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
7342             scroll_layer->TotalScrollOffset().ToString());
7343
7344   did_request_redraw_ = false;
7345   did_request_animate_ = false;
7346   did_request_commit_ = false;
7347
7348   // End the scroll while the controls are still offset from the limit.
7349   host_impl_->ScrollEnd();
7350   ASSERT_TRUE(host_impl_->top_controls_manager()->animation());
7351   EXPECT_TRUE(did_request_animate_);
7352   EXPECT_TRUE(did_request_redraw_);
7353   EXPECT_FALSE(did_request_commit_);
7354
7355   // Animate the top controls to the limit.
7356   base::TimeTicks animation_time = gfx::FrameTime::Now();
7357   while (did_request_animate_) {
7358     did_request_redraw_ = false;
7359     did_request_animate_ = false;
7360     did_request_commit_ = false;
7361
7362     float old_offset =
7363         host_impl_->top_controls_manager()->ControlsTopOffset();
7364
7365     animation_time += base::TimeDelta::FromMilliseconds(5);
7366     host_impl_->Animate(animation_time);
7367
7368     float new_offset =
7369         host_impl_->top_controls_manager()->ControlsTopOffset();
7370
7371     if (new_offset != old_offset) {
7372       EXPECT_TRUE(did_request_redraw_);
7373       EXPECT_TRUE(did_request_commit_);
7374     }
7375   }
7376   EXPECT_FALSE(host_impl_->top_controls_manager()->animation());
7377 }
7378
7379 class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest {
7380  public:
7381   void SetupVirtualViewportLayers(const gfx::Size& content_size,
7382                                   const gfx::Size& outer_viewport,
7383                                   const gfx::Size& inner_viewport) {
7384     LayerTreeImpl* layer_tree_impl = host_impl_->active_tree();
7385     const int kOuterViewportClipLayerId = 6;
7386     const int kOuterViewportScrollLayerId = 7;
7387     const int kInnerViewportScrollLayerId = 2;
7388     const int kInnerViewportClipLayerId = 4;
7389     const int kPageScaleLayerId = 5;
7390
7391     scoped_ptr<LayerImpl> inner_scroll =
7392         LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId);
7393     inner_scroll->SetIsContainerForFixedPositionLayers(true);
7394     inner_scroll->SetScrollOffset(gfx::ScrollOffset());
7395
7396     scoped_ptr<LayerImpl> inner_clip =
7397         LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId);
7398     inner_clip->SetBounds(inner_viewport);
7399
7400     scoped_ptr<LayerImpl> page_scale =
7401         LayerImpl::Create(layer_tree_impl, kPageScaleLayerId);
7402
7403     inner_scroll->SetScrollClipLayer(inner_clip->id());
7404     inner_scroll->SetBounds(outer_viewport);
7405     inner_scroll->SetContentBounds(outer_viewport);
7406     inner_scroll->SetPosition(gfx::PointF());
7407
7408     scoped_ptr<LayerImpl> outer_clip =
7409         LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId);
7410     outer_clip->SetBounds(outer_viewport);
7411     outer_clip->SetIsContainerForFixedPositionLayers(true);
7412
7413     scoped_ptr<LayerImpl> outer_scroll =
7414         LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId);
7415     outer_scroll->SetScrollClipLayer(outer_clip->id());
7416     outer_scroll->SetScrollOffset(gfx::ScrollOffset());
7417     outer_scroll->SetBounds(content_size);
7418     outer_scroll->SetContentBounds(content_size);
7419     outer_scroll->SetPosition(gfx::PointF());
7420
7421     scoped_ptr<LayerImpl> contents =
7422         LayerImpl::Create(layer_tree_impl, 8);
7423     contents->SetDrawsContent(true);
7424     contents->SetBounds(content_size);
7425     contents->SetContentBounds(content_size);
7426     contents->SetPosition(gfx::PointF());
7427
7428     outer_scroll->AddChild(contents.Pass());
7429     outer_clip->AddChild(outer_scroll.Pass());
7430     inner_scroll->AddChild(outer_clip.Pass());
7431     page_scale->AddChild(inner_scroll.Pass());
7432     inner_clip->AddChild(page_scale.Pass());
7433
7434     layer_tree_impl->SetRootLayer(inner_clip.Pass());
7435     layer_tree_impl->SetViewportLayersFromIds(kPageScaleLayerId,
7436         kInnerViewportScrollLayerId, kOuterViewportScrollLayerId);
7437
7438     host_impl_->active_tree()->DidBecomeActive();
7439   }
7440 };
7441
7442 TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) {
7443   gfx::Size content_size = gfx::Size(100, 160);
7444   gfx::Size outer_viewport = gfx::Size(50, 80);
7445   gfx::Size inner_viewport = gfx::Size(25, 40);
7446
7447   SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
7448
7449   LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
7450   LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
7451   DrawFrame();
7452   {
7453     gfx::Vector2dF inner_expected;
7454     gfx::Vector2dF outer_expected;
7455     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7456     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7457
7458     // Make sure the fling goes to the outer viewport first
7459     EXPECT_EQ(InputHandler::ScrollStarted,
7460         host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7461     EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
7462
7463     gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height());
7464     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
7465     outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
7466
7467     host_impl_->ScrollEnd();
7468
7469     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7470     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7471
7472     // Fling past the outer viewport boundry, make sure inner viewport scrolls.
7473     EXPECT_EQ(InputHandler::ScrollStarted,
7474         host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7475     EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
7476
7477     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
7478     outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
7479
7480     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
7481     inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y());
7482
7483     host_impl_->ScrollEnd();
7484
7485     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7486     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7487   }
7488 }
7489
7490 TEST_F(LayerTreeHostImplVirtualViewportTest,
7491        DiagonalScrollBubblesPerfectlyToInner) {
7492   gfx::Size content_size = gfx::Size(100, 160);
7493   gfx::Size outer_viewport = gfx::Size(50, 80);
7494   gfx::Size inner_viewport = gfx::Size(25, 40);
7495
7496   SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
7497
7498   LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
7499   LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
7500   DrawFrame();
7501   {
7502     gfx::Vector2dF inner_expected;
7503     gfx::Vector2dF outer_expected;
7504     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7505     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7506
7507     // Make sure the scroll goes to the outer viewport first.
7508     EXPECT_EQ(InputHandler::ScrollStarted,
7509               host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
7510     EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
7511
7512     // Scroll near the edge of the outer viewport.
7513     gfx::Vector2d scroll_delta(inner_viewport.width(), inner_viewport.height());
7514     host_impl_->ScrollBy(gfx::Point(), scroll_delta);
7515     outer_expected += scroll_delta;
7516
7517     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7518     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7519
7520     // Now diagonal scroll across the outer viewport boundary in a single event.
7521     // The entirety of the scroll should be consumed, as bubbling between inner
7522     // and outer viewport layers is perfect.
7523     host_impl_->ScrollBy(gfx::Point(), gfx::ScaleVector2d(scroll_delta, 2));
7524     outer_expected += scroll_delta;
7525     inner_expected += scroll_delta;
7526     host_impl_->ScrollEnd();
7527
7528     EXPECT_VECTOR_EQ(inner_expected, inner_scroll->TotalScrollOffset());
7529     EXPECT_VECTOR_EQ(outer_expected, outer_scroll->TotalScrollOffset());
7530   }
7531 }
7532
7533 class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
7534  public:
7535   virtual void SetUp() override {
7536     LayerTreeSettings settings = DefaultSettings();
7537     settings.max_memory_for_prepaint_percentage = 50;
7538     CreateHostImpl(settings, CreateOutputSurface());
7539   }
7540 };
7541
7542 TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) {
7543   // Set up a memory policy and percentages which could cause
7544   // 32-bit integer overflows.
7545   ManagedMemoryPolicy mem_policy(300 * 1024 * 1024);  // 300MB
7546
7547   // Verify implicit limits are calculated correctly with no overflows
7548   host_impl_->SetMemoryPolicy(mem_policy);
7549   EXPECT_EQ(host_impl_->global_tile_state().hard_memory_limit_in_bytes,
7550             300u * 1024u * 1024u);
7551   EXPECT_EQ(host_impl_->global_tile_state().soft_memory_limit_in_bytes,
7552             150u * 1024u * 1024u);
7553 }
7554
7555 TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) {
7556   const gfx::Size layer_size(100, 100);
7557   gfx::Transform external_transform;
7558   const gfx::Rect external_viewport(layer_size);
7559   const gfx::Rect external_clip(layer_size);
7560   const bool resourceless_software_draw = false;
7561   LayerImpl* layer = SetupScrollAndContentsLayers(layer_size);
7562
7563   host_impl_->SetExternalDrawConstraints(external_transform,
7564                                          external_viewport,
7565                                          external_clip,
7566                                          external_viewport,
7567                                          external_transform,
7568                                          resourceless_software_draw);
7569   DrawFrame();
7570   EXPECT_TRANSFORMATION_MATRIX_EQ(
7571       external_transform, layer->draw_properties().target_space_transform);
7572
7573   external_transform.Translate(20, 20);
7574   host_impl_->SetExternalDrawConstraints(external_transform,
7575                                          external_viewport,
7576                                          external_clip,
7577                                          external_viewport,
7578                                          external_transform,
7579                                          resourceless_software_draw);
7580   DrawFrame();
7581   EXPECT_TRANSFORMATION_MATRIX_EQ(
7582       external_transform, layer->draw_properties().target_space_transform);
7583 }
7584
7585 TEST_F(LayerTreeHostImplTest, ScrollAnimated) {
7586   SetupScrollAndContentsLayers(gfx::Size(100, 200));
7587   DrawFrame();
7588
7589   base::TimeTicks start_time =
7590       base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
7591
7592   EXPECT_EQ(InputHandler::ScrollStarted,
7593             host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7594
7595   LayerImpl* scrolling_layer = host_impl_->CurrentlyScrollingLayer();
7596
7597   host_impl_->Animate(start_time);
7598   host_impl_->UpdateAnimationState(true);
7599
7600   EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->TotalScrollOffset());
7601
7602   host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(50));
7603   host_impl_->UpdateAnimationState(true);
7604
7605   float y = scrolling_layer->TotalScrollOffset().y();
7606   EXPECT_TRUE(y > 1 && y < 49);
7607
7608   // Update target.
7609   EXPECT_EQ(InputHandler::ScrollStarted,
7610             host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)));
7611
7612   host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(200));
7613   host_impl_->UpdateAnimationState(true);
7614
7615   y = scrolling_layer->TotalScrollOffset().y();
7616   EXPECT_TRUE(y > 50 && y < 100);
7617   EXPECT_EQ(scrolling_layer, host_impl_->CurrentlyScrollingLayer());
7618
7619   host_impl_->Animate(start_time + base::TimeDelta::FromMilliseconds(250));
7620   host_impl_->UpdateAnimationState(true);
7621
7622   EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
7623                    scrolling_layer->TotalScrollOffset());
7624   EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer());
7625 }
7626
7627 TEST_F(LayerTreeHostImplTest, GetPictureLayerImplPairs) {
7628   host_impl_->CreatePendingTree();
7629   host_impl_->pending_tree()->SetRootLayer(
7630       PictureLayerImpl::Create(host_impl_->pending_tree(), 10));
7631
7632   LayerTreeImpl* pending_tree = host_impl_->pending_tree();
7633   LayerImpl* pending_layer = pending_tree->root_layer();
7634
7635   std::vector<PictureLayerImpl::Pair> layer_pairs;
7636   host_impl_->GetPictureLayerImplPairs(&layer_pairs);
7637   EXPECT_EQ(1u, layer_pairs.size());
7638   EXPECT_EQ(pending_layer, layer_pairs[0].pending);
7639   EXPECT_EQ(nullptr, layer_pairs[0].active);
7640
7641   host_impl_->ActivateSyncTree();
7642
7643   LayerTreeImpl* active_tree = host_impl_->active_tree();
7644   LayerImpl* active_layer = active_tree->root_layer();
7645   EXPECT_NE(active_tree, pending_tree);
7646   EXPECT_NE(active_layer, pending_layer);
7647   EXPECT_NE(nullptr, active_tree);
7648   EXPECT_NE(nullptr, active_layer);
7649
7650   host_impl_->CreatePendingTree();
7651
7652   layer_pairs.clear();
7653   host_impl_->GetPictureLayerImplPairs(&layer_pairs);
7654   EXPECT_EQ(1u, layer_pairs.size());
7655   EXPECT_EQ(active_layer, layer_pairs[0].active);
7656   EXPECT_EQ(pending_layer, layer_pairs[0].pending);
7657
7658   // Activate, the active layer has no twin now.
7659   host_impl_->ActivateSyncTree();
7660
7661   layer_pairs.clear();
7662   host_impl_->GetPictureLayerImplPairs(&layer_pairs);
7663   EXPECT_EQ(1u, layer_pairs.size());
7664   EXPECT_EQ(active_layer, layer_pairs[0].active);
7665   EXPECT_EQ(nullptr, layer_pairs[0].pending);
7666
7667   // Create another layer in the pending tree that's not in the active tree. We
7668   // should get two pairs.
7669   host_impl_->CreatePendingTree();
7670   host_impl_->pending_tree()->root_layer()->AddChild(
7671       PictureLayerImpl::Create(host_impl_->pending_tree(), 11));
7672
7673   LayerImpl* new_pending_layer = pending_tree->root_layer()->children()[0];
7674
7675   layer_pairs.clear();
7676   host_impl_->GetPictureLayerImplPairs(&layer_pairs);
7677   EXPECT_EQ(2u, layer_pairs.size());
7678
7679   // The pair ordering is flaky, so make it consistent.
7680   if (layer_pairs[0].active != active_layer)
7681     std::swap(layer_pairs[0], layer_pairs[1]);
7682
7683   EXPECT_EQ(active_layer, layer_pairs[0].active);
7684   EXPECT_EQ(pending_layer, layer_pairs[0].pending);
7685   EXPECT_EQ(new_pending_layer, layer_pairs[1].pending);
7686   EXPECT_EQ(nullptr, layer_pairs[1].active);
7687 }
7688
7689 TEST_F(LayerTreeHostImplTest, DidBecomeActive) {
7690   host_impl_->CreatePendingTree();
7691   host_impl_->ActivateSyncTree();
7692   host_impl_->CreatePendingTree();
7693
7694   LayerTreeImpl* pending_tree = host_impl_->pending_tree();
7695
7696   scoped_ptr<FakePictureLayerImpl> pending_layer =
7697       FakePictureLayerImpl::Create(pending_tree, 10);
7698   pending_layer->DoPostCommitInitializationIfNeeded();
7699   FakePictureLayerImpl* raw_pending_layer = pending_layer.get();
7700   pending_tree->SetRootLayer(pending_layer.Pass());
7701   ASSERT_EQ(raw_pending_layer, pending_tree->root_layer());
7702
7703   EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count());
7704   pending_tree->DidBecomeActive();
7705   EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
7706
7707   scoped_ptr<FakePictureLayerImpl> mask_layer =
7708       FakePictureLayerImpl::Create(pending_tree, 11);
7709   mask_layer->DoPostCommitInitializationIfNeeded();
7710   FakePictureLayerImpl* raw_mask_layer = mask_layer.get();
7711   raw_pending_layer->SetMaskLayer(mask_layer.Pass());
7712   ASSERT_EQ(raw_mask_layer, raw_pending_layer->mask_layer());
7713
7714   EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count());
7715   EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count());
7716   pending_tree->DidBecomeActive();
7717   EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
7718   EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
7719
7720   scoped_ptr<FakePictureLayerImpl> replica_layer =
7721       FakePictureLayerImpl::Create(pending_tree, 12);
7722   scoped_ptr<FakePictureLayerImpl> replica_mask_layer =
7723       FakePictureLayerImpl::Create(pending_tree, 13);
7724   replica_mask_layer->DoPostCommitInitializationIfNeeded();
7725   FakePictureLayerImpl* raw_replica_mask_layer = replica_mask_layer.get();
7726   replica_layer->SetMaskLayer(replica_mask_layer.Pass());
7727   raw_pending_layer->SetReplicaLayer(replica_layer.Pass());
7728   ASSERT_EQ(raw_replica_mask_layer,
7729             raw_pending_layer->replica_layer()->mask_layer());
7730
7731   EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count());
7732   EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count());
7733   EXPECT_EQ(0u, raw_replica_mask_layer->did_become_active_call_count());
7734   pending_tree->DidBecomeActive();
7735   EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count());
7736   EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count());
7737   EXPECT_EQ(1u, raw_replica_mask_layer->did_become_active_call_count());
7738 }
7739
7740 class LayerTreeHostImplCountingLostSurfaces : public LayerTreeHostImplTest {
7741  public:
7742   LayerTreeHostImplCountingLostSurfaces() : num_lost_surfaces_(0) {}
7743   void DidLoseOutputSurfaceOnImplThread() override { num_lost_surfaces_++; }
7744
7745  protected:
7746   int num_lost_surfaces_;
7747 };
7748
7749 TEST_F(LayerTreeHostImplCountingLostSurfaces, TwiceLostSurface) {
7750   // Really we just need at least one client notification each time
7751   // we go from having a valid output surface to not having a valid output
7752   // surface.
7753   EXPECT_EQ(0, num_lost_surfaces_);
7754   host_impl_->DidLoseOutputSurface();
7755   EXPECT_EQ(1, num_lost_surfaces_);
7756   host_impl_->DidLoseOutputSurface();
7757   EXPECT_LE(1, num_lost_surfaces_);
7758 }
7759
7760 }  // namespace
7761 }  // namespace cc