# 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.