A client requests a set of commands to be Presented as part of a future Scenic frame. A single Scenic frame can have multiple client “Presents”, where each Present represents a Session's update to the global scene graph. This doc describes the architecture internal to Scenic for how a request becomes pixels.
The diagram below shows the steps a client Present follows when it is requested. Everything between the Scenic FIDL Boundary and the Vulkan driver is currently single-threaded and executes sequentially.
Enqueue()s a set of commands to change the contents of its part of the scene, and calls Present2() to commit them.Present2() request enters scenic_impl::Session,. scenic_impl::Session waits for any acquire fences to signal, as well as any previous Present2() calls whose fences haven't been reached yet. scenic_impl::Session then schedules an update for the targeted presentation_time with the FrameScheduler.FrameScheduler starts sleeps until there's just enough time to prepare a frame in time for the targeted presentation time. At that point the FrameScheduler wakes up and calls SessionUpdater::UpdateSessions() on all SessionUpdaters.GfxSystem calls ApplyScheduledUpdates(), which applies the commands to the scene graph which were enqueued in step 1. Note: GfxSystem is a SessionUpdater.SessionUpdaters have successfully updated, the FrameScheduler is notified that the scene graph is dirty, and triggers a RenderFrame() call on the FrameRenderer.gfx::Engine's renderer traverses the scene graph and creates Escher::objects for each element in the scene. The renderer then passes these objects to Escher, and calls DrawFrame(). Note: gfx::Engine is a FrameRenderer.Escher interprets the scene graph objects as vk::commands, and sends these commands to the GPU.