Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h	(revision 56921)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h	(revision 56922)
@@ -46,5 +46,6 @@
 #define SHCROGL_SSM_VERSION_WITH_PEND_CMD_INFO                      47
 #define SHCROGL_SSM_VERSION_WITH_SEPARATE_DEPTH_STENCIL_BUFFERS     48
-#define SHCROGL_SSM_VERSION                                         48
+#define SHCROGL_SSM_VERSION_WITH_DISPLAY_LISTS                      49
+#define SHCROGL_SSM_VERSION                                         49
 
 /* These define the Chromium release number.
Index: /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 56922)
@@ -31,5 +31,5 @@
 
 ifeq ($(KBUILD_TARGET),darwin)
- #VBOX_WITH_CR_DISPLAY_LISTS=1
+ VBOX_WITH_CR_DISPLAY_LISTS=1
 endif
 
@@ -290,6 +290,5 @@
 	dlm/dlm.c \
 	dlm/dlm_arrays.c \
-	dlm/dlm_bbox.c \
-	dlm/dlm_calllist.c \
+	dlm/dlm_state.c \
 	dlm/dlm_checklist.c \
 	dlm/dlm_error.c \
@@ -310,5 +309,5 @@
 		| $$(dir $$@)
 	$(call MSG_GENERATE,python,$@,$<)
-	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< header $(VBOX_PATH_CROGL_GLAPI) > $@
+	$(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< header $(<D) $(VBOX_PATH_CROGL_GLAPI) > $@
 
 $(VBOX_PATH_CROGL_GENFILES)/dlm_generated.h: \
@@ -350,5 +349,6 @@
 	$(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
 	$(VBOX_LIB_OGL_HOSTCRUTIL) \
-	$(LIB_RUNTIME)
+	$(LIB_RUNTIME) \
+	$(LIB_VMM)
 #
 # Generate files for VBoxOGLexpandospu.
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 56922)
@@ -1683,8 +1683,14 @@
     }
 
+    rc = crServerPendSaveState(pSSM);
+    AssertRCReturn(rc, rc);
+
+    rc = CrPMgrSaveState(pSSM);
+    AssertRCReturn(rc, rc);
+
 #ifdef VBOX_WITH_CR_DISPLAY_LISTS
     if (cr_server.head_spu->dispatch_table.spu_save_state)
     {
-        rc = cr_server.head_spu->dispatch_table.spu_save_state("NULL");
+        rc = cr_server.head_spu->dispatch_table.spu_save_state((void *)pSSM);
         AssertRCReturn(rc, rc);
     }
@@ -1692,10 +1698,4 @@
         crDebug("Do not save %s SPU state: no interface exported.", cr_server.head_spu->name);
 #endif
-
-    rc = crServerPendSaveState(pSSM);
-    AssertRCReturn(rc, rc);
-
-    rc = CrPMgrSaveState(pSSM);
-    AssertRCReturn(rc, rc);
 
     /* all context gl error states should have now be synced with chromium erro states,
@@ -2481,4 +2481,17 @@
     }
 
+#ifdef VBOX_WITH_CR_DISPLAY_LISTS
+    if (version >= SHCROGL_SSM_VERSION_WITH_DISPLAY_LISTS)
+    {
+        if (cr_server.head_spu->dispatch_table.spu_load_state)
+        {
+            rc = cr_server.head_spu->dispatch_table.spu_load_state((void *)pSSM);
+            AssertRCReturn(rc, rc);
+        }
+        else
+            crDebug("Do not load %s SPU state: no interface exported.", cr_server.head_spu->name);
+    }
+#endif
+
     while ((err = cr_server.head_spu->dispatch_table.GetError()) != GL_NO_ERROR)
         crWarning("crServer: glGetError %d after loading snapshot", err);
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 56922)
@@ -229,5 +229,4 @@
 	state->currentListMode = GL_FALSE;
 	state->listBase = 0;
-	state->replayState = CRDLM_IMMEDIATE;
 	
 	/* Increment the use count of the DLM provided.  This guarantees that
@@ -321,21 +320,4 @@
 }
 
-/* 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;
-    }
-}
-
 /**
  *
@@ -365,10 +347,6 @@
 {
     CRDLMContextState *listState = CURRENT_STATE();
-    if (listState) {
-	CRDLMReplayState oldReplayState = listState->replayState;
-	listState->replayState = CRDLM_REPLAY_ALL_FUNCTIONS;
-	crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
-	listState->replayState = oldReplayState;
-    }
+    if (listState)
+        crDLMReplayDLMList(listState->dlm, listIdentifier, dispatchTable);
 }
 
@@ -398,10 +376,6 @@
 {
     CRDLMContextState *listState = CURRENT_STATE();
-    if (listState) {
-	CRDLMReplayState oldReplayState = listState->replayState;
-	listState->replayState = CRDLM_REPLAY_STATE_FUNCTIONS;
-	crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
-	listState->replayState = oldReplayState;
-    }
+    if (listState)
+        crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable);
 }
 
@@ -565,48 +539,4 @@
 };
 
-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;
-    }
-}
-
 /*
  * Return id of list currently being compiled.  Returns 0 of there's no
@@ -644,33 +574,2 @@
 		(*ErrorCallback)(line, file, error, info);
 }
-
-static void crDLMSaveListsCb(unsigned long key, void *pData1, void *pData2 /* unused */ )
-{
-    DLMListInfo *pListInfo = (DLMListInfo*)pData1;
-
-    if (pListInfo)
-    {
-        crDebug("Saving Display Lists: found ID=%u, numInstances=%d, references=%p.",
-            key, pListInfo->numInstances, pListInfo->references);
-
-        DLMInstanceList *pInstance = pListInfo->first;
-        while (pInstance) {
-            crDebug("\t%p", pInstance->execute);
-            pInstance = pInstance->next;
-        }
-    }
-    else
-        crError("Saving Display Lists: found record with no data. Skipping.");
-}
-
-int32_t DLM_APIENTRY crDLMSaveState(void)
-{
-    CRDLMContextState *pListState = CURRENT_STATE();
-
-    if (pListState)
-        crHashtableWalk(pListState->dlm->displayLists, crDLMSaveListsCb, (void *)NULL);
-    else
-        crDebug("Saving Display Lists: no data to save.");
-
-    return 0;
-}
Index: unk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_bbox.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_bbox.c	(revision 56921)
+++ 	(revision )
@@ -1,454 +1,0 @@
-/* $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: unk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c	(revision 56921)
+++ 	(revision )
@@ -1,67 +1,0 @@
-/* $Id$ */
-#if 0
-
-#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);
-}
-
-#endif
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_generated.py	(revision 56922)
@@ -126,108 +126,21 @@
 
 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
