This migration guide explains the guidelines that applications that use direct screen access (DSA) must follow in order to run on ScreenPlay (NGA) devices.
Introduced in an earlier version of the Symbian platform, DSA enables applications that require high frame rates (such as video and games) to bypass the Window Server and write to the screen directly. On ScreenPlay, Symbian recommends the use of EGL window surfaces in preference to DSA.
Support for DSA is maintained for backward compatibility reasons. However, whereas on some earlier devices, applications might work without fully conforming to the rules of DSA, these rules are now necessarily enforced. Applications that follow the following guidelines should run correctly on a ScreenPlay device.
The main classes
of the DSA framework are CDirectScreenAccess
, RDirectScreenAccess
and MDirectScreenAccess
. Before drawing to the screen, the DSA application must create a
DSA session; for example, by instantiating CDirectScreenAccess
and calling CDirectScreenAccess::StartL()
. This
rule applies regardless of whether the application accesses the DSA
framebuffer using CFbsBitGc
, CFbsScreenDevice
or gains a pointer directly through HAL.
Applications that fail to create a DSA session will not work. Applications that draw outside of an active period of DSA will not work. This is because all DSA rendering is directed into a virtual framebuffer and the Operating System uses the DSA session to determine when that framebuffer should be made visible.
The following example demonstrates requesting direct screen access:
voidCMyDSAEngine::StartDrawingL() { // Initialize DSA. TRAPD(dsaError,iDSA->StartL()); if (dsaError==KErrNone) { // Get the graphics context for drawing. iGc=iDSA->Gc(); // Get the region to draw to. iRegion=iDSA->DrawingRegion(); // Set the clipping region to this region. iGc->SetClippingRegion(iRegion); // Start generating timer events (the drawing is done in a timer callback). iPeriodicTimer=CPeriodic::NewL(CActive::EPriorityStandard); iPeriodicTimer->Start(0,KInterval,TCallBack(DrawNextFrame, this)); iDrawing=ETrue; } }
Applications
can access the screen by writing to the video hardware framebuffer
or by using CFbsScreenDevice
. Regardless which
of these methods you use, the application must inform the OS that
the framebuffer has been updated in order for the DSA drawing to be
pushed to the display.
Applications that fail to declare modifications to the framebuffer will not see their content correctly appear on-screen. This is because the OS uses event-driven updating to copy the contents of the DSA framebuffer into the display.
When writing to the video hardware frame buffer, force a screen update by creating a redraw event like this:
TRawEventredraw; redraw.Set(TRawEvent::ERedraw); UserSvr::AddEvent(redraw);
When using CFbsScreenDevice
, force a screen update by calling one of the following:
void CFbsScreenDevice::Update(); void CFbsScreenDevice::Update(constTRegion &aRegion);
The application must not
issue CWindowGc
rendering to a window when DSA
is active on that window. If both types of rendering are required,
the application must ensure that they only happen in distinct periods
demarcated by the DSA session.
Applications that interleave
periods of DSA rendering with periods of standard indirect (CWindowGc
) rendering, expecting to see each painted on
top of the previous, will not work. This is because the OS now uses
two separate framebuffers; one for DSA rendering and one for indirect
rendering. Previous versions of the OS use a single
framebuffer for both types of rendering.
Applications must be written to render the entire contents of their window using either DSA or indirect rendering at any one point of time.