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