
libGGI2D internals
------------------
(please read the libGGI2D specification first)

1. Structure
------------

The drawing functions are implemented in loadable modules,
which are organized in three levels:

generic:
    hardware independent, emulates most high level functions
framebuffer specific:
    functions optimized for a specific framebuffer layout
drivers:
    hardware accelerated functions (KGI), X,Win32 etc. interface,
    access to framebuffers which aren't mmapped.
        
2. The function table
---------------------

libGGI2D uses a function table to call functions
that are optimized for the current graphics context (GC):

void	(*putPixel)(ggi_visual_t vis, int x, int y, ggi_pixel color);
void	(*drawPixel)(ggi_visual_t vis, int x, int y);
void	(*drawPixelA)(ggi_visual_t vis, int x, int y, ggi_alpha alpha);
void	(*fillPixelA)(ggi_visual_t vis, int x, int y, ggi_alpha alpha);
void	(*drawPixels)(ggi_visual_t vis, ggi_coord coords[], uint count);
void	(*scanLine)(ggi_visual_t vis, int x1, int x2, int y);
void	(*scanLines)(ggi_visual_t vis, ggi_scanline scanlines[], uint count);
void	(*hLine)(ggi_visual_t vis, int x1, int x2, int y);
void	(*vLine)(ggi_visual_t vis, int x, int y1, int y2);
void	(*drawRect)(ggi_visual_t vis, int x1, int y1, int x2, int y2);
void	(*fillRect)(ggi_visual_t vis, int x1, int y1, int x2, int y2);
void	(*line)(ggi_visual_t vis, int x1, int y1, int x2, int y2);
void	(*linef)(ggi_visual_t vis, ggi_float x1, ggi_float y1,
			    ggi_float x2, ggi_float y2);
void	(*drawLines)(ggi_visual_t vis, ggi_line lines[], uint count);
void	(*drawCircle)(ggi_visual_t vis, int x, int y, uint r);
void	(*fillCircle)(ggi_visual_t vis, int x, int y, uint r);
void	(*drawEllipse)(ggi_visual_t vis, int x, int y, uint rx, uint ry);
void	(*fillEllipse)(ggi_visual_t vis, int x, int y, uint rx, uint ry);
void	(*drawArc)(ggi_visual_t vis, int x, int y, uint rx, uint ry,
	    	   ggi_float start, ggi_float end, ggi_bool close);
void	(*fillArc)(ggi_visual_t vis, int x, int y, uint rx, uint ry,
		   ggi_float start, ggi_float end);
void	(*bezier)(ggi_visual_t vis, int x1, int y1, int x2, int y2,
		     int x3, int y3, int x4, int y4);
void	(*trapezoid)(ggi_visual_t vis, 
		    int xl1, int xr1, int y1,
		    int xl2, int xr2, int y2);
void	(*triangle)(ggi_visual_t vis, 
		    int x1, int y1, int x2, int y2, int x3, int y3);
void	(*drawPoly)(ggi_visual_t vis, ggi_coord coords[], uint count);
void	(*fillPoly)(ggi_visual_t vis, ggi_coord coords[], uint count);
void	(*fillPolys)(ggi_visual_t vis, ggi_coord coords[], 
		uint counts[], uint count);
void	(*blit)(
	    ggi_visual_t dest, int dx, int dy,
	    ggi_visual_t src, int sx, int sy, 
	    int width, int height);	
void	(*blitOp)(
	    ggi_visual_t dest, int dx, int dy, 
	    ggi_visual_t src1, ggi_visual_t src2, int sx, int sy, 
	    int width, int height, ggi_operator op);
void	(*stretchBlit)(
	    ggi_visual_t dest, int dx, int dy, int dwidth, int dheight, 
	    ggi_visual_t src, int sx, int sy, int swidth, int sheight);
void	(*stretchBlitOp)(
	    ggi_visual_t dest, int dx, int dy, int dwidth, int dheight,
	    ggi_visual_t src1, ggi_visual_t src2,
	    int sx, int sy, int swidth, int sheight,
	    ggi_operator op);

3. GC changes
--------------

