Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h	(revision 45506)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_blitter.h	(revision 45507)
@@ -44,7 +44,7 @@
         uint32_t CtxCreated          : 1;
         uint32_t SupportsFBO         : 1;
-        uint32_t SupportsFBOBlit     : 1;
         uint32_t CurrentMuralChanged : 1;
         uint32_t LastWasFBODraw      : 1;
+        uint32_t ForceDrawBlit       : 1;
         uint32_t Reserved            : 26;
     };
@@ -103,5 +103,6 @@
 }
 
-VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, SPUDispatchTable *pDispatch);
+VBOXBLITTERDECL(int) CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, SPUDispatchTable *pDispatch);
+
 VBOXBLITTERDECL(void) CrBltTerm(PCR_BLITTER pBlitter);
 
@@ -132,5 +133,5 @@
 }
 
-VBOXBLITTERDECL(void) CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural);
+VBOXBLITTERDECL(int) CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural);
 DECLINLINE(const CR_BLITTER_WINDOW *) CrBltMuralGetCurrentInfo(PCR_BLITTER pBlitter)
 {
Index: /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp	(revision 45506)
+++ /trunk/src/VBox/GuestHost/OpenGL/util/blitter.cpp	(revision 45507)
@@ -29,7 +29,25 @@
 
 
-int CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, SPUDispatchTable *pDispatch)
-{
-    if (pCtxBase->Base.id == 0 || pCtxBase->Base.id < -1)
+/* @param pCtxBase      - contains the blitter context info. Its value is treated differently depending on the fCreateNewCtx value
+ * @param fCreateNewCtx - if true  - the pCtxBase must NOT be NULL. its visualBits is used as a visual bits info for the new context,
+ *                                   its id field is used to specified the shared context id to be used for blitter context.
+ *                                   The id can be null to specify no shared context is needed
+ *                        if false - if pCtxBase is NOT null AND its id field is NOT null -
+ *                                     specified the blitter context to be used
+ *                                     blitter treats it as if it has default ogl state.
+ *                                   otherwise -
+ *                                     the blitter works in a "no-context" mode, i.e. a caller is responsible
+ *                                     to making a proper context current before calling the blitter.
+ *                                     Note that BltEnter/Leave MUST still be called, but the proper context
+ *                                     must be set before doing BltEnter, and ResoreContext info is ignored in that case.
+ *                                     Also note that blitter caches the current window info, and assumes the current context's values are preserved
+ *                                     wrt that window before the calls, so if one uses different contexts for one blitter,
+ *                                     the blitter current window values must be explicitly reset by doing CrBltMuralSetCurrent(pBlitter, NULL)
+ * @param fForceDrawBlt - if true  - forces the blitter to always use glDrawXxx-based blits even if GL_EXT_framebuffer_blit.
+ *                                   This is needed because BlitFramebufferEXT is known to be often buggy, and glDrawXxx-based blits appear to be more reliable
+ */
+int CrBltInit(PCR_BLITTER pBlitter, const CR_BLITTER_CONTEXT *pCtxBase, bool fCreateNewCtx, bool fForceDrawBlt, SPUDispatchTable *pDispatch)
+{
+    if (pCtxBase && pCtxBase->Base.id < 0)
     {
         crWarning("Default share context not initialized!");
@@ -37,8 +55,18 @@
     }
 
+    if (!pCtxBase && fCreateNewCtx)
+    {
+        crWarning("pCtxBase is zero while fCreateNewCtx is set!");
+        return VERR_INVALID_PARAMETER;
+    }
+
     memset(pBlitter, 0, sizeof (*pBlitter));
 
     pBlitter->pDispatch = pDispatch;
-    pBlitter->CtxInfo = *pCtxBase;
+    if (pCtxBase)
+        pBlitter->CtxInfo = *pCtxBase;
+
+    pBlitter->Flags.ForceDrawBlit = fForceDrawBlt;
+
     if (fCreateNewCtx)
     {
@@ -62,10 +90,10 @@
 }
 
-void CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural)
+int CrBltMuralSetCurrent(PCR_BLITTER pBlitter, const CR_BLITTER_WINDOW *pMural)
 {
     if (pMural)
     {
         if (!memcmp(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural)))
-            return;
+            return VINF_SUCCESS;
         memcpy(&pBlitter->CurrentMural, pMural, sizeof (pBlitter->CurrentMural));
     }
@@ -73,5 +101,5 @@
     {
         if (!pBlitter->CurrentMural.Base.id)
-            return;
+            return VINF_SUCCESS;
         pBlitter->CurrentMural.Base.id = 0;
     }
@@ -80,5 +108,12 @@
 
     if (!CrBltIsEntered(pBlitter))
-        return;
+        return VINF_SUCCESS;
+    else if (!pBlitter->CtxInfo.Base.id)
+    {
+        crWarning("setting current mural for entered no-context blitter");
+        return VERR_INVALID_STATE;
+    }
+
+    pBlitter->pDispatch->Flush();
 
     if (pMural)
@@ -86,4 +121,6 @@
     else
         pBlitter->pDispatch->MakeCurrent(0, 0, 0);
+
+    return VINF_SUCCESS;
 }
 
