DSA Migration Guide

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.

Always use a DSA session when using DSA

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;
        }
    }

Inform the Operating System after updating the DSA buffer

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);

Do not mix DSA and non-DSA rendering

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.