Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 46800)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCr.cpp	(revision 46801)
@@ -882,4 +882,9 @@
     }
 
+#ifndef DEBUG_misha
+    /* zero it up temporary to avoid new code activation */
+    g_VBoxMpCrHostCaps = 0;
+#endif
+
     rc = VBoxMpCrCtlConDisconnect(&CrCtlCon, u32ClientID);
     if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 46800)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp	(revision 46801)
@@ -1993,4 +1993,5 @@
                     memset (pQi, 0, sizeof (VBOXWDDM_QI));
                     pQi->u32Version = VBOXVIDEOIF_VERSION;
+                    pQi->u32VBox3DCaps = VBoxMpCrGetHostCaps();
                     pQi->cInfos = VBoxCommonFromDeviceExt(pDevExt)->cDisplays;
 #ifdef VBOX_WITH_VIDEOHWACCEL
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 46800)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 46801)
@@ -346,5 +346,4 @@
 typedef struct CR_DISPLAY
 {
-    VBOXVR_SCR_COMPOSITOR Compositor;
     CRMuralInfo Mural;
 } CR_DISPLAY, *PCR_DISPLAY;
@@ -358,5 +357,4 @@
 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);
-int CrDpPresentEntry(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
 DECLINLINE(bool) CrDpEntryIsUsed(PCR_DISPLAY_ENTRY pEntry)
 {
Index: /trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp	(revision 46800)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/vreg.cpp	(revision 46801)
@@ -621,5 +621,6 @@
 static int vboxVrListSubstNoJoin(PVBOXVR_LIST pList, uint32_t cRects, const RTRECT * aRects, bool *pfChanged)
 {
-    *pfChanged = false;
+    if (pfChanged)
+        *pfChanged = false;
 
     if (VBoxVrListIsEmpty(pList))
@@ -637,5 +638,7 @@
     }
 
-    *pfChanged = Data.fChanged;
+    if (pfChanged)
+        *pfChanged = Data.fChanged;
+
     return VINF_SUCCESS;
 }
@@ -910,5 +913,7 @@
 #endif
 
-    int rc = vboxVrListSubstNoJoin(pList, cRects, aRects, pfChanged);
+    bool fChanged = false;
+
+    int rc = vboxVrListSubstNoJoin(pList, cRects, aRects, &fChanged);
     if (!RT_SUCCESS(rc))
     {
@@ -917,5 +922,5 @@
     }
 
-    if (!*pfChanged)
+    if (fChanged)
         goto done;
 
@@ -927,4 +932,8 @@
         RTMemFree(pRects);
 #endif
+
+    if (pfChanged)
+        *pfChanged = fChanged;
+
     return rc;
 }
@@ -1198,5 +1207,5 @@
 {
     bool fOthersChanged = false, fCurChanged = false, fEntryChanged = false, fEntryWasInList = false, fEntryReplaced = false;
-    PVBOXVR_COMPOSITOR_ENTRY pCur;
+    PVBOXVR_COMPOSITOR_ENTRY pCur, pNext;
     int rc = VINF_SUCCESS;
 
@@ -1230,6 +1239,10 @@
         Assert(!VBoxVrListIsEmpty(&pEntry->Vr));
     }
-
-    RTListForEach(&pCompositor->List, pCur, VBOXVR_COMPOSITOR_ENTRY, Node)
+    else
+    {
+        fEntryChanged = true;
+    }
+
+    RTListForEachSafe(&pCompositor->List, pCur, pNext, VBOXVR_COMPOSITOR_ENTRY, Node)
     {
         Assert(!VBoxVrListIsEmpty(&pCur->Vr));
@@ -1621,5 +1634,5 @@
     uint32_t cRects = VBoxVrListRectsCount(&pCEntry->Vr);
     Assert(cRects);
-    Assert(cRects >= pData->cRects);
+    Assert(cRects <= pData->cRects);
     int rc = VBoxVrListRectsGet(&pCEntry->Vr, cRects, pEntry->paDstRects);
     AssertRC(rc);
@@ -1729,5 +1742,5 @@
 {
     uint32_t fChangedFlags = 0;
-    int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, &pEntry->Ce, cRegions, paRegions, &fChangedFlags);
+    int rc = VBoxVrCompositorEntryRegionsAdd(&pCompositor->Compositor, pEntry ? &pEntry->Ce : NULL, cRegions, paRegions, &fChangedFlags);
     if (!RT_SUCCESS(rc))
     {
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 46800)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 46801)
@@ -113,5 +113,5 @@
 GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID);
 GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID);
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID);
+GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fSetVRegs);
 void crServerMuralTerm(CRMuralInfo *mural);
 void crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height);
