Refer to the previous article on the Internet to reorganize the knowledge of Dual-buffering and DSA on the screen!
(1) graphic settings and graphic Context
The application must use a graphical device and graphical context to draw a graph.
A graphical device is a drawing object (such as a screen or printer). A graphical device context provides a device abstraction mechanism to completely block a specific graphic device, when using these graphics devices, applications only need to interact with these abstract graphics devices without considering their specific devices.
The graphic context is a collection of tools required for the painting platform and painting. It also includes the size, direction, color of the platform and all the accessories that can achieve the painting imagination.
The following figure shows the graphic devices used in Symbian and their functions. They are the basis for painting.
Graphics Devices |
Description |
CGraphicsDevice |
Basic Category of graphics Devices |
CBitmapDevice |
Basic class of bitmap graphics Devices |
CFbsDevice |
Graph device base class using the font bitmap Server |
CPrinterDevice |
Device base class with printing function |
CWsScreenDevice |
Use the screen device of the window Server |
CFbsBitmapDevice |
Specific implementation of devices using the font bitmap Server |
CFbsScreenDevice |
Direct screen access (DSA) without passing through the window Server |
The inheritance relationships of these devices are as follows:
CWindowsGcFor screen painting, CFbsBitGc for memory painting!
(2) Double Buffering
Generally, the application uses the CWsScreenDevice Graphics Device to describe on the screen, which is associated with the CWindowGc graphics context. CONE provides a CWindowGc instance as the standard graphical context of the Drawing Control. It is created by CCoeEnv and can be accessed using the CCoeControls: SystemGc () method. The CWindowGc method is used to buffer the client window Server Buffer.
Void CExampleControl: Draw (const TRect &/* aRect */) const { // Get the system graphics context CWindowGc & gc = SystemGc (); // Set drawing settings Gc. SetBrushStyle (CGraphicsContext: ESolidBrush ); Gc. SetBrushColor (KRgbRed ); // Draw Gc. DrawLine (TPoint (10, 10), TPoint (30, 10 )); } |
DrawNow () forces the control to re-draw itself immediately, while DrawDeferred () causes a re-draw event to use low-priority operations!
If a game's graphics are composed of multiple motion objects that need to be updated frequently, the client buffer of the window server may be filled and may overflow when all objects are updated, the screen may flash. If a view is still being updated, it may flash or have other undesirable effects. The solution to these problems is dual buffering. The image is first painted on an off-screen bitmap and then painted on the screen as a single window server. Especially for games that redraw screens several times in one second, using off-screen bitmaps can improve their performance.
An out-of-screen bitmap can be created using bitmap graphics context and graphics equipment class: CFbsBitGc and CFbsBitmapDevice. They are created and used using other context and device classes. For extra performance, the bitmap itself should be a CWsBitmap bitmap. After the screen bitmap is updated, it can be painted in the window using the normal method of the window server.
When an application draws a bitmap in a window, it is converted to the same display mode as the window. This is a very time-consuming operation, which may actually reduce the plotting speed. Therefore, the game that uses bitmaps for animation should complete the conversion before the animation starts.The conversion can be performed by using an off-screen bitmap, as shown in the following example:
CFbsBitmap * CExampleControl: LoadAndConvertBitmapL (Const TDesC & aFileName, TInt aBitmapId) { // Load the bitmap CFbsBitmap * originalBitmap = new (ELeave) CFbsBitmap (); CleanupStack: PushL (originalBitmap ); User: LeaveIfError (originalBitmap-> Load (aFileName, aBitmapId, EFalse )); // Create a new bitmap, graphics device and context CFbsBitmap * newBitmap = new (ELeave) CFbsBitmap (); CleanupStack: PushL (newBitmap ); NewBitmap-> Create (originalBitmap-> SizeInPixels (), Window ()-> DisplayMode ()); CFbsBitmapDevice * graphicsDevice = CFbsBitmapDevice: NewL (newBitmap ); CleanupStack: PushL (graphicsDevice ); CFbsBitGc * graphicsContext; User: LeaveIfError (graphicsDevice-> CreateContext (graphicsContext )); TPoint zero (0, 0 ); // Bmap the loaded bitmap to the new bitmap GraphicsContext-> BitBlt (zero, originalBitmap ); CleanupStack: Pop (3 ); Delete graphicsContext; Delete graphicsDevice; Delete originalBitmap; Return newBitmap; } |
The example uses a file name and a bitmap ID as the parameter, and loads the corresponding bitmap from an MBM file. If a game has many bitmaps that should be converted, it should be converted in the game or Level Initialization phase, so the user will not see this operation.
(2) Direct screen access (DSA)
Using a window server to draw images on the screen requires a context conversion, which slows down the painting speed. To bypass the window server, you can directly access the screen without tedious context conversion. This is called direct screen access.
There are two methods in Symbian OS to draw images directly on the screen:
① CFbsScreenDeviceIsScreen driver SCDV. DLL. After creating a CFbsBitGc image context, it can be used like any other graphics device. However, you can draw images directly on the screen without using a window server.
②Another way to draw images directly on the screen isQuery the screen memory address from the system,This can be achieved using the UserSrv class:
TPckgBuf InfoPckg; TScreenInfoV01 & screenInfo = infoPckg (); UserSvr: ScreenInfo (infoPckg ); TUint16 * screenMemory = screenInfo. iScreenAddress + 16; |
The screen memory has a 32-byte header.
Even if writing data in the screen memory is a little faster than CFbsScreenDevice, the function may vary depending on the hardware and the driver of the screen.In some Symbian OS-based terminals, the screen is automatically updated from the screen memory when the memory changes, while in other terminals, it needs to be explicitly activated.. The screen memory address is only valid for the target hardware. Therefore, the plotting code must be divided into two parts: hardware and simulator. In the simulator environment, you can draw an out-of-screen bitmap instead of the screen memory, and then use the normal window server to draw a method block to transfer it to the screen.The environment can be detected by using the _ WINS _ definition.
# Ifdef _ WINS _ // Emulator environment
// Draw to an off-screen bitmap
# Else // Hardware environment
// Draw directly to the screen memory
# Endif
One common problem between the two direct plotting methods is that the window server does not understand the plotting.Therefore, it cannot notify the application whether another window or window group exists. Even if an application gets an event when it loses focus, it cannot stop Directly Plotting because it is too fast and the screen content may be messed up. This may happen when a phone call comes in during a game.
The latest GT 6.1 version provides an Application Programming Interface for direct plotting, which can solve the problems mentioned above.
This application programming interface consists of two classes:A MDirectScreenAccess class that provides callback methods for applications, and a CDirectScreenAccess class that processes communications with window servers. The following code describes how the CDirectScreenAccess instance is constructed and how the direct drawing support is activated.
IDrawer = CDirectScreenAccess: NewL (iEikonEnv-> WsSession (), * iEikonEnv-> ScreenDevice (), Window (), * this );
IEikonEnv-> WsSession (). Flush ();
IDrawer-> StartL ();
IDrawer-> ScreenDevice ()-> SetAutoUpdate (ETrue );
The NewL method of CDirectScreenAccess obtainsWindow Server session,CONE graphics Devices,Application WindowAndA pointer to the MDirectedScreenAccess export classAs a parameter. Before CDirectScreenAccess: StartL is called to activate direct plotting, the client window Server Buffer should overflow.In order to automatically update the screen, the SetAutoUpdate method of the screen device must use the ETrue parameter. Otherwise, the gc draw command will not be immediately displayed in the simulator, but will not be displayed in the next Flush window server.When direct plotting supports activation, CDirectScreenAccess generates a CFbsBitGc graphical context that can be used by applications to draw images on the screen.
IDrawer-> Gc ()-> BitBlt (TPoint (0, 0), iBitmap );
When another window appears in the application window, CDirectScreenAccess obtains an event from the window server to interrupt the profiling.CDirectScreenAccess then calls the AbortNow method of the derived class of MDirectScreenAccess. This method must be reloaded by the application to interrupt plotting.To prevent screen clutter, the window server does not draw overlapping windows until the trace interruption event is handled.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx? PostId = 1557141