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