Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_hash.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_hash.h	(revision 56565)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_hash.h	(revision 56566)
@@ -21,4 +21,5 @@
 /* Callback function used for freeing/deleting table entries */
 typedef void (*CRHashtableCallback)(void *data);
+typedef void (*CRHashtableCallbackEx)(void *data1, void *data2);
 /* Callback function used for walking through table entries */
 typedef void (*CRHashtableWalkCallback)(unsigned long key, void *data1, void *data2);
@@ -39,4 +40,5 @@
 DECLEXPORT(CRHashTable *) crAllocHashtableEx( GLuint min, GLuint max );
 DECLEXPORT(void) crFreeHashtable( CRHashTable *hash, CRHashtableCallback deleteCallback );
+DECLEXPORT(void) crFreeHashtableEx( CRHashTable *hash, CRHashtableCallbackEx deleteCallback, void *pData );
 DECLEXPORT(void) crHashtableAdd( CRHashTable *h, unsigned long key, void *data );
 /* to ensure hash table pool id consistency, there is no crHashTableFreeKeys/UnregisterKey,
@@ -47,4 +49,5 @@
 DECLEXPORT(GLboolean) crHashtableAllocRegisterKey( CRHashTable *h,  GLuint key);
 DECLEXPORT(void) crHashtableDelete( CRHashTable *h, unsigned long key, CRHashtableCallback deleteCallback );
+DECLEXPORT(void) crHashtableDeleteEx( CRHashTable *h, unsigned long key, CRHashtableCallbackEx deleteCallback, void *pData );
 DECLEXPORT(void) crHashtableDeleteBlock( CRHashTable *h, unsigned long key, GLsizei range, CRHashtableCallback deleteFunc );
 DECLEXPORT(void *) crHashtableSearch( const CRHashTable *h, unsigned long key );
Index: /trunk/src/VBox/GuestHost/OpenGL/util/hash.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/hash.c	(revision 56565)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/hash.c	(revision 56566)
@@ -433,4 +433,45 @@
 }
 
+void crFreeHashtableEx(CRHashTable *hash, CRHashtableCallbackEx deleteFunc, void *pData)
+{
+    int i;
+    CRHashNode *entry, *next;
+
+    if (!hash) return;
+
+#ifdef CHROMIUM_THREADSAFE
+    crLockMutex(&hash->mutex);
+#endif
+
+    for (i = 0; i < CR_NUM_BUCKETS; i++)
+    {
+        entry = hash->buckets[i];
+        while (entry)
+        {
+            next = entry->next;
+            /* Clear the key in case crHashtableDelete() is called
+             * from this callback.
+             */
+            entry->key = 0;
+            if (deleteFunc && entry->data)
+            {
+                (*deleteFunc)(entry->data, pData);
+            }
+            crFree(entry);
+            entry = next;
+
+        }
+    }
+    crFreeHashIdPool(hash->idPool);
+
+#ifdef CHROMIUM_THREADSAFE
+    crUnlockMutex(&hash->mutex);
+    crFreeMutex(&hash->mutex);
+#endif
+
+    crFree(hash);
+}
+
+
 void crHashtableLock(CRHashTable *h)
 {
@@ -585,4 +626,39 @@
 }
 
+void crHashtableDeleteEx(CRHashTable *h, unsigned long key, CRHashtableCallbackEx deleteFunc, void *pData)
+{
+    unsigned int index = crHash( key );
+    CRHashNode *temp, *beftemp = NULL;
+
+#ifdef CHROMIUM_THREADSAFE
+    crLockMutex(&h->mutex);
+#endif
+    for (temp = h->buckets[index]; temp; temp = temp->next)
+    {
+        if (temp->key == key)
+            break;
+        beftemp = temp;
+    }
+    if (temp)
+    {
+        if (beftemp)
+            beftemp->next = temp->next;
+        else
+            h->buckets[index] = temp->next;
+        h->num_elements--;
+        if (temp->data && deleteFunc) {
+            (*deleteFunc)(temp->data, pData);
+        }
+
+        crFree(temp);
+    }
+
+    crHashIdPoolFreeBlock(h->idPool, key, 1);
+#ifdef CHROMIUM_THREADSAFE
+    crUnlockMutex(&h->mutex);
+#endif
+}
+
+
 void crHashtableDeleteBlock( CRHashTable *h, unsigned long key, GLsizei range, CRHashtableCallback deleteFunc )
 {
Index: /trunk/src/VBox/GuestHost/OpenGL/util/util.def
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/util.def	(revision 56565)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/util.def	(revision 56566)
@@ -78,4 +78,5 @@
 crHashtableAdd
 crHashtableDelete
+crHashtableDeleteEx
 crHashtableSearch
 crHashtableReplace
@@ -87,4 +88,5 @@
 crAllocHashtableEx
 crFreeHashtable
+crFreeHashtableEx
 crHashtableGetDataKey
 crDetermineEndianness
Index: /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 56566)
@@ -31,5 +31,5 @@
 
 ifeq ($(KBUILD_TARGET),darwin)
