Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22796)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22797)
@@ -1282,5 +1282,7 @@
     static void doSetupMatrix(const QSize & aSize, bool bInverted);
 
-    void vboxDoUpdateViewport(const QRect * pRect);
+    void vboxDoUpdateViewport(const QRect & aRect);
+    void vboxDoUpdateRect(const QRect * pRect);
+
     const QRect & vboxViewport() const {return mViewport;}
 
@@ -1310,5 +1312,4 @@
 
 
-    void vboxDoUpdateRect(const QRect * pRect);
 #ifdef VBOXQGL_DBG_SURF
     void vboxDoTestSurfaces(void *context);
@@ -1449,4 +1450,34 @@
     void vboxUpdateRect(const QRect * pRect);
 private:
+    void makeCurrent()
+    {
+        if(!mGlCurrent)
+        {
+            mGlCurrent = true;
+            mpOverlayWidget->makeCurrent();
+        }
+    }
+
+    void performDisplayOverlay()
+    {
+        if(mOverlayVisible)
+        {
+#if 0
+            mpOverlayWidget->updateGL();
+#else
+            makeCurrent();
+            mpOverlayWidget->performDisplay();
+            mpOverlayWidget->swapBuffers();
+#endif
+        }
+    }
+
+    void vboxOpExit()
+    {
+        performDisplayOverlay();
+        mGlCurrent = false;
+    }
+
+
     void vboxSetGlOn(bool on);
     bool vboxGetGlOn() { return mGlOn; }
@@ -1454,4 +1485,7 @@
     void vboxDoVHWACmdExec(void *cmd);
     void vboxShowOverlay(bool show);
+    bool vboxDoCheckUpdateViewport();
+    void vboxDoVHWACmd(void *cmd);
+    void vboxDoUpdateRect(const QRect * pRect);
     void vboxUpdateOverlayPosition(const QPoint & pos);
     void vboxUpdateOverlay(const QRect & rect, bool show);
@@ -1460,4 +1494,7 @@
     bool mGlOn;
     bool mOverlayVisible;
+    bool mGlCurrent;
+    bool mProcessingCommands;
+    QRect mOverlayViewportCoords;
     VBoxVHWADirtyRect mMainDirtyRect;
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22796)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22797)
@@ -3003,5 +3003,5 @@
     if(vp != pw->vboxViewport())
     {
-        pw->vboxDoUpdateViewport(&vp);
+        pw->vboxDoUpdateViewport(vp);
     }
 
@@ -3560,5 +3560,8 @@
     }
 
+    Assert(handle != VBOXVHWA_SURFHANDLE_INVALID);
+    Assert(surf->handle() == VBOXVHWA_SURFHANDLE_INVALID);
     surf->setHandle(handle);
+    Assert(surf->handle() == handle);
 
     VBOXQGLLOG_EXIT(("pSurf (0x%x)\n",surf));
@@ -4628,8 +4631,8 @@
 #endif
 
-void VBoxGLWidget::vboxDoUpdateViewport(const QRect * pRect)
-{
-    adjustViewport(mDisplay.getPrimary()->size(), *pRect);
-    mViewport = *pRect;
+void VBoxGLWidget::vboxDoUpdateViewport(const QRect & aRect)
+{
+    adjustViewport(mDisplay.getPrimary()->size(), aRect);
+    mViewport = aRect;
 
     const SurfList & primaryList = mDisplay.primaries().surfaces();
@@ -4639,5 +4642,5 @@
     {
         VBoxVHWASurfaceBase *pSurf = *pr;
-        pSurf->updateVisibleTargRect(NULL, *pRect);
+        pSurf->updateVisibleTargRect(NULL, aRect);
     }
 
@@ -4653,5 +4656,5 @@
         {
             VBoxVHWASurfaceBase *pSurf = *sit;
-            pSurf->updateVisibleTargRect(mDisplay.getPrimary(), *pRect);
+            pSurf->updateVisibleTargRect(mDisplay.getPrimary(), aRect);
         }
     }
@@ -5229,4 +5232,6 @@
       mGlOn(false),
       mOverlayVisible(false),
+      mGlCurrent(false),
+      mProcessingCommands(false),
       mCmdPipe(aView)
 {
@@ -5252,4 +5257,8 @@
 {
     Q_UNUSED(pEvent);
+    Assert(!mProcessingCommands);
+    mProcessingCommands = true;
+    Assert(!mGlCurrent);
+    mGlCurrent = false; /* just a fall-back */
     VBoxVHWACommandElement * pFirst = mCmdPipe.detachCmdList(NULL, NULL);
     do
@@ -5259,4 +5268,7 @@
         pFirst = mCmdPipe.detachCmdList(pFirst, pLast);
     } while(pFirst);
+
+    mProcessingCommands = false;
+    vboxOpExit();
 }
 
@@ -5264,11 +5276,40 @@
                          ULONG aW, ULONG aH)
 {
+#if 1
     QRect r(aX, aY, aW, aH);
     mCmdPipe.postCmd(VBOXVHWA_PIPECMD_PAINT, &r);
     return S_OK;
+#else
+    /* We're not on the GUI thread and update() isn't thread safe in
+     * Qt 4.3.x on the Win, Qt 3.3.x on the Mac (4.2.x is),
+     * on Linux (didn't check Qt 4.x there) and probably on other
+     * non-DOS platforms, so post the event instead. */
+    QApplication::postEvent (mView,
+                             new VBoxRepaintEvent (aX, aY, aW, aH));
+
+    return S_OK;
+#endif
+}
+
+bool VBoxQGLOverlayFrameBuffer::vboxDoCheckUpdateViewport()
+{
+    Assert(0);
+//    QRect vp(mView->contentsX(), mView->contentsY(), mpOverlayWidget->width(), mpOverlayWidget->height());
+//    if(vp != mpOverlayWidget->vboxViewport())
+//    {
+//        mpOverlayWidget->vboxDoUpdateViewport(vp);
+//        return true;
+//    }
+    return false;
 }
 
 void VBoxQGLOverlayFrameBuffer::paintEvent (QPaintEvent *pe)
 {
+    if(mOverlayVisible && !mProcessingCommands)
+    {
+        Assert(!mGlCurrent);
+        vboxOpExit();
+    }
+
     VBoxQImageFrameBuffer::paintEvent (pe);
 }
