Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 46887)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 46966)
@@ -140,10 +140,19 @@
 }
 
-void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData)
-{
-    CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData);
+#define PCR_DISPLAY_ENTRY_FROM_CENTRY(_pe) ((PCR_DISPLAY_ENTRY)((uint8_t*)(_pe) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
+static DECLCALLBACK(void) crDpEntryCEntryReleaseCB(const struct VBOXVR_SCR_COMPOSITOR *pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pReplacingEntry)
+{
+    PCR_DISPLAY_ENTRY pCEntry = PCR_DISPLAY_ENTRY_FROM_CENTRY(pEntry);
+    CrDemEntryRelease(pCEntry);
+}
+
+void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, void *pvUserData1, void *pvUserData2)
+{
+    CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData, crDpEntryCEntryReleaseCB);
     CrVrScrCompositorEntryFlagsSet(&pEntry->CEntry, CRBLT_F_INVERT_SRC_YCOORDS);
-    CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData);
+    CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData, NULL);
     CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, CRBLT_F_INVERT_SRC_YCOORDS);
+    pEntry->pvUserData1 = pvUserData1;
+    pEntry->pvUserData2 = pvUserData2;
 }
 
@@ -175,10 +184,66 @@
 }
 
+void crDemEntryRelease(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY pEntry, bool fForceDelete)
+{
+    CRTextureObj *pTobj = (CRTextureObj *)pEntry->pvUserData2;
+    if (!pTobj)
+    {
+        crWarning("Trying to release entry that does not have tobj specified");
+        return;
+    }
+
+    CR_STATE_SHAREDOBJ_USAGE_CLEAR(pTobj, cr_server.MainContextInfo.pContext);
+
+    bool fDeleteEntry = fForceDelete;
+    GLuint idTexture = pTobj->id;
+
+    if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj))
+    {
+        CRSharedState *pShared = crStateGlobalSharedAcquire();
+
+        CRASSERT(pShared);
+        /* on the host side, we need to delete an ogl texture object here as well, which crStateDeleteTextureCallback will do
+         * in addition to calling crStateDeleteTextureObject to delete a state object */
+        crHashtableDelete(pShared->textureTable, idTexture, crStateDeleteTextureCallback);
+
+        crStateGlobalSharedRelease();
+
+        fDeleteEntry = true;
+    }
+    else
+    {
+        /* this is something we would not generally expect */
+        CRASSERT(!fForceDelete);
+    }
+
+    if (fDeleteEntry)
+    {
+        if (pMap)
+            crHashtableDelete(pMap->pTextureMap, idTexture, crFree);
+        else
+            crFree(pEntry); /* <- when called from crDemTermEntryCb */
+
+        crStateGlobalSharedRelease();
+    }
+}
+
+void crDemTermEntryCb(void *pvEntry)
+{
+    crDemEntryRelease(NULL, (PCR_DISPLAY_ENTRY)pvEntry, true);
+}
+
 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
 {
-    crFreeHashtable(pMap->pTextureMap, crFree);
-}
-
-PCR_DISPLAY_ENTRY CrDemEntryGetCreate(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture, CRContextInfo *pCtxInfo)
+    crFreeHashtable(pMap->pTextureMap, crDemTermEntryCb);
+}
+
+void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry)
+{
+    PCR_DISPLAY_ENTRY_MAP pMap = (PCR_DISPLAY_ENTRY_MAP)pEntry->pvUserData1;
+    Assert(pMap);
+    crDemEntryRelease(pMap, pEntry, false);
+}
+
+PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
 {
     PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
@@ -186,17 +251,20 @@
         return pEntry;
 
-    CRContext *pContext = pCtxInfo->pContext;
-    if (!pContext)
-    {
-        crWarning("pContext is null!");
+    CRSharedState *pShared = crStateGlobalSharedAcquire();
+    if (!pShared)
+    {
+        crWarning("pShared is null!");
         return NULL;
     }
 
-    CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pContext->shared->textureTable, idTexture);
+    CRTextureObj *pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, idTexture);
     if (!pTobj)
     {
         crWarning("pTobj is null!");
+        crStateGlobalSharedRelease();
         return NULL;
     }
+
+    Assert(pTobj->id == idTexture);
 
     GLuint hwId = crStateGetTextureObjHWID(pTobj);
@@ -204,4 +272,5 @@
     {
         crWarning("hwId is null!");
+        crStateGlobalSharedRelease();
         return NULL;
     }
@@ -217,8 +286,12 @@
     {
         crWarning("crAlloc failed allocating CR_DISPLAY_ENTRY");
+        crStateGlobalSharedRelease();
         return NULL;
     }
 
-    CrDpEntryInit(pEntry, &TextureData);
+    CrDpEntryInit(pEntry, &TextureData, pMap, pTobj);
+
+    /* just use main context info's context to hold the texture reference */
+    CR_STATE_SHAREDOBJ_USAGE_SET(pTobj, cr_server.MainContextInfo.pContext);
 
     crHashtableAdd(pMap->pTextureMap, idTexture, pEntry);
@@ -226,5 +299,5 @@
 
 }
-
+#if 0
 void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
 {
@@ -243,5 +316,5 @@
     crHashtableDelete(pMap->pTextureMap, idTexture, crFree);
 }
-
+#endif
 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
 {
@@ -412,8 +485,8 @@
     if (texture)
     {
-        pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
+        pEntry = CrDemEntryAcquire(&cr_server.PresentTexturepMap, texture);
         if (!pEntry)
         {
-            crWarning("CrDemEntryGetCreate Failed");
+            crWarning("CrDemEntryAcquire Failed");
             return;
         }
@@ -428,5 +501,7 @@
         if (!RT_SUCCESS(rc))
         {
-            crWarning("CrDpEntrySetRegions Failed rc %d", rc);
+            crWarning("CrDpEntryRegionsAdd Failed rc %d", rc);
+//            if (pEntry)
+//                CrDemEntryRelease(pEntry);
             return;
         }
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46887)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46966)
@@ -55,9 +55,9 @@
         Tex.target = GL_TEXTURE_2D;
         Tex.hwid = 0;
-        CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex);
+        CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex, NULL);
 
         if (cr_server.fRootVrOn)
         {
-            CrVrScrCompositorEntryInit(&mural->DefaultDEntry.RootVrCEntry, &Tex);
+            CrVrScrCompositorEntryInit(&mural->DefaultDEntry.RootVrCEntry, &Tex, NULL);
             mural->fRootVrOn = GL_TRUE;
         }
@@ -407,5 +407,5 @@
 {
     CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
-    CrVrScrCompositorEntryInit(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(pEntry));
+    CrVrScrCompositorEntryInit(&pDEntry->RootVrCEntry, CrVrScrCompositorEntryTexGet(pEntry), NULL);
     return &pDEntry->RootVrCEntry;
 }
@@ -416,4 +416,8 @@
 
     crServerVBoxRootVrTranslateForMural(mural);
+
+    /* ensure the rootvr compositor does not hold any data,
+     * i.e. cleanup all rootvr entries data */
+    CrVrScrCompositorClear(&mural->RootVrCompositor);
 
     rc = CrVrScrCompositorIntersectedList(&mural->Compositor, &cr_server.RootVr, &mural->RootVrCompositor, crServerMuralGetRootVrCEntry, NULL, NULL);
@@ -468,5 +472,5 @@
                 goto end;
             }
-            CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex);
+            CrVrScrCompositorEntryInit(&mural->DefaultDEntry.CEntry, &Tex, NULL);
             /* initially set regions to all visible since this is what some guest assume
              * and will not post any more visible regions command */
