Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 43931)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_server.h	(revision 43932)
@@ -79,31 +79,4 @@
 struct BucketingInfo;
 
-/**
- * Mural info
- */
-typedef struct {
-    GLuint width, height;
-    GLint gX, gY;            /*guest coordinates*/
-    GLint hX, hY;            /*host coordinates, screenID related*/
-
-    int spuWindow;           /*the SPU's corresponding window ID */
-
-    int screenId;
-
-    GLboolean bVisible;      /*guest window is visible*/
-    GLboolean bUseFBO;       /*redirect to FBO instead of real host window*/
-    GLboolean bFbDraw;       /*GL_FRONT buffer is drawn to directly*/
-
-    GLint       cVisibleRects;    /*count of visible rects*/
-    GLint      *pVisibleRects;    /*visible rects left, top, right, bottom*/
-    GLboolean   bReceivedRects;   /*indicates if guest did any updates for visible regions*/
-
-    GLuint idFBO, idColorTex, idDepthStencilRB;
-    GLuint fboWidth, fboHeight;
-    GLuint idPBO;
-
-    void *pvOutputRedirectInstance;
-} CRMuralInfo;
-
 typedef struct {
     char   *pszDpyName;
@@ -111,4 +84,33 @@
     int32_t externalID;
 } CRCreateInfo_t;
+
+/**
+ * Mural info
+ */
+typedef struct {
+    GLuint width, height;
+    GLint gX, gY;            /*guest coordinates*/
+    GLint hX, hY;            /*host coordinates, screenID related*/
+
+    int spuWindow;           /*the SPU's corresponding window ID */
+
+    int screenId;
+
+    GLboolean bVisible;      /*guest window is visible*/
+    GLubyte   fUseFBO;       /*redirect to FBO instead of real host window*/
+    GLboolean bFbDraw;       /*GL_FRONT buffer is drawn to directly*/
+
+    GLint       cVisibleRects;    /*count of visible rects*/
+    GLint      *pVisibleRects;    /*visible rects left, top, right, bottom*/
+    GLboolean   bReceivedRects;   /*indicates if guest did any updates for visible regions*/
+
+    GLuint idFBO, idColorTex, idDepthStencilRB;
+    GLuint fboWidth, fboHeight;
+    GLuint idPBO;
+
+    void *pvOutputRedirectInstance;
+
+    CRCreateInfo_t CreateInfo;
+} CRMuralInfo;
 
 typedef struct {
@@ -225,5 +227,5 @@
 } CR_BLITTER, *PCR_BLITTER;
 
-int CrBltInit(PCR_BLITTER pBlitter, CRMuralInfo *pCurrentMural, GLint visualBits);
+int CrBltInit(PCR_BLITTER pBlitter, CRMuralInfo *pCurrentMural);
 void CrBltTerm(PCR_BLITTER pBlitter);
 
@@ -244,4 +246,5 @@
 void CrBltBlitTexMural(PCR_BLITTER pBlitter, CR_BLITTER_TEXTURE *pSrc, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects, uint32_t fFlags);
 void CrBltBlitTexTex(PCR_BLITTER pBlitter, CR_BLITTER_TEXTURE *pSrc, const RTRECT *pSrcRect, CR_BLITTER_TEXTURE *pDst, const RTRECT *pDstRect, uint32_t cRects, uint32_t fFlags);
+void CrBltPresent(PCR_BLITTER pBlitter);
 /* */
 
@@ -253,5 +256,5 @@
 typedef FNCRDISPLAY_REGIONS_CHANGED *PFNCRDISPLAY_REGIONS_CHANGED;
 
-typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_ENTRY(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter);
+typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_ENTRY(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn);
 typedef FNCRDISPLAY_DRAW_ENTRY *PFNCRDISPLAY_DRAW_ENTRY;
 
@@ -265,7 +268,7 @@
     CR_BLITTER_TEXTURE Texture;
     RTPOINT Pos;
+    uint32_t cRects;
     PRTRECT paSrcRects;
     PRTRECT paDstRects;
-    uint32_t cRects;
 } CR_PRESENTER_ENTRY, *PCR_PRESENTER_ENTRY;
 
@@ -285,6 +288,6 @@
 
 
-DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter);
-DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter);
+DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn);
+DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn);
 
 DECLINLINE(void) CrPtEntryInit(PCR_PRESENTER_ENTRY pEntry, PCR_BLITTER_TEXTURE pTextureData)
@@ -298,5 +301,8 @@
     return VBoxVrCompositorEntryIsInList(&pEntry->Ce);
 }
-int CrPtEntryPresent(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, PCR_BLITTER pBlitter);
+int CrPtPresent(PCR_PRESENTER pPresenter, PCR_BLITTER pBlitter);
+int CrPtPresentEntry(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, PCR_BLITTER pBlitter);
+int CrPtEntryRegionsAdd(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
+int CrPtEntryRegionsSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
 int CrPtEntryRemove(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry);
 int CrPtInit(PCR_PRESENTER pPresenter, PFNCRDISPLAY_REGIONS_CHANGED pfnRegionsChanged, PFNCRDISPLAY_DRAW_ENTRY pfnDrawEntry, PFNCRDISPLAY_DRAW_TEXTURE pfnDrawTexture);
@@ -318,5 +324,4 @@
     CR_PRESENTER Presenter;
     CRMuralInfo Mural;
-    CRCreateInfo_t MuralCreateInfo;
     PCR_BLITTER pBlitter;
 } CR_DISPLAY, *PCR_DISPLAY;
@@ -328,10 +333,13 @@
     pDisplay->pBlitter = pBlitter;
 }
