Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 22794)
@@ -84,5 +84,5 @@
         InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
 #ifdef VBOX_GUI_USE_QGL
-        , QGLMode
+        , QGLMode, QGLOverlayMode
 #endif
     };
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 22794)
@@ -420,4 +420,13 @@
     const QRect & rect() const {return mRect;}
 
+    const QRect & toRect()
+    {
+        if(isClear())
+        {
+            mRect.setCoords(0, 0, -1, -1);
+        }
+        return mRect;
+    }
+
     bool intersects(const QRect & aRect) const {return mIsClear ? false : mRect.intersects(aRect);}
 
@@ -665,5 +674,8 @@
             bool aIsYInverted,
 #endif
-            const QSize * aSize, const QSize * aTargetSize,
+            const QSize & aSize,
+            const QRect & aTargRect,
+            const QRect & aSrcRect,
+            const QRect & aVisTargRect,
             VBoxVHWAColorFormat & aColorFormat,
             VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
@@ -689,6 +701,7 @@
     void performDisplay(VBoxVHWASurfaceBase *pPrimary);
 
-    void setRects(VBoxVHWASurfaceBase *pPrimary, const QRect * aTargRect, const QRect * aSrcRect);
-    void setTargetRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint * aPoint);
+    void setRects(VBoxVHWASurfaceBase *pPrimary, const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisibleTargRect, bool bForceReinit);
+    void setTargRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint & aPoint, const QRect & aVisibleTargRect);
+    void updateVisibleTargRect(VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect);
 
     static ulong calcBytesPerPixel(GLenum format, GLenum type);
@@ -824,7 +837,10 @@
     static int setCKey(class VBoxVHWAGlProgramVHWA * pProgram, const VBoxVHWAColorFormat * pFormat, const VBoxVHWAColorKey * pCKey, bool bDst);
 
-    uint32_t handle() {return mHGHandle;}
+    uint32_t handle() const {return mHGHandle;}
     void setHandle(uint32_t h) {mHGHandle = h;}
-private:
+
+private:
+    void doSetRectValuesInternal(const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect);
+
     void setComplexList(VBoxVHWASurfList *aComplexList) { mComplexList = aComplexList; }
     void initDisplay(VBoxVHWASurfaceBase *pPrimary);
@@ -845,5 +861,7 @@
     QRect mSrcRect;
     QRect mTargRect; /* == Vis FB size */
-    QRect mTargSize;
+
+    QRect mVisibleTargRect;
+    QRect mVisibleSrcRect;
 
     GLuint mVisibleDisplay;
@@ -1026,4 +1044,5 @@
 
     const OverlayList & overlays() const {return mOverlays;}
+    const VBoxVHWASurfList & primaries() const { return mPrimary; }
 
 private:
@@ -1202,65 +1221,5 @@
     void vhwaSaveExec(struct SSMHANDLE * pSSM);
     int vhwaLoadExec(struct SSMHANDLE * pSSM, uint32_t u32Version);
-#endif
-
-    ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
-    ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
-
-    void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
-    void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
-
-    void vboxProcessVHWACommands(class VBoxVHWACommandProcessEvent * pEvent) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pEvent);}
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
-#endif
-    class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
-
-    VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
-
-    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
-
-    static void doSetupMatrix(const QSize & aSize, bool bInverted);
-protected:
-
-    void paintGL()
-    {
-        if(mpfnOp)
-        {
-            (this->*mpfnOp)(mOpContext);
-            mpfnOp = NULL;
-        }
-        else
-        {
-            mDisplay.performDisplay();
-        }
-    }
-
-    void initializeGL();
-private:
-    static void setupMatricies(const QSize &display);
-    static void adjustViewport(const QSize &display, const QRect &viewport);
-    void vboxDoResize(void *re);
-    void vboxDoPaint(void *rec);
-
-    void vboxDoUpdateRect(const QRect * pRect);
-#ifdef VBOXQGL_DBG_SURF
-    void vboxDoTestSurfaces(void *context);
-#endif
-#ifdef VBOX_WITH_VIDEOHWACCEL
-    void vboxDoVHWACmdExec(void *cmd);
-    void vboxDoVHWACmdAndFree(void *cmd);
-    void vboxDoVHWACmd(void *cmd);
-
-    void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
-    {
-        if (pSurface->addressAlocated())
-        {
-            uchar * addr = vboxVRAMAddressFromOffset(offset);
-            if(addr)
-            {
-                pSurface->setAddress(addr);
-            }
-        }
-    }
+
     int vhwaSurfaceCanCreate(struct _VBOXVHWACMD_SURF_CANCREATE *pCmd);
     int vhwaSurfaceCreate(struct _VBOXVHWACMD_SURF_CREATE *pCmd);