@@ -131,4 +131,5 @@
 
 void crVBoxServerNotifyEvent(int32_t idScreen);
+void crServerDisplayTermAll();
 
 #define CR_SERVER_REDIR_F_NONE     0x00
@@ -403,5 +404,7 @@
 void crServerDumpDrawel(const char*pszFormat, ...);
 void crServerDumpDrawelv(GLuint idx, const char*pszElFormat, uint32_t cbEl, const void *pvVal, uint32_t cVal);
-
+int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal);
+void CrDpEnter(PCR_DISPLAY pDisplay);
+void CrDpLeave(PCR_DISPLAY pDisplay);
 
 extern unsigned long g_CrDbgDumpEnabled;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 46800)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 46801)
@@ -64,5 +64,5 @@
 }
 
-static int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal)
+int crServerVBoxParseNumerics(const char *pszStr, const int defaultVal)
 {
     int result = 0;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 46800)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 46801)
@@ -187,4 +187,9 @@
     crFreeHashtable(cr_server.muralTable, deleteMuralInfoCallback);
 
+    crServerDisplayTermAll();
+    CrDemTerm(&cr_server.PresentTexturepMap);
+    memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
+    memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
+
     for (i = 0; i < cr_server.numClients; i++) {
         if (cr_server.clients[i]) {
@@ -333,4 +338,18 @@
     }
 
+    env = crGetenv("CR_SERVER_CAPS");
+    if (env && env[0] != '\0')
+    {
+        cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
+        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_NO_DWM_SUPPORT);
+    }
+    else
+    {
+        cr_server.u32Caps = 0;
+#ifdef DEBUG_misha
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
+#endif
+    }
+
     cr_server.firstCallCreateContext = GL_TRUE;
     cr_server.firstCallMakeCurrent = GL_TRUE;
@@ -362,4 +381,8 @@
     cr_server.dummyMuralTable = crAllocHashtable();
 
+    CrDemInit(&cr_server.PresentTexturepMap);
+    memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
+    memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
+
     cr_server.fRootVrOn = GL_FALSE;
     VBoxVrListInit(&cr_server.RootVr);
@@ -425,4 +448,18 @@
         crInfo("Info: using multiple contexts!");
         crDebug("Debug: using multiple contexts!");
+    }
+
+    env = crGetenv("CR_SERVER_CAPS");
+    if (env && env[0] != '\0')
+    {
+        cr_server.u32Caps = crServerVBoxParseNumerics(env, 0);
+        cr_server.u32Caps &= ~(CR_VBOX_CAP_TEX_PRESENT | CR_VBOX_CAP_NO_DWM_SUPPORT);
+    }
+    else
+    {
+        cr_server.u32Caps = 0;
+#ifdef DEBUG_misha
+        cr_server.u32Caps = CR_VBOX_CAP_TEX_PRESENT;
+#endif
     }
 
@@ -464,4 +501,8 @@
 
     cr_server.dummyMuralTable = crAllocHashtable();
+
+    CrDemInit(&cr_server.PresentTexturepMap);
+    memset(cr_server.DisplaysInitMap, 0, sizeof (cr_server.DisplaysInitMap));
+    memset(cr_server.aDispplays, 0, sizeof (cr_server.aDispplays));
 
     cr_server.fRootVrOn = GL_FALSE;
@@ -970,5 +1011,5 @@
             return NULL;
         }