-bool CrDpBlitterTest(PCR_DISPLAY pDisplay, PCR_BLITTER pBlitter);
+int CrDpBlitterTestWithMural(PCR_BLITTER pBlitter, CRMuralInfo *pMural);
+int CrDpBlitterTest(PCR_DISPLAY pDisplay, PCR_BLITTER pBlitter);
 void CrDpResize(PCR_DISPLAY pDisplay, uint32_t width, uint32_t height,
         uint32_t stretchedWidth, uint32_t stretchedHeight);
 void CrDpEntryInit(PCR_DISPLAY_ENTRY pEntry, PCR_BLITTER_TEXTURE pTextureData);
 void CrDpEntryCleanup(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry);
-int CrDpPresentTexture(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions);
+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)
 {
@@ -343,10 +351,4 @@
     return &pDisplay->Mural;
 }
-
-DECLINLINE(CRCreateInfo_t*) CrDpGetMuralCreateInfo(PCR_DISPLAY pDisplay)
-{
-    return &pDisplay->MuralCreateInfo;
-}
-
 
 typedef struct CR_DISPLAY_ENTRY_MAP
@@ -387,5 +389,4 @@
 
     CRHashTable *muralTable;  /**< hash table where all murals are stored */
-    CRHashTable *pWindowCreateInfoTable; /**< hash table with windows creation info */
 
     int client_spu_id;
@@ -467,6 +468,7 @@
 
     PFNCRSERVERPRESENTFBO pfnPresentFBO;
-    GLboolean             bForceOffscreenRendering; /*Force server to render 3d data offscreen
+    GLubyte               bForceOffscreenRendering; /*Force server to render 3d data offscreen
                                                      *using callback above to update vbox framebuffers*/
+    GLubyte               bOffscreenRenderingDefault; /*can be set with CR_SERVER_DEFAULT_RENDER_TYPE*/
     GLboolean             bUsePBOForReadback;       /*Use PBO's for data readback*/
 
@@ -476,7 +478,11 @@
     GLboolean             bUseMultipleContexts;
 
-    uint8_t               fPresentBlitterInited;
+    /* @todo: should we use just one blitter?
+     * we use two currently because the drawable attribs can differ*/
+    int8_t                fPresentBlitterInited;
+    int8_t                fFBOModeBlitterInited;
     CR_DISPLAY_ENTRY_MAP  PresentTexturepMap;
     CR_BLITTER            PresentBlitter;
+    CR_BLITTER            FBOModeBlitter;
     uint32_t              DisplaysInitMap[(CR_MAX_GUEST_MONITORS + 31)/32];
     CR_DISPLAY            aDispplays[CR_MAX_GUEST_MONITORS];
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 43932)
@@ -117,6 +117,4 @@
 void crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height);
 
-void crServerCreateInfoDeleteCB(void *data);
-
 GLint crServerGenerateID(GLint *pCounter);
 
@@ -128,11 +126,21 @@
 void crServerCheckMuralGeometry(CRMuralInfo *mural);
 GLboolean crServerSupportRedirMuralFBO(void);
-void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir);
+
+#define CR_SERVER_REDIR_NONE     0
+#define CR_SERVER_REDIR_FBO_BLT  1
+#define CR_SERVER_REDIR_FBO_RAM  2
+#define CR_SERVER_REDIR_MAXVAL   CR_SERVER_REDIR_FBO_RAM
+
+int32_t crServerSetOffscreenRenderingMode(GLubyte value);
+void crServerRedirMuralFBO(CRMuralInfo *mural, GLubyte redir);
 void crServerCreateMuralFBO(CRMuralInfo *mural);
 void crServerDeleteMuralFBO(CRMuralInfo *mural);
 void crServerPresentFBO(CRMuralInfo *mural);
 GLboolean crServerIsRedirectedToFBO();
+PCR_BLITTER crServerGetFBOPresentBlitter(CRMuralInfo*pMural);
 
 int32_t crVBoxServerInternalClientRead(CRClient *pClient, uint8_t *pBuffer, uint32_t *pcbBuffer);
