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