Mesa Implementation Notes This document is an overview of the internal structure of Mesa and is meant for those who are interested in modifying or enhancing Mesa, or just curious.
NOTE: As of version 2.0 of Mesa, some of this information is out of date.
The gl_context struct actually contains a number of sub structs which exactly correspond to OpenGL's attribute groups. This organization made glPushAttrib and glPopAttrib trivial to implement and proved to be a good way of organizing the state variables.
Originally, Mesa didn't accumulate vertices in this way. Instead, glVertex transformed and lit then buffered each vertex as it was received. When enough vertices to draw the primitive (1 for points, 2 for lines, >2 for polygons) were accumulated the primitive was drawn and the buffer cleared.
The new approach of buffering many vertices and then transforming, lighting and clip testing is faster because it's done in a "vectorized" manner. See gl_transform_points() in xform.c for an example. Also, vertices shared between primitives (i.e. GL_LINE_STRIP) are only transformed once.
The only complication is clipping. If no vertices in the vertex buffer have their clip flag set, the rasterization functions can be applied directly to the vertex buffer. Otherwise, a clipping function is called before rasterizing each primitive. If clipping introduces new vertices they will be stored at the end of the vertex buffer.
For best performance Mesa clients should try to maximize the number of vertices between glBegin/End pairs and used connected primitives when possible.
In general, typical states (depth-buffered & smooth-shading) result in optimized rasterizers being selected. Non-typical states (stenciling, blending, stippling) result in slower, general purpose rasterizers being selected.
For best performance, Mesa clients should group state changes (glEnable, glDisable, glShadeModel, glLight*, glMaterial) together to minimize the number of times the rasterizer selectors are called.
In addition to the device driver table functions, each Mesa driver has its own set of unique interface functions. For example, the X/Mesa driver has the XMesaCreateContext, XMesaBindWindow, and XMesaSwapBuffers functions while the Windows/Mesa interface has WMesaCreateContext, WMesaPaletteChange and WMesaSwapBuffers. New Mesa drivers need to both implement the dd_function_table functions and define a set of unique window system or operating system-specific interface functions.
The device driver functions can roughly be divided into four groups:
Even if hardware accelerated renderers aren't available, the device driver may implement tuned, special purpose code for common kinds of points, lines or polygons. The X/Mesa device driver does this for a number of lines and polygons. See the xmesa3.c file.
+-----------------------------------------------------------+
| |
| Application Programs |
| |
| +- glu.h -+- aux.h tk.h glut.h -+ |
| | | | |
| | GLU | aux, tk or GLUT | |
| | | toolkits | |
| | | | |
+---------- gl.h ------------+-------- glx.h ----+ |
| | | |
| Mesa core | GLX functions | |
| | | |
+---------- dd.h ------------+------------- xmesa.h --------+
| |
| XMesa* and device driver functions |
| |
+-----------------------------------------------------------+
| Hardware/OS/Window System |
+-----------------------------------------------------------+