+
+PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen);
 
 RT_C_DECLS_END
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_blitter.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_blitter.cpp	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_blitter.cpp	(revision 43932)
@@ -31,5 +31,5 @@
 
 
-int CrBltInit(PCR_BLITTER pBlitter, CRMuralInfo *pCurrentMural, GLint visualBits)
+int CrBltInit(PCR_BLITTER pBlitter, CRMuralInfo *pCurrentMural)
 {
     memset(pBlitter, 0, sizeof (*pBlitter));
@@ -43,5 +43,5 @@
 
     pBlitter->CtxInfo.CreateInfo.pszDpyName = "";
-    pBlitter->CtxInfo.CreateInfo.visualBits = visualBits;
+    pBlitter->CtxInfo.CreateInfo.visualBits = pCurrentMural->CreateInfo.visualBits;
     pBlitter->CtxInfo.SpuContext = cr_server.head_spu->dispatch_table.CreateContext(pBlitter->CtxInfo.CreateInfo.pszDpyName,
                                         pBlitter->CtxInfo.CreateInfo.visualBits,
@@ -379,5 +379,7 @@
 
     if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
-        cr_server.head_spu->dispatch_table.MakeCurrent(pBlitter->pRestoreMural->spuWindow, 0, pBlitter->pRestoreCtxInfo->SpuContext);
+        cr_server.head_spu->dispatch_table.MakeCurrent(pBlitter->pRestoreMural->spuWindow, 0,
+                pBlitter->pRestoreCtxInfo->SpuContext >= 0
+                    ? pBlitter->pRestoreCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext);
     else
         cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
@@ -410,5 +412,8 @@
     int rc = crBltInitOnMakeCurent(pBlitter);
     if (RT_SUCCESS(rc))
+    {
+        pBlitter->Flags.Initialized = 1;
         return VINF_SUCCESS;
+    }
 
     crWarning("crBltInitOnMakeCurent failed, rc %d", rc);
@@ -447,2 +452,9 @@
 }
 
+void CrBltPresent(PCR_BLITTER pBlitter)
+{
+    if (pBlitter->CtxInfo.CreateInfo.visualBits & CR_DOUBLE_BIT)
+        cr_server.head_spu->dispatch_table.SwapBuffers(pBlitter->pCurrentMural->spuWindow, 0);
+    else
+        cr_server.head_spu->dispatch_table.Flush();
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_config.c	(revision 43932)
@@ -56,5 +56,6 @@
 
     cr_server.screenCount = 0;
-    cr_server.bForceOffscreenRendering = GL_FALSE;
+    cr_server.bForceOffscreenRendering = CR_SERVER_REDIR_NONE;
+    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;
     cr_server.bUsePBOForReadback = GL_FALSE;
     cr_server.bUseOutputRedirect = GL_FALSE;
@@ -80,4 +81,5 @@
     char **clientchain, **clientlist;
     GLint dims[4];
+    char * env;
 
     defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
@@ -156,4 +158,19 @@
         crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server);
 
+    env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
+    if (env != NULL)
+    {
+        GLubyte redir = (env[0] - 0x30);
+        if (redir <= CR_SERVER_REDIR_MAXVAL)
+        {
+            int rc = crServerSetOffscreenRenderingMode(redir);
+            if (!RT_SUCCESS(rc))
+                            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
+        }
+        else
+            crWarning("invalid redir option %c", redir);
+    }
+    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;
+
     /* Need to do this as early as possible */
 
@@ -259,4 +276,5 @@
     int i;
     GLint dims[4];
+    char * env;
 
     defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
@@ -272,4 +290,19 @@
     if (!cr_server.head_spu)
         return;
+
+    env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
+    if (env != NULL)
+    {
+        GLubyte redir = (env[0] - 0x30);
+        if (redir <= CR_SERVER_REDIR_MAXVAL)
+        {
+            int rc = crServerSetOffscreenRenderingMode(redir);
+            if (!RT_SUCCESS(rc))
+                            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
+        }
+        else
+            crWarning("invalid redir option %c", redir);
+    }
+    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;
 
     cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 43932)
@@ -332,5 +332,5 @@
      * crStateSwichPrepare restores the FBO state to its default values before the context window switch,
      * while crStateSwichPostprocess restores it back to the original values */
-    oldCtx = crStateSwichPrepare(ctx, cr_server.bUseMultipleContexts, oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO() ? oldMural->idFBO : 0);
+    oldCtx = crStateSwichPrepare(ctx, cr_server.bUseMultipleContexts, oldMural && oldMural->fUseFBO && crServerSupportRedirMuralFBO() ? oldMural->idFBO : 0);
 
     /*
@@ -395,5 +395,5 @@
     crStateMakeCurrent( ctx );
 
-    crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->bUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0);
+    crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->fUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0);
 
     if (!ctx->framebufferobject.drawFB
@@ -401,5 +401,5 @@
         cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
 
-    if (!mural->bUseFBO)
+    if (!mural->fUseFBO)
     {
         ctx->buffer.width = mural->width;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 43932)
@@ -150,7 +150,4 @@
     crFreeHashtable(cr_server.contextTable, deleteContextInfoCallback);
 
-    /* Free context/window creation info */
-    crFreeHashtable(cr_server.pWindowCreateInfoTable, crServerCreateInfoDeleteCB);
-
     /* Free vertex programs */
     crFreeHashtable(cr_server.programTable, crFree);
@@ -386,6 +383,4 @@
      */
     cr_server.contextTable = crAllocHashtable();
-//    cr_server.pContextCreateInfoTable = crAllocHashtable();
-    cr_server.pWindowCreateInfoTable = crAllocHashtable();
 
     crServerSetVBoxConfigurationHGCM();
@@ -691,5 +686,5 @@
     CRASSERT(rc == VINF_SUCCESS);
 
-    rc = SSMR3PutMem(pSSM, pMI, sizeof(*pMI));
+    rc = SSMR3PutMem(pSSM, pMI, RT_OFFSETOF(CRMuralInfo, CreateInfo));
     CRASSERT(rc == VINF_SUCCESS);
 
@@ -708,4 +703,7 @@
 
     CRASSERT(pCreateInfo && pSSM);
+
+    /* Don't store default mural create info */
+    if (!key) return;
 
     rc = SSMR3PutMem(pSSM, &key, sizeof(key));
@@ -844,15 +842,14 @@
 
     /* Save windows creation info */
-    ui32 = crHashtableNumElements(cr_server.pWindowCreateInfoTable);
-    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
+    ui32 = crHashtableNumElements(cr_server.muralTable);
+    /* There should be default mural always */
+    CRASSERT(ui32>=1);
+    rc = SSMR3PutU32(pSSM, (uint32_t) ui32-1);
     AssertRCReturn(rc, rc);
-    crHashtableWalk(cr_server.pWindowCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM);
+    crHashtableWalk(cr_server.muralTable, crVBoxServerSaveCreateInfoCB, pSSM);
 
     /* Save cr_server.muralTable
      * @todo we don't need it all, just geometry info actually
      */
