# Surface content rect
Let's take a look inside cc.
cc has a class called [RenderSurfaceImpl](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.h;l=55;drc=cf2ba5ddae1d5cd3cb9bd3765ada9367ad33e65d) to carry draw properties and compute the size to draw.
And [LayerTreeHostImpl](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host_impl.h;l=189;drc=b475091ab9ecff82505c502497b39723da00bc69) owns the rendering states and sets/refers to RenderSurfaceImpl data.
Let's see how surface content rect works within these two classes.
## Content Rect Compuitation: Root and Non-Root surface
[ComputeSurfaceContentRects](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/draw_property_utils.cc;l=1103;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) Calculates the content rect from draw_property_utils.
The logic is different between root render surface and non-root render surface.
```cpp=
for (RenderSurfaceImpl* render_surface :
base::Reversed(*render_surface_list)) {
if (render_surface->EffectTreeIndex() == kContentsRootPropertyNodeId) {
render_surface->SetContentRectToViewport();
continue;
}
render_surface->CalculateContentRectFromAccumulatedContentRect(
max_texture_size);
}
```
For root render surface, it simply sets viewport rect as a content rect.
[SetContentRectToViewport](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=301;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) gets `viewport` from clip tree via `layer_tree_impl_->property_trees()->clip_tree().ViewportClip()` and [SetContentRect](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=203;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) it.
In this method, there is a check `DCHECK_EQ(render_target(), this);`.
`render_target`returns `this` if it's kRootPropertyNodeId, or return [GetRenderSurface](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/property_tree.h;l=404;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) for the target id instead.
This aims to check whether this is only called for root render surface.
For non-root render surface, it [CalculateContentRectFromAccumulatedContentRect](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=273;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349).
On contrary to [SetContentRectToViewport](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=301;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349), this checks `DCHECK_NE(render_target(), this);`: which prohibits the call from root render surface.
This [CalculateClippedAccumulatedContentRect](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=226;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) and accumulate the children surfaces with clipping.
## How content rect is used
The content rect computed above can be obtained from, [`content_rect()`](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.h;l=180;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349).
This value is refered to [CreateRenderPass](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=401;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349).
[CompositorRenderPass](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/compositor_render_pass.h;l=51;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) is created from [SetNew](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/compositor_render_pass.h;l=64;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349) with setting `content_rect()` as an output rect.
Note that `damage_rect` also takes [intersection with `content_rect()`](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=405;drc=5a524eccbe4138e4edbccbb30ff79f8e0766e349).