Mesa User's Guide


This document discusses a number of Mesa subjects which are often asked about. Also see the FAQ for miscellaneous subjects. Suggestions for new topics are welcome.


  1. X visuals and colormaps
  2. Mesa's X driver
  3. Optimizing Mesa's performance
  4. Installing Mesa
  5. Remote display of OpenGL apps

    Subject 1: X visuals and colormaps

    Before explaining the details of the X driver for Mesa (subject 2) it's important to understand some basic information about X visuals. Volume 1 of the O'Reilly series on the X window system is a good source for this information.


    An X "visual" describes how data in a frame buffer are displayed as colored pixels on your screen. Visuals are characterized by their depth and class. The depth is the number of bits per pixel. The class determines what kind of colormap, if any, is used.

    X supports 6 different visual types or classes (N=depth):

    Note: mutable = dynamic or changable, immutable = fixed, can't be changed.

    The most common visual type on low-end displays is 8-bit PseudoColor. In this case each byte in the frame buffer is an index into a 256-entry colormap which can be loaded with colors you choose.

    A common visual type on high-end displays is 24-bit TrueColor. In this case each triplet of bytes in the frame buffer directly maps to an RGB color on the screen. 256 shades of red, 256 shades of green and 256 shades of blue allow 16,777,216 differeent colors. Some people say you can display "16 million colors at once" but that's false because nobody has a display with that many pixels!

    Here are some other common visuals:

    Which visual(s) does my display support?

    You can find out with the standard xdpyinfo command. It prints all sorts of interesting information about your display including a list of visuals supported by each screen. Note that an X display is a collection of one or more X screens, each of which can support a different set of visuals. Most people have one screen per display. Low-end systems usually list 1 or 2 visuals, high-end systems may list upwards of 70 visuals.

    Which visual is the default?

    One of the visuals in the list from xdpyinfo is the default visual. The default visual is the visual used by the root (background) window. Look for default visual id in the xdpyinfo output.

    Another way to determine the default (root) visual is to use xwininfo. When you run xwininfo your pointer will turn into a cross-hair. Point over the root window and press a mouse button. Among the information printed will be the visual class and depth. Note that you can apply this program to any X window.

    Can I control which visuals are available?

    That depends on your graphics hardware and X server software. On Linux systems with XFree86 you can do startx -- -bpp16 or startx -- -bpp32 to start the X server with deeper visuals. Ask your sysadmin or consult your system's X documentation to learn more.

    If your display supports more than one visual you should also be able to configure the default (root) visual to be which ever you want. Again, read your documentation.

    Information for Xlib programmers

    If you're programming with Xlib (or a higher level toolkit) you need to be aware of visual issues when creating windows. Naive programmers who use XCreateSimpleWindow may find all kinds of problems when later running their client on a different display. The problem is XCreateSimpleWindow inherits its parent's visual. If creating a top-level window, it'll inherit the root win window's visual which will vary from display to display.

    When creating top-level windows it's much better to use XGetVisualInfo or XMatchVisualInfo to explicitly choose the visual and XCreateWindow to create the window. Alternatively, if you want to use the default visual, your code should verify that the default visual is suitable for your application's needs and deal with it appropriately.

    Finally, If you create a window with a visual you've explicitly chosen you must also be sure to provide a colormap which matches the visual. Otherwise you'll get a BAD MATCH X protocol error.


    Color management in X is complicated. What follows is a quick overview of X's colormap system. See the O'Reilly Xlib Programming Manual for more detailed info.

    An X colormap is really an abstraction over the hardware. While your X screen may only have one real colormap, X gives programmers the illusion of having an unlimited number of colormaps. If the hardware colormap(s) become over commited you'll probably see the "technicolor" effect or colormap "flashing" when you move the input focus from one window to another. That's caused by the window manager installing the virtual X colormap into the hardware colormap for the current window. Careful programming can reduce or eliminate this problem as we'll see.

    X colormaps come into two varieties: private and shared. When you call XCreateColormap you indicate AllocAll for private or AllocNone for shared.

    When you create a private colormap you get a whole colormap to yourself in which you can setup any mapping of pixels to colors you want using XStoreColor(s). You should avoid using private colormaps when possible because they inhibit color sharing. Remember, it's not sharing colors with other clients which leads to the dreaded colormap flashing.

    When you create a shared colormap you must allocate colors from it using XAllocColor. You specify a color by red, green, and blue values and XAllocColor returns a pixel value for you to use when drawing things. If X can't allocate the color you need, XAllocColor will fail. Your best recourse is to then search the colormap for the closest match and use that color. X will try to combine shared colormaps into one hardware colormap to reduce flashing.

    Programming tips:

    How Mesa works with colormaps is the subject of the next section.

    Subject 2: Mesa's X driver- visuals and colormaps

    According to the OpenGL GLX spec, when using OpenGL in RGB mode you must use a TrueColor or DirectColor visual. When using OpenGL in color-index mode you must use a PseudoColor or StaticColor visual. Indeed these are the only possibilities returned by glXChooseVisual.

    Mesa's X driver is more flexible, allowing you to use any X visual type in RGB mode and either GrayScale, StaticGray, PseudoColor or StaticColor in color- index mode. Unfortunately, this flexibility sometimes causes problems.

    It's very important to understand that most of the visual and colormap problems people have with Mesa are not caused by the core Mesa library but rather the higher level toolkits such as aux, tk and GLUT. However, the toolkits cannot be blamed too much because they were designed to work with OpenGL but not Mesa's unique features.

    Mesa's glXChooseVisual

    Mesa's implementation of glXChooseVisual is written to be as compatible with the OpenGL semantics as possible. However, The fact that Mesa's glXChooseVisual may return, for example, a PseudoColor visual in RGB mode is enough to make some OpenGL applications fail. If the OpenGL application requires a TrueColor or DirectColor visual and your display doesn't support such a visual you may be out of luck. This is no one's fault. However, if you write an OpenGL application, you'd be doing a service to Mesa users if you wrote code which would accept any visual type in RGB mode.

    Remember that if Mesa's glXChooseVisual were modified to behave exactly like OpenGL's we would actually be losing functionality which a lot of people (everyone without a TrueColor display) depend on.

    How can I stop colormap flashing?

    If the colors on your screen flash when you move the pointer in and out of a Mesa window it's because the working set of Mesa and other X clients have allocated more colors than will fit in the hardware colormap(s). To remedy this, you can either close some of your other X clients or try setting the MESA_RGB_VISUAL environment variable to match the root window's visual, thereby encouraging colormap sharing.

    I don't see flashing but the Mesa window's colors are wrong!

    Your Mesa window is probably using the same visual type as the root window and is sharing the root's colormap. Unfortunately, either the window manager and/or other X clients have allocated so many entries from the colormap that Mesa can't get the ones it needs for its palette. The solution is to try the Mesa application again after you've terminated other color-demanding clients. Or set the MESA_PRIVATE_CMAP variable which forces the aux, tk and GLUT toolkits to allocate a private colormap. Unfortunately, now you'll probably see colormap flashing.

    Note that the MESA_PRIVATE_CMAP variable is recognized by the aux and tk toolkits and not the Mesa core library. Colormap management is an issue at a level above the core of Mesa.


    The above discussion assumed you're using Mesa in RGB mode. If you're using color-index mode most of the above is still applicable. However, many (most?) color-index mode application need a private colormap so they can manipulate (read/write) the colormap. If, for example, your display does not have a PseudoColor visual the Mesa/OpenGL application many generate X protocol errors when it tries to execute an XStoreColor command.

    Subject 3: Optimizing Mesa's performance

    The following is a list of things you can do to maximize the performance of Mesa. In no particular order...

    Experiment with the MESA_BACK_BUFFER environment variable if using double buffered mode. Possible values are "P" for pixmap and "X" for XImage. When displaying on the local host and using an XImage for the back buffer, the X shared memory extension is used to accelerate the glXSwapBuffers() function. Using an X image is usually faster except when rendering scenes which don't use any raster operations (such as depth-test, stenciling, dithering, etc) since the Xlib point, line and polygon functions can be used.

    Experiment with different visuals with the MESA_RGB_VISUAL environment variable. Some are visuals faster than others.

    Try to maximize the number of vertices between glBegin/glEnd.

    Group state changes such as glEn/Disable, glShadeModel, etc together before glBegin/glEnd to minimize the number internal state change computations.

    Disable smooth shading when not needed. Smooth shading is usually only needed for drawing lit polygons.

    Disable dithering when not needed.

    Disable depth testing and any other raster operations you don't need.

    glDrawPixels works quickest with GL_UNSIGNED_BYTE, GL_RGB - format image data.

    Use GLfloat-valued functions such as glVertexf[v], glNormal3f[v], glColorf[v] glLoadMatrixf, glMultMatrixf, etc. because conversion to the internal GLfloat type will not be needed.

    Use backface culling to reduce the rasterization bottleneck.

    Using a smaller window will speed up polygon rasterization, glClear, and glXSwapBuffers.

    Avoid using glColorMaterial.

    Use directional lights rather than positional lights. i.e. W component of position = 0.0.


    Avoid using spot lights.

    Use low-numbered, consecutive lights such as GL_LIGHT0, GL_LIGHT1, GL_LIGHT2 rather than GL_LIGHT2, GL_LIGHT5, GL_LIGHT7 for example.

    Avoid using GL_NORMALIZE.

    Use viewports which are completely inside the window boundaries.

    Subject 4: Installing Mesa (on Unix systems)

    After you've compiled the Mesa library files, as seen in Mesa/lib, you should probably move them and the include files to a more appropriate location. I suggest copying the Mesa/lib files to /usr/local/lib and copying the Mesa/include/GL directory to /usr/local/include.

    When you compile your Mesa/OpenGL application just add -I/usr/local/include to your C compiler flags and add -L/usr/local/lib to your linker flags.

    If your system doesn't have real OpenGL libraries it may also be a good idea to make a few symbolic links so that "off the shelf" OpenGL applications compile painlessly:

    ln -s /usr/local/include/GL /usr/include/GL
    ln -s /usr/local/lib/libMesaGL.a /usr/lib/libGL.a
    ln -s /usr/local/lib/libMesaGLU.a /usr/lib/libGLU.a
    NOTE: if you've made shared Mesa libraries the symbolic links will probably have different names: .so suffix instead of .a suffix, for example. If you do this you may also have to run a special program such as ldconfig -v on Linux to make things work.

    Then you can specify -lGL and -lGLU when linking your Mesa application and be confident that it will also compile successfully on other systems which may have real OpenGL libraries.

    Subject 5: Remote display of OpenGL apps

    Normally, X11-based OpenGL applications can only be displayed on X servers which have the GLX extension. The GLX extension decodes the GLX protocol (which is sent within the X protocol stream) and executes the appropriate OpenGL rendering operations. You can check if your display server has this extension by examining the output of running xdpyinfo.

    If you have an OpenGL application and want to display it on a server which lacks the GLX extension, Mesa can help you. You have two alternatives:

    1. If you have the application source, recompile it (or just relink it) using the Mesa libraries instead of the OpenGL libraries. Basically, just substitute -lGL with -lMesaGL in the Makefile. The application should now be displayable on almost any X server.

    2. If you don't have the application source but it was linked with a shared OpenGL library you can replace the OpenGL shared library with the Mesa shared library at runtime. Naturally, this requires that your operating system uses shared libraries (i.e. IRIX, Linux 1.2.x, SunOS, AIX, HPUX and others).

      If you're not familiar with shared libraries you should read your system's documentation. Man pages on ld, rld, or man -k library should turn up something.

      Here are the steps to using a Mesa shared library in place of OpenGL:

      1. You have to compile Mesa as a shared library. The Mesa Makefile already supports this for a number of systems. Just type make in the Mesa directory to see a list of configurations and look for yours.

      2. Make a symbolic link with the same name as your system's OpenGL library which points to the Mesa library. For example, on IRIX systems the OpenGL lib is named so you'd create the symbolic link with: ln -s in the Mesa/lib directory. Note that you could just rename the Mesa library instead of making a symbolic link, if you prefer.

      3. Tell the runtime linker to look in Mesa/lib (or where ever you've installed the Mesa shared library) for libraries before the default library directories. On IRIX 5.x systems this is done by setting the _RLD_LIST environment variable: setenv _RLD_LIST "mesalibdir/" where mesalibdir is the full path to the location of the symbolic link you made previously.

      Now when you execute the OpenGL application the runtime linker should select the Mesa shared library instead of the OpenGL shared library.

    Using either of these methods, The application should now be displayable on almost any X server since the OpenGL API calls will effectively be translated into ordinary X protocol by Mesa.

    Why did I say "almost any X server"? Because it might be the case that the OpenGL application won't accept any of the visual types offered by your display. For example, if the OpenGL app asks for an RGBA visual and Mesa returns a PseudoColor visual the application may not accept it because a TrueColor or DirectColor visual was expected. You may have to experiment with the MESA_RGB_VISUAL environment variable if you have this problem.

    Back to the Mesa home page

    Last updated on January 19, 1996 by