-    ui32 = crHashtableNumElements(cr_server.muralTable);
-    /* There should be default mural always */
-    CRASSERT(ui32>=1);
     rc = SSMR3PutU32(pSSM, (uint32_t) ui32-1);
     AssertRCReturn(rc, rc);
@@ -1028,5 +1025,5 @@
         rc = SSMR3GetMem(pSSM, &key, sizeof(key));
         AssertRCReturn(rc, rc);
-        rc = SSMR3GetMem(pSSM, &muralInfo, sizeof(muralInfo));
+        rc = SSMR3GetMem(pSSM, &muralInfo, RT_OFFSETOF(CRMuralInfo, CreateInfo));
         AssertRCReturn(rc, rc);
 
@@ -1332,4 +1329,10 @@
 #endif
 
+    {
+        PCR_DISPLAY pDisplay = crServerDisplayGetInitialized(sIndex);
+        if (pDisplay)
+            CrDpResize(pDisplay, w, h, w, h);
+    }
+
     return VINF_SUCCESS;
 }
@@ -1347,21 +1350,32 @@
 }
 
+int32_t crServerSetOffscreenRenderingMode(GLubyte value)
+{
+    if (cr_server.bForceOffscreenRendering==value)
+    {
+        return VINF_SUCCESS;
+    }
+
+    if (value > CR_SERVER_REDIR_MAXVAL)
+    {
+        crWarning("crServerSetOffscreenRenderingMode: invalid arg: %d", value);
+        return VERR_INVALID_PARAMETER;
+    }
+
+    if (value && !crServerSupportRedirMuralFBO())
+    {
+        return VERR_NOT_SUPPORTED;
+    }
+
+    cr_server.bForceOffscreenRendering=value;
+
+    crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
+
+    return VINF_SUCCESS;
+}
+
 DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value)
 {
-    if (cr_server.bForceOffscreenRendering==value)
-    {
-        return VINF_SUCCESS;
-    }
-
-    if (value && !crServerSupportRedirMuralFBO())
-    {
-        return VERR_NOT_SUPPORTED;
-    }
-
-    cr_server.bForceOffscreenRendering=value;
-
-    crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL);
-
-    return VINF_SUCCESS;
+    return crServerSetOffscreenRenderingMode(value ? CR_SERVER_REDIR_FBO_RAM : cr_server.bOffscreenRenderingDefault);
 }
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 43932)
@@ -264,12 +264,4 @@
 }
 
-void crServerCreateInfoDeleteCB(void *data)
-{
-    CRCreateInfo_t *pCreateInfo = (CRCreateInfo_t *) data;
-    if (pCreateInfo->pszDpyName)
-        crFree(pCreateInfo->pszDpyName);
-    crFree(pCreateInfo);
-}
-
 GLint crServerGenerateID(GLint *pCounter)
 {
@@ -875,5 +867,5 @@
             cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
 
-        if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
+        if (crServerIsRedirectedToFBO()
                 && cr_server.curClient->currentMural->idFBO)
         {
@@ -903,5 +895,5 @@
     crStateReadBuffer( mode );
 
-    if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
+    if (crServerIsRedirectedToFBO()
             && cr_server.curClient->currentMural->idFBO
             && !crStateGetCurrent()->framebufferobject.readFB)
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 43932)
@@ -108,4 +108,5 @@
         CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
         CRASSERT(cr_server.screenCount>0);
+        CRASSERT(mural->fUseFBO == CR_SERVER_REDIR_NONE);
 
         mural->hX = mural->gX-cr_server.screen[0].x;
@@ -163,7 +164,7 @@
         CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
 
-        if (mural->bUseFBO)
-        {
-            crServerRedirMuralFBO(mural, GL_FALSE);
+        if (mural->fUseFBO)
+        {
+            crServerRedirMuralFBO(mural, CR_SERVER_REDIR_NONE);
             crServerDeleteMuralFBO(mural);
         }
@@ -173,19 +174,21 @@
     else
     {
+        GLubyte redir = overlappingScreenCount >= 2 ? CR_SERVER_REDIR_FBO_RAM : cr_server.bForceOffscreenRendering;
+
         if (mural->spuWindow)
         {
-            if (!mural->bUseFBO)
-            {
-                crServerRedirMuralFBO(mural, GL_TRUE);
-            }
-            else
+            if (mural->fUseFBO)
             {
                 if (mural->width!=mural->fboWidth
                     || mural->height!=mural->height)
                 {
-                    crServerRedirMuralFBO(mural, GL_FALSE);
+                    crServerRedirMuralFBO(mural, CR_SERVER_REDIR_NONE);
                     crServerDeleteMuralFBO(mural);
-                    crServerRedirMuralFBO(mural, GL_TRUE);
                 }
+            }
+
+            if (mural->fUseFBO != redir)
+            {
+                crServerRedirMuralFBO(mural, redir);
             }
         }
@@ -193,9 +196,9 @@
         else
         {
-            Assert(!mural->bUseFBO);
+            Assert(!mural->fUseFBO);
         }
 #endif
 
-        if (!mural->bUseFBO)
+        if (mural->fUseFBO != CR_SERVER_REDIR_FBO_RAM)
         {
             CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId];
@@ -229,6 +232,12 @@
 }
 
-void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir)
-{
+void crServerRedirMuralFBO(CRMuralInfo *mural, GLubyte redir)
+{
+    if (mural->fUseFBO == redir)
+    {
+        crWarning("crServerRedirMuralFBO called with the same redir status %d", redir);
+        return;
+    }
+
     if (redir)
     {
@@ -239,5 +248,8 @@
         }
 
-        cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, GL_FALSE);
+        if (redir == CR_SERVER_REDIR_FBO_RAM)
+            cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, GL_FALSE);
+        else
+            cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible);
 
         if (mural->idFBO==0)
