-
Notifications
You must be signed in to change notification settings - Fork 278
Life of a Task
Renderer::new()
creates the WebRender (WR) instance with the following components:
-
RenderBackend
(RB). It's not returned from the function, but instead put to work in a separate thread and communicate via messages with the following objects. -
RenderApiSender
, needed to produceRenderApi
instances, each with a unique namespace. -
Renderer
owns the graphics context and does the actual rendering.
RenderApi
is the front-end API to WR, it has methods for:
- resource management
- setting root pipeline/display list (DL)
- scrolling
When issuing commands through RenderApi
, they get serialized and sent over the IPC channel (not necessary through the IPC boundary) to RB.
RenderBackend
:
- owns
ResourceCache
, which in turn ownsTextureCache
-
build_scene
flattens theStackingContext
and allocates all the GPU data into textures. -
render()
builds a newFrame
by culling the primitives against layers/tiles and filling up the batch instance data -
publish()
sends a frame over the result channel - any messages requiring feedback provide a sender themselves
All the work in a produced Frame
is based off a task tree. This tree is composed by the RB and flattened out into passes before sending to the Renderer
. A RenderPass
:
- has list of tasks that are independent of each other
- all these tasks depend on some tasks in the previous pass
- is rendered into a texture array layer by layer. The previous pass's texture is seen as
sCache
texture sampler.
Each texture array is an atlas of the target regions that were requested by the tasks (see RenderTaskLocation::Dynamic
). The width and height are the same across all passes, and the depth is as little as required to fit all the target regions.
Let's take the blur filter for example. Considering the source of the blur stored in pass[0]
(supposing, a text run has been rendered there), the vertical pass will be done in pass[1]
. Since the horizontal pass works off the vertical pass results, it will be assigned to the next pass[2]
.
-
RenderTask
gets created inScreenTile::compile()
and put into the tree with the root ofCompiledScreenTile::main_render_task
. -
CompiledScreenTile::build()
is given aVec<RenderPass>
, and it starts callingRenderTask::assign_to_passes
. The topmost tasks going to the last pass, their children going to the one below it, and so forth. We assume (and guarantee) that the number of passes equals to the depth of the tree. Tasks end up being stored inRenderPass::tasks
. - The
Frame
containing our render passes is being sent to theRenderer
. -
RenderPass::build
creates render targets if needed for the tasks storage allocation and callsRenderTarget::add_task
, which dissects the task to be consumed by one of the batchers: Alpha, Clip, or Blur. -
Renderer::draw_target
goes through the batchers and issues the specific draw calls.