Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 47566)
@@ -893,5 +893,5 @@
     }
 
-#if 1 //ndef DEBUG_misha
+#ifndef DEBUG_misha
     /* zero it up temporary to avoid new code activation */
     g_VBoxMpCrHostCaps = 0;
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp	(revision 47566)
@@ -242,5 +242,5 @@
 }
 
-PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc)
 {
     return vboxWddmSwapchainRetainByAllocData(pDevExt, &pAlloc->AllocData);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h	(revision 47566)
@@ -74,5 +74,5 @@
 BOOLEAN vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain);
 VOID vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain);
-PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc);
+PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOCATION *pAlloc);
 PVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAllocData(PVBOXMP_DEVEXT pDevExt, const struct VBOXWDDM_ALLOC_DATA *pAllocData);
 VOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp	(revision 47566)
@@ -992,9 +992,9 @@
         VBOXMP_CRPACKER *pCrPacker,
         uint32_t u32CrConClientID,
-        const VBOXWDDM_ALLOC_DATA *pSrcAllocData,
-        const VBOXWDDM_ALLOC_DATA *pDstAllocData,
+        const VBOXWDDM_ALLOCATION *pSrcAlloc,
+        const VBOXWDDM_ALLOCATION *pDstAlloc,
         const RECT *pSrcRect, const VBOXVDMAPIPE_RECTS *pDstRects)
 {
-    D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId = pDstAllocData->SurfDesc.VidPnSourceId;
+    D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId = pDstAlloc->AllocData.SurfDesc.VidPnSourceId;
     VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[srcId];
     NTSTATUS Status = STATUS_SUCCESS;
@@ -1003,5 +1003,5 @@
     {
         /* we care only about screen regions */
-        if (pDstAllocData != &pSource->pPrimaryAllocation->AllocData)
+        if (pDstAlloc != pSource->pPrimaryAllocation)
         {
             WARN(("non-primary allocation passed to vboxWddmSubmitBltCmd!"));
@@ -1009,5 +1009,5 @@
         }
 
-        uint32_t hostID = pSrcAllocData->hostID;
+        uint32_t hostID = pSrcAlloc->AllocData.hostID;
         int rc;
         if (hostID)
@@ -1029,5 +1029,5 @@
                 WARN(("vboxVdmaTexPresentSubmit failed Status 0x%x", Status));
         }
-        else if (&pSource->pPrimaryAllocation->AllocData == pDstAllocData)
+        else if (pSource->pPrimaryAllocation == pDstAlloc)
         {
             bool fChanged = false;
@@ -1049,6 +1049,6 @@
                                 if (Rect.xLeft == 0
                                         && Rect.yTop == 0
-                                        && Rect.xRight == pDstAllocData->SurfDesc.width
-                                        && Rect.yBottom == pDstAllocData->SurfDesc.height)
+                                        && Rect.xRight == pDstAlloc->AllocData.SurfDesc.width
+                                        && Rect.yBottom == pDstAlloc->AllocData.SurfDesc.height)
                                 {
                                     pSource->fHas3DVrs = FALSE;
@@ -1072,10 +1072,10 @@
     else
     {
-        PVBOXWDDM_SWAPCHAIN pSwapchain = vboxWddmSwapchainRetainByAllocData(pDevExt, pSrcAllocData);
+        PVBOXWDDM_SWAPCHAIN pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
 
         if (pSwapchain)
         {
-            Assert(pSrcAllocData->SurfDesc.width == pSwapchain->width);
-            Assert(pSrcAllocData->SurfDesc.height == pSwapchain->height);
+            Assert(pSrcAlloc->AllocData.SurfDesc.width == pSwapchain->width);
+            Assert(pSrcAlloc->AllocData.SurfDesc.height == pSwapchain->height);
         }
 
@@ -1091,5 +1091,5 @@
 }
 
-NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData)
+NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc)
 {
     VBOXMP_CRPACKER CrPacker;
@@ -1107,6 +1107,6 @@
     Rect.left = 0;
     Rect.top = 0;
-    Rect.right = pAllocData->SurfDesc.width;
-    Rect.bottom = pAllocData->SurfDesc.height;
+    Rect.right = pRealFbAlloc->AllocData.SurfDesc.width;
+    Rect.bottom = pRealFbAlloc->AllocData.SurfDesc.height;
 
     VBOXVDMAPIPE_RECTS RectInfo;
@@ -1116,5 +1116,5 @@
 
     return vboxVdmaProcessVReg(pDevExt, &CrPacker, u32CrConClientID,
-            pAllocData, pAllocData,
+            pRealFbAlloc, pRealFbAlloc,
             &Rect, &RectInfo);
 }