@@ -263,7 +275,8 @@
     else
     {
-        cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible);
-
-        if (mural->bUseFBO && crServerSupportRedirMuralFBO())
+        if (mural->fUseFBO == CR_SERVER_REDIR_FBO_RAM)
+            cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible);
+
+        if (mural->fUseFBO && crServerSupportRedirMuralFBO())
         {
             if (!crStateGetCurrent()->framebufferobject.drawFB)
@@ -284,5 +297,5 @@
     }
 
-    mural->bUseFBO = redir;
+    mural->fUseFBO = redir;
 }
 
@@ -371,5 +384,5 @@
 void crServerDeleteMuralFBO(CRMuralInfo *mural)
 {
-    CRASSERT(!mural->bUseFBO);
+    CRASSERT(!mural->fUseFBO);
 
     if (mural->idFBO!=0)
@@ -452,5 +465,6 @@
     CRContext *ctx = crStateGetCurrent();
 
-    CRASSERT(cr_server.pfnPresentFBO);
+    CRASSERT(mural->fUseFBO);
+    CRASSERT(cr_server.pfnPresentFBO || mural->fUseFBO == CR_SERVER_REDIR_FBO_BLT);
 
     if (!mural->bVisible)
@@ -461,4 +475,48 @@
     if (!mural->width || !mural->height)
     {
+        return;
+    }
+
+    if (mural->fUseFBO == CR_SERVER_REDIR_FBO_BLT)
+    {
+        int rc;
+        PCR_BLITTER pBlitter = crServerGetFBOPresentBlitter(mural);
+        if (!pBlitter)
+        {
+            static int cPrintedWarnings = 0;
+            if (++cPrintedWarnings <= 5)
+            {
+                crWarning("crServerGetFBOPresentBlitter returned no blitter %d", cPrintedWarnings);
+                if (cPrintedWarnings == 5)
+                    crWarning("won't print the above crServerGetFBOPresentBlitter warning any more", cPrintedWarnings);
+            }
+            return;
+        }
+
+        CrBltMuralSetCurrent(pBlitter, mural);
+        rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
+        if (RT_SUCCESS(rc))
+        {
+            CR_BLITTER_TEXTURE Tex;
+            RTRECT Rect;
+            Tex.width = mural->width;
+            Tex.height = mural->height;
+            Tex.target = GL_TEXTURE_2D;
+            Tex.hwid = mural->idColorTex;
+            Rect.xLeft = 0;
+            Rect.yTop = 0;
+            Rect.xRight = Tex.width;
+            Rect.yBottom = Tex.height;
+
+            CrBltBlitTexMural(pBlitter, &Tex, &Rect, &Rect, 1, 0);
+            CrBltPresent(pBlitter);
+
+            CrBltLeave(pBlitter);
+        }
+        else
+        {
+            crWarning("CrBltEnter failed rc %d", rc);
+            return;
+        }
         return;
     }
@@ -588,4 +646,4 @@
     return cr_server.curClient
            && cr_server.curClient->currentMural
-           && cr_server.curClient->currentMural->bUseFBO;
-}
+           && cr_server.curClient->currentMural->fUseFBO;
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp	(revision 43932)
@@ -32,15 +32,4 @@
 #include <iprt/mem.h>
 
-typedef DECLCALLBACK(int) FNCRDISPLAY_REGIONS_CHANGED(struct CR_PRESENTER *pPresenter);
-typedef FNCRDISPLAY_REGIONS_CHANGED *PFNCRDISPLAY_REGIONS_CHANGED;
-
-typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_ENTRY(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter);
-typedef FNCRDISPLAY_DRAW_ENTRY *PFNCRDISPLAY_DRAW_ENTRY;
-
-typedef DECLCALLBACK(int) FNCRDISPLAY_DRAW_TEXTURE(struct CR_PRESENTER *pPresenter, PCR_BLITTER pBlitter,
-                                            CR_BLITTER_TEXTURE *pTexture, const RTRECT *paSrcRects, const RTRECT *paDstRects, uint32_t cRects);
-typedef FNCRDISPLAY_DRAW_TEXTURE *PFNCRDISPLAY_DRAW_TEXTURE;
-
-
 #define CR_DISPLAY_RECTS_UNDEFINED UINT32_MAX
 
@@ -212,6 +201,9 @@
 }
 
-DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter)
-{
+DECLCALLBACK(int) CrPtCbDrawEntrySingle(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn)
+{
+    if (pfAllEntriesDrawn)
+        *pfAllEntriesDrawn = false;
+
     int rc = crPtRectsCheckInit(pPresenter);
     if (!RT_SUCCESS(rc))
@@ -241,13 +233,14 @@
     struct CR_PRESENTER_ENTRY *pEntry = CR_PRESENTER_ENTRY_FROM_ENTRY(pCEntry);
     PCR_BLITTER pBlitter = (PCR_BLITTER)pvVisitor;
-    int rc = CrPtCbDrawEntrySingle(pPresenter, pEntry, pBlitter);
+    bool fAllEntriesDrawn;
+    int rc = CrPtCbDrawEntrySingle(pPresenter, pEntry, pBlitter, &fAllEntriesDrawn);
     if (!RT_SUCCESS(rc))
     {
         crWarning("CrPtCbDrawEntrySingle failed, rc %d", rc);
     }
-    return true;
-}
-
-DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter)
+    return !fAllEntriesDrawn;
+}
+
+DECLCALLBACK(int) CrPtCbDrawEntryAll(struct CR_PRESENTER *pPresenter, struct CR_PRESENTER_ENTRY *pEntry, PCR_BLITTER pBlitter, bool *pfAllEntriesDrawn)
 {
     int rc = crPtRectsCheckInit(pPresenter);
@@ -258,5 +251,8 @@
     }
 