If the GC is changed by one of the GC manipulation functions 
(ggiSetAntialias etc.) the function table and the accelerator's registers 
have to be updated.
This is done by calling the update() function of each module (generic first),
which then sets the functions it can accelerate/emulate.
Otherwise the function of the next higher level is used.
Every module has to provide a update() function, which is declared as
    void update(ggi_visual_t vis, int what);
"what" describes which attribute of the GC has changed:
    
/* mode changes: functions should be updated */
GGI2D_UPD_ARCMODE	/* segment/sector */
GGI2D_UPD_POLYMODE	/* even-odd/winding */
GGI2D_UPD_LINEMODE	/* line pattern on/off(dash size == 0) */
GGI2D_UPD_APPENDMODE	/* append mode on/off */
GGI2D_UPD_ANTIALIAS	/* antialiasing on/off */
GGI2D_UPD_TEXTUREMODE	/* fillcolor/texture */
GGI2D_UPD_ALPHAMODE	/* alpha value on/off(== GGI_MAX_ALPHA) */
GGI2D_UPD_OPERATOR	/* operators (default = GGI_SET) */

/* value changes: accelerator should be updated */
GGI2D_UPD_LINE
GGI2D_UPD_CLIP
GGI2D_UPD_DRAWCOL
GGI2D_UPD_FILLCOL
GGI2D_UPD_TEXTURE
GGI2D_UPD_ALPHA

Value changes normally require no update of the function table, 
but of the hardware's registers.
They're normally ignored by the hardware driver and only processed 
when one of its functions is called. 
Then it can read out the previous changes from
the variable "accel_changes" in the GC.

Mode changes and what functions they affect on:

 arc mode (c):
	DrawArc,FillArc
 poly mode (p):
	FillPoly,FillPolys
 line mode (l):
	HLine,VLine,DrawRect,Line,Linef,DrawLines,DrawCircle,
	DrawEllipse,DrawArc,Bezier,DrawPoly
 append mode (n):
	HLine,VLine,Line,Linef,DrawArc,Bezier,DrawPoly
 antialias (s):
	Line,Linef,DrawLines,DrawCircle,FillCircle,
	DrawEllipse,FillEllipse,DrawArc,FillArc,Bezier,
	Trapezoid,Triangle,DrawPoly,FillPoly,FillPolys
 texture mode (t):
	Scanline,Scanlines,FillRect,FillCircle,FillEllipse,FillArc,
	Trapezoid,Triangle,FillPoly,FillPolys
 alpha mode (a):
	all
 operator (o):
	all

Functions:	
      ao	PutPixel
      ao	DrawPixel
      ao	DrawPixelA
     tao	FillPixelA
      ao	DrawPixels
     tao	Scanline
     tao	Scanlines
  ln  ao	HLine
  ln  ao	VLine
  l   ao	DrawRect
     tao	FillRect
  lns ao	Line
  lns ao	Linef
  lns ao	DrawLines
  l s ao	DrawCircle
    stao	FillCircle
  l s ao	DrawEllipse
    stao	FillEllipse
 clns ao	DrawArc
 c nstao	FillArc
  lns ao	Bezier
    stao	Trapezoid
    stao	Triangle
  lns ao	DrawPoly
 p  stao	FillPoly
 p  stao	FillPolys
      ao	Blit
      ao	BlitOp
      ao	StretchBlit
      ao	StretchBlitOp
	    
There are three cases in which drawing is completely disabled:
1. the clipping rectangle has the size (0,0)
2. the operator is GGI_NOOP
3. the alpha value is 0 

4. Loading of modules
---------------------

When ggi2dOpen() is called to initialize a visual, the corresponding
driver module will be loaded by libGGI2D.
This module loads then the modules it requires, normally a framebuffer module,
which again requires the generic module.
After a module has loaded all required modules it registers its update()
function using libGGI2D's 
 void	GGI2DregisterUpdateFunc(ggi_visual_t vis, updatefunc f, int mask);
"mask" specifies on which changes update() should be called.
Then it sets all functions in the function table for the default GC.

5.Adding new targets or drivers
-------------------------------

[...write me...]
    
libGGI2D uses function templates (see include/templates/) to simplify
the implementation of new drivers and to reduce the size of the source code.
        
        Thomas Tanner (tanner@gmx.de)
