Window Server Plug-in Framework in the Non-ScreenPlay Variant

This topic provides an introduction to the Window Server plug-in framework in the non-ScreenPlay variant. This framework was introduced in a project to improve the Window Server.

Variant: Non-ScreenPlay. Target audience: Device creators.

Purpose

The Window Server (WSERV) performance improvements introduce several new APIs and Service Provider Interfaces (SPIs). An SPI differs from an API in that an API describes functionality that a developer expects to use, whereas an SPI defines an interface that a developer is expected to implement.

The SPI part consists primarily of abstract interfaces for plug-ins, faders and render stages. Developers are expected to provide concrete implementations of these interfaces. The API part consists of new object provider interfaces that can be used by plug-ins (including the existing Content Rendering Plug-ins (CRP)).

This document provides an overview for the new WSERV performance improvements.

Library details

There is one library affected by the WSERV performance improvements changes.

Library Name Short Description

wsgraphicdrawer.lib

Server-side base-classes for graphic drawer plug-ins

Architectural relationship

New additions

In the past, Window Server (WSERV) has supported a number of plug-in interfaces, for example:

  • Anim dlls

  • Content rendering plug-ins

In general, these plug-ins enable UI platform providers to have code running in the WSERV process for specific purposes, without having to modify WSERV. This mechanism can be used to extend or customize WSERV functionality. However, in the past, new plug-in types were added in a fairly ad hoc way, with each new implementer going about things in a different way.

In order to improve performance, there have been changes made to this previous method. These changes are a generic plug-in framework, two new types of plug-in and some new extension interfaces.

A generic plug-in framework

The generic plug-in framework provides a standard mechanism for adding new types of plug-ins, based on the support provided by the Symbian ECOM component. This amounts to a fairly thin wrapper around ECOM, with WSERV specific features such as the ability to specify which plug-ins to load at boot time, using the WSINI.INI file. The intention is that when new types of plug-in are introduced in future they should use this generic plug-in framework rather than an ad hoc mechanism, leading to reduced implementation time.

Two new types of plug-in

The WSERV performance improvements make use of the new framework to add two new types of plug-in:

  • Fader plug-ins, which enable customizable fading

  • Render stage plug-ins, which enable modification of the tail end of the rendering pipeline, at the point where WSERV outputs draw operations for a screen target.

New extension interfaces

The WSERV performance improvements also provide a number of new extension interfaces giving plug-ins a more detailed picture than previously of WSERV’s internal workings. This applies not only to plug-ins using the new framework, but also to the existing CRP plug-ins.

APIs and SPIs

To understand the new SPIs, it is necessary to show how they would fit into a configuration in which concrete implementations have been supplied by plug-ins. The following diagram shows the default configuration, in which the concrete classes are supplied by the WSERV reference plug-ins:

Figure 1. Default configuration of WSERV plug-ins

The diagram has three layers, going down:

  1. The top layer is the MWsObjectProvider interface, which is an existing class in WSERV. This provides a framework for extensible interfaces.

  2. In the middle layer, there are four new interfaces introduced by the WSERV performance improvements: CWsPlugin, MWsFader, MWsRenderStageFactory and CWsRenderStage.

  3. In the bottom layer, there are the concrete implementations of the new interfaces.

The classes in the above diagram are as follows:

  • CWsPlugin is the base class from which the top level objects presented by plug-ins should derive.

  • MWsFader is the interface that the plug-in object in a fader plug-in should present. Thus the concrete implementation of a fader should derive from CWsPlugin and MWsFader.

  • MWsRenderStageFactory is the interface that the plug-in object in a render stage plug-in should present. Thus concrete implementations of render stage factories should derive from CWsPlugin and MWsRenderStageFactory.

  • CWsRenderStage is the abstract base class for render stages. Concrete implementations should derive from this. (Note that CWsRenderStage is *not* a subclass of CWsPlugin. The plug-in provides only a render stage factory. Render stages must then be obtained from the factory.)

Why do render stages have factories, but faders do not? The idea here is that faders are not expected to have any internal state, and therefore a single fader instance can be shared across multiple screens. Therefore there is no need for a factory. On the other hand, render stages could have internal state (such as stored draw commands or offscreen bitmaps), and therefore each screen needs its own instance. Therefore we need a factory to create the instances as required.

Note that in addition, we may want multiple render stages (of different types) per screen, if they are chained. Therefore we will typically have multiple render stage factories. For example, in the default configuration, there are two render stage factory plug-ins, producing flicker buffer and standard render stages respectively.

New object provider extensions

In addition to the above, the WSERV performance improvements provide some minor extensions to existing object provider interfaces, together with the following new object provider extension interfaces:

  • MWsWindow – an interface through which windows can be examined

  • MWsScreenRedraw – an extension of the existing MWsScreen interface for handling the animation aspects of the redraw sequence

  • MWsScreenRedrawObserver – an interface for receiving notifications of screen updates

  • MWsMemoryRelease – an interface which enables plug-ins to cooperate with WSERV by releasing memory when requested (for example caches)

  • MWsGcClipRect – an extension interface that can be requested from an MWsGc, providing some functionality to do with clipping rectangles which was omitted from the original MWsGc implementation

  • MWsPluginManager – enables plug-ins to request services from other plug-ins

  • MWsIniFile – enables plug-ins to read the WSINI.INI file