-    VBoxVrCompositorVisit(&pPresenter->Compositor, crPtDrawEntryAllCb, pPresenter);
+    VBoxVrCompositorVisit(&pPresenter->Compositor, crPtDrawEntryAllCb, pBlitter);
+
+    if (pfAllEntriesDrawn)
+        *pfAllEntriesDrawn = true;
 
     return VINF_SUCCESS;
@@ -289,15 +285,102 @@
 }
 
+static int crPtEntryRegionsSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, uint32_t cRegions, const RTRECT *paRegions, bool *pfChanged)
+{
+    bool fChanged;
+    int rc = VBoxVrCompositorEntryRegionsSet(&pPresenter->Compositor, &pEntry->Ce, cRegions, paRegions, &fChanged);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("VBoxVrCompositorEntryRegionsSet failed, rc %d", rc);
+        return rc;
+    }
+
+    if (fChanged)
+    {
+        crPtRectsInvalidate(pPresenter);
+        rc = pPresenter->pfnRegionsChanged(pPresenter);
+        if (!RT_SUCCESS(rc))
+        {
+            crWarning("pfnRegionsChanged failed, rc %d", rc);
+            return rc;
+        }
+    }
+
+    if (pfChanged)
+        *pfChanged = fChanged;
+    return VINF_SUCCESS;
+}
+
 static void crPtEntryPositionSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos)
 {
-    if (pEntry && pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y)
-    {
-        VBoxVrCompositorEntryRemove(&pPresenter->Compositor, &pEntry->Ce);
-        crPtRectsInvalidate(pPresenter);
+    if (pEntry && (pEntry->Pos.x != pPos->x || pEntry->Pos.y != pPos->y))
+    {
+        if (VBoxVrCompositorEntryIsInList(&pEntry->Ce))
+        {
+            VBoxVrCompositorEntryRemove(&pPresenter->Compositor, &pEntry->Ce);
+            crPtRectsInvalidate(pPresenter);
+        }
         pEntry->Pos = *pPos;
     }
 }
 
-int CrPtEntryPresent(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions, PCR_BLITTER pBlitter)
+int CrPtPresentEntry(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, PCR_BLITTER pBlitter)
+{
+    int rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrBltEnter failed, rc %d", rc);
+        return rc;
+    }
+
+    rc = pPresenter->pfnDrawEntry(pPresenter, pEntry, pBlitter, NULL);
+
+    CrBltLeave(pBlitter);
+
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("pfnDraw failed, rc %d", rc);
+        return rc;
+    }
+
+    return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(bool) crPtPresentCb(PVBOXVR_COMPOSITOR pCompositor, PVBOXVR_COMPOSITOR_ENTRY pCEntry, void *pvVisitor)
+{
+    struct CR_PRESENTER *pPresenter = CR_PRESENTER_FROM_COMPOSITOR(pCompositor);
+    struct CR_PRESENTER_ENTRY *pEntry = CR_PRESENTER_ENTRY_FROM_ENTRY(pCEntry);
+    PCR_BLITTER pBlitter = (PCR_BLITTER)pvVisitor;
+    bool fAllDrawn = false;
+    int rc = pPresenter->pfnDrawEntry(pPresenter, pEntry, pBlitter, &fAllDrawn);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("pfnDrawEntry failed, rc %d", rc);
+    }
+    return !fAllDrawn;
+}
+
+int CrPtPresent(PCR_PRESENTER pPresenter, PCR_BLITTER pBlitter)
+{
+    int rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrBltEnter failed, rc %d", rc);
+        return rc;
+    }
+
+    VBoxVrCompositorVisit(&pPresenter->Compositor, crPtPresentCb, pBlitter);
+
+    CrBltLeave(pBlitter);
+
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("pfnDraw failed, rc %d", rc);
+        return rc;
+    }
+
+    return VINF_SUCCESS;
+}
+
+int CrPtEntryRegionsAdd(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
 {
     crPtEntryPositionSet(pPresenter, pEntry, pPos);
@@ -310,23 +393,18 @@
     }
 
-    if (!pEntry)
-        return VINF_SUCCESS;
-
-    rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
-    if (!RT_SUCCESS(rc))
-    {
-        crWarning("CrBltEnter failed, rc %d", rc);
-        return rc;
-    }
-
-    rc = pPresenter->pfnDrawEntry(pPresenter, pEntry, pBlitter);
-
-    CrBltLeave(pBlitter);
-
-    if (!RT_SUCCESS(rc))
-    {
-        crWarning("pfnDrawEntry failed, rc %d", rc);
-        return rc;
-    }
+    return VINF_SUCCESS;
+}
+
+int CrPtEntryRegionsSet(PCR_PRESENTER pPresenter, PCR_PRESENTER_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
+{
+    crPtEntryPositionSet(pPresenter, pEntry, pPos);
+
+    int rc = crPtEntryRegionsSet(pPresenter, pEntry, cRegions, paRegions, NULL);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("crPtEntryRegionsAdd failed, rc %d", rc);
+        return rc;
+    }
+
     return VINF_SUCCESS;
 }
