Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 49166)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 49167)
@@ -1,7 +1,5 @@
 /* $Id$ */
 /** @file
- *
- * VBox frontends: Qt GUI ("VirtualBox"):
- * UIFrameBuffer class and subclasses implementation
+ * VBox Qt GUI - UIFrameBuffer class implementation.
  */
 
@@ -46,5 +44,5 @@
     : m_pMachineView(pMachineView)
     , m_width(0), m_height(0)
-    , m_fIsScheduledToDelete(false)
+    , m_fIsMarkedAsUnused(false)
 #ifdef Q_OS_WIN
     , m_iRefCnt(0)
@@ -52,24 +50,49 @@
 {
     /* Assign mahine-view: */
-    AssertMsg(m_pMachineView, ("UIMachineView must not be null\n"));
+    AssertMsg(m_pMachineView, ("UIMachineView must not be NULL\n"));
     m_WinId = (m_pMachineView && m_pMachineView->viewport()) ? (LONG64)m_pMachineView->viewport()->winId() : 0;
+
+    /* Initialize critical-section: */
+    int rc = RTCritSectInit(&m_critSect);
+    AssertRC(rc);
 
     /* Connect handlers: */
     if (m_pMachineView)
         prepareConnections();
-
-    /* Initialize critical-section: */
-    int rc = RTCritSectInit(&m_critSect);
-    AssertRC(rc);
 }
 
 UIFrameBuffer::~UIFrameBuffer()
 {
-    /* Deinitialize critical-section: */
-    RTCritSectDelete(&m_critSect);
-
     /* Disconnect handlers: */
     if (m_pMachineView)
         cleanupConnections();
+
+    /* Deinitialize critical-section: */
+    RTCritSectDelete(&m_critSect);
+}
+
+/**
+ * Checks if the framebuffer marked as <b>unused</b>.
+ * @returns @c true if framebuffer ingores EMT events, @c false otherwise.
+ * @note    Any call to this (and #setMarkAsUnused method) is synchronized between calling threads.
+ */
+bool UIFrameBuffer::isMarkedAsUnused() const
+{
+    lock();
+    bool fIsMarkedAsUnused = m_fIsMarkedAsUnused;
+    unlock();
+    return fIsMarkedAsUnused;
+}
+
+/**
+ * Sets the framebuffer <b>unused</b> status.
+ * @param fIsMarkAsUnused determines whether framebuffer should ignore EMT events or not.
+ * @note  Any call to this (and #isMarkedAsUnused method) is synchronized between calling threads.
+ */
+void UIFrameBuffer::setMarkAsUnused(bool fIsMarkAsUnused)
+{
+    lock();
+    m_fIsMarkedAsUnused = fIsMarkAsUnused;
+    unlock();
 }
 
@@ -180,29 +203,29 @@
                 (unsigned long)uWidth, (unsigned long)uHeight));
 
-    /* Make sure frame-buffer is not yet scheduled for removal: */
-    if (m_fIsScheduledToDelete)
+    /* Make sure result pointer is valid: */
+    if (!pbFinished)
+        return E_POINTER;
+
+    /* Make sure frame-buffer is used: */
+    if (isMarkedAsUnused())
+    {
+        LogRelFlow(("UIFrameBuffer::RequestResize: Ignored!\n"));
+
+        /* Mark request as finished.
+         * It is required to report to the VM thread that we finished resizing and rely on the
+         * later synchronisation when the new view is attached. */
+        *pbFinished = TRUE;
+
+        /* Ignore RequestResize: */
         return E_FAIL;
-
-    /* Currently screen ID is not used: */
-    Q_UNUSED(uScreenId);
+    }
 
     /* Mark request as not-yet-finished: */
     *pbFinished = FALSE;
 
