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