@@ -1126,5 +1126,5 @@
 {
     return vboxVdmaProcessVReg(pDevExt, &pContext->CrPacker, pContext->u32CrConClientID,
-            &pSrcAllocInfo->pAlloc->AllocData, &pDstAllocInfo->pAlloc->AllocData,
+            pSrcAllocInfo->pAlloc, pDstAllocInfo->pAlloc,
             pSrcRect, pDstRects);
 }
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h	(revision 47566)
@@ -334,5 +334,5 @@
 NTSTATUS vboxVdmaProcessClrFillCmd(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, struct VBOXWDDM_DMA_PRIVATEDATA_CLRFILL *pCF);
 
-NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData);
+NTSTATUS vboxVdmaTexPresentSetAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc);
 
 #endif /* #ifndef ___VBoxMPVdma_h___ */
Index: trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 47565)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 47566)
@@ -270,5 +270,5 @@
 }
 
-NTSTATUS vboxWddmGhDisplaySetInfo(PVBOXMP_DEVEXT pDevExt, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos)
+NTSTATUS vboxWddmGhDisplaySetInfo(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pRealFbAlloc, const VBOXWDDM_ALLOC_DATA *pAllocData, const POINT * pVScreenPos)
 {
     NTSTATUS Status = vboxWddmGhDisplaySetMode(pDevExt, pAllocData);
@@ -283,5 +283,5 @@
                 if (pDevExt->f3DEnabled)
                 {
-                    Status = vboxVdmaTexPresentSetAlloc(pDevExt, pAllocData);
+                    Status = vboxVdmaTexPresentSetAlloc(pDevExt, pRealFbAlloc);
                     if (NT_SUCCESS(Status))
                         return STATUS_SUCCESS;
@@ -311,4 +311,5 @@
     char fGhSynced = 1;
     PVBOXWDDM_ALLOCATION pFbAlloc = VBOXWDDM_FB_ALLOCATION(pDevExt, pSource);
+    PVBOXWDDM_ALLOCATION pRealFbAlloc = pSource->pPrimaryAllocation;
 #ifdef VBOXWDDM_RENDER_FROM_SHADOW
 # ifdef VBOX_WDDM_WIN8
@@ -339,5 +340,5 @@
     Assert(!pFbAlloc || pFbAlloc->AllocData.Addr.SegmentId == pSource->AllocData.Addr.SegmentId);
 
-    NTSTATUS Status = vboxWddmGhDisplaySetInfo(pDevExt, pFbAlloc ? &pFbAlloc->AllocData : &pSource->AllocData, &pSource->VScreenPos);
+    NTSTATUS Status = vboxWddmGhDisplaySetInfo(pDevExt, pRealFbAlloc, pFbAlloc ? &pFbAlloc->AllocData : &pSource->AllocData, &pSource->VScreenPos);
     if (NT_SUCCESS(Status))
         pSource->fGhSynced = fGhSynced;
@@ -1428,4 +1429,8 @@
         uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
         bOur = (flags & HGSMIHOSTFLAGS_IRQ);
+
+        if (bOur)
+            VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
+
         do
         {
@@ -1559,5 +1564,4 @@
             }
 
-            VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
 #if 0 //def DEBUG_misha
             /* this is not entirely correct since host may concurrently complete some commands and raise a new IRQ while we are here,
Index: trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 47565)
+++ trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 47566)
@@ -209,6 +209,4 @@
     VBOXVR_SCR_COMPOSITOR_ENTRY CEntry;
     VBOXVR_SCR_COMPOSITOR_ENTRY RootVrCEntry;
-    void *pvUserData1;
-    void *pvUserData2;
 } CR_DISPLAY_ENTRY, *PCR_DISPLAY_ENTRY;
 /**/
@@ -349,4 +347,7 @@
 /* DISPLAY */
 
+#define CR_DENTRY_FROM_CENTRY(_pCentry) ((CR_DISPLAY_ENTRY*)((uint8_t*)(_pCentry) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
+
+
 /* @todo:
  * 1. use compositor stored inside mural to use current MuralFBO and window-related API
@@ -359,32 +360,10 @@
 } CR_DISPLAY, *PCR_DISPLAY;
 
-int CrDpInit(PCR_DISPLAY pDisplay);
-void CrDpTerm(PCR_DISPLAY pDisplay);
-void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height);
-void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, void *pvUserData);
-void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
-int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
-int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
-void CrDpEntryRegionsClear(PCR_DISPLAY pDisplay);
-DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry)
-{
-    return CrVrScrCompositorEntryIsInList(&pEntry->CEntry);
-}
-
-DECLINLINE(CRMuralInfo*) CrDpGetMural(PCR_DISPLAY pDisplay)
-{
-    return &pDisplay->Mural;
-}
 
 typedef struct CR_DISPLAY_ENTRY_MAP
 {
-    CRHashTable * pTextureMap;
+    CRHashTable * pTexIdToDemInfoMap;
 } CR_DISPLAY_ENTRY_MAP, *PCR_DISPLAY_ENTRY_MAP;
 
-int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap);
-void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap);
-PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture);
-void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry);
-//void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture);
 
 /* */
Index: trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h	(revision 47565)
+++ trunk/src/VBox/GuestHost/OpenGL/include/cr_version.h	(revision 47566)
@@ -37,5 +37,6 @@
 /* dummy windows and contexts have 0 external IDs, so never get stored to the state */
 #define SHCROGL_SSM_VERSION_WITH_FIXED_DUMMYIDS                     39
-#define SHCROGL_SSM_VERSION                                         39
+#define SHCROGL_SSM_VERSION_WITH_SCREEN_INFO                        40
+#define SHCROGL_SSM_VERSION                                         40
 
 /* These define the Chromium release number.
Index: trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h	(revision 47565)
+++ trunk/src/VBox/GuestHost/OpenGL/include/cr_vreg.h	(revision 47566)
@@ -400,5 +400,10 @@
 VBOXVREGDECL(int) CrVrScrCompositorEntryRemove(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
 VBOXVREGDECL(void) CrVrScrCompositorEntryFlagsSet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry, uint32_t fFlags);
-VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
+VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry);
+DECLINLINE(uint32_t) CrVrScrCompositorEntryFlagsGet(PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
+{
+    return pEntry->fFlags;
+}
+
 VBOXVREGDECL(void) CrVrScrCompositorInit(PVBOXVR_SCR_COMPOSITOR pCompositor);
 VBOXVREGDECL(void) CrVrScrCompositorClear(PVBOXVR_SCR_COMPOSITOR pCompositor);
Index: trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp	(revision 47565)
+++ trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp	(revision 47566)
@@ -1749,12 +1749,10 @@
     Assert(cRects);
     Assert(cRects <= pData->cRects);
-    int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstRects);
+    int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstUnstretchedRects);
     AssertRC(rc);
 
-    memcpy(pEntry->paDstUnstretchedRects, pEntry->paDstRects, cRects * sizeof (*pEntry->paDstUnstretchedRects));
-
     if (!pEntry->Pos.x && !pEntry->Pos.y)
     {
-        memcpy(pEntry->paSrcRects, pEntry->paDstRects, cRects * sizeof (*pEntry->paSrcRects));
+        memcpy(pEntry->paSrcRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paSrcRects));
     }
     else
@@ -1762,8 +1760,8 @@
         for (uint32_t i = 0; i < cRects; ++i)
         {
-            pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstRects[i].xLeft - pEntry->Pos.x));
-            pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstRects[i].yTop - pEntry->Pos.y));
-            pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstRects[i].xRight - pEntry->Pos.x));
-            pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstRects[i].yBottom - pEntry->Pos.y));
+            pEntry->paSrcRects[i].xLeft = (int32_t)((pEntry->paDstUnstretchedRects[i].xLeft - pEntry->Pos.x));
+            pEntry->paSrcRects[i].yTop = (int32_t)((pEntry->paDstUnstretchedRects[i].yTop - pEntry->Pos.y));
+            pEntry->paSrcRects[i].xRight = (int32_t)((pEntry->paDstUnstretchedRects[i].xRight - pEntry->Pos.x));
+            pEntry->paSrcRects[i].yBottom = (int32_t)((pEntry->paDstUnstretchedRects[i].yBottom - pEntry->Pos.y));
         }
     }
@@ -1776,15 +1774,21 @@
             if (pCompositor->StretchX != 1.)
             {
-                pEntry->paDstRects[i].xLeft = (int32_t)(pEntry->paDstRects[i].xLeft * pCompositor->StretchX);
-                pEntry->paDstRects[i].xRight = (int32_t)(pEntry->paDstRects[i].xRight * pCompositor->StretchX);
+                pEntry->paDstRects[i].xLeft = (int32_t)(pEntry->paDstUnstretchedRects[i].xLeft * pCompositor->StretchX);
+                pEntry->paDstRects[i].xRight = (int32_t)(pEntry->paDstUnstretchedRects[i].xRight * pCompositor->StretchX);
             }
             if (pCompositor->StretchY != 1.)
             {
-                pEntry->paDstRects[i].yTop = (int32_t)(pEntry->paDstRects[i].yTop * pCompositor->StretchY);
-                pEntry->paDstRects[i].yBottom = (int32_t)(pEntry->paDstRects[i].yBottom * pCompositor->StretchY);
-            }
-        }
-    }
-
+                pEntry->paDstRects[i].yTop = (int32_t)(pEntry->paDstUnstretchedRects[i].yTop * pCompositor->StretchY);
+                pEntry->paDstRects[i].yBottom = (int32_t)(pEntry->paDstUnstretchedRects[i].yBottom * pCompositor->StretchY);
+            }
+        }
+    }
+    else
+#endif
+    {
+        memcpy(pEntry->paDstRects, pEntry->paDstUnstretchedRects, cRects * sizeof (*pEntry->paDstUnstretchedRects));
+    }
+
+#if 0//ndef IN_RING0
     bool canZeroX = (pCompositor->StretchX < 1.);
     bool canZeroY = (pCompositor->StretchY < 1.);
@@ -1795,7 +1799,7 @@
         for (iOrig = 0, iNew = 0; iOrig < cRects; ++iOrig)
         {
-            PRTRECT pOrigRect = &pEntry->paSrcRects[iOrig];
-            if (pOrigRect->xLeft == pOrigRect->xRight
-                    || pOrigRect->yTop == pOrigRect->yBottom)
+            PRTRECT pOrigRect = &pEntry->paDstRects[iOrig];
+            if (pOrigRect->xLeft != pOrigRect->xRight
+                    && pOrigRect->yTop != pOrigRect->yBottom)
                 continue;
 
@@ -2294,5 +2298,5 @@
 }
 
-VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
+VBOXVREGDECL(uint32_t) CrVrScrCompositorEntryFlagsCombinedGet(PVBOXVR_SCR_COMPOSITOR pCompositor, PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry)
 {
     return CRBLT_FOP_COMBINE(pCompositor->fFlags, pEntry->fFlags);
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 47566)
@@ -398,6 +398,46 @@
 
 int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal);
+
+
 void CrDpEnter(PCR_DISPLAY pDisplay);
 void CrDpLeave(PCR_DISPLAY pDisplay);
+int CrDpInit(PCR_DISPLAY pDisplay);
+void CrDpTerm(PCR_DISPLAY pDisplay);
+
+DECLINLINE(bool) CrDpIsEmpty(PCR_DISPLAY pDisplay)
+{
+    return CrVrScrCompositorIsEmpty(&pDisplay->Mural.Compositor);
+}
+
+int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM);
+int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version);
+
+void CrDpResize(PCR_DISPLAY pDisplay, int32_t xPos, int32_t yPos, uint32_t width, uint32_t height);
+void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData);
+void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
+int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
+int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
+void CrDpEntryRegionsClear(PCR_DISPLAY pDisplay);
+DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry)
+{
+    return CrVrScrCompositorEntryIsInList(&pEntry->CEntry);
+}
+
+DECLINLINE(CRMuralInfo*) CrDpGetMural(PCR_DISPLAY pDisplay)
+{
+    return &pDisplay->Mural;
+}
+
+int CrDemGlobalInit();
+void CrDemTeGlobalTerm();
+int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap);
+void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap);
+PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture);
+void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry);
+int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM);
+int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM);
+
+int crServerDisplaySaveState(PSSMHANDLE pSSM);
+int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version);
 
 //#define VBOX_WITH_CRSERVER_DUMPER
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 47566)
@@ -382,5 +382,5 @@
         if (id != mural->iCurDrawBuffer)
         {
-            crWarning("DBO draw buffer changed on make current");
+            crDebug("DBO draw buffer changed on make current");
             mural->iCurDrawBuffer = id;
         }
@@ -389,5 +389,5 @@
         if (id != mural->iCurReadBuffer)
         {
-            crWarning("DBO read buffer changed on make current");
+            crDebug("DBO read buffer changed on make current");
             mural->iCurReadBuffer = id;
         }
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 47566)
@@ -189,4 +189,5 @@
     crServerDisplayTermAll();
     CrDemTerm(&cr_server.PresentTexturepMap);
+    CrDemTeGlobalTerm();
     memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
     memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
@@ -348,5 +349,5 @@
         cr_server.u32Caps = 0;
 #ifdef DEBUG_misha
-//        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
 #endif
     }
@@ -381,4 +382,6 @@
     cr_server.dummyMuralTable = crAllocHashtable();
 
+    CrDemGlobalInit();
+
     CrDemInit(&cr_server.PresentTexturepMap);
     memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
@@ -460,5 +463,5 @@
         cr_server.u32Caps = 0;
 #ifdef DEBUG_misha
-//        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
 #endif
     }
@@ -501,4 +504,6 @@
 
     cr_server.dummyMuralTable = crAllocHashtable();
+
+    CrDemGlobalInit();
 
     CrDemInit(&cr_server.PresentTexturepMap);
@@ -1725,4 +1730,7 @@
     }
 
+    rc = crServerDisplaySaveState(pSSM);
+    AssertRCReturn(rc, rc);
+
     /* all context gl error states should have now be synced with chromium erro states,
      * reset the error if any */
@@ -2612,4 +2620,10 @@
     cr_server.curClient = NULL;
 
+    if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO)
+    {
+        rc = crServerDisplayLoadState(pSSM, version);
+        AssertRCReturn(rc, rc);
+    }
+
     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/crserverlib/server_presenter.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 47566)