@@ -1277,9 +1236,80 @@
     int vhwaConstruct(struct _VBOXVHWACMD_HH_CONSTRUCT *pCmd);
 
+    bool hasSurfaces() const;
+    bool hasVisibleOverlays();
+    const QRect & overlaysRectUnion();
+#endif
+
+    ulong vboxBitsPerPixel() { return mDisplay.getVGA()->bitsPerPixel(); }
+    ulong vboxBytesPerLine() { return mDisplay.getVGA() ? mDisplay.getVGA()->bytesPerLine() : 0; }
+
+//    void vboxPaintEvent (QPaintEvent *pe) {vboxPerformGLOp(&VBoxGLWidget::vboxDoPaint, pe); }
+    void vboxResizeEvent (VBoxResizeEvent *re) {vboxPerformGLOp(&VBoxGLWidget::vboxDoResize, re); }
+
+    void vboxProcessVHWACommands(class VBoxVHWACommandProcessEvent * pEvent) {vboxPerformGLOp(&VBoxGLWidget::vboxDoProcessVHWACommands, pEvent);}
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void vboxVHWACmd (struct _VBOXVHWACMD * pCmd) {vboxPerformGLOp(&VBoxGLWidget::vboxDoVHWACmd, pCmd);}
+#endif
+    class VBoxVHWAGlProgramMngr * vboxVHWAGetGlProgramMngr() { return mpMngr; }
+
+    VBoxVHWASurfaceBase * vboxGetVGASurface() { return mDisplay.getVGA(); }
+
+    void postCmd(VBOXVHWA_PIPECMD_TYPE aType, void * pvData);
+
+    static void doSetupMatrix(const QSize & aSize, bool bInverted);
+
+    void vboxDoUpdateViewport(const QRect * pRect);
+    const QRect & vboxViewport() const {return mViewport;}
+
+    void performDisplay() { mDisplay.performDisplay(); }
+protected:
+
+    void paintGL()
+    {
+        if(mpfnOp)
+        {
+            (this->*mpfnOp)(mOpContext);
+            mpfnOp = NULL;
+        }
+//        else
+//        {
+            mDisplay.performDisplay();
+//        }
+    }
+
+    void initializeGL();
+
+private:
+    static void setupMatricies(const QSize &display);
+    static void adjustViewport(const QSize &display, const QRect &viewport);
+    void vboxDoResize(void *re);
+//    void vboxDoPaint(void *rec);
+
+
+    void vboxDoUpdateRect(const QRect * pRect);
+#ifdef VBOXQGL_DBG_SURF
+    void vboxDoTestSurfaces(void *context);
+#endif
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void vboxDoVHWACmdExec(void *cmd);
+    void vboxDoVHWACmdAndFree(void *cmd);
+    void vboxDoVHWACmd(void *cmd);
+
+    void vboxCheckUpdateAddress (VBoxVHWASurfaceBase * pSurface, uint64_t offset)
+    {
+        if (pSurface->addressAlocated())
+        {
+            uchar * addr = vboxVRAMAddressFromOffset(offset);
+            if(addr)
+            {
+                pSurface->setAddress(addr);
+            }
+        }
+    }
+
     int vhwaSaveSurface(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, uint32_t surfCaps);
     int vhwaLoadSurface(struct SSMHANDLE * pSSM, uint32_t u32Version);
     int vhwaSaveOverlayData(struct SSMHANDLE * pSSM, VBoxVHWASurfaceBase *pSurf, bool bVisible);
     int vhwaLoadOverlayData(struct SSMHANDLE * pSSM, uint32_t u32Version);
