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