+
+    params = apiutil.Parameters(functionName)
+    (pointers, _, pointerarg, _, _, _) = GetPointerInfo(functionName)
+
+    print 'static void execute%s(DLMInstanceList *x, SPUDispatchTable *dispatchTable)' % functionName
+    print '{'
+    if len(params) > 0:
+        print '    struct instance%s *instance = (struct instance%s *)x;' % (functionName, functionName)
+
+    if len(pointers) == 1:
+        print '    instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
+
+    print '    if (dispatchTable->%s != NULL)' % (functionName)
+    print '        dispatchTable->%s(%s);' % (functionName, InstanceCallString(params))
+    print '    else'
+    print '        crWarning("DLM warning: execute%s called with NULL dispatch entry");' % (functionName)
+    print '}'
 
 # These code snippets isolate the code required to add a given instance
@@ -239,8 +152,8 @@
     print '%sinstance->stateNext = NULL;' % pad
     print '%sif (!state->currentListInfo->first) {' % pad
-    print '%s\tstate->currentListInfo->first = (DLMInstanceList *)instance;' % pad
+    print '%s    state->currentListInfo->first = (DLMInstanceList *)instance;' % pad
     print '%s}' % pad
     print '%selse {' % pad
-    print '%s\tstate->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
+    print '%s  state->currentListInfo->last->next = (DLMInstanceList *)instance;' % pad
     print '%s}' % pad
     print '%sstate->currentListInfo->last = (DLMInstanceList *)instance;' % pad
@@ -250,8 +163,8 @@
     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    state->currentListInfo->stateFirst = (DLMInstanceList *)instance;' % pad
     print '%s}' % pad
     print '%selse {' % pad