-    /* See comment in setView(): */
-    lock();
-
-    /* Widget resize is NOT thread safe and never will be,
-     * We have to notify the machine-view with the async signal to perform resize operation. */
-    if (m_pMachineView)
-        emit sigRequestResize(uPixelFormat, pVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight);
-    else
-        /* Mark request as finished.
-         * It is required to report to the VM thread that we finished resizing and rely on the
-         * synchronisation when the new view is attached. */
-        *pbFinished = TRUE;
-
-    /* Unlock thread finally: */
-    unlock();
+    /* Widget resize is NOT thread-safe and *probably* never will be,
+     * We have to notify machine-view with the async-signal to perform resize operation. */
+    LogRelFlow(("UIFrameBuffer::RequestResize: Sending to async-handler...\n"));
+    emit sigRequestResize(uPixelFormat, pVRAM, uBitsPerPixel, uBytesPerLine, uWidth, uHeight);
 
     /* Confirm RequestResize: */
@@ -212,22 +235,21 @@
 STDMETHODIMP UIFrameBuffer::NotifyUpdate(ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight)
 {
-    LogRelFlow(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu\n",
-                (unsigned long)uX, (unsigned long)uY,
-                (unsigned long)uWidth, (unsigned long)uHeight));
-
-    /* Make sure frame-buffer is not yet scheduled for removal: */
-    if (m_fIsScheduledToDelete)
+    LogRel2(("UIFrameBuffer::NotifyUpdate: Origin=%lux%lu, Size=%lux%lu\n",
+             (unsigned long)uX, (unsigned long)uY,
+             (unsigned long)uWidth, (unsigned long)uHeight));
+
+    /* Make sure frame-buffer is used: */
+    if (isMarkedAsUnused())
+    {
+        LogRel2(("UIFrameBuffer::NotifyUpdate: Ignored!\n"));
+
+        /* Ignore NotifyUpdate: */
         return E_FAIL;
-
-    /* See comment in setView(): */
-    lock();
-
-    /* QWidget::update() is NOT thread safe and seems never will be,
-     * So we have to notify the machine-view with the async signal to perform update operation. */
-    if (m_pMachineView)
-        emit sigNotifyUpdate(uX, uY, uWidth, uHeight);
-
-    /* Unlock thread finally: */
-    unlock();
+    }
+
+    /* Widget update is NOT thread-safe and *seems* never will be,
+     * We have to notify machine-view with the async-signal to perform update operation. */
+    LogRel2(("UIFrameBuffer::NotifyUpdate: Sending to async-handler...\n"));
+    emit sigNotifyUpdate(uX, uY, uWidth, uHeight);
 
     /* Confirm NotifyUpdate: */
