Index: /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 54904)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 54905)
@@ -29,4 +29,13 @@
 	$(VBOX_PATH_CROGL_GENFILES)/
 endif
+
+ifeq ($(KBUILD_TARGET),darwin)
+ #VBOX_WITH_CR_DISPLAY_LISTS=1
+endif
+
+ifdef VBOX_WITH_CR_DISPLAY_LISTS
+ LIBRARIES += VBoxOGLcrdlm
+ DLLS      += VBoxOGLexpandospu
+endif # VBOX_WITH_CR_DISPLAY_LISTS
 
 ifeq ($(KBUILD_TARGET),darwin)
@@ -155,4 +164,7 @@
 	$(VBOX_PATH_CROGL_GENFILES)/server_simpleget.c \
 	$(VBOX_PATH_CROGL_GENFILES)/server_dispatch.h
+ifdef VBOX_WITH_CR_DISPLAY_LISTS
+VBoxOGLcrserverlib_DEFS += VBOX_WITH_CR_DISPLAY_LISTS
+endif
 ifdef VBOXCR_LOGFPS
 VBoxOGLcrserverlib_DEFS += VBOXCR_LOGFPS
@@ -255,4 +267,92 @@
 
 
+ifdef VBOX_WITH_CR_DISPLAY_LISTS
+#
+# VBoxOGLcrdlm
+#
+
+VBoxOGLcrdlm_TEMPLATE       = VBOXCROGLR3HOSTLIB
+VBoxOGLcrdlm_INCS           = \
+	dlm
+VBoxOGLcrdlm_INTERMEDIATES  = \
+	$(VBOX_PATH_CROGL_GENFILES)/cr_dlm.h \
+	$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h
+
+VBoxOGLcrdlm_SOURCES  = \
+	dlm/dlm.c \
+	dlm/dlm_arrays.c \
+	dlm/dlm_bbox.c \
+	dlm/dlm_calllist.c \
+	dlm/dlm_checklist.c \
+	dlm/dlm_error.c \
+	dlm/dlm_lists.c \
+	dlm/dlm_pointers.c \
+	$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.c
+
+VBoxOGLcrdlm_CLEAN = \
+	$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.c \
+	$(VBOX_PATH_CROGL_GENFILES)/cr_dlm.h \
+	$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h
+#
+# Generate files for VBoxOGLcrdlm.
+#
+$(VBOX_PATH_CROGL_GENFILES)/cr_dlm.h: \
+		$(addprefix $(PATH_SUB_CURRENT)/dlm/, dlm_header.py) \
+		$(VBOX_CROGL_API_FILES) \
+		| $$(dir $$@)
+	$(call MSG_GENERATE,python,$@,$<)
+	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< header $(VBOX_PATH_CROGL_GLAPI) > $@
+
+$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h: \
+		$(addprefix $(PATH_SUB_CURRENT)/dlm/, dlm_generated.py dlm_special) \
+		$(VBOX_PATH_CROGL_GENFILES)/cr_dlm.h \
+		$(VBOX_CROGL_API_FILES) \
+		| $$(dir $$@)
+	$(call MSG_GENERATE,python,$@,$<)
+	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< headers $(<D) $(VBOX_PATH_CROGL_GLAPI) > $@
+
+$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.c: \
+		$(addprefix $(PATH_SUB_CURRENT)/dlm/, dlm_generated.py dlm_special) \
+		$(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h \
+		$(VBOX_CROGL_API_FILES) \
+		| $$(dir $$@)
+	$(call MSG_GENERATE,python,$@,$<)
+	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< source $(<D) $(VBOX_PATH_CROGL_GLAPI) > $@
+
+
+#
+# VBoxOGLexpandospu
+#
+VBoxOGLexpandospu_TEMPLATE       = VBOXCROGLR3HOSTDLL
+VBoxOGLexpandospu_INCS           = \
+	expando
+VBoxOGLexpandospu_SOURCES  = \
+	expando/expandospu.c \
+	expando/expandospu_config.c \
+	expando/expandospu_init.c \
+	$(VBOX_PATH_CROGL_GENFILES)/expando.c
+VBoxOGLexpandospu_CLEAN = \
+	$(VBOX_PATH_CROGL_GENFILES)/expando.c
+VBoxOGLexpandospu_CLEAN = \
+	$(VBOX_PATH_CROGL_GENFILES)/expando.c
+VBoxOGLexpandospu_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxOGLexpandospu.dylib
+VBoxOGLexpandospu_LIBS = \
+	$(PATH_STAGE_LIB)/VBoxOGLcrdlm$(VBOX_SUFF_LIB) \
+	$(PATH_STAGE_LIB)/VBoxOGLhostcrstate$(VBOX_SUFF_LIB) \
+	$(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
+	$(VBOX_LIB_OGL_HOSTCRUTIL) \
+	$(LIB_RUNTIME)
+#
+# Generate files for VBoxOGLexpandospu.
+#
+$(VBOX_PATH_CROGL_GENFILES)/expando.c: \
+		$(addprefix $(PATH_SUB_CURRENT)/expando/, expando.py expando_special) \
+		$(VBOX_CROGL_API_FILES) \
+		| $$(dir $$@)
+	$(call MSG_GENERATE,python,$@,$<)
+	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D) > $@
+endif
+
+
 #
 # VBoxOGLrenderspu
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 54904)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 54905)
@@ -116,5 +116,9 @@
     }
 
+#ifdef VBOX_WITH_CR_DISPLAY_LISTS
+    strcpy(response, "1 0 expando");
+#else
     strcpy(response, "1 0 render");
+#endif
     crDebug("CRServer: my SPU chain: %s", response);
 
@@ -286,6 +290,11 @@
     CRMuralInfo *defaultMural;
 
+#ifdef VBOX_WITH_CR_DISPLAY_LISTS
+    int spu_ids[1]     = {0};
+    char *spu_names[1] = {"expando"};
+#else
     int spu_ids[1]     = {0};
     char *spu_names[1] = {"render"};
+#endif
     char *spu_dir = NULL;
     int i;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 54904)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 54905)