@@ -436,4 +473,6 @@
     }
 
+    pBlitter->pDispatch->BindTexture(pSrc->target, 0);
+
     return VINF_SUCCESS;
 }
@@ -453,7 +492,6 @@
     /* BlitFramebuffer seems to be buggy on Intel, 
      * try always glDrawXxx for now */
-    if (0 && crStrstr(pszExtension, "GL_EXT_framebuffer_blit"))
-    {
-        pBlitter->Flags.SupportsFBOBlit = 1;
+    if (!pBlitter->Flags.ForceDrawBlit && crStrstr(pszExtension, "GL_EXT_framebuffer_blit"))
+    {
         pBlitter->pfnBlt = crBltBlitTexBufImplFbo;
     }
@@ -486,11 +524,14 @@
     pBlitter->pDispatch->Flush();
 
-    if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
-    {
-        pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id);
-    }
-    else
-    {
-        pBlitter->pDispatch->MakeCurrent(0, 0, 0);
+    if (pBlitter->CtxInfo.Base.id)
+    {
+        if (pBlitter->pRestoreCtxInfo != &pBlitter->CtxInfo)
+        {
+            pBlitter->pDispatch->MakeCurrent(pBlitter->pRestoreMural->Base.id, 0, pBlitter->pRestoreCtxInfo->Base.id);
+        }
+        else
+        {
+            pBlitter->pDispatch->MakeCurrent(0, 0, 0);
+        }
     }
 
@@ -512,4 +553,17 @@
     }
 
+    if (pBlitter->CurrentMural.Base.id) /* <- pBlitter->CurrentMural.Base.id can be null if the blitter is in a "no-context" mode (see comments to BltInit for detail)*/
+    {
+        pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
+    }
+    else
+    {
+        if (pRestoreCtxInfo)
+        {
+            crWarning("pRestoreCtxInfo is not NULL for \"no-context\" blitter");
+            pRestoreCtxInfo = NULL;
+        }
+    }
+
     if (pRestoreCtxInfo)
     {
@@ -523,6 +577,4 @@
         pBlitter->pRestoreCtxInfo = &pBlitter->CtxInfo;
     }
-
-    pBlitter->pDispatch->MakeCurrent(pBlitter->CurrentMural.Base.id, pBlitter->i32MakeCurrentUserData, pBlitter->CtxInfo.Base.id);
 
     if (pBlitter->Flags.Initialized)
@@ -573,4 +625,6 @@
 
     crBltBlitTexBuf(pBlitter, pSrc, pSrcRect, GL_DRAW_FRAMEBUFFER, &DstSize, pDstRect, cRects, fFlags);
+
+    pBlitter->pDispatch->FramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, pDst->target, 0, 0);
 }
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 45506)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c	(revision 45507)
@@ -634,5 +634,5 @@
         Ctx.Base.id = cr_server.MainContextInfo.SpuContext;
         Ctx.Base.visualBits = cr_server.MainContextInfo.CreateInfo.visualBits;
-        rc = CrBltInit(&cr_server.Blitter, &Ctx, true, &cr_server.head_spu->dispatch_table);
+        rc = CrBltInit(&cr_server.Blitter, &Ctx, true, true, &cr_server.head_spu->dispatch_table);
         if (RT_SUCCESS(rc))
         {
Index: /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 45506)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c	(revision 45507)
@@ -762,5 +762,5 @@
             ctx.Base.id = 1;
             ctx.Base.visualBits = window->visual->visAttribs;
-            rc = CrBltInit(pBlitter, &ctx, true, render_spu.blitterDispatch);
+            rc = CrBltInit(pBlitter, &ctx, true, true, render_spu.blitterDispatch);
             if (!RT_SUCCESS(rc))
             {