- #VBOX_WITH_CR_DISPLAY_LISTS=1
+ VBOX_WITH_CR_DISPLAY_LISTS=1
 endif
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c	(revision 56566)
@@ -40,8 +40,10 @@
 static GLuint TranslateListID( GLuint id )
 {
+#ifndef VBOX_WITH_CR_DISPLAY_LISTS
     if (!cr_server.sharedDisplayLists) {
         int client = cr_server.curClient->number;
         return id + client * 100000;
     }
+#endif
     return id;
 }
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c	(revision 56566)
@@ -49,10 +49,10 @@
     CRDLMContextState *listState = (CRDLMContextState *)tsd;
 
-    if (listState) {
-	if (listState->currentListInfo) {
-	    crdlm_free_list(listState->currentListInfo);
-	}
-
-	crFree(listState);
+    if (listState)
+    {
+        //if (listState->currentListInfo)
+        //    crdlm_free_list(listState->currentListInfo);
+
+        crFree(listState);
     }
 }
@@ -144,5 +144,5 @@
  * itself when no one is still using the DLM.
  */
-void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm)
+void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable)
 {
     /* We're about to change the displayLists hash; lock it first */
@@ -157,10 +157,5 @@
     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);
+	crFreeHashtableEx(dlm->displayLists, crdlmFreeDisplayListResourcesCb, dispatchTable);
 	dlm->displayLists = NULL;
 
@@ -269,30 +264,30 @@
  */
 
-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);
+void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state, SPUDispatchTable *dispatchTable)
+{
+    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, dispatchTable);
+    state->dlm = NULL;
+
+    /* If any buffers still remain (e.g. because there was an open
+     * display list), remove those as well.
+     */
+    if (state->currentListInfo)
+    {
+        crdlmFreeDisplayListResourcesCb((void *)state->currentListInfo, (void *)dispatchTable);
+        state->currentListInfo = NULL;
+    }
+    state->currentListIdentifier = 0;
+
+    /* Free the state record itself */
+    crFree(state);
 }
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h	(revision 56566)
@@ -26,5 +26,5 @@
  */
 extern void crdlmWarning( int line, char *file, GLenum error, char *format, ... );
-extern void crdlm_free_list(/* DLMListInfo * */ void *listInfo);
+extern void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2);
 extern void crdlm_error(int line, const char *file, GLenum error, const char *info);
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c	(revision 56566)
@@ -1,3 +1,5 @@
 /* $Id$ */
+#if 0
+
 #include <stdio.h>
 #include "cr_spu.h"
@@ -62,2 +64,4 @@
 	crdlm_add_to_list((DLMInstanceList *)instance, executeCallLists);
 }
+
+#endif
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py	(revision 56566)
@@ -16,7 +16,7 @@
 	('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', 'crDLMFreeContext', 'CRDLMContextState *state, SPUDispatchTable *dispatchTable'),
 	('void DLM_APIENTRY', 'crDLMUseDLM', 'CRDLM *dlm'),
-	('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm'),
+	('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'),
 	('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'),
 	('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'),
@@ -42,10 +42,12 @@
 	('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', 'crDLMNewList', 'GLuint list, GLenum mode, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMEndList', 'SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMCallList', 'GLuint list, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMCallLists', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMDeleteLists', 'GLuint list, GLsizei range, SPUDispatchTable *dispatchTable'),
+	('void DLM_APIENTRY', 'crDLMListBase', 'GLuint base, SPUDispatchTable *dispatchTable'),
+	('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list, SPUDispatchTable *dispatchTable'),
+	('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range, SPUDispatchTable *dispatchTable'),
 	('int32_t DLM_APIENTRY', 'crDLMSaveState', 'void'),
 	#('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
@@ -115,4 +117,5 @@
 	CRDLMBounds bbox;
 	GLboolean listSent;
+	GLuint hwid;
 } DLMListInfo;
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c	(revision 56566)
@@ -1,3 +1,25 @@
 /* $Id$ */
