Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 44105)
@@ -60,4 +60,6 @@
 # define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) (ASMBitClear((_pObj)->ctxUsage, (_pCtx)->id))
 # define CR_STATE_SHAREDOBJ_USAGE_IS_USED(_pObj) (ASMBitFirstSet((_pObj)->ctxUsage, sizeof ((_pObj)->ctxUsage)<<3) >= 0)
+# define CR_STATE_SHAREDOBJ_USAGE_GET_FIRST_USED_IDX(_pObj) (ASMBitFirstSet((_pObj)->ctxUsage, sizeof ((_pObj)->ctxUsage)<<3))
+# define CR_STATE_SHAREDOBJ_USAGE_GET_NEXT_USED_IDX(_pObj, _i) (ASMBitNextSet((_pObj)->ctxUsage, sizeof ((_pObj)->ctxUsage)<<3, (_i)))
 #else
 # define CR_STATE_SHAREDOBJ_USAGE_INIT(_pObj) do {} while (0)
@@ -65,5 +67,8 @@
 # define CR_STATE_SHAREDOBJ_USAGE_CLEAR(_pObj, _pCtx) do {} while (0)
 # define CR_STATE_SHAREDOBJ_USAGE_IS_USED(_pObj) (GL_FALSE)
-#endif
+# define CR_STATE_SHAREDOBJ_USAGE_GET_FIRST_USED_IDX(_pObj) (-1)
+# define CR_STATE_SHAREDOBJ_USAGE_GET_NEXT_USED_IDX(_pObj, _i) (-1)
+#endif
+# define CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(_pObj, _i) for (((int)(_i)) = CR_STATE_SHAREDOBJ_USAGE_GET_FIRST_USED_IDX(_pObj); ((int)(_i)) >= 0; ((int)(_i)) = CR_STATE_SHAREDOBJ_USAGE_GET_NEXT_USED_IDX((_pObj), ((int)(_i))))
 
 #define CR_MAX_EXTENTS 256
@@ -241,5 +246,4 @@
 typedef FNCRSTATE_CONTEXT_GET *PFNCRSTATE_CONTEXT_GET;
 DECLEXPORT(int32_t) crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PFNCRSTATE_CONTEXT_GET pfnCtxGet, PSSMHANDLE pSSM, uint32_t u32Version);
-DECLEXPORT(void)    crStateFreeShared(CRContext *pContext, CRSharedState *s);
 DECLEXPORT(void) crStateFreeShared(CRContext *pContext, CRSharedState *s);
 #endif
Index: /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_client.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_client.h	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_client.h	(revision 44105)
@@ -128,6 +128,6 @@
 DECLEXPORT(void) crStateClientInitBits(CRClientBits *c);
 DECLEXPORT(void) crStateClientDestroyBits(CRClientBits *c);
-DECLEXPORT(void) crStateClientInit(CRClientState *c);
-DECLEXPORT(void) crStateClientDestroy(CRClientState *c);
+DECLEXPORT(void) crStateClientInit(struct CRContext *g);
+DECLEXPORT(void) crStateClientDestroy(struct CRContext *g);
 
 DECLEXPORT(GLboolean) crStateUseServerArrays(void);
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 44105)
@@ -44,4 +44,8 @@
 #endif
 
+extern GLboolean g_bVBoxEnableDiffOnMakeCurrent;
+
+extern CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS];
+
 extern void crStateTextureInitTextureObj (CRContext *ctx, CRTextureObj *tobj, GLuint name, GLenum target);
 extern void crStateTextureInitTextureFormat( CRTextureLevel *tl, GLenum internalFormat );
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c	(revision 44105)
@@ -115,5 +115,5 @@
     b->arrayBuffer = b->nullBuffer;
     b->elementsBuffer = b->nullBuffer;
-    b->nullBuffer->refCount = 3;
+    b->nullBuffer->refCount += 2;
 #ifdef CR_ARB_pixel_buffer_object
     b->packBuffer = b->nullBuffer;
@@ -272,12 +272,78 @@
 }
 
