---
# System prepended metadata

title: How Property Node is added to Tree
tags: [Chromium-Graphics, elkurin-daily-note]

---

# How Property Node is added to Tree
[PropertyTree](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.h) is a concept in cc.  
It stores each property such as clip_rect, transform etc... as a tree hierarchy.

Let's see how the node is added.

## Overview
[PropertyTree](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.h;l=75;drc=ca067f2604f9bf0ff2fa070eafeed664698d819a) is a template.  
The template parameter is a type of the node.  
We can use such as [ClipNode](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/clip_node.h;l=30;drc=8e78783dc1f7007bad46d657c9f332614e240fd8), [EffectNode](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/effect_node.h;l=62;drc=ca067f2604f9bf0ff2fa070eafeed664698d819a)... to construct the tree.

PropertyTree corresponds to a uinique [cc::LayerTreeHost](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host.h;l=120;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).  
It's built in [LayerTreeHost::DoUpdateLayers](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host.cc;l=930;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) which is triggered from [ProxyMain::BeginMainFrame](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/proxy_main.cc;l=355;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) or [SingleThreadProxy::DoPainting](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/single_thread_proxy.cc;l=1134;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).

The concept of the property tree exists only inside cc.

## Insert
[PropertyTree::Insert](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.cc;l=97;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is a method to add a new `tree_node` to the tree.  
You need to specify `parent_id` which represents which node `tree_node` should be attached. This parameter ensures that the child is attached later then its parent.  
On adding the node, the id is incrementally assigned, so the parent id is guranteed to be smaller than its children.

[AddClipNodeIfNeeded](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=213;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) calls insert if needed.  
First it checks [LayerClipsSubtree](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=208;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) value and see if there is a meaningful information in the subtree related to clipping. If there is none, it skips inserting. This is for performance.

## BuildPropertyTrees
[BuildPropertyTrees](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=824;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) build property trees including clip tree.  
Let's focus on clip node and track the behavior of ClipTree.  
Here's the suedo code extracted from PropertyTreeBuilder.

```cpp=
void PropertyTreeBuilderContext::BuildPropertyTrees() {
  clip_tree_->SetViewportClip(
    gfx::RectF(layer_tree_host_->device_viewport_rect()));
  
  DataForRecursion data_for_recursion;
  data_for_recursion.clip_tree_parent = kRootPropertyNodeId;
  
  ClipNode root_clip;
  root_clip.clip = gfx::RectF(layer_tree_host_->device_viewport_rect());
  data_for_recursion.clip_tree_parent =
      clip_tree_->Insert(root_clip, kRootPropertyNodeId);
  
  BuildPropertyTreesInternal(root_layer_, data_for_recursion);
}

void PropertyTreeBuilderContext::BuildPropertyTreesInternal(
    Layer* layer,
    const DataForRecursion& data_from_parent) const {
  ...;
  
  AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node,
                      &data_for_children);
  
  for (const scoped_refptr<Layer>& child : layer->children()) {
    BuildPropertyTreesInternal(child.get(), data_for_children);
  }
  ...;
}
```

The tree is recursively constructed.  
Inside `BuildPropertyTrees`, it sets device_viewport_rect to root_clip, but on clip computation ClipNode corresponding to kRootPropertyNodeId is never refered, instead the computation starts from kViewportPropertyNodeId which is the children of the root node.

According to the current implementation, all property tree have a same structure except for the subtrees extracted as they are not useful.

PropertyTree has the same hierarchy as the layer hierarchy, so the question "How Property Node is addeds to Tree" is the same as how the layer is attached to its parent.
