Initially, Chromium did not have any support for multi-window or multi-context OpenGL applications. Now, Chromium can effectively deal with multi-window and multi-context applications, but it's a bit complicated. This section describes how things work.
A context is an OpenGL rendering context; it represents the current OpenGL state, including things like polygon mode, blending mode, current drawing color, texture settings, transformation matrices, etc.
A 3D window is considered to be a window in which we render 3D graphics with OpenGL. There may be other (2d) application windows but we're not concerned with them.
Note: while this section desribes things in terms of the GLX interface, everything is equally applicable to the WGL interface.
When glXMakeCurrent
is called we determine if the window
and/or context identifiers are new.
If they're new, we must determine if Chromium or the native OpenGL library
is to be used for rendering.
The application node configuration options
minimum_window_size, maximum_window_size,
match_window_title, match_window_count and
ignore_window_list are used to make this determination.
By default, Chromium is used to handle all contexts and windows.
At this point, Chromium knows whether context and window handles should be processed by Chromium or the native OpenGL library.
If the native OpenGL library is to be used, we call the native
glXMakeCurrent
function and setup the GL dispatch table to
point to the native OpenGL functions.
Thereafter, OpenGL API calls are routed to the native OpenGL library.
If Chromium is to be used, we first check if the context and/or window
handles are new.
If they're new, we call the Chromium crCreateContext
and/or
crWindowCreate
functions.
These functions propogate through the Chromium SPU chains, creating the
appropriate context and window data structures along the way.
The GL dispatch table is initialized to point to the functions in the
first SPU in the SPU chain.
Thereafter, OpenGL API calls are routed through Chromium's SPUs.
Once a context is marked as a Chromium context, it can't be used to render to a native OpenGL window. Similarly, once a window is marked as a Chromium window, it can't be renered into by a native OpenGL context. Errors will be reported if this is attempted.
Parallel applications (like progs/psubmit/psubmit.c) typically don't use the GLX or WGL APIs but instead use the direct Chromium interface functions:
GLint crCreateContext(const char *dpyName, GLint visBits); void crDestroyContext(GLint context); void crMakeCurrent(GLint window, GLint context); GLint crGetCurrentContext(void); GLint crGetCurrentWindow(void); void crSwapBuffers(GLint window, GLint flags); GLint crWindowCreate(const char *dpyName, GLint visBits); void crWindowDestroy(GLint window); void crWindowSize(GLint window, GLint w, GLint h); void crWindowPosition(GLint window, GLint x, GLint y);
along with the barrier and semapahore extension functions:
void glBarrierCreateCR(GLuint name, GLuint count); void glBarrierDestroyCR(GLuint name); void glBarrierExecCR(GLuint name); void glSemaphoreCreateCR(GLuint name, GLuint count); void glSemaphoreDestroyCR(GLuint name); void glSemaphorePCR(GLuint name); void glSemaphoreVCR(GLuint name);
A parallel application can use the crCreateContext
,
crWindowCreate
and crMakeCurrent
functions
to explicitely manage its window and rendering contexts.
But if a parallel application only uses one window and rendering context, it can rely on the default context and default window.
Chromium always creates a default window and rendering context. They are identified as rendering context 0 and window 0.
Originally, when Chromium did not support multi-window, multi-context applications, it relied on using a single default rendering context and window. These defaults are still present since they're still useful.
A specific example is the readback SPU.
A typical pararallel sort-last configuration will have N application
nodes, each using a readback SPU.
Each application instance may issue a crWindowCreate
call
to create a readback SPU window.
However, the readback SPU does not propogate the
WindowCreate
call to the next SPU (the shared render SPU).
If we did, we'd wind up with N rendering SPU windows instead of one.
So, the readback SPU relies on using the render SPU's default window (0).
That way, all the readback SPUs send their images to the same render
SPU window (0) on the server/network node.