-
     void vhwaDoSurfaceOverlayUpdate(VBoxVHWASurfaceBase *pDstSurf, VBoxVHWASurfaceBase *pSrcSurf, struct _VBOXVHWACMD_SURF_OVERLAY_UPDATE *pCmd);
 #endif
@@ -1292,5 +1322,10 @@
      * submit the operation to be performed
      * @todo: could be moved outside the updateGL */
-    void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext) {mpfnOp = pfn; mOpContext = pContext; updateGL();}
+    void vboxPerformGLOp(PFNVBOXQGLOP pfn, void* pContext)
+    {
+        mpfnOp = pfn;
+        mOpContext = pContext;
+        updateGL();
+    }
 
 //    /* posts op to UI thread */
@@ -1380,4 +1415,36 @@
 };
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+class VBoxQGLOverlayFrameBuffer : public VBoxQImageFrameBuffer
+{
+public:
+    VBoxQGLOverlayFrameBuffer (VBoxConsoleView *aView);
+
+
+    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
+
+    void doProcessVHWACommand(QEvent * pEvent);
+
+    STDMETHOD(NotifyUpdate) (ULONG aX, ULONG aY,
+                             ULONG aW, ULONG aH);
+
+    void paintEvent (QPaintEvent *pe);
+    void resizeEvent (VBoxResizeEvent *re);
+
+    void vboxUpdateRect(const QRect * pRect);
+private:
+    void vboxSetGlOn(bool on);
+    bool vboxGetGlOn() { return mGlOn; }
+    void vboxSynchGl();
+    void vboxDoVHWACmdExec(void *cmd);
+    void vboxShowOverlay(bool show);
+    void vboxUpdateOverlayPosition(const QPoint & pos);
+    void vboxUpdateOverlay(const QPoint & pos, const QRect & rect, bool show);
+    VBoxGLWidget *mpOverlayWidget;
+    bool mGlOn;
+    bool mOverlayVisible;
+    VBoxVHWADirtyRect mMainDirtyRect;
+};
+#endif
 
 #endif
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h	(revision 22794)
@@ -750,5 +750,11 @@
 #ifdef VBOX_WITH_VIDEOHWACCEL
     static bool isAcceleration2DVideoAvailable();
-    VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() { return VBoxDefs::QGLMode; }
+    VBoxDefs::RenderMode vmAcceleration2DVideoRenderMode() {
+#if 0
+        return VBoxDefs::QGLOverlayMode;
+#else
+        return VBoxDefs::QGLMode;
+#endif
+        }
 #endif
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 22794)
@@ -825,4 +825,7 @@
         case VBoxDefs::QGLMode:
             mFrameBuf = new VBoxQGLFrameBuffer (this);
+            break;
+        case VBoxDefs::QGLOverlayMode:
+            mFrameBuf = new VBoxQGLOverlayFrameBuffer (this);
             break;
 #endif
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQGL.cpp	(revision 22794)
@@ -1735,10 +1735,14 @@
 }
 
-VBoxVHWASurfaceBase::VBoxVHWASurfaceBase(class VBoxGLWidget *aWidget, const QSize * aSize, const QSize * aTargSize,
+VBoxVHWASurfaceBase::VBoxVHWASurfaceBase(class VBoxGLWidget *aWidget,
+        const QSize & aSize,
+        const QRect & aTargRect,
+        const QRect & aSrcRect,
+        const QRect & aVisTargRect,
         VBoxVHWAColorFormat & aColorFormat,
         VBoxVHWAColorKey * pSrcBltCKey, VBoxVHWAColorKey * pDstBltCKey,
                     VBoxVHWAColorKey * pSrcOverlayCKey, VBoxVHWAColorKey * pDstOverlayCKey,
                     bool bVGA) :
-                mRect(0,0,aSize->width(),aSize->height()),
+                mRect(0,0,aSize.width(),aSize.height()),
                 mVisibleDisplayInitialized(false),
                 mAddress(NULL),
@@ -1770,15 +1774,14 @@
     resetDefaultSrcOverlayCKey();
 
-    mpTex[0] = vboxVHWATextureCreate(QRect(0,0,aSize->width(),aSize->height()), mColorFormat, bVGA);
+    mpTex[0] = vboxVHWATextureCreate(QRect(0,0,aSize.width(),aSize.height()), mColorFormat, bVGA);
     if(mColorFormat.fourcc() == FOURCC_YV12)
     {
-        QRect rect(0,0,aSize->width()/2,aSize->height()/2);
+        QRect rect(0,0,aSize.width()/2,aSize.height()/2);
         mpTex[1] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
         mpTex[2] = vboxVHWATextureCreate(rect, mColorFormat, bVGA);
     }
 
-    mSrcRect = mRect;
-    mTargRect = mRect; /* == Vis FB size */
-    mTargSize = QRect(0, 0, aTargSize->width(), aTargSize->height());
+    doSetRectValuesInternal(aTargRect, aSrcRect, aVisTargRect);
+//    mTargSize = QRect(0, 0, aTargSize->width(), aTargSize->height());
 
 //    mBytesPerPixel = calcBytesPerPixel(mColorFormat.format(), mColorFormat.type());
@@ -2644,25 +2647,66 @@
 }
 