@@ -31,4 +31,6 @@
 #include <iprt/asm.h>
 #include <iprt/mem.h>
+#include <iprt/list.h>
+#include <iprt/memcache.h>
 
 
@@ -63,5 +65,5 @@
 {
     const GLint visBits = cr_server.MainContextInfo.CreateInfo.visualBits;
-    if (crServerMuralInit(&pDisplay->Mural, "", visBits, 0, GL_FALSE) < 0)
+    if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1, GL_FALSE) < 0)
     {
         crWarning("crServerMuralInit failed!");
@@ -85,4 +87,110 @@
     CrVrScrCompositorSetStretching(&pDisplay->Mural.Compositor, 1., 1.);
 }
+
+int CrDpSaveState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM)
+{
+    VBOXVR_SCR_COMPOSITOR_ITERATOR Iter;
+    CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
+    PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
+    uint32_t u32 = 0;
+    while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
+    {
+        ++u32;
+    }
+
+    int rc = SSMR3PutU32(pSSM, u32);
+    AssertRCReturn(rc, rc);
+
+    CrVrScrCompositorIterInit(&pDisplay->Mural.Compositor, &Iter);
+
+    while ((pEntry = CrVrScrCompositorIterNext(&Iter)) != NULL)
+    {
+        CR_DISPLAY_ENTRY *pDEntry = CR_DENTRY_FROM_CENTRY(pEntry);
+        rc = CrDemEntrySaveState(pDEntry, pSSM);
+        AssertRCReturn(rc, rc);
+
+        u32 = CrVrScrCompositorEntryFlagsGet(&pDEntry->CEntry);
+        rc = SSMR3PutU32(pSSM, u32);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->x);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutS32(pSSM, CrVrScrCompositorEntryPosGet(&pDEntry->CEntry)->y);
+        AssertRCReturn(rc, rc);
+
+        const RTRECT * pRects;
+        rc = CrVrScrCompositorEntryRegionsGet(&pDisplay->Mural.Compositor, &pDEntry->CEntry, &u32, NULL, NULL, &pRects);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3PutU32(pSSM, u32);
+        AssertRCReturn(rc, rc);
+
+        if (u32)
+        {
+            rc = SSMR3PutMem(pSSM, pRects, u32 * sizeof (*pRects));
+            AssertRCReturn(rc, rc);
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+int CrDpLoadState(PCR_DISPLAY pDisplay, PSSMHANDLE pSSM, uint32_t version)
+{
+    uint32_t u32 = 0;
+    int rc = SSMR3GetU32(pSSM, &u32);
+    AssertRCReturn(rc, rc);
+
+    if (!u32)
+        return VINF_SUCCESS;
+
+    CrDpEnter(pDisplay);
+
+    for (uint32_t i = 0; i < u32; ++i)
+    {
+        CR_DISPLAY_ENTRY *pDEntry;
+        rc = CrDemEntryLoadState(&cr_server.PresentTexturepMap, &pDEntry, pSSM);
+        AssertRCReturn(rc, rc);
+
+        uint32_t fFlags;
+        rc = SSMR3GetU32(pSSM, &fFlags);
+        AssertRCReturn(rc, rc);
+
+        CrVrScrCompositorEntryFlagsSet(&pDEntry->CEntry, fFlags);
+
+        RTPOINT Pos;
+        rc = SSMR3GetS32(pSSM, &Pos.x);
+        AssertRCReturn(rc, rc);
+
+        rc = SSMR3GetS32(pSSM, &Pos.y);
+        AssertRCReturn(rc, rc);
+
+        uint32_t cRects;
+        rc = SSMR3GetU32(pSSM, &cRects);
+        AssertRCReturn(rc, rc);
+
+        RTRECT * pRects = NULL;
+        if (cRects)
+        {
+            pRects = (RTRECT *)crAlloc(cRects * sizeof (*pRects));
+            AssertReturn(pRects, VERR_NO_MEMORY);
+
+            rc = SSMR3GetMem(pSSM, pRects, cRects * sizeof (*pRects));
+            AssertRCReturn(rc, rc);
+        }
+
+        rc = CrDpEntryRegionsAdd(pDisplay, pDEntry, &Pos, (uint32_t)cRects, (const RTRECT*)pRects);
+        AssertRCReturn(rc, rc);
+
+        if (pRects)
+            crFree(pRects);
+    }
+
+    CrDpLeave(pDisplay);
+
+    return VINF_SUCCESS;
+}
+
 
 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
@@ -147,5 +255,5 @@
 }
 
-void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData, void *pvUserData1, void *pvUserData2)
+void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData)
 {
     CrVrScrCompositorEntryInit(&pEntry->CEntry, pTextureData, crDpEntryCEntryReleaseCB);
@@ -153,6 +261,4 @@
     CrVrScrCompositorEntryInit(&pEntry->RootVrCEntry, pTextureData, NULL);
     CrVrScrCompositorEntryFlagsSet(&pEntry->RootVrCEntry, CRBLT_F_INVERT_SRC_YCOORDS);
-    pEntry->pvUserData1 = pvUserData1;
-    pEntry->pvUserData2 = pvUserData2;
 }
 
