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