+static void ctStateBuffersRefsCleanup(CRContext *ctx, CRBufferObject *obj, CRbitvalue *neg_bitid)
+{
+    CRBufferObjectState *b = &(ctx->bufferobject);
+    CRStateBits *sb = GetCurrentBits();
+    CRBufferObjectBits *bb = &(sb->bufferobject);
+    int j, k;
+
+    if (obj == b->arrayBuffer)
+    {
+        b->arrayBuffer = b->nullBuffer;
+        b->arrayBuffer->refCount++;
+        DIRTY(bb->dirty, neg_bitid);
+        DIRTY(bb->arrayBinding, neg_bitid);
+    }
+    if (obj == b->elementsBuffer)
+    {
+        b->elementsBuffer = b->nullBuffer;
+        b->elementsBuffer->refCount++;
+        DIRTY(bb->dirty, neg_bitid);
+        DIRTY(bb->elementsBinding, neg_bitid);
+    }
+#ifdef CR_ARB_pixel_buffer_object
+    if (obj == b->packBuffer)
+    {
+        b->packBuffer = b->nullBuffer;
+        b->packBuffer->refCount++;
+        DIRTY(bb->dirty, neg_bitid);
+        DIRTY(bb->packBinding, neg_bitid);
+    }
+    if (obj == b->unpackBuffer)
+    {
+        b->unpackBuffer = b->nullBuffer;
+        b->unpackBuffer->refCount++;
+        DIRTY(bb->dirty, neg_bitid);
+        DIRTY(bb->unpackBinding, neg_bitid);
+    }
+#endif
+
+#ifdef CR_ARB_vertex_buffer_object
+    for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
+    {
+        CRClientPointer *cp = crStateGetClientPointerByIndex(j, &ctx->client.array);
+        if (obj == cp->buffer)
+        {
+            cp->buffer = b->nullBuffer;
+            ++b->nullBuffer->refCount;
+        }
+    }
+
+    for (k=0; k<ctx->client.vertexArrayStackDepth; ++k)
+    {
+        CRVertexArrays *pArray = &ctx->client.vertexArrayStack[k];
+        for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
+        {
+            CRClientPointer *cp = crStateGetClientPointerByIndex(j, pArray);
+            if (obj == cp->buffer)
+            {
+                cp->buffer = b->nullBuffer;
+                ++b->nullBuffer->refCount;
+            }
+        }
+    }
+#endif
+
+#ifndef IN_GUEST
+    CR_STATE_SHAREDOBJ_USAGE_CLEAR(obj, ctx);
+#endif
+}
+
 void STATE_APIENTRY
 crStateDeleteBuffersARB(GLsizei n, const GLuint *buffers)
 {
     CRContext *g = GetCurrentContext();
-    CRBufferObjectState *b = &(g->bufferobject);
-    CRStateBits *sb = GetCurrentBits();
-    CRBufferObjectBits *bb = &(sb->bufferobject);
-    int i, j, k;
+    int i;
 
     FLUSH();
@@ -300,60 +366,16 @@
                 crHashtableSearch(g->shared->buffersTable, buffers[i]);
             if (obj) {
-                if (obj == b->arrayBuffer) 
+                int j;
+
+                ctStateBuffersRefsCleanup(g, obj, g->neg_bitid);
+
+                CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(obj, j)
                 {
-                    b->arrayBuffer = b->nullBuffer;
-                    b->arrayBuffer->refCount++;
-                    DIRTY(bb->dirty, g->neg_bitid);
-                    DIRTY(bb->arrayBinding, g->neg_bitid);
-                } 
-                else if (obj == b->elementsBuffer) 
-                {
-                    b->elementsBuffer = b->nullBuffer;
-                    b->elementsBuffer->refCount++;
-                    DIRTY(bb->dirty, g->neg_bitid);
-                    DIRTY(bb->elementsBinding, g->neg_bitid);
+                    CRContext *ctx = g_pAvailableContexts[j];
+                    CRASSERT(ctx);
+                    ctStateBuffersRefsCleanup(ctx, obj, g->neg_bitid); /* <- yes, use g->neg_bitid, i.e. neg_bitid of the current context to ensure others bits get dirtified,
+                                                                        * but not the current context ones*/
                 }
-#ifdef CR_ARB_pixel_buffer_object
-                else if (obj == b->packBuffer) 
-                {
-                    b->packBuffer = b->nullBuffer;
-                    b->packBuffer->refCount++;
-                    DIRTY(bb->dirty, g->neg_bitid);
-                    DIRTY(bb->packBinding, g->neg_bitid);
-                }
-                else if (obj == b->unpackBuffer) 
-                {
-                    b->unpackBuffer = b->nullBuffer;
-                    b->unpackBuffer->refCount++;
-                    DIRTY(bb->dirty, g->neg_bitid);
-                    DIRTY(bb->unpackBinding, g->neg_bitid);
-                }
-#endif
-
-#ifdef CR_ARB_vertex_buffer_object
-                for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
-                {
-                    CRClientPointer *cp = crStateGetClientPointerByIndex(j, &g->client.array);
-                    if (obj == cp->buffer)
-                    {
-                        cp->buffer = b->nullBuffer;
-                        ++b->nullBuffer->refCount;
-                    }
-                }
-
-                for (k=0; k<g->client.vertexArrayStackDepth; ++k)
-                {
-                    CRVertexArrays *pArray = &g->client.vertexArrayStack[k];
-                    for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
-                    {
-                        CRClientPointer *cp = crStateGetClientPointerByIndex(j, pArray);
-                        if (obj == cp->buffer)
-                        {
-                            cp->buffer = b->nullBuffer;
-                            ++b->nullBuffer->refCount;
-                        }
-                    }
-                }
-#endif
+
                 crHashtableDelete(g->shared->buffersTable, buffers[i], crStateFreeBufferObject);
             }
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c	(revision 44105)
@@ -84,6 +84,7 @@
 }
 
