Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 22833)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 22834)
@@ -138,4 +138,8 @@
     void requestToResize (const QSize &aSize);
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void scrollContentsBy (int dx, int dy);
+#endif
+
 #if defined(Q_WS_MAC)
     void updateDockIcon();
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h	(revision 22833)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFBOverlay.h	(revision 22834)
@@ -572,4 +572,6 @@
     void setHandle(uint32_t h) {mHGHandle = h;}
 
+    const VBoxVHWADirtyRect & getDirtyRect() { return mUpdateMem2TexRect; }
+
 private:
     void doSetRectValuesInternal(const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect);
@@ -1187,4 +1189,16 @@
     void onResizeEventPostprocess (const class VBoxResizeEvent *re);
 
+    void viewportResized(QResizeEvent * re)
+    {
+        vboxDoCheckUpdateViewport();
+        mGlCurrent = false;
+    }
+
+    void viewportScrolled(int dx, int dy)
+    {
+        vboxDoCheckUpdateViewport();
+        mGlCurrent = false;
+    }
+
     static bool isAcceleration2DVideoAvailable();
 
@@ -1193,4 +1207,20 @@
     void vhwaSaveExec(struct SSMHANDLE * pSSM);
 private:
+    int vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd);
+
+    void repaintMain();
+    void repaintOverlay()
+    {
+        if(mNeedOverlayRepaint)
+        {
+            mNeedOverlayRepaint = false;
+            performDisplayOverlay();
+        }
+    }
+    void repaint()
+    {
+        repaintOverlay();
+        repaintMain();
+    }
 
     void makeCurrent()
@@ -1217,19 +1247,19 @@
     }
 
-    void vboxOpExit()
-    {
-        performDisplayOverlay();
-        mGlCurrent = false;
-    }
+//    void vboxOpExit()
+//    {
+//        performDisplayOverlay();
+//        mGlCurrent = false;
+//    }
 
 
     void vboxSetGlOn(bool on);
     bool vboxGetGlOn() { return mGlOn; }
-    void vboxSynchGl();
+    bool vboxSynchGl();
     void vboxDoVHWACmdExec(void *cmd);
     void vboxShowOverlay(bool show);
     void vboxDoCheckUpdateViewport();
     void vboxDoVHWACmd(void *cmd);
-    void vboxDoUpdateRect(const QRect * pRect);
+    void addMainDirtyRect(const QRect & aRect);
 //    void vboxUpdateOverlayPosition(const QPoint & pos);
     void vboxCheckUpdateOverlay(const QRect & rect);
@@ -1246,4 +1276,5 @@
     bool mGlCurrent;
     bool mProcessingCommands;
+    bool mNeedOverlayRepaint;
     QRect mOverlayViewport;
     VBoxVHWADirtyRect mMainDirtyRect;
@@ -1310,4 +1341,16 @@
         mOverlay.onResizeEventPostprocess(re);
     }
+
+    void viewportResized(QResizeEvent * re)
+    {
+        mOverlay.viewportResized(re);
+        T::viewportResized(re);
+    }
+
+    void viewportScrolled(int dx, int dy)
+    {
+        mOverlay.viewportScrolled(dx, dy);
+        T::viewportScrolled(dx, dy);
+    }
 private:
     VBoxQGLOverlay mOverlay;
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22833)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22834)
@@ -243,4 +243,8 @@
      * the event is framebuffer implementation specific */
     virtual void doProcessVHWACommand(QEvent * pEvent);
+
+    virtual void viewportResized(QResizeEvent * re){}
+
+    virtual void viewportScrolled(int dx, int dy){}
 #endif
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 22833)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 22834)
@@ -1733,4 +1733,16 @@
 }
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+void VBoxConsoleView::scrollContentsBy (int dx, int dy)
+{
+    if (mAttached && mFrameBuf)
+    {
+        mFrameBuf->viewportScrolled(dx, dy);
+    }
+    QAbstractScrollArea::scrollContentsBy (dx, dy);
+}
+#endif
+
+
 bool VBoxConsoleView::eventFilter (QObject *watched, QEvent *e)
 {
@@ -1783,4 +1795,10 @@
                 if (mMouseCaptured)
                     updateMouseClipping();
+#ifdef VBOX_WITH_VIDEOHWACCEL
+                if (mFrameBuf)
+                {
+                    mFrameBuf->viewportResized((QResizeEvent*)e);
+                }
+#endif
                 break;
             }