-    print '%s\tstate->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
+    print '%s    state->currentListInfo->stateLast->stateNext = (DLMInstanceList *)instance;' % pad
     print '%s}' % pad
     print '%sstate->currentListInfo->stateLast = (DLMInstanceList *)instance;' % pad
@@ -262,98 +175,95 @@
 # 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)
-	
-	# We need to know instance size in bytes in order to save its state later.
-	print '\tinstance->cbInstance = sizeof(struct instance%s);' % functionName
-	
-	# Set OPCODE.
-	print '\tinstance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
-	
-	# 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 '\tinstance->cbInstance += 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 '\tinstance->cbInstance += 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 '}'
+    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)
+
+    # 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 '    if (crDLMCheckList%s(%s))' % (functionName, apiutil.MakeCallString(params))
+        print '    {'
+        print '        crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,'
+        print '            "this instance of function %s should not be compiled");' % functionName;
+        print '        return;'
+        print '    }'
+
+    if len(pointers) > 1 or pointersize == 'special':
+        # Pass NULL, to just allocate space
+        print '    instance = crCalloc(sizeof(struct instance%s) + crdlm_pointers_%s(NULL, %s));' % (functionName, functionName, callstring)
+    else:
+        print '    instance = crCalloc(sizeof(struct instance%s));' % (functionName)
+    print '    if (!instance)'
+    print '    {'
+    print '        crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,'
+    print '            "out of memory adding %s to display list");' % (functionName)
+    print '        return;'
+    print '    }'
+
+    # Put in the fields that must always exist
+    print '    instance->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 '    instance->%s = %s;' % (name, name)
+
+    # We need to know instance size in bytes in order to save its state later.
+    print '    instance->cbInstance = sizeof(struct instance%s);' % functionName
+
+    # Set OPCODE.
+    print '    instance->iVBoxOpCode = VBOX_DL_OPCODE_%s;' % functionName
+
+    # If there's a pointer parameter, apply it.
+    if len(pointers) == 1:
+
+        print '    if (%s == NULL)' % (params[pointers[0]][0])
+        print '        instance->%s = NULL;' % (params[pointers[0]][0])
+        print '    else'
+        print '        instance->%s = instance->%s;' % (params[pointers[0]][0], pointerarg)
+
+        if pointersize == 'special':
+            print '    instance->cbInstance += crdlm_pointers_%s(instance, %s);' % (functionName, callstring)
+        else:
+            print '    crMemcpy((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 '    instance->cbInstance += 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('    ')
+    # If the element is a state-changing element, add it to the current state list
+    if apiutil.SetsTrackedState(functionName):
+        AddInstanceToStateList('    ')
+    print '}'
 
 whichfile=sys.argv[1]
@@ -361,4 +271,6 @@
     print """#ifndef _DLM_GENERATED_H
 #define _DLM_GENERATED_H
+
+#include <VBox/VBoxUhgsmi.h>
 
 /* DO NOT EDIT.  This file is auto-generated by dlm_generated.py. */
@@ -417,5 +329,26 @@
 		    wrap_execute(func_name)
 		    wrap_compile(func_name)
-		# All others just pass through
+
+
+# Generate mapping between OPCODE and routines to be executed.
+
+if whichfile == "headers":
+    # Execute routine prototype needed to add static array of routines.
+    print ''
+    print 'struct DLMInstanceList;'
+    print 'typedef void (*VBoxDLMExecuteFn)(struct DLMInstanceList *instance, SPUDispatchTable *dispatchTable);'
+    print ''
+    print 'extern VBoxDLMExecuteFn g_VBoxDLMExecuteFns[VBOX_DL_OPCODE_MAX];'
+    print ''
+else:
+    print ''
+    print 'VBoxDLMExecuteFn g_VBoxDLMExecuteFns[] = {'
+
+    for func_name in keys:
+        if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
+            print '    execute%s,' % func_name
+
+    print '};'
+    print ''
 
 if whichfile == 'headers':
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 56922)
@@ -8,5 +8,5 @@
 mode = sys.argv[1]
 
-keys = apiutil.GetDispatchedFunctions(sys.argv[2]+"/APIspec.txt")
+keys = apiutil.GetDispatchedFunctions(sys.argv[3]+"/APIspec.txt")
 
 # Any new function implemented in the DLM has to have an entry added here.
@@ -21,5 +21,4 @@
 	('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'),
@@ -37,5 +36,4 @@
 	('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'),
 	('void DLM_APIENTRY', 'crDLMComputeBoundingBox', 'unsigned long listId'),
 	('GLuint DLM_APIENTRY', 'crDLMGetCurrentList', 'void'),
@@ -50,5 +48,6 @@
 	('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list, SPUDispatchTable *dispatchTable'),
 	('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range, SPUDispatchTable *dispatchTable'),
-	('int32_t DLM_APIENTRY', 'crDLMSaveState', 'void'),
+	('int32_t DLM_APIENTRY', 'crDLMSaveState', 'CRDLM *dlm, PSSMHANDLE pSSM'),
+	('bool DLM_APIENTRY', 'crDLMLoadState', 'CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable'),
 	#('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
 	#('GLboolean DLM_APIENTRY', 'crDLMIsListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
@@ -77,4 +76,5 @@
 #include "cr_threads.h"
 #endif
+#include <VBox/types.h>
 """ % os.path.basename(sys.argv[0])
 