-void VBoxVHWASurfaceBase::setRects(VBoxVHWASurfaceBase *pPrimary, const QRect * aTargRect, const QRect * aSrcRect)
-{
-    if(mTargRect == *aTargRect && mSrcRect == *aSrcRect)
-        return;
-
-    mTargRect = *aTargRect;
-    mSrcRect = *aSrcRect;
-
-    initDisplay(pPrimary);
-}
-
-void VBoxVHWASurfaceBase::setTargetRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint * aPoint)
-{
-    if(mTargRect.topLeft() == *aPoint)
-        return;
-
-    mTargRect = QRect(aPoint->x(), aPoint->y(), mTargRect.width(), mTargRect.height());
-
-    initDisplay(pPrimary
-//            false
-            );
+void VBoxVHWASurfaceBase::doSetRectValuesInternal(const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect)
+{
+    mVisibleTargRect = aVisTargRect.intersected(aTargRect);
+    mTargRect = aTargRect;
+    mSrcRect = aSrcRect;
+    if(mVisibleTargRect.isEmpty() || mTargRect.isEmpty())
+    {
+        mVisibleSrcRect.setSize(QSize(0, 0));
+    }
+    else
+    {
+        float stretchX = float(mSrcRect.width()) / mTargRect.width();
+        float stretchY = float(mSrcRect.height()) / mTargRect.height();
+        int tx1, tx2, ty1, ty2, vtx1, vtx2, vty1, vty2;
+        int sx1, sx2, sy1, sy2;
+        mVisibleTargRect.getCoords(&vtx1, &vty1, &vtx2, &vty2);
+        mTargRect.getCoords(&tx1, &ty1, &tx2, &ty2);
+        mSrcRect.getCoords(&sx1, &sy1, &sx2, &sy2);
+        int dx1 = vtx1 - tx1;
+        int dy1 = vty1 - ty1;
+        int dx2 = vtx2 - tx2;
+        int dy2 = vty2 - ty2;
+        int vsx1, vsy1, vsx2, vsy2;
+        Assert(dx1 >= 0);
+        Assert(dy1 >= 0);
+        Assert(dx2 <= 0);
+        Assert(dy2 <= 0);
+        vsx1 = sx1 + int(dx1*stretchX);
+        vsy1 = sy1 + int(dy1*stretchY);
+        vsx2 = sx2 + int(dx2*stretchX);
+        vsy2 = sy2 + int(dy2*stretchY);
+        mVisibleSrcRect.setCoords(vsx1, vsy1, vsx2, vsy2);
+        Assert(mSrcRect.contains(mVisibleSrcRect));
+    }
+}
+
+void VBoxVHWASurfaceBase::setRects(VBoxVHWASurfaceBase *pPrimary, const QRect & aTargRect, const QRect & aSrcRect, const QRect & aVisTargRect, bool bForceReinit)
+{
+    QRect aVisibleTargRect = aVisTargRect.intersected(mTargRect);
+
+    if(mTargRect != aTargRect || mSrcRect != aSrcRect || mVisibleTargRect != aVisibleTargRect)
+    {
+        doSetRectValuesInternal(aTargRect, aSrcRect, aVisTargRect);
+        bForceReinit = true;
+    }
+
+    if(bForceReinit)
+    {
+        initDisplay(pPrimary);
+    }
+}
+
+void VBoxVHWASurfaceBase::setTargRectPosition(VBoxVHWASurfaceBase *pPrimary, const QPoint & aPoint, const QRect & aVisibleTargRect)
+{
+    QRect tRect = targRect();
+    tRect.moveTopLeft(aPoint);
+    setRects(pPrimary, tRect, srcRect(), aVisibleTargRect, false);
+}
+
+void VBoxVHWASurfaceBase::updateVisibleTargRect(VBoxVHWASurfaceBase *pPrimary, const QRect & aVisibleTargRect)
+{
+    setRects(pPrimary, targRect(), srcRect(), aVisibleTargRect, false);
 }
 
@@ -2807,4 +2851,10 @@
 }
 
