---
# System prepended metadata

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

---

# How to Build Property Tree

[PropertyTree](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.h;l=75;drc=ca067f2604f9bf0ff2fa070eafeed664698d819a) is a concept in cc to carry the property such as transform, opacity and so on.

Let's see initilization order.

## BuildPropertyTree
[PropertyTreeBuilderContext::BuildPropertyTrees](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=824;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) is responsible for property tree.

First, it initializes the root node of clip tree and transofmr tree. It sets viewport as a root node of `clip_tree_` and scale factor to root scale.  

On constructing TransformTree, the scale factor is set by [SetRootScaleAndTransform](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.cc;l=709;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).  
The given `transform` is scaled by this scale factor and set to [`content_root_node`](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.cc;l=745;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).  

After initializing the root nodes, we constructs [DataForRecursion](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=40;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) for the parent node.  
Then starting from `root_layer_`, it starts [BuildPropertyTreesInternal](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=772;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).  

Here's the order of property tree construction.
- AddEffectNodeIfNeeded
- AddTransformNodeIfNeeded
- AddClipNodeIfNeeded
- AddScrollNodeIfNeeded

After all these, [UpdateRenderSurfaceIfNeeded](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=623;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) is called and it creates the render surfae.

### Effect Node
[AddEffectNodeIfNeeded](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=458;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) creates the effect tree.

Render surface corresponding to `layer` may be constructed, and effect tree determins whether we should construct it.  
[ComputeRenderSurfaceReason](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=347;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) returns whether we should computes render surface or not with its reason.  
This is also used to check whether we should create effect node for its layer as [`requires_node`](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=490;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).

[EffectNode](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/effect_node.h;l=62;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) has so many properties and they are set inside [here](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=506-591;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).

### Transform Node
Next [AddTransformNodeIfNeeded](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=245;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) is called and calculate transform.  
This uses `created_render_surface` that was calcualted by effect tree construction.  
Transform node also may be constructed and may not.  
If created, the node will be [inserted](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=303;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).  
`device_scale_factor` is only set for [root node](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=324;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).

If the node is required, parent_offset propagated from parent node, and the local offset that is assigned to its layer will be added and [set](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree_builder.cc;l=298;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).

## Who builds property tree
The property tree is built from LayerTreeHost.  
[LayerTreeHost::UpdateLayer](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host.cc;l=820;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed) -> [LayerTreeHost::DoUpdateLayers](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host.cc;l=919;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).

Thsi is called by [BeginMainFrame](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/single_thread_proxy.cc;l=1095;drc=adb3b9bc3ff928029b19d5ac5379841dae0ad6ed).  
So, property tree is constructed for each BeginFrame event.
