A Longer Introduction to GGI

Revision : 1.2
Revision date : 2004-03-02

This document gives on overview of the principles on which the GGI project is based, without going into implementation details.

The GGI concept of display

Visuals and targets

GGI aims at unifying the way applications access the user display by defining a generic abstraction of the notion of graphic display.

Generally speaking, a display is a 2D surface that can be drawn on and with which a user can interact. Whatever the physical displays actually are (a TV screen or an X11 window) they always have this basic in common. Of course, they all have specific characteristics and low-level access methods, but the idea behind GGI is that this difference is not a concern to the application.

So basically, GGI defines high-level abstraction of input sources and displays, with a small set of management functions and general drawing operations.

In GGI, the abstraction of a display is called a visual, and the actual device to which a visual is bound is a target. Targets can be anything from an X11 window to a 10 meter wide multi screen display. The association of a visual and a target is done at runtime by GGI internals and the process is transparent to the application.

Basic features of a visual

Visuals must first be opened and configured, and LibGGI abstracts this process as well as the actual use of the visual. That means that even the action of deciding your visual's resolution and bit-depth is independent of the target. In addition, unlike a lot of other graphics libraries, LibGGI allows you to negotiate for a display mode -- even when you are currently using the display. This means communication between your application and LibGGI is a two way street: you can tell LibGGI what you want from the display, and LibGGI can tell you what is available, allowing your application to operate in a display mode optimal for it's purposes -- all without the end user needing to reconfigure the back-end target.

LibGGI provides full access to information about color depths and pixel formats, which provides as much detail as anyone could desire about how the back-end target prefers to store pixels. Yet, at the same time, LibGGI also provides a level of abstraction which allows applications to run independent of the color depth. LibGGI supports color depths and pixel schemes from monocrome through 4 and 8 bit palette to full 32-bit color.

LibGGI displays can perform the drawing operations that form the basic building blocks needed for most applications. This basically breaks down to filling rectangles with solid colors or loading them with data, or copying/moving them around. LibGGI subdivides the rectangle operations up in such a way that they can either be built out of more basic operations, or utilize special acceleration features of any given back-end target. The building block functions are available directly to the user, so operations other than rectangles are easy to construct and will be relatively efficient.

In addition, all LibGGI displays can contain a LibGII input, which allows receiving and sending events from a large variety of input systems, with the same benefit that the back-end input system can be changed.

Adding features

The basic operations on visuals, as defined by GGI, are intentionally limited. It's impossible to define an API for all possible graphic features because of the variety of hardware, and the fact that graphic needs are constantly evolving. Such an API would be bloated and quickly obsolete. The GGI answer is to implement only a simple set of universal features, and leave the rest for extensions.

GGI offers a dynamic extension mechanism that allows additional features to be attached to a visual at runtime. A simple extension can be specially written to access exotic features found in a very specific hardware, or to abstract fairly common features by providing an implementation for them on a variety of different targets.

What makes GGI so good

GGI's modular design is a real plus in the tough, wild and fast moving world of graphic technology, where only the strongest can survive.

Targets

Since targets are dynamically chosen at runtime, the same application can run on different displays without recompilation. You don't have to worry anymore about the end-user graphic subsystem.

GGI has back-ends for a wide range of targets : X11 windows, svgalib, memory (not really visually impressive:), fbdev, DirectX, glide and more. There is even an ASCII target for text console : playing Quake in text-mode is a psychedelic experience. The tele target which allows an application running on a machine to transparently display onto another machine over a tcp network, or the tile target splitting a virtual display into different visuals, are good illustrations of GGI strength. The ultimate target for GGI is KGI : the Kernel Graphic Interface, which provides secure user land access to all graphic hardware features and acceleration.

Extensions

The extension mechanism is another the strength of GGI.

For the end user, it allows to limit the installed libraries to what is necessary for a given application to run. Thus, the memory usage can stay very low for embedded application.

From the developer point of view, the API stays as simple as it needs to fit his purpose.

The most interesting thing is that the features a display can have are not limited by the basic functionalities defined by GGI. If a new ground-breaking graphic feature appears, an extension can be written for it. Imagine people becoming suddenly hysterical about this brand new advance in 2D graphic : split your display horizontally or vertically into n slices and shuffle them. It can be implemented in GGI via an extension, which can be added to any system without touching what's already there.

As the core of GGI is becoming more and more mature, a number of of extensions are being developed, with the same care for genericity and simplicity without functionality tradeoff.

Organization of the GGI libraries

The big picture

Concretely, GGI is a set of libraries implementing the concept described above, plus a few other nifty things. These libraries are divided into several categories.

The most important set is ggi-core, containing libgii, libggi and libgalloc. They define the basic data structures and provide the extensions and targets management code, as well as a set of basic drawing primitives. This book is mainly focused on these.

The lowlevel libraries are extensions which gives access to the features found in modern graphics hardware, such as blitting and overlay operations.

Highlevel libraries are basically wrappers for higher-level graphic rendering interfaces, like libxmi. It eases the porting of applications to ggi.

The ggi-libs set of libraries make use of the lowlevel extensions to further abstract graphic features. For example, the LibBSE sprite interface internally makes use of lowlevel features to provide either a true overlay, or emulate an overlay using Blt functions.

GGI also has bindings for other popular languages like Perl and Python.

The core libraries

We will focus on the three main components of GGI : LibGII, LibGGI and the newcomer LibGAlloc, which form the base of a what is called GGI.

LibGII (General Input Interface) defines input source abstraction. An typical event-driven application receives events from various sources(mouse, keyboard,...) and reacts accordingly. LibGII provides an event-queue mechanism.

LibGGI defines the display abstraction. It performs basic mode negotiation with the underlying device and open/close visuals. It uses LibGII internally to bind inputs to an opened visual. Furthermore, it provides basic drawing primitives (lines, point, box) and a simple unfeatured blitting operation.

LibGAlloc (Graphic Allocator) is the youngest of the three and defines a resource system for feature abstraction. It allows applications and extensions to know which features are available on a target (sprites, VRAM, Z-buffers, motion video windows, etc.). It also provides a resource request mechanism, based on feature priority, which helps applications to grab possibly concurrent resources in a clean and optimal way.