+//void VBoxVHWASurfaceBase::setVisibleTargetRect(const QRect & aRect)
+//{
+//    Assert(mVisibleRect.contains(aRect));
+//    mVisibleRect = mSrcRect.intersected(aRect);
+//}
+
 void VBoxVHWASurfaceBase::performDisplay(VBoxVHWASurfaceBase *pPrimary)
 {
@@ -2924,5 +2974,16 @@
 void VBoxQGLFrameBuffer::paintEvent (QPaintEvent *pe)
 {
-    vboxWidget()->vboxPaintEvent(pe);
+    VBoxGLWidget * pw = vboxWidget();
+    pw->makeCurrent();
+
+    QRect vp(mView->contentsX(), mView->contentsY(), pw->width(), pw->height());
+    if(vp != pw->vboxViewport())
+    {
+        pw->vboxDoUpdateViewport(&vp);
+    }
+
+    pw->performDisplay();
+
+    pw->swapBuffers();
 }
 
@@ -3173,5 +3234,5 @@
     } while(pFirst);
 
-    mDisplay.performDisplay();
+//    mDisplay.performDisplay();
 }
 
@@ -3473,8 +3534,10 @@
         	                                pCmd->SurfInfo.PixelFormat.m3.rgbBBitMask);
             QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
-            QSize primarySize = mDisplay.getPrimary()->rect().size();
-            surf = new VBoxVHWASurfaceBase(this, &surfSize,
+            QRect primaryRect = mDisplay.getPrimary()->rect();
+            surf = new VBoxVHWASurfaceBase(this, surfSize,
 //                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &surfSize),
-                        &primarySize,
+                        primaryRect,
+                        QRect(0, 0, surfSize.width(), surfSize.height()),
+                        mViewport,
                         format,
                         pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
@@ -3484,10 +3547,12 @@
         {
             QSize surfSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height);
-            QSize primarySize = mDisplay.getPrimary()->rect().size();
+            QRect primaryRect = mDisplay.getPrimary()->rect();
 
             VBoxVHWAColorFormat format(pCmd->SurfInfo.PixelFormat.fourCC);
-            surf = new VBoxVHWASurfaceBase(this, &surfSize,
+            surf = new VBoxVHWASurfaceBase(this, surfSize,
             //                        ((pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY) ? mDisplay.getPrimary()->rect().size() : &QSize(pCmd->SurfInfo.width, pCmd->SurfInfo.height)),
-                                    &primarySize,
+                                    primaryRect,
+                                    QRect(0, 0, surfSize.width(), surfSize.height()),
+                                    mViewport,
                                     format,
                                     pSrcBltCKey, pDstBltCKey, pSrcOverlayCKey, pDstOverlayCKey,
@@ -3502,5 +3567,5 @@
 
         uchar * addr = vboxVRAMAddressFromOffset(pCmd->SurfInfo.offSurface);
-        surf->init(mDisplay.getVGA(), addr);
+        surf->init(mDisplay.getPrimary(), addr);
 
         if(pCmd->SurfInfo.surfCaps & VBOXVHWA_SCAPS_OVERLAY)
@@ -3828,5 +3893,5 @@
         }
 
-        pSrcSurf->setRects(pDstSurf, &dstRect, &srcRect);
+        pSrcSurf->setRects(pDstSurf, dstRect, srcRect, mViewport, true);
     }
 }
@@ -3889,5 +3954,5 @@
     {
         VBoxVHWASurfaceBase *pCurSrcSurf = (*it);
-        pCurSrcSurf->setTargetRectPosition(pDstSurf, &pos);
+        pCurSrcSurf->setTargRectPosition(pDstSurf, pos, mViewport);
     }
 
@@ -4250,5 +4315,5 @@
     int rc = SSMR3PutU32(pSSM, flags); AssertRC(rc);
 
-    rc = SSMR3PutU32(pSSM, mDisplay.getVGA()->handle()); AssertRC(rc);
+    rc = SSMR3PutU32(pSSM, mDisplay.getPrimary()->handle()); AssertRC(rc);
     rc = SSMR3PutU32(pSSM, pSurf->handle()); AssertRC(rc);
 
@@ -4601,28 +4666,84 @@
 #endif
 
-void VBoxGLWidget::vboxDoPaint(void *pe)
-{
-    Q_UNUSED(pe);
-
-#ifdef VBOXQGL_DBG_SURF
-    vboxDoTestSurfaces(NULL);
-#endif
-    QRect vp(mView->contentsX(), mView->contentsY(), width(), height());
-
-    if(vp != mViewport)
-    {
-        adjustViewport(mDisplay.getVGA()->size(), vp);
-        mViewport = vp;
-    }
-
-//#ifdef VBOXQGL_PROF_BASE
-//    vboxDoUpdateRect(&((QPaintEvent*)pe)->rect());
+void VBoxGLWidget::vboxDoUpdateViewport(const QRect * pRect)
+{
+    adjustViewport(mDisplay.getPrimary()->size(), *pRect);
+    mViewport = *pRect;
+
+    const SurfList & primaryList = mDisplay.primaries().surfaces();
+
+    for (SurfList::const_iterator pr = primaryList.begin();
+         pr != primaryList.end(); ++ pr)
+    {
+        VBoxVHWASurfaceBase *pSurf = *pr;
+        pSurf->updateVisibleTargRect(NULL, *pRect);
+    }
+
+    const OverlayList & overlays = mDisplay.overlays();
+
+    for (OverlayList::const_iterator it = overlays.begin();
+         it != overlays.end(); ++ it)
+    {
+        VBoxVHWASurfList * pSurfList = *it;
+        const SurfList & surfaces = pSurfList->surfaces();
+        for (SurfList::const_iterator sit = surfaces.begin();
+             sit != surfaces.end(); ++ sit)
+        {
+            VBoxVHWASurfaceBase *pSurf = *sit;
+            pSurf->updateVisibleTargRect(mDisplay.getPrimary(), *pRect);
+        }
+    }
+}
+
+bool VBoxGLWidget::hasSurfaces() const
+{
+    return mDisplay.overlays().size() != 0;
+}
+
+bool VBoxGLWidget::hasVisibleOverlays()
+{
+    const OverlayList & overlays = mDisplay.overlays();
+    for (OverlayList::const_iterator it = overlays.begin();
+         it != overlays.end(); ++ it)
+    {
+        VBoxVHWASurfList * pSurfList = *it;
+        if(pSurfList->current() != NULL)
+            return true;
+    }
+    return false;
+}
+
+const QRect & VBoxGLWidget::overlaysRectUnion()
+{
+    const OverlayList & overlays = mDisplay.overlays();
+    VBoxVHWADirtyRect un;
+    for (OverlayList::const_iterator it = overlays.begin();
+         it != overlays.end(); ++ it)
+    {
+        VBoxVHWASurfaceBase * pOverlay = (*it)->current();
+        if(pOverlay != NULL)
+        {
+            un.add(pOverlay->targRect());
+        }
+    }
+    return un.toRect();
+}
+
+//void VBoxGLWidget::vboxDoPaint(void *pe)
+//{
+//    Q_UNUSED(pe);
+//
+//#ifdef VBOXQGL_DBG_SURF
+//    vboxDoTestSurfaces(NULL);
 //#endif
-    mDisplay.performDisplay();
-}
+////#ifdef VBOXQGL_PROF_BASE
+////    vboxDoUpdateRect(&((QPaintEvent*)pe)->rect());
+////#endif
+////    mDisplay.performDisplay();
+//}
 
 void VBoxGLWidget::vboxDoUpdateRect(const QRect * pRect)
 {
-    mDisplay.getVGA()->updatedMem(pRect);
+    mDisplay.getPrimary()->updatedMem(pRect);
 }
 
@@ -4790,5 +4911,10 @@
     VBoxVHWAColorFormat format(bitsPerPixel, r,g,b);
     QSize dispSize(displayWidth, displayHeight);
-    pDisplay = new VBoxVHWASurfaceBase(this, &dispSize, &dispSize,
+    QRect dispRect(0, 0, displayWidth, displayHeight);
+    pDisplay = new VBoxVHWASurfaceBase(this,
+            dispSize,
+            dispRect,
+            dispRect,
+            dispRect, /* we do not know viewport at the stage of recise, set as a disp rect, it will be updated on repaint */
     		format,
             (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, (VBoxVHWAColorKey*)NULL, true);
@@ -4906,5 +5032,5 @@
 
 
-    mDisplay.performDisplay();
+//    mDisplay.performDisplay();
 
     if (remind)
@@ -5136,4 +5262,213 @@
     *b = mB.colorValNorm(pix);
 }
-
-#endif
+#ifdef VBOX_WITH_VIDEOHWACCEL
+VBoxQGLOverlayFrameBuffer::VBoxQGLOverlayFrameBuffer (VBoxConsoleView *aView)
+    : VBoxQImageFrameBuffer(aView),
+      mGlOn(false),
+      mOverlayVisible(false)
+{
+    mpOverlayWidget = new VBoxGLWidget (aView, aView->viewport());
+    mpOverlayWidget->setVisible(false);
+}
+
+STDMETHODIMP VBoxQGLOverlayFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
+{
+//    Assert(0);
+    VBOXVHWACMD * pCmd = (VBOXVHWACMD*)pCommand;
+    /* indicate that we process and complete the command asynchronously */
+    pCmd->Flags |= VBOXVHWACMD_FLAG_HG_ASYNCH;
+    /* post the command to the GUI thread for processing */
+//    QApplication::postEvent (mView,
+//                             new VBoxVHWACommandProcessEvent (pCmd));
+    mpOverlayWidget->postCmd(VBOXVHWA_PIPECMD_VHWA, pCmd);
+    return S_OK;
+//    return E_NOTIMPL;
+}
+
+void VBoxQGLOverlayFrameBuffer::doProcessVHWACommand(QEvent * pEvent)
+{
+    mpOverlayWidget->vboxProcessVHWACommands((VBoxVHWACommandProcessEvent*)pEvent);
+}
+
+STDMETHODIMP VBoxQGLOverlayFrameBuffer::NotifyUpdate(ULONG aX, ULONG aY,
+                         ULONG aW, ULONG aH)
+{
+    return VBoxQImageFrameBuffer::NotifyUpdate(aX, aY, aW, aH);
+}
+
+void VBoxQGLOverlayFrameBuffer::paintEvent (QPaintEvent *pe)
+{
+    VBoxQImageFrameBuffer::paintEvent (pe);
+}
+
+void VBoxQGLOverlayFrameBuffer::resizeEvent (VBoxResizeEvent *re)
+{
+    VBoxQImageFrameBuffer::resizeEvent(re);
+
+    if(mGlOn)
+    {
+        /* need to ensure we're in synch */
+        vboxSynchGl();
+    }
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxSynchGl()
+{
+    /* create and issue a resize event to the gl widget to ensure we have all gl data initialized
+     * and synchronized with the framebuffer */
+    VBoxResizeEvent re(pixelFormat(),
+            address(),
+            bitsPerPixel(),
+            bytesPerLine(),
+            width(),
+            height());
+
+    mpOverlayWidget->vboxResizeEvent(&re);
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxSetGlOn(bool on)
+{
+    if(on == mGlOn)
+        return;
+
+    mGlOn = on;
+
+    if(on)
+    {
+        VBOXQGLLOGREL(("Switching Gl mode on\n"));
+        Assert(!mpOverlayWidget->isVisible());
+        /* just to ensure */
+        mpOverlayWidget->setVisible(false);
+        vboxSynchGl();
+    }
+    else
+    {
+        VBOXQGLLOGREL(("Switching Gl mode off\n"));
+        /* for now just set the flag w/o destroying anything */
+    }
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxShowOverlay(bool show)
+{
+    /** @todo */
+    Assert(0);
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxUpdateOverlayPosition(const QPoint & pos)
+{
+    /** @todo */
+    Assert(0);
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxUpdateOverlay(const QPoint & pos, const QRect & rect, bool show)
+{
+    /** @todo */
+    Assert(0);
+}
+
+void VBoxQGLOverlayFrameBuffer::vboxDoVHWACmdExec(void *cmd)
+{
+    struct _VBOXVHWACMD * pCmd = (struct _VBOXVHWACMD *)cmd;
+    switch(pCmd->enmCmd)
+    {
+        case VBOXVHWACMD_TYPE_SURF_CANCREATE:
+        {
+            VBOXVHWACMD_SURF_CANCREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceCanCreate(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_CREATE:
+        {
+            VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
+            vboxSetGlOn(true);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceCreate(pBody);
+            if(!mpOverlayWidget->hasSurfaces())
+            {
+                vboxSetGlOn(false);
+            }
+            else if(mpOverlayWidget->hasVisibleOverlays())
+            {
+                QRect overRect = mpOverlayWidget->overlaysRectUnion();
+                vboxUpdateOverlay(QPoint(overRect.x(), overRect.y()), overRect, true);
+            }
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_DESTROY:
+        {
+            VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceDestroy(pBody);
+            if(!mpOverlayWidget->hasSurfaces())
+            {
+                vboxSetGlOn(false);
+            }
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_LOCK:
+        {
+            VBOXVHWACMD_SURF_LOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceLock(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_UNLOCK:
+        {
+            VBOXVHWACMD_SURF_UNLOCK * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceUnlock(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_BLT:
+        {
+            VBOXVHWACMD_SURF_BLT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceBlt(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_FLIP:
+        {
+            VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceFlip(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE:
+        {
+            VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlayUpdate(pBody);
+            if(mpOverlayWidget->hasVisibleOverlays())
+            {
+                QRect overRect = mpOverlayWidget->overlaysRectUnion();
+                vboxUpdateOverlay(QPoint(overRect.x(), overRect.y()), overRect, true);
+            }
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION:
+        {
+            VBOXVHWACMD_SURF_OVERLAY_SETPOSITION * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceOverlaySetPosition(pBody);
+            if(mpOverlayWidget->hasVisibleOverlays())
+            {
+                QRect overRect = mpOverlayWidget->overlaysRectUnion();
+                vboxUpdateOverlayPosition(QPoint(overRect.x(), overRect.y()));
+            }
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_COLORKEY_SET:
+        {
+            VBOXVHWACMD_SURF_COLORKEY_SET * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET);
+            pCmd->rc = mpOverlayWidget->vhwaSurfaceColorkeySet(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_QUERY_INFO1:
+        {
+            VBOXVHWACMD_QUERYINFO1 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
+            pCmd->rc = mpOverlayWidget->vhwaQueryInfo1(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_QUERY_INFO2:
+        {
+            VBOXVHWACMD_QUERYINFO2 * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
+            pCmd->rc = mpOverlayWidget->vhwaQueryInfo2(pBody);
+        } break;
+        case VBOXVHWACMD_TYPE_ENABLE:
+        case VBOXVHWACMD_TYPE_DISABLE:
+            pCmd->rc = VINF_SUCCESS;
+            break;
+        case VBOXVHWACMD_TYPE_HH_CONSTRUCT:
+        {
+            VBOXVHWACMD_HH_CONSTRUCT * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_HH_CONSTRUCT);
+            pCmd->rc = mpOverlayWidget->vhwaConstruct(pBody);
+        } break;
+        default:
+            Assert(0);
+            pCmd->rc = VERR_NOT_IMPLEMENTED;
+            break;
+    }
+}
+#endif
+#endif
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 22793)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 22794)
@@ -549,4 +549,9 @@
             mode = VBoxDefs::QGLMode;
 #endif
+#if defined (VBOX_GUI_USE_QGL)
+        else if (::strcmp (aModeStr, "qgloverlay") == 0)
+            mode = VBoxDefs::QGLOverlayMode;
+#endif
+
     }
 
