1 // Copyright 2019 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/test/property_tree_test_utils.h"
6 
7 #include "cc/layers/picture_layer.h"
8 #include "cc/layers/picture_layer_impl.h"
9 #include "cc/trees/clip_node.h"
10 #include "cc/trees/effect_node.h"
11 #include "cc/trees/layer_tree_host.h"
12 #include "cc/trees/layer_tree_impl.h"
13 #include "cc/trees/property_tree.h"
14 #include "cc/trees/scroll_node.h"
15 #include "cc/trees/transform_node.h"
16 
17 namespace cc {
18 
19 namespace {
20 
21 template <typename LayerType>
SetupRootPropertiesInternal(LayerType * root)22 void SetupRootPropertiesInternal(LayerType* root) {
23   root->set_property_tree_sequence_number(
24       GetPropertyTrees(root)->sequence_number);
25   root->SetElementId(LayerIdToElementIdForTesting(root->id()));
26 
27   auto& root_transform_node =
28       CreateTransformNode(root, TransformTree::kRootNodeId);
29   DCHECK_EQ(root_transform_node.id, TransformTree::kContentsRootNodeId);
30 
31   auto& root_clip_node = CreateClipNode(root, ClipTree::kRootNodeId);
32   DCHECK_EQ(root_clip_node.id, ClipTree::kViewportNodeId);
33   root_clip_node.clip = gfx::RectF(gfx::SizeF(root->bounds()));
34   // Root clip is in the real root transform space instead of the root layer's
35   // transform space.
36   root_clip_node.transform_id = TransformTree::kRootNodeId;
37 
38   auto& root_effect_node = CreateEffectNode(root, EffectTree::kRootNodeId);
39   DCHECK_EQ(root_effect_node.id, EffectTree::kContentsRootNodeId);
40   root_effect_node.render_surface_reason = RenderSurfaceReason::kRoot;
41   // Root effect is in the real root transform space instead of the root layer's
42   // transform space.
43   root_effect_node.transform_id = TransformTree::kRootNodeId;
44 
45   auto& root_scroll_node =
46       CreateScrollNode(root, gfx::Size(), ScrollTree::kRootNodeId);
47   DCHECK_EQ(root_scroll_node.id, ScrollTree::kSecondaryRootNodeId);
48 }
49 
50 template <typename LayerType>
CopyPropertiesInternal(const LayerType * from,LayerType * to)51 void CopyPropertiesInternal(const LayerType* from, LayerType* to) {
52   to->SetTransformTreeIndex(from->transform_tree_index());
53   to->SetClipTreeIndex(from->clip_tree_index());
54   to->SetEffectTreeIndex(from->effect_tree_index());
55   to->SetScrollTreeIndex(from->scroll_tree_index());
56 }
57 
58 // We use a macro instead of a function to avoid |default_id| (which is
59 // |layer->xxx_tree_index()|) from being evaluated when it's not used because
60 // |layer| may be null when |id| is valid.
61 #define ID_OR_DEFAULT(id, default_id) \
62   ((id) == TransformTree::kInvalidNodeId ? (default_id) : (id))
63 
64 template <typename LayerType>
CreateTransformNodeInternal(LayerType * layer,PropertyTrees * property_trees,int parent_id)65 TransformNode& CreateTransformNodeInternal(LayerType* layer,
66                                            PropertyTrees* property_trees,
67                                            int parent_id) {
68   auto& transform_tree = property_trees->transform_tree;
69   int id = transform_tree.Insert(
70       TransformNode(), ID_OR_DEFAULT(parent_id, layer->transform_tree_index()));
71   auto* node = transform_tree.Node(id);
72   if (layer) {
73     layer->SetTransformTreeIndex(id);
74     layer->SetHasTransformNode(true);
75     node->element_id = layer->element_id();
76     if (node->element_id) {
77       property_trees->element_id_to_transform_node_index[node->element_id] =
78           node->id;
79     }
80   }
81   if (const auto* parent_node = transform_tree.Node(node->parent_id)) {
82     node->in_subtree_of_page_scale_layer =
83         parent_node->in_subtree_of_page_scale_layer;
84   }
85   transform_tree.set_needs_update(true);
86   return *node;
87 }
88 
89 template <typename LayerType>
CreateClipNodeInternal(LayerType * layer,PropertyTrees * property_trees,int parent_id,int transform_id=TransformTree::kInvalidNodeId)90 ClipNode& CreateClipNodeInternal(
91     LayerType* layer,
92     PropertyTrees* property_trees,
93     int parent_id,
94     int transform_id = TransformTree::kInvalidNodeId) {
95   auto& clip_tree = property_trees->clip_tree;
96   int id = clip_tree.Insert(ClipNode(),
97                             ID_OR_DEFAULT(parent_id, layer->clip_tree_index()));
98   auto* node = clip_tree.Node(id);
99   node->clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP;
100   node->transform_id =
101       ID_OR_DEFAULT(transform_id, layer->transform_tree_index());
102   if (layer) {
103     layer->SetClipTreeIndex(id);
104     node->clip = gfx::RectF(
105         gfx::PointAtOffsetFromOrigin(layer->offset_to_transform_parent()),
106         gfx::SizeF(layer->bounds()));
107   }
108   clip_tree.set_needs_update(true);
109   return *node;
110 }
111 
112 template <typename LayerType>
CreateEffectNodeInternal(LayerType * layer,PropertyTrees * property_trees,int parent_id,int transform_id=TransformTree::kInvalidNodeId,int clip_id=ClipTree::kInvalidNodeId)113 EffectNode& CreateEffectNodeInternal(
114     LayerType* layer,
115     PropertyTrees* property_trees,
116     int parent_id,
117     int transform_id = TransformTree::kInvalidNodeId,
118     int clip_id = ClipTree::kInvalidNodeId) {
119   auto& effect_tree = property_trees->effect_tree;
120   int id = effect_tree.Insert(
121       EffectNode(), ID_OR_DEFAULT(parent_id, layer->effect_tree_index()));
122   auto* node = effect_tree.Node(id);
123   if (layer) {
124     layer->SetEffectTreeIndex(id);
125     node->stable_id = layer->id();
126     if (layer->element_id()) {
127       property_trees->element_id_to_effect_node_index[layer->element_id()] =
128           node->id;
129     }
130   }
131   node->transform_id =
132       ID_OR_DEFAULT(transform_id, layer->transform_tree_index());
133   node->clip_id = ID_OR_DEFAULT(clip_id, layer->clip_tree_index());
134   effect_tree.set_needs_update(true);
135   return *node;
136 }
137 
138 template <typename LayerType>
CreateScrollNodeInternal(LayerType * layer,const gfx::Size & scroll_container_bounds,int parent_id)139 ScrollNode& CreateScrollNodeInternal(LayerType* layer,
140                                      const gfx::Size& scroll_container_bounds,
141                                      int parent_id) {
142   auto* property_trees = GetPropertyTrees(layer);
143   auto& scroll_tree = property_trees->scroll_tree;
144   int id = scroll_tree.Insert(
145       ScrollNode(), ID_OR_DEFAULT(parent_id, layer->scroll_tree_index()));
146   layer->SetScrollTreeIndex(id);
147   auto* node = scroll_tree.Node(id);
148   node->element_id = layer->element_id();
149   if (node->element_id) {
150     property_trees->element_id_to_scroll_node_index[node->element_id] =
151         node->id;
152   }
153   node->bounds = layer->bounds();
154   node->container_bounds = scroll_container_bounds;
155   node->scrollable = !scroll_container_bounds.IsEmpty();
156   node->user_scrollable_horizontal = true;
157   node->user_scrollable_vertical = true;
158   node->is_composited = true;
159 
160   DCHECK(layer->has_transform_node());
161   node->transform_id = layer->transform_tree_index();
162   auto* transform_node = GetTransformNode(layer);
163   transform_node->should_be_snapped = true;
164   transform_node->scrolls = true;
165 
166   scroll_tree.SetScrollOffset(layer->element_id(), gfx::ScrollOffset());
167   return *node;
168 }
169 
170 template <typename LayerType, typename MaskLayerType>
SetupMaskPropertiesInternal(LayerType * masked_layer,MaskLayerType * mask_layer)171 void SetupMaskPropertiesInternal(LayerType* masked_layer,
172                                  MaskLayerType* mask_layer) {
173   if (!GetEffectNode(masked_layer)->backdrop_filters.IsEmpty())
174     mask_layer->SetIsBackdropFilterMask(true);
175   mask_layer->SetBounds(masked_layer->bounds());
176   auto* masked_effect = GetEffectNode(masked_layer);
177   masked_effect->render_surface_reason = RenderSurfaceReason::kMask;
178   masked_effect->has_masking_child = true;
179   if (!masked_effect->backdrop_filters.IsEmpty()) {
180     if (!mask_layer->element_id())
181       mask_layer->SetElementId(LayerIdToElementIdForTesting(mask_layer->id()));
182     masked_effect->backdrop_mask_element_id = mask_layer->element_id();
183   }
184 
185   CopyProperties(masked_layer, mask_layer);
186   mask_layer->SetOffsetToTransformParent(
187       masked_layer->offset_to_transform_parent());
188   CreateEffectNode(mask_layer).blend_mode = SkBlendMode::kDstIn;
189 }
190 
191 template <typename LayerType>
SetScrollOffsetInternal(LayerType * layer,const gfx::ScrollOffset & scroll_offset)192 void SetScrollOffsetInternal(LayerType* layer,
193                              const gfx::ScrollOffset& scroll_offset) {
194   DCHECK(layer->has_transform_node());
195   auto* transform_node = GetTransformNode(layer);
196   transform_node->scroll_offset = scroll_offset;
197   SetLocalTransformChanged(layer);
198   GetPropertyTrees(layer)->scroll_tree.SetScrollOffset(layer->element_id(),
199                                                        scroll_offset);
200 }
201 
202 // TODO(wangxianzhu): Viewport properties can exist without layers, but for now
203 // it's more convenient to create properties based on layers.
204 template <typename LayerType>
SetupViewportProperties(LayerType * root,LayerType * inner_viewport_scroll_layer,LayerType * outer_viewport_scroll_layer)205 LayerTreeHost::ViewportPropertyIds SetupViewportProperties(
206     LayerType* root,
207     LayerType* inner_viewport_scroll_layer,
208     LayerType* outer_viewport_scroll_layer) {
209   LayerTreeHost::ViewportPropertyIds viewport_property_ids;
210   auto* property_trees = GetPropertyTrees(root);
211 
212   viewport_property_ids.overscroll_elasticity_transform =
213       CreateTransformNode(property_trees, root->transform_tree_index()).id;
214 
215   auto& page_scale_transform = CreateTransformNode(
216       property_trees, viewport_property_ids.overscroll_elasticity_transform);
217   page_scale_transform.in_subtree_of_page_scale_layer = true;
218   viewport_property_ids.page_scale_transform = page_scale_transform.id;
219 
220   CopyProperties(root, inner_viewport_scroll_layer);
221   CreateTransformNode(inner_viewport_scroll_layer,
222                       viewport_property_ids.page_scale_transform);
223   auto& inner_scroll =
224       CreateScrollNode(inner_viewport_scroll_layer, root->bounds());
225   inner_scroll.scrolls_inner_viewport = true;
226   inner_scroll.max_scroll_offset_affected_by_page_scale = true;
227   viewport_property_ids.inner_scroll = inner_scroll.id;
228 
229   auto& outer_clip = CreateClipNode(property_trees, root->clip_tree_index(),
230                                     inner_scroll.transform_id);
231   outer_clip.clip =
232       gfx::RectF(gfx::SizeF(inner_viewport_scroll_layer->bounds()));
233   viewport_property_ids.outer_clip = outer_clip.id;
234 
235   CopyProperties(inner_viewport_scroll_layer, outer_viewport_scroll_layer);
236   CreateTransformNode(outer_viewport_scroll_layer);
237   auto& outer_scroll = CreateScrollNode(outer_viewport_scroll_layer,
238                                         inner_viewport_scroll_layer->bounds());
239   outer_scroll.scrolls_outer_viewport = true;
240   viewport_property_ids.outer_scroll = outer_scroll.id;
241 
242   return viewport_property_ids;
243 }
244 
245 }  // anonymous namespace
246 
SetupRootProperties(Layer * root)247 void SetupRootProperties(Layer* root) {
248   SetupRootPropertiesInternal(root);
249 }
250 
SetupRootProperties(LayerImpl * root)251 void SetupRootProperties(LayerImpl* root) {
252   SetupRootPropertiesInternal(root);
253 }
254 
CopyProperties(const Layer * from,Layer * to)255 void CopyProperties(const Layer* from, Layer* to) {
256   DCHECK(from->layer_tree_host()->IsUsingLayerLists());
257   to->SetLayerTreeHost(from->layer_tree_host());
258   to->set_property_tree_sequence_number(from->property_tree_sequence_number());
259   CopyPropertiesInternal(from, to);
260 }
261 
CopyProperties(const LayerImpl * from,LayerImpl * to)262 void CopyProperties(const LayerImpl* from, LayerImpl* to) {
263   CopyPropertiesInternal(from, to);
264 }
265 
CreateTransformNode(Layer * layer,int parent_id)266 TransformNode& CreateTransformNode(Layer* layer, int parent_id) {
267   DCHECK(layer->layer_tree_host()->IsUsingLayerLists());
268   return CreateTransformNodeInternal(layer, GetPropertyTrees(layer), parent_id);
269 }
270 
CreateTransformNode(LayerImpl * layer,int parent_id)271 TransformNode& CreateTransformNode(LayerImpl* layer, int parent_id) {
272   return CreateTransformNodeInternal(layer, GetPropertyTrees(layer), parent_id);
273 }
274 
CreateTransformNode(PropertyTrees * property_trees,int parent_id)275 TransformNode& CreateTransformNode(PropertyTrees* property_trees,
276                                    int parent_id) {
277   return CreateTransformNodeInternal<Layer>(nullptr, property_trees, parent_id);
278 }
279 
CreateClipNode(Layer * layer,int parent_id)280 ClipNode& CreateClipNode(Layer* layer, int parent_id) {
281   DCHECK(layer->layer_tree_host()->IsUsingLayerLists());
282   return CreateClipNodeInternal(layer, GetPropertyTrees(layer), parent_id);
283 }
284 
CreateClipNode(LayerImpl * layer,int parent_id)285 ClipNode& CreateClipNode(LayerImpl* layer, int parent_id) {
286   return CreateClipNodeInternal(layer, GetPropertyTrees(layer), parent_id);
287 }
288 
CreateClipNode(PropertyTrees * property_trees,int parent_id,int transform_id)289 ClipNode& CreateClipNode(PropertyTrees* property_trees,
290                          int parent_id,
291                          int transform_id) {
292   return CreateClipNodeInternal<Layer>(nullptr, property_trees, parent_id,
293                                        transform_id);
294 }
295 
CreateEffectNode(Layer * layer,int parent_id)296 EffectNode& CreateEffectNode(Layer* layer, int parent_id) {
297   DCHECK(layer->layer_tree_host()->IsUsingLayerLists());
298   return CreateEffectNodeInternal(layer, GetPropertyTrees(layer), parent_id);
299 }
300 
CreateEffectNode(LayerImpl * layer,int parent_id)301 EffectNode& CreateEffectNode(LayerImpl* layer, int parent_id) {
302   return CreateEffectNodeInternal(layer, GetPropertyTrees(layer), parent_id);
303 }
304 
CreateEffectNode(PropertyTrees * property_trees,int parent_id,int transform_id,int clip_id)305 EffectNode& CreateEffectNode(PropertyTrees* property_trees,
306                              int parent_id,
307                              int transform_id,
308                              int clip_id) {
309   return CreateEffectNodeInternal<Layer>(nullptr, property_trees, parent_id,
310                                          transform_id, clip_id);
311 }
312 
CreateScrollNode(Layer * layer,const gfx::Size & scroll_container_bounds,int parent_id)313 ScrollNode& CreateScrollNode(Layer* layer,
314                              const gfx::Size& scroll_container_bounds,
315                              int parent_id) {
316   DCHECK(layer->layer_tree_host()->IsUsingLayerLists());
317   return CreateScrollNodeInternal(layer, scroll_container_bounds, parent_id);
318 }
319 
CreateScrollNode(LayerImpl * layer,const gfx::Size & scroll_container_bounds,int parent_id)320 ScrollNode& CreateScrollNode(LayerImpl* layer,
321                              const gfx::Size& scroll_container_bounds,
322                              int parent_id) {
323   auto& node =
324       CreateScrollNodeInternal(layer, scroll_container_bounds, parent_id);
325   layer->UpdateScrollable();
326   return node;
327 }
328 
CreateScrollNodeForUncompositedScroller(PropertyTrees * property_trees,int parent_id,ElementId element_id,const gfx::Size & bounds,const gfx::Size & scroll_container_bounds)329 ScrollNode& CreateScrollNodeForUncompositedScroller(
330     PropertyTrees* property_trees,
331     int parent_id,
332     ElementId element_id,
333     const gfx::Size& bounds,
334     const gfx::Size& scroll_container_bounds) {
335   auto& scroll_tree = property_trees->scroll_tree;
336   int id = scroll_tree.Insert(ScrollNode(), parent_id);
337 
338   auto* node = scroll_tree.Node(id);
339 
340   DCHECK(element_id);
341   node->element_id = element_id;
342   property_trees->element_id_to_scroll_node_index[element_id] = node->id;
343 
344   node->bounds = bounds;
345   node->container_bounds = scroll_container_bounds;
346   node->scrollable = !scroll_container_bounds.IsEmpty();
347   node->user_scrollable_horizontal = true;
348   node->user_scrollable_vertical = true;
349   node->is_composited = false;
350 
351   // Create a matching transform node.
352   {
353     auto& transform_tree = property_trees->transform_tree;
354     ScrollNode& scroll_parent = *scroll_tree.Node(parent_id);
355     int transform_id =
356         transform_tree.Insert(TransformNode(), scroll_parent.transform_id);
357     auto* transform_node = transform_tree.Node(transform_id);
358     transform_node->element_id = element_id;
359     property_trees
360         ->element_id_to_transform_node_index[transform_node->element_id] =
361         transform_node->id;
362 
363     if (const auto* parent_transform_node =
364             transform_tree.Node(transform_node->parent_id)) {
365       transform_node->in_subtree_of_page_scale_layer =
366           parent_transform_node->in_subtree_of_page_scale_layer;
367     }
368 
369     transform_tree.set_needs_update(true);
370     transform_node->should_be_snapped = true;
371     transform_node->scrolls = true;
372 
373     node->transform_id = transform_node->id;
374   }
375 
376   scroll_tree.SetScrollOffset(element_id, gfx::ScrollOffset());
377   return *node;
378 }
379 
SetupMaskProperties(Layer * masked_layer,PictureLayer * mask_layer)380 void SetupMaskProperties(Layer* masked_layer, PictureLayer* mask_layer) {
381   mask_layer->SetIsDrawable(true);
382   SetupMaskPropertiesInternal(masked_layer, mask_layer);
383 }
384 
SetupMaskProperties(LayerImpl * masked_layer,PictureLayerImpl * mask_layer)385 void SetupMaskProperties(LayerImpl* masked_layer,
386                          PictureLayerImpl* mask_layer) {
387   mask_layer->SetDrawsContent(true);
388   SetupMaskPropertiesInternal(masked_layer, mask_layer);
389 }
390 
SetScrollOffset(Layer * layer,const gfx::ScrollOffset & scroll_offset)391 void SetScrollOffset(Layer* layer, const gfx::ScrollOffset& scroll_offset) {
392   if (layer->layer_tree_host()->IsUsingLayerLists()) {
393     if (CurrentScrollOffset(layer) != scroll_offset)
394       layer->SetNeedsCommit();
395     SetScrollOffsetInternal(layer, scroll_offset);
396   } else {
397     layer->SetScrollOffset(scroll_offset);
398   }
399 }
400 
SetScrollOffsetFromImplSide(Layer * layer,const gfx::ScrollOffset & scroll_offset)401 void SetScrollOffsetFromImplSide(Layer* layer,
402                                  const gfx::ScrollOffset& scroll_offset) {
403   if (layer->layer_tree_host()->IsUsingLayerLists())
404     SetScrollOffsetInternal(layer, scroll_offset);
405   else
406     layer->SetScrollOffsetFromImplSide(scroll_offset);
407 }
408 
SetScrollOffset(LayerImpl * layer,const gfx::ScrollOffset & scroll_offset)409 void SetScrollOffset(LayerImpl* layer, const gfx::ScrollOffset& scroll_offset) {
410   if (layer->IsActive())
411     layer->SetCurrentScrollOffset(scroll_offset);
412   SetScrollOffsetInternal(layer, scroll_offset);
413 }
414 
SetupViewport(Layer * root,scoped_refptr<Layer> outer_viewport_scroll_layer,const gfx::Size & outer_viewport_size)415 void SetupViewport(Layer* root,
416                    scoped_refptr<Layer> outer_viewport_scroll_layer,
417                    const gfx::Size& outer_viewport_size) {
418   DCHECK(root);
419   DCHECK_EQ(root, root->layer_tree_host()->root_layer());
420   DCHECK(root->layer_tree_host()->IsUsingLayerLists());
421 
422   scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create();
423   inner_viewport_scroll_layer->SetBounds(outer_viewport_size);
424   inner_viewport_scroll_layer->SetHitTestable(true);
425   outer_viewport_scroll_layer->SetHitTestable(true);
426 
427   root->AddChild(inner_viewport_scroll_layer);
428   root->AddChild(outer_viewport_scroll_layer);
429   root->layer_tree_host()->SetElementIdsForTesting();
430 
431   auto viewport_property_ids =
432       SetupViewportProperties(root, inner_viewport_scroll_layer.get(),
433                               outer_viewport_scroll_layer.get());
434   root->layer_tree_host()->RegisterViewportPropertyIds(viewport_property_ids);
435 }
436 
SetupViewport(Layer * root,const gfx::Size & outer_viewport_size,const gfx::Size & content_size)437 void SetupViewport(Layer* root,
438                    const gfx::Size& outer_viewport_size,
439                    const gfx::Size& content_size) {
440   scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create();
441   outer_viewport_scroll_layer->SetBounds(content_size);
442   outer_viewport_scroll_layer->SetIsDrawable(true);
443   SetupViewport(root, outer_viewport_scroll_layer, outer_viewport_size);
444 }
445 
SetupViewport(LayerImpl * root,const gfx::Size & outer_viewport_size,const gfx::Size & content_size)446 void SetupViewport(LayerImpl* root,
447                    const gfx::Size& outer_viewport_size,
448                    const gfx::Size& content_size) {
449   DCHECK(root);
450 
451   LayerTreeImpl* layer_tree_impl = root->layer_tree_impl();
452   DCHECK(!layer_tree_impl->InnerViewportScrollNode());
453   DCHECK(layer_tree_impl->settings().use_layer_lists);
454   DCHECK_EQ(root, layer_tree_impl->root_layer());
455 
456   std::unique_ptr<LayerImpl> inner_viewport_scroll_layer =
457       LayerImpl::Create(layer_tree_impl, 10000);
458   inner_viewport_scroll_layer->SetBounds(outer_viewport_size);
459   inner_viewport_scroll_layer->SetHitTestable(true);
460   inner_viewport_scroll_layer->SetElementId(
461       LayerIdToElementIdForTesting(inner_viewport_scroll_layer->id()));
462 
463   std::unique_ptr<LayerImpl> outer_viewport_scroll_layer =
464       LayerImpl::Create(layer_tree_impl, 10001);
465   outer_viewport_scroll_layer->SetBounds(content_size);
466   outer_viewport_scroll_layer->SetDrawsContent(true);
467   outer_viewport_scroll_layer->SetHitTestable(true);
468   outer_viewport_scroll_layer->SetElementId(
469       LayerIdToElementIdForTesting(outer_viewport_scroll_layer->id()));
470 
471   auto viewport_property_ids =
472       SetupViewportProperties(root, inner_viewport_scroll_layer.get(),
473                               outer_viewport_scroll_layer.get());
474   layer_tree_impl->AddLayer(std::move(inner_viewport_scroll_layer));
475   layer_tree_impl->AddLayer(std::move(outer_viewport_scroll_layer));
476   layer_tree_impl->SetViewportPropertyIds(viewport_property_ids);
477 }
478 
GetPropertyTrees(const Layer * layer)479 PropertyTrees* GetPropertyTrees(const Layer* layer) {
480   return layer->layer_tree_host()->property_trees();
481 }
482 
GetPropertyTrees(const LayerImpl * layer)483 PropertyTrees* GetPropertyTrees(const LayerImpl* layer) {
484   return layer->layer_tree_impl()->property_trees();
485 }
486 
GetRenderSurface(const LayerImpl * layer)487 RenderSurfaceImpl* GetRenderSurface(const LayerImpl* layer) {
488   auto& effect_tree = GetPropertyTrees(layer)->effect_tree;
489   if (auto* surface = effect_tree.GetRenderSurface(layer->effect_tree_index()))
490     return surface;
491   return effect_tree.GetRenderSurface(GetEffectNode(layer)->target_id);
492 }
493 
ScrollOffsetBase(const LayerImpl * layer)494 gfx::ScrollOffset ScrollOffsetBase(const LayerImpl* layer) {
495   return GetPropertyTrees(layer)->scroll_tree.GetScrollOffsetBaseForTesting(
496       layer->element_id());
497 }
498 
ScrollDelta(const LayerImpl * layer)499 gfx::ScrollOffset ScrollDelta(const LayerImpl* layer) {
500   return GetPropertyTrees(layer)->scroll_tree.GetScrollOffsetDeltaForTesting(
501       layer->element_id());
502 }
503 
CurrentScrollOffset(const Layer * layer)504 gfx::ScrollOffset CurrentScrollOffset(const Layer* layer) {
505   auto result = GetPropertyTrees(layer)->scroll_tree.current_scroll_offset(
506       layer->element_id());
507   if (!layer->layer_tree_host()->IsUsingLayerLists())
508     DCHECK_EQ(layer->scroll_offset(), result);
509   return result;
510 }
511 
CurrentScrollOffset(const LayerImpl * layer)512 gfx::ScrollOffset CurrentScrollOffset(const LayerImpl* layer) {
513   return GetPropertyTrees(layer)->scroll_tree.current_scroll_offset(
514       layer->element_id());
515 }
516 
MaxScrollOffset(const LayerImpl * layer)517 gfx::ScrollOffset MaxScrollOffset(const LayerImpl* layer) {
518   return GetPropertyTrees(layer)->scroll_tree.MaxScrollOffset(
519       layer->scroll_tree_index());
520 }
521 
522 }  // namespace cc
523