@@ -84,6 +84,8 @@
 
     for func_name in keys:
-        print "    VBOX_DL_OPCODE_%s," % func_name
-
+        if apiutil.CanCompile(func_name) and not apiutil.FindSpecial("dlm", func_name):
+            print "    VBOX_DL_OPCODE_%s," % func_name
+
+    print "    VBOX_DL_OPCODE_MAX,"
     print "} VBoxDLOpCode;"
 
@@ -111,11 +113,8 @@
 
 typedef struct {
-	DLMInstanceList *first, *last;
-	int numInstances;
-	DLMInstanceList *stateFirst, *stateLast;
-	CRHashTable *references; /* display lists that this display list calls */
-	CRDLMBounds bbox;
-	GLboolean listSent;
-	GLuint hwid;
+    DLMInstanceList *first, *last;
+    uint32_t         numInstances;
+    DLMInstanceList *stateFirst, *stateLast;
+    GLuint           hwid;
 } DLMListInfo;
 
@@ -160,5 +159,4 @@
 	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;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 56922)
@@ -7,5 +7,5 @@
  *   glListBase and glIsList.
  *
- * Privide OpenGL IDs mapping between host and guest.
+ * Provide OpenGL IDs mapping between host and guest.
  */
 
@@ -57,10 +57,4 @@
         crdlmFreeDisplayListElements(pListInfo->first);
         pListInfo->first = pListInfo->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(pListInfo->references, NULL);
 
         /* Free host OpenGL resources. */
@@ -191,28 +185,16 @@
                     listInfo->first = listInfo->last = NULL;
                     listInfo->stateFirst = listInfo->stateLast = NULL;