@@ -174,27 +280,95 @@
 }
 
-int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
-{
-    pMap->pTextureMap = crAllocHashtable();
-    if (pMap->pTextureMap)
-        return VINF_SUCCESS;
-
-    crWarning("crAllocHashtable failed!");
-    return VERR_NO_MEMORY;
-}
-
-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;
+typedef struct CR_DEM_ENTRY_INFO
+{
+    CRTextureObj *pTobj;
+    uint32_t cEntries;
+} CR_DEM_ENTRY_INFO;
+
+typedef struct CR_DEM_ENTRY
+{
+    CR_DISPLAY_ENTRY Entry;
+    CR_DEM_ENTRY_INFO *pInfo;
+    CR_DISPLAY_ENTRY_MAP *pMap;
+} CR_DEM_ENTRY;
+
+#define PCR_DEM_ENTRY_FROM_ENTRY(_pEntry) ((CR_DEM_ENTRY*)((uint8_t*)(_pEntry) - RT_OFFSETOF(CR_DEM_ENTRY, Entry)))
+
+static RTMEMCACHE g_VBoxCrDemLookasideList;
+static RTMEMCACHE g_VBoxCrDemInfoLookasideList;
+
+int CrDemGlobalInit()
+{
+    int rc = RTMemCacheCreate(&g_VBoxCrDemLookasideList, sizeof (CR_DEM_ENTRY),
+                            0, /* size_t cbAlignment */
+                            UINT32_MAX, /* uint32_t cMaxObjects */
+                            NULL, /* PFNMEMCACHECTOR pfnCtor*/
+                            NULL, /* PFNMEMCACHEDTOR pfnDtor*/
+                            NULL, /* void *pvUser*/
+                            0 /* uint32_t fFlags*/
+                            );
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTMemCacheCreate(&g_VBoxCrDemInfoLookasideList, sizeof (CR_DEM_ENTRY_INFO),
+                                    0, /* size_t cbAlignment */
+                                    UINT32_MAX, /* uint32_t cMaxObjects */
+                                    NULL, /* PFNMEMCACHECTOR pfnCtor*/
+                                    NULL, /* PFNMEMCACHEDTOR pfnDtor*/
+                                    NULL, /* void *pvUser*/
+                                    0 /* uint32_t fFlags*/
+                                    );
+        if (RT_SUCCESS(rc))
+            return VINF_SUCCESS;
+        else
+            crWarning("RTMemCacheCreate failed rc %d", rc);
+
+        RTMemCacheDestroy(g_VBoxCrDemLookasideList);
+    }
+    else
+        crWarning("RTMemCacheCreate failed rc %d", rc);
+    return VINF_SUCCESS;
+}
+
+void CrDemTeGlobalTerm()
+{
+    RTMemCacheDestroy(g_VBoxCrDemLookasideList);
+    RTMemCacheDestroy(g_VBoxCrDemInfoLookasideList);
+}
+
+static CR_DEM_ENTRY* crDemEntryAlloc()
+{
+    return (CR_DEM_ENTRY*)RTMemCacheAlloc(g_VBoxCrDemLookasideList);
+}
+
+static CR_DEM_ENTRY_INFO* crDemEntryInfoAlloc()
+{
+    return (CR_DEM_ENTRY_INFO*)RTMemCacheAlloc(g_VBoxCrDemInfoLookasideList);
+}
+
+static void crDemEntryFree(CR_DEM_ENTRY* pDemEntry)
+{
+    RTMemCacheFree(g_VBoxCrDemLookasideList, pDemEntry);
+}
+
+static void crDemEntryInfoFree(CR_DEM_ENTRY_INFO* pDemEntryInfo)
+{
+    RTMemCacheFree(g_VBoxCrDemInfoLookasideList, pDemEntryInfo);
+}
+
+void crDemEntryRelease(PCR_DISPLAY_ENTRY_MAP pMap, CR_DEM_ENTRY *pDemEntry)
+{
+    CR_DEM_ENTRY_INFO *pInfo = pDemEntry->pInfo;
+    CRTextureObj *pTobj = pInfo->pTobj;
+
+    --pInfo->cEntries;
+
+    if (!pInfo->cEntries)
+    {
+        CR_STATE_SHAREDOBJ_USAGE_CLEAR(pInfo->pTobj, cr_server.MainContextInfo.pContext);
+
+        crHashtableDelete(pMap->pTexIdToDemInfoMap, pTobj->id, NULL);
+
+        crDemEntryInfoFree(pInfo);
+    }
 
     if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj))