+
+/** @file
+ * Implementation of all the Display Lists related routines:
+ *
+ *   glGenLists, glDeleteLists, glNewList, glEndList, glCallList, glCallLists,
+ *   glListBase and glIsList.
+ *
+ * Privide OpenGL IDs mapping between host and guest.
+ */
+
+/*
+ * 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 <float.h>
 #include "cr_dlm.h"
@@ -6,272 +28,401 @@
 
 
-
-/* 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.
+/**
+ * Destroy each list entry.
+ */
+static void crdlmFreeDisplayListElements(DLMInstanceList *instance)
+{
+    while (instance)
+    {
+        DLMInstanceList *nextInstance = instance->next;
+        crFree(instance);
+        instance = nextInstance;
+    }
+}
+
+
+/**
+ * A callback routine used when iterating over all
+ * available lists in order to remove them.
+ *
+ * NOTE: @param pParam2 might be NULL.
+ */
+void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2)
+{
+    DLMListInfo      *pListInfo     = (DLMListInfo *)pParm1;
+    SPUDispatchTable *dispatchTable = (SPUDispatchTable *)pParam2;
+
+    if (pListInfo)
+    {
+        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. */
+        if (dispatchTable)
+            dispatchTable->DeleteLists(pListInfo->hwid, 1);
+
+        crFree(pListInfo);
+    }
+}
+
+
+/**
+ * Generate host and guest IDs, setup IDs mapping between host and guest.
+ */
+GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+    GLuint             idHostRangeStart = 0;
+    GLuint             idGuestRangeStart = 0;
+
+    crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0);
+
+    if (listState)
+    {
+        idHostRangeStart = dispatchTable->GenLists(range);
+        if (idHostRangeStart > 0)
+        {
+            idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range);
+            if (idGuestRangeStart > 0)
+            {
+                GLuint i;
+                bool fSuccess = true;
+
+                /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */
+                for (i = 0; i < (GLuint)range; i++)
+                {
+                    DLMListInfo *pListInfo;
+
+                    pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
+                    if (pListInfo)
+                    {
+                        crMemset(pListInfo, 0, sizeof(DLMListInfo));
+                        pListInfo->hwid = idHostRangeStart + i;
+
+                        /* Insert pre-initialized list data which contains IDs mapping into the hash. */
+                        crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL);
+                    }
+                    else
+                    {
+                        fSuccess = false;
+                        break;
+                    }
+                }
+
+                /* All structures allocated and initialized successfully. */
+                if (fSuccess)
+                    return idGuestRangeStart;
+
+                /* Rollback some data was not allocated. */
+                crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ );
+            }
+            else
+                crDebug("DLM: Can't allocate Display List IDs range for the guest.");
+
+            dispatchTable->DeleteLists(idHostRangeStart, range);
+        }
+        else
+            crDebug("DLM: Can't allocate Display List IDs range on the host side.");
+    }
+    else
+        crDebug("DLM: GenLists(%u) called with no current state.", range);
+
+    /* Can't reserve IDs range.  */
+    return 0;
+}
+
+
+/**
+ * Release host and guest IDs, free memory resources.
+ */
+void DLM_APIENTRY crDLMDeleteLists(GLuint list, GLsizei range, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: DeleteLists(%u, %d) (DLM=%p).", list, range, listState ? listState->dlm : 0);
+
+    if (listState)
+    {
+        if (range >= 0)
+        {
+            int i;
+
+            /* Free resources: host memory, host IDs and guest IDs. */
+            DLM_LOCK(listState->dlm)
+            for (i = 0; i < range; i++)
+                crHashtableDeleteEx(listState->dlm->displayLists, list + i, crdlmFreeDisplayListResourcesCb, dispatchTable);
+            DLM_UNLOCK(listState->dlm)
+        }
+        else
+            crDebug("DLM: DeleteLists(%u, %d) not allowed.", list, range);
+    }
+    else
+        crDebug("DLM: DeleteLists(%u, %d) called with no current state.", list, range);
+}
+
+
+/**
+ * Start recording 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;
-
-    crDebug("Display Lists: create new with guest ID %u.", listIdentifier);
-}
-
-
-/* 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;
-}
+crDLMNewList(GLuint list, GLenum mode, SPUDispatchTable *dispatchTable)
+{
+    DLMListInfo       *listInfo;
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: NewList(%u, %u) (DLM=%p).", list, mode, listState ? listState->dlm : 0);
+
+    if (listState)
+    {
+        /* Valid list ID should be > 0. */
+        if (list > 0)
+        {
+            if (listState->currentListInfo == NULL)
+            {
+                listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
+                if (listInfo)
+                {
+                    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.");
+                }
+                else
+                    crDebug("DLM: Requested Display List %u was not previously reserved with glGenLists().", list);
+            }
+            else
+                crDebug("DLM: NewList called with display list %u while display list %u was already open.", list, listState->currentListIdentifier);
+        }
+        else
+            crDebug("DLM: NewList called with a list identifier of 0.");
+    }
+    else
+        crDebug("DLM: NewList(%u, %u) called with no current state.\n", list, mode);
+}
+
+
+/**
+ * Stop recording a list.
+ */
+void DLM_APIENTRY crDLMEndList(SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: EndList() (DLM=%p).", listState ? listState->dlm : 0);
+
+    if (listState)
+    {
+        /* Check if list was ever started. */
+        if (listState->currentListInfo)
+        {
+            /* reset the current state to show the list had been ended */
+            listState->currentListIdentifier = 0;
+            listState->currentListInfo = NULL;
+            listState->currentListMode = GL_FALSE;
+
+            dispatchTable->EndList();
+        }
+        else
+            crDebug("DLM: glEndList() is assuming glNewList() was issued previously.");
+    } 
+    else
+        crDebug("DLM: EndList called with no current state.");
+}
+
+
+/**
+ * Execute list on hardware and cach ethis call if we currently recording a list.
+ */
+void DLM_APIENTRY crDLMCallList(GLuint list, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    //crDebug("DLM: CallList(%u).", list);
+
+    if (listState)
+    {
+        DLMListInfo *listInfo;
+
+        /* Add to calls cache if we recording a list. */
+        if (listState->currentListInfo)
+            crDLMCompileCallList(list);
+
+        /* Find hwid for list. */
+        listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
+        if (listInfo)
+            dispatchTable->CallList(listInfo->hwid);
+        else
+            crDebug("DLM: CallList(%u) issued for non-existent list.", list);
+    }
+    else
+        crDebug("DLM: CallList(%u) called with no current state.", list);
+}
+
+
+/* Helper for crDLMCallLists().
+ * We need to extract list ID by index from array of given type and cast it to GLuint.
+ * Please replece it w/ something more elegant if better solution will be found!
+ */
+inline GLuint crDLMGetListByIndex(const GLvoid *aValues, GLsizei index, GLenum type)
+{
+    GLuint element = 0;
+
+    switch (type)
+    {
+#define CRDLM_LIST_BY_INDEX_HANDLE_TYPE(_type_name, _size_of_type) \
+        case _type_name: \
+        { \
+            crMemcpy((void *)&element, (void *)((void *)(aValues) + (index * (_size_of_type))) \
+            , (_size_of_type)); \
+            break; \
+        }
+
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_BYTE,            sizeof(GLbyte));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_BYTE,   sizeof(GLubyte));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_SHORT,           sizeof(GLshort));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_SHORT,  sizeof(GLushort));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_INT,             sizeof(GLint));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_INT,    sizeof(GLuint));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_FLOAT,           sizeof(GLfloat));
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_2_BYTES,         2);
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_3_BYTES,         3);
+        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_4_BYTES,         4);
+
+        default:
+            crError("DLM: attempt to pass to crDLMCallLists() unknown type: %u.", index);
+
+#undef CRDLM_LIST_BY_INDEX_HANDLE_TYPE
+    }
+
+    return element;
+}
+
+/**
+ * Execute lists on hardware and cach ethis call if we currently recording a list.
+ */
+void DLM_APIENTRY crDLMCallLists(GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: CallLists(%d, %u, %p).", n, type, lists);
+
+    if (listState)
+    {
+        GLsizei i;
+
+        /* Add to calls cache if we recording a list. */
+        if (listState->currentListInfo)
+            crDLMCompileCallLists(n, type, lists);
+
+        /* This is sad, but we need to translate guest IDs into host ones.
+         * Since spec does not promise that @param lists conain contiguous set of IDs,
+         * the only way to do that is to iterate over each guest ID and perform translation.
+         * This might have negative performance impact. */
+        for (i = 0; i < n; i++)
+        {
+            DLMListInfo *listInfo;
+            GLuint guest_id = crDLMGetListByIndex(lists, n, type);
+
+            if (guest_id > 0)
+            {
+                listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, guest_id);
+                if (listInfo)
+                    dispatchTable->CallList(listInfo->hwid);
+                else
+                    crDebug("DLM: CallLists(%d, %u, %p) was unabbe to resolve host ID for guest ID %u.", n, type, lists, guest_id);
+            }
+            else
+                crDebug("DLM: CallLists(%d, %u, %p) received bad array of IDs.", n, type, lists);
+        }
+    }
+    else
+        crDebug("DLM: CallLists(%d, %u, %p) called with no current state.", n, type, lists);
+}
+
+
+/**
+ * Set list base, remember its value and add call to the cache.
+ */
+void DLM_APIENTRY crDLMListBase(GLuint base, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: ListBase(%u).", base);
+
+    if (listState)
+    {
+        listState->listBase = base;
+        crDLMCompileListBase(base);
+        dispatchTable->ListBase(base);
+    }
+    else
+        crDebug("DLM: ListBase(%u) called with no current state.", base);
+}
+
+
+/**
+ * Check if specified list ID belongs to valid Display List.
+ * Positive result is only returned in case both conditions below are satisfied:
+ *
+ *   - given list found in DLM hash table (i.e., it was previously allocated
+ *     with crDLMGenLists and still not released with crDLMDeleteLists);
+ *
+ *   - list is valid on the host side.
+ */
+GLboolean DLM_APIENTRY crDLMIsList(GLuint list, SPUDispatchTable *dispatchTable)
+{
+    CRDLMContextState *listState = CURRENT_STATE();
+
+    crDebug("DLM: IsList(%u).", list);
+
+    if (listState)
+    {
+        if (list > 0)
+        {
+            DLMListInfo *listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
+            if (listInfo)
+            {
+                if (dispatchTable->IsList(listInfo->hwid))
+                    return true;
+                else
+                    crDebug("DLM: list [%u, %u] not found on the host side.", list, listInfo->hwid);
+            }
+            else
+                crDebug("DLM: list %u not found in guest cache.", list);
+        }
+        else
+            crDebug("DLM: IsList(%u) is not allowed.", list);
+    }
+    else
+        crDebug("DLM: IsList(%u) called with no current state.", list);
+
+    return false;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special	(revision 56566)
@@ -11,6 +11,6 @@
 # inside display lists, we can manage state updates for
 # these sorts of elements.
-CallList
-CallLists
+#CallList
+#CallLists
 
 # Calls to be ignored.
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special	(revision 56566)
@@ -6,4 +6,5 @@
 DeleteLists
 GenLists
+ListBase
 IsList
 CallList
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c	(revision 56566)
@@ -1,7 +1,24 @@
 /* $Id$ */
+/** @file
+ * Implementation of routines which Expando SPU explicitly overrides.
+ */
+
 /* Copyright (c) 2001, Stanford University
  * All rights reserved
  *
  * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+
+/*
+ * 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.
  */
 
@@ -15,80 +32,104 @@
 expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx)
 {
-	ExpandoContextState *contextState;
-	GLint contextId;
+    ExpandoContextState *contextState;
 
-	/* Allocate our own per-context record */
-	contextState = crCalloc(sizeof(ExpandoContextState));
-	if (contextState == NULL) {
-	    crError("expando: couldn't allocate per-context state");
-	    return 0;
-	}
+    /* Allocate our own per-context record */
+    contextState = crCalloc(sizeof(ExpandoContextState));
+    if (contextState)
+    {
+        GLint contextId;
 
-	/* Get an official context ID from our super */
-	contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx);
+        /* 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!");
-	}
+        /* 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)
+        {
+            contextState->dlmContext = crDLMNewContext(contextState->dlm);
+            if (contextState->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);
 
-	contextState->dlmContext = crDLMNewContext(contextState->dlm);
-	if (!contextState->dlmContext) {
-		crError("expando: couldn't get dlmContext");
-	}
+                /* Associate the Expando context with the user context. */
+                crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
 
-	/* 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);
+                crDebug("Expando SPU: created context %d (contextState=%p, contextState->dlm=%p, "
+                        "contextState->dlmContext=%p, contextState->State=%p).",
+                        contextId, contextState, contextState->dlm, contextState->dlmContext, contextState->State);
 
-	/* Associate the Expando context with the user context. */
-	crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
+                return contextId;
+            }
+            else
+                crError("Expando SPU: can't allocate new DLM context.");
 