@@ -429,6 +507,6 @@
 int CrDpInit(PCR_DISPLAY pDisplay)
 {
-    const GLint visBits = CR_RGB_BIT;
-    int rc = CrPtInit(&pDisplay->Presenter, crDpCbRegionsChanged, CrPtCbDrawEntrySingle, crDpCbDrawTextureWindow);
+    const GLint visBits = CR_RGB_BIT | CR_DOUBLE_BIT;
+    int rc = CrPtInit(&pDisplay->Presenter, crDpCbRegionsChanged, CrPtCbDrawEntryAll, crDpCbDrawTextureWindow);
     if (RT_SUCCESS(rc))
     {
@@ -455,7 +533,7 @@
 }
 
-bool CrDpBlitterTest(PCR_DISPLAY pDisplay, PCR_BLITTER pBlitter)
-{
-    CrBltMuralSetCurrent(pBlitter, &pDisplay->Mural);
+int CrDpBlitterTestWithMural(PCR_BLITTER pBlitter, CRMuralInfo *pMural)
+{
+    CrBltMuralSetCurrent(pBlitter, pMural);
     /* try to enter to make sure the blitter is initialized completely and to make sure we actually can do that */
     int rc = CrBltEnter(pBlitter, cr_server.currentCtxInfo, cr_server.currentMural);
@@ -463,5 +541,5 @@
     {
         CrBltLeave(pBlitter);
-        return true;
+        return VINF_SUCCESS;
     }
     else
@@ -469,5 +547,10 @@
         crWarning("CrBltEnter failed, rc %d", rc);
     }
-    return false;
+    return rc;
+}
+
+int CrDpBlitterTest(PCR_DISPLAY pDisplay, PCR_BLITTER pBlitter)
+{
+    return CrDpBlitterTestWithMural(pBlitter, &pDisplay->Mural);
 }
 
@@ -482,7 +565,17 @@
 }
 
