# Display size on viz
Display is a concept in viz.
[viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h;l=75;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) produces a surface that can be used to draw to a physical display which is [viz::OutputSurface](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/output_surface.h;l=50;drc=25a9dc176029598d968de92e6cfd7dcb5e6246e4).
Display size is an important info which determins CompositorFrame.
Let's see how it's decided on Lacros.
## Size calculation
[`resize_based_on_root_surface`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/output_surface.h;l=128;drc=25a9dc176029598d968de92e6cfd7dcb5e6246e4) flag is used to resize display size based on root surface.
This feature is set to true on Lacros by [GbmSurfaceWayland::SupportOverridePlatformSize](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc;l=242;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244).
This is a property tied to [viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h;l=75;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244).
If this property is set for the target display, the size is calculated based on root surface.
[RootCompositorFrameSinkImpl::SubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc;l=539;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) resizes the display size:
```cpp=
if (support_->last_activated_local_surface_id() != local_surface_id &&
!support_->IsEvicted(local_surface_id)) {
display_->SetLocalSurfaceId(local_surface_id, frame.device_scale_factor());
if (display_->resize_based_on_root_surface())
display_->Resize(frame.render_pass_list.back()->output_rect.size());
}
```
[Resize](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=469;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) is only called from here for Lacros.
`display_->Resize(frame.render_pass_list.back()->output_rect.size())` updates the size to the top of the render pas list's output rect. Top is a root surface.
By the way, [RootCompositorFrameSinkImpl::Resize](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc;l=363;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) may resize the dislay size but if the above feature is enabled, resize request will be blocked.
This size will be set to [`current_surface_size_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=482;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244).
On [Display::DrawAndSwap](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=758;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) refers to this value.
In short, display size on Lacros is the same as the root surface size.
## RCFS
RCFS stands for [RootCompositorFrameSinkImpl](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=758;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244)
This is a viz portion of a root CompositorFrameSink holding the pipe to mojom::CompositorFrameSink and owns Display.
[CompositorFrameSink](https://source.chromium.org/chromium/chromium/src/+/main:services/viz/public/mojom/compositing/compositor_frame_sink.mojom;l=31;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) interface contains the complete output meant for display.
It has SubmitCompositorFrame and SetNeedsBeginFrame.
SubmitCompositorFrame is called from [AsyncLayerTreeFrameSink::SubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:cc/mojo_embedder/async_layer_tree_frame_sink.cc;l=172;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) in cc mojo embedder.
This will check the size not change if surface id is the same.
[cc::LayerTreeHostImpl::DrawLayers](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host_impl.cc;l=2546-2548;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) calls this API by creating CompositorFrame from [FrameData](https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host_impl.h;l=203;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244).
## viz::Display roles
Let's look at viz::Display roles as well.
viz::Display is the class that owns multiple managers.
For example, it owns [SurfaceManager](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/surfaces/surface_manager.h;l=52;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) which will create the next surface.
[MaybeSubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/compositor_frame_sink_support.cc;l=858;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) creates surface and [QueueFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/compositor_frame_sink_support.cc;l=882;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) to the surface.
If the size is mismatrched, QueueFrame is rejected and [SubmitResult::SIZE_MISMATCH](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/compositor_frame_sink_support.cc;l=888;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) is returned as a result.
It also has the surface id which display is currently presenting.
[SetLocalSurfaceId](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=439;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) stores the current surface id.
This is set from [RootCompositorFrameSinkImpl::SubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc;l=539;drc=400bd0d71fb18ec50bd4fb36cfe59b7b90411244) which passes monotonically increasing id for each change.