Index: trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk	(revision 46343)
@@ -152,4 +152,11 @@
 VBoxOGLcrserverlib_DEFS += ifdef VBOX_WITH_CRHGSMI
 endif
+ifdef VBOX_WITH_CRDUMPER
+VBoxOGLcrserverlib_DEFS        += VBOX_WITH_CRDUMPER
+endif
+ifdef VBOX_WITH_CRSERVER_DUMPER
+VBoxOGLcrserverlib_DEFS        += VBOX_WITH_CRSERVER_DUMPER
+endif
+
 
 #
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 46343)
@@ -351,5 +351,5 @@
 } CR_SERVER_CTX_SWITCH;
 
-DECLINLINE(void) cr_serverCtxSwitchPrepare(CR_SERVER_CTX_SWITCH *pData, CRContext *pNewCtx)
+DECLINLINE(void) crServerCtxSwitchPrepare(CR_SERVER_CTX_SWITCH *pData, CRContext *pNewCtx)
 {
     CRMuralInfo *pCurrentMural = cr_server.currentMural;
@@ -379,8 +379,55 @@
 }
 
-DECLINLINE(void) cr_serverCtxSwitchPostprocess(CR_SERVER_CTX_SWITCH *pData)
+DECLINLINE(void) crServerCtxSwitchPostprocess(CR_SERVER_CTX_SWITCH *pData)
 {
     crStateSwitchPostprocess(pData->pOldCtx, pData->pNewCtx, pData->idDrawFBO, pData->idReadFBO);
 }
+
+void crServerInitTmpCtxDispatch();
+
+#ifdef VBOX_WITH_CRSERVER_DUMPER
+void crServerDumpCheckTerm();
+int crServerDumpCheckInit();
+void crServerDumpBuffer();
+void crServerDumpTextures();
+
+#define CR_SERVER_DUMP_F_DRAW_BUFF_ENTER 0x01
+#define CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE  0x02
+#define CR_SERVER_DUMP_F_DRAW_TEX_ENTER  0x10
+#define CR_SERVER_DUMP_F_DRAW_TEX_LEAVE   0x20
+
+extern int g_CrDbgDumpDraw;
+bool crServerDumpFilter(int event);
+
+#define CR_SERVER_DUMP_IF_ANY(_ev) ((g_CrDbgDumpDraw & (_ev)) && crServerDumpFilter((_ev)))
+
+#define CR_SERVER_DUMP_DRAW_ENTER() do { \
+            if (!CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_BUFF_ENTER | CR_SERVER_DUMP_F_DRAW_TEX_ENTER)) break; \
+            crServerDumpCheckInit(); \
+            crDmpStrF(cr_server.Recorder.pDumper, "==> %s\n", __FUNCTION__); \
+            if (CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_BUFF_ENTER)) { \
+                crServerDumpBuffer(); \
+            } \
+            if (CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_TEX_ENTER)) { \
+                crServerDumpTextures(); \
+            } \
+        } while (0)
+
+#define CR_SERVER_DUMP_DRAW_LEAVE() do { \
+            if (!CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE | CR_SERVER_DUMP_F_DRAW_TEX_LEAVE)) break; \
+            crServerDumpCheckInit(); \
+            crDmpStrF(cr_server.Recorder.pDumper, "<== %s\n", __FUNCTION__); \
+            if (CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE)) { \
+                crServerDumpBuffer(); \
+            } \
+            if (CR_SERVER_DUMP_IF_ANY(CR_SERVER_DUMP_F_DRAW_TEX_LEAVE)) { \
+                crServerDumpTextures(); \
+            } \
+        } while (0)
+#else /* if !defined VBOX_WITH_CRSERVER_DUMPER */
+#define CR_SERVER_DUMP_DRAW_ENTER() do {} while (0)
+#define CR_SERVER_DUMP_DRAW_LEAVE() do {} while (0)
+#endif /* !VBOX_WITH_CRSERVER_DUMPER */
+
 RT_C_DECLS_END
 
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 46343)
@@ -380,4 +380,5 @@
 
     crServerInitDispatch();
+    crServerInitTmpCtxDispatch();
     crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );
 
@@ -487,4 +488,5 @@
 
     crServerInitDispatch();
+    crServerInitTmpCtxDispatch();
     crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );
 
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 46343)
@@ -1292,2 +1292,187 @@
     return retval; /* WILL PROBABLY BE IGNORED */
 }