-int CrDpPresentTexture(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
-{
-    return CrPtEntryPresent(&pDisplay->Presenter, &pEntry->Pe, pPos, cRegions, paRegions, pDisplay->pBlitter);
+int CrDpEntryRegionsSet(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
+{
+    return CrPtEntryRegionsSet(&pDisplay->Presenter, &pEntry->Pe, pPos, cRegions, paRegions);
+}
+
+int CrDpEntryRegionsAdd(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry, const RTPOINT *pPos, uint32_t cRegions, const RTRECT *paRegions)
+{
+    return CrPtEntryRegionsAdd(&pDisplay->Presenter, &pEntry->Pe, pPos, cRegions, paRegions);
+}
+
+int CrDpPresentEntry(PCR_DISPLAY pDisplay, PCR_DISPLAY_ENTRY pEntry)
+{
+    return CrPtPresentEntry(&pDisplay->Presenter, &pEntry->Pe, pDisplay->pBlitter);
 }
 
@@ -582,5 +675,40 @@
 #define CR_PRESENT_GET_FLAGS(_cfg) ((_cfg) >> CR_PRESENT_FLAGS_OFFSET)
 
-static uint8_t crServerCheckInitDisplayBlitter()
+int crServerBlitterInit(PCR_BLITTER pBlitter, CRMuralInfo*pMural)
+{
+    int rc = CrBltInit(pBlitter, pMural);
+    if (RT_SUCCESS(rc))
+    {
+        rc = CrDpBlitterTestWithMural(pBlitter, pMural);
+        if (RT_SUCCESS(rc))
+            return VINF_SUCCESS;
+        else
+            crWarning("CrDpBlitterTestWithMural failed, rc %d", rc);
+        CrBltTerm(pBlitter);
+    }
+    else
+        crWarning("CrBltInit failed, rc %d", rc);
+    return rc;
+}
+
+PCR_BLITTER crServerGetFBOPresentBlitter(CRMuralInfo*pMural)
+{
+    if (cr_server.fFBOModeBlitterInited > 0)
+        return &cr_server.FBOModeBlitter;
+    if (!cr_server.fFBOModeBlitterInited)
+    {
+        int rc = crServerBlitterInit(&cr_server.FBOModeBlitter, pMural);
+        if (RT_SUCCESS(rc))
+        {
+            cr_server.fFBOModeBlitterInited = 1;
+            return &cr_server.FBOModeBlitter;
+        }
+        crWarning("crServerBlitterInit failed rc %d", rc);
+        cr_server.fFBOModeBlitterInited = -1;
+    }
+    return NULL;
+}
+
+static int8_t crServerCheckInitDisplayBlitter()
 {
     if (cr_server.fPresentBlitterInited)
@@ -597,24 +725,18 @@
         {
             CRMuralInfo*pMural = CrDpGetMural(&cr_server.aDispplays[0]);
-            CRCreateInfo_t*pCreateInfo = CrDpGetMuralCreateInfo(&cr_server.aDispplays[0]);
-            rc = CrBltInit(&cr_server.PresentBlitter, pMural, pCreateInfo->visualBits);
+            rc = crServerBlitterInit(&cr_server.PresentBlitter, pMural);
             if (RT_SUCCESS(rc))
             {
-                if (CrDpBlitterTest(&cr_server.aDispplays[0], &cr_server.PresentBlitter))
-                {
-                    CrDpBlitterSet(&cr_server.aDispplays[0], &cr_server.PresentBlitter);
-                    ASMBitSet(cr_server.DisplaysInitMap, 0);
-                    cr_server.fPresentBlitterInited = 1;
-                    return 1;
-                }
-                else
-                {
-                    crWarning("CrDpBlitterTest failed");
-                }
-                CrBltTerm(&cr_server.PresentBlitter);
+                CrDpBlitterSet(&cr_server.aDispplays[0], &cr_server.PresentBlitter);
+                CrDpResize(&cr_server.aDispplays[0],
+                            cr_server.screen[0].w, cr_server.screen[0].h,
+                            cr_server.screen[0].w, cr_server.screen[0].h);
+                ASMBitSet(cr_server.DisplaysInitMap, 0);
+                cr_server.fPresentBlitterInited = 1;
+                return 1;
             }
             else
             {
-                crWarning("CrBltInit failed, rc %d", rc);
+                crWarning("crServerBlitterInit failed, rc %d", rc);
             }
             CrDpTerm(&cr_server.aDispplays[0]);
@@ -638,4 +760,11 @@
 {
     return crServerCheckInitDisplayBlitter() > 0;
+}
+
+PCR_DISPLAY crServerDisplayGetInitialized(uint32_t idScreen)
+{
+    if (ASMBitTest(cr_server.DisplaysInitMap, idScreen))
+        return &cr_server.aDispplays[idScreen];
+    return NULL;
 }
 
@@ -662,4 +791,7 @@
         {
             CrDpBlitterSet(&cr_server.aDispplays[idScreen], &cr_server.PresentBlitter);
+            CrDpResize(&cr_server.aDispplays[idScreen],
+                    cr_server.screen[idScreen].w, cr_server.screen[idScreen].h,
+                    cr_server.screen[idScreen].w, cr_server.screen[idScreen].h);
             ASMBitSet(cr_server.DisplaysInitMap, idScreen);
             return &cr_server.aDispplays[idScreen];
@@ -697,8 +829,16 @@
 
     RTPOINT Point = {xPos, yPos};
-    int rc = CrDpPresentTexture(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects);
-    if (!RT_SUCCESS(rc))
-    {
-        crWarning("CrDpPresentTexture Failed rc %d", rc);
-    }
-}
+    int rc = CrDpEntryRegionsAdd(pDisplay, pEntry, &Point, (uint32_t)cRects, (const RTRECT*)pRects);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrDpEntrySetRegions Failed rc %d", rc);
+        return;
+    }
+
+    rc = CrDpPresentEntry(pDisplay, pEntry);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrDpEntrySetRegions Failed rc %d", rc);
+        return;
+    }
+}
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_simpleget.py	(revision 43932)
@@ -76,6 +76,5 @@
         CRASSERT(tablesize/sizeof(%s)==1);
         fboid = crStateFBOHWIDtoID((GLuint) *get_values);
-        if (cr_server.curClient->currentMural->bUseFBO
-            && crServerIsRedirectedToFBO()
+        if (crServerIsRedirectedToFBO()
             && fboid==cr_server.curClient->currentMural->idFBO)
         {
@@ -86,5 +85,5 @@
     else if (GL_READ_BUFFER==pname)
     {
-        if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
+        if (crServerIsRedirectedToFBO()
             && cr_server.curClient->currentMural->idFBO
             && !crStateGetCurrent()->framebufferobject.readFB)
@@ -95,5 +94,5 @@
     else if (GL_DRAW_BUFFER==pname)
     {
-        if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
+        if (crServerIsRedirectedToFBO()
             && cr_server.curClient->currentMural->idFBO
             && !crStateGetCurrent()->framebufferobject.drawFB)
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 43931)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 43932)
@@ -44,5 +44,5 @@
     mural->screenId = 0;
     mural->bVisible = GL_FALSE;
-    mural->bUseFBO = GL_FALSE;
+    mural->fUseFBO = CR_SERVER_REDIR_NONE;
 
     mural->cVisibleRects = 0;
@@ -58,4 +58,8 @@
         windowID = preloadWinID<0 ? crServerGenerateID(&cr_server.idsPool.freeWindowID) : preloadWinID;
 
+    mural->CreateInfo.visualBits = visBits;
+    mural->CreateInfo.externalID = windowID;
+    mural->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
+
     crServerSetupOutputRedirect(mural);
 
@@ -68,5 +72,4 @@
     CRMuralInfo *mural;
     GLint windowID = -1;
-    CRCreateInfo_t *pCreateInfo;
 
     if (cr_server.sharedWindows) {
@@ -119,9 +122,4 @@
     crHashtableAdd(cr_server.muralTable, windowID, mural);
 
-    pCreateInfo = (CRCreateInfo_t *) crAlloc(sizeof(CRCreateInfo_t));
-    pCreateInfo->pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
-    pCreateInfo->visualBits = visBits;
-    crHashtableAdd(cr_server.pWindowCreateInfoTable, windowID, pCreateInfo);
-
     crDebug("CRServer: client %p created new window %d (SPU window %d)",
                     cr_server.curClient, windowID, mural->spuWindow);
@@ -165,5 +163,5 @@
     }
 
-    crServerRedirMuralFBO(mural, GL_FALSE);
+    crServerRedirMuralFBO(mural, CR_SERVER_REDIR_NONE);
     crServerDeleteMuralFBO(mural);
 
@@ -270,5 +268,6 @@
     }
 
-    crHashtableDelete(cr_server.pWindowCreateInfoTable, window, crServerCreateInfoDeleteCB);
+    if (mural->CreateInfo.pszDpyName)
+        crFree(mural->CreateInfo.pszDpyName);
 
     crHashtableDelete(cr_server.muralTable, window, crFree);
@@ -389,5 +388,5 @@
     }
 
-    if (!mural->bUseFBO)
+    if (mural->fUseFBO != CR_SERVER_REDIR_FBO_RAM)
     {
         cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, state);