-	return contextId;
+            crDLMFreeDLM(contextState->dlm, &expando_spu.super);
+        }
+        else
+            crError("Expando SPU: can't allocate new DLM.");
+
+        crFree(contextState);
+    }
+    else
+        crError("Expando SPU: couldn't allocate per-context state");
+
+    return 0;
 }
 
 void expando_free_context_state(void *data)
 {
-    ExpandoContextState *expandoContextState = (ExpandoContextState *)data;
+    ExpandoContextState *contextState = (ExpandoContextState *)data;
 
-    crDLMFreeContext(expandoContextState->dlmContext);
-    crDLMFreeDLM(expandoContextState->dlm);
-    crStateDestroyContext(expandoContextState->State);
-    crFree(expandoContextState);
+    crDebug("Expando SPU: destroying context internals: "
+            "contextState=%p, contextState->dlm=%p, contextState->dlmContext=%p, contextState->State=%p",
+            contextState, contextState->dlm, contextState->dlmContext, contextState->State);
+
+    crDLMFreeContext(contextState->dlmContext, &expando_spu.super);
+    crDLMFreeDLM(contextState->dlm, &expando_spu.super);
+    crStateDestroyContext(contextState->State);
+    crFree(contextState);
 }
 
-extern void EXPANDOSPU_APIENTRY
+void EXPANDOSPU_APIENTRY
 expandoDestroyContext(GLint contextId)
 {
-	/* Destroy our context information */
-	crHashtableDelete(expando_spu.contextTable, contextId, 
-				expando_free_context_state);
+    crDebug("Expando SPU: destroy context %d.", contextId);
 
-	/* Pass along the destruction to our super. */
-	expando_spu.super.DestroyContext(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
+void EXPANDOSPU_APIENTRY
 expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId)
 {
-	ExpandoContextState *expandoContextState;
+    ExpandoContextState *expandoContextState;
 
-	expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId);
+    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);
-	}
+    expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId);
+    if (expandoContextState)
+    {
+        crDebug("Expando SPU: switch to context %d.", contextId);
+
+        crDLMSetCurrentState(expandoContextState->dlmContext);
+        crStateMakeCurrent(expandoContextState->State);
+    }
+    else
+    {
+        crDebug("Expando SPU: can't switch to context %d: not found.", contextId);
+
+        crDLMSetCurrentState(NULL);
+        crStateMakeCurrent(NULL);
+    }
 }
 