@@ -205,49 +379,64 @@
         /* 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);
+        crHashtableDelete(pShared->textureTable, pTobj->id, 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);
+    }
+
+    crDemEntryFree(pDemEntry);
+
+    crStateGlobalSharedRelease();
+}
+
+int CrDemInit(PCR_DISPLAY_ENTRY_MAP pMap)
+{
+    pMap->pTexIdToDemInfoMap = crAllocHashtable();
+    if (pMap->pTexIdToDemInfoMap)
+        return VINF_SUCCESS;
+
+    crWarning("crAllocHashtable failed");
+    return VERR_NO_MEMORY;
 }
 
 void CrDemTerm(PCR_DISPLAY_ENTRY_MAP pMap)
 {
-    crFreeHashtable(pMap->pTextureMap, crDemTermEntryCb);
+    crFreeHashtable(pMap->pTexIdToDemInfoMap, NULL);
+    pMap->pTexIdToDemInfoMap = NULL;
 }
 
 void CrDemEntryRelease(PCR_DISPLAY_ENTRY pEntry)
 {
-    PCR_DISPLAY_ENTRY_MAP pMap = (PCR_DISPLAY_ENTRY_MAP)pEntry->pvUserData1;
-    Assert(pMap);
-    crDemEntryRelease(pMap, pEntry, false);
+    CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
+    crDemEntryRelease(pDemEntry->pMap, pDemEntry);
+}
+
+int CrDemEntrySaveState(PCR_DISPLAY_ENTRY pEntry, PSSMHANDLE pSSM)
+{
+    CR_DEM_ENTRY *pDemEntry = PCR_DEM_ENTRY_FROM_ENTRY(pEntry);
+    int  rc = SSMR3PutU32(pSSM, pDemEntry->pInfo->pTobj->id);
+    AssertRCReturn(rc, rc);
+    return rc;
+}
+
+int CrDemEntryLoadState(PCR_DISPLAY_ENTRY_MAP pMap, PCR_DISPLAY_ENTRY *ppEntry, PSSMHANDLE pSSM)
+{
+    uint32_t u32;
+    int  rc = SSMR3GetU32(pSSM, &u32);
+    AssertRCReturn(rc, rc);
+
+    PCR_DISPLAY_ENTRY pEntry = CrDemEntryAcquire(pMap, u32);
+    if (!pEntry)
+    {
+        crWarning("CrDemEntryAcquire failed");
+        return VERR_NO_MEMORY;
+    }
+
+    *ppEntry = pEntry;
+    return VINF_SUCCESS;
 }
 
 PCR_DISPLAY_ENTRY CrDemEntryAcquire(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
 {
-    PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
-    if (pEntry)
-        return pEntry;
+    CR_DEM_ENTRY *pDemEntry = NULL;
 
     CRSharedState *pShared = crStateGlobalSharedAcquire();
@@ -282,39 +471,34 @@
     TextureData.hwid = hwId;
 
-    pEntry = (PCR_DISPLAY_ENTRY)crAlloc(sizeof (*pEntry));
-    if (!pEntry)
-    {
-        crWarning("crAlloc failed allocating CR_DISPLAY_ENTRY");
+    pDemEntry = crDemEntryAlloc();
+    if (!pDemEntry)
+    {
+        crWarning("crDemEntryAlloc failed allocating CR_DEM_ENTRY");
         crStateGlobalSharedRelease();
         return NULL;
     }
 
-    CrDpEntryInit(pEntry, &TextureData, pMap, pTobj);
+    CrDpEntryInit(&pDemEntry->Entry, &TextureData);
+
+    CR_DEM_ENTRY_INFO *pInfo = (CR_DEM_ENTRY_INFO*)crHashtableSearch(pMap->pTexIdToDemInfoMap, pTobj->id);
+    if (!pInfo)
+    {
+        pInfo = crDemEntryInfoAlloc();
+        CRASSERT(pInfo);
+        crHashtableAdd(pMap->pTexIdToDemInfoMap, pTobj->id, pInfo);
+        pInfo->cEntries = 0;
+        pInfo->pTobj = pTobj;
+    }
+
+    ++pInfo->cEntries;
+    pDemEntry->pInfo = pInfo;
+    pDemEntry->pMap = pMap;
 
     /* 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);
-    return pEntry;
-
-}
-#if 0
-void CrDemEntryDestroy(PCR_DISPLAY_ENTRY_MAP pMap, GLuint idTexture)
-{
-#ifdef DEBUG
-    {
-        PCR_DISPLAY_ENTRY pEntry = (PCR_DISPLAY_ENTRY)crHashtableSearch(pMap->pTextureMap, idTexture);
-        if (!pEntry)
-        {
-            crWarning("request to delete inexistent entry");
-            return;
-        }
-
-        Assert(!CrDpEntryIsUsed(pEntry));
-    }
-#endif
-    crHashtableDelete(pMap->pTextureMap, idTexture, crFree);
-}
-#endif
+    return &pDemEntry->Entry;
+}
+
 PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
 {
@@ -352,4 +536,61 @@
 }
 
+int crServerDisplaySaveState(PSSMHANDLE pSSM)
+{
+    int rc;
+    int cDisplays = 0, i;
+    for (i = 0; i < cr_server.screenCount; ++i)
+    {
+        if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
+            ++cDisplays;
+    }
+
+    rc = SSMR3PutS32(pSSM, cDisplays);
+    AssertRCReturn(rc, rc);
+
+    for (i = 0; i < cr_server.screenCount; ++i)
+    {
+        if (ASMBitTest(cr_server.DisplaysInitMap, i) && !CrDpIsEmpty(&cr_server.aDispplays[i]))
+        {
+            rc = SSMR3PutS32(pSSM, i);
+            AssertRCReturn(rc, rc);
+
+            rc = CrDpSaveState(&cr_server.aDispplays[i], pSSM);
+            AssertRCReturn(rc, rc);
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+int crServerDisplayLoadState(PSSMHANDLE pSSM, uint32_t u32Version)
+{
+    int rc;
+    int s32, i;
+
+    rc = SSMR3GetS32(pSSM, &s32);
+    AssertRCReturn(rc, rc);
+
+    for (i = 0; i < s32; ++i)
+    {
+        int iScreen;
+
+        rc = SSMR3GetS32(pSSM, &iScreen);
+        AssertRCReturn(rc, rc);
+
+        PCR_DISPLAY pDisplay = crServerDisplayGet((uint32_t)iScreen);
+        if (!pDisplay)
+        {
+            crWarning("crServerDisplayGet failed");
+            return VERR_GENERAL_FAILURE;
+        }
+
+        rc = CrDpLoadState(pDisplay, pSSM, u32Version);
+        AssertRCReturn(rc, rc);
+    }
+
+    return VINF_SUCCESS;
+}
+
 void crServerDisplayTermAll()
 {
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 47566)
@@ -492,6 +492,4 @@
 }
 
-#define CR_DENTRY_FROM_CENTRY(_pCentry) ((CR_DISPLAY_ENTRY*)((uint8_t*)(_pCentry) - RT_OFFSETOF(CR_DISPLAY_ENTRY, CEntry)))
-
 static DECLCALLBACK(VBOXVR_SCR_COMPOSITOR_ENTRY*) crServerMuralGetRootVrCEntry(VBOXVR_SCR_COMPOSITOR_ENTRY*pEntry, void *pvContext)
 {
@@ -706,6 +704,4 @@
             if (mural->fRootVrOn)
             {
-                uint32_t cRects;
-                const RTRECT *pRects;
                 int rc = crServerMuralSynchRootVr(mural);
                 if (RT_SUCCESS(rc))
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 47566)
@@ -669,5 +669,5 @@
         const RTRECT *paSrcRegions, *paDstRegions;
         int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
-        uint32_t fFlags = CrVrScrCompositorEntryFlagsGet(pCompositor, pEntry);
+        uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
         if (RT_SUCCESS(rc))
         {
@@ -700,5 +700,5 @@
         const RTRECT *paSrcRegions, *paDstRegions;
         int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
-        uint32_t fFlags = CrVrScrCompositorEntryFlagsGet(pCompositor, pEntry);
+        uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
         if (RT_SUCCESS(rc))
         {
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 47565)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 47566)
@@ -1255,5 +1255,5 @@
         const RTRECT *paSrcRegions, *paDstRegions;
         int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
-        uint32_t fFlags = CrVrScrCompositorEntryFlagsGet(pCompositor, pEntry);
+        uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
         if (RT_SUCCESS(rc))
         {
@@ -1379,5 +1379,5 @@
                 const RTRECT *paSrcRegions, *paDstRegions;
                 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
-                uint32_t fFlags = CrVrScrCompositorEntryFlagsGet(pCompositor, pEntry);
+                uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
                 if (RT_SUCCESS(rc))
                 {