@@ -237,33 +259,27 @@
 STDMETHODIMP UIFrameBuffer::VideoModeSupported(ULONG uWidth, ULONG uHeight, ULONG uBPP, BOOL *pbSupported)
 {
-    LogRelFlow(("UIFrameBuffer::VideoModeSupported: Mode: BPP=%lu, Size=%lux%lu\n",
-                (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight));
-
-    /* Make sure frame-buffer is not yet scheduled for removal: */
-    if (m_fIsScheduledToDelete)
+    LogRel2(("UIFrameBuffer::IsVideoModeSupported: Mode: BPP=%lu, Size=%lux%lu\n",
+             (unsigned long)uBPP, (unsigned long)uWidth, (unsigned long)uHeight));
+
+    /* Make sure frame-buffer is used: */
+    if (isMarkedAsUnused())
+    {
+        LogRel2(("UIFrameBuffer::IsVideoModeSupported: Ignored!\n"));
+
+        /* Ignore VideoModeSupported: */
         return E_FAIL;
-
+    }
+
+    /* Make sure result pointer is valid: */
     if (!pbSupported)
         return E_POINTER;
+
+    /* Determine if supported: */
     *pbSupported = TRUE;
-
-    /* Currently BPP is not used: */
-    Q_UNUSED(uBPP);
-
-    /* See comment in setView(): */
-    lock();
-
-    QSize screenSize;
-    if (m_pMachineView)
-        screenSize = m_pMachineView->maxGuestSize();
-
-    /* Unlock thread finally: */
-    unlock();
-
+    QSize screenSize = m_pMachineView->maxGuestSize();
     if (   (screenSize.width() != 0)
         && (uWidth > (ULONG)screenSize.width())
         && (uWidth > (ULONG)width()))
         *pbSupported = FALSE;
-
     if (   (screenSize.height() != 0)
         && (uHeight > (ULONG)screenSize.height())
@@ -271,6 +287,5 @@
         *pbSupported = FALSE;
 
-    LogRelFlow(("UIFrameBuffer::VideoModeSupported: Verdict: Supported=%s\n",
-                *pbSupported ? "TRUE" : "FALSE"));
+    LogRel2(("UIFrameBuffer::IsVideoModeSupported: %s\n", *pbSupported ? "TRUE" : "FALSE"));
 
     /* Confirm VideoModeSupported: */
@@ -293,9 +308,15 @@
 STDMETHODIMP UIFrameBuffer::SetVisibleRegion(BYTE *pRectangles, ULONG uCount)
 {
-    LogRelFlow(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu\n", (unsigned long)uCount));
-
-    /* Make sure frame-buffer is not yet scheduled for removal: */
-    if (m_fIsScheduledToDelete)
+    LogRel2(("UIFrameBuffer::SetVisibleRegion: Rectangle count=%lu\n",
+             (unsigned long)uCount));
+
+    /* Make sure frame-buffer is used: */
+    if (isMarkedAsUnused())
+    {
+        LogRel2(("UIFrameBuffer::SetVisibleRegion: Ignored!\n"));
+
+        /* Ignore SetVisibleRegion: */
         return E_FAIL;
+    }
 
     /* Make sure rectangles were passed: */
@@ -320,15 +341,9 @@
     }
 
-    /* See comment in setView(): */
-    lock();
-
     /* We are directly updating synchronous visible-region: */
     m_syncVisibleRegion = region;
-    /* And send async signal to update asynchronous one: */
-    if (m_pMachineView)
-        emit sigSetVisibleRegion(region);
-
-    /* Unlock thread finally: */
-    unlock();
+    /* And send async-signal to update asynchronous one: */
+    LogRel2(("UIFrameBuffer::SetVisibleRegion: Sending to async-handler...\n"));
+    emit sigSetVisibleRegion(region);
 
     /* Confirm SetVisibleRegion: */
@@ -344,19 +359,36 @@
 STDMETHODIMP UIFrameBuffer::Notify3DEvent(ULONG uType, BYTE *pData)
 {
+    LogRel2(("UIFrameBuffer::Notify3DEvent\n"));
+
+    /* Make sure frame-buffer is used: */
+    if (isMarkedAsUnused())
+    {
+        LogRel2(("UIFrameBuffer::Notify3DEvent: Ignored!\n"));
+
+        /* Ignore Notify3DEvent: */
+        return E_FAIL;
+    }
+
     switch (uType)
     {
         case VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA:
         {
-            /* Notify GUI about 3D overlay visibility change: */
+            /* Notify machine-view with the async-signal
+             * about 3D overlay visibility change: */
             BOOL fVisible = !!pData;
-            LogRelFlow(("UIFrameBuffer::Notify3DEvent: "
-                        "VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA=%s\n",
-                        fVisible ? "TRUE" : "FALSE"));
+            LogRel2(("UIFrameBuffer::Notify3DEvent: Sending to async-handler: "
+                     "(VBOX3D_NOTIFY_EVENT_TYPE_VISIBLE_3DDATA = %s)\n",
+                     fVisible ? "TRUE" : "FALSE"));
             emit sigNotifyAbout3DOverlayVisibilityChange(fVisible);
+
+            /* Confirm Notify3DEvent: */
             return S_OK;
         }
         default:
-            return E_INVALIDARG;
-    }
+            break;
+    }
+
+    /* Ignore Notify3DEvent: */
+    return E_INVALIDARG;
 }
 
@@ -392,10 +424,4 @@
 void UIFrameBuffer::setView(UIMachineView * pView)
 {
-    /* We are not supposed to use locking for things which are done
-     * on the GUI thread.  Unfortunately I am not clever enough to
-     * understand the original author's wise synchronisation logic
-     * so I will do it anyway. */
-    lock();
-
     /* Disconnect handlers: */
     if (m_pMachineView)
@@ -409,7 +435,4 @@
     if (m_pMachineView)
         prepareConnections();
-
-    /* Unlock thread finally: */
-    unlock();
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 49166)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 49167)
@@ -1,6 +1,4 @@
 /** @file
- *
- * VBox frontends: Qt GUI ("VirtualBox"):
- * UIFrameBuffer class and subclasses declarations
+ * VBox Qt GUI - UIFrameBuffer class declaration.
  */
 
@@ -106,5 +104,7 @@
     virtual ~UIFrameBuffer();
 
-    void setScheduledToDelete(bool fIsScheduledToDelete) { m_fIsScheduledToDelete = fIsScheduledToDelete; }
+    /* API: [Un]used status stuff: */
+    bool isMarkedAsUnused() const;
+    void setMarkAsUnused(bool fIsMarkAsUnused);
 
     NS_DECL_ISUPPORTS
@@ -180,6 +180,6 @@
     }
 
-    void lock() { RTCritSectEnter(&m_critSect); }
-    void unlock() { RTCritSectLeave(&m_critSect); }
+    void lock() const { RTCritSectEnter(&m_critSect); }
+    void unlock() const { RTCritSectLeave(&m_critSect); }
 
     virtual uchar *address() = 0;
@@ -209,10 +209,10 @@
 
     UIMachineView *m_pMachineView;
-    RTCRITSECT m_critSect;
+    mutable RTCRITSECT m_critSect;
     ulong m_width;
     ulong m_height;
     QSize m_scaledSize;
     int64_t m_WinId;
-    bool m_fIsScheduledToDelete;
+    bool m_fIsMarkedAsUnused;
 
     /* To avoid a seamless flicker,
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 49166)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp	(revision 49167)
@@ -284,4 +284,11 @@
     /* Emit a signal about guest was resized: */
     emit resizeHintDone();
+
+    LogRelFlow(("UIMachineView::ResizeHandled: "
+                "Screen=%d, Format=%d, "
+                "BitsPerPixel=%d, BytesPerLine=%d, "
+                "Size=%dx%d.\n\n",
+                (unsigned long)m_uScreenId, iPixelFormat,
+                iBitsPerPixel, iBytesPerLine, iWidth, iHeight));
 }
 