@@ -204,7 +204,9 @@
     if (!fContextsDeleted)
     {
+#ifndef VBOX_WITH_CR_DISPLAY_LISTS
         /* sync our state with renderspu,
          * do it before mural & context deletion to avoid deleting currently set murals/contexts*/
         cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
+#endif
     }
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 54905)
@@ -0,0 +1,734 @@
+/* $Id$ */
+
+#include <float.h>
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "dlm.h"
+
+/**
+ * \mainpage Dlm 
+ *
+ * \section DlmIntroduction Introduction
+ *
+ * Chromium consists of all the top-level files in the cr
+ * directory.  The dlm module basically takes care of API dispatch,
+ * and OpenGL state management.
+ *
+ */
+
+/**
+ * Module globals: the current DLM state, bound either to each thread, or
+ * to a global.
+ */
+#ifdef CHROMIUM_THREADSAFE
+CRtsd CRDLMTSDKey;
+#else
+CRDLMContextState *CRDLMCurrentState = NULL;
+#endif
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+
+/*************************************************************************/
+
+#ifdef CHROMIUM_THREADSAFE
+/**
+ * This is the thread-specific destructor function for the 
+ * data used in the DLM.  It's very simple: if a thread exits
+ * that has DLM-specific data, the data represents the listState
+ * for the thread.  All data and buffers associated with the list
+ * can be deleted, and the structure itself can be freed.
+ *
+ * Most Chromium threads don't have such things; but then,
+ * if a thread dies elsewhere in Chromium, huge buffers
+ * of information won't still be floating around in
+ * unrecoverable allocated areas, either.
+ */
+static void threadDestructor(void *tsd)
+{
+    CRDLMContextState *listState = (CRDLMContextState *)tsd;
+
+    if (listState) {
+	if (listState->currentListInfo) {
+	    crdlm_free_list(listState->currentListInfo);
+	}
+
+	crFree(listState);
+    }
+}
+#endif
+
+/**
+ * This function creates and initializes a new display list
+ * manager.  It returns a pointer to the manager, or NULL in
+ * the case of insufficient memory.  The dispatch table pointer
+ * is passed in to allow the utilities to muck with the table
+ * to gain functional control when GL calls are made.
+ */
+CRDLM DLM_APIENTRY *crDLMNewDLM(unsigned int userConfigSize, const CRDLMConfig *userConfig)
+{
+    CRDLM *dlm;
+
+    /* This is the default configuration.  We'll overwrite it later
+     * with user-supplied configuration information.
+     */
+    CRDLMConfig config = {
+	CRDLM_DEFAULT_BUFFERSIZE,
+    };
+
+    dlm = crAlloc(sizeof(*dlm));
+    if (!dlm) {
+	return NULL;
+    }
+
+    /* Start off by initializing all entries that require further
+     * memory allocation, so we can free up all the memory if there's
+     * a problem.
+     */
+    if (!(dlm->displayLists = crAllocHashtable())) {
+	crFree(dlm);
+	return NULL;
+    }
+
+    /* The creator counts as the first user. */
+    dlm->userCount = 1;
+
+#ifdef CHROMIUM_THREADSAFE
+    /* This mutex ensures that only one thread is changing the displayLists
+     * hash at a time.  Note that we may also need a mutex to guarantee that
+     * the hash is not changed by one thread while another thread is
+     * traversing it; this issue has not yet been resolved.
+     */
+    crInitMutex(&(dlm->dlMutex));
+
+    /* Although the thread-specific data (TSD) functions will initialize
+     * the thread key themselves when needed, those functions do not allow
+     * us to specify a thread destructor.  Since a thread could potentially
+     * exit with considerable memory allocated (e.g. if a thread exits 
+     * after it has issued NewList but before EndList, and while there
+     * are considerable content buffers allocated), I do the initialization
+     * myself, in order to be able to reclaim those resources if a thread
+     * exits.
+     */
+    crInitTSDF(&(dlm->tsdKey), threadDestructor);
+    crInitTSD(&CRDLMTSDKey);
+#endif
+
+    /* Copy over any appropriate configuration values */
+    if (userConfig != NULL) {
+	/* Copy over as much configuration information as is provided.
+	 * Note that if the CRDLMConfig structure strictly grows, this
+	 * allows forward compatability - routines compiled with
+	 * older versions of the structure will only initialize that
+	 * section of the structure that they know about.
+	 */
+	crMemcpy((void *)&config, (void *) userConfig, 
+		MIN(userConfigSize, sizeof(config)));
+    }
+    dlm->bufferSize = config.bufferSize;
+
+    /* Return the pointer to the newly-allocated display list manager */
+    return dlm;
+}
+
+void DLM_APIENTRY crDLMUseDLM(CRDLM *dlm)
+{
+    DLM_LOCK(dlm);
+    dlm->userCount++;
+    DLM_UNLOCK(dlm);
+}
+
+/**
+ * This routine is called when a context or thread is done with a DLM.
+ * It maintains an internal count of users, and will only actually destroy
+ * itself when no one is still using the DLM.
+ */
+void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm)
+{
+    /* We're about to change the displayLists hash; lock it first */
+    DLM_LOCK(dlm)
+
+    /* Decrement the user count.  If the user count has gone to
+     * 0, then free the rest of the DLM.  Otherwise, other
+     * contexts or threads are still using this DLM; keep
+     * it around.
+     */
+    dlm->userCount--;
+    if (dlm->userCount == 0) {
+
+	/* Free the set of display lists.  As each one is freed, the
+	 * crdlm_free_list function will be called to free up its
+	 * internal resources.  The crdlm_free_list() routine is
+	 * cast to a (void *) to avoid warnings about being an
+	 */
+	crFreeHashtable(dlm->displayLists, crdlm_free_list);
+	dlm->displayLists = NULL;
+
+	/* Must unlock before freeing the mutex */
+	DLM_UNLOCK(dlm)
+
+#ifdef CHROMIUM_THREADSAFE
+	/* We release the mutex here; we really should delete the
+	 * thread data key, but there's no utility in Chromium to
+	 * do this.
+	 *
+	 * Note that, should one thread release the entire DLM
+	 * while other threads still believe they are using it,
+	 * any other threads that have current display lists (i.e.
+	 * have issued glNewList more recently than glEndList)
+	 * will be unable to reclaim their (likely very large)
+	 * content buffers, as there will be no way to reclaim
+	 * the thread-specific data.
+	 *
+	 * On the other hand, if one thread really does release
+	 * the DLM while other threads still believe they are 
+	 * using it, unreclaimed memory is the least of the
+	 * application's problems...
+	 */
+	crFreeMutex(&(dlm->dlMutex));
+
+	/* We free the TSD key here as well.  Note that this will
+	 * strand any threads that still have thread-specific data
+	 * tied to this key; but as stated above, if any threads
+	 * still do have thread-specific data attached to this DLM,
+	 * they're in big trouble anyway.
+	 */
+	crFreeTSD(&(dlm->tsdKey));
+	//crFreeTSD(&CRDLMTSDKey);
+#endif
+
+	/* Free the master record, and we're all done. */
+	crFree(dlm);
+    }
+    else {
+	/* We're keeping the DLM around for other users.  Unlock it,
+	 * but retain its memory and display lists.
+	 */
+	DLM_UNLOCK(dlm)
+    }
+}
+
+/**
+ * The actual run-time state of a DLM is bound to a context
+ * (because each context can be used by at most one thread at
+ * a time, and a thread can only use one context at a time,
+ * while multiple contexts can use the same DLM).
+ * This creates the structure required to hold the state, and
+ * returns it to the caller, who should store it with any other
+ * context-specific information.
+ */
+
+CRDLMContextState DLM_APIENTRY *crDLMNewContext(CRDLM *dlm)
+{
+	CRDLMContextState *state;
+
+	/* Get a record for our own internal state structure */
+	state = (CRDLMContextState *)crAlloc(sizeof(CRDLMContextState));
+	if (!state) {
+		return NULL;
+	}
+
+	state->dlm = dlm;
+	state->currentListIdentifier = 0;
+	state->currentListInfo = NULL;
+	state->currentListMode = GL_FALSE;
+	state->listBase = 0;
+	state->replayState = CRDLM_IMMEDIATE;
+	
+	/* Increment the use count of the DLM provided.  This guarantees that
+	 * the DLM won't be released until all the contexts have released it.
+	 */
+	crDLMUseDLM(dlm);
+
+	return state;
+}
+
+
+/**
+ * This routine should be called when a MakeCurrent changes the current
+ * context.  It sets the thread data (or global data, in an unthreaded
+ * environment) appropriately; this in turn changes the behavior of
+ * the installed DLM API functions.
+ */
+void DLM_APIENTRY crDLMSetCurrentState(CRDLMContextState *state)
+{
+	CRDLMContextState *currentState = CURRENT_STATE();
+	if (currentState != state) {
+		SET_CURRENT_STATE(state);
+	}
+}
+
+CRDLMContextState DLM_APIENTRY *crDLMGetCurrentState(void)
+{
+	return CURRENT_STATE();
+}
+
+/**
+ * This routine, of course, is used to release a DLM context when it
+ * is no longer going to be used.
+ */
+
+void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+
+	/* If we're currently using this context, release it first */
+	if (listState == state) {
+		crDLMSetCurrentState(NULL);
+	}
+
+	/* Try to free the DLM.  This will either decrement the use count,
+	 * or will actually free the DLM, if we were the last user.
+	 */
+	crDLMFreeDLM(state->dlm);
+	state->dlm = NULL;
+
+	/* If any buffers still remain (e.g. because there was an open
+	 * display list), remove those as well.
+	 */
+	if (state->currentListInfo) {
+		crdlm_free_list((void *)state->currentListInfo);
+	}
+	state->currentListInfo = NULL;
+	state->currentListIdentifier = 0;
+
+	/* Free the state record itself */
+	crFree(state);
+}
+
+
+/**
+ * This function can be used if the caller wishes to free up the
+ * potentially considerable resources used to store the display list
+ * content, without losing the rest of the display list management.
+ * For one example, consider an SPU that conditionally sends its 
+ * input stream to multiple servers.  It could broadcast all display
+ * lists to all servers, or it could only send display lists to servers
+ * that need them.  After all servers have the display list, the SPU
+ * may wish to release the resources used to manage the content.
+ */
+CRDLMError DLM_APIENTRY crDLMDeleteListContent(CRDLM *dlm, unsigned long listIdentifier)
+{
+    DLMListInfo *listInfo;
+    DLMInstanceList *instance;
+
+    listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+    if (listInfo && (instance = listInfo->first)) {
+	while (instance) {
+	    DLMInstanceList *nextInstance;
+	    nextInstance = instance->next;
+	    crFree(instance);
+	    instance = nextInstance;
+	}
+	listInfo->first = listInfo->last = NULL;
+    }
+    return GL_NO_ERROR;
+}
+
+/* Return whether the current thread is involved in playback.
+ * This is useful for some routines to selectively choose their
+ * unpack state, for example (as replayed DLM functions must be
+ * unpacked with crStateNativePixelPacking instead of the 
+ * normal unpack state, for example.
+ */
+CRDLMReplayState DLM_APIENTRY crDLMGetReplayState(void)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	return listState->replayState;
+    }
+    else {
+	return CRDLM_IMMEDIATE;
+    }
+}
+
+/**
+ *
+ * Playback/execute a list.
+ * dlm - the display list manager context
+ * listIdentifier - the display list ID (as specified by app) to playback
+ * dispatchTable - the GL dispatch table to jump through as we execute commands
+ */
+void DLM_APIENTRY crDLMReplayDLMList(CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+    DLMListInfo *listInfo;
+
+    listInfo = (DLMListInfo *)crHashtableSearch(dlm->displayLists, listIdentifier);
+    if (listInfo) {
+	DLMInstanceList *instance = listInfo->first;
+	while (instance) {
+	    /* mutex, to make sure another thread doesn't change the list? */
+	    /* For now, leave it alone. */
+	    (*instance->execute)(instance, dispatchTable);
+	    instance = instance->next;
+	}
+    }
+}
+
+/* Playback/execute a list in the current DLM */
+void DLM_APIENTRY crDLMReplayList(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	CRDLMReplayState oldReplayState = listState->replayState;
+	listState->replayState = CRDLM_REPLAY_ALL_FUNCTIONS;
+	crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
+	listState->replayState = oldReplayState;
+    }
+}
+
+/*
+ * Playback/execute the state changing portions of a list.
+ * dlm - the display list manager context
+ * listIdentifier - the display list ID (as specified by app) to playback
+ * dispatchTable - the GL dispatch table to jump through as we execute commands
+ */
+void DLM_APIENTRY crDLMReplayDLMListState(CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+    DLMListInfo *listInfo;
+
+    listInfo = (DLMListInfo *)crHashtableSearch(dlm->displayLists, listIdentifier);
+    if (listInfo) {
+	DLMInstanceList *instance = listInfo->stateFirst;
+	while (instance) {
+	    /* mutex, to make sure another thread doesn't change the list? */
+	    /* For now, leave it alone. */
+	    (*instance->execute)(instance, dispatchTable);
+	    instance = instance->stateNext;
+	}
+    }
+}
+
+void DLM_APIENTRY crDLMReplayListState(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	CRDLMReplayState oldReplayState = listState->replayState;
+	listState->replayState = CRDLM_REPLAY_STATE_FUNCTIONS;
+	crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
+	listState->replayState = oldReplayState;
+    }
+}
+
+/* This is a switch statement that lists every "type" value valid for a
+ * glCallLists() function call, with code for decoding the subsequent
+ * values correctly.  It uses the current value of the EXPAND() macro,
+ * which must expand into an appropriate action to be taken.
+ * Its codification here allows for multiple uses.
+ */
+#define CALL_LISTS_SWITCH(type, defaultAction) \
+    switch (type) {\
+	EXPAND(GL_BYTE, GLbyte *, *p, p++)\
+	EXPAND(GL_UNSIGNED_BYTE, GLubyte *, *p, p++)\
+	EXPAND(GL_SHORT, GLshort *, *p, p++)\
+	EXPAND(GL_UNSIGNED_SHORT, GLushort *, *p, p++)\
+	EXPAND(GL_INT, GLint *, *p, p++)\
+	EXPAND(GL_FLOAT, GLfloat *, *p, p++)\
+	EXPAND(GL_2_BYTES, unsigned char *, 256*p[0] + p[1], p += 2)\
+	EXPAND(GL_3_BYTES, unsigned char *, 65536*p[0] + 256*p[1] + p[2], p += 3)\
+	EXPAND(GL_4_BYTES, unsigned char *, 16777216*p[0] + 65536*p[1] + 256*p[2] + p[3], p += 4)\
+	default:\
+	    defaultAction;\
+    }
+
+void DLM_APIENTRY crDLMReplayDLMLists(CRDLM *dlm, GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+    unsigned long listId;
+    CRDLMContextState *listState = CURRENT_STATE();
+
+#define EXPAND(TYPENAME, TYPE, REFERENCE, INCREMENT) \
+    case TYPENAME: {\
+	TYPE p = (TYPE)lists;\
+	while (n--) {\
+	    listId = listState->listBase + (unsigned long) (REFERENCE);\
+	    crDLMReplayDLMList(dlm, listId, dispatchTable);\
+	    INCREMENT;\
+	}\
+	break;\
+    }
+
+    CALL_LISTS_SWITCH(type, break)
+#undef EXPAND
+
+}
+
+void DLM_APIENTRY crDLMReplayLists(GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	crDLMReplayDLMLists(listState->dlm, n, type, lists, dispatchTable);
+    }
+}
+
+void DLM_APIENTRY crDLMReplayDLMListsState(CRDLM *dlm, GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+    unsigned long listId;
+    CRDLMContextState *listState = CURRENT_STATE();
+
+#define EXPAND(TYPENAME, TYPE, REFERENCE, INCREMENT) \
+    case TYPENAME: {\
+	TYPE p = (TYPE)lists;\
+	while (n--) {\
+	    listId = listState->listBase + (unsigned long) (REFERENCE);\
+	    crDLMReplayDLMListState(dlm, listId, dispatchTable);\
+	    INCREMENT;\
+	}\
+	break;\
+    }
+
+    CALL_LISTS_SWITCH(type, break)
+#undef EXPAND
+
+}
+
+void DLM_APIENTRY crDLMReplayListsState(GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	crDLMReplayDLMListsState(listState->dlm, n, type, lists, dispatchTable);
+    }
+}
+
+/* When we compiled the display list, we packed all pixel data
+ * tightly.  When we execute the display list, we have to make
+ * sure that the client state reflects that the pixel data is
+ * tightly packed, or it will be interpreted incorrectly.
+ */
+void DLM_APIENTRY crDLMSetupClientState(SPUDispatchTable *dispatchTable)
+{
+    dispatchTable->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    dispatchTable->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    dispatchTable->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+    dispatchTable->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+}
+
+void DLM_APIENTRY crDLMRestoreClientState(CRClientState *clientState, SPUDispatchTable *dispatchTable)
+{
+    if (clientState) {
+	dispatchTable->PixelStorei(GL_UNPACK_ROW_LENGTH, clientState->unpack.rowLength);
+	dispatchTable->PixelStorei(GL_UNPACK_SKIP_PIXELS, clientState->unpack.skipPixels);
+	dispatchTable->PixelStorei(GL_UNPACK_SKIP_ROWS, clientState->unpack.skipRows);
+	dispatchTable->PixelStorei(GL_UNPACK_ALIGNMENT, clientState->unpack.alignment);
+    }
+}
+
+void DLM_APIENTRY crDLMSendDLMList(CRDLM *dlm, unsigned long listIdentifier,
+	SPUDispatchTable *dispatchTable)
+{
+    dispatchTable->NewList(listIdentifier, GL_COMPILE);
+    crDLMReplayDLMList(dlm, listIdentifier, dispatchTable);
+    dispatchTable->EndList();
+}
+
+void DLM_APIENTRY crDLMSendList(unsigned long listIdentifier, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	crDLMSendDLMList(listState->dlm, listIdentifier, dispatchTable);
+    }
+}
+
+struct sendListsCallbackParms {
+    CRDLM *dlm;
+    SPUDispatchTable *dispatchTable;
+};
+
+static void sendListsCallback(unsigned long key, void *data, void *dataPtr2)
+{
+    struct sendListsCallbackParms *parms = (struct sendListsCallbackParms *)dataPtr2;
+
+    crDLMSendDLMList(parms->dlm, key, parms->dispatchTable);
+}
+
+void DLM_APIENTRY crDLMSendAllDLMLists(CRDLM *dlm, SPUDispatchTable *dispatchTable)
+{
+    struct sendListsCallbackParms parms;
+
+    /* This is how we pass our parameter information to the callback routine -
+     * through a pointer to this local structure.
+     */
+    parms.dlm = dlm;
+    parms.dispatchTable = dispatchTable;
+
+    crHashtableWalk(dlm->displayLists, sendListsCallback, (void *)&parms);
+}
+
+void DLM_APIENTRY crDLMSendAllLists(SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	crDLMSendAllDLMLists(listState->dlm, dispatchTable);
+    }
+}
+
+/** Another clever callback arrangement to get the desired data. */
+struct getRefsCallbackParms {
+    int remainingOffset;
+    int remainingCount;
+    unsigned int *buffer;
+    int totalCount;
+};
+
+static void getRefsCallback(unsigned long key, void *data, void *dataPtr2)
+{
+    struct getRefsCallbackParms *cbParms = 
+	(struct getRefsCallbackParms *)dataPtr2;
+
+    /* Count the total number of references */
+    cbParms->totalCount++;
+
+    /* If we haven't yet reached the desired offset, decrement it */
+    if (cbParms->remainingOffset > 0) {
+	cbParms->remainingOffset--;
+    }
+    else if (cbParms->remainingCount > 0) {
+	 /* Store data until we've stored all we can.
+	 */
+	*(cbParms->buffer++) = key;
+	cbParms->remainingCount--;
+    }
+}
+
+int DLM_APIENTRY crDLMGetReferences(CRDLM *dlm, unsigned long listIdentifier,
+    int firstIndex, int sizeofBuffer, unsigned int *buffer)
+{
+    DLMListInfo *listInfo;
+
+    listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+    if (listInfo) {
+	struct getRefsCallbackParms cbParms;
+
+	cbParms.remainingOffset = firstIndex;
+	cbParms.remainingCount = sizeofBuffer;
+	cbParms.buffer = buffer;
+	cbParms.totalCount = 0;
+
+	crHashtableWalk(listInfo->references, getRefsCallback, (void *)&cbParms);
+
+	return cbParms.totalCount;
+    }
+    else {
+	/* No list exists; it therefore has no references */
+	return 0;
+    }
+}
+
+CRDLMError DLM_APIENTRY crDLMGetDLMBounds(CRDLM *dlm, unsigned long listIdentifier, CRDLMBounds *bounds)
+{
+	DLMListInfo *listInfo
+		= (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+	if (listInfo) {
+		*bounds = listInfo->bbox;
+		return GL_NO_ERROR;
+	}
+	else {
+		return GL_INVALID_OPERATION;
+	}
+}
+
+CRDLMError DLM_APIENTRY crDLMGetBounds(unsigned long listIdentifier, CRDLMBounds *bounds)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	return crDLMGetDLMBounds(listState->dlm, listIdentifier, bounds);
+    }
+    else {
+	return CRDLM_ERROR_STATE;
+    }
+}
+
+
+/**
+ * Set the bounding box for a display list.
+ */
+void DLM_APIENTRY crDLMSetDLMBounds(CRDLM *dlm, unsigned long listIdentifier,
+               double xmin, double ymin, double zmin,
+               double xmax, double ymax, double zmax)
+{
+	DLMListInfo *listInfo
+		= (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+	if (!listInfo) {
+		/* allocate a list info now */
+		CRDLMContextState *listState = CURRENT_STATE();
+		listInfo = (DLMListInfo *) crCalloc(sizeof(DLMListInfo));
+		crHashtableReplace(listState->dlm->displayLists,
+											 listIdentifier, listInfo, crdlm_free_list);
+	}
+	if (listInfo) {
+		listInfo->bbox.xmin = xmin;
+		listInfo->bbox.ymin = ymin;
+		listInfo->bbox.zmin = zmin;
+		listInfo->bbox.xmax = xmax;
+		listInfo->bbox.ymax = ymax;
+		listInfo->bbox.zmax = zmax;
+	}
+}
+
+void DLM_APIENTRY crDLMSetBounds(unsigned long listIdentifier,
+               double xmin, double ymin, double zmin,
+               double xmax, double ymax, double zmax)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	crDLMSetDLMBounds(listState->dlm, listIdentifier,
+	    xmin, ymin, zmin, xmax, ymax, zmax);
+    }
+}
+
+/**
+ * Return GL_TRUE if the given list has a valid bounding box
+ */
+GLboolean DLM_APIENTRY crDLMListHasDLMBounds(CRDLM *dlm, unsigned long listIdentifier)
+{
+	DLMListInfo *listInfo
+		= (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier);
+	if (listInfo)
+		return listInfo->bbox.xmin != FLT_MAX;
+	else
+		return GL_FALSE;
+}
+
+GLboolean DLM_APIENTRY crDLMListHasBounds(unsigned long listIdentifier)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    if (listState) {
+	return crDLMListHasDLMBounds(listState->dlm, listIdentifier);
+    }
+    return 0;
+}
+
+/*
+ * Return id of list currently being compiled.  Returns 0 of there's no
+ * current DLM state, or if no list is being compiled. 
+ */
+GLuint DLM_APIENTRY crDLMGetCurrentList(void)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+	return listState ? listState->currentListIdentifier : 0;
+}
+
+/*
+ * Return mode of list currently being compiled.  Should be 
+ * GL_FALSE if no list is being compiled, or GL_COMPILE if a
+ * list is being compiled but not executed, or GL_COMPILE_AND_EXECUTE
+ * if a list is being compiled and executed.
+ */
+GLenum DLM_APIENTRY crDLMGetCurrentMode(void)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+	return listState ? listState->currentListMode : 0;
+}
+
+
+static CRDLMErrorCallback ErrorCallback = NULL;
+
+void DLM_APIENTRY crDLMErrorFunction(CRDLMErrorCallback callback)
+{
+	ErrorCallback = callback;
+}
+
+void crdlm_error(int line, const char *file, GLenum error, const char *info)
+{
+	if (ErrorCallback)
+		(*ErrorCallback)(line, file, error, info);
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h	(revision 54905)
@@ -0,0 +1,31 @@
+/* $Id$ */
+
+#ifndef _DLM_H
+#define _DLM_H
+
+#include "cr_dlm.h"
+#include "cr_spu.h"
+
+#ifdef CHROMIUM_THREADSAFE
+#define DLM_LOCK(dlm) crLockMutex(&(dlm->dlMutex));
+#define DLM_UNLOCK(dlm) crUnlockMutex(&(dlm->dlMutex));
+extern CRtsd CRDLMTSDKey;
+#define SET_CURRENT_STATE(state) crSetTSD(&CRDLMTSDKey, (void *)state);
+#define CURRENT_STATE() ((CRDLMContextState *)crGetTSD(&CRDLMTSDKey))
+#else
+#define DLM_LOCK(dlm)
+#define DLM_UNLOCK(dlm)
+extern CRDLMContextState *CRDLMCurrentState;
+#define SET_CURRENT_STATE(state) CRDLMCurrentState = (state);
+#define CURRENT_STATE() (CRDLMCurrentState)
+#endif
+
+/* These routines are intended to be used within the DLM library, across
+ * the modules therein, but not as an API into the DLM library from
+ * outside.
+ */
+extern void crdlmWarning( int line, char *file, GLenum error, char *format, ... );
+extern void crdlm_free_list(/* DLMListInfo * */ void *listInfo);
+extern void crdlm_error(int line, const char *file, GLenum error, const char *info);
+
+#endif
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_arrays.c	(revision 54905)
@@ -0,0 +1,387 @@
+/* $Id$ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "chromium.h"
+#include "cr_dlm.h"
+#include "dlm.h"
+
+/*
+ * XXX this code is awfully similar to the code in arrayspu.c
+ * We should try to write something reusable.
+ */
+
+void DLM_APIENTRY crDLMCompileArrayElement (GLint index, CRClientState *c)
+{
+  unsigned char *p;
+  int unit;
+
+  if (c->array.e.enabled)
+  {
+    crDLMCompileEdgeFlagv(c->array.e.p + index*c->array.e.stride);
+  }
+  for (unit = 0; unit < CR_MAX_TEXTURE_UNITS; unit++)
+  {
+    if (c->array.t[unit].enabled)
+    {
+      p = c->array.t[unit].p + index*c->array.t[unit].stride;
+      switch (c->array.t[unit].type)
+      {
+        case GL_SHORT:
+          switch (c->array.t[c->curClientTextureUnit].size)
+          {
+            case 1: crDLMCompileMultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+            case 2: crDLMCompileMultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+            case 3: crDLMCompileMultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+            case 4: crDLMCompileMultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+          }
+          break;
+        case GL_INT:
+          switch (c->array.t[c->curClientTextureUnit].size)
+          {
+            case 1: crDLMCompileMultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+            case 2: crDLMCompileMultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+            case 3: crDLMCompileMultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+            case 4: crDLMCompileMultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+          }
+          break;
+        case GL_FLOAT:
+          switch (c->array.t[c->curClientTextureUnit].size)
+          {
+            case 1: crDLMCompileMultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+            case 2: crDLMCompileMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+            case 3: crDLMCompileMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+            case 4: crDLMCompileMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+          }
+          break;
+        case GL_DOUBLE:
+          switch (c->array.t[c->curClientTextureUnit].size)
+          {
+            case 1: crDLMCompileMultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+            case 2: crDLMCompileMultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+            case 3: crDLMCompileMultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+            case 4: crDLMCompileMultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+          }
+          break;
+      }
+    }
+  } /* loop over texture units */
+
+  if (c->array.i.enabled)
+  {
+    p = c->array.i.p + index*c->array.i.stride;
+    switch (c->array.i.type)
+    {
+      case GL_SHORT: crDLMCompileIndexsv((GLshort *)p); break;
+      case GL_INT: crDLMCompileIndexiv((GLint *)p); break;
+      case GL_FLOAT: crDLMCompileIndexfv((GLfloat *)p); break;
+      case GL_DOUBLE: crDLMCompileIndexdv((GLdouble *)p); break;
+    }
+  }
+  if (c->array.c.enabled)
+  {
+    p = c->array.c.p + index*c->array.c.stride;
+    switch (c->array.c.type)
+    {
+      case GL_BYTE:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3bv((GLbyte *)p); break;
+          case 4: crDLMCompileColor4bv((GLbyte *)p); break;
+        }
+        break;
+      case GL_UNSIGNED_BYTE:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3ubv((GLubyte *)p); break;
+          case 4: crDLMCompileColor4ubv((GLubyte *)p); break;
+        }
+        break;
+      case GL_SHORT:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3sv((GLshort *)p); break;
+          case 4: crDLMCompileColor4sv((GLshort *)p); break;
+        }
+        break;
+      case GL_UNSIGNED_SHORT:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3usv((GLushort *)p); break;
+          case 4: crDLMCompileColor4usv((GLushort *)p); break;
+        }
+        break;
+      case GL_INT:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3iv((GLint *)p); break;
+          case 4: crDLMCompileColor4iv((GLint *)p); break;
+        }
+        break;
+      case GL_UNSIGNED_INT:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3uiv((GLuint *)p); break;
+          case 4: crDLMCompileColor4uiv((GLuint *)p); break;
+        }
+        break;
+      case GL_FLOAT:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3fv((GLfloat *)p); break;
+          case 4: crDLMCompileColor4fv((GLfloat *)p); break;
+        }
+        break;
+      case GL_DOUBLE:
+        switch (c->array.c.size)
+        {
+          case 3: crDLMCompileColor3dv((GLdouble *)p); break;
+          case 4: crDLMCompileColor4dv((GLdouble *)p); break;
+        }
+        break;
+    }
+  }
+  if (c->array.n.enabled)
+  {
+    p = c->array.n.p + index*c->array.n.stride;
+    switch (c->array.n.type)
+    {
+      case GL_BYTE: crDLMCompileNormal3bv((GLbyte *)p); break;
+      case GL_SHORT: crDLMCompileNormal3sv((GLshort *)p); break;
+      case GL_INT: crDLMCompileNormal3iv((GLint *)p); break;
+      case GL_FLOAT: crDLMCompileNormal3fv((GLfloat *)p); break;
+      case GL_DOUBLE: crDLMCompileNormal3dv((GLdouble *)p); break;
+    }
+  }
+#ifdef CR_EXT_secondary_color
+  if (c->array.s.enabled)
+  {
+    p = c->array.s.p + index*c->array.s.stride;
+    switch (c->array.s.type)
+    {
+      case GL_BYTE:
+        crDLMCompileSecondaryColor3bvEXT((GLbyte *)p); break;
+      case GL_UNSIGNED_BYTE:
+        crDLMCompileSecondaryColor3ubvEXT((GLubyte *)p); break;
+      case GL_SHORT:
+        crDLMCompileSecondaryColor3svEXT((GLshort *)p); break;
+      case GL_UNSIGNED_SHORT:
+        crDLMCompileSecondaryColor3usvEXT((GLushort *)p); break;
+      case GL_INT:
+        crDLMCompileSecondaryColor3ivEXT((GLint *)p); break;
+      case GL_UNSIGNED_INT:
+        crDLMCompileSecondaryColor3uivEXT((GLuint *)p); break;
+      case GL_FLOAT:
+        crDLMCompileSecondaryColor3fvEXT((GLfloat *)p); break;
+      case GL_DOUBLE:
+        crDLMCompileSecondaryColor3dvEXT((GLdouble *)p); break;
+    }
+  }
+#endif
+  if (c->array.v.enabled)
+  {
+    p = c->array.v.p + (index*c->array.v.stride);
+
+    switch (c->array.v.type)
+    {
+      case GL_SHORT:
+        switch (c->array.v.size)
+        {
+          case 2: crDLMCompileVertex2sv((GLshort *)p); break;
+          case 3: crDLMCompileVertex3sv((GLshort *)p); break;
+          case 4: crDLMCompileVertex4sv((GLshort *)p); break;
+        }
+        break;
+      case GL_INT:
+        switch (c->array.v.size)
+        {
+          case 2: crDLMCompileVertex2iv((GLint *)p); break;
+          case 3: crDLMCompileVertex3iv((GLint *)p); break;
+          case 4: crDLMCompileVertex4iv((GLint *)p); break;
+        }
+        break;
+      case GL_FLOAT:
+        switch (c->array.v.size)
+        {
+          case 2: crDLMCompileVertex2fv((GLfloat *)p); break;
+          case 3: crDLMCompileVertex3fv((GLfloat *)p); break;
+          case 4: crDLMCompileVertex4fv((GLfloat *)p); break;
+        }
+        break;
+      case GL_DOUBLE:
+        switch (c->array.v.size)
+        {
+          case 2: crDLMCompileVertex2dv((GLdouble *)p); break;
+          case 3: crDLMCompileVertex3dv((GLdouble *)p); break;
+          case 4: crDLMCompileVertex4dv((GLdouble *)p); break;
+        }
+        break;
+    }
+  }
+}
+
+void DLM_APIENTRY crDLMCompileDrawArrays(GLenum mode, GLint first, GLsizei count, CRClientState *c)
+{
+  int i;
+
+  if (count < 0)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawArrays(negative count)");
+    return;
+  }
+
+  if (mode > GL_POLYGON)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawArrays(bad mode)");
+    return;
+  }
+
+  crDLMCompileBegin(mode);
+  for (i=0; i<count; i++)
+  {
+    crDLMCompileArrayElement(first + i, c);
+  }
+  crDLMCompileEnd();
+}
+
+void DLM_APIENTRY crDLMCompileDrawElements(GLenum mode, GLsizei count,
+                                      GLenum type, const GLvoid *indices, CRClientState *c)
+{
+  int i;
+  GLubyte *p = (GLubyte *)indices;
+
+  if (count < 0)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawElements(negative count)");
+    return;
+  }
+
+  if (mode > GL_POLYGON)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawElements(bad mode)");
+    return;
+  }
+
+  if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawElements(bad type)");
+    return;
+  }
+
+  crDLMCompileBegin(mode);
+  switch (type)
+  {
+  case GL_UNSIGNED_BYTE:
+    for (i=0; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) *p++, c);
+    }
+    break;
+  case GL_UNSIGNED_SHORT:
+    for (i=0; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) * (GLushort *) p, c);
+      p+=sizeof (GLushort);
+    }
+    break;
+  case GL_UNSIGNED_INT:
+    for (i=0; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) * (GLuint *) p, c);
+      p+=sizeof (GLuint);
+    }
+    break;
+  default:
+    crError( "this can't happen: DLM DrawElements" );
+    break;
+  }
+  crDLMCompileEnd();
+}
+
+void DLM_APIENTRY crDLMCompileDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, 
+                                      GLenum type, const GLvoid *indices, CRClientState *c)
+{
+  int i;
+  GLubyte *p = (GLubyte *)indices;
+
+  (void) end;
+
+  if (count < 0)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_VALUE, "DLM DrawRangeElements(negative count)");
+    return;
+  }
+
+  if (mode > GL_POLYGON)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawRangeElements(bad mode)");
+    return;
+  }
+
+  if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+  {
+    crdlmWarning(__LINE__, __FILE__, GL_INVALID_ENUM, "DLM DrawRangeElements(bad type)");
+    return;
+  }
+
+  crDLMCompileBegin(mode);
+  switch (type)
+  {
+  case GL_UNSIGNED_BYTE:
+    for (i=start; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) *p++, c);
+    }
+    break;
+  case GL_UNSIGNED_SHORT:
+    for (i=start; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) * (GLushort *) p, c);
+      p+=sizeof (GLushort);
+    }
+    break;
+  case GL_UNSIGNED_INT:
+    for (i=start; i<count; i++)
+    {
+      crDLMCompileArrayElement((GLint) * (GLuint *) p, c);
+      p+=sizeof (GLuint);
+    }
+    break;
+  default:
+    crError( "this can't happen: DLM DrawRangeElements" );
+    break;
+  }
+  crDLMCompileEnd();
+}
+
+#ifdef CR_EXT_multi_draw_arrays
+void DLM_APIENTRY crDLMCompileMultiDrawArraysEXT( GLenum mode, GLint *first,
+                          GLsizei *count, GLsizei primcount, CRClientState *c)
+{
+   GLint i;
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         crDLMCompileDrawArrays(mode, first[i], count[i], c);
+      }
+   }
+}
+
+
+void DLM_APIENTRY crDLMCompileMultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
+                            const GLvoid **indices, GLsizei primcount, CRClientState *c)
+{
+   GLint i;
+
+   for (i = 0; i < primcount; i++) {
+      if (count[i] > 0) {
+         crDLMCompileDrawElements(mode, count[i], type, indices[i], c);
+      }
+   }
+}
+#endif /* CR_EXT_multi_draw_arrays */
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_bbox.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_bbox.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_bbox.c	(revision 54905)
@@ -0,0 +1,454 @@
+/* $Id$ */
+/**
+ * Code to compute the bounding box of a DLM display list.
+ * Matrix commands in the display list are observed to properly
+ * transform the vertices we find.
+ */
+
+#include <float.h>
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_spu.h"
+#include "cr_glstate.h"
+#include "dlm.h"
+
+
+static CRMatrixStack ModelViewStack;
+static CRMatrixStack DummyStack;
+static CRMatrixStack *CurrentStack;
+
+
+static GLfloat Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
+
+
+static void
+MatrixMode(GLenum matrix)
+{
+	switch (matrix) {
+	case GL_MODELVIEW:
+		CurrentStack = &ModelViewStack;
+		break;
+	default:
+		CurrentStack = &DummyStack;
+	}
+}
+
+
+static void
+LoadMatrixf(const GLfloat m[16])
+{
+	crMatrixInitFromFloats(CurrentStack->top, m);
+}
+
+
+static void
+LoadMatrixd(const GLdouble m[16])
+{
+	crMatrixInitFromDoubles(CurrentStack->top, m);
+}
+
+
+static void
+LoadIdentity(void)
+{
+	crMatrixInit(CurrentStack->top);
+}
+
+
+static void
+PushMatrix(void)
+{
+	if (CurrentStack->depth < CurrentStack->maxDepth) {
+		/* copy matrix */
+		*(CurrentStack->top + 1) = *(CurrentStack->top);
+		/* Move the stack pointer */
+		CurrentStack->depth++;
+		CurrentStack->top = CurrentStack->stack + CurrentStack->depth;
+	}
+	else {
+		crWarning("Stack overflow in dlm_bbox.c");
+	}
+}
+
+
+static void
+PopMatrix(void)
+{
+	if (CurrentStack->depth > 0) {
+		CurrentStack->depth--;
+		CurrentStack->top = CurrentStack->stack + CurrentStack->depth;
+	}
+	else {
+		crWarning("Stack underflow in dlm_bbox.c");
+	}
+}
+
+
+static void
+MultMatrixf(const GLfloat m1[16])
+{
+	CRmatrix *m = CurrentStack->top;
+	const GLdefault lm00 = m->m00;  
+	const GLdefault lm01 = m->m01;  
+	const GLdefault lm02 = m->m02;	
+	const GLdefault lm03 = m->m03;	
+	const GLdefault lm10 = m->m10;	
+	const GLdefault lm11 = m->m11;	
+	const GLdefault lm12 = m->m12;	
+	const GLdefault lm13 = m->m13;	
+	const GLdefault lm20 = m->m20;	
+	const GLdefault lm21 = m->m21;	
+	const GLdefault lm22 = m->m22;	
+	const GLdefault lm23 = m->m23;	
+	const GLdefault lm30 = m->m30;	
+	const GLdefault lm31 = m->m31;	
+	const GLdefault lm32 = m->m32;		
+	const GLdefault lm33 = m->m33;		
+	const GLdefault rm00 = (GLdefault) m1[0];	
+	const GLdefault rm01 = (GLdefault) m1[1];	
+	const GLdefault rm02 = (GLdefault) m1[2];	
+	const GLdefault rm03 = (GLdefault) m1[3];	
+	const GLdefault rm10 = (GLdefault) m1[4];	
+	const GLdefault rm11 = (GLdefault) m1[5];		
+	const GLdefault rm12 = (GLdefault) m1[6];	
+	const GLdefault rm13 = (GLdefault) m1[7];	
+	const GLdefault rm20 = (GLdefault) m1[8];	
+	const GLdefault rm21 = (GLdefault) m1[9];	
+	const GLdefault rm22 = (GLdefault) m1[10];	
+	const GLdefault rm23 = (GLdefault) m1[11];	
+	const GLdefault rm30 = (GLdefault) m1[12];	
+	const GLdefault rm31 = (GLdefault) m1[13];	
+	const GLdefault rm32 = (GLdefault) m1[14];	
+	const GLdefault rm33 = (GLdefault) m1[15];	
+
+	m->m00 = lm00*rm00 + lm10*rm01 + lm20*rm02 + lm30*rm03;	
+	m->m01 = lm01*rm00 + lm11*rm01 + lm21*rm02 + lm31*rm03;	
+	m->m02 = lm02*rm00 + lm12*rm01 + lm22*rm02 + lm32*rm03;	
+	m->m03 = lm03*rm00 + lm13*rm01 + lm23*rm02 + lm33*rm03;	
+	m->m10 = lm00*rm10 + lm10*rm11 + lm20*rm12 + lm30*rm13;	
+	m->m11 = lm01*rm10 + lm11*rm11 + lm21*rm12 + lm31*rm13;	
+	m->m12 = lm02*rm10 + lm12*rm11 + lm22*rm12 + lm32*rm13;	
+	m->m13 = lm03*rm10 + lm13*rm11 + lm23*rm12 + lm33*rm13;	
+	m->m20 = lm00*rm20 + lm10*rm21 + lm20*rm22 + lm30*rm23;	
+	m->m21 = lm01*rm20 + lm11*rm21 + lm21*rm22 + lm31*rm23;	
+	m->m22 = lm02*rm20 + lm12*rm21 + lm22*rm22 + lm32*rm23;	
+	m->m23 = lm03*rm20 + lm13*rm21 + lm23*rm22 + lm33*rm23;	
+	m->m30 = lm00*rm30 + lm10*rm31 + lm20*rm32 + lm30*rm33;	
+	m->m31 = lm01*rm30 + lm11*rm31 + lm21*rm32 + lm31*rm33;	
+	m->m32 = lm02*rm30 + lm12*rm31 + lm22*rm32 + lm32*rm33;	
+	m->m33 = lm03*rm30 + lm13*rm31 + lm23*rm32 + lm33*rm33;
+}
+
+
+static void
+MultMatrixd(const GLdouble m1[16])
+{
+	GLfloat m2[16];
+	int i;
+	for (i = 0; i < 16; i++)
+		m2[i] = (GLfloat) m1[i];
+	MultMatrixf(m2);
+}
+
+
+static void
+Rotatef(GLfloat ang, GLfloat x, GLfloat y, GLfloat z) 
+{
+	crMatrixRotate(CurrentStack->top, ang, x, y, z);
+}
+
+
+static void
+Rotated(GLdouble ang, GLdouble x, GLdouble y, GLdouble z) 
+{
+	crMatrixRotate(CurrentStack->top, (GLfloat) ang,
+								 (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+static void
+Translatef(GLfloat x, GLfloat y, GLfloat z) 
+{
+	crMatrixTranslate(CurrentStack->top, x, y, z);
+}
+
+
+static void
+Translated(GLdouble x, GLdouble y, GLdouble z) 
+{
+	crMatrixTranslate(CurrentStack->top, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+static void
+Scalef(GLfloat x, GLfloat y, GLfloat z) 
+{
+	crMatrixScale(CurrentStack->top, x, y, z);
+}
+
+
+static void
+Scaled(GLdouble x, GLdouble y, GLdouble z) 
+{
+	crMatrixScale(CurrentStack->top, (GLfloat) x, (GLfloat) y, (GLfloat) z);
+}
+
+
+/**
+ * Transform given (x,y,z,w) by current matrix and update the bounding box.
+ */
+static void
+DoVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	const CRmatrix *m = CurrentStack->top;
+	const GLfloat x2 = m->m00 * x + m->m10 * y + m->m20 * z + m->m30 * w;
+	const GLfloat y2 = m->m01 * x + m->m11 * y + m->m21 * z + m->m31 * w;
+	const GLfloat z2 = m->m02 * x + m->m12 * y + m->m22 * z + m->m32 * w;
+	/*const GLfloat w2 = m->m03 * x + m->m13 * y + m->m23 * z + m->m33 * w;*/
+
+	if (x2 < Xmin) Xmin = x2;
+	if (x2 > Xmax) Xmax = x2;
+	if (y2 < Ymin) Ymin = y2;
+	if (y2 > Ymax) Ymax = y2;
+	if (z2 < Zmin) Zmin = z2;
+	if (z2 > Zmax) Zmax = z2;
+}
+
+
+static void
+Vertex2f(GLfloat x, GLfloat y)
+{
+	DoVertex(x, y, 0.0f, 1.0f);
+}
+
+static void
+Vertex2fv(const GLfloat *v)
+{
+	DoVertex(v[0], v[1], 0.0f, 1.0f);
+}
+
+static void
+Vertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+	DoVertex(x, y, z, 1.0f);
+}
+
+static void
+Vertex3fv(const GLfloat *v)
+{
+	DoVertex(v[0], v[1], v[2], 1.0f);
+}
+
+static void
+Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	DoVertex(x, y, z, w);
+}
+
+static void
+Vertex4fv(const GLfloat *v)
+{
+	DoVertex(v[0], v[1], v[2], v[3]);
+}
+
+
+/**
+ ** XXX TO DO:
+ **
+glVertex2d( GLdouble x, GLdouble y );
+glVertex2f( GLfloat x, GLfloat y );
+glVertex2i( GLint x, GLint y );
+glVertex2s( GLshort x, GLshort y );
+glVertex3d( GLdouble x, GLdouble y, GLdouble z );
+glVertex3f( GLfloat x, GLfloat y, GLfloat z );
+glVertex3i( GLint x, GLint y, GLint z );
+glVertex3s( GLshort x, GLshort y, GLshort z );
+glVertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w );
+glVertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w );
+glVertex4i( GLint x, GLint y, GLint z, GLint w );
+glVertex4s( GLshort x, GLshort y, GLshort z, GLshort w );
+glVertex2dv( const GLdouble *v );
+glVertex2fv( const GLfloat *v );
+glVertex2iv( const GLint *v );
+glVertex2sv( const GLshort *v );
+glVertex3dv( const GLdouble *v );
+glVertex3fv( const GLfloat *v );
+glVertex3iv( const GLint *v );
+glVertex3sv( const GLshort *v );
+glVertex4dv( const GLdouble *v );
+glVertex4fv( const GLfloat *v );
+glVertex4iv( const GLint *v );
+glVertex4sv( const GLshort *v );
+
+glVertexAttrib1dARB(GLuint, GLdouble);
+glVertexAttrib1dvARB(GLuint, const GLdouble *);
+glVertexAttrib1fARB(GLuint, GLfloat);
+glVertexAttrib1fvARB(GLuint, const GLfloat *);
+glVertexAttrib1sARB(GLuint, GLshort);
+glVertexAttrib1svARB(GLuint, const GLshort *);
+glVertexAttrib2dARB(GLuint, GLdouble, GLdouble);
+glVertexAttrib2dvARB(GLuint, const GLdouble *);
+glVertexAttrib2fARB(GLuint, GLfloat, GLfloat);
+glVertexAttrib2fvARB(GLuint, const GLfloat *);
+glVertexAttrib2sARB(GLuint, GLshort, GLshort);
+glVertexAttrib2svARB(GLuint, const GLshort *);
+glVertexAttrib3dARB(GLuint, GLdouble, GLdouble, GLdouble);
+glVertexAttrib3dvARB(GLuint, const GLdouble *);
+**/
+
+static void
+VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+	if (index == 0)
+		DoVertex(x, y, z, 1.0f);
+}
+
+/**
+glVertexAttrib3fvARB(GLuint, const GLfloat *);
+glVertexAttrib3sARB(GLuint, GLshort, GLshort, GLshort);
+glVertexAttrib3svARB(GLuint, const GLshort *);
+glVertexAttrib4NbvARB(GLuint, const GLbyte *);
+glVertexAttrib4NivARB(GLuint, const GLint *);
+glVertexAttrib4NsvARB(GLuint, const GLshort *);
+glVertexAttrib4NubARB(GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+glVertexAttrib4NubvARB(GLuint, const GLubyte *);
+glVertexAttrib4NuivARB(GLuint, const GLuint *);
+glVertexAttrib4NusvARB(GLuint, const GLushort *);
+glVertexAttrib4bvARB(GLuint, const GLbyte *);
+glVertexAttrib4dARB(GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+glVertexAttrib4dvARB(GLuint, const GLdouble *);
+glVertexAttrib4fARB(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+glVertexAttrib4fvARB(GLuint, const GLfloat *);
+glVertexAttrib4ivARB(GLuint, const GLint *);
+glVertexAttrib4sARB(GLuint, GLshort, GLshort, GLshort, GLshort);
+glVertexAttrib4svARB(GLuint, const GLshort *);
+glVertexAttrib4ubvARB(GLuint, const GLubyte *);
+glVertexAttrib4uivARB(GLuint, const GLuint *);
+glVertexAttrib4usvARB(GLuint, const GLushort *);
+
+glVertexAttrib1dNV(GLuint, GLdouble);
+glVertexAttrib1dvNV(GLuint, const GLdouble *);
+glVertexAttrib1fNV(GLuint, GLfloat);
+glVertexAttrib1fvNV(GLuint, const GLfloat *);
+glVertexAttrib1sNV(GLuint, GLshort);
+glVertexAttrib1svNV(GLuint, const GLshort *);
+glVertexAttrib2dNV(GLuint, GLdouble, GLdouble);
+glVertexAttrib2dvNV(GLuint, const GLdouble *);
+glVertexAttrib2fNV(GLuint, GLfloat, GLfloat);
+glVertexAttrib2fvNV(GLuint, const GLfloat *);
+glVertexAttrib2sNV(GLuint, GLshort, GLshort);
+glVertexAttrib2svNV(GLuint, const GLshort *);
+glVertexAttrib3dNV(GLuint, GLdouble, GLdouble, GLdouble);
+glVertexAttrib3dvNV(GLuint, const GLdouble *);
+glVertexAttrib3fNV(GLuint, GLfloat, GLfloat, GLfloat);
+glVertexAttrib3fvNV(GLuint, const GLfloat *);
+glVertexAttrib3sNV(GLuint, GLshort, GLshort, GLshort);
+glVertexAttrib3svNV(GLuint, const GLshort *);
+glVertexAttrib4dNV(GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+glVertexAttrib4dvNV(GLuint, const GLdouble *);
+glVertexAttrib4fNV(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+glVertexAttrib4fvNV(GLuint, const GLfloat *);
+glVertexAttrib4sNV(GLuint, GLshort, GLshort, GLshort, GLshort);
+glVertexAttrib4svNV(GLuint, const GLshort *);
+glVertexAttrib4ubNV(GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+glVertexAttrib4ubvNV(GLuint, const GLubyte *);
+
+glVertexAttribs1dvNV(GLuint, GLsizei, const GLdouble *);
+glVertexAttribs1fvNV(GLuint, GLsizei, const GLfloat *);
+glVertexAttribs1svNV(GLuint, GLsizei, const GLshort *);
+glVertexAttribs2dvNV(GLuint, GLsizei, const GLdouble *);
+glVertexAttribs2fvNV(GLuint, GLsizei, const GLfloat *);
+glVertexAttribs2svNV(GLuint, GLsizei, const GLshort *);
+glVertexAttribs3dvNV(GLuint, GLsizei, const GLdouble *);
+glVertexAttribs3fvNV(GLuint, GLsizei, const GLfloat *);
+glVertexAttribs3svNV(GLuint, GLsizei, const GLshort *);
+glVertexAttribs4dvNV(GLuint, GLsizei, const GLdouble *);
+glVertexAttribs4fvNV(GLuint, GLsizei, const GLfloat *);
+glVertexAttribs4svNV(GLuint, GLsizei, const GLshort *);
+glVertexAttribs4ubvNV(GLuint, GLsizei, const GLubyte *);
+**/
+
+
+/**
+ ** XXX also need to track evaluator coordinates (glutTeapot)
+ **/
+
+
+static void
+InitDispatchTable(SPUDispatchTable *t)
+{
+	crMemZero(t, sizeof(*t));
+	crSPUInitDispatchNops(t);
+  /* drm1 */
+	t->MatrixMode = (MatrixModeFunc_t)MatrixMode;
+	t->LoadIdentity = (LoadIdentityFunc_t)LoadIdentity;
+	t->LoadMatrixf = (LoadMatrixfFunc_t)LoadMatrixf;
+	t->LoadMatrixd = (LoadMatrixdFunc_t)LoadMatrixd;
+	t->PushMatrix = (PushMatrixFunc_t)PushMatrix;
+	t->PopMatrix = (PopMatrixFunc_t)PopMatrix;
+	t->MultMatrixf = (MultMatrixfFunc_t)MultMatrixf;
+	t->MultMatrixd = (MultMatrixdFunc_t)MultMatrixd;
+	t->Rotatef = (RotatefFunc_t)Rotatef;
+  t->Rotated = (RotatedFunc_t)Rotated;
+	t->Translatef = (TranslatefFunc_t)Translatef;
+	t->Translated = (TranslatedFunc_t)Translated;
+	t->Scalef = (ScalefFunc_t)Scalef;
+	t->Scaled = (ScaledFunc_t)Scaled;
+	t->Vertex2f = (Vertex2fFunc_t)Vertex2f;
+	t->Vertex2fv = (Vertex2fvFunc_t)Vertex2fv;
+	t->Vertex3f = (Vertex3fFunc_t)Vertex3f;
+	t->Vertex3fv = (Vertex3fvFunc_t)Vertex3fv;
+	t->Vertex4f = (Vertex4fFunc_t)Vertex4f;
+	t->Vertex4fv = (Vertex4fvFunc_t)Vertex4fv;
+	t->VertexAttrib3fARB = (VertexAttrib3fARBFunc_t)VertexAttrib3fARB;
+}
+
+
+void
+crDLMComputeBoundingBox(unsigned long listId)
+{
+	static GLboolean tableInitialized = GL_FALSE;
+	static SPUDispatchTable t;
+	CRDLMContextState *listState = CURRENT_STATE();
+	CRDLM *dlm = listState->dlm;
+	DLMListInfo *listInfo
+		= (DLMListInfo *) crHashtableSearch(dlm->displayLists, listId);
+
+	if (!tableInitialized) {
+		InitDispatchTable(&t);
+		crStateInitMatrixStack(&ModelViewStack, CR_MAX_MODELVIEW_STACK_DEPTH);
+		crStateInitMatrixStack(&DummyStack, CR_MAX_MODELVIEW_STACK_DEPTH);
+		tableInitialized = GL_TRUE;
+	}
+
+	CurrentStack = &ModelViewStack;
+
+	Xmin = Ymin = Zmin = FLT_MAX;
+	Xmax = Ymax = Zmax = -FLT_MAX;
+	
+	crDLMReplayDLMList(listState->dlm, listId, &t);
+
+	if (Xmin == FLT_MAX) {
+		/* XXX review this choice of default bounds */
+		/*
+		crDebug("Warning: no bounding box!");
+		*/
+		Xmin = -100;
+		Xmax =  100;
+		Ymin = -100;
+		Ymax =  100;
+		Zmin = -100;
+		Zmax =  100;
+	}
+	/*
+	crDebug("List %d bbox: %f, %f, %f .. %f, %f, %f", (int) listId,
+					Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+	*/
+
+	listInfo->bbox.xmin = Xmin;
+	listInfo->bbox.ymin = Ymin;
+	listInfo->bbox.zmin = Zmin;
+	listInfo->bbox.xmax = Xmax;
+	listInfo->bbox.ymax = Ymax;
+	listInfo->bbox.zmax = Zmax;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c	(revision 54905)
@@ -0,0 +1,63 @@
+/* $Id$ */
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_error.h"
+#include "dlm.h"
+#include <VBox/VBoxUhgsmi.h>
+/* The headers and structures are still auto-generated */
+#include "dlm_generated.h"
+
+/* The CallList functions have a special implementation.  They aren't commonly
+ * listed as state-changers, but they can cause state to change.
+ */
+
+static void DLM_APIENTRY executeCallList(DLMInstanceList *x, SPUDispatchTable *dispatchTable)
+{
+	struct instanceCallList *instance = (struct instanceCallList *)x;
+	dispatchTable->CallList(instance->list);
+}
+void DLM_APIENTRY crDLMCompileCallList( GLuint list )
+{
+	struct instanceCallList *instance;
+	instance = crCalloc(sizeof(struct instanceCallList));
+	if (!instance) {
+		crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
+			"out of memory adding CallList to display list");
+		return;
+	}
+	/* Put in the parameters */
+	instance->list = list;
+
+	/* Add to the display list correctly */
+	crdlm_add_to_list((DLMInstanceList *)instance, executeCallList);
+}
+
+/*** CallLists ***/
+static void DLM_APIENTRY executeCallLists(DLMInstanceList *x, SPUDispatchTable *dispatchTable)
+{
+	struct instanceCallLists *instance = (struct instanceCallLists *)x;
+	dispatchTable->CallLists(instance->n, instance->type, instance->lists);
+}
+void DLM_APIENTRY crDLMCompileCallLists( GLsizei n, GLenum type, const GLvoid * lists )
+{
+	struct instanceCallLists *instance;
+	instance = crCalloc(sizeof(struct instanceCallLists) + crdlm_pointers_CallLists(NULL, n, type, lists));
+	if (!instance) {
+		crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
+			"out of memory adding CallLists to display list");
+		return;
+	}
+	instance->n = n;
+	instance->type = type;
+	if (lists == NULL) {
+		instance->lists = NULL;
+	}
+	else {
+		instance->lists = instance->listsData;
+	}
+	(void) crdlm_pointers_CallLists(instance, n, type, lists);
+
+	crdlm_add_to_list((DLMInstanceList *)instance, executeCallLists);
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_checklist.c	(revision 54905)
@@ -0,0 +1,51 @@
+/* $Id$ */
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_pixeldata.h"
+#include "cr_string.h"
+#include "dlm.h"
+
+/*****************************************************************************
+ * These helper functions are used for GL functions that are listed in
+ * the APIspec.txt file as "checklist", meaning that sometimes they
+ * represent functions that can be stored in a display list, and sometimes
+ * they represent control functions that must be executed immediately.
+ *
+ * The calling SPU must use these check functions (or their equivalents)
+ * before asking the DLM to compile any elements of these types.
+ * They return nonzero (TRUE) if the element goes into a display list.
+ */
+
+int DLM_APIENTRY crDLMCheckListTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+    return (target != GL_PROXY_TEXTURE_1D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    return (target != GL_PROXY_TEXTURE_1D);
+}
+int DLM_APIENTRY crDLMCheckListTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+    return (target != GL_PROXY_TEXTURE_2D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    return (target != GL_PROXY_TEXTURE_2D);
+}
+
+int DLM_APIENTRY crDLMCheckListTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+    return (target != GL_PROXY_TEXTURE_3D);
+}
+
+int DLM_APIENTRY crDLMCheckListTexImage3DEXT(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+    return (target != GL_PROXY_TEXTURE_3D);
+}
+
+int DLM_APIENTRY crDLMCheckListCompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    return (target != GL_PROXY_TEXTURE_3D);
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_error.c	(revision 54905)
@@ -0,0 +1,56 @@
+/* $Id$ */
+#include <stdio.h>
+#include <stdarg.h>
+#include "chromium.h"
+#include "cr_mem.h"
+#include "dlm.h"
+#include "cr_environment.h"
+#include "cr_error.h"
+
+#define GLCLIENT_LIST_ALLOC 1024
+
+void crdlmWarning( int line, char *file, GLenum error, char *format, ... )
+{
+    char errstr[8096];
+    va_list args;
+
+    if (crGetenv("CR_DEBUG")) {
+	char *glerr;
+	va_start( args, format );
+	vsprintf( errstr, format, args );
+	va_end( args );
+
+	switch (error) {
+	    case GL_NO_ERROR:
+		glerr = "GL_NO_ERROR";
+		break;
+	    case GL_INVALID_VALUE:
+		glerr = "GL_INVALID_VALUE";
+		break;
+	    case GL_INVALID_ENUM:
+		glerr = "GL_INVALID_ENUM";
+		break;
+	    case GL_INVALID_OPERATION:
+		glerr = "GL_INVALID_OPERATION";
+		break;
+	    case GL_STACK_OVERFLOW:
+		glerr = "GL_STACK_OVERFLOW";
+		break;
+	    case GL_STACK_UNDERFLOW:
+		glerr = "GL_STACK_UNDERFLOW";
+		break;
+	    case GL_OUT_OF_MEMORY:
+		glerr = "GL_OUT_OF_MEMORY";
+		break;
+	    case GL_TABLE_TOO_LARGE:
+		glerr = "GL_TABLE_TOO_LARGE";
+		break;
+	    default:
+		glerr = "unknown";
+		break;
+	}
+
+	crWarning( "DLM error in %s, line %d: %s: %s\n",
+	    file, line, glerr, errstr );
+    }
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py	(revision 54905)
@@ -0,0 +1,414 @@
+# $Id$
+import sys, cPickle, re
+
+sys.path.append( "../glapi_parser" )
+import apiutil
+
+# A routine that can create call strings from instance names
+def InstanceCallString( params ):
+	output = ''
+	for index in range(0,len(params)):
+		if index > 0:
+			output += ", "
+		if params[index][0] != '':
+			output += 'instance->' + params[index][0]
+	return output
+
+def GetPointerType(basetype):
+	words = basetype.split()
+	if words[0] == 'const':
+		words = words[1:]
+	if words[-1].endswith('*'):
+		words[-1] = words[-1][:-1].strip()
+		if words[-1] == '':
+			words = words[:-1]
+	if words[0] == 'void' or words[0] == 'GLvoid':
+		words[0] = 'int'
+	return ' '.join(words)
+
+
+def GetPointerInfo(functionName):
+	# We'll keep track of all the parameters that require pointers.
+	# They'll require special handling later.
+	params = apiutil.Parameters(functionName)
+	pointers = []
+	pointername=''
+	pointerarg=''
+	pointertype=''
+	pointersize=0
+	pointercomment=''
+
+	index = 0
+	for (name, type, vecSize) in params:
+		# Watch out for the word "const" (which should be ignored)
+		# and for types that end in "*" (which are pointers and need
+		# special treatment)
+		words = type.split()
+		if words[-1].endswith('*'):
+			pointers.append(index)
+		index += 1
+
+	# If any argument was a pointer, we need a special pointer data
+	# array.  The pointer data will be stored into this array, and
+	# references to the array will be generated as parameters.
+	if len(pointers) == 1:
+		index = pointers[0]
+		pointername = params[index][0]
+		pointerarg = pointername + 'Data'
+		pointertype = GetPointerType(params[index][1])
+		pointersize = params[index][2]
+		if pointersize == 0:
+			pointersize = "special"
+	elif len(pointers) > 1:
+		pointerarg = 'data';
+		pointertype = GetPointerType(params[pointers[0]][1])
+		for index in range(1,len(pointers)):
+			if GetPointerType(params[pointers[index]][1]) != pointertype:
+				pointertype = 'GLvoid *'
+
+	return (pointers,pointername,pointerarg,pointertype,pointersize,pointercomment)
+
+def wrap_struct(functionName):
+	params = apiutil.Parameters(functionName)
+	argstring = apiutil.MakeDeclarationString(params)
+	extendedArgstring = argstring
+	props = apiutil.Properties(functionName)
+	if "useclient" in props or "pixelstore" in props:
+		extendedArgstring += ", CRClientState *c"
+
+	# We'll keep track of all the parameters that require pointers.
+	# They'll require special handling later.
+	(pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
+
+	# Start writing the header
+	print 'struct instance%s {' % (functionName)
+	print '	DLMInstanceList *next;'
+	print '	DLMInstanceList *stateNext;'
+	print '	void (DLM_APIENTRY *execute)(DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
+	for (name, type, vecSize) in params:
+		# Watch out for the word "const" (which should be ignored)
+		# and for types that end in "*" (which are pointers and need
+		# special treatment)
+		words = type.split()
+		if words[0] == 'const':
+			words = words[1:]
+		if words[0] != "void":
+			print '	%s %s;' % (' '.join(words), name)
+
+	# If any argument was a pointer, we need a special pointer data
+	# array.  The pointer data will be stored into this array, and
+	# references to the array will be generated as parameters.
+	if len(pointers) == 1:
+		if pointersize == None:
+			print "	/* Oh no - pointer parameter %s found, but no pointer class specified and can't guess */" % pointername
+		else:
+			if pointersize == 'special':
+				print '	%s %s[1];%s' % (pointertype, pointerarg, pointercomment)
+			else:
+				print '	%s %s[%s];%s' % (pointertype, pointerarg, pointersize,pointercomment)
+	elif len(pointers) > 1:
+		print '	%s %s[1];%s' % (pointertype, pointerarg,pointercomment)
+
+	print '};'
+
+	# Pointers only happen with instances
+	if len(pointers) > 1 or (len(pointers) == 1 and pointersize == 'special'):
+		print 'int crdlm_pointers_%s(struct instance%s *instance, %s);' % (functionName, functionName, extendedArgstring)
+		
+	# See if the GL function must sometimes allow passthrough even
+	# if the display list is open
+	if "checklist" in apiutil.ChromiumProps(functionName):
+		print 'int crdlm_checklist_%s(%s);' % (functionName, argstring)
+
+	return
+
+def wrap_execute(functionName):
+	params = apiutil.Parameters(functionName)
+	print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
+	print '{'
+	if len(params) > 0:
+	    print '\tstruct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
+	print '\tif (dispatchTable->%s != NULL) {' % (functionName)
+	print '\t\tdispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
+	print '\t}'
+	print '\telse {'
+	print '\t\tcrWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
+	print '\t}'
+	print '}'
+
+def generate_bbox_code(functionName):
+	assert functionName[0:6] == "Vertex"
+	pattern = "(VertexAttribs|VertexAttrib|Vertex)(1|2|3|4)(N?)(f|d|i|s|b|ub|us|ui)(v?)"
+	m = re.match(pattern, functionName)
+	if m:
+		name = m.group(1)
+		size = int(m.group(2))
+		normalize = m.group(3)
+		type = m.group(4)
+		vector = m.group(5)
+
+		# only update bbox for vertex attribs if index == 0
+		if name == "VertexAttrib":
+			test = "if (index == 0) {"
+		elif name == "VertexAttribs":
+			test = "if (index == 0) {"
+		else:
+			assert name == "Vertex"
+			test = "{"
+
+		# find names of the X, Y, Z, W values
+		xName = ""
+		yName = ""
+		zName = "0.0"
+		wName = ""
+		if vector == "v":
+			xName = "v[0]"
+			if size > 1:
+				yName = "v[1]"
+			if size > 2:
+				zName = "v[2]"
+			if size > 3:
+				wName = "v[3]"
+		else:
+			xName = "x"
+			if size > 1:
+				yName = "y"
+			if size > 2:
+				zName = "z"
+			if size > 3:
+				wName = "w"
+
+		# start emitting code
+		print '\t%s' % test
+
+		if normalize == "N":
+			if type == "b":
+				denom = "128.0f"
+			elif type == "s":
+				denom = "32768.0f"
+			elif type == "i":
+				denom = "2147483647.0f"
+			elif type == "ub":
+				denom = "255.0f"
+			elif type == "us":
+				denom = "65535.0f"
+			elif type == "ui":
+				denom = "4294967295.0f"
+			
+			print '\t\tGLfloat nx = (GLfloat) %s / %s;' % (xName, denom)
+			xName = "nx"
+			if yName:
+				print '\t\tGLfloat ny = (GLfloat) %s / %s;' % (yName, denom)
+				yName = "ny"
+			if zName:
+				print '\t\tGLfloat nz = (GLfloat) %s / %s;' % (zName, denom)
+				zName = "nz"
+			if 0 and wName:
+				print '\t\tGLfloat nw = (GLfloat) %s / %s;' % (wName, denom)
+				wName = "nw"
+
+		if xName:
+			print '\t\tif (%s < state->currentListInfo->bbox.xmin)' % xName
+			print '\t\t\tstate->currentListInfo->bbox.xmin = %s;' % xName
+			print '\t\tif (%s > state->currentListInfo->bbox.xmax)' % xName
+			print '\t\t\tstate->currentListInfo->bbox.xmax = %s;' % xName
+		if yName:
+			print '\t\tif (%s < state->currentListInfo->bbox.ymin)' % yName
+			print '\t\t\tstate->currentListInfo->bbox.ymin = %s;' % yName
+			print '\t\tif (%s > state->currentListInfo->bbox.ymax)' % yName
+			print '\t\t\tstate->currentListInfo->bbox.ymax = %s;' % yName
+		if zName:
+			print '\t\tif (%s < state->currentListInfo->bbox.zmin)' % zName
+			print '\t\t\tstate->currentListInfo->bbox.zmin = %s;' % zName
+			print '\t\tif (%s > state->currentListInfo->bbox.zmax)' % zName
+			print '\t\t\tstate->currentListInfo->bbox.zmax = %s;' % zName
+		# XXX what about divide by W if we have 4 components?
+		print '\t}'
+			
+	else:
+		print ' /* bbox error for %s !!!!! */' % functionName
+
+# These code snippets isolate the code required to add a given instance
+# to the display list correctly.  They are used during generation, to
+# generate correct code, and also to create useful utilities.
+def AddInstanceToList(pad):
+    print '%s/* Add this instance to the current display list. */' % pad
+    print '%sinstance->next = NULL;' % pad
+    print '%sinstance->stateNext = NULL;' % pad
+    print '%sif (!state->currentListInfo->first) {' % pad
+    print '%s\tstate->currentListInfo->first = (DLMInstanceList *)instance;' % pad
+    print '%s}' % pad
+    print '%selse {' % pad
+    print '%s\tstate->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
+    print '%s}' % pad
+    print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
+    print '%sstate->currentListInfo->numInstances++;' % pad
+
+def AddInstanceToStateList(pad):
+    print '%s/* Instances that change state have to be added to the state list as well. */' % pad
+    print '%sif (!state->currentListInfo->stateFirst) {' % pad
+    print '%s\tstate->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
+    print '%s}' % pad
+    print '%selse {' % pad
+    print '%s\tstate->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
+    print '%s}' % pad
+    print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
+
+
+# The compile wrapper collects the parameters into a DLMInstanceList
+# element, and adds that element to the end of the display list currently
+# being compiled.
+def wrap_compile(functionName):
+	params = apiutil.Parameters(functionName)
+	return_type = apiutil.ReturnType(functionName)
+	# Make sure the return type is void.  It's nonsensical to compile
+	# an element with any other return type.
+	if return_type != 'void':
+		print '/* Nonsense: DL function %s has a %s return type?!? */' % (functionName, return_type)
+	#	return
+	# Define a structure to hold all the parameters.  Note that the
+	# top parameters must exactly match the DLMInstanceList structure
+	# in include/cr_dlm.h, or everything will break horribly.
+	# Start off by getting all the pointer info we could ever use
+	# from the parameters
+	(pointers, pointername, pointerarg, pointertype, pointersize, pointercomment) = GetPointerInfo(functionName)
+
+	# Finally, the compile wrapper.  This one will diverge strongly
+	# depending on whether or not there are pointer parameters. 
+	callstring = apiutil.MakeCallString(params)
+	argstring = apiutil.MakeDeclarationString(params)
+	props = apiutil.Properties(functionName)
+	if "useclient" in props or "pixelstore" in props:
+		callstring += ", c"
+		argstring += ", CRClientState *c"
+	print 'void DLM_APIENTRY crDLMCompile%s( %s )' % (functionName, argstring)
+	print '{'
+	print '	CRDLMContextState *state = CURRENT_STATE();'
+	print '	struct instance%s *instance;' % (functionName)
+
+	# The calling SPU is supposed to verify that the element is supposed to be
+	# compiled before it is actually compiled; typically, this is done based
+	# on whether a glNewList has been executed more recently than a glEndList.
+	# But some functions are dual-natured, sometimes being compiled, and sometimes
+	# being executed immediately.  We can check for this here.
+	if "checklist" in apiutil.ChromiumProps(functionName):
+	    print '\tif (crDLMCheckList%s(%s)) {' % (functionName, apiutil.MakeCallString(params))
+	    print '\t\tcrdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
+	    print '\t\t    "this instance of function %s should not be compiled");' % functionName;
+	    print '\t\treturn;'
+	    print '\t}'
+
+	if len(pointers) > 1 or pointersize == 'special':
+		# Pass NULL, to just allocate space
+		print '\tinstance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
+	else:
+		print '\tinstance = crCalloc(sizeof(struct instance%s));' % (functionName)
+	print '\tif (!instance) {'
+	print '\t\tcrdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
+	print '\t\t\t"out of memory adding %s to display list");' % (functionName)
+	print '\t\treturn;'
+	print '\t}'
+
+	# Put in the fields that must always exist
+	print '\tinstance->execute = execute%s;' % functionName
+
+	# Apply all the simple (i.e. non-pointer) parameters
+	for index in range(len(params)):
+		if index not in pointers:
+			name = params[index][0]
+			print '\tinstance->%s = %s;' % (name, name)
+
+	# If there's a pointer parameter, apply it.
+	if len(pointers) == 1:
+		print '\tif (%s == NULL) {' % (params[pointers[0]][0])
+		print '\t\tinstance->%s = NULL;' % (params[pointers[0]][0])
+		print '\t}'
+		print '\telse {'
+		print '\t\tinstance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
+		print '\t}'
+		if pointersize == 'special':
+			print '\t(void) crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
+		else:
+			print '\tcrMemcpy((void *)instance->%s, (void *) %s, %s*sizeof(%s));' % (params[pointers[0]][0], params[pointers[0]][0], pointersize, pointertype)
+	elif len(pointers) == 2:
+		# this seems to work
+		print '\t(void) crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
+	elif len(pointers) > 2:
+		print "#error don't know how to handle pointer parameters for %s" % (functionName)
+
+	# Add the element to the current display list
+	AddInstanceToList('\t')
+	# If the element is a state-changing element, add it to the current state list
+	if apiutil.SetsTrackedState(functionName):
+	    AddInstanceToStateList('\t')
+
+	# XXX might need a better test here
+	if functionName[0:6] == "Vertex":
+		generate_bbox_code(functionName)
+
+	print '}'
+
+whichfile=sys.argv[1]
+if whichfile == 'headers':
+    print """#ifndef _DLM_GENERATED_H
+#define _DLM_GENERATED_H
+
+/* DO NOT EDIT.  This file is auto-generated by dlm_generated.py. */
+"""
+else:
+    print """#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_error.h"
+#include "state/cr_statefuncs.h"
+#include "dlm.h"
+#include "dlm_pointers.h"
+#include "dlm_generated.h"
+
+/* DO NOT EDIT.  This file is auto-generated by dlm_generated.py. */
+"""
+
+# Add in the "add_to_dl" utility function, which will be used by
+# external (i.e. non-generated) functions.  The utility ensures that 
+# any external functions that are written for compiling elements
+# don't have to be rewritten if the conventions for adding to display
+# lists are changed.
+print """
+void crdlm_add_to_list(
+    DLMInstanceList *instance,
+    void (*executeFunc)(DLMInstanceList *x, SPUDispatchTable *dispatchTable)"""
+
+if (whichfile == 'headers'):
+    print ");"
+else:
+    print """) {
+    CRDLMContextState *state = CURRENT_STATE();
+    instance->execute = executeFunc;"""
+
+    # Add in the common code for adding the instance to the display list
+    AddInstanceToList("    ")
+
+    print '}'
+    print ''
+
+# Now generate the functions that won't use the crdlm_add_to_list utility.
+# These all directly add their own instances to the current display list
+# themselves, without using the crdlm_add_to_list() function.
+keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
+for func_name in keys:
+	if apiutil.CanCompile(func_name):
+		print "\n/*** %s ***/" % func_name
+		# Auto-generate an appropriate DL function.  First, functions
+		# that go into the display list but that rely on state will
+		# have to have their argument strings expanded, to take pointers 
+		# to that appropriate state.
+		if whichfile == "headers":
+		    wrap_struct(func_name)
+		elif not apiutil.FindSpecial("dlm", func_name):
+		    wrap_execute(func_name)
+		    wrap_compile(func_name)
+		# All others just pass through
+
+if whichfile == 'headers':
+    print "#endif /* _DLM_GENERATED_H */"
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 54905)
@@ -0,0 +1,263 @@
+# $Id$
+import sys, cPickle, re, os
+
+sys.path.append( "../glapi_parser" )
+import apiutil
+
+# mode is "header" or "defs"
+mode = sys.argv[1]
+
+# Any new function implemented in the DLM has to have an entry added here.
+# Each function has its return type, function name, and parameters provided.
+# We'll use these to generate both a header file, and a definition file.
+additionalFunctions = [
+	('CRDLM DLM_APIENTRY *', 'crDLMNewDLM', 'unsigned int configSize, const CRDLMConfig *config'),
+	('CRDLMContextState DLM_APIENTRY *', 'crDLMNewContext', 'CRDLM *dlm'),
+	('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state'),
+	('void DLM_APIENTRY', 'crDLMUseDLM', 'CRDLM *dlm'),
+	('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm'),
+	('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'),
+	('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'),
+	('CRDLMReplayState DLM_APIENTRY', 'crDLMGetReplayState', 'void'),
+	('void DLM_APIENTRY', 'crDLMSetupClientState', 'SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMRestoreClientState', 'CRClientState *clientState, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMSendAllDLMLists', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMSendAllLists', 'SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMSendDLMList', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMSendList', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayDLMList', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayList', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayDLMListState', 'CRDLM *dlm, unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayListState', 'unsigned long listIdentifier, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayDLMLists', 'CRDLM *dlm, GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayLists', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayDLMListsState', 'CRDLM *dlm, GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMReplayListsState', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+	('CRDLMError DLM_APIENTRY', 'crDLMDeleteListContent', 'CRDLM *dlm, unsigned long listIdentifier'),
+	('int DLM_APIENTRY', 'crDLMGetReferences', 'CRDLM *dlm, unsigned long listIdentifier, int firstIndex, int sizeofBuffer, unsigned int *buffer'),
+	('CRDLMError DLM_APIENTRY', 'crDLMGetDLMBounds', 'CRDLM *dlm, unsigned long listIdentifier, CRDLMBounds *bounds'),
+	('CRDLMError DLM_APIENTRY', 'crDLMGetBounds', 'unsigned long listIdentifier, CRDLMBounds *bounds'),
+	('void DLM_APIENTRY', 'crDLMSetDLMBounds', 'CRDLM *dlm, unsigned long listIdentifier, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax'),
+	('void DLM_APIENTRY', 'crDLMSetBounds', 'unsigned long listIdentifier, double xmin, double ymin, double zmin, double xmax, double ymax, double zmax'),
+	('void DLM_APIENTRY', 'crDLMComputeBoundingBox', 'unsigned long listId'),
+	('GLboolean DLM_APIENTRY', 'crDLMListHasDLMBounds', 'CRDLM *dlm, unsigned long listIdentifier'),
+	('GLboolean DLM_APIENTRY', 'crDLMListHasBounds', 'unsigned long listIdentifier'),
+	('GLuint DLM_APIENTRY', 'crDLMGetCurrentList', 'void'),
+	('GLenum DLM_APIENTRY', 'crDLMGetCurrentMode', 'void'),
+	('void DLM_APIENTRY', 'crDLMErrorFunction', 'CRDLMErrorCallback callback'),
+	('void DLM_APIENTRY', 'crDLMNewList', 'GLuint listIdentifier, GLenum mode'),
+	('void DLM_APIENTRY', 'crDLMEndList', 'void'),
+	('void DLM_APIENTRY', 'crDLMDeleteLists', 'GLuint firstListIdentifier, GLsizei range'),
+	('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list'),
+	('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range'),
+	('void DLM_APIENTRY', 'crDLMListBase', 'GLuint base'),
+	#('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
+	#('GLboolean DLM_APIENTRY', 'crDLMIsListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
+	#('GLint DLM_APIENTRY', 'crDLMListSize', 'CRDLM *dlm, unsigned long listIdentifier'),
+]
+
+if mode == 'header':
+	print """#ifndef CR_DLM_H
+
+/* DO NOT EDIT.  This file is auto-generated by %s. */
+#define CR_DLM_H
+
+#if defined(WINDOWS)
+#define DLM_APIENTRY
+#else
+#define DLM_APIENTRY
+#endif
+
+#include "chromium.h"
+#include "state/cr_client.h"
+#include "cr_spu.h"
+#include "cr_hash.h"
+#include "cr_threads.h"
+#include "cr_pack.h"
+#ifdef CHROMIUM_THREADSAFE
+#include "cr_threads.h"
+#endif
+
+/* 3D bounding box */
+typedef struct {
+	double xmin, xmax, ymin, ymax, zmin, zmax;
+} CRDLMBounds;
+
+/* Indicates whether we're currently involved in playback or not */
+typedef enum {
+	CRDLM_IMMEDIATE = 0,
+	CRDLM_REPLAY_STATE_FUNCTIONS = 1,
+	CRDLM_REPLAY_ALL_FUNCTIONS = 2
+} CRDLMReplayState;
+
+/* This is enough information to hold an instance of a single function call. */
+typedef struct DLMInstanceList {
+	struct DLMInstanceList *next;
+	struct DLMInstanceList *stateNext;
+	void (*execute)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);
+} DLMInstanceList;
+
+typedef struct {
+	DLMInstanceList *first, *last;
+	int numInstances;
+	DLMInstanceList *stateFirst, *stateLast;
+	CRHashTable *references; /* display lists that this display list calls */
+	CRDLMBounds bbox;
+	GLboolean listSent;
+} DLMListInfo;
+
+typedef struct {
+	/* This holds all the display list information, hashed by list identifier. */
+	CRHashTable *displayLists;
+
+	/* This is a count of the number of contexts/users that are using
+	 * this DLM.
+	 */
+	unsigned int userCount;
+
+#ifdef CHROMIUM_THREADSAFE
+	/* This mutex protects the displayLists hash table from simultaneous
+	 * updates by multiple contexts.
+	 */
+	CRmutex dlMutex;
+	CRtsd tsdKey;
+#endif
+
+	/* Configuration information - see the CRDLMConfig structure below
+	 * for details.
+	 */
+	unsigned int bufferSize;
+} CRDLM;
+
+/* This structure holds thread-specific state.  Each thread can be
+ * associated with one (and only one) context; and each context can
+ * be associated with one (and only one) DLM.  Making things interesting,
+ * though, is that each DLM can be associated with multiple contexts.
+ *
+ * So the thread-specific data key is associated with each context, not
+ * with each DLM.  Two different threads can, through two different
+ * contexts that share a single DLM, each have independent state and
+ * conditions.
+ */
+
+typedef struct {
+	CRDLM *dlm;			/* the DLM associated with this state */
+	unsigned long currentListIdentifier;	/* open display list */
+	DLMListInfo *currentListInfo;	/* open display list data */
+	GLenum currentListMode;		/* GL_COMPILE or GL_COMPILE_AND_EXECUTE */
+	GLuint listBase;
+	CRDLMReplayState replayState;	/* CRDLM_IMMEDIATE, CRDLM_REPLAY_STATE_FUNCTIONS, or CRDLM_REPLAY_ALL_FUNCTIONS */
+
+} CRDLMContextState;
+
+/* These additional structures are for passing information to and from the 
+ * CRDLM interface routines.
+ */
+typedef struct {
+	/* The size, in bytes, that the packer will initially allocate for
+	 * each new buffer.
+	 */
+#define CRDLM_DEFAULT_BUFFERSIZE (1024*1024)
+	unsigned int bufferSize;	/* this will be allocated for each buffer */
+} CRDLMConfig;
+
+/* Positive values match GL error values.
+ * 0 (GL_NO_ERROR) is returned for success
+ * Negative values are internal errors.
+ * Possible positive values (from GL/gl.h) are:
+ * GL_NO_ERROR (0x0)
+ * GL_INVALID_ENUM (0x0500)
+ * GL_INVALID_VALUE (0x0501)
+ * GL_INVALID_OPERATION (0x0502)
+ * GL_STACK_OVERFLOW (0x0503)
+ * GL_STACK_UNDERFLOW (0x0504)
+ * GL_OUT_OF_MEMORY (0x0505)
+ */
+typedef int CRDLMError;
+
+/* This error reported if there's no current state. The caller is responsible
+ * for appropriately allocating context state with crDLMNewContext(), and
+ * for making it current with crDLMMakeCurrent().
+ */
+#define CRDLM_ERROR_STATE	(-1)
+
+
+typedef void (*CRDLMErrorCallback)(int line, const char *file, GLenum error, const char *info);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+""" % os.path.basename(sys.argv[0])
+elif mode == 'defs':
+	apiutil.CopyrightDef()
+	print '''\t; DO NOT EDIT.  This code is generated by %s.
+
+EXPORTS''' % os.path.basename(sys.argv[0])
+else:
+	raise "unknown generation mode '%s'" % mode
+
+# Generate the list of functions, starting with those coded into
+# the module
+for (returnValue, name, parameters) in additionalFunctions:
+	if mode == 'header':
+		print "extern %s %s(%s);" % (returnValue, name, parameters)
+	elif mode == 'defs':
+		print "%s" % name
+
+# Continue with functions that are auto-generated.
+
+if mode == 'header':
+	print 
+	print "/* auto-generated compilation functions begin here */"
+
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[2]+"/APIspec.txt")
+for func_name in keys:
+	props = apiutil.Properties(func_name)
+	# We're interested in intercepting all calls that:
+	#   - can be put into a display list (i.e. "not ("nolist" in props)")
+	#   - change client-side state that affects saving DL elements (i.e. "setclient" in props)
+
+	if apiutil.CanCompile(func_name):
+		params = apiutil.Parameters(func_name)
+		argstring = apiutil.MakeDeclarationString(params)
+		if "useclient" in props or "pixelstore" in props:
+			argstring = argstring + ", CRClientState *c"
+
+		if mode == 'header':
+			print 'extern void DLM_APIENTRY crDLMCompile%s( %s );' % (func_name, argstring)
+		elif mode == 'defs':
+			print "crDLMCompile%s" % func_name
+
+# Next make declarations for all the checklist functions.
+if mode == 'header':
+	print """
+/* auto-generated CheckList functions begin here.  There is one for each
+ * function that has a dual nature: even when there's an active glNewList,
+ * sometimes they are compiled into the display list, and sometimes they
+ * are treated like a control function.  The CheckList function will
+ * return TRUE if the function should really be compiled into a display
+ * list.  The calling SPU is responsible for checking this; but the
+ * DLM will also print an error if it detects an invalid use.
+ */
+"""
+elif mode == 'defs':
+	pass
+
+for func_name in keys:
+	if "checklist" in apiutil.ChromiumProps(func_name):
+		params = apiutil.Parameters(func_name)
+		argstring = apiutil.MakeDeclarationString(params)
+		if mode == 'header':
+			print 'int DLM_APIENTRY crDLMCheckList%s( %s );' % (func_name, argstring)
+		elif mode == 'defs':
+			print "crDLMCheckList%s" % func_name
+
+if mode == 'header':
+	print """
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CR_DLM_H */"""
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 54905)
@@ -0,0 +1,275 @@
+/* $Id$ */
+#include <float.h>
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "dlm.h"
+
+
+
+/* This file defines the display list functions such as NewList, EndList,
+ * IsList, DeleteLists, etc.
+ * Generally, SPUs will call these as needed to implement display lists.
+ * See the expando, replicate, and tilesort SPUs for examples.
+ *
+ * The functions which compile GL functions into our display lists are named:
+ *     void DLM_APIENTRY crdlm_<function name>
+ * where <function_name> is the Chromium function name (which in 
+ * turn is the GL function name with the "gl" prefix removed).
+ *
+ * All these entry points require that a CRDLMContextState structure
+ * be created (with crDLMNewContext()) and assigned to the current
+ * thread (with crDLMSetCurrentState()).
+ */
+
+
+/*
+ * Begin compiling a list.
+ */
+void DLM_APIENTRY
+crDLMNewList(GLuint listIdentifier, GLenum mode)
+{
+    DLMListInfo *listInfo;
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    /* Error checks: 0 is not a valid identifier, and
+     * we can't call NewList if NewList has been called
+     * more recently than EndList.
+     *
+     * The caller is expected to check for an improper
+     * mode parameter (GL_INVALID_ENUM), or for a NewList
+     * within a glBegin/glEnd (GL_INVALID_OPERATION).
+     */
+    if (listState == NULL)
+    {
+	crWarning("DLM error: NewList(%d,%d) called with no current state (%s line %d)\n",
+	    (int) listIdentifier, (int) mode, __FILE__, __LINE__);
+	return;
+    }
+
+    if (listIdentifier == 0)
+    {
+	crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE,
+	     "NewList called with a list identifier of 0");
+	return;
+    }
+
+    if (listState->currentListInfo != NULL)
+    {
+	char msg[1000];
+	sprintf(msg, "NewList called with display list %d while display list %d was already open",
+	    (int) listIdentifier, (int) listState->currentListIdentifier);
+	crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, msg);
+	return;
+    }
+
+    listInfo = (DLMListInfo *) crCalloc(sizeof(DLMListInfo));
+    if (!(listInfo))
+    {
+	char msg[1000];
+	sprintf(msg, "could not allocate %u bytes of memory in NewList",
+	    (unsigned) sizeof(DLMListInfo));
+	crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY, msg);									 
+	return;
+    }
+
+    listInfo->first = listInfo->last = NULL;
+    listInfo->stateFirst = listInfo->stateLast = NULL;
+    listInfo->references = crAllocHashtable();
+    if (!(listInfo->references))
+    {
+	crFree(listInfo);
+	crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
+	    "could not allocate memory in NewList");
+	return;
+    }
+    listInfo->numInstances = 0;
+    listInfo->listSent = GL_FALSE;
+    listInfo->bbox.xmin = FLT_MAX;
+    listInfo->bbox.xmax = -FLT_MAX;
+    listInfo->bbox.ymin = FLT_MAX;
+    listInfo->bbox.ymax = -FLT_MAX;
+    listInfo->bbox.zmin = FLT_MAX;
+    listInfo->bbox.zmax = -FLT_MAX;
+
+    listState->currentListInfo = listInfo;
+    listState->currentListIdentifier = listIdentifier;
+    listState->currentListMode = mode;
+}
+
+
+/* This small utility routine is used to traverse a buffer
+ * list, freeing each buffer.  It is used to free the buffer
+ * list in the DLMListInfo structure, both when freeing the
+ * entire structure and when freeing just the retained content.
+ */
+static void free_instance_list(DLMInstanceList * instance)
+{
+	while (instance)
+	{
+		DLMInstanceList *nextInstance = instance->next;
+		crFree(instance);
+		instance = nextInstance;
+	}
+}
+
+/* This utility routine frees a DLMListInfo structure and all
+ * of its components.  It is used directly, when deleting a
+ * single list; it is also used as a callback function for
+ * hash tree operations (Free and Replace).
+ *
+ * The parameter is listed as a (void *) instead of a (DLMListInfo *)
+ * in order that the function can be used as a callback routine for
+ * the hash table functions.  The (void *) designation causes no
+ * other harm, save disabling type-checking on the pointer argument
+ * of the function.
+ */
+void crdlm_free_list(void *parm)
+{
+	DLMListInfo *listInfo = (DLMListInfo *) parm;
+
+	free_instance_list(listInfo->first);
+	listInfo->first = listInfo->last = NULL;
+
+	/* The references list has no allocated information; it's
+	 * just a set of entries.  So we don't need to free any
+	 * information as each entry is deleted.
+	 */
+	crFreeHashtable(listInfo->references, NULL);
+
+	crFree(listInfo);
+}
+
+
+void DLM_APIENTRY crDLMEndList(void)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    /* Error check: cannot call EndList without a (successful)
+     * preceding NewList.
+     *
+     * The caller is expected to check for glNewList within
+     * a glBegin/glEnd sequence.
+     */
+    if (listState == NULL)
+    {
+	crWarning("DLM error: EndList called with no current state (%s line %d)\n",
+	    __FILE__, __LINE__);
+	return;
+    }
+    if (listState->currentListInfo == NULL)
+    {
+	crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,
+	    "EndList called while no display list was open");
+	return;
+    }
+
+    DLM_LOCK(listState->dlm)
+
+    /* This function will either replace the list information that's
+     * already present with our new list information, freeing the
+     * former list information; or will add the new information
+     * to the set of display lists, depending on whether the
+     * list already exists or not.
+     */
+    crHashtableReplace(listState->dlm->displayLists,
+	listState->currentListIdentifier,
+	listState->currentListInfo, crdlm_free_list);
+
+    DLM_UNLOCK(listState->dlm)
+
+    /* reset the current state to show the list had been ended */
+    listState->currentListIdentifier = 0;
+    listState->currentListInfo = NULL;
+    listState->currentListMode = GL_FALSE;
+}
+
+
+void DLM_APIENTRY crDLMDeleteLists(GLuint firstListIdentifier, GLsizei range)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+	register int i;
+
+	if (listState == NULL)
+	{
+		crWarning
+			("DLM error: DeleteLists(%d,%d) called with no current state (%s line %d)\n",
+			 (int) firstListIdentifier, (int) range, __FILE__, __LINE__);
+		return;
+	}
+	if (range < 0)
+	{
+		char msg[1000];
+		sprintf(msg, "DeleteLists called with range (%d) less than zero", (int) range);
+		crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE, msg);								 
+		return;
+	}
+
+	/* Interestingly, there doesn't seem to be an error for deleting
+	 * display list 0, which cannot exist.
+	 *
+	 * We could delete the desired lists by walking the entire hash of
+	 * display lists and looking for and deleting any in our range; or we
+	 * could delete lists one by one.  The former is faster if the hashing
+	 * algorithm is inefficient or if we're deleting all or most of our
+	 * lists; the latter is faster if we're deleting a relatively small
+	 * number of lists.
+	 *
+	 * For now, we'll go with the latter; it's also easier to implement
+	 * given the current functions available.
+	 */
+	DLM_LOCK(listState->dlm)
+	for (i = 0; i < range; i++)
+	{
+		crHashtableDelete(listState->dlm->displayLists, 
+				  firstListIdentifier + i, crdlm_free_list);
+	}
+	DLM_UNLOCK(listState->dlm)
+}
+
+GLboolean DLM_APIENTRY crDLMIsList(GLuint list)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+
+	if (listState == NULL)
+	{
+		crWarning
+			("DLM error: IsLists(%d) called with no current state (%s line %d)\n",
+			 (int) list, __FILE__, __LINE__);
+		return 0;
+	}
+
+	if (list == 0)
+		return GL_FALSE;
+
+	return crHashtableIsKeyUsed(listState->dlm->displayLists, list);
+}
+
+GLuint DLM_APIENTRY crDLMGenLists(GLsizei range)
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+
+	if (listState == NULL)
+	{
+		crWarning
+			("DLM error: GenLists(%d) called with no current state (%s line %d)\n",
+			 (int) range, __FILE__, __LINE__);
+		return 0;
+	}
+
+	return crHashtableAllocKeys(listState->dlm->displayLists, range);
+}
+
+void DLM_APIENTRY crDLMListBase( GLuint base )
+{
+	CRDLMContextState *listState = CURRENT_STATE();
+
+	if (listState == NULL)
+	{
+		crWarning
+			("DLM error: ListBase(%d) called with no current state (%s line %d)\n",
+			 (int) base, __FILE__, __LINE__);
+		return;
+	}
+
+	listState->listBase = base;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.c	(revision 54905)
@@ -0,0 +1,1125 @@
+/* $Id$ */
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "cr_pixeldata.h"
+#include "cr_string.h"
+#include "dlm.h"
+#include "dlm_pointers.h"
+
+/**
+ * These helper functions are used for GL functions that take a pointers,
+ * if the size of the arrays that the pointers refer to is not constant.
+ * These helper functions will determine, on a case-by-case basis,
+ * how much space is needed to store the array.  If the buffer 
+ * parameter is not NULL, they will also pack the data into the given
+ * array.
+ *
+ * Many of the functions included deal with pixel state (Bitmap, DrawPixels,
+ * etc.).  In all these cases, when the function instance is stored in a
+ * display list, its data is read from memory (as per the parameters
+ * to PixelStore) and is stored in a tightly packed format (with no
+ * excess row length, no pixels skipped, no rows, skipped, and a byte
+ * alignment).
+ *
+ * When the instances are executed again, care must be taken to ensure
+ * that the PixelStore client state that unpacks them is set to reflect
+ * the tight packing actually used, instead of whatever the current
+ * client state indicates.
+ *
+ * So to do this, client PixelStore state is forced to known values
+ * before any instances in the display list are executed.  The client
+ * state is then restored to known values afterwards.  (The difficulty
+ * of this is somewhat mollified by the observation that PixelStore
+ * instances affect client state, and cannot be stored in a display list.)
+ *
+ */
+
+int crdlm_pointers_Bitmap( struct instanceBitmap *instance, GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap, CRClientState *c)
+{
+    unsigned int size = ((int)((width + 7) / 8)) * height;
+    /* glBitmap can be called with a NULL size 0 bitmap, say for
+     * an empty glyph that only moves the current raster position.
+     * crMemcpy will raise an exception with a NULL source pointer, even if
+     * the size to copy is 0.  So make sure we don't ram into this.
+     * Also, the bitmap isn't necessarily just sitting in memory; the PixelStore
+     * client-side state affects how it is read from memory.  It's easiest to just
+     * use the utility.
+     */
+    if (instance && size > 0) {
+	crBitmapCopy(width, height, instance->bitmap, bitmap,
+		&c->unpack);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_DrawPixels( struct instanceDrawPixels *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size = crImageSize(format, type, width, height);
+
+    if (instance && size > 0) {
+	crPixelCopy2D(width, height, 
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+    }
+
+    return size;
+}
+int crdlm_pointers_Fogfv( struct instanceFogfv *instance, GLenum pname, const GLfloat *params )
+{
+    unsigned int size = (pname == GL_FOG_COLOR?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_Fogiv( struct instanceFogiv *instance, GLenum pname, const GLint *params )
+{
+    unsigned int size = (pname == GL_FOG_COLOR?4:1)*sizeof(GLint);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_LightModelfv( struct instanceLightModelfv *instance, GLenum pname, const GLfloat *params )
+{
+    unsigned int size = (pname == GL_LIGHT_MODEL_AMBIENT?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_LightModeliv( struct instanceLightModeliv *instance, GLenum pname, const GLint *params )
+{
+    unsigned int size = (pname == GL_LIGHT_MODEL_AMBIENT?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_Lightfv( struct instanceLightfv *instance, GLenum light, GLenum pname, const GLfloat *params )
+{
+    unsigned int size;
+    switch(pname) {
+	case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION:
+	    size = 4 * sizeof(GLfloat);
+	    break;
+	case GL_SPOT_DIRECTION:
+	    size = 3 * sizeof(GLfloat);
+	    break;
+	default:
+	    size = 1 * sizeof(GLfloat);
+	    break;
+    }
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_Lightiv( struct instanceLightiv *instance, GLenum light, GLenum pname, const GLint *params )
+{
+    unsigned int size;
+    switch(pname) {
+	case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_POSITION:
+	    size = 4 * sizeof(GLint);
+	    break;
+	case GL_SPOT_DIRECTION:
+	    size = 3 * sizeof(GLint);
+	    break;
+	default:
+	    size = 1 * sizeof(GLint);
+	    break;
+    }
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+/* This utility routine returns the number of components per
+ * mapping point for all the glMap* functions.
+ */
+static int map_num_components(GLenum target)
+{
+    switch(target) {
+	case GL_MAP1_INDEX: case GL_MAP1_TEXTURE_COORD_1:
+	    return 1;
+	case GL_MAP1_TEXTURE_COORD_2:
+	    return 2;
+	case GL_MAP1_VERTEX_3: case GL_MAP1_NORMAL: 
+	case GL_MAP1_TEXTURE_COORD_3:
+	    return 3;
+	case GL_MAP1_VERTEX_4: case GL_MAP1_COLOR_4:
+	case GL_MAP1_TEXTURE_COORD_4:
+	    return 4;
+
+	case GL_MAP2_INDEX: case GL_MAP2_TEXTURE_COORD_1:
+	    return 1;
+	case GL_MAP2_TEXTURE_COORD_2:
+	    return 2;
+	case GL_MAP2_VERTEX_3: case GL_MAP2_NORMAL:
+	case GL_MAP2_TEXTURE_COORD_3:
+	    return 3;
+	case GL_MAP2_VERTEX_4: case GL_MAP2_COLOR_4:
+	case GL_MAP2_TEXTURE_COORD_4:
+	    return 4;
+    }
+    return 0;
+} 
+
+
+int crdlm_pointers_Map1d( struct instanceMap1d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points )
+{
+    unsigned int numValues = map_num_components(target);
+    unsigned int size = order * numValues * sizeof(GLdouble);
+    if (instance) {
+	/* This one's a little different - we rearrange the order to
+	 * compress it, and change the instance's stride value to
+	 * match.
+	 */
+	const GLdouble *src = points;
+	GLdouble *dest = instance->points;
+	register int i;
+	for (i = 0; i < order; i++) {
+	    crMemcpy(dest, src, numValues * sizeof(GLdouble));
+	    dest += numValues;
+	    src += stride;
+	}
+
+	/* We override the stride to show we've compressed the data */
+	instance->stride = numValues;
+    }
+    return size;
+}
+int crdlm_pointers_Map1f( struct instanceMap1f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points )
+{
+    unsigned int numValues = map_num_components(target);
+    unsigned int size = order * numValues * sizeof(GLfloat);
+    if (instance) {
+	/* This one's a little different - we rearrange the order to
+	 * compress it, and change the instance's stride value to
+	 * match.
+	 */
+	const GLfloat *src = points;
+	GLfloat *dest = instance->points;
+	register int i;
+	for (i = 0; i < order; i++) {
+	    crMemcpy(dest, src, numValues * sizeof(GLfloat));
+	    dest += numValues;
+	    src += stride;
+	}
+
+	/* We override the stride to show we've compressed the data */
+	instance->stride = numValues;
+    }
+    return size;
+}
+int crdlm_pointers_Map2d( struct instanceMap2d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points )
+{
+    unsigned int numValues = map_num_components(target);
+    unsigned int size = uorder * vorder * numValues * sizeof(GLdouble);
+    if (instance) {
+	register int v, u;
+	const GLdouble *src = points;
+	GLdouble *dest = instance->points;
+	for (v = 0; v < vorder; v++) {
+	    for (u = 0; u < uorder; u++) {
+		crMemcpy(dest, src, numValues * sizeof(GLdouble));
+		dest += numValues;
+		src += ustride;
+	    }
+	    src += vstride - ustride*uorder;
+	}
+	/* We override the stride to show we've compressed the data */
+	instance->ustride = numValues;
+	instance->vstride = ustride * uorder;
+    }
+    return size;
+}
+int crdlm_pointers_Map2f( struct instanceMap2f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points )
+{
+    unsigned int numValues = map_num_components(target);
+    unsigned int size = uorder * vorder * numValues * sizeof(GLfloat);
+    if (instance) {
+	register int v, u;
+	const GLfloat *src = points;
+	GLfloat *dest = instance->points;
+	for (v = 0; v < vorder; v++) {
+	    for (u = 0; u < uorder; u++) {
+		crMemcpy(dest, src, numValues * sizeof(GLfloat));
+		dest += numValues;
+		src += ustride;
+	    }
+	    src += vstride - ustride*uorder;
+	}
+	/* We override the stride to show we've compressed the data */
+	instance->ustride = numValues;
+	instance->vstride = ustride * uorder;
+    }
+    return size;
+}
+
+int crdlm_pointers_Materialfv(struct instanceMaterialfv *instance, GLenum face, GLenum pname, const GLfloat *params)
+{
+    unsigned int size = 0;
+    switch(pname) {
+	case GL_AMBIENT_AND_DIFFUSE:
+	    size = 8 * sizeof(GLfloat);
+	    break;
+	case GL_AMBIENT:
+	case GL_DIFFUSE:
+	case GL_SPECULAR:
+	case GL_EMISSION:
+	    size = 4 * sizeof(GLfloat);
+	    break;
+	case GL_SHININESS:
+	    size = 1 * sizeof(GLfloat);
+	    break;
+	case GL_COLOR_INDEXES:
+	    size = 3 * sizeof(GLfloat);
+	    break;
+	default:
+	    break;
+    }
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+int crdlm_pointers_Materialiv(struct instanceMaterialiv *instance, GLenum face, GLenum pname, const GLint *params)
+{
+    unsigned int size = 0;
+    switch(pname) {
+	case GL_AMBIENT_AND_DIFFUSE:
+	    size = 8 * sizeof(GLint);
+	    break;
+	case GL_AMBIENT:
+	case GL_DIFFUSE:
+	case GL_SPECULAR:
+	case GL_EMISSION:
+	    size = 4 * sizeof(GLint);
+	    break;
+	case GL_SHININESS:
+	    size = 1 * sizeof(GLint);
+	    break;
+	case GL_COLOR_INDEXES:
+	    size = 3 * sizeof(GLint);
+	    break;
+	default:
+	    break;
+    }
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+int crdlm_pointers_PixelMapfv( struct instancePixelMapfv *instance, GLenum map, GLsizei mapsize, const GLfloat *values )
+{
+    unsigned int size = mapsize * sizeof(GLfloat);
+    if (instance && size > 0) crMemcpy(instance->values, values, size);
+    return size;
+}
+int crdlm_pointers_PixelMapuiv( struct instancePixelMapuiv *instance, GLenum map, GLsizei mapsize, const GLuint *values )
+{
+    unsigned int size = mapsize * sizeof(GLuint);
+    if (instance && size > 0) crMemcpy(instance->values, values, size);
+    return size;
+}
+int crdlm_pointers_PixelMapusv( struct instancePixelMapusv *instance, GLenum map, GLsizei mapsize, const GLushort *values )
+{
+    unsigned int size = mapsize * sizeof(GLushort);
+    if (instance && size > 0) crMemcpy(instance->values, values, size);
+    return size;
+}
+
+int crdlm_pointers_PointParameterfvARB( struct instancePointParameterfvARB *instance, GLenum pname, const GLfloat *params)
+{
+    unsigned int size = 0;
+    switch(pname) {
+	case GL_POINT_DISTANCE_ATTENUATION_ARB:
+	    size = 3 * sizeof(GLfloat);
+	    break;
+	default:
+	    size = 1 * sizeof(GLfloat);
+	    break;
+    }
+    return size;
+}
+
+int crdlm_pointers_PointParameteriv( struct instancePointParameteriv *instance, GLenum pname, const GLint *params)
+{
+    unsigned int size = 0;
+    switch(pname) {
+	case GL_POINT_DISTANCE_ATTENUATION_ARB:
+	    size = 3 * sizeof(GLint);
+	    break;
+	default:
+	    size = 1 * sizeof(GLint);
+	    break;
+    }
+    return size;
+}
+
+int crdlm_pointers_TexEnvfv( struct instanceTexEnvfv *instance, GLenum target, GLenum pname, const GLfloat *params )
+{
+    unsigned int size = (pname == GL_TEXTURE_ENV_COLOR?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexEnviv( struct instanceTexEnviv *instance, GLenum target, GLenum pname, const GLint *params )
+{
+    unsigned int size = (pname == GL_TEXTURE_ENV_COLOR?4:1)*sizeof(GLint);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexGendv( struct instanceTexGendv *instance, GLenum coord, GLenum pname, const GLdouble *params )
+{
+    unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLdouble);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexGenfv( struct instanceTexGenfv *instance, GLenum coord, GLenum pname, const GLfloat *params )
+{
+    unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexGeniv( struct instanceTexGeniv *instance, GLenum coord, GLenum pname, const GLint *params )
+{
+    unsigned int size = (pname == GL_OBJECT_PLANE||pname==GL_EYE_PLANE?4:1)*sizeof(GLint);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexImage1D( struct instanceTexImage1D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size = crImageSize(format, type, width, 1);
+
+    if (instance && size > 0) {
+	crPixelCopy1D(instance->pixels, format, type,
+		pixels, format, type, width, &c->unpack);
+    }
+
+    return size;
+}
+int crdlm_pointers_CompressedTexImage1DARB(struct instanceCompressedTexImage1DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_TexImage2D( struct instanceTexImage2D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size = crImageSize(format, type, width, height);
+
+    if (instance && size > 0) {
+	crPixelCopy2D(width, height, 
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+    }
+
+    return size;
+}
+int crdlm_pointers_CompressedTexImage2DARB(struct instanceCompressedTexImage2DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_TexImage3D( struct instanceTexImage3D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size;
+    int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+    if (pixels == NULL) {
+	size = 0;
+    }
+    else if (is_distrib) {
+	size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+    }
+    else {
+	size = crTextureSize(format, type, width, height, depth);
+    }
+
+    if (instance && size > 0) {
+	if (is_distrib) {
+	    crMemcpy(instance->pixels, pixels, size);
+	}
+	else {
+	    crPixelCopy3D(width, height, depth,
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+	}
+    }
+
+    return size;
+}
+int crdlm_pointers_TexImage3DEXT( struct instanceTexImage3DEXT *instance, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size;
+    int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+    if (pixels == NULL) {
+	size = 0;
+    }
+    else if (is_distrib) {
+	size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+    }
+    else {
+	size = crTextureSize(format, type, width, height, depth);
+    }
+
+    if (instance && size > 0) {
+	if (is_distrib) {
+	    crMemcpy(instance->pixels, pixels, size);
+	}
+	else {
+	    crPixelCopy3D(width, height, depth,
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+	}
+    }
+
+    return size;
+}
+
+int crdlm_pointers_CompressedTexImage3DARB(struct instanceCompressedTexImage3DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_TexParameterfv( struct instanceTexParameterfv *instance, GLenum target, GLenum pname, const GLfloat *params )
+{
+    unsigned int size = (pname == GL_TEXTURE_BORDER_COLOR?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexParameteriv( struct instanceTexParameteriv *instance, GLenum target, GLenum pname, const GLint *params )
+{
+    unsigned int size = (pname == GL_TEXTURE_BORDER_COLOR?4:1)*sizeof(GLfloat);
+    if (instance) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_TexSubImage1D( struct instanceTexSubImage1D *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size = crImageSize(format, type, width, 1);
+
+    if (instance && size > 0) {
+	crPixelCopy1D(instance->pixels, format, type,
+		pixels, format, type, width, &c->unpack);
+    }
+
+    return size;
+}
+int crdlm_pointers_TexSubImage2D( struct instanceTexSubImage2D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size = crImageSize(format, type, width, height);
+
+    if (instance && size > 0) {
+	crPixelCopy2D(width, height, 
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+    }
+
+    return size;
+}
+int crdlm_pointers_TexSubImage3D( struct instanceTexSubImage3D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c )
+{
+    unsigned int size;
+    int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
+
+    if (pixels == NULL) {
+	size = 0;
+    }
+    else if (is_distrib) {
+	size = crStrlen(pixels) + 1 + (type==GL_TRUE?width*height*3:0);
+    }
+    else {
+	size = crTextureSize(format, type, width, height, depth);
+    }
+
+    if (instance && size > 0) {
+	if (is_distrib) {
+	    crMemcpy(instance->pixels, pixels, size);
+	}
+	else {
+	    crPixelCopy3D(width, height, depth,
+		instance->pixels, format, type, NULL,
+		pixels, format, type, &c->unpack);
+	}
+    }
+
+    return size;
+}
+
+int crdlm_pointers_CompressedTexSubImage1DARB(struct instanceCompressedTexSubImage1DARB *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_CompressedTexSubImage2DARB(struct instanceCompressedTexSubImage2DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+int crdlm_pointers_CompressedTexSubImage3DARB(struct instanceCompressedTexSubImage3DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+    unsigned int size = imagesize;
+
+    if (instance && size > 0) {
+	crMemcpy(instance->data, data, size);
+    }
+
+    return size;
+}
+
+int crdlm_pointers_Rectdv(struct instanceRectdv *instance, const GLdouble *v1, const GLdouble *v2)
+{
+    unsigned int size = 4 * sizeof(GLdouble);
+    if (instance) {
+	instance->data[0] = v1[0];
+	instance->data[1] = v1[1];
+	instance->data[2] = v2[0];
+	instance->data[3] = v2[1];
+	instance->v1 = &instance->data[0];
+	instance->v2 = &instance->data[2];
+    }
+    return size;
+}
+int crdlm_pointers_Rectfv(struct instanceRectfv *instance, const GLfloat *v1, const GLfloat *v2)
+{
+    unsigned int size = 4 * sizeof(GLfloat);
+    if (instance) {
+	instance->data[0] = v1[0];
+	instance->data[1] = v1[1];
+	instance->data[2] = v2[0];
+	instance->data[3] = v2[1];
+	instance->v1 = &instance->data[0];
+	instance->v2 = &instance->data[2];
+    }
+    return size;
+}
+int crdlm_pointers_Rectiv(struct instanceRectiv *instance, const GLint *v1, const GLint *v2)
+{
+    unsigned int size = 4 * sizeof(GLint);
+    if (instance) {
+	instance->data[0] = v1[0];
+	instance->data[1] = v1[1];
+	instance->data[2] = v2[0];
+	instance->data[3] = v2[1];
+	instance->v1 = &instance->data[0];
+	instance->v2 = &instance->data[2];
+    }
+    return size;
+}
+int crdlm_pointers_Rectsv(struct instanceRectsv *instance, const GLshort *v1, const GLshort *v2)
+{
+    unsigned int size = 4 * sizeof(GLshort);
+    if (instance) {
+	instance->data[0] = v1[0];
+	instance->data[1] = v1[1];
+	instance->data[2] = v2[0];
+	instance->data[3] = v2[1];
+	instance->v1 = &instance->data[0];
+	instance->v2 = &instance->data[2];
+    }
+    return size;
+}
+
+int crdlm_pointers_PrioritizeTextures(struct instancePrioritizeTextures *instance, GLsizei n, const GLuint *textures, const GLclampf *priorities)
+{
+    unsigned int size = n * (sizeof(GLuint) + sizeof(GLclampf));
+    if (instance) {
+	instance->textures = (GLuint *)&instance->data[0];
+	instance->priorities = (GLclampf *)(((char *)&instance->data[0]) + n * sizeof(GLuint));
+	if (size > 0) {
+	    crMemcpy(instance->textures, textures, n * sizeof(GLuint));
+	    crMemcpy(instance->priorities, priorities, n * sizeof(GLclampf));
+	}
+    }
+
+    return size;
+}
+
+static int combiner_num_components(GLenum pname)
+{
+    switch(pname) {
+	case GL_CONSTANT_COLOR0_NV:
+	case GL_CONSTANT_COLOR1_NV:
+	    return 4;
+	case GL_NUM_GENERAL_COMBINERS_NV:
+	case GL_COLOR_SUM_CLAMP_NV:
+	    return 1;
+    }
+    return 0;
+} 
+int crdlm_pointers_CombinerParameterivNV(struct instanceCombinerParameterivNV *instance, GLenum pname, const GLint *params)
+{
+    unsigned int size = combiner_num_components(pname) * sizeof(GLint);
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+int crdlm_pointers_CombinerParameterfvNV(struct instanceCombinerParameterfvNV *instance, GLenum pname, const GLfloat *params)
+{
+    unsigned int size = combiner_num_components(pname) * sizeof(GLfloat);
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+static int combinerstage_num_components(GLenum pname)
+{
+    switch(pname) {
+	case GL_CONSTANT_COLOR0_NV:
+	case GL_CONSTANT_COLOR1_NV:
+	    return 4;
+    }
+    return 0;
+} 
+int crdlm_pointers_CombinerStageParameterfvNV(struct instanceCombinerStageParameterfvNV *instance, GLenum stage, GLenum pname, const GLfloat *params)
+{
+    unsigned int size = combinerstage_num_components(pname) * sizeof(GLfloat);
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+static int program_num_components(GLenum target)
+{
+    switch(target) {
+	case GL_VERTEX_STATE_PROGRAM_NV:
+	    return 4;
+    }
+    return 0;
+} 
+int crdlm_pointers_ExecuteProgramNV(struct instanceExecuteProgramNV *instance, GLenum target, GLuint id, const GLfloat *params)
+{
+    unsigned int size = program_num_components(target) * sizeof(GLfloat);
+    if (instance && size > 0) crMemcpy(instance->params, params, size);
+    return size;
+}
+
+int crdlm_pointers_RequestResidentProgramsNV(struct instanceRequestResidentProgramsNV *instance, GLsizei n, const GLuint *ids)
+{
+    unsigned int size = 4*sizeof(GLuint);
+    if (instance && size > 0) crMemcpy(instance->ids, ids, size);
+    return size;
+}
+
+int crdlm_pointers_LoadProgramNV(struct instanceLoadProgramNV *instance, GLenum target, GLuint id, GLsizei len, const GLubyte *program)
+{
+    unsigned int size = len*sizeof(GLubyte);
+    if (instance && size > 0) crMemcpy(instance->program, program, size);
+    return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4dNV(struct instanceProgramNamedParameter4dNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+	unsigned int size = len * sizeof(GLubyte);
+	/* XXX */
+	return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4dvNV(struct instanceProgramNamedParameter4dvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v)
+{
+	unsigned int size = len * sizeof(GLubyte);
+	/* XXX */
+	return size;
+}
+	
+int crdlm_pointers_ProgramNamedParameter4fNV(struct instanceProgramNamedParameter4fNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+	unsigned int size = len * sizeof(GLubyte);
+	/* XXX */
+	return size;
+}
+
+int crdlm_pointers_ProgramNamedParameter4fvNV(struct instanceProgramNamedParameter4fvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v)
+{
+	unsigned int size = len * sizeof(GLubyte);
+	/* XXX */
+	return size;
+}
+
+int crdlm_pointers_ProgramStringARB(struct instanceProgramStringARB *instance, GLenum target, GLenum format, GLsizei len, const GLvoid * string)
+{
+	unsigned int size = len*sizeof(GLubyte);
+	if (instance && size > 0) crMemcpy(instance->string, string, size);
+	return size;
+}
+
+int crdlm_pointers_CallLists(struct instanceCallLists *instance, GLsizei n, GLenum type, const GLvoid *lists )
+{
+	unsigned int size;
+	switch (type) {
+		case GL_BYTE:
+			size = sizeof(GLbyte);
+			break;
+		case GL_UNSIGNED_BYTE:
+			size = sizeof(GLubyte);
+			break;
+		case GL_SHORT:
+			size = sizeof(GLshort);
+			break;
+		case GL_UNSIGNED_SHORT:
+			size = sizeof(GLushort);
+			break;
+		case GL_INT:
+			size = sizeof(GLint);
+			break;
+		case GL_UNSIGNED_INT:
+			size = sizeof(GLuint);
+			break;
+		case GL_FLOAT:
+			size = sizeof(GLfloat);
+			break;
+		case GL_2_BYTES:
+			size = 2 * sizeof(GLbyte);
+			break;
+		case GL_3_BYTES:
+			size = 3 * sizeof(GLbyte);
+			break;
+		case GL_4_BYTES:
+			size = 4 * sizeof(GLbyte);
+			break;
+		default:
+			size = 0;
+	}
+	size *= n;
+	if (instance && size > 0) crMemcpy(instance->lists, lists, size);
+	return size;
+}
+
+
+int crdlm_pointers_VertexAttribs1dvNV(struct instanceVertexAttribs1dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+   return 1 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs1fvNV(struct instanceVertexAttribs1fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+   return 1 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs1svNV(struct instanceVertexAttribs1svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+   return 1 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs2dvNV(struct instanceVertexAttribs2dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+   return 2 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs2fvNV(struct instanceVertexAttribs2fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+   return 2 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs2svNV(struct instanceVertexAttribs2svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+   return 2 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs3dvNV(struct instanceVertexAttribs3dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+   return 3 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs3fvNV(struct instanceVertexAttribs3fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+   return 3 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs3svNV(struct instanceVertexAttribs3svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+   return 3 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs4dvNV(struct instanceVertexAttribs4dvNV *instance, GLuint index, GLsizei n, const GLdouble *v)
+{
+   return 4 * n * sizeof(GLdouble);
+}
+
+int crdlm_pointers_VertexAttribs4fvNV(struct instanceVertexAttribs4fvNV *instance, GLuint index, GLsizei n, const GLfloat *v)
+{
+   return 4 * n * sizeof(GLfloat);
+}
+
+int crdlm_pointers_VertexAttribs4svNV(struct instanceVertexAttribs4svNV *instance, GLuint index, GLsizei n, const GLshort *v)
+{
+   return 4 * n * sizeof(GLshort);
+}
+
+int crdlm_pointers_VertexAttribs4ubvNV(struct instanceVertexAttribs4ubvNV *instance, GLuint index, GLsizei n, const GLubyte *v)
+{
+   return 4 * n * sizeof(GLubyte);
+}
+
+int crdlm_pointers_ZPixCR( struct instanceZPixCR *instance, GLsizei width, 
+			 GLsizei height, GLenum format, GLenum type, 
+			 GLenum ztype, GLint zparm, GLint length, 
+			 const GLvoid *pixels, CRClientState *c)
+{
+     unsigned int size = length;
+     if (instance && size > 0) {
+	  crMemcpy(instance->pixels,pixels,length);
+     }
+     
+     return size;
+}
+
+
+/*
+ * Prototypes for functions below are auto-generated and definded at out/<os.arch>/<build type>/obj/VBoxOGLgen/dlm_generated.h.
+ *
+ * All non-pointer structure fields are already assifned to *instance in out/<os.arch>/<build type>/obj/VBoxOGLgen/dlm_generated.c.
+ * Here we need to specify the additional size which is required to store data from pointers.
+ * This size will be added to sizeof(*instance) when dlm_generated.c will dynamically allocate memory for it. Also,
+ * data from pointers shouls be copied to *instance in case if instance != NULL. Each of functions below is called
+ * twice from dlm_generated.c:
+ *  - first time with instance = NULL in order to get actual size of data provided by pointer
+ *  - the second time with valid instance in order to copy data into it.
+ */
+
+int crdlm_pointers_BindAttribLocation(struct instanceBindAttribLocation *instance, GLuint program, GLuint index, const char * name)
+{
+    int cbExtraSpace = (name ? crStrlen(name) + 1 : 0);
+    if (instance && name && cbExtraSpace)
+    {
+        crMemcpy(instance->name, name, cbExtraSpace);
+    }
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_DeleteFramebuffersEXT(struct instanceDeleteFramebuffersEXT *instance, GLsizei n, const GLuint * framebuffers)
+{
+    int cbExtraSpace = n * sizeof(GLuint);
+
+    if (instance && framebuffers && cbExtraSpace)
+        crMemcpy(instance->framebuffers, framebuffers, cbExtraSpace);
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_DeleteRenderbuffersEXT(struct instanceDeleteRenderbuffersEXT *instance, GLsizei n, const GLuint * renderbuffers)
+{
+    int cbExtraSpace = n * sizeof(GLuint);
+
+    if (instance && renderbuffers && cbExtraSpace)
+        crMemcpy(instance->renderbuffers, renderbuffers, cbExtraSpace);
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_DrawBuffers(struct instanceDrawBuffers *instance, GLsizei n, const GLenum* bufs)
+{
+    int cbExtraSpace = n * sizeof(GLenum);
+
+    if (instance && bufs && cbExtraSpace)
+        crMemcpy(instance->bufs, bufs, cbExtraSpace);
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_ShaderSource(struct instanceShaderSource *instance, GLuint shader, GLsizei count, const char ** string, const GLint * length)
+{
+    int cbExtraSpace = 0;
+    int cbStrings    = 0;
+    int cbLenghts    = 0;
+    int i;
+
+    /* Calculate reported source code size. */
+    if (length && count)
+        for (i = 0; i < count; i++)
+            cbStrings += length[i] + /* termination character */ 1;
+
+    /* Calculate size of the rest of parameters. */
+    cbLenghts = count * sizeof(GLint);
+
+    /* Resulting size is a summ. */
+    cbExtraSpace = cbStrings + cbLenghts;
+
+    /* Copy data if requested. */
+    if (instance)
+    {
+        if (string && *string && cbStrings)
+            crMemcpy(instance->string, *string, cbStrings);
+        if (length && cbLenghts)
+            crMemcpy(instance->length, length, cbLenghts);
+    }
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_StringMarkerGREMEDY(struct instanceStringMarkerGREMEDY *instance, GLsizei len, const GLvoid* string)
+{
+    /* @param len assumed to indicate string lenght in bytes. No termination character assumed. */
+    int cbExtraSpace = (string && len) ? len : 0;
+
+    if (instance && string && cbExtraSpace)
+        crMemcpy(instance->string, string, cbExtraSpace);
+
+    return cbExtraSpace;
+}
+
+/* Simplify things a bit. Use this macro instead of copy/paste to similar functions. */
+#define _VBOX_crdlm_pointers_UniformX(_uniformType) \
+    int cbExtraSpace = count * sizeof(_uniformType); \
+    if (instance && cbExtraSpace && value) \
+        crMemcpy(instance->value, value, cbExtraSpace); \
+    return cbExtraSpace;
+
+int crdlm_pointers_Uniform1fv(struct instanceUniform1fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform1iv(struct instanceUniform1iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform2fv(struct instanceUniform2fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform2iv(struct instanceUniform2iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform3fv(struct instanceUniform3fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform3iv(struct instanceUniform3iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+int crdlm_pointers_Uniform4fv(struct instanceUniform4fv *instance, GLint location, GLsizei count, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLfloat);
+}
+
+int crdlm_pointers_Uniform4iv(struct instanceUniform4iv *instance, GLint location, GLsizei count, const GLint * value)
+{
+    _VBOX_crdlm_pointers_UniformX(GLint);
+}
+
+#undef crdlm_pointers_Uniform4iv
+
+/* Now do the same for UniformMatrix. */
+#define _VBOX_crdlm_pointers_UniformMatrixX(_uniformMatrixType) \
+    int cbExtraSpace = count * sizeof(_uniformMatrixType); \
+    if (instance && value && cbExtraSpace) \
+        crMemcpy(instance->value, value, cbExtraSpace); \
+    return cbExtraSpace;
+
+int crdlm_pointers_UniformMatrix2fv(struct instanceUniformMatrix2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix2x3fv(struct instanceUniformMatrix2x3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix2x4fv(struct instanceUniformMatrix2x4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3fv(struct instanceUniformMatrix3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3x2fv(struct instanceUniformMatrix3x2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix3x4fv(struct instanceUniformMatrix3x4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4fv(struct instanceUniformMatrix4fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4x2fv(struct instanceUniformMatrix4x2fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+int crdlm_pointers_UniformMatrix4x3fv(struct instanceUniformMatrix4x3fv *instance, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value)
+{
+    _VBOX_crdlm_pointers_UniformMatrixX(GLfloat);
+}
+
+#undef _VBOX_crdlm_pointers_UniformMatrixX
+
+#if 0
+VBoxConCreate
+VBoxCreateContext
+VBoxPackSetInjectThread
+VBoxPresentComposition
+VBoxWindowCreate
+#endif
+
+int crdlm_pointers_VBoxConCreate(struct instanceVBoxConCreate *instance, struct VBOXUHGSMI * pHgsmi)
+{
+    CRASSERT(0);
+    return 0;
+}
+
+int crdlm_pointers_VBoxCreateContext(struct instanceVBoxCreateContext *instance, GLint con, const char * dpyName, GLint visual, GLint shareCtx)
+{
+    int cbExtraSpace = (dpyName ? crStrlen(dpyName) + 1 : 0);
+
+    if (instance && dpyName && cbExtraSpace)
+        crMemcpy(instance->dpyName, dpyName, cbExtraSpace);
+
+    return cbExtraSpace;
+}
+
+int crdlm_pointers_VBoxPackSetInjectThread(struct instanceVBoxPackSetInjectThread *instance, struct VBOXUHGSMI * pHgsmi)
+{
+    CRASSERT(0);
+    return 0;
+}
+
+int crdlm_pointers_VBoxPresentComposition(struct instanceVBoxPresentComposition *instance, GLint win,
+    const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY * pChangedEntry)
+{
+    CRASSERT(0);
+    return 0;
+}
+
+int crdlm_pointers_VBoxWindowCreate(struct instanceVBoxWindowCreate *instance, GLint con, const char * dpyName, GLint visBits)
+{
+    int cbExtraSpace = (dpyName ? crStrlen(dpyName) + 1 : 0);
+
+    if (instance && dpyName && cbExtraSpace)
+        crMemcpy(instance->dpyName, dpyName, cbExtraSpace);
+
+    return cbExtraSpace;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_pointers.h	(revision 54905)
@@ -0,0 +1,81 @@
+/* $Id$ */
+#include <VBox/VBoxUhgsmi.h>
+
+#include "cr_dlm.h"
+#include "dlm_generated.h"
+
+#ifndef _DLM_POINTERS_H
+#define _DLM_POINTERS_H
+
+extern int crdlm_pointers_Bitmap( struct instanceBitmap *instance, GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap, CRClientState *c);
+extern int crdlm_pointers_DrawPixels( struct instanceDrawPixels *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_Fogfv( struct instanceFogfv *instance, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_Fogiv( struct instanceFogiv *instance, GLenum pname, const GLint *params );
+extern int crdlm_pointers_LightModelfv( struct instanceLightModelfv *instance, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_LightModeliv( struct instanceLightModeliv *instance, GLenum pname, const GLint *params );
+extern int crdlm_pointers_Lightfv( struct instanceLightfv *instance, GLenum light, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_Lightiv( struct instanceLightiv *instance, GLenum light, GLenum pname, const GLint *params );
+extern int crdlm_pointers_Map1d( struct instanceMap1d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points );
+extern int crdlm_pointers_Map1f( struct instanceMap1f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points );
+extern int crdlm_pointers_Map2d( struct instanceMap2d *instance, GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points );
+extern int crdlm_pointers_Map2f( struct instanceMap2f *instance, GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points );
+extern int crdlm_pointers_Materialfv(struct instanceMaterialfv *instance, GLenum face, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_Materialiv(struct instanceMaterialiv *instance, GLenum face, GLenum pname, const GLint *params);
+extern int crdlm_pointers_PixelMapfv( struct instancePixelMapfv *instance, GLenum map, GLsizei mapsize, const GLfloat *values );
+extern int crdlm_pointers_PixelMapuiv( struct instancePixelMapuiv *instance, GLenum map, GLsizei mapsize, const GLuint *values );
+extern int crdlm_pointers_PixelMapusv( struct instancePixelMapusv *instance, GLenum map, GLsizei mapsize, const GLushort *values );
+extern int crdlm_pointers_PointParameterfvARB( struct instancePointParameterfvARB *instance, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_PointParameteriv( struct instancePointParameteriv *instance, GLenum pname, const GLint *params);
+extern int crdlm_pointers_TexEnvfv( struct instanceTexEnvfv *instance, GLenum target, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexEnviv( struct instanceTexEnviv *instance, GLenum target, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexGendv( struct instanceTexGendv *instance, GLenum coord, GLenum pname, const GLdouble *params );
+extern int crdlm_pointers_TexGenfv( struct instanceTexGenfv *instance, GLenum coord, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexGeniv( struct instanceTexGeniv *instance, GLenum coord, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexImage1D( struct instanceTexImage1D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage1DARB(struct instanceCompressedTexImage1DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexImage2D( struct instanceTexImage2D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage2DARB(struct instanceCompressedTexImage2DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexImage3D( struct instanceTexImage3D *instance, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexImage3DEXT( struct instanceTexImage3DEXT *instance, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexImage3DARB(struct instanceCompressedTexImage3DARB *instance, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_TexParameterfv( struct instanceTexParameterfv *instance, GLenum target, GLenum pname, const GLfloat *params );
+extern int crdlm_pointers_TexParameteriv( struct instanceTexParameteriv *instance, GLenum target, GLenum pname, const GLint *params );
+extern int crdlm_pointers_TexSubImage1D( struct instanceTexSubImage1D *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexSubImage2D( struct instanceTexSubImage2D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_TexSubImage3D( struct instanceTexSubImage3D *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels, CRClientState *c );
+extern int crdlm_pointers_CompressedTexSubImage1DARB(struct instanceCompressedTexSubImage1DARB *instance, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_CompressedTexSubImage2DARB(struct instanceCompressedTexSubImage2DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_CompressedTexSubImage3DARB(struct instanceCompressedTexSubImage3DARB *instance, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imagesize, const GLvoid *data);
+extern int crdlm_pointers_Rectdv(struct instanceRectdv *instance, const GLdouble *v1, const GLdouble *v2);
+extern int crdlm_pointers_Rectfv(struct instanceRectfv *instance, const GLfloat *v1, const GLfloat *v2);
+extern int crdlm_pointers_Rectiv(struct instanceRectiv *instance, const GLint *v1, const GLint *v2);
+extern int crdlm_pointers_Rectsv(struct instanceRectsv *instance, const GLshort *v1, const GLshort *v2);
+extern int crdlm_pointers_PrioritizeTextures(struct instancePrioritizeTextures *instance, GLsizei n, const GLuint *textures, const GLclampf *priorities);
+extern int crdlm_pointers_CombinerParameterivNV(struct instanceCombinerParameterivNV *instance, GLenum pname, const GLint *params);
+extern int crdlm_pointers_CombinerParameterfvNV(struct instanceCombinerParameterfvNV *instance, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_CombinerStageParameterfvNV(struct instanceCombinerStageParameterfvNV *instance, GLenum stage, GLenum pname, const GLfloat *params);
+extern int crdlm_pointers_ExecuteProgramNV(struct instanceExecuteProgramNV *instance, GLenum target, GLuint id, const GLfloat *params);
+extern int crdlm_pointers_RequestResidentProgramsNV(struct instanceRequestResidentProgramsNV *instance, GLsizei n, const GLuint *ids);
+extern int crdlm_pointers_LoadProgramNV(struct instanceLoadProgramNV *instance, GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+extern int crdlm_pointers_ProgramNamedParameter4dNV(struct instanceProgramNamedParameter4dNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+extern int crdlm_pointers_ProgramNamedParameter4dvNV(struct instanceProgramNamedParameter4dvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v);
+extern int crdlm_pointers_ProgramNamedParameter4fNV(struct instanceProgramNamedParameter4fNV *instance, GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+extern int crdlm_pointers_ProgramNamedParameter4fvNV(struct instanceProgramNamedParameter4fvNV *instance, GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v);
+extern int crdlm_pointers_ProgramStringARB(struct instanceProgramStringARB *instance, GLenum target, GLenum format, GLsizei len, const GLvoid * string);
+extern int crdlm_pointers_CallLists(struct instanceCallLists *instance, GLsizei n, GLenum type, const GLvoid *lists );
+extern int crdlm_pointers_VertexAttribs1dvNV(struct instanceVertexAttribs1dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs1fvNV(struct instanceVertexAttribs1fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs1svNV(struct instanceVertexAttribs1svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs2dvNV(struct instanceVertexAttribs2dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs2fvNV(struct instanceVertexAttribs2fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs2svNV(struct instanceVertexAttribs2svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs3dvNV(struct instanceVertexAttribs3dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs3fvNV(struct instanceVertexAttribs3fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs3svNV(struct instanceVertexAttribs3svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs4dvNV(struct instanceVertexAttribs4dvNV *instance, GLuint index, GLsizei n, const GLdouble *v);
+extern int crdlm_pointers_VertexAttribs4fvNV(struct instanceVertexAttribs4fvNV *instance, GLuint index, GLsizei n, const GLfloat *v);
+extern int crdlm_pointers_VertexAttribs4svNV(struct instanceVertexAttribs4svNV *instance, GLuint index, GLsizei n, const GLshort *v);
+extern int crdlm_pointers_VertexAttribs4ubvNV(struct instanceVertexAttribs4ubvNV *instance, GLuint index, GLsizei n, const GLubyte *v);
+extern int crdlm_pointers_ZPixCR( struct instanceZPixCR *instance, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum ztype, GLint zparm, GLint length, const GLvoid *pixels, CRClientState *c );
+
+#endif
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special	(revision 54905)
@@ -0,0 +1,21 @@
+# dlm_arrays.c: these have to be expanded out into
+# their components before being stored in a display list
+ArrayElement
+DrawArrays
+DrawElements
+DrawRangeElements
+MultiDrawArraysEXT
+MultiDrawElementsEXT
+
+# dlm_calllist.c: since the DLM can manage state stored
+# inside display lists, we can manage state updates for
+# these sorts of elements.
+CallList
+CallLists
+
+# Calls to be ignored.
+#VBoxConCreate
+#VBoxCreateContext
+#VBoxPackSetInjectThread
+#VBoxPresentComposition
+#VBoxWindowCreate
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando.py	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando.py	(revision 54905)
@@ -0,0 +1,91 @@
+# $Id$
+# This script generates calls for display list compilation
+# and state management.
+import sys
+
+sys.path.append( "../../glapi_parser" )
+import apiutil
+
+apiutil.CopyrightC()
+
+print """
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY expando.py SCRIPT */
+#include <stdio.h>
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "expandospu.h"
+"""
+
+allFunctions = []
+generatedFunctions = []
+
+for func_name in apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt"):
+	if apiutil.FindSpecial("expando", func_name):
+		allFunctions.append(func_name)
+	elif apiutil.CanCompile(func_name) or apiutil.SetsClientState(func_name):
+		generatedFunctions.append(func_name)
+		allFunctions.append(func_name)
+
+for func_name in generatedFunctions:
+	params = apiutil.Parameters(func_name)
+	return_type = apiutil.ReturnType(func_name)
+	basicCallString = apiutil.MakeCallString(params)
+	declarationString = apiutil.MakeDeclarationString(params)
+	dlmCallString = basicCallString
+	chromiumProps = apiutil.ChromiumProps(func_name)
+
+	needClientState = 0
+	if apiutil.UsesClientState(func_name):
+		dlmCallString = basicCallString + ", clientState"
+		needClientState = 1
+
+	needDL = 0
+	if apiutil.CanCompile(func_name):
+		needDL = 1
+
+	print 'static %s EXPANDOSPU_APIENTRY expando%s( %s )' % ( return_type, func_name, declarationString)
+	print '{'
+	if needDL:
+		print '\tGLenum dlMode = crDLMGetCurrentMode();'
+	if needClientState:
+		print '\tCRContext *stateContext = crStateGetCurrent();'
+		print '\tCRClientState *clientState = NULL;'
+		print '\tif (stateContext != NULL) {'
+		print '\t\tclientState = &(stateContext->client);'
+		print '\t}'
+
+	if needDL:
+		if "checklist" in chromiumProps:
+			print '\tif (dlMode != GL_FALSE && crDLMCheckList%s(%s)) {' % (func_name, basicCallString)
+		else:
+			print '\tif (dlMode != GL_FALSE) {'
+		print '\t\tcrDLMCompile%s(%s);' % (func_name, dlmCallString)
+		# If we're only compiling, return now.
+		print '\t\tif (dlMode == GL_COMPILE) return %s;' % '0' if return_type != "void" else ""
+		print '\t}'
+
+	# If it gets this far, we're either just executing, or executing
+	# and compiling.  Either way, pass the call to the super SPU,
+	# and to the state tracker (if appropriate; note that we only
+	# track client-side state, not all state).
+	if return_type != "void":
+	    print '\t%s rc = expando_spu.super.%s(%s);' % (return_type, func_name, basicCallString)
+	else:
+	    print '\texpando_spu.super.%s(%s);' % (func_name, basicCallString)
+	if apiutil.SetsClientState(func_name):
+		print '\tcrState%s( %s );' % (func_name, basicCallString)	
+	
+	if return_type != "void":
+	    print "\treturn rc;"
+
+	print '}'
+	print ''
+
+# Generate the table of named functions. including all the static generated
+# functions as well as the special functions.
+print 'SPUNamedFunctionTable _cr_expando_table[] = {'
+for func_name in allFunctions:
+	print '\t{ "%s", (SPUGenericFunction) expando%s },' % (func_name, func_name )
+print '\t{ NULL, NULL }'
+print '};'
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special	(revision 54905)
@@ -0,0 +1,17 @@
+CreateContext
+DestroyContext
+MakeCurrent
+NewList
+EndList
+DeleteLists
+GenLists
+IsList
+CallList
+CallLists
+
+# Calls to be ignored.
+#VBoxConCreate
+#VBoxCreateContext
+#VBoxPackSetInjectThread
+#VBoxPresentComposition
+#VBoxWindowCreate
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c	(revision 54905)
@@ -0,0 +1,158 @@
+/* $Id$ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_mem.h"
+#include "expandospu.h"
+
+extern GLint EXPANDOSPU_APIENTRY
+expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx)
+{
+	ExpandoContextState *contextState;
+	GLint contextId;
+
+	/* Allocate our own per-context record */
+	contextState = crCalloc(sizeof(ExpandoContextState));
+	if (contextState == NULL) {
+	    crError("expando: couldn't allocate per-context state");
+	    return 0;
+	}
+
+	/* Get an official context ID from our super */
+	contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx);
+
+	/* Supplement that with our DLM.  In a more correct situation, we should
+	 * see if we've been called through glXCreateContext, which has a parameter
+	 * for sharing DLMs.  We don't currently get that information, so for now
+	 * give each context its own DLM.
+	 */
+	contextState->dlm = crDLMNewDLM(0, NULL);
+	if (!contextState->dlm) {
+		crError("expando: couldn't get DLM!");
+	}
+
+	contextState->dlmContext = crDLMNewContext(contextState->dlm);
+	if (!contextState->dlmContext) {
+		crError("expando: couldn't get dlmContext");
+	}
+
+	/* The DLM needs us to use the state tracker to track client
+	 * state, so we can compile client-state-using functions correctly.
+	 */
+	contextState->State = crStateCreateContext(NULL, visBits, NULL);
+
+	/* Associate the Expando context with the user context. */
+	crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
+
+	return contextId;
+}
+
+void expando_free_context_state(void *data)
+{
+    ExpandoContextState *expandoContextState = (ExpandoContextState *)data;
+
+    crDLMFreeContext(expandoContextState->dlmContext);
+    crDLMFreeDLM(expandoContextState->dlm);
+    crStateDestroyContext(expandoContextState->State);
+    crFree(expandoContextState);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoDestroyContext(GLint contextId)
+{
+	/* Destroy our context information */
+	crHashtableDelete(expando_spu.contextTable, contextId, 
+				expando_free_context_state);
+
+	/* Pass along the destruction to our super. */
+	expando_spu.super.DestroyContext(contextId);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId)
+{
+	ExpandoContextState *expandoContextState;
+
+	expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId);
+
+	expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId);
+	if (expandoContextState) {
+	    crDLMSetCurrentState(expandoContextState->dlmContext);
+	    crStateMakeCurrent(expandoContextState->State);
+	}
+	else {
+	    crDLMSetCurrentState(NULL);
+	    crStateMakeCurrent(NULL);
+	}
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoNewList(GLuint list, GLenum mode)
+{
+    crDebug("Expando SPU: expandoNewList()");
+	crDLMNewList(list, mode);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoEndList(void)
+{
+    crDebug("Expando SPU: expandoEndList()");
+	crDLMEndList();
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoDeleteLists(GLuint first, GLsizei range)
+{
+	crDLMDeleteLists(first, range);
+}
+
+extern GLuint EXPANDOSPU_APIENTRY
+expandoGenLists(GLsizei range)
+{
+	 return crDLMGenLists(range);
+}
+
+extern GLboolean EXPANDOSPU_APIENTRY
+expandoIsList(GLuint list)
+{
+	 return crDLMIsList(list);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoCallList(GLuint list)
+{
+	GLenum mode = crDLMGetCurrentMode();
+	if (mode != GL_FALSE) {
+		crDLMCompileCallList(list);
+		if (mode == GL_COMPILE) return;
+	}
+
+	/* Instead of passing through the CallList,
+	 * expand it into its components.  This will cause
+	 * a recursion if there are any compiled CallList
+	 * elements within the display list.
+	 */
+	crDLMReplayList(list, &expando_spu.self);
+}
+
+extern void EXPANDOSPU_APIENTRY
+expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists)
+{
+	GLenum mode = crDLMGetCurrentMode();
+	if (mode != GL_FALSE) {
+		crDLMCompileCallLists(n, type, lists);
+		if (mode == GL_COMPILE) return;
+	}
+	/* Instead of passing through the CallLists,
+	 * expand it into its components.  This will cause
+	 * a recursion if there are any compiled CallLists
+	 * elements within the display list.
+	 */
+	crDLMReplayLists(n, type, lists, &expando_spu.self);
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.def	(revision 54905)
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h	(revision 54905)
@@ -0,0 +1,68 @@
+/* $Id$ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef EXPANDO_SPU_H
+#define EXPANDO_SPU_H
+
+#ifdef WINDOWS
+#define EXPANDOSPU_APIENTRY __stdcall
+#else
+#define EXPANDOSPU_APIENTRY
+#endif
+
+#include "cr_glstate.h"
+#include "cr_spu.h"
+#include "cr_server.h"
+#include "cr_dlm.h"
+
+typedef struct {
+	int id;
+	int has_child;
+	SPUDispatchTable self, child, super;
+	CRServer *server;
+
+	/* Expando-specific variables */
+	CRHashTable *contextTable;
+} ExpandoSPU;
+
+typedef struct {
+	/* Local copy of state, needed by DLM to compile client-side stuff.
+	 * We only collect client-side state; we ignore all server-side
+	 * state (we just don't need it).
+	 */
+	CRContext *State; 
+
+	/* The DLM, and the per-context state for a DLM.  Right now, every
+	 * context will have its own DLM; it's possible in OpenGL to share
+	 * DLMs, but the Chromium interface doesn't allow it yet.
+	 */
+	CRDLM *dlm;
+	CRDLMContextState *dlmContext;
+} ExpandoContextState;
+
+extern ExpandoSPU expando_spu;
+
+extern SPUNamedFunctionTable _cr_expando_table[];
+
+extern SPUOptions expandoSPUOptions[];
+
+extern void expandospuGatherConfiguration( void );
+
+extern void expando_free_context_state(void *data);
+
+extern GLint EXPANDOSPU_APIENTRY expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx);
+extern void EXPANDOSPU_APIENTRY expandoDestroyContext(GLint contextId);
+extern void EXPANDOSPU_APIENTRY expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId);
+extern void EXPANDOSPU_APIENTRY expandoNewList(GLuint list, GLenum mode);
+extern void EXPANDOSPU_APIENTRY expandoEndList(void);
+extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range);
+extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range);
+extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list);
+extern  void EXPANDOSPU_APIENTRY expandoCallList(GLuint list);
+extern void EXPANDOSPU_APIENTRY expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists);
+
+#endif /* EXPANDO_SPU_H */
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_config.c	(revision 54905)
@@ -0,0 +1,48 @@
+/* $Id$ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "expandospu.h"
+
+//#include "cr_mothership.h"
+#include "cr_string.h"
+
+#include <stdio.h>
+
+static void __setDefaults( void )
+{
+}
+
+/* option, type, nr, default, min, max, title, callback
+ */
+SPUOptions expandoSPUOptions[] = {
+	{ NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+void expandospuGatherConfiguration( void )
+{
+	CRConnection *conn;
+
+	__setDefaults();
+#if 0
+	/* Connect to the mothership and identify ourselves. */
+	
+	conn = crMothershipConnect( );
+	if (!conn)
+	{
+		/* The mothership isn't running.  Some SPU's can recover gracefully, some 
+		 * should issue an error here. */
+		crSPUSetDefaultParams( &expando_spu, expandoSPUOptions );
+		return;
+	}
+	crMothershipIdentifySPU( conn, expando_spu.id );
+
+	crSPUGetMothershipParams( conn, &expando_spu, expandoSPUOptions );
+
+	crMothershipDisconnect( conn );
+#endif
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c	(revision 54905)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c	(revision 54905)
@@ -0,0 +1,87 @@
+/* $Id$ */
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_dlm.h"
+#include "cr_hash.h"
+#include "expandospu.h"
+
+ExpandoSPU expando_spu;
+
+static SPUFunctions expando_functions = {
+	NULL, /* CHILD COPY */
+	NULL, /* DATA */
+	_cr_expando_table /* THE ACTUAL FUNCTIONS */
+};
+
+static SPUFunctions *
+expandoSPUInit( int id, SPU *child, SPU *self,
+								 unsigned int context_id,
+								 unsigned int num_contexts )
+{
+
+	(void) self;
+	(void) context_id;
+	(void) num_contexts;
+
+	expando_spu.id = id;
+	expando_spu.has_child = 0;
+	expando_spu.server = NULL;
+	if (child)
+	{
+		crSPUInitDispatchTable( &(expando_spu.child) );
+		crSPUCopyDispatchTable( &(expando_spu.child), &(child->dispatch_table) );
+		expando_spu.has_child = 1;
+	}
+	crSPUInitDispatchTable( &(expando_spu.super) );
+	crSPUCopyDispatchTable( &(expando_spu.super), &(self->superSPU->dispatch_table) );
+	expandospuGatherConfiguration();
+
+	/* Expando-specific initialization */
+	expando_spu.contextTable = crAllocHashtable();
+
+	/* We'll be using the state tracker for each context */
+	crStateInit();
+
+	return &expando_functions;
+}
+
+static void
+expandoSPUSelfDispatch(SPUDispatchTable *self)
+{
+	crSPUInitDispatchTable( &(expando_spu.self) );
+	crSPUCopyDispatchTable( &(expando_spu.self), self );
+
+	expando_spu.server = (CRServer *)(self->server);
+}
+
+
+static int
+expandoSPUCleanup(void)
+{
+    crFreeHashtable(expando_spu.contextTable, expando_free_context_state);
+    crStateDestroy();
+    return 1;
+}
+
+int
+SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+				 SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+				 SPUOptionsPtr *options, int *flags )
+{
+	*name = "expando";
+	//*super = "passthrough";
+	*super = "render";
+	*init = expandoSPUInit;
+	*self = expandoSPUSelfDispatch;
+	*cleanup = expandoSPUCleanup;
+	*options = expandoSPUOptions;
+	*flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+	
+	return 1;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c	(revision 54904)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c	(revision 54905)
@@ -187,4 +187,5 @@
 #ifdef CHROMIUM_THREADSAFE
     crDebug("Render SPU: thread-safe");
+    crInitTSD(&_RenderTSD);
 #endif
 
