Understanding OpenGL programs internals

For a start, you will need to understand lots of terms: GLX, OpenGL, DRI, DRM etc. Lookup here:


for the definition.

Looking up resources in internet (eg, http://pyopengl.sourceforge.net/, or just search "wiretorus.py" for python implementation of torus drawing using OpenGL),

The heart of the program can summarized as follows:


0.0, 0.0, 10.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0)

glRotatef(xrot, 1.0, 0.0, 0.0)
glRotatef(yrot, 0.0, 1.0, 0.0)
glRotatef(zrot, 0.0, 0.0, 1.0)

glColor3f(0.5, 0.0, 1.0)

And the drawing as follow:

Using gdb to attach to the python program:

#0 0x00007fa60b4acb90 in __poll_nocancel ()
at ../sysdeps/unix/syscall-template.S:81
#1 0x00007fa607d12b72 in ?? () from /usr/lib/x86_64-linux-gnu/libxcb.so.1
#2 0x00007fa607d143ff in ?? () from /usr/lib/x86_64-linux-gnu/libxcb.so.1
#3 0x00007fa607d14512 in xcb_wait_for_reply ()
from /usr/lib/x86_64-linux-gnu/libxcb.so.1
#4 0x00007fa60898c48f in _XReply () from /usr/lib/x86_64-linux-gnu/libX11.so.6==========================>
#5 0x00007fa60970c673 in ?? () from /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
#6 0x00007fa60970a02b in ?? () from /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1
#7 0x00007fa60263a9a9 in ?? () from /usr/lib/x86_64-linux-gnu/dri/i965_dri.so
#8 0x00007fa60263adc3 in ?? () from /usr/lib/x86_64-linux-gnu/dri/i965_dri.so
#9 0x00007fa60262f8f5 in ?? () from /usr/lib/x86_64-linux-gnu/dri/i965_dri.so
#30 0x000000000055c594 in PyEval_EvalCodeEx ()
#31 0x00000000005b7392 in PyEval_EvalCode ()
#32 0x0000000000469663 in ?? ()
#33 0x00000000004699e3 in PyRun_FileExFlags ()
#34 0x0000000000469f1c in PyRun_SimpleFileExFlags ()
#35 0x000000000046ab81 in Py_Main ()
#36 0x00007fa60b3e0ec5 in __libc_start_main (main=0x46ac3f <main>, argc=2,
argv=0x7fff7d08c1e8, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fff7d08c1d8) at libc-start.c:287
#37 0x000000000057497e in _start ()

The legacy of X protocol as shown below (http://www.artima.com/articles/desktop_grid2.html):


And underlying the packet exchange:


Here "_XReply" is an X extension API as documented here:



and here:


As defined above: _XReply does: "Flushes the output buffer, waits for a reply packet, and copies the contents into the specified Reply parameter."

And the modern implementation is this (inside src/xcb_io.c of libX11-1.6.2 from Ubuntu’s source code repository):

* _XReply - Wait for a reply packet and copy its contents into the
* specified rep.
* extra: number of 32-bit words expected after the reply
* discard: should I discard data following "extra" words?
Status _XReply(Display *dpy, xReply *rep, int extra, Bool discard)
xcb_generic_error_t *error;
xcb_connection_t *c = dpy->xcb->connection;
char *reply;
PendingRequest *current;

which is implemented using XCB API (vs Xlib in the past, which uses lots of locks, and thus is slow). And further understanding XCB protocol (notice the mention of lockless protocol):


And the public API is documented here:


Doing a search for the packages:

apt-file search libGL.so

libgl1-mesa-dev: /usr/lib/x86_64-linux-gnu/libGL.so
libgl1-mesa-dev: /usr/lib/x86_64-linux-gnu/mesa/libGL.so
libgl1-mesa-glx: /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1

So, based on above, if you do a "apt-get source libgl1-mesa-dev" you will see that you end up with the Mesa source code.

From the stack trace above, we see that the Mesa component is implemented on top of _XReply API (X extension):

For example, is the glx init screen:

glx_screen_init(struct glx_screen *psc,
int screen, struct glx_display * priv)
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
psc->scr = screen;
psc->dpy = priv->dpy;
psc->display = priv;

getVisualConfigs(psc, priv, screen);
getFBConfigs(psc, priv, screen);

return GL_TRUE;

where getVisualConfigs():

static GLboolean
getVisualConfigs(struct glx_screen *psc,
struct glx_display *priv, int screen)
xGLXGetVisualConfigsReq *req;
xGLXGetVisualConfigsReply reply;
Display *dpy = priv->dpy;


psc->visuals = NULL;
GetReq(GLXGetVisualConfigs, req);
req->reqType = priv->majorOpcode;
req->glxCode = X_GLXGetVisualConfigs;
req->screen = screen;

if (!_XReply(dpy, (xReply *) & reply, 0, False))
goto out;

psc->visuals = createConfigsFromProperties(dpy,
screen, GL_FALSE);

return psc->visuals != NULL;

And here are the relation between GLX and OpenGL (OpenGL extension):


And trying to understanding the Mesa source tree downloaded:


From above both the OpenGL and DRI drivers will talk to Nouveau modules directly:

And the kernel modules loaded:

lsmod |grep nouv

nouveau 1097199 0
mxm_wmi 13021 1 nouveau
ttm 85150 1 nouveau
drm_kms_helper 55071 2 i915,nouveau
drm 303102 7 ttm,i915,drm_kms_helper,nouveau
i2c_algo_bit 13413 2 i915,nouveau
wmi 19177 3 mxm_wmi,nouveau,asus_wmi
video 19476 3 i915,nouveau,asus_wmi

Another way of looking at some ofl the libraries called by the python program:

(gdb) info sharedlibrary



Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: