This topic provides an introduction to displaying an external surface on a window. The surface is then known as a background surface. This feature is available in ScreenPlay only.
Variant: ScreenPlay. Target audience: Device creators.
There are two main use cases for using external surfaces in this way. One is to display a video, in which case DevVideo renders the content. The other main use case is an OpenGL ES background surface, in which case the client issues OpenGL ES rendering commands. This topic covers how to get the surface onto the screen and not rendering the content to the surface.
The following diagram illustrates some of the key concepts that are used in the documentation of surfaces.
Figure: Composition of the UI surface and an external surface, showing the viewport and extent
A graphics surface (usually simply called a surface) is a hardware-independent memory buffer for holding an image or part of a scene. A surface has a set of attributes, the most important of which is its ID (which is a TSurfaceId).
The UI surface is a special surface onto which the Window Server renders all of the UI content. It is created automatically during system start up and corresponds to the frame buffer in the non-ScreenPlay variant. The UI surface is semi-transparent and is always the topmost layer.
An external surface is any surface other than the UI surface—for example, a surface that holds a video or to which OpenGL ES content is rendered. External surfaces are always opaque. When an external surface is attached to a window, the Window Server creates a transparent hole in the UI surface to reveal the external surface.
The viewport is a rectangular area of an external surface all or part of which is to be displayed. You can think of the viewport as the source.
The extent is a rectangular area in the composition scene in which all or part of the viewport is placed. The content of the viewport can be scaled and rotated within the extent relative to its normal size and orientation. The extent is normally a window to which the external surface is attached.
The following diagram provides a cross-section view through the surfaces shown in the previous figure. Notice that the UI surface is the topmost layer and that it contains a hole through which the external surface can be seen.
Figure: A cross section through the surfaces, showing the display output
You can:
Display an external surface (for example, video content or a viewfinder image) within a window.
Dynamically set or remove a background surface across multiple windows on the same screen without having to register and unregister the surface. This reduces resource churn and content transfer.
Reconfigure the attributes of the surface such as its extent, viewport and orientation, after it is set as a background.
Reposition the displayed surface on the window.
Zoom in and out of the contents of the surface.
Place the surface content in a specified window area rather than filling the entire window.
Crop the surface content rather than using the entire surface.
Rotate the contents of the background surface by quadrant angles.
Flip the background surface from top to bottom and rotate it by 180° to achieve a mirroring effect.
The following diagrams shows some surface configuration use cases.
Figure: Surface configuration use cases
There are a number of ways in which dynamically updated content can be configured to appear on a window.
A single content surface filling the window
External
content can be fitted onto a Window Server window. Each axis of the surface
can be stretched independently of the other axis. The window must be a visible
client window: RWindow
or RBlankWindow
.
Placement of a single surface on a selected area of the window
The position
and display size for the external content can be specified as an area within
the Window Server window, rather than filling the window. The window must
be a visible client (RWindow
or RBlankWindow
)
as before. You specify the area by using TSurfaceConfiguration::SetExtent(const
TRect& aExtent).
After the extent is specified, its size does not change if the window size changes but its position moves to maintain its relative position on the window.
Clipping of a surface
Video sometimes needs to appear cropped, so that a sub-area of the video is displayed instead of the full image. The crop viewport is specified in surface co-ordinates. The cropped viewport fills the output extent (or the window when the extent is not specified). The content appears scaled if the size of the viewport does not match the size of the extent (or the window).
Scaling
It is possible to arbitrarily scale a surface to user specifications using the extent and viewport features. Each axis is scaled independently. When the extent and viewport are coincident, no scaling occurs. Filtering can be applied by the implementation of stretching and shrinking.
Rotation
The viewport can be displayed rotated relative to its normal orientation. For example, if there is a fixed camera on the front of a device and the device is rotated by 90°, the image captured by the camera needs to be rotated by 90° in the other direction to get the expected result. The orientation is always relative to the current device orientation.
Flipping
An external surface can be flipped from top to bottom around the x axis.
Atomic combination of these operations
All the above mentioned configurations can be specified and combined unambiguously for a particular content on a particular window. You can specify parameters for a combination of these configurations in a single operation.
Changing surfaces
The surface assigned to a window can be changed.
Reconfiguring
It is possible to change the configuration options applied to a surface without re-assigning the surface.
Sharing surfaces
Content surfaces are transferable and sharable between windows.
The initial registration step ensures that any resources allocated to the content surface are held while the surface is removed from one window and added to another. This reduces the likelihood of failure between operations.
This section provides a summary of the classes and functions that you use to manage surfaces:
SetBackgroundSurface(const
TSurfaceConfiguration &,TBool)
sets the background
of the window to be a given surface. The TSurfaceConfiguration argument
contains the surface ID and the configuration attributes. Another form of
the function simply takes a surface ID as an argument, which provides less
control and auto-stretches the surface to fill the window.
RemoveBackgroundSurface()
removes
any background surface that has been set to the window.
GetBackgroundSurface()
retrieves
a copy of the current configuration for the background surface attached to
the window.
See RWindowBase
.
This class encapsulates the surface configuration attributes that can be specified while setting the background surface of a window. If the values for the attributes are not set, the default values for the corresponding attribute are used.
Symbian recommends that the client validates the surface configuration data before passing it on to the server. Invalid data that inadvertently slips through the client-side validation mechanism, or maliciously bypasses it, causes a panic.
See TSurfaceConfiguration.
RegisterSurface()
registers
a surface for use in composition on the screen associated with this device
within this session.
UnregisterSurface()
removes
the surface from the session’s register of surfaces that are used in composition
on the screen associated with this device.
PreferredSurfaceConfigurationSize()
returns
the window server’s preferred size for the TSurfaceConfiguration
object,
used for RWindow::SetBackgroundSurface()
.
See RWsSession
.
This code snippet is provided for illustrative purposes only. A Window Server client application wants to run a 3D game full-screen at the native physical resolution of the display (either current or selected using a display controlling system application). This example assumes that the MDisplayMapping interface has already been obtained, as shown in Display Control and Mapping in the Window Server Client.
// Establish connection and get display mapping interface. RWindowGroup group = RWindowGroup(iSession); RWindow window(iSession); group.Construct(1, iScreenDevice); window.Construct(group, 2); TRect winExtent; iDisplayMapping.GetMaximumWindowExtent(winExtent); window.SetExtent(winExtent); // Map window size to composition coordinates TRect surfaceExtent; iDisplayMapping.MapCoordinates(EApplicationSpace, winExtent, ECompositionSpace, surfaceExtent); RSurfaceManager::TSurfaceCreationAttributes attribs; attribs.iSize = surfaceExtent.Size(); // Set up other attributes and create surface window.SetBackgroundSurface(surface); window.Activate();
A similar approach can be used by other surface content providers, such as video.