This topic provides an introduction to drawing graphics to the screen.
Variant: Both (ScreenPlay and non-ScreenPlay). Target audience: Application developers.
Applications can draw to any RDrawableWindow —such as an RWindow —via a graphics device, of type CWsScreenDevice, and a graphics context, of type CWindowGc. These classes are derived from the GDI component classes CGraphicsDevice and CGraphicsContext, respectively. This means that general drawing functions can be used for drawing to windows, as well as to other graphics devices. The Window Server itself does not provide the facilities to draw graphics to a physical device. CWindowGc functions are not passed to the Window Server directly. Rather, they are stored in a buffer maintained by the Window Server Client API. This buffer is flushed to the Window Server only rarely. By this means the context switching involved in drawing is minimised, and system performance significantly enhanced.
CWsScreenDeviceminimized encapsulates the device-dependent aspects of graphics operations. Graphics functions are not carried out directly via a CWsScreenDevice, however, but via a graphics context with which it is associated. The graphics context class, CWindowGc, provides a rich set of drawing functions, including functions to draw lines, arcs, polygons, text and bitmaps.
A graphics context contains a collection of configurable parameters concerned with graphics, such as pen width, pen color, brush color. It is stored in the server, thus reducing the amount of information that has to be sent with each graphics call. The graphics call simply specifies the graphics context it wishes to use, and a single graphics context can be shared between multiple windows.
To draw to a graphics context it must be associated with a window. Typically a graphics context is created when a session is constructed, and that graphics context is shared between several windows in the application. When the window needs to use the graphics context it calls CWindowGc::Activate(). If necessary it can change the graphics context's settings. CWindowGc::Deactivate() should be called first if the graphics context is currently active upon another window.
Several optimizations are used by the Window Server to obtain high-performance graphics:
Each window is associated with an RWsSession which is in turn associated with a client-side buffer. Instead of implementing graphics operations by a direct client-server call, which involves expensive context switching, all graphics operations are stored as opcodes in the buffer, and the buffer is only flushed in certain circumstances.
The CFbsBitmap class allows a bitmap to be shared between all threads in the system, including the client and the Window Server. This sharing is mediated by the Font and Bitmap server. The CWsBitmap class eliminates further context switches by taking ownership of the handle of the bitmap. Applications can use this class to more efficiently open, blit-to-screen, and close a series of bitmaps. Use functions that take a CWsBitmap in preference to those that take a CFbsBitmap, because they are faster.
A single graphics context may be used for drawing to many windows—it is not necessary to have one per window. The Activate() function associates a CWindowGc with a particular window.
Provided drawing operations to an RWindow are performed as redraw drawing, the Window Server stores the sequence of drawing commands that represent the window contents in redraw stores. Then when the Window Server needs to repaint the window (because, for example, a dialog box popped up over it and has now closed) it simply replays the sequence of stored commands, rather than sending a redraw request to the client. This minimizes the number of client-server transactions and means that windows are repainted as soon as the Window Server detects that they are needed.
This means that all CWindowGc drawing should now be redraw drawing, which means that it takes place between RWindow::BeginRedraw() and RWindow::EndRedraw() calls. If you use the CCoeControl::DrawNow() and CCoeControl::DrawDeferred() methods, the UI Control Framework (CONE) takes care of this for you. See Redraw Drawing for more information.