-                    listInfo->references = crAllocHashtable();
-                    if (listInfo->references)
-                    {
-                        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 = list;
-                        listState->currentListMode = mode;
-
-                        dispatchTable->NewList(listInfo->hwid, mode);
-
-                        crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
-
-                        return;
-                    }
-                    else
-                        crDebug("DLM: Could not allocate memory in NewList.");
+
+                    listInfo->numInstances = 0;
+
+                    listState->currentListInfo = listInfo;
+                    listState->currentListIdentifier = list;
+                    listState->currentListMode = mode;
+
+                    dispatchTable->NewList(listInfo->hwid, mode);
+
+                    crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
+
+                    return;
                 }
                 else
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c	(revision 56922)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_state.c	(revision 56922)
@@ -0,0 +1,353 @@
+/* $Id$ */
+/** @file
+ * Implementation of saving and restoring Display Lists.
+ */
+
+/*
+ * Copyright (C) 2015 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "cr_mem.h"
+#include "cr_dlm.h"
+#include "dlm.h"
+#include "dlm_generated.h"
+
+#include "VBox/vmm/ssm.h"
+#include "iprt/err.h"
+
+
+typedef struct {
+
+    PSSMHANDLE pSSM;
+    uint32_t   err;
+
+} CRDLMSaveListsCbArg;
+
+static void crDLMSaveListsCb(unsigned long key, void *pData1, void *pData2)
+{
+    DLMListInfo         *pListInfo      = (DLMListInfo*)pData1;
+    CRDLMSaveListsCbArg *pArg           = (CRDLMSaveListsCbArg *)pData2;
+    PSSMHANDLE           pSSM           = pArg->pSSM;
+    DLMInstanceList     *pInstance      = pListInfo->first;
+    uint32_t             cInstanceCheck = 0;
+    int32_t              rc;
+
+    crDebug("Saving Display Lists: found ID=%u, numInstances=%d.", key, pListInfo->numInstances);
+
+    /* Store Display List length. */
+    rc = SSMR3PutU32(pSSM, pListInfo->numInstances);
+    if (RT_SUCCESS(rc))
+    {
+        /* Store Display List (guest) ID. */
+        rc = SSMR3PutU32(pSSM, (uint32_t)key);
+        if (RT_SUCCESS(rc))
+        {
+            /* Store each Display List item one by one. */
+            while (pInstance)
+            {
+                /* Let's count each list item and compare total number with pListInfo->numInstances.
+                 * This is simple consistency check. */
+                cInstanceCheck++;
+
+                /* Store instance data size. */
+                rc = SSMR3PutU32(pSSM, (uint32_t)pInstance->cbInstance);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = SSMR3PutMem(pSSM, pInstance, pInstance->cbInstance);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* We just stored all we need. Let's move on to the next list element. */
+                        pInstance = pInstance->next;
+                        continue;
+                    }
+                }
+
+                crError("Saving Display Lists: can't store data.");
+
+                pArg->err = 1;
+                return;
+            }
+
+            if (cInstanceCheck == pListInfo->numInstances)
+                return;
+
+            crError("Saving Display Lists: list currupted.");
+        }
+    }
+
+    pArg->err = 1;
+}
+
+int32_t DLM_APIENTRY crDLMSaveState(CRDLM *dlm, PSSMHANDLE pSSM)
+{
+    uint32_t ui32;
+    int32_t  rc;
+
+    CRDLMSaveListsCbArg arg;
+
+    arg.pSSM = pSSM;
+    arg.err = 0;
+
+    /* Save number of Display Lists assigned to current DLM context. */
+    ui32 = (uint32_t)crHashtableNumElements(dlm->displayLists);
+    rc = SSMR3PutU32(pSSM, ui32); AssertRCReturn(rc, rc);
+
+    crHashtableWalk(dlm->displayLists, crDLMSaveListsCb, (void *)&arg);
+
+    return arg.err == 0;
+}
+
+static VBoxDLMExecuteFn crDLMGetExecuteRoutine(VBoxDLOpCode opcode)
+{
+    if (opcode < VBOX_DL_OPCODE_MAX)
+        return g_VBoxDLMExecuteFns[opcode];
+
+    crError("Restoring Display Lists: Invalid opcode %u.", opcode);
+
+    return NULL;
+}
+
+static bool
+crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable)
+{
+    uint32_t         cbInstance = 0;
+    DLMInstanceList *pInstance;
+    int32_t          rc;
+
+    /* Get Display List item size. */
+    rc = SSMR3GetU32(pSSM, &cbInstance);
+    if (RT_SUCCESS(rc))
+    {
+        /* Allocate memory for the item, initialize it and put into the list. */
+        pInstance = crCalloc(cbInstance);
+        if (pInstance)
+        {
+            crMemset(pInstance, 0, cbInstance);
+
+            rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc);
+            if (RT_SUCCESS(rc))
+            {
+                pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode);
+                if (pInstance->execute)
+                {
+                    pInstance->execute(pInstance, dispatchTable);
+
+                    pInstance->next         = NULL;
+                    pInstance->stateNext    = NULL;
+                    pInstance->cbInstance   = cbInstance;
+
+                    pListInfo->numInstances++;
+
+                    if (!pListInfo->first)
+                        pListInfo->first = pInstance;
+
+                    if (pListInfo->last)
+                        pListInfo->last->next = pInstance;
+
+                    pListInfo->last = pInstance;
+
+                    return true;
+                }
+                else
+                    crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode);
+            }
+            else
+                crError("Restoring Display Lists: can't read list element size.");
+        }
+        else
+            crError("Restoring Display Lists: not enough memory, aborting.");
+    }
+    else
+        crError("Restoring Display Lists: saved state file might be corrupted.");
+
+    return false;
+}
+
+static bool
+crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
+{
+    uint32_t cElements = 0;
+    uint32_t idList    = 0;
+    uint32_t i;
+    int32_t  rc;
+
+    /* Restore Display List length. */
+    rc = SSMR3GetU32(pSSM, &cElements);
+    if (RT_SUCCESS(rc))
+    {
+        /* Restore Display List ID. */
+        rc = SSMR3GetU32(pSSM, &idList);
+        if (RT_SUCCESS(rc))
+        {
+            /* Initialize new list data and start recording it. */
+            DLMListInfo *pListInfo;
+
+            pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
+            if (pListInfo)
+            {
+                GLuint hwid;
+
+                crMemset(pListInfo, 0, sizeof(DLMListInfo));
+
+                hwid = dispatchTable->GenLists(1);
+                if (hwid > 0)
+                {
+                    bool               fSuccess = true;
+                    CRDLMContextState *pDLMContextState;
+
+                    pListInfo->numInstances = 0;
+                    pListInfo->stateFirst   = pListInfo->stateLast = NULL;
+                    pListInfo->hwid         = hwid;
+
+                    dispatchTable->NewList(hwid, GL_COMPILE);
+
+                    /* Fake list state in order to prevent expando SPU from double caching. */
+                    pDLMContextState = crDLMGetCurrentState();
+                    pDLMContextState->currentListMode = GL_FALSE;
+
+                    crDebug("Restoring Display Lists:\t%u elements to restore.", cElements);
+
+                    /* Iterate over list instances. */
+                    for (i = 0; i < cElements; i++)
+                    {
+                        fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable);
+                        if (!fSuccess)
+                            break;
+                    }
+
+                    dispatchTable->EndList();
+
+                    if (fSuccess)
+                    {
+                        /* Add list to cache. */
+                        crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL);
+                        return true;
+                    }
+                    else
+                        crError("Restoring Display Lists: some elements could not be restored.");
+                }
+                else
+                    crError("Restoring Display Lists: can't allocate hwid for list %u.", idList);
+
+                crFree(pListInfo);
+            }
+            else
+                crError("Restoring Display Lists: can't allocate memory.");
+        }
+        else
+            crError("Restoring Display Lists: can't get list ID.");
+    }
+    else
+        crError("Restoring Display Lists: can't get number of elements in list.");
+
+    return false;
+}
+
+
+bool DLM_APIENTRY
+crDLMLoadState(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
+{
+    uint32_t cLists = 0;
+    uint32_t i;
+    int32_t  rc;
+    bool     fSuccess = true;
+
+    /* Get number of Display Lists assigned to current DLM context. */
+    rc = SSMR3GetU32(pSSM, &cLists);
+    if (RT_SUCCESS(rc))
+    {
+        crDebug("Restoring Display Lists: %u lists to restore.", cLists);
+
+        for (i = 0; i < cLists; i++)
+        {
+            fSuccess = crDLMLoadList(dlm, pSSM, dispatchTable);
+            if (!fSuccess)
+                break;
+        }
+    }
+    else
+        crError("Restoring Display Lists: can't get number of lists.");
+
+    return fSuccess;
+}
+
+
+
+
+
+
+
+#if 0
+
+#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);
+}
+
+#endif
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c	(revision 56921)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu_init.c	(revision 56922)
@@ -10,55 +10,237 @@
 #include "cr_dlm.h"
 #include "cr_hash.h"