-        id = crServerMuralInit(pMural, "", visualBits, -1);
+        id = crServerMuralInit(pMural, "", visualBits, -1, GL_TRUE);
         if (id < 0)
         {
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 46800)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 46801)
@@ -62,31 +62,16 @@
 int CrDpInit(PCR_DISPLAY pDisplay)
 {
-    int rc = CrVrScrCompositorInit(&pDisplay->Compositor);
-    if (RT_SUCCESS(rc))
-    {
-        const GLint visBits = CR_RGB_BIT | CR_DOUBLE_BIT;
-        if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1) >= 0)
-        {
-            return VINF_SUCCESS;
-//            crServerMuralTerm(&pDisplay->Mural);
-        }
-        else
-        {
-            crWarning("crServerMuralInit failed!");
-            rc = VERR_GENERAL_FAILURE;
-        }
-        CrVrScrCompositorTerm(&pDisplay->Compositor);
-    }
-    else
-    {
-        crWarning("CrVrScrCompositorInit failed, rc %d", rc);
-    }
-    CRASSERT(RT_FAILURE(rc));
-    return rc;
+    const GLint visBits = cr_server.MainContextInfo.CreateInfo.visualBits;
+    if (crServerMuralInit(&pDisplay->Mural, "", visBits, -1, GL_FALSE) < 0)
+    {
+        crWarning("crServerMuralInit failed!");
+        return VERR_GENERAL_FAILURE;
+    }
+
+    return VINF_SUCCESS;
 }
 
 void CrDpTerm(PCR_DISPLAY pDisplay)
 {
-    CrVrScrCompositorTerm(&pDisplay->Compositor);
     crServerMuralTerm(&pDisplay->Mural);
 }
@@ -99,14 +84,10 @@
     StretchY = ((float)stretchedHeight)/height;
     crServerMuralSize(&pDisplay->Mural, stretchedWidth, stretchedHeight);
-    CrVrScrCompositorLock(&pDisplay->Compositor);
-    CrVrScrCompositorSetStretching(&pDisplay->Compositor, StretchX, StretchY);
-    CrVrScrCompositorUnlock(&pDisplay->Compositor);
+    CrVrScrCompositorSetStretching(&pDisplay->Mural.Compositor, StretchX, StretchY);
 }
 
 int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
 {
-    CrVrScrCompositorLock(&pDisplay->Compositor);
-    int rc = CrVrScrCompositorEntryRegionsSet(&pDisplay->Compositor, &pEntry->CEntry, pPos, cRegions, paRegions, NULL);
-    CrVrScrCompositorUnlock(&pDisplay->Compositor);
+    int rc = CrVrScrCompositorEntryRegionsSet(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, NULL);
     return rc;
 }
@@ -114,31 +95,8 @@
 int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
 {
-    CrVrScrCompositorLock(&pDisplay->Compositor);
-    int rc = CrVrScrCompositorEntryRegionsAdd(&pDisplay->Compositor, &pEntry->CEntry, pPos, cRegions, paRegions, NULL);
-    CrVrScrCompositorUnlock(&pDisplay->Compositor);
+    int rc = CrVrScrCompositorEntryRegionsAdd(&pDisplay->Mural.Compositor, pEntry ? &pEntry->CEntry : NULL, pPos, cRegions, paRegions, NULL);
     return rc;
 }
 
