Next Previous Contents

4. LibGGI usage guidelines

4.1 Synchronous and asynchronous drawing modes

Some targets allow different modes with regard to when the screen is updated and the actual drawing takes place.

The synchronous mode is default because it is what most programmers expect: When the drawing command returns, it is already or will be executed very shortly. So the visible effect is that everything is drawn immediately. (It is not guaranteed in the strict sense that it is already drawn when the function call returns, but almost.)

The asynchronous mode is (at least on the X) faster, but does not guarantee that the command is executed immediately. To make sure that all pending graphics operations are actually done and the screen is updated, you need to call ggiFlush(myvis);.

(Side note: The screen refresh the X target does every 1/20 s can take about half the execution time of a program. So syncronous mode can really slow things down.)

As it stands now, all operations are guaranteed to be performed in the order given in both modes. Reordering has been discussed but is currently not done.

So the recommendation for all graphics applications is to set the asynchronous mode. It will be far more efficient on some platforms and will never be worse. (If asynchronous mode is not supported by a target, setting it is still allowed, but has no effect.)

How to set up asynchronous mode?

4.2 LibGGI and threads

It is strongly discouraged to draw to one visual from two (or more) different processes or threads at the same time. While serious damage is unlikely, corrupted graphics output might happen and a big performance penalty is almost guaranteed.

If drawing from two threads is needed, the application is required to synchronise the threads so that not both draw simultanously.

(Side note: Some cards need some sort of paging for accessing their video ram (banked framebuffer). Two threads accessing different parts of the screen would require a page change on each process switch, which could slow them down to a crawl. State information that has to be reloaded to the accellerator engine after every switch would be another example.)

4.3 Mixing LibGGI and direct frame buffer access

Some tricky spots have to be taken care of if you mix libggi calls and direct access to the frame buffer. While direct access is done immediately, execution of a libggi call might be delayed due to the accellerator architecture, so framebuffer access immediately after an accellerated libggi call could actually be executed before or while the accellerator accesses the frame buffer itself, which worst case could lock the card and give best case wrong pixels on the screen.

To make sure that all pending accellerator commands are executed, you need to call ggiFlush(myvis); between a (series of) libGGI call(s) and direct frame buffer access.

(Side note: ggiFlush(myvis); does more than just waiting for the accellerator to finish pending jobs, so there will be another call introduced for only this purpose. Stay tuned.)

4.4 Environment variables

LIBGGI_DEBUG

If this is set to 255 (anything > 0 currently works), debugging output is printed to stderr.

LIBGGI_DEFMODE

This can be used to specify the default target and resolution to use. The common usage is probably only

export LIBGGI_DEFMODE=800x600

for this default resolution, for the complete definition see _ggiParseMode.

LIBGGI_DISPLAY

This variable is used to determine the default display target. Currently allowed values include:

display-X

force usage of X target

display-Xlib

force usage of Xlib target

display-AA

force usage of aalib target

display-memory

force usage of memory target

display-svga

force usage of SVGAlib target

display-dga

force usage of XF86 DGA target

display-glide

force usage of Glide target

display-terminfo

force usage of terminfo target (text apps only)

display-trueemu

emulate a true colour display on a display with lower capabilities, e.g. display true color on an 8-bit X display:

export LIBGGI_DISPLAY="display-trueemu:8:display-X"

If LIBGGI_DISPLAY is unset but DISPLAY is set, this is used to force usage of the X target with the appropriate display.


Next Previous Contents