Each of these new interfaces inherits from the existing MWsObjectProvider interface, and they are made available through the object provider mechanism. In other words, each interface has an associated “type id”, and the interface is obtained by calling MWsObjectProvider::ResolveObjectInterface(<type id>) on an appropriate object provider. In the case where a plug-in wants to request the interface, the object provider will be WSERV’s MWsGraphicDrawerEnvironment, which is passed to plug-ins during construction.

Fader plug-ins

Fader plug-ins enable WSERV to delegate the implementation of window fading. This means that when RWindowTreeNode::SetFaded() or RWindowBase::FadeBehind() is called on the client side, WSERV calls the fader plug-in to do the fading. Note that fader plug-ins are not involved in CWindowGc fading. Calls to CWindowGc::SetFaded() do not result in calls to fader plug-ins – WSERV passes them straight through to the rendering backend as GDI calls.

In principle, fader plug-ins enable the implementation of custom fading algorithms. However, one potential limitation at the moment is that the existing client-side APIs dictate the form that parameters to control fading must take - therefore RWsSession::SetDefaultFadingParameters(TUint8 aBlackMap,TUint8 aWhiteMap) has to be used. In addition, RWindowTreeNode::SetFaded() has a variant in which these parameters can be passed in. The API that fader plug-ins present to WSERV has been designed so that fading parameters can be passed as opaque binary data. However, as it stands this data will always take the form of two TUint8 s.

Note: In ScreenPlay, fading effects can be created using render stages. See Window Server Plugins Component for more information.

Render stage plug-ins

Render stage plug-ins are designed to allow the customizations of the final stages of the rendering pipeline. The idea is that, to WSERV, a render stage looks pretty much like the graphics context that it is expecting to use to draw to a screen. WSERV carries on with its usual tasks, tracking dirty rectangles and so on, and issuing draw operations when it believes that it needs to repaint some region of the screen. However, instead of these draw operations being used immediately to repaint the screen, they are passed to a render stage. The simplest render stage implementation would indeed use the draw operations to repaint the screen. However, the render stage may do other things with the draw operations, such as capturing some of them for later use in a transition effect or redirecting them to another target and so on.

The render stage API is such that every time WSERV wants to do a redraw, it must call CWsRenderStage::Begin() in order to get hold of the graphics context with which to do the drawing. When it is finished, it must call CWsRenderStage::End(), and release its pointer to the graphics context. This means in particular that render stages understand that draw operations come in blocks corresponding to a single redraw.

Render stages can be chained, so that the output of the first render stage (in the form of draw operations), passes not to the screen but to a second render stage. In the default implementation supplied with WSERV, two render stages are used to achieve flicker-free drawing. The first render stage takes the draw operations that are passed in, and draws them to an offscreen bitmap. When CWsRenderStage::End() is called, it then blits the updated region to the second render stage. The second render stage draws to the screen. This setup therefore eliminates flicker within individual redraws.

For information about render stages in ScreenPlay, see ScreenPlay Render Stages.

Key classes

All classes belong to wsgraphicdrawer.lib.

Class name Description

CWsPlugin

This is the base class that all top-level plug-in objects must derive from. Note that it is an abstract class – in particular it does not provide an implementation of ResolveObjectInterface() (inherited from MWsObjectProvider) – subclasses are expected to do so for themselves.

MWsFader

This is the interface that fader plug-ins are required to implement.

MWsRenderStageFactory

This is the interface that render stage factory plug-ins are required to implement.

MWsWindow

This interface represents a window, and provides plug-ins with information about some attributes of windows. Currently, the only way to get hold of an MWsWindow is from the new TWsCREvent EWindowClosing event. The intended use is for transition engines to discover information about a window that is closing.

MWsPluginManager

An interface enabling plug-ins to get pointers to other plug-ins, enabling them to use the services of other plug-ins. An example use would be that a platform provider could write a plug-in providing a new interface MWsBitmapCache. They could modify the WSINI.INI file to ensure that this plug-in was loaded. Then other plug-ins could request the MWsPluginManager interface from the MWsGraphicDrawerEnvironment, and then request the MWsBitmapCache interface from MWsPluginManager. Thus the purpose of this interface is to enable the use case where one writes plug-ins providing services for the benefit of other plug-ins.

MWsMemoryRelease

This is an SPI that enables plug-in objects to assist WSERV in memory management, by freeing memory when requested to do so.

MWsIniFile

An interface enabling plug-ins to read the WSINI.INI file.

New functions in MWsAnimationScheduler

WSERV has an animation scheduler which was previously used to schedule CRP animations, and is now also used to schedule deferred redraws. The default scheduler can be replaced by a plug-in, via the call MWsGraphicDrawerEnvironment::SetCustomAnimationScheduler(MWsAnimationScheduler*). The class MWsAnimationScheduler already contained functions relevant to CRP animation, but the WSERV performance improvements add new functions relevant to deferred redraw.

New functions in MWsGraphicDrawerEnvironment

MWsGraphicDrawerEnvironment is an existing class. It is an interface provided to all plug-ins, which makes available some generic services. The new functions are primarily for registration/unregistration of event handlers and memory releasers.

New functions in TWsCREvent

TWsCREvent is an existing class. It provides event reporting of some WSERV internals to Content Rendering Plug-ins (and now other plug-ins too). It is typically used by transition effects plug-ins, to provide them with additional information about what is happening inside WSERV. The new functionality is a new event to notify that a window is closing.