+
+void SERVER_DISPATCH_APIENTRY
+crServerMakeTmpCtxCurrent( GLint window, GLint nativeWindow, GLint context )
+{
+    CRContext *pCtx = crStateGetCurrent();
+    CRContext *pCurCtx = NULL;
+    GLuint idDrawFBO = 0, idReadFBO = 0;
+    int fDoPrePostProcess = 0;
+
+    if (pCtx)
+    {
+        GLint curSrvSpuCtx = cr_server.currentCtxInfo && cr_server.currentCtxInfo->SpuContext > 0 ? cr_server.currentCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext;
+        bool fSwitchToTmpCtx = (curSrvSpuCtx != context);
+        CRMuralInfo *pCurrentMural = cr_server.currentMural;
+        CRContextInfo *pCurCtxInfo = cr_server.currentCtxInfo;
+        pCurCtx = pCurCtxInfo ? pCurCtxInfo->pContext : NULL;
+
+        CRASSERT(pCurCtx == pCtx);
+
+        if (pCurrentMural)
+        {
+            idDrawFBO = CR_SERVER_FBO_FOR_IDX(pCurrentMural, pCurrentMural->iCurDrawBuffer);
+            idReadFBO = CR_SERVER_FBO_FOR_IDX(pCurrentMural, pCurrentMural->iCurReadBuffer);
+        }
+        else
+        {
+            idDrawFBO = 0;
+            idReadFBO = 0;
+        }
+
+        fDoPrePostProcess = fSwitchToTmpCtx ? 1 : -1;
+    }
+    else
+    {
+        /* this is a GUI thread, so no need to do anything here */
+    }
+
+    if (fDoPrePostProcess > 0)
+        crStateSwitchPrepare(NULL, pCurCtx, idDrawFBO, idReadFBO);
+
+    cr_server.head_spu->dispatch_table.MakeCurrent( window, nativeWindow, context);
+
+    if (fDoPrePostProcess < 0)
+        crStateSwitchPostprocess(pCurCtx, NULL, idDrawFBO, idReadFBO);
+}
+
+void crServerInitTmpCtxDispatch()
+{
+    crSPUInitDispatchTable(&cr_server.TmpCtxDispatch);
+    crSPUCopyDispatchTable(&cr_server.TmpCtxDispatch, &cr_server.head_spu->dispatch_table);
+    cr_server.TmpCtxDispatch.MakeCurrent = crServerMakeTmpCtxCurrent;
+}
+
+/* dump stuff */
+#ifdef VBOX_WITH_CRSERVER_DUMPER
+
+/* first four bits are buffer dump config
+ * second four bits are texture dump config
+ * config flags:
+ * 1 - blit on enter
+ * 2 - blit on exit
+ *
+ *
+ * Example:
+ *
+ * 0x03 - dump buffer on enter and exit
+ * 0x22 - dump texture and buffer on exit */
+int g_CrDbgDumpDraw = 0; //CR_SERVER_DUMP_F_DRAW_BUFF_ENTER | CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE;
+
+void crServerDumpCheckTerm()
+{
+    if (!CrBltIsInitialized(&cr_server.RecorderBlitter))
+        return;
+
+    CrBltTerm(&cr_server.RecorderBlitter);
+}
+
+int crServerDumpCheckInit()
+{
+    int rc;
+    CR_BLITTER_WINDOW BltWin;
+    CR_BLITTER_CONTEXT BltCtx;
+    CRMuralInfo *pBlitterMural;
+
+    if (CrBltIsInitialized(&cr_server.RecorderBlitter))
+        return VINF_SUCCESS;
+
+    pBlitterMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.visualBits);
+    if (!pBlitterMural)
+    {
+        crWarning("crServerGetDummyMural failed");
+        return VERR_GENERAL_FAILURE;
+    }
+
+    crServerVBoxBlitterWinInit(&BltWin, pBlitterMural);
+    crServerVBoxBlitterCtxInit(&BltCtx, &cr_server.MainContextInfo);
+
+    rc = CrBltInit(&cr_server.RecorderBlitter, &BltCtx, true, true, &cr_server.TmpCtxDispatch);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrBltInit failed rc %d", rc);
+        return rc;
+    }
+
+    rc = CrBltMuralSetCurrent(&cr_server.RecorderBlitter, &BltWin);
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("CrBltMuralSetCurrent failed rc %d", rc);
+        return rc;
+    }
+
+#if 0
+    crDmpDbgPrintInit(&cr_server.DbgPrintDumper);
+    cr_server.pDumper = &cr_server.DbgPrintDumper.Base;
+#else
+    crDmpHtmlInit(&cr_server.HtmlDumper, "S:\\projects\\virtualbox\\3d\\dumps\\1", "index.html");
+    cr_server.pDumper = &cr_server.HtmlDumper.Base;
+#endif
+
+    crRecInit(&cr_server.Recorder, &cr_server.RecorderBlitter, &cr_server.TmpCtxDispatch, cr_server.pDumper);
+    return VINF_SUCCESS;
+}
+
+void crServerDumpBuffer()
+{
+    CRContextInfo *pCtxInfo = cr_server.currentCtxInfo;
+    CR_BLITTER_WINDOW BltWin;
+    CR_BLITTER_CONTEXT BltCtx;
+    CRContext *ctx = crStateGetCurrent();
+    GLint idx = crServerMuralFBOIdxFromBufferName(cr_server.currentMural, pCtxInfo->pContext->buffer.drawBuffer);
+    GLint idFBO;
+    GLint idTex;
+    VBOXVR_TEXTURE RedirTex;
+    int rc = crServerDumpCheckInit();
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("crServerDumpCheckInit failed, rc %d", rc);
+        return;
+    }
+
+    if (idx < 0)
+    {
+        crWarning("neg idx, unsupported");
+        return;
+    }
+
+    idFBO = CR_SERVER_FBO_FOR_IDX(cr_server.currentMural, idx);
+    idTex = CR_SERVER_FBO_TEX_FOR_IDX(cr_server.currentMural, idx);
+
+    crServerVBoxBlitterWinInit(&BltWin, cr_server.currentMural);
+    crServerVBoxBlitterCtxInit(&BltCtx, pCtxInfo);
+
+    RedirTex.width = cr_server.currentMural->fboWidth;
+    RedirTex.height = cr_server.currentMural->fboHeight;
+    RedirTex.target = GL_TEXTURE_2D;
+    RedirTex.hwid = idTex;
+
+    crRecDumpBuffer(&cr_server.Recorder, ctx, &BltCtx, &BltWin, idFBO, idTex ? &RedirTex : NULL);
+}
+
+void crServerDumpTextures()
+{
+    CRContextInfo *pCtxInfo = cr_server.currentCtxInfo;
+    CR_BLITTER_WINDOW BltWin;
+    CR_BLITTER_CONTEXT BltCtx;
+    CRContext *ctx = crStateGetCurrent();
+    int rc = crServerDumpCheckInit();
+    if (!RT_SUCCESS(rc))
+    {
+        crWarning("crServerDumpCheckInit failed, rc %d", rc);
+        return;
+    }
+
+    crServerVBoxBlitterWinInit(&BltWin, cr_server.currentMural);
+    crServerVBoxBlitterCtxInit(&BltCtx, pCtxInfo);
+
+    crRecDumpTextures(&cr_server.Recorder, ctx, &BltCtx, &BltWin);
+}
+
+bool crServerDumpFilter(int event)
+{
+    return true;
+}
+#endif
+/* */
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.c	(revision 46343)
@@ -914,5 +914,5 @@
         crServerRpwEntryDrawSettingsToTex(&mural->RpwEntry, &DstTex);
 