-void crStateClientDestroy(CRClientState *c)
-{
+void crStateClientDestroy(CRContext *g)
+{
+    CRClientState *c = &(g->client);
 #ifdef CR_EXT_compiled_vertex_array
     if (c->array.locked)
@@ -110,7 +111,7 @@
 }
 
-void crStateClientInit(CRClientState *c) 
-{
-    CRContext *g = GetCurrentContext();
+void crStateClientInit(CRContext *g)
+{
+    CRClientState *c = &(g->client);
     unsigned int i;
 
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 44105)
@@ -18,5 +18,5 @@
 
 CRStateBits *__currentBits = NULL;
-GLboolean g_availableContexts[CR_MAX_CONTEXTS];
+CRContext *g_pAvailableContexts[CR_MAX_CONTEXTS];
 
 static CRSharedState *gSharedState=NULL;
@@ -24,5 +24,5 @@
 static CRContext *defaultContext = NULL;
 
-static GLboolean g_bVBoxEnableDiffOnMakeCurrent = GL_TRUE;
+GLboolean g_bVBoxEnableDiffOnMakeCurrent = GL_TRUE;
 
 
@@ -219,9 +219,22 @@
                                              GLint visBits, CRContext *shareCtx)
 {
-    CRContext *ctx = (CRContext *) crCalloc( sizeof( *ctx ) );
+    CRContext *ctx;
     int j;
     int node32 = i >> 5;
     int node = i & 0x1f;
 
+    if (g_pAvailableContexts[i] != NULL)
+    {
+        crWarning("trying to create context with used id");
+        return NULL;
+    }
+
+    ctx = (CRContext *) crCalloc( sizeof( *ctx ) );
+    if (!ctx)
+    {
+        crWarning("failed to allocate context");
+        return NULL;
+    }
+    g_pAvailableContexts[i] = ctx;
     ctx->id = i;
 #ifdef CHROMIUM_THREADSAFE
@@ -253,5 +266,5 @@
 
     crStateBufferObjectInit( ctx ); /* must precede client state init! */
-    crStateClientInit( &(ctx->client) );
+    crStateClientInit( ctx );
 
     crStateBufferInit( ctx );
@@ -331,5 +344,9 @@
 crStateFreeContext(CRContext *ctx)
 {
-    crStateClientDestroy( &(ctx->client) );
+    CRASSERT(g_pAvailableContexts[ctx->id] == ctx);
+    if (ctx->id || ctx == defaultContext)
+        g_pAvailableContexts[ctx->id] = NULL;
+
+    crStateClientDestroy( ctx );
     crStateLimitsDestroy( &(ctx->limits) );
     crStateBufferObjectDestroy( ctx );
@@ -381,5 +398,5 @@
 
     for (i=0;i<CR_MAX_CONTEXTS;i++)
-        g_availableContexts[i] = 0;
+        g_pAvailableContexts[i] = NULL;
 
 #ifdef CHROMIUM_THREADSAFE
@@ -413,7 +430,7 @@
 
     /* Allocate the default/NULL context */
+    CRASSERT(g_pAvailableContexts[0] == NULL);
     defaultContext = crStateCreateContextId(0, NULL, CR_RGB_BIT, NULL);
-    CRASSERT(g_availableContexts[0] == 0);
-    g_availableContexts[0] = 1; /* in use forever */
+    g_pAvailableContexts[0] = defaultContext; /* in use forever */
 
 #ifdef CHROMIUM_THREADSAFE
@@ -426,4 +443,5 @@
 void crStateDestroy(void)
 {
+    int i;
     if (__currentBits)
     {
@@ -433,4 +451,23 @@
         __currentBits = NULL;
     }
+
+    SetCurrentContext(NULL);
+
+    for (i = CR_MAX_CONTEXTS-1; i >= 0; i--)
+    {
+        if (g_pAvailableContexts[i])
+        {
+#ifdef CHROMIUM_THREADSAFE
+            if (VBoxTlsRefIsFunctional(g_pAvailableContexts[i]))
+                VBoxTlsRefRelease(g_pAvailableContexts[i]);
+#else
+            crStateFreeContext(g_pAvailableContexts[i]);
+#endif
+        }
+    }
+
+    /* default context was stored in g_pAvailableContexts[0], so it was destroyed already */
+    defaultContext = NULL;
+
 
 #ifdef CHROMIUM_THREADSAFE
@@ -486,33 +523,44 @@
 crStateCreateContext(const CRLimitsState *limits, GLint visBits, CRContext *share)
 {
-    int i;
-
+    return crStateCreateContextEx(limits, visBits, share, -1);
+}
+
+CRContext *
+crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID)
+{
     /* Must have created the default context via crStateInit() first */
     CRASSERT(defaultContext);
 
-    for (i = 1 ; i < CR_MAX_CONTEXTS ; i++)
-    {
-        if (!g_availableContexts[i])
-        {
-            g_availableContexts[i] = 1; /* it's no longer available */
-            return crStateCreateContextId( i, limits, visBits, share );
-        }
-    }
-    crError( "Out of available contexts in crStateCreateContexts (max %d)",
-                     CR_MAX_CONTEXTS );
-    /* never get here */
-    return NULL;
-}
-
-CRContext *
-crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID)
-{
     if (presetID>0)
     {
-        CRASSERT(!g_availableContexts[presetID]);
-        g_availableContexts[presetID] = 1;
-        return crStateCreateContextId(presetID, limits, visBits, share);
-    }
-    else return crStateCreateContext(limits, visBits, share);
+        if(g_pAvailableContexts[presetID])
+        {
+            crWarning("requesting to create context with already allocated id");
+            return NULL;
+        }
+    }
+    else
+    {
+        int i;
+
+        for (i = 1 ; i < CR_MAX_CONTEXTS ; i++)
+        {
+            if (!g_pAvailableContexts[i])
+            {
+                presetID = i;
+                break;
+            }
+        }
+
+        if (presetID<=0)
+        {
+            crError( "Out of available contexts in crStateCreateContexts (max %d)",
+                             CR_MAX_CONTEXTS );
+            /* never get here */
+            return NULL;
+        }
+    }
+
+    return crStateCreateContextId(presetID, limits, visBits, share);
 }
 
@@ -536,7 +584,7 @@
         crStateMatrixMode(defaultContext->transform.matrixMode);
     }
-    g_availableContexts[ctx->id] = 0;
-
-#ifdef CHROMIUM_THREADSAFE
+
+#ifdef CHROMIUM_THREADSAFE
+    VBoxTlsRefMarkDestroy(ctx);
     VBoxTlsRefRelease(ctx);
 #else
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c	(revision 44104)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c	(revision 44105)
@@ -736,4 +736,5 @@
     }
 
+    CR_STATE_SHAREDOBJ_USAGE_CLEAR(tObj, g);
 }
 
@@ -769,5 +770,13 @@
         if (name && tObj)
         {
+            GLuint j;
+
             crStateCleanupTextureRefs(g, tObj);
+
+            CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(tObj, j)
+            {
+                CRContext *ctx = g_pAvailableContexts[j];
+                crStateCleanupTextureRefs(ctx, tObj);
+            }
 
             /* on the host side, ogl texture object is deleted by a separate cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures);
@@ -875,6 +884,4 @@
         CRTextureBits *tb = &(sb->texture);
         CRTextureState *t = &(g->texture);
-
-        CR_STATE_SHAREDOBJ_USAGE_CLEAR(tobj, g);
 
         crStateCleanupTextureRefs(g, tobj);
