Next Previous Contents

5. LibGGI usage guidelines

5.1 Hints on memory visuals

Memory visuals are very handy for preparing picture parts and blitting them onto the sccreen with ggiCrossBlit.

To speed this up, the memory visual must use the same pixel coding as the target. You can achieve this with the following code sequence:


ggi_mode memmode;
ggi_visual_t mainvis,memvis;
 ...
ggiGetMode(mainvis,&memmode);
/* now maybe change size, but leave graphtype untouched */
memvis=ggiOpen("memory",NULL);
ggiCheckMode(memvis,&memmode);
ggiSetMode(memvis,&memmode);

Which will try to open the memory visual with exactly the same mode and pixel encoding as the main visual.

5.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.)

Some libGGI functions may not be thread-safe (even with multi-threading enabled, currently). Therefore, only call libGGI functions from one thread.

5.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.)

5.4 Inactivated applications, Redraw requests

If an application loses the focus and is not physically displayed (e.g. console switching, iconifying), it may be stopped. Some targets may implement a backbuffer and allow continuing, though.

After reactivation the application receives a redraw event. It is required to be able to perform a redraw. Whether it needs to re-set it's palette is still undecided.

Example:


        ggi_event ev;

        /* ... wait and get the event... */

        if (ev.any.type == evExpose) {

                if ((ev.expose.w == 0) && (ev.expose.h == 0)) {
                
                        /* redraw whole screen... */
                        redraw_screen(0, 0, screen_w, screen_h);
                        
                } else {
                        /* redraw part of screen... */
                        redraw_screen(ev.expose.x, ev.expose.y,
                                      ev.expose.w, ev.expose.h);
                }
        }
        
        /* ... etc ... */

5.5 Environment variables

GGI_DEBUG

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

GGI_DEFMODE

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

export GGI_DEFMODE=800x600

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

GGI_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 GGI_DISPLAY="display-trueemu:8:display-X"

display-multi

allows multiple displays with identical properties: export GGI_DISPLAY="display-multi:x;x;xlib"

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


Next Previous Contents