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/layers/layer_impl.h"
6
7#include "cc/layers/painted_scrollbar_layer_impl.h"
8#include "cc/output/filter_operation.h"
9#include "cc/output/filter_operations.h"
10#include "cc/test/fake_impl_proxy.h"
11#include "cc/test/fake_layer_tree_host_impl.h"
12#include "cc/test/fake_output_surface.h"
13#include "cc/test/geometry_test_utils.h"
14#include "cc/test/test_shared_bitmap_manager.h"
15#include "cc/trees/layer_tree_impl.h"
16#include "cc/trees/single_thread_proxy.h"
17#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19#include "third_party/skia/include/effects/SkBlurImageFilter.h"
20#include "ui/gfx/geometry/vector2d_conversions.h"
21
22namespace cc {
23namespace {
24
25#define EXECUTE_AND_VERIFY_SUBTREE_CHANGED(code_to_test)                       \
26  root->ResetAllChangeTrackingForSubtree();                                    \
27  code_to_test;                                                                \
28  EXPECT_TRUE(root->needs_push_properties());                                  \
29  EXPECT_FALSE(child->needs_push_properties());                                \
30  EXPECT_FALSE(grand_child->needs_push_properties());                          \
31  EXPECT_TRUE(root->LayerPropertyChanged());                                   \
32  EXPECT_TRUE(child->LayerPropertyChanged());                                  \
33  EXPECT_TRUE(grand_child->LayerPropertyChanged());
34
35#define EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(code_to_test)                \
36  root->ResetAllChangeTrackingForSubtree();                                    \
37  code_to_test;                                                                \
38  EXPECT_FALSE(root->needs_push_properties());                                 \
39  EXPECT_FALSE(child->needs_push_properties());                                \
40  EXPECT_FALSE(grand_child->needs_push_properties());                          \
41  EXPECT_FALSE(root->LayerPropertyChanged());                                  \
42  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
43  EXPECT_FALSE(grand_child->LayerPropertyChanged());
44
45#define EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(   \
46      code_to_test)                                                            \
47  root->ResetAllChangeTrackingForSubtree();                                    \
48  code_to_test;                                                                \
49  EXPECT_TRUE(root->needs_push_properties());                                  \
50  EXPECT_FALSE(child->needs_push_properties());                                \
51  EXPECT_FALSE(grand_child->needs_push_properties());                          \
52  EXPECT_FALSE(root->LayerPropertyChanged());                                  \
53  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
54  EXPECT_FALSE(grand_child->LayerPropertyChanged());
55
56#define EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(code_to_test)                    \
57  root->ResetAllChangeTrackingForSubtree();                                    \
58  code_to_test;                                                                \
59  EXPECT_TRUE(root->needs_push_properties());                                  \
60  EXPECT_FALSE(child->needs_push_properties());                                \
61  EXPECT_FALSE(grand_child->needs_push_properties());                          \
62  EXPECT_TRUE(root->LayerPropertyChanged());                                   \
63  EXPECT_FALSE(child->LayerPropertyChanged());                                 \
64  EXPECT_FALSE(grand_child->LayerPropertyChanged());
65
66#define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test)                      \
67  root->ResetAllChangeTrackingForSubtree();                                    \
68  host_impl.ForcePrepareToDraw();                                              \
69  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());       \
70  code_to_test;                                                                \
71  EXPECT_TRUE(host_impl.active_tree()->needs_update_draw_properties());
72
73#define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test)                   \
74  root->ResetAllChangeTrackingForSubtree();                                    \
75  host_impl.ForcePrepareToDraw();                                              \
76  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());       \
77  code_to_test;                                                                \
78  EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties());
79
80TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) {
81  //
82  // This test checks that layerPropertyChanged() has the correct behavior.
83  //
84
85  // The constructor on this will fake that we are on the correct thread.
86  // Create a simple LayerImpl tree:
87  FakeImplProxy proxy;
88  TestSharedBitmapManager shared_bitmap_manager;
89  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
90  EXPECT_TRUE(host_impl.InitializeRenderer(
91      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
92  scoped_ptr<LayerImpl> root_clip =
93      LayerImpl::Create(host_impl.active_tree(), 1);
94  scoped_ptr<LayerImpl> root_ptr =
95      LayerImpl::Create(host_impl.active_tree(), 2);
96  LayerImpl* root = root_ptr.get();
97  root_clip->AddChild(root_ptr.Pass());
98  scoped_ptr<LayerImpl> scroll_parent =
99      LayerImpl::Create(host_impl.active_tree(), 3);
100  LayerImpl* scroll_child = LayerImpl::Create(host_impl.active_tree(), 4).get();
101  std::set<LayerImpl*>* scroll_children = new std::set<LayerImpl*>();
102  scroll_children->insert(scroll_child);
103  scroll_children->insert(root);
104
105  scoped_ptr<LayerImpl> clip_parent =
106      LayerImpl::Create(host_impl.active_tree(), 5);
107  LayerImpl* clip_child = LayerImpl::Create(host_impl.active_tree(), 6).get();
108  std::set<LayerImpl*>* clip_children = new std::set<LayerImpl*>();
109  clip_children->insert(clip_child);
110  clip_children->insert(root);
111
112  root->AddChild(LayerImpl::Create(host_impl.active_tree(), 7));
113  LayerImpl* child = root->children()[0];
114  child->AddChild(LayerImpl::Create(host_impl.active_tree(), 8));
115  LayerImpl* grand_child = child->children()[0];
116
117  root->SetScrollClipLayer(root_clip->id());
118
119  // Adding children is an internal operation and should not mark layers as
120  // changed.
121  EXPECT_FALSE(root->LayerPropertyChanged());
122  EXPECT_FALSE(child->LayerPropertyChanged());
123  EXPECT_FALSE(grand_child->LayerPropertyChanged());
124
125  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
126  gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f);
127  float arbitrary_number = 0.352f;
128  gfx::Size arbitrary_size = gfx::Size(111, 222);
129  gfx::Point arbitrary_point = gfx::Point(333, 444);
130  gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
131  gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
132  gfx::RectF arbitrary_rect_f =
133      gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f));
134  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
135  gfx::Transform arbitrary_transform;
136  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
137  FilterOperations arbitrary_filters;
138  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
139  SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode;
140
141  // These properties are internal, and should not be considered "change" when
142  // they are used.
143  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
144      root->SetUpdateRect(arbitrary_rect_f));
145  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size));
146
147  // Changing these properties affects the entire subtree of layers.
148  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
149      root->SetTransformOrigin(arbitrary_point_3f));
150  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(arbitrary_filters));
151  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetFilters(FilterOperations()));
152  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
153      root->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 9)));
154  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetMasksToBounds(true));
155  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetContentsOpaque(true));
156  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
157      root->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 10)));
158  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetPosition(arbitrary_point_f));
159  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetShouldFlattenTransform(false));
160  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->Set3dSortingContextId(1));
161  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(
162      root->SetDoubleSided(false));  // constructor initializes it to "true".
163  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->ScrollBy(arbitrary_vector2d));
164  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetScrollDelta(gfx::Vector2d()));
165  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetScrollOffset(arbitrary_vector2d));
166  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetHideLayerAndSubtree(true));
167  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetOpacity(arbitrary_number));
168  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBlendMode(arbitrary_blend_mode));
169  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetTransform(arbitrary_transform));
170
171  // Changing these properties only affects the layer itself.
172  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetContentBounds(arbitrary_size));
173  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
174      root->SetContentsScale(arbitrary_number, arbitrary_number));
175  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true));
176  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
177      root->SetBackgroundColor(arbitrary_color));
178  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(
179      root->SetBackgroundFilters(arbitrary_filters));
180
181  // Special case: check that SetBounds changes behavior depending on
182  // masksToBounds.
183  root->SetMasksToBounds(false);
184  EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(gfx::Size(135, 246)));
185  root->SetMasksToBounds(true);
186  // Should be a different size than previous call, to ensure it marks tree
187  // changed.
188  EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->SetBounds(arbitrary_size));
189
190  // Changing this property does not cause the layer to be marked as changed
191  // but does cause the layer to need to push properties.
192  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
193      root->SetIsRootForIsolatedGroup(true));
194
195  // Changing these properties should cause the layer to need to push properties
196  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
197      root->SetScrollParent(scroll_parent.get()));
198  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
199      root->SetScrollChildren(scroll_children));
200  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
201      root->SetClipParent(clip_parent.get()));
202  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
203      root->SetClipChildren(clip_children));
204  EXECUTE_AND_VERIFY_NEEDS_PUSH_PROPERTIES_AND_SUBTREE_DID_NOT_CHANGE(
205      root->SetNumDescendantsThatDrawContent(10));
206
207  // After setting all these properties already, setting to the exact same
208  // values again should not cause any change.
209  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
210      root->SetTransformOrigin(arbitrary_point_3f));
211  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetMasksToBounds(true));
212  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
213      root->SetPosition(arbitrary_point_f));
214  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
215      root->SetShouldFlattenTransform(false));
216  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->Set3dSortingContextId(1));
217  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
218      root->SetTransform(arbitrary_transform));
219  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
220      root->SetDoubleSided(false));  // constructor initializes it to "true".
221  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
222      root->SetScrollDelta(gfx::Vector2d()));
223  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
224      root->SetScrollOffset(arbitrary_vector2d));
225  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
226      root->SetContentBounds(arbitrary_size));
227  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
228      root->SetContentsScale(arbitrary_number, arbitrary_number));
229  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetContentsOpaque(true));
230  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetOpacity(arbitrary_number));
231  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
232      root->SetBlendMode(arbitrary_blend_mode));
233  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
234      root->SetIsRootForIsolatedGroup(true));
235  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetDrawsContent(true));
236  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(arbitrary_size));
237  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
238      root->SetScrollParent(scroll_parent.get()));
239  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
240      root->SetScrollChildren(scroll_children));
241  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
242      root->SetClipParent(clip_parent.get()));
243  EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
244      root->SetClipChildren(clip_children));
245}
246
247TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) {
248  FakeImplProxy proxy;
249  TestSharedBitmapManager shared_bitmap_manager;
250  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
251  EXPECT_TRUE(host_impl.InitializeRenderer(
252      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
253  host_impl.active_tree()->SetRootLayer(
254      LayerImpl::Create(host_impl.active_tree(), 1));
255  LayerImpl* root = host_impl.active_tree()->root_layer();
256  scoped_ptr<LayerImpl> layer_ptr =
257      LayerImpl::Create(host_impl.active_tree(), 2);
258  LayerImpl* layer = layer_ptr.get();
259  root->AddChild(layer_ptr.Pass());
260  layer->SetScrollClipLayer(root->id());
261  DCHECK(host_impl.CanDraw());
262
263  gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f);
264  float arbitrary_number = 0.352f;
265  gfx::Size arbitrary_size = gfx::Size(111, 222);
266  gfx::Point arbitrary_point = gfx::Point(333, 444);
267  gfx::Vector2d arbitrary_vector2d = gfx::Vector2d(111, 222);
268  gfx::Size large_size = gfx::Size(1000, 1000);
269  gfx::Rect arbitrary_rect = gfx::Rect(arbitrary_point, arbitrary_size);
270  gfx::RectF arbitrary_rect_f =
271      gfx::RectF(arbitrary_point_f, gfx::SizeF(1.234f, 5.678f));
272  SkColor arbitrary_color = SkColorSetRGB(10, 20, 30);
273  gfx::Transform arbitrary_transform;
274  arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f);
275  FilterOperations arbitrary_filters;
276  arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
277  SkXfermode::Mode arbitrary_blend_mode = SkXfermode::kMultiply_Mode;
278
279  // Related filter functions.
280  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
281  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
282  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(FilterOperations()));
283  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
284
285  // Related scrolling functions.
286  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
287  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size));
288  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d));
289  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d()));
290  layer->SetScrollDelta(gfx::Vector2d(0, 0));
291  host_impl.ForcePrepareToDraw();
292  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
293      layer->SetScrollDelta(arbitrary_vector2d));
294  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
295      layer->SetScrollDelta(arbitrary_vector2d));
296  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
297      layer->SetScrollOffset(arbitrary_vector2d));
298  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
299      layer->SetScrollOffset(arbitrary_vector2d));
300
301  // Unrelated functions, always set to new values, always set needs update.
302  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
303      layer->SetMaskLayer(LayerImpl::Create(host_impl.active_tree(), 4)));
304  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
305  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
306  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
307      layer->SetReplicaLayer(LayerImpl::Create(host_impl.active_tree(), 5)));
308  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
309  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetShouldFlattenTransform(false));
310  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1));
311
312  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
313      layer->SetDoubleSided(false));  // constructor initializes it to "true".
314  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentBounds(arbitrary_size));
315  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
316      layer->SetContentsScale(arbitrary_number, arbitrary_number));
317  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
318  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
319      layer->SetBackgroundColor(arbitrary_color));
320  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
321      layer->SetBackgroundFilters(arbitrary_filters));
322  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
323  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
324      layer->SetBlendMode(arbitrary_blend_mode));
325  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetTransform(arbitrary_transform));
326  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));
327
328  // Unrelated functions, set to the same values, no needs update.
329  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
330      layer->SetIsRootForIsolatedGroup(true));
331  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetFilters(arbitrary_filters));
332  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true));
333  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true));
334  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetPosition(arbitrary_point_f));
335  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->Set3dSortingContextId(1));
336  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
337      layer->SetDoubleSided(false));  // constructor initializes it to "true".
338  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
339      layer->SetContentBounds(arbitrary_size));
340  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
341      layer->SetContentsScale(arbitrary_number, arbitrary_number));
342  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true));
343  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
344      layer->SetBackgroundColor(arbitrary_color));
345  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
346      layer->SetBackgroundFilters(arbitrary_filters));
347  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetOpacity(arbitrary_number));
348  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
349      layer->SetBlendMode(arbitrary_blend_mode));
350  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
351      layer->SetIsRootForIsolatedGroup(true));
352  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
353      layer->SetTransform(arbitrary_transform));
354  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size));
355}
356
357TEST(LayerImplTest, SafeOpaqueBackgroundColor) {
358  FakeImplProxy proxy;
359  TestSharedBitmapManager shared_bitmap_manager;
360  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
361  EXPECT_TRUE(host_impl.InitializeRenderer(
362      FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
363  scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
364
365  for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) {
366    for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) {
367      for (int host_opaque = 0; host_opaque < 2; ++host_opaque) {
368        layer->SetContentsOpaque(!!contents_opaque);
369        layer->SetBackgroundColor(layer_opaque ? SK_ColorRED
370                                               : SK_ColorTRANSPARENT);
371        host_impl.active_tree()->set_background_color(
372            host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT);
373
374        SkColor safe_color = layer->SafeOpaqueBackgroundColor();
375        if (contents_opaque) {
376          EXPECT_EQ(SkColorGetA(safe_color), 255u)
377              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
378              << host_opaque << "\n";
379        } else {
380          EXPECT_NE(SkColorGetA(safe_color), 255u)
381              << "Flags: " << contents_opaque << ", " << layer_opaque << ", "
382              << host_opaque << "\n";
383        }
384      }
385    }
386  }
387}
388
389TEST(LayerImplTest, TransformInvertibility) {
390  FakeImplProxy proxy;
391  TestSharedBitmapManager shared_bitmap_manager;
392  FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
393
394  scoped_ptr<LayerImpl> layer = LayerImpl::Create(host_impl.active_tree(), 1);
395  EXPECT_TRUE(layer->transform().IsInvertible());
396  EXPECT_TRUE(layer->transform_is_invertible());
397
398  gfx::Transform transform;
399  transform.Scale3d(
400      SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0));
401  layer->SetTransform(transform);
402  EXPECT_FALSE(layer->transform().IsInvertible());
403  EXPECT_FALSE(layer->transform_is_invertible());
404
405  transform.MakeIdentity();
406  transform.ApplyPerspectiveDepth(SkDoubleToMScalar(100.0));
407  transform.RotateAboutZAxis(75.0);
408  transform.RotateAboutXAxis(32.2);
409  transform.RotateAboutZAxis(-75.0);
410  transform.Translate3d(SkDoubleToMScalar(50.5),
411                        SkDoubleToMScalar(42.42),
412                        SkDoubleToMScalar(-100.25));
413
414  layer->SetTransform(transform);
415  EXPECT_TRUE(layer->transform().IsInvertible());
416  EXPECT_TRUE(layer->transform_is_invertible());
417}
418
419class LayerImplScrollTest : public testing::Test {
420 public:
421  LayerImplScrollTest()
422      : host_impl_(&proxy_, &shared_bitmap_manager_), root_id_(7) {
423    host_impl_.active_tree()->SetRootLayer(
424        LayerImpl::Create(host_impl_.active_tree(), root_id_));
425    host_impl_.active_tree()->root_layer()->AddChild(
426        LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1));
427    layer()->SetScrollClipLayer(root_id_);
428    // Set the max scroll offset by noting that the root layer has bounds (1,1),
429    // thus whatever bounds are set for the layer will be the max scroll
430    // offset plus 1 in each direction.
431    host_impl_.active_tree()->root_layer()->SetBounds(gfx::Size(1, 1));
432    gfx::Vector2d max_scroll_offset(51, 81);
433    layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y()));
434  }
435
436  LayerImpl* layer() {
437    return host_impl_.active_tree()->root_layer()->children()[0];
438  }
439
440  LayerTreeHostImpl& host_impl() { return host_impl_; }
441
442  LayerTreeImpl* tree() { return host_impl_.active_tree(); }
443
444 private:
445  FakeImplProxy proxy_;
446  TestSharedBitmapManager shared_bitmap_manager_;
447  FakeLayerTreeHostImpl host_impl_;
448  int root_id_;
449};
450
451TEST_F(LayerImplScrollTest, ScrollByWithZeroOffset) {
452  // Test that LayerImpl::ScrollBy only affects ScrollDelta and total scroll
453  // offset is bounded by the range [0, max scroll offset].
454
455  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->TotalScrollOffset());
456  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
457  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());
458
459  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
460  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
461
462  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->TotalScrollOffset());
463  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
464
465  layer()->ScrollBy(gfx::Vector2dF(100, -100));
466  EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->TotalScrollOffset());
467
468  EXPECT_VECTOR_EQ(layer()->ScrollDelta(), layer()->TotalScrollOffset());
469  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->scroll_offset());
470}
471
472TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) {
473  gfx::Vector2d scroll_offset(10, 5);
474  layer()->SetScrollOffset(scroll_offset);
475
476  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
477  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
478  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());
479
480  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
481  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
482
483  EXPECT_VECTOR_EQ(layer()->ScrollDelta() + scroll_offset,
484                   layer()->TotalScrollOffset());
485  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
486
487  layer()->ScrollBy(gfx::Vector2dF(100, -100));
488  EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), layer()->TotalScrollOffset());
489
490  EXPECT_VECTOR_EQ(layer()->ScrollDelta() + scroll_offset,
491                   layer()->TotalScrollOffset());
492  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
493}
494
495class ScrollDelegateIgnore : public LayerImpl::ScrollOffsetDelegate {
496 public:
497  virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_value) OVERRIDE {}
498  virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
499    return fixed_offset_;
500  }
501  virtual bool IsExternalFlingActive() const OVERRIDE { return false; }
502
503  void set_fixed_offset(const gfx::Vector2dF& fixed_offset) {
504    fixed_offset_ = fixed_offset;
505  }
506
507 private:
508  gfx::Vector2dF fixed_offset_;
509};
510
511TEST_F(LayerImplScrollTest, ScrollByWithIgnoringDelegate) {
512  gfx::Vector2d scroll_offset(10, 5);
513  layer()->SetScrollOffset(scroll_offset);
514
515  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
516  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
517  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());
518
519  ScrollDelegateIgnore delegate;
520  gfx::Vector2dF fixed_offset(32, 12);
521  delegate.set_fixed_offset(fixed_offset);
522  layer()->SetScrollOffsetDelegate(&delegate);
523
524  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
525  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
526
527  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
528
529  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
530  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
531
532  layer()->SetScrollOffsetDelegate(NULL);
533
534  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
535  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
536
537  gfx::Vector2dF scroll_delta(1, 1);
538  layer()->ScrollBy(scroll_delta);
539
540  EXPECT_VECTOR_EQ(fixed_offset + scroll_delta, layer()->TotalScrollOffset());
541  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
542}
543
544class ScrollDelegateAccept : public LayerImpl::ScrollOffsetDelegate {
545 public:
546  virtual void SetTotalScrollOffset(const gfx::Vector2dF& new_value) OVERRIDE {
547    current_offset_ = new_value;
548  }
549  virtual gfx::Vector2dF GetTotalScrollOffset() OVERRIDE {
550    return current_offset_;
551  }
552  virtual bool IsExternalFlingActive() const OVERRIDE { return false; }
553
554 private:
555  gfx::Vector2dF current_offset_;
556};
557
558TEST_F(LayerImplScrollTest, ScrollByWithAcceptingDelegate) {
559  gfx::Vector2d scroll_offset(10, 5);
560  layer()->SetScrollOffset(scroll_offset);
561
562  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
563  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
564  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());
565
566  ScrollDelegateAccept delegate;
567  layer()->SetScrollOffsetDelegate(&delegate);
568
569  EXPECT_VECTOR_EQ(scroll_offset, layer()->TotalScrollOffset());
570  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
571  EXPECT_VECTOR_EQ(gfx::Vector2dF(), layer()->ScrollDelta());
572
573  layer()->ScrollBy(gfx::Vector2dF(-100, 100));
574
575  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
576  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
577
578  layer()->SetScrollOffsetDelegate(NULL);
579
580  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), layer()->TotalScrollOffset());
581  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
582
583  gfx::Vector2dF scroll_delta(1, 1);
584  layer()->ScrollBy(scroll_delta);
585
586  EXPECT_VECTOR_EQ(gfx::Vector2dF(1, 80), layer()->TotalScrollOffset());
587  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
588}
589
590TEST_F(LayerImplScrollTest, ApplySentScrollsNoDelegate) {
591  gfx::Vector2d scroll_offset(10, 5);
592  gfx::Vector2dF scroll_delta(20.5f, 8.5f);
593  gfx::Vector2d sent_scroll_delta(12, -3);
594
595  layer()->SetScrollOffset(scroll_offset);
596  layer()->ScrollBy(scroll_delta);
597  layer()->SetSentScrollDelta(sent_scroll_delta);
598
599  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, layer()->TotalScrollOffset());
600  EXPECT_VECTOR_EQ(scroll_delta, layer()->ScrollDelta());
601  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
602  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());
603
604  layer()->ApplySentScrollDeltasFromAbortedCommit();
605
606  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, layer()->TotalScrollOffset());
607  EXPECT_VECTOR_EQ(scroll_delta - sent_scroll_delta, layer()->ScrollDelta());
608  EXPECT_VECTOR_EQ(scroll_offset + sent_scroll_delta, layer()->scroll_offset());
609  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
610}
611
612TEST_F(LayerImplScrollTest, ApplySentScrollsWithIgnoringDelegate) {
613  gfx::Vector2d scroll_offset(10, 5);
614  gfx::Vector2d sent_scroll_delta(12, -3);
615  gfx::Vector2dF fixed_offset(32, 12);
616
617  layer()->SetScrollOffset(scroll_offset);
618  ScrollDelegateIgnore delegate;
619  delegate.set_fixed_offset(fixed_offset);
620  layer()->SetScrollOffsetDelegate(&delegate);
621  layer()->SetSentScrollDelta(sent_scroll_delta);
622
623  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
624  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
625  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());
626
627  layer()->ApplySentScrollDeltasFromAbortedCommit();
628
629  EXPECT_VECTOR_EQ(fixed_offset, layer()->TotalScrollOffset());
630  EXPECT_VECTOR_EQ(scroll_offset + sent_scroll_delta, layer()->scroll_offset());
631  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
632}
633
634TEST_F(LayerImplScrollTest, ApplySentScrollsWithAcceptingDelegate) {
635  gfx::Vector2d scroll_offset(10, 5);
636  gfx::Vector2d sent_scroll_delta(12, -3);
637  gfx::Vector2dF scroll_delta(20.5f, 8.5f);
638
639  layer()->SetScrollOffset(scroll_offset);
640  ScrollDelegateAccept delegate;
641  layer()->SetScrollOffsetDelegate(&delegate);
642  layer()->ScrollBy(scroll_delta);
643  layer()->SetSentScrollDelta(sent_scroll_delta);
644
645  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, layer()->TotalScrollOffset());
646  EXPECT_VECTOR_EQ(scroll_offset, layer()->scroll_offset());
647  EXPECT_VECTOR_EQ(sent_scroll_delta, layer()->sent_scroll_delta());
648
649  layer()->ApplySentScrollDeltasFromAbortedCommit();
650
651  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, layer()->TotalScrollOffset());
652  EXPECT_VECTOR_EQ(scroll_offset + sent_scroll_delta, layer()->scroll_offset());
653  EXPECT_VECTOR_EQ(gfx::Vector2d(), layer()->sent_scroll_delta());
654}
655
656// The user-scrollability breaks for zoomed-in pages. So disable this.
657// http://crbug.com/322223
658TEST_F(LayerImplScrollTest, DISABLED_ScrollUserUnscrollableLayer) {
659  gfx::Vector2d scroll_offset(10, 5);
660  gfx::Vector2dF scroll_delta(20.5f, 8.5f);
661
662  layer()->set_user_scrollable_vertical(false);
663  layer()->SetScrollOffset(scroll_offset);
664  gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);
665
666  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 8.5f), unscrolled);
667  EXPECT_VECTOR_EQ(gfx::Vector2dF(30.5f, 5), layer()->TotalScrollOffset());
668}
669
670TEST_F(LayerImplScrollTest, PushPropertiesToMirrorsTotalScrollOffset) {
671  gfx::Vector2d scroll_offset(10, 5);
672  gfx::Vector2dF scroll_delta(12, 18);
673
674  host_impl().CreatePendingTree();
675
676  layer()->SetScrollOffset(scroll_offset);
677  gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta);
678
679  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), unscrolled);
680  EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->TotalScrollOffset());
681
682  layer()->SetSentScrollDelta(gfx::ToFlooredVector2d(scroll_delta));
683
684  scoped_ptr<LayerImpl> pending_layer =
685      LayerImpl::Create(host_impl().sync_tree(), layer()->id());
686  pending_layer->SetScrollOffset(
687      gfx::ToFlooredVector2d(layer()->TotalScrollOffset()));
688
689  pending_layer->PushPropertiesTo(layer());
690
691  EXPECT_VECTOR_EQ(gfx::Vector2dF(22, 23), layer()->TotalScrollOffset());
692  EXPECT_VECTOR_EQ(layer()->TotalScrollOffset(),
693                   pending_layer->TotalScrollOffset());
694}
695
696TEST_F(LayerImplScrollTest, SetNewScrollbarParameters) {
697  gfx::Vector2d scroll_offset(10, 5);
698  layer()->SetScrollOffset(scroll_offset);
699
700  scoped_ptr<PaintedScrollbarLayerImpl> vertical_scrollbar(
701      PaintedScrollbarLayerImpl::Create(tree(), 100, VERTICAL));
702  vertical_scrollbar->SetScrollLayerAndClipLayerByIds(
703      layer()->id(), tree()->root_layer()->id());
704
705  int expected_vertical_maximum =
706      layer()->bounds().height() - tree()->root_layer()->bounds().height();
707  EXPECT_EQ(expected_vertical_maximum, vertical_scrollbar->maximum());
708  EXPECT_EQ(scroll_offset.y(), vertical_scrollbar->current_pos());
709
710  scoped_ptr<PaintedScrollbarLayerImpl> horizontal_scrollbar(
711      PaintedScrollbarLayerImpl::Create(tree(), 101, HORIZONTAL));
712  horizontal_scrollbar->SetScrollLayerAndClipLayerByIds(
713      layer()->id(), tree()->root_layer()->id());
714
715  int expected_horizontal_maximum =
716      layer()->bounds().width() - tree()->root_layer()->bounds().width();
717  EXPECT_EQ(expected_horizontal_maximum, horizontal_scrollbar->maximum());
718  EXPECT_EQ(scroll_offset.x(), horizontal_scrollbar->current_pos());
719}
720
721}  // namespace
722}  // namespace cc
723