@@ -2977,5 +2995,5 @@
 {
 #if 1
-    
+
     LogRel3(("%s: type=%03d x=%03d y=%03d btns=%08X wdelta=%03d wdir=%s\n",
              __PRETTY_FUNCTION__ , aType, aPos.x(), aPos.y(),
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 22833)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp	(revision 22834)
@@ -5087,4 +5087,5 @@
       mGlCurrent(false),
       mProcessingCommands(false),
+      mNeedOverlayRepaint(false),
       mCmdPipe(aView)
 {
@@ -5127,5 +5128,7 @@
 
     mProcessingCommands = false;
-    vboxOpExit();
+    repaint();
+//    vboxOpExit();
+    mGlCurrent = false;
 }
 
@@ -5154,32 +5157,30 @@
     Q_UNUSED(pRect);
 
-    if(mOverlayWidgetVisible && !mProcessingCommands)
+//    if(mOverlayWidgetVisible && !mProcessingCommands)
+//    {
+//        Assert(!mGlCurrent);
+//        vboxDoCheckUpdateViewport();
+//        vboxOpExit();
+//    }
+    return VBOXFBOVERLAY_UNTOUCHED;
+}
+
+void VBoxQGLOverlay::onResizeEvent (const VBoxResizeEvent *re)
+{
+    Q_UNUSED(re);
+}
+
+void VBoxQGLOverlay::onResizeEventPostprocess (const VBoxResizeEvent *re)
+{
+    Q_UNUSED(re);
+
+    if(mGlOn)
     {
         Assert(!mGlCurrent);
-        vboxDoCheckUpdateViewport();
-        vboxOpExit();
-    }
-    return VBOXFBOVERLAY_UNTOUCHED;
-}
-
-void VBoxQGLOverlay::onResizeEvent (const VBoxResizeEvent *re)
-{
-    Q_UNUSED(re);
-}
-
-void VBoxQGLOverlay::onResizeEventPostprocess (const VBoxResizeEvent *re)
-{
-    Q_UNUSED(re);
-
-    bool bDoOpExit = false;
-
-    if(mGlOn)
-    {
-        Assert(!mGlCurrent);
+        Assert(!mNeedOverlayRepaint);
         mGlCurrent = false;
         makeCurrent();
         /* need to ensure we're in synch */
-        vboxSynchGl();
-        bDoOpExit = true;
+        mNeedOverlayRepaint = vboxSynchGl();
     }
 
@@ -5194,13 +5195,27 @@
         }
         mOnResizeCmdList.clear();
-        bDoOpExit = true;
-    }
-
-    if(bDoOpExit)
-    {
-        vboxOpExit();
-    }
-    Assert(mGlCurrent == false);
-
+    }
+
+    repaintOverlay();
+    mGlCurrent = false;
+}
+
+void VBoxQGLOverlay::repaintMain()
+{
+    if(mMainDirtyRect.isClear())
+        return;
+
+    const QRect &rect = mMainDirtyRect.rect();
+    if(mOverlayWidgetVisible)
+    {
+        if(mOverlayViewport.contains(rect))
+            return;
+    }
+
+    mView->viewport()->repaint (rect.x() - mView->contentsX(),
+            rect.y() - mView->contentsY(),
+            rect.width(), rect.height());
+
+    mMainDirtyRect.clear();
 }
 
@@ -5215,24 +5230,24 @@
 }
 
-void VBoxQGLOverlay::vboxDoUpdateRect(const QRect * pRect)
-{
-    if(mGlOn)
-    {
-        makeCurrent();
-        mpOverlayWidget->vboxDoUpdateRect(pRect);
-        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);
-}
-
-void VBoxQGLOverlay::vboxSynchGl()
+//void VBoxQGLOverlay::vboxDoUpdateRect(const QRect * pRect)
+//{
+//    if(mGlOn)
+//    {
+//        makeCurrent();
+//        mpOverlayWidget->vboxDoUpdateRect(pRect);
+//        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);
+//}
+
+bool VBoxQGLOverlay::vboxSynchGl()
 {
     if(mpOverlayWidget->vboxIsInitialized()
@@ -5244,5 +5259,5 @@
             && mContainer->height() == mpOverlayWidget->vboxFbHeight())
     {
-        return;
+        return false;
     }
     /* create and issue a resize event to the gl widget to ensure we have all gl data initialized
@@ -5256,4 +5271,5 @@
 
     mpOverlayWidget->vboxResizeEvent(&re);
+    return true;
 }
 
@@ -5306,4 +5322,5 @@
             makeCurrent();
             mpOverlayWidget->vboxDoUpdateViewport(overVp);
+            mNeedOverlayRepaint = true;
         }
 
@@ -5353,4 +5370,29 @@
 //
 //    vboxShowOverlay(show);
+}
+
+void VBoxQGLOverlay::addMainDirtyRect(const QRect & aRect)
+{
+    mMainDirtyRect.add(aRect);
+    if(mGlOn)
+    {
+        mpOverlayWidget->vboxDoUpdateRect(&aRect);
+        if(aRect.intersects(mpOverlayWidget->vboxViewport()))
+        {
+            mNeedOverlayRepaint = true;
+        }
+    }
+}
+
+int VBoxQGLOverlay::vhwaSurfaceUnlock(struct _VBOXVHWACMD_SURF_UNLOCK *pCmd)
+{
+    int rc = mpOverlayWidget->vhwaSurfaceUnlock(pCmd);
+    VBoxVHWASurfaceBase * pVGA = mpOverlayWidget->vboxGetVGASurface();
+    const VBoxVHWADirtyRect & rect = pVGA->getDirtyRect();
+    if(!rect.isClear())
+    {
+        mMainDirtyRect.add(rect);
+    }
+    return rc;
 }
 
@@ -5411,5 +5453,5 @@
         {
             VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
-            pCmd->rc = mpOverlayWidget->vhwaSurfaceUnlock(pBody);
+            pCmd->rc = vhwaSurfaceUnlock(pBody);
         } break;
         case VBOXVHWACMD_TYPE_SURF_BLT:
@@ -5422,4 +5464,5 @@
             VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
             pCmd->rc = mpOverlayWidget->vhwaSurfaceFlip(pBody);
+            mNeedOverlayRepaint = true;
         } break;
         case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
@@ -5553,5 +5596,5 @@
         {
         case VBOXVHWA_PIPECMD_PAINT:
-            vboxDoUpdateRect(&pCmd->rect());
+            addMainDirtyRect(pCmd->rect());
             break;
 #ifdef VBOX_WITH_VIDEOHWACCEL
