Double Buffering

Microchip Graphics Library

Microchip Graphics Library
Double Buffering

Manipulating pixels on the screen requires direct writes to the frame buffer. While these changes are being executed, the screen is also refreshed. This means that the changes are displayed immediately as the frame buffer is being updated. This is not a suitable scheme when the changes are slow, for example, decoding an image or having a large number of widgets on a screen. The display may appear slow in that case. One solution to this problem is to use a double-buffering scheme supported by the Microchip Graphics Library. In this scheme, the changes are not directly written to the frame buffer, but instead, they are written to a separate buffer, called the ‘Draw Buffer’. After all the changes are made, the draw buffer and frame buffer are exchanged. Now the draw buffer becomes the frame buffer, and because of all the changes drawn there, the changes appear spontaneous to the user. Of course, there will be a delay, as all the changes have to be written to the draw buffer before displaying it. This delay is generally more tolerable than displaying the changes slowly. After exchanging of the buffers, the latest buffer (which is now the frame buffer) is copied to the new draw buffer in the background and then the new draw buffer is in sync with what is being displayed. New changes are then written to the draw buffer and the cycle continues. As the double-buffering scheme uses two buffers, the RAM requirement will double. 

 

In the Microchip Graphics Library, if double-buffering is enabled, the frame buffer and draw buffer are exchanged after the changes of all the widgets on a screen are done (i.e., the new screen appears after the whole screen is updated and not after updating an individual widget). 

 

The work flow of double-buffering is graphically explained along with tips on deciding when to use double buffering in the APPENDIX B of the Application note AN1368: Developing Embedded Graphics Applications using PIC® Microcontrollers with Integrated Graphics Controller. 

 

To use double buffering in an application, follow the steps described below: 

 

1. Enable the option USE_DOUBLE_BUFFERING in GraphicsConfig.h 

2. Update GFX_DISPLAY_BUFFER_LENGTH to include both the buffers in HardwareProfile.h. Note that when using external memory the GFX_DISPLAY_BUFFER_LENGTH must fit into the external memory size. For example in PIC24FJ256DA210 external memory can be added using EPMP. External memory mapped to the EPMP must be big enough to accommodate the display buffers required by double buffering. See Set Up Display Interface for more information on memory requirements. 

3. Check the jumper settings to enable the required RAM address space on the development board 

 

If Graphics Objects Layer (GOL) is used in the application, the switching of buffers is handled automatically in order to keep the switching task transparent to the users. If double buffering is enabled in applications using only the Primitive layer, then the switching of buffers has to be handled by the application itself as explained in the following steps. 

 

Steps required for manually handling the switching of buffers: 

 

1. After InitGraph() is called, call the APIs InvalidateAll() followed by UpdateDisplayNow(). The two buffers are properly setup after these calls and from this point onwards, the drawing happens on the draw-buffer. 

2. When a shape is drawn on the draw buffer, that rectangular area has to be marked as invalid by using the API InvalidateRectangle(left, top, right, bottom). Only the invalidated rectangular areas are copied to the frame buffer in order to reduce the copy operations thereby reducing the overall time and energy required to sync the two buffers. Hence, it is important to invalidate the changed rectangular areas failing which the change doesn’t show up on the display. 

3. Call either RequestDisplayUpdate() or UpdateDisplayNow() to sync the two buffers and as a result the changes appear on the display. The former API exchanges the buffers during the next display blanking period on TFT LCDs causing the change to appear smooth and immediate whereas the latter API exchanges the two buffers at the time of the API call probably causing a slight flicker on the display. On displays which doesn’t support blanking periods (e.g. CSTN LCDs), the effect of RequestDisplayUpdate() is same as that of UpdateDisplayNow(). 

 

Even if double buffering is enabled at compile time, it can be switched off and on at run time using APIs SwitchOffDoubleBuffering() and SwitchOnDoubleBuffering(). Switching double buffering on/off at runtime is useful in applications which need some screens having fast updates like waveform or animation which requires double buffering to be switched off and some other screens where double buffering is beneficial. 

 

Note: In applications using Graphics Objects Layer and double buffering, the double buffering is not immediately enabled after the API GOLInit() is called in order to support hassles splash screens but is automatically enabled from the second screen update onwards. If double buffering is needed from the first screen itself, then follow step 1 immediately after calling GOLInit().

Functions
 
Name 
Description 
 
Switches off the double buffering. All rendering will be performed on the frame buffer. Calls to UpdateDisplayNow() or RequestDisplayUpdate() will have no effect. 
 
Switches on the double buffering. Double buffering utilizes two buffers. The frame buffer and the draw buffer. The frame buffer is the buffer that is being displayed while the draw buffer is used for all rendering. When this function is called, it copies the contents of the frame buffer to the draw buffer once and all succeeding rendering will be performed on the draw buffer. To update the frame buffer with newly drawn items on the draw buffer call UpdateDisplayNow() or RequestDisplayUpdate(). 
 
Invalidates the specified rectangular area. This increments the number of invalidated areas and if the number of invalidated areas exceed the GFX_MAX_INVALIDATE_AREAS, the whole frame buffer is invalidated. 
 
Synchronizes the draw and frame buffers at next VBlank 
 
Synchronizes the draw and frame buffers immediately. 
Module
Links
Microchip Graphics Library Version 3.06.02 - October 15, 2012
Copyright © 2012 Microchip Technology, Inc.  All rights reserved