+#include "cr_mem.h"
 #include "expandospu.h"
 
+/* This magic number is used for SSM data consistency check. */
+#define VBOX_EXPANDOSPU_SSM_MAGIC           0x3d3d3d3d
+/* Modify VBox Expando SPU SSM version if SSM data structure changed. */
+#define VBOX_EXPANDOSPU_SSM_VERSION_ONE     1
+#define VBOX_EXPANDOSPU_SSM_VERSION         VBOX_EXPANDOSPU_SSM_VERSION_ONE
+
 ExpandoSPU expando_spu;
 
 static SPUFunctions expando_functions = {
-	NULL, /* CHILD COPY */
-	NULL, /* DATA */
-	_cr_expando_table /* THE ACTUAL FUNCTIONS */
+    NULL,               /* CHILD COPY */
+    NULL,               /* DATA */
+    _cr_expando_table   /* THE ACTUAL FUNCTIONS */
 };
+
+/*
+ * Structure of SSM data:
+ *
+ * <VBOX_EXPANDOSPU_SSM_MAGIC>
+ * <VBOX_EXPANDOSPU_SSM_VERSION>
+ * <Number of Expando SPU contexts>
+ *
+ *     <Context ID>
+ *     <CRDLMContextState structure>
+ *         <DLM module data>
+ *
+ *     <Next context...>
+ *
+ * <VBOX_EXPANDOSPU_SSM_MAGIC>
+ */
+
+static void
+expandoSPUSaveContextCb(unsigned long id, void *pData1, void *pData2)
+{
+    uint32_t   ui32 = (uint32_t)id;
+    PSSMHANDLE pSSM = (PSSMHANDLE)pData2;
+    int32_t    rc;
+
+    ExpandoContextState *pExpandoContextState = (ExpandoContextState *)pData1;
+    CRDLMContextState    dlmContextState;
+
+    /* Save context ID. */
+    rc = SSMR3PutU32(pSSM, ui32); AssertRCReturnVoid(rc);
+
+    /* Save DLM context state. Clean fields which will not be valid on restore (->dlm and ->currentListInfo).
+     * We interested only in fields: currentListIdentifier, currentListMode and listBase. */
+    crMemcpy(&dlmContextState, pExpandoContextState->dlmContext, sizeof(CRDLMContextState));
+    dlmContextState.dlm             = NULL;
+    dlmContextState.currentListInfo = NULL;
+    rc = SSMR3PutMem(pSSM, &dlmContextState, sizeof(CRDLMContextState)); AssertRCReturnVoid(rc);
+
+    /* Delegate the rest of work to DLM module. */
+    crDLMSaveState(pExpandoContextState->dlmContext->dlm, pSSM);
+}
 
 static int
 expandoSPUSaveState(void *pData)
 {
+    uint32_t    magic   = VBOX_EXPANDOSPU_SSM_MAGIC;
+    uint32_t    version = VBOX_EXPANDOSPU_SSM_VERSION;
+    PSSMHANDLE  pSSM    = (PSSMHANDLE)pData;
+    int32_t     rc;
+    uint32_t    cStates;
+
     crDebug("Saving state of Expando SPU.");
-    crDLMSaveState();
+
+    AssertReturn(pSSM, 1);
+
+    /* Magic & version first. */
+    rc = SSMR3PutU32(pSSM, magic);      AssertRCReturn(rc, rc);
+    rc = SSMR3PutU32(pSSM, version);    AssertRCReturn(rc, rc);
+
+    /* Store number of Expando SPU contexts. */
+    cStates = (uint32_t)crHashtableNumElements(expando_spu.contextTable);
+    rc = SSMR3PutU32(pSSM, cStates);  AssertRCReturn(rc, rc);
+
+    /* Walk over context table and store required data. */
+    crHashtableWalk(expando_spu.contextTable, expandoSPUSaveContextCb, pSSM);
+
+    /* Expando SPU and DLM data should end with magic (consistency check). */
+    rc = SSMR3PutU32(pSSM, magic);      AssertRCReturn(rc, rc);
+
     return 0;
 }
 
