Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39814)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39815)
@@ -207,4 +207,7 @@
 DECLEXPORT(void) crStateDestroyContext(CRContext *ctx);
 
+CRContext * crStateSwichPrepare(CRContext *toCtx);
+void crStateSwichPostprocess(CRContext *fromCtx);
+
 DECLEXPORT(void) crStateFlushFunc( CRStateFlushFunc ff );
 DECLEXPORT(void) crStateFlushArg( void *arg );
Index: /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h	(revision 39814)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/state/cr_framebuffer.h	(revision 39815)
@@ -67,4 +67,8 @@
 DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectDestroy(CRContext *ctx);
 DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectSwitch(CRContext *from, CRContext *to);
+
+DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectDisableHW(CRContext *ctx);
+DECLEXPORT(void) STATE_APIENTRY crStateFramebufferObjectReenableHW(CRContext *fromCtx, CRContext *toCtx);
+
 DECLEXPORT(GLuint) STATE_APIENTRY crStateGetFramebufferHWID(GLuint id);
 DECLEXPORT(GLuint) STATE_APIENTRY crStateGetRenderbufferHWID(GLuint id);
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c	(revision 39814)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_diff.c	(revision 39815)
@@ -345,2 +345,25 @@
 #endif
 }
+
+CRContext * crStateSwichPrepare(CRContext *toCtx)
+{
+    CRContext *fromCtx = GetCurrentContext();
+
+#ifdef CR_EXT_framebuffer_object
+    if (fromCtx)
+        crStateFramebufferObjectDisableHW(fromCtx);
+#endif
+
+    return fromCtx;
+}
+
+void crStateSwichPostprocess(CRContext *fromCtx)
+{
+    CRContext *toCtx = GetCurrentContext();;
+    if (!fromCtx || !toCtx)
+        return;
+
+#ifdef CR_EXT_framebuffer_object
+    crStateFramebufferObjectReenableHW(fromCtx, toCtx);
+#endif
+}
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c	(revision 39814)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_framebuffer.c	(revision 39815)
@@ -748,9 +748,57 @@
 }
 
+
+DECLEXPORT(void) STATE_APIENTRY
+crStateFramebufferObjectDisableHW(CRContext *ctx)
+{
+    if (ctx->framebufferobject.drawFB)
+        diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
+
+    if (ctx->framebufferobject.readFB)
+        diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
+
+    if (ctx->framebufferobject.drawFB)
+        diff_api.DrawBuffer(GL_BACK);
+    if (ctx->framebufferobject.readFB)
+        diff_api.ReadBuffer(GL_BACK);
+
+    if (ctx->framebufferobject.renderbuffer)
+        diff_api.BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+}
+
+DECLEXPORT(void) STATE_APIENTRY
+crStateFramebufferObjectReenableHW(CRContext *fromCtx, CRContext *toCtx)
+{
+    GLboolean fAdjustDrawReadBuffers = GL_FALSE;
+
+    if (fromCtx->framebufferobject.drawFB
+            && fromCtx->framebufferobject.drawFB == toCtx->framebufferobject.drawFB)
+    {
+        diff_api.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, toCtx->framebufferobject.drawFB->hwid);
+        fAdjustDrawReadBuffers = GL_TRUE;
+    }
+
+    if (fromCtx->framebufferobject.readFB
+            && fromCtx->framebufferobject.readFB == toCtx->framebufferobject.readFB)
+    {
+        diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, toCtx->framebufferobject.readFB->hwid);
+        fAdjustDrawReadBuffers = GL_TRUE;
+    }
+
+    if (fAdjustDrawReadBuffers)
+    {
+        diff_api.DrawBuffer(toCtx->framebufferobject.drawFB?toCtx->framebufferobject.drawFB->drawbuffer[0]:toCtx->buffer.drawBuffer);
+        diff_api.ReadBuffer(toCtx->framebufferobject.readFB?toCtx->framebufferobject.readFB->readbuffer:toCtx->buffer.readBuffer);
+    }
+}
+
+
 DECLEXPORT(GLuint) STATE_APIENTRY crStateGetFramebufferHWID(GLuint id)
 {
     CRContext *g = GetCurrentContext();
     CRFramebufferObject *pFBO = (CRFramebufferObject*) crHashtableSearch(g->shared->fbTable, id);
-
+#ifdef DEBUG_misha
+    crDebug("FB id(%d) hw(%d)", id, pFBO ? pFBO->hwid : 0);
+#endif
     return pFBO ? pFBO->hwid : 0;
 }
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 39814)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_context.c	(revision 39815)
@@ -231,5 +231,5 @@
 {
     CRMuralInfo *mural, *oldMural;
-    CRContext *ctx;
+    CRContext *ctx, *oldCtx;
 
     if (context >= 0 && window >= 0) {
@@ -267,4 +267,11 @@
         return;
     }
+
+    /* Ubuntu 11.04 hosts misbehave if context window switch is
+     * done with non-default framebuffer object settings.
+     * crStateSwichPrepare & crStateSwichPostprocess are supposed to work around this problem
+     * 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);
 
     /*
@@ -326,4 +333,6 @@
     crStateMakeCurrent( ctx );
 
+    crStateSwichPostprocess(oldCtx);
+
     if (oldMural != mural && crServerSupportRedirMuralFBO())
     {
Index: /trunk/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py	(revision 39814)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py	(revision 39815)
@@ -227,4 +227,8 @@
     for (i = 0 ; i < num_opcodes ; i++)
     {
+    
+        CRDBGPTR_CHECKZ(writeback_ptr);
+        CRDBGPTR_CHECKZ(return_ptr);
+    
         /*crDebug(\"Unpacking opcode \%d\", *unpack_opcodes);*/
         switch( *unpack_opcodes )
@@ -263,4 +267,8 @@
                 break;
         }
+        
+        CRDBGPTR_CHECKZ(writeback_ptr);
+        CRDBGPTR_CHECKZ(return_ptr);
+        
         unpack_opcodes--;
     }