@@ -96,6 +137,5 @@
 expandoNewList(GLuint list, GLenum mode)
 {
-    crDebug("Expando SPU: expandoNewList()");
-	crDLMNewList(list, mode);
+    crDLMNewList(list, mode, &expando_spu.super);
 }
 
@@ -103,6 +143,5 @@
 expandoEndList(void)
 {
-    crDebug("Expando SPU: expandoEndList()");
-	crDLMEndList();
+    crDLMEndList(&expando_spu.super);
 }
 
@@ -110,5 +149,5 @@
 expandoDeleteLists(GLuint first, GLsizei range)
 {
-	crDLMDeleteLists(first, range);
+    crDLMDeleteLists(first, range, &expando_spu.super);
 }
 
@@ -116,5 +155,11 @@
 expandoGenLists(GLsizei range)
 {
-	 return crDLMGenLists(range);
+    return crDLMGenLists(range, &expando_spu.super);
+}
+
+void EXPANDOSPU_APIENTRY
+expandoListBase(GLuint base)
+{
+    crDLMListBase(base, &expando_spu.super);
 }
 
@@ -122,5 +167,5 @@
 expandoIsList(GLuint list)
 {
-	 return crDLMIsList(list);
+    return crDLMIsList(list, &expando_spu.super);
 }
 
@@ -128,16 +173,5 @@
 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);
+    crDLMCallList(list, &expando_spu.super);
 }
 
@@ -145,14 +179,4 @@
 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);
+    crDLMCallLists(n, type, lists, &expando_spu.super);
 }
Index: /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h	(revision 56565)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h	(revision 56566)
@@ -62,4 +62,5 @@
 extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range);
 extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range);
+extern void EXPANDOSPU_APIENTRY expandoListBase(GLuint base);
 extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list);
 extern  void EXPANDOSPU_APIENTRY expandoCallList(GLuint list);