-int CrDpPresentEntry(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
-{
-    GLuint idDrawFBO = 0, idReadFBO = 0;
-    CRMuralInfo *pMural = cr_server.currentMural;
-    CRContext *pCtx = cr_server.currentCtxInfo ? cr_server.currentCtxInfo->pContext : cr_server.MainContextInfo.pContext;
-
-    if (pMural)
-    {
-        idDrawFBO = CR_SERVER_FBO_FOR_IDX(pMural, pMural->iCurDrawBuffer);
-        idReadFBO = CR_SERVER_FBO_FOR_IDX(pMural, pMural->iCurReadBuffer);
-    }
-
-    crStateSwitchPrepare(NULL, pCtx, idDrawFBO, idReadFBO);
-
-    cr_server.head_spu->dispatch_table.VBoxPresentComposition(pDisplay->Mural.spuWindow, &pDisplay->Compositor, &pEntry->CEntry);
-
-    crStateSwitchPostprocess(pCtx, NULL, idDrawFBO, idReadFBO);
-
-    return VINF_SUCCESS;
-}
-
 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, const VBOXVR_TEXTURE *pTextureData)
 {
@@ -148,7 +106,16 @@
 void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
 {
-    CrVrScrCompositorLock(&pDisplay->Compositor);
-    CrVrScrCompositorEntryRemove(&pDisplay->Compositor, &pEntry->CEntry);
-    CrVrScrCompositorUnlock(&pDisplay->Compositor);
+    CrVrScrCompositorEntryRemove(&pDisplay->Mural.Compositor, &pEntry->CEntry);
+}
+
+void CrDpEnter(PCR_DISPLAY pDisplay)
+{
+    crServerVBoxCompositionDisableEnter(&pDisplay->Mural);
+}
+
+void CrDpLeave(PCR_DISPLAY pDisplay)
+{
+    pDisplay->Mural.fDataPresented = GL_TRUE;
+    crServerVBoxCompositionDisableLeave(&pDisplay->Mural, GL_FALSE);
 }
 
@@ -278,4 +245,17 @@
 }
 
+void crServerDisplayTermAll()
+{
+    int i;
+    for (i = 0; i < cr_server.screenCount; ++i)
+    {
+        if (ASMBitTest(cr_server.DisplaysInitMap, i))
+        {
+            CrDpTerm(&cr_server.aDispplays[i]);
+            ASMBitClear(cr_server.DisplaysInitMap, i);
+        }
+    }
+}
+
 void CrHlpFreeTexImage(CRContext *pCurCtx, GLuint idPBO, void *pvData)
 {
@@ -395,10 +375,16 @@
     }
 
-    PCR_DISPLAY_ENTRY pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
-    if (!pEntry)
-    {
-        crWarning("CrDemEntryGetCreate Failed");
-        return;
-    }
+    PCR_DISPLAY_ENTRY pEntry = NULL;
+    if (texture)
+    {
+        pEntry = CrDemEntryGetCreate(&cr_server.PresentTexturepMap, texture, cr_server.currentCtxInfo);
+        if (!pEntry)
+        {
+            crWarning("CrDemEntryGetCreate Failed");
+            return;
+        }
+    }
+
+    CrDpEnter(pDisplay);
 
     RTPOINT Point = {xPos, yPos};
@@ -410,9 +396,4 @@
     }
 
-    rc = CrDpPresentEntry(pDisplay, pEntry);
-    if (!RT_SUCCESS(rc))
-    {
-        crWarning("CrDpEntrySetRegions Failed rc %d", rc);
-        return;
-    }
-}
+    CrDpLeave(pDisplay);
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46800)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46801)
@@ -17,5 +17,5 @@
 }
 
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID)
+GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID, GLboolean fSetVRegs)
 {
     CRMuralInfo *defaultMural;
@@ -24,5 +24,4 @@
     GLint spuWindow;
     VBOXVR_TEXTURE Tex = {0};
-    RTRECT Rect;
     int rc;
 
@@ -103,13 +102,17 @@
     CR_STATE_SHAREDOBJ_USAGE_INIT(mural);
 
-    Rect.xLeft = 0;
-    Rect.xRight = mural->width;
-    Rect.yTop = 0;
-    Rect.yBottom = mural->height;
-    rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, 1, &Rect, NULL);
-    if (!RT_SUCCESS(rc))
-    {
-        crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
-        return -1;
+    if (fSetVRegs)
+    {
+        RTRECT Rect;
+        Rect.xLeft = 0;
+        Rect.xRight = mural->width;
+        Rect.yTop = 0;
+        Rect.yBottom = mural->height;
+        rc = CrVrScrCompositorEntryRegionsSet(&mural->Compositor, &mural->CEntry, NULL, 1, &Rect, NULL);
+        if (!RT_SUCCESS(rc))
+        {
+            crWarning("CrVrScrCompositorEntryRegionsSet failed, rc %d", rc);
+            return -1;
+        }
     }
 
@@ -183,5 +186,5 @@
     }
 
-    windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID);
+    windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID, GL_TRUE);
     if (windowID < 0)
     {
