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