==============================================
GGI : Yet-Another Graphic Interface? Not quite
==============================================

:Author: Brian S. Julin
:Date: 2003-03-15
:Revision: $Revision: 1.5 $
:Revision date: $Date: 2004/03/02 12:38:43 $

.. contents::
   :depth: 1

This article was written for the `Free Software Magazine`__.

__ http://www.rons.net.cn/


Genesis
=======


If you've ever coded for a graphics program like a game or demo, or
written a toolkit for GUI based applications, you've probably noticed
how very suboptimal the state of graphics libraries and display APIs
is today.  Odds are, when you began, you spent a good deal of time
trying to choose between systems like Xlib, DGA, DirectX/DirectDraw,
SVGALIB, various OS framebuffer devices, SDL, and DirectFB.  You made
some compromises and did some workarounds to get your code running,
and then sometime later when the whole thing worked, you realized a
lot of people wanted to run your console application in X windows, or
visa versa, or that performance wasn't as good as you had hoped, or
that it only worked on certain hardware.  In order to expand the user
base, you may even have ported it to additional graphics back-end
systems -- and in the process found that you had to rework your code
not only to accomodate for the shortcomings of the new graphics
systems and quirks resulting from the shortcomings of the original
graphics system, but also switch to a completely different input
device system, since most back-ends seem to be hopelessly entangled
with a particular input API.


Why do we put ourselves through this mess?  Why does every
graphics-using project have a huge stash of source code containing
re-implementations and re-inventions of a general graphics interface
-- re-implementations which seem to unfortunately always be too
tailored to the individual application to be re-used by others?
That's exactly what the founders of the GGI project were asking
themselves when they began to pour molten metal in their hidden caves
and beat it into the shape of things to come.  With the exception
perhaps of SDL, which has managed to claw its way to some popularity
by having a fair number of implemented back-ends and an interface
which is usable by a good portion of programs, noone had put serious
effort into pooling this solution set into a truly re-usable codebase
for graphics applications.  GGI aims to do just that -- and to create
a new framework where higher level functionality can also begin to
collect into a common codebase.


Design and achievements
=======================


The GGI Project was founded on a few principals which are admittedly
rather obvious...  but the unique thing about GGI is it stuck to them
with a fervor, and the result has been some very beautiful code
indeed.



