This topic provides a brief introduction to the Window Server's rendering loop, which takes place in two stages, known as the upper loop and the lower loop.
Variant: ScreenPlay and non-ScreenPlay. Target audience: Device creators.
The following diagram provides a simplified representation of the upper and lower loops.
Figure: The Window Server's upper and lower rendering loops
The upper loop is the process by which the Window Server’s scene state information is updated based on commands from the client. There are two types of scene state updates: window tree updates (such as when a window is moved) and redraw store updates (such as when new drawing operations are sent for a particular window).
The lower loop is the process by which updates are made to what the user sees on the screen. The lower loop runs after the upper loop.
The two most important APIs on the client side are:
RWindow
,
which is the class through which a client controls a window. Its main functions
enable a client to create and destroy windows, move and resize them, make
them visible or invisible, and send them to the foreground or background.
CWindowGc
,
which is the class through which a client issues draw operations. At any given
time, a CWindowGc
is activated on a particular window. The CWindowGc
functions
that are used most frequently are DrawBitmap()
and BitBlt()
,
for drawing a skin bitmap as a background, and DrawText()
.
Figure: The main participants in the ScreenPlay Window Server rendering loop
On the client side, RWindow
and CWindowGc
commands
are converted to opcodes that are stored in a command buffer. When the command
buffer is full, it is automatically flushed, which means that it is
transferred across to a corresponding server-side command buffer. The client
can also explicitly request a flush using RWsSession::Flush()
.
On the server side:
The upper loop processes
the server-side command buffers. RWindow
commands are processed
as updates to the window tree. CWindowGc
commands
are processed as updates to the redraw stores.
The lower loop ultimately causes the updates to be drawn to the UI surface. However, the updates do not go straight to the UI surface. Instead they go through an additional level of indirection called render stages. These are replaceable plug-ins to the Window Server, which enable the customization of the final stages of the rendering pipeline.
The details of the upper and lower loops vary depending on whether dirty-rectangle tracking or change tracking is in use.
Dirty-rectangle tracking mode
Dirty-rectangle tracking mode is always used in the non-ScreenPlay variant and is the default mode in ScreenPlay.
Updates to both the window tree and the redraw stores typically mean that
the current contents of the screen become invalid. Therefore, when processing RWindow
or CWindowGc
commands,
the upper loop adds the affected regions to a list of dirty rectangles that
need to be redrawn. The list includes transparent windows that are on top
of other windows and excludes windows that are obscured. The upper loop then
starts a scheduler, which eventually causes the dirty rectangles to be redrawn.
Some time later the scheduler runs the lower loop. The task of the lower loop is to clean any dirty rectangles by playing (or replaying) the drawing operations from the redraw stores into the first render stage. This is done for all of the visible windows, starting at the back and working forwards.
Change tracking mode
Change tracking mode is only available in ScreenPlay. To enable change
tracking mode, add the CHANGETRACKING
parameter to the wsini.ini file. This
parameter is set on a per-screen basis.
In change tracking mode, the upper loop keeps a list of all of the windows for which there are new or changed drawing operations, regardless whether the window is obscured or not. The list does not include transparent windows that have not changed and which are on top of other windows. As in dirty-rectangle tracking mode, changes cause the upper loop to start the scheduler which eventually causes the lower loop to run. This plays the drawing operations for all of the windows in the list of changed windows into the first render stage.
Typically you enable change tracking mode only if you are creating a transition effects (TFX) render stage that is building up its own visuals stores. Visual stores are replicas of the redraw stores and are often used with a visuals tree. A visuals tree is a replica of the Window Server's window tree, into which the render stage may add nodes that the Window Server does not "know" about. In addition, these render stages typically introduce transition effects which may change the visibility of windows that the Window Server does know about. For example, the following diagram shows a transition effect in which a window slides onto the screen from the top and temporarily obscures an existing window on the screen.
Figure: A transition effect temporarily obscures a window on the screen
In this and similar scenarios, the Window Server does not know whether a window is obscured or visible. Therefore dirty-rectangle tracking is not effective.
Each screen on the device has a separate render stage chain.
Because you set the CHANGETRACKING
parameter on a per-screen
basis, it is possible to have a sophisticated TFX on one screen and a simple
display render stage on another screen.