# Partial Swapping in Chromium
Partial swap is a technique to improve graphic performance.
When the frame is updated, the updated image areas may be only limited. For example, when you are writing a document, the area where is updated is only a character you just added. In such scenairo, updating the whole frame is unnecessary. Instead, we can only update a small area and avoid drawing the frame that are not changed.
This is a "partial" swapping.
"Swap" is swapping the old frame and the newly created frame. "Draw" and "Swap" is a set of terms that represents the frame presentation.
## Damage Rect
Let's introduce another terminology.
Damage rect is the area that should be updated. As it is called "rect", the area must be one rectangle.
There are two types of damage:
- Invalidation damage: Texture has changed and the screen needs to update due to rastar invalidation.
- Expose damage: When layer goes away, added for the first time or gets reordered. There is no raster invalidation in this case.
[DamageTracker](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/damage_tracker.h;l=34;drc=c97609b6bb0b545340877ae17d6bdce82c8865bd) is responsible for computing the regions where pixels have changed and need to be updated.
This instance is managed by [RenderSurfaceImpl](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.h;l=356;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) and calculated damage rect will be used to [CreateRenderPass](https://source.chromium.org/chromium/chromium/src/+/main:cc/layers/render_surface_impl.cc;l=404;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).
[DamageAccumulator](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/damage_tracker.h;l=62;drc=c97609b6bb0b545340877ae17d6bdce82c8865bd) accumulates the union of the whole damege rectangles.
Here's how damege rect is calculated:
```cpp=
void Union(const Type& rect) {
if (!is_valid_rect_)
return;
if (rect.IsEmpty())
return;
if (IsEmpty()) {
x_ = rect.x();
y_ = rect.y();
right_ = rect.right();
bottom_ = rect.bottom();
return;
}
x_ = std::min(x_, rect.x());
y_ = std::min(y_, rect.y());
right_ = std::max(right_, rect.right());
bottom_ = std::max(bottom_, rect.bottom());
}
```
As you can see, it's taking the minimum one rectangle that covers whole damaged area instead of holding the list of rectangles.
This means, for example, if you have one small damage area at the top right and another small damage area at the left bottom, the whole window will be the union of the damaged area, instead of two small rectangles being cosidered as the only damaged area.
## Partial Swap
Partial swapping is done using Damage Rect information described above.
This feature can be disabled by the flag [ui-disable-partial-swap](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/ui_base_switches.cc;l=110;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).
For [OutputPresenterGL](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display_embedder/output_presenter_gl.cc;l=141;drc=8e78783dc1f7007bad46d657c9f332614e240fd8), it's enabled by default.
This is part of [RenderSettings](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/display/renderer_settings.h;l=30;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) that can be override via [mojom](https://source.chromium.org/chromium/chromium/src/+/main:services/viz/privileged/mojom/compositing/renderer_settings.mojom;l=19;drc=3fc4d8a37eb1c0a2b021b580a89d31ebcc17350f).
[`use_partial_swap_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/direct_renderer.h;l=357;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is a flag specifying whether we should use partial swap logic.
If it's enabled, `damage_rect` is set as [`swap_buffer_rect_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/skia_renderer.cc;l=1055-1057;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) written on [FinishDrawingFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/skia_renderer.cc;l=1012;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).
`root_damage_rect` is a parameter in [DrawingFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/direct_renderer.h;l=128;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) struct which is tied with Aggregated RenderPass.
This is also passed from [`root_render_pass`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/direct_renderer.cc;l=233;drc=8e78783dc1f7007bad46d657c9f332614e240fd80) while [`device_viewport_size`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/direct_renderer.cc;l=407-408;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is refered if the full frame redraw is needed.
This damage rect is calculated inside Viz with some complex logic.
## Note: Render Pass
[RenderPass](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/render_pass_internal.h;l=30;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is a list of quad.
[QuadList](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/quad_list.h;l=18;drc=8e78783dc1f7007bad46d657c9f332614e240fd8), whoo is cc:List of [DrawQuad](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/draw_quad.h;l=35;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is an actual data to carry this quad list.
DrawQuad is a bag of data used for drawing a quad.