One of the principals is that an API should come without strings
attached, and so should a library's runtime requirements.  For
example, if a programmer does not want to use the GGI Project's input
system (LibGII), it can be disabled, leaving input handles and devices
free to be driven by something else.  Furthermore, the entire project
is modular, abstracting graphics back-ends to the point where the
computer running a binary does not need to have every back-end
installed in order to use LibGGI -- in fact, the same binary can be
run on one machine, say a machine where there is no xlib installed,
and then be copied to another machine and run inside an X window,
without recompiling it from source.  The GGI Project even went so far
as to divide APIs into levels such that if you do not need e.g. fast
2D blended triangle operations, you don't need to install the module
that provides that functionality -- and consequently you do not need
to implement 2d blended triangles for new/private/esoteric graphics
back-ends if all you want to do is access a framebuffer.  This is
important because it allows the application programmer to make
informed decisions balancing portability (some systems will never be
able to do fast 2d blended triangles) against functionality -- code
for the minimal API subset that provides what you need, and the result will
be that your application runs on the maximum number of platforms and
graphics back-ends capable of supporting it.  This level of granularity 
will make GGI Project libraries equally as well suited for large complex 
workstation applications (even full desktop environment servers such
as Berlin_ as they are for
slimmed-down embedded appliances.

.. _Berlin: http://www.fresco.org


Another principal GGI strove for was to please 99% of the people 99%
of the time. Special attention was payed to ensuring that GGI could
tweak every common aspect of a graphics back-end (and there is a
method that allows external user configuration to tweak
back-end-specific aspects), but also to avoid requiring simple
applications to pass large numbers of parameters to a very complicated
API function with a 20KB manpage.  Consider the difference between
LibGGI's ggiCheck* family of functions and the functions used by many
other graphics libraries.  LibGGI's ggiCheckMode function allows the
user to specify many aspects of the desired video mode -- visible and
virtual size, graphics scheme and bitdepth, number of frames
(double-buffer, triple-buffer, etc.) to name a few, and simultaneously
allows other aspects to be auto-optimized.  Many other APIs provide a
list of supported modes, which must be be checked one-by-one until a
satisfactory mode is found.  However, LibGGI also provides a
ggiSetSimpleMode, which does what most applications want -- gets the
*best* mode available.  Most GGI Project APIs are designed like this,
with powerful do-all functions which are there to cover the bases when
the easy-to-use convenience functions aren't smart enough.


Another goal of course was speed.  The GGI Project's highly modular
architecture could have been layered into some sort of complex,
gratuitously object oriented paradigm, but instead stuck with simple C
and spartan faux-OO techniques.  In most cases, the modularity costs
only one extra level of indirection/calling overhead, which on most
systems is virtually unnoticable.  The overloadable system developed
by the GGI Project allows layout/pixelformat/hardware optimizations to
be dynamically loaded at various levels without additional overhead.
(In this last aspect we must admit we are still short of our goal,
because there remains work to be done in actually building a larger
portfolio of dynamically loadable accelerations and extending
accelerations to higher level GGI Project APIs.)

.. image:: ../resources/images/brian-fsm-graphic.png
   :height: 700
   :width: 700
   :align: center

A few side-benefits emerged from the LibGGI architecture.  First,
LibGGI is easily integratable into other programming languages (C is,
after all, the common denominator of 99% of computing languages).
Wrappers for both python and PERL have been produced for the base
LibGGI library.  Second, the overall axiom of the project ("Do The
Right Thing") may have caused GGI Project participants to spend a good
deal of time and effort covering corner cases and implementing facets
which may rarely be used, but in doing so LibGGI has become sort of a
reference book which gives a good read of the state of the art of
basic graphics subsystems.  If you want to assess the shortcomings or
benefits of a graphics system, read the *display target* code of some
GGI Project libraries for that system.  Ugly code tends to accumulate
around the places where a back-end falls short.  I would say that this
is the reason why our sister `KGI Project`_ emerged and began trying
to develop the perfect graphics back-end, but I suspect the founders
of the KGI Project had that in mind long before LibGGI was released to
the public.


.. _KGI Project: http://www.kgi-project.org

Finally, the GGI Project applied the same principals in creating
LibGII, which provides a portable event interface covering a large
variety of input devices and libraries across many platforms and OSes,
and a modular filter system that allows some pretty neat tricks, to
boot.


Where are we going now?
=======================


So what is up with GGI these days?  Well, we have admittedly been
stuck on a log in that LibGGI and LibGGIMISC, our production quality
graphics libraries which are available today in many OS distributions
(Debian_, Mandrake_, Gentoo_, NetBSD_, FreeBSD_, OpenBSD_), do not
fulfill the expectations of a large number of application developers.
However, we are determined to take the GGI Project to the next level
by providing extensions that cover the needs of modern applications --
APIs for fast blending, blitting, and overlays have been drawn up and
prototype implementations are being completed.  This phase will allow
LibGGI to compete in the area of heavily menu-driven applications and
applications providing motion video.  From there, depending on how
OpenGL2 fares, we will decide how to proceed with GGI's 3D
implementation.

.. _Debian: http://www.debian.org
.. _Mandrake: http://www.mandrakesoft.com
.. _Gentoo: http://www.gentoo.org
.. _NetBSD: http://www.netbsd.org
.. _FreeBSD: http://www.freebsd.org
.. _OpenBSD: http://www.openbsd.org

Currently we are wrestling with the issue of marrying the basic object
paradigm, which can entail storage, efficiency, and transfer
overheads, with the display-list/vector-list/programmable-pipeline
paradigm, where data is arranged in back-end-specific manners for fast
transfer to accelerated graphics engines -- it has been a challenging
and educational discussion so far and though we feel we are near
closure, folks are welcome to drop by and throw a monkey wrench or two
into the plan -- what doesn't kill it will make it stronger.


Conclusion
==========

In closing I would like to appeal to the reader to really think about
the benefits that a mutual graphics codebase, fully opensource and
fully under opensource community control, provides.  Often our
greatest obstacle is that application developers do not realize that
with some extra effort, a good portion of their applications could
become generic library code which would be reusable -- and enhancable
-- by a large number of people.  Don't underestimate the utility of
that 3/3/2-to-5/6/5-RGB-anti-aliased-triangle-copy routine you have
lurking on your hard disk.  Categorizing, abstracting, and
modularizing basic algorithms into a coherent set of APIs seems like a
lot of work when you are doing it, but it saves everybody a lot more
work in the long run.  Interested developers can hook up with us on
our mailing list or IRC channels.


