---
# System prepended metadata

title: Display in Chromium
tags: [Chromium-Graphics, elkurin-daily-note]

---

# Display in Chromium
The word "Display" is used as a name of the physical monitor.  
In Chromium, we also have several Display class.  
This note digs into what those "Display" classes do and are responsible for.

## ui::Display
[ui::Display](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/display/display.h) usually corresponds to a physical display. It can also correspond to a remote / virtual display.

Display is identified by [id](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/display/display.h;l=281;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) with unique int number and can be obtained for example from [Screen::GetPrimaryDisplay](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/display/screen.h;l=118;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).

This [ui::Display](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/display/display.h) bounds is used by [ShellSurfaceBase::GetVisibleBounds](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/shell_surface_base.cc;l=1865;drc=f14515c4f3e94aa8eb7869fdb985aafd8c19c290), but for Lacros, this display is not set as [`display_id_`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/shell_surface_base.h;l=450;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) stays [display::kInvalidDisplayId](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/display/types/display_constants.h;l=18;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).  
`display_id_` can be set only from [SetDisplay](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/shell_surface_base.cc;l=782;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and it is called only from [ClientControlledShellSurface](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/client_controlled_shell_surface.cc) while Lacros uses [ShellSurface](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/shell_surface.cc) instead.  

Lacros surfaces do not refer to display as they are controlled by Server (Ash) as an intermediate layer between display and Lacros window.

## viz::Display
[viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h) is a key class to produce output surface, so it's a bit different from what we think of "display".  
Each widget / toplevel window has corresponding viz::Display.

### What does Display do?
[viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h) produces a surface that can be used to fraw to a physical display.  

Followings are main viz::Display roles:
- [DrawAndSwap](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.cc;l=702;drc=f80633b34538615fcb73515ad8c4bc56a748abfe):
Draws [AggregatedFrame](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/aggregated_frame.h;l=23;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and swaps the produced frame.  
[DrawFrame](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/direct_renderer.h;l=86;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and [SwapBuffers](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/direct_renderer.h;l=116;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) is implemented in [DirectRender](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/direct_renderer.h) or its subclass. viz::Display holds this [`renderer_`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.h;l=309;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) instance and calls them.  
AggregatedFrame is generated by [SurfaceAggregator::Aggregate](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/surface_aggregator.cc;l=2107;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) that Display owns as [`aggregator_`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.h;l=290;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).  
During this, it notifies [DisplayScheduler](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display_scheduler_base.h) the current status and let it handles whether GPU is busy or not from [SetIsGpuBusy](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/common/frame_sinks/begin_frame_source.cc;l=164;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).  
- [SurfaceId](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h;l=276;drc=d259e164a3fac98c83b5e533284875be3087bf22):
viz::Display stores SurfaceId. [SurfaceId](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/common/surfaces/surface_id.h;l=40;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) is a pair of [FrameSinkId](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/common/surfaces/frame_sink_id.h;l=36;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and [LocalSurfaceId](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/common/surfaces/local_surface_id.h;l=65;drc=f80633b34538615fcb73515ad8c4bc56a748abfe). Both ids are used to synchronize the status between service and client. SurfaceId corresponds to a unique [viz::Surface](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/surfaces/surface.h;l=98;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) that can be obtained from [GetSurfaceForId](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/surfaces/surface_manager.cc;l=443;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).
- [SetVisible](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.cc;l=434;drc=f80633b34538615fcb73515ad8c4bc56a748abfe), [Resize](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.cc;l=450;drc=f80633b34538615fcb73515ad8c4bc56a748abfe):
On [SetVisible](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.cc;l=434;drc=f80633b34538615fcb73515ad8c4bc56a748abfe), it notifies [DirectRender](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/direct_renderer.h) that visibility is changed and updates the visibility  
On [Resize](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display.cc;l=450;drc=f80633b34538615fcb73515ad8c4bc56a748abfe), it notifies [DisplayDamageTracker](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display_damage_tracker.cc;l=63;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and ends up calling [DisplayScheduler::OnDisplayDamaged](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/display/display_scheduler.cc;l=117;drc=f80633b34538615fcb73515ad8c4bc56a748abfe)

### Who owns Display?
When widget is created, it calls [Compositor::SetAcceleratedWidget](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:ui/compositor/compositor.cc;l=603;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and creates LayerTreeFrameSink as well.  
On [CreateLayerTreeFrameSink](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:content/browser/compositor/viz_process_transport_factory.cc;l=192;drc=f80633b34538615fcb73515ad8c4bc56a748abfe), it [EstablishGpuChannel](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:content/browser/gpu/browser_gpu_channel_host_factory.cc;l=314;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and then call [VizProcessTransportFactory::OnEstablishedGpuChannel](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:content/browser/compositor/viz_process_transport_factory.cc;l=348;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) as a callbck top create compositor frame sink from [HostFrmeSinkMnger::CreateRootCompositorFrameSink](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/host/host_frame_sink_manager.cc;l=129;drc=f80633b34538615fcb73515ad8c4bc56a748abfe).  
This is established per ui::Compositor and [`compositor_data`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:content/browser/compositor/viz_process_transport_factory.cc;l=385;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) stored in [`compositor_data_map_`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:content/browser/compositor/viz_process_transport_factory.h;l=136;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) is passed as a `root_params` to create RootCompositorFrameSink.

This bypasses [Mojo API CreateRootCompositorFrameSink](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:services/viz/privileged/mojom/compositing/frame_sink_manager.mojom;l=112;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) to [Create](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/frame_sinks/frame_sink_manager_impl.cc;l=200-203;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) RootCompositorFrameSink on viz.  
Inside [RootCompositorFrameSink](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc), [viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h) is costructed and owned.  

[viz::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.h) is owned by [RootCompositorFrameSink](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc) and it corresponds to each Widget on browser process.  

## exo::Display
[exo::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.h;l=45;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c) provides functions for creating surfaces and is in charge of combining the contents of multiple surfaces into one displayable output.  

Here are the main method in [exo::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.h;l=45;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c)
- [CreateSurface](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.cc;l=76;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c)
- [CreateShellSurface](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.cc;l=127;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c)
- [Shutdown](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.cc;l=69;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c)

[exo::Display](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/display.h;l=45;drc=bfd314bbd7da4622f6d4dcdee3266e0ebb14ba1c) owns [InputMethodSurfaceManager](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/input_method_surface_manager.h;l=12;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) and [Seat](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/seat.h;l=43;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) class which represents input devices such as a keyboard, pointer and touch devices.  
It looks to manage input related features.

It's used by, for example, [`shell_get_shell_surface`](https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:components/exo/wayland/wl_shell.cc;l=139;drc=f80633b34538615fcb73515ad8c4bc56a748abfe) wayland message.  
Here, `wl_resource` is parsed as Display resource.