# Allocate Surface ID Local surface id is used to synchronize the surface. This is a short note to look how and when the local surface id is allocated in Exo. ## SurfaceTreeHost [SurfaceTreeHost::AllocateLocalSurfaceId](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=532;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is API to allocate local surface id. SurfaceTreeHost has [child_local_surface_id_allocator_](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/surfaces/child_local_surface_id_allocator.h;l=23;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) which is a helper class to generate the id for FrameSink. [GenerateId](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/surfaces/child_local_surface_id_allocator.cc;l=76;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) API increments [`child_sequence_number_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/surfaces/local_surface_id.h;l=164;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) of the LocalSurfaceId [`current_local_surface_id_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/surfaces/child_local_surface_id_allocator.h;l=46;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). SurfaceTreeHost allocates new id on [PrepareToSubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=585;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). It allocates id when the size is changed or the device scale factor has changed. ```cpp= if (output_surface_size_in_pixels != layer_tree_frame_sink_holder_->LastSizeInPixels() || device_scale_factor != layer_tree_frame_sink_holder_->LastDeviceScaleFactor()) { AllocateLocalSurfaceId(); } ``` The previous size and device scale factor is stored in [`layer_tree_frame_sink_holder_`](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.h;l=285;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). [LayerTreeFrameSinkHolder](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/layer_tree_frame_sink_holder.h;l=56;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is responsible for tracking the references to the contents of Buffers through interacting with CompositorFrameSink. This is inside Exo. After allocating surface id, the incremented id will be [set to `layer_tree_frame_sink_holder_`](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=641;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). [SubmitCompositorFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=310;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) will prepare and get `frame` as viz::CompositorFrame. Then [AppendSurfaceHierarchyContentsToFrame](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/surface_tree_host.cc;l=341;drc=8e78783dc1f7007bad46d657c9f332614e240fd8).