@@ -412,7 +419,12 @@
         case QImageMode:
         {
-            UIFrameBuffer* pFrameBuffer = uisession()->frameBuffer(screenId());
+            UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId());
             if (pFrameBuffer)
+            {
                 pFrameBuffer->setView(this);
+                /* Mark framebuffer as used again: */
+                LogRelFlow(("UIMachineView::prepareFrameBuffer: Start EMT callbacks accepting for screen: %d.\n", screenId()));
+                pFrameBuffer->setMarkAsUnused(false);
+            }
             else
             {
@@ -442,7 +454,12 @@
             /* Indicate that we are doing all drawing stuff ourself: */
             viewport()->setAttribute(Qt::WA_PaintOnScreen);
-            UIFrameBuffer* pFrameBuffer = uisession()->frameBuffer(screenId());
+            UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(screenId());
             if (pFrameBuffer)
+            {
                 pFrameBuffer->setView(this);
+                /* Mark framebuffer as used again: */
+                LogRelFlow(("UIMachineView::prepareFrameBuffer: Start EMT callbacks accepting for screen: %d.\n", screenId()));
+                pFrameBuffer->setMarkAsUnused(false);
+            }
             else
             {
@@ -595,45 +612,27 @@
 void UIMachineView::cleanupFrameBuffer()
 {
-    if (m_pFrameBuffer)
-    {
-        /* Process pending frame-buffer resize events: */
-        QApplication::sendPostedEvents(this, ResizeEventType);
-        if (   0
-#ifdef VBOX_GUI_USE_QIMAGE
-            || vboxGlobal().vmRenderMode() == QImageMode
-#endif /* VBOX_GUI_USE_QIMAGE */
-#ifdef VBOX_GUI_USE_QUARTZ2D
-            || vboxGlobal().vmRenderMode() == Quartz2DMode
-#endif /* VBOX_GUI_USE_QUARTZ2D */
-#ifdef VBOX_WITH_VIDEOHWACCEL
-            || m_fAccelerate2DVideo
-#endif /* VBOX_WITH_VIDEOHWACCEL */
-           )
-        {
-            Assert(m_pFrameBuffer == uisession()->frameBuffer(screenId()));
-            CDisplay display = session().GetConsole().GetDisplay();
-            /* Temporarily remove the framebuffer in Display while unsetting
-             * the view in order to respect the thread synchonisation logic
-             * (see UIFrameBuffer.h). */
-            /* Note! VBOX_WITH_CROGL additionally requires us to call
-             * SetFramebuffer to ensure 3D gets notified of view being
-             * destroyed */
-            display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL));
-            m_pFrameBuffer->setView(NULL);
-            display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer));
-        }
-        else
-        {
-            /* Warn framebuffer about its no more necessary: */
-            m_pFrameBuffer->setScheduledToDelete(true);
-            /* Detach framebuffer from Display: */
-            CDisplay display = session().GetConsole().GetDisplay();
-            display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL));
-            /* Release the reference: */
-            m_pFrameBuffer->Release();
-//          delete m_pFrameBuffer; // TODO_NEW_CORE: possibly necessary to really cleanup
-            m_pFrameBuffer = NULL;
-        }
-    }
+    /* Make sure proper framebuffer assigned: */
+    AssertReturnVoid(m_pFrameBuffer);
+    AssertReturnVoid(m_pFrameBuffer == uisession()->frameBuffer(screenId()));
+
+    /* Mark framebuffer as unused: */
+    LogRelFlow(("UIMachineView::cleanupFrameBuffer: Stop EMT callbacks accepting for screen: %d.\n", screenId()));
+    m_pFrameBuffer->setMarkAsUnused(true);
+
+    /* Process pending framebuffer events: */
+    QApplication::sendPostedEvents(this, QEvent::MetaCall);
+
+    /* Temporarily detach the framebuffer from IDisplay before detaching
+     * from view in order to respect the thread synchonisation logic (see UIFrameBuffer.h).
+     * Note: VBOX_WITH_CROGL additionally requires us to call SetFramebuffer
+     * to ensure 3D gets notified of view being destroyed... */
+    CDisplay display = session().GetConsole().GetDisplay();
+    display.SetFramebuffer(m_uScreenId, CFramebuffer(NULL));
+
+    /* Detach framebuffer from view: */
+    m_pFrameBuffer->setView(NULL);
+
+    /* Attach frambuffer back to IDisplay: */
+    display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer));
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 49166)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 49167)
@@ -1150,10 +1150,10 @@
         if (pFb)
         {
-            /* Warn framebuffer about its no more necessary: */
-            pFb->setScheduledToDelete(true);
+            /* Mark framebuffer as unused: */
+            pFb->setMarkAsUnused(true);
             /* Detach framebuffer from Display: */
             CDisplay display = session().GetConsole().GetDisplay();
             display.SetFramebuffer(i, CFramebuffer(NULL));
-            /* Release the reference: */
+            /* Release framebuffer reference: */
             pFb->Release();
         }