+static int
+expandoSPULoadState(void *pData)
+{
+    uint32_t    magic   = 0;
+    uint32_t    version = 0;
+    PSSMHANDLE  pSSM    = (PSSMHANDLE)pData;
+    int32_t     rc;
+
+    crDebug("Loading state of Expando SPU.");
+
+    AssertReturn(pSSM, 1);
+
+    /* Check magic and version. */
+    rc = SSMR3GetU32(pSSM, &magic);
+    AssertRCReturn(rc, rc);
+
+    if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
+    {
+        rc = SSMR3GetU32(pSSM, &version);
+        AssertRCReturn(rc, rc);
+
+        if (version >= VBOX_EXPANDOSPU_SSM_VERSION_ONE)
+        {
+            uint32_t cStates = 0;
+            uint32_t i;
+            bool     fSuccess = false;
+
+            /* Restore number of Expando SPU contexts. */
+            rc = SSMR3GetU32(pSSM, &cStates);
+            AssertRCReturn(rc, rc);
+
+            /* Restore and update Expando SPU contexts one by one. */
+            for (i = 0; i < cStates; i++)
+            {
+                uint32_t             idContext = 0;
+                ExpandoContextState *pExpandoContextState;
+
+                rc = SSMR3GetU32(pSSM, &idContext);
+                AssertRCReturn(rc, rc);
+
+                /* Find context which was previously created by CR Server. */
+                pExpandoContextState = crHashtableSearch(expando_spu.contextTable, idContext);
+                if (pExpandoContextState)
+                {
+                    CRDLMContextState dlmContextState;
+
+                    /* Restore and update DLM context state. */
+                    rc = SSMR3GetMem(pSSM, &dlmContextState, sizeof(CRDLMContextState));
+                    if (RT_SUCCESS(rc))
+                    {
+                        pExpandoContextState->dlmContext->currentListIdentifier = dlmContextState.currentListIdentifier;
+                        pExpandoContextState->dlmContext->currentListMode       = dlmContextState.currentListMode;
+                        pExpandoContextState->dlmContext->listBase              = dlmContextState.listBase;
+
+                        crDLMSetCurrentState(pExpandoContextState->dlmContext);
+                        crStateMakeCurrent(pExpandoContextState->State);
+
+                        /* Delegate the rest of work to DLM module. */
+                        fSuccess = crDLMLoadState(pExpandoContextState->dlmContext->dlm, pSSM, &expando_spu.server->dispatch);
+                        if (fSuccess)
+                        {
+                            continue;
+                        }
+                        else
+                        {
+                            crError("Expando SPU: stop restoring Display Lists.");
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        crError("Expando SPU: unable to load state: state file structure error (1).");
+                        break;
+                    }
+                }
+                else
+                {
+                    crError("Expando SPU: unable to load state: no context ID %u found.", idContext);
+                    break;
+                }
+            }
+
+            if (fSuccess)
+            {
+                /* Expando SPU and DLM data should end with magic (consistency check). */
+                magic = 0;
+                rc = SSMR3GetU32(pSSM, &magic);
+                if (RT_SUCCESS(rc))
+                {
+                    if (magic == VBOX_EXPANDOSPU_SSM_MAGIC)
+                    {
+                        crInfo("Expando SPU state loaded.");
+                        return 0;
+                    }
+                    else
+                        crError("Expando SPU: unable to load state: SSM data corrupted.");
+                }
+                else
+                    crError("Expando SPU: unable to load state: state file structure error (2): no magic.");
+            }
+            else
+                crError("Expando SPU: unable to load state: some list(s) could not be restored.");
+        }
+        else
+            crError("Expando SPU: unable to load state: unexpected SSM version (0x%x).", version);
+    }
+    else
+        crError("Expando SPU: unable to load state: SSM data possibly corrupted.");
+
+    return VERR_SSM_UNEXPECTED_DATA;
+}
+
 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();
+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();
 
     /* Export optional interfaces for SPU save/restore. */
     self->dispatch_table.spu_save_state = expandoSPUSaveState;
-
-	return &expando_functions;
+    self->dispatch_table.spu_load_state = expandoSPULoadState;
+
+    return &expando_functions;
 }
 
@@ -66,8 +248,8 @@
 expandoSPUSelfDispatch(SPUDispatchTable *self)
 {
-	crSPUInitDispatchTable( &(expando_spu.self) );
-	crSPUCopyDispatchTable( &(expando_spu.self), self );
-
-	expando_spu.server = (CRServer *)(self->server);
+    crSPUInitDispatchTable(&(expando_spu.self));
+    crSPUCopyDispatchTable(&(expando_spu.self), self);
+
+    expando_spu.server = (CRServer *)(self->server);
 }
 
@@ -82,17 +264,15 @@
 
 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;
-}
+SPULoad(char **name, char **super, SPUInitFuncPtr *init, SPUSelfDispatchFuncPtr *self,
+    SPUCleanupFuncPtr *cleanup, SPUOptionsPtr *options, int *flags)
+{
+    *name = "expando";
+    *super = "render";
+    *init = expandoSPUInit;
+    *self = expandoSPUSelfDispatch;
+    *cleanup = expandoSPUCleanup;
+    *options = expandoSPUOptions;
+    *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+
+    return 1;
+}