-        cr_serverCtxSwitchPrepare(&CtxSwitch, NULL);
+        crServerCtxSwitchPrepare(&CtxSwitch, NULL);
 
         crServerVBoxBlitterWinInit(&CurrentBltInfo, pCurrentMural);
@@ -933,5 +933,5 @@
         }
 
-        cr_serverCtxSwitchPostprocess(&CtxSwitch);
+        crServerCtxSwitchPostprocess(&CtxSwitch);
 
 #if 1
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_rpw.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_rpw.cpp	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_rpw.cpp	(revision 46343)
@@ -368,5 +368,5 @@
                         CR_SERVER_CTX_SWITCH CtxSwitch;
 
-                        cr_serverCtxSwitchPrepare(&CtxSwitch, NULL);
+                        crServerCtxSwitchPrepare(&CtxSwitch, NULL);
 
                         cr_server.head_spu->dispatch_table.Flush();
@@ -383,5 +383,5 @@
                             cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
 
-                        cr_serverCtxSwitchPostprocess(&CtxSwitch);
+                        crServerCtxSwitchPostprocess(&CtxSwitch);
 
                         rc = RTThreadCreate(&pWorker->hThread, crServerRpwWorkerThread, pWorker, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "CrServerDw");
Index: trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c	(revision 46343)
@@ -465,5 +465,4 @@
     /* the compositor lock is not needed actually since we have prevented renderspu from using the compositor */
     /* CrVrScrCompositorLock(&mural->Compositor); */
-#if 0
     if (!mural->bReceivedRects)
     {
@@ -489,5 +488,4 @@
     }
     else
-#endif
     {
         rc = CrVrScrCompositorEntryTexUpdate(&mural->Compositor, &mural->CEntry, &Tex);
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 46343)
@@ -679,5 +679,5 @@
                 DstRect.xRight = paDstRegions[i].xRight * scaleX;
                 DstRect.yBottom = paDstRegions[i].yBottom * scaleY;
-                CrBltBlitTexMural(pBlitter, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
+                CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
             }
         }
@@ -701,5 +701,5 @@
         if (RT_SUCCESS(rc))
         {
-            CrBltBlitTexMural(pBlitter, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
+            CrBltBlitTexMural(pBlitter, true, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
         }
         else
Index: trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m
===================================================================
--- trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 46229)
+++ trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa_helper.m	(revision 46343)
@@ -1284,5 +1284,5 @@
                     }
                     
-                    CrBltBlitTexMural(m_pBlitter, &pEntry->Tex, pSrcRect, pDstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
+                    CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_YCOORDS);
                 }
                 CrBltLeave(m_pBlitter);
@@ -1407,5 +1407,5 @@
                             }
                     
-                            CrBltBlitTexMural(m_pBlitter, &pEntry->Tex, pSrcRect, pDstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_SRC_YCOORDS);
+                            CrBltBlitTexMural(m_pBlitter, true, &pEntry->Tex, pSrcRect, pDstRect, 1, CRBLT_F_LINEAR | CRBLT_F_INVERT_SRC_YCOORDS);
                         }
                         CrBltLeave(m_pBlitter);