@@ -5280,7 +5321,46 @@
     if(mGlOn)
     {
+        Assert(!mGlCurrent);
+        mGlCurrent = false;
+        makeCurrent();
         /* need to ensure we're in synch */
         vboxSynchGl();
-    }
+        vboxOpExit();
+        Assert(mGlCurrent == false);
+    }
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxDoVHWACmd(void *cmd)
+{
+    vboxDoVHWACmdExec(cmd);
+
+    CDisplay display = mView->console().GetDisplay();
+    Assert (!display.isNull());
+
+    display.CompleteVHWACommand((BYTE*)cmd);
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxDoUpdateRect(const QRect * pRect)
+{
+    if(mGlOn)
+    {
+        makeCurrent();
+        mpOverlayWidget->vboxDoUpdateRect(pRect);
+//        if(mOverlayVisible)
+//        {
+//            mpOverlayWidget->performDisplay();
+//            mpOverlayWidget->swapBuffers();
+//        }
+        vboxOpExit();
+    }
+
+    mView->viewport()->repaint (pRect->x() - mView->contentsX(),
+            pRect->y() - mView->contentsY(),
+            pRect->width(), pRect->height());
+
+    /* translate to widget coords
+     * @todo: may eliminate this */
+//    QPaintEvent pe(pRect->translated(-mView->contentsX(), -mView->contentsY()));
+//    VBoxQImageFrameBuffer::paintEvent (&pe);
 }
 
@@ -5324,9 +5404,17 @@
 {
     mpOverlayWidget->setVisible(show);
+    mOverlayVisible = show;
 }
 
 void VBoxQGLOverlayFrameBuffer::vboxUpdateOverlayPosition(const QPoint & pos)
 {
+    makeCurrent();
+
     mpOverlayWidget->move(pos);
+
+    /* */
+    QRect rect = mpOverlayWidget->vboxViewport();
+    rect.moveTo(pos);
+    mpOverlayWidget->vboxDoUpdateViewport(rect);
 }
 
@@ -5335,5 +5423,8 @@
     mpOverlayWidget->move(rect.x(), rect.y());
     mpOverlayWidget->resize(rect.width(), rect.height());
-    mpOverlayWidget->setVisible(show);
+
+    mpOverlayWidget->vboxDoUpdateViewport(rect);
+
+    vboxShowOverlay(show);
 }
 
@@ -5341,4 +5432,5 @@
 {
     struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
+    makeCurrent();
     switch(pCmd->enmCmd)
     {
@@ -5401,4 +5493,8 @@
                 vboxUpdateOverlay(overRect, true);
             }
+            else
+            {
+                vboxShowOverlay(false);
+            }
         } break;
         case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
@@ -5452,9 +5548,9 @@
         {
         case VBOXVHWA_PIPECMD_PAINT:
-//            vboxDoUpdateRect(&pCmd->rect());
+            vboxDoUpdateRect(&pCmd->rect());
             break;
 #ifdef VBOX_WITH_VIDEOHWACCEL
         case VBOXVHWA_PIPECMD_VHWA:
-//            vboxDoVHWACmd(pCmd->vhwaCmd());
+            vboxDoVHWACmd(pCmd->vhwaCmd());
             break;
         case VBOXVHWA_PIPECMD_OP:
