Index: trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 52573)
+++ trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 52574)
@@ -394,4 +394,25 @@
 }
 
+STDMETHODIMP VBoxSDLFB::COMGETTER(Capabilities)(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities))
+{
+    if (ComSafeArrayOutIsNull(aCapabilities))
+        return E_POINTER;
+
+    com::SafeArray<FramebufferCapabilities_T> caps;
+
+    if (mfUpdateImage)
+    {
+        caps.resize(1);
+        caps[0] = FramebufferCapabilities_UpdateImage;
+    }
+    else
+    {
+        /* No caps to return. */
+    }
+
+    caps.detachTo(ComSafeArrayOutArg(aCapabilities));
+    return S_OK;
+}
+
 /**
  * Notify framebuffer of an update.
@@ -666,9 +687,4 @@
 
     resizeGuest();
-
-    if (mfUpdateImage)
-    {
-        gpDisplay->SetFramebufferUpdateMode(aScreenId, FramebufferUpdateMode_NotifyUpdateImage);
-    }
 
     gpDisplay->InvalidateAndUpdateScreen(aScreenId);
Index: trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 52573)
+++ trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 52574)
@@ -80,4 +80,5 @@
     STDMETHOD(COMGETTER(Overlay)) (IFramebufferOverlay **aOverlay);
     STDMETHOD(COMGETTER(WinId)) (int64_t *winId);
+    STDMETHOD(COMGETTER(Capabilities))(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities));
 
     STDMETHOD(NotifyUpdate)(ULONG x, ULONG y, ULONG w, ULONG h);
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 52573)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp	(revision 52574)
@@ -194,4 +194,18 @@
 }
 
+STDMETHODIMP UIFrameBuffer::COMGETTER(Capabilities)(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities))
+{
+    if (ComSafeArrayOutIsNull(aCapabilities))
+        return E_POINTER;
+
+    com::SafeArray<FramebufferCapabilities_T> caps;
+    caps.resize(2);
+    caps[0] = FramebufferCapabilities_VHWA;
+    caps[1] = FramebufferCapabilities_VisibleRegion;
+
+    caps.detachTo(ComSafeArrayOutArg(aCapabilities));
+    return S_OK;
+}
+
 STDMETHODIMP UIFrameBuffer::NotifyChange(ULONG uScreenId, ULONG uX, ULONG uY, ULONG uWidth, ULONG uHeight)
 {
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 52573)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h	(revision 52574)
@@ -105,4 +105,5 @@
     STDMETHOD(COMGETTER(Overlay))(IFramebufferOverlay **ppOverlay);
     STDMETHOD(COMGETTER(WinId))(LONG64 *pWinId);
+    STDMETHOD(COMGETTER(Capabilities))(ComSafeArrayOut(FramebufferCapabilities_T, aCapabilities));
 
     /** EMT callback: Notifies frame-buffer about guest-screen size change.
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 52573)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 52574)
@@ -15296,24 +15296,4 @@
   -->
 
-  <enum
-    name="FramebufferUpdateMode"
-    uuid="1268d8ab-dd2f-443c-bc56-d93d3ced5cde"
-    >
-    <desc>
-      How a framebuffer is notified about screen updates.
-    </desc>
-
-    <const name="NotifyUpdate"       value="0">
-      <desc>
-        IFramebuffer::NotifyUpdate is called.
-      </desc>
-    </const>
-    <const name="NotifyUpdateImage"  value="1">
-      <desc>
-        IFramebuffer::NotifyUpdateImage is called.
-      </desc>
-    </const>
-  </enum>
-
   <interface
     name="IDisplaySourceBitmap" extends="$unknown" wsmap="suppress"
@@ -15333,7 +15313,34 @@
   </interface>
 
+  <enum
+    name="FramebufferCapabilities"
+    uuid="cc395839-30fa-4ca5-ae65-e6360e3edd7a"
+    >
+    <desc>
+      Framebuffer capability flags.
+    </desc>
+
+    <const name="UpdateImage" value="0x01">
+      <desc>
+        Requires NotifyUpdateImage. NotifyUpdate must not be called.
+      </desc>
+    </const>
+
+    <const name="VHWA" value="0x02">
+      <desc>
+        Supports VHWA interface. If set, then IFramebuffer::processVHWACommand can be called.
+      </desc>
+    </const>
+
+    <const name="VisibleRegion" value="0x04">
+      <desc>
+        Supports visible region. If set, then IFramebuffer::setVisibleRegion can be called.
+      </desc>
+    </const>
+  </enum>
+
   <interface
     name="IFramebuffer" extends="$unknown"
-    uuid="16d73cd3-da84-4a11-a607-ebab57d050d0"
+    uuid="735365aa-544d-415c-a25b-a5ea913d63f3"
     wsmap="managed"
     >
@@ -15560,4 +15567,13 @@
     </method>
 
+    <attribute name="capabilities" type="FramebufferCapabilities" safearray="yes" readonly="yes">
+      <desc>
+        Capabilities of the framebuffer instance.
+
+        For the meaning of individual capability flags see
+        <link to="FramebufferCapabilities"/>.
+      </desc>
+    </attribute>
+
   </interface>
 
@@ -15610,5 +15626,5 @@
   <interface
     name="IDisplay" extends="$unknown"
-    uuid="1659de81-24f0-41a9-afd4-abd03dcfbcbc"
+    uuid="fb51010f-eefd-430d-8cd7-3c1bc14740eb"
     wsmap="managed"
     wrap-hint-server-addinterfaces="IEventListener"
@@ -15909,10 +15925,4 @@
       <param name="screenId" type="unsigned long" dir="in"/>
       <param name="displaySourceBitmap" type="IDisplaySourceBitmap" dir="out"/>
-    </method>
-
-    <method name="setFramebufferUpdateMode">
-      <desc>Select how the framebuffer is informed about screen updates.</desc>
-      <param name="screenId" type="unsigned long" dir="in"/>
-      <param name="framebufferUpdateMode" type="FramebufferUpdateMode" dir="in"/>
     </method>
 
Index: trunk/src/VBox/Main/include/DisplayImpl.h
===================================================================
--- trunk/src/VBox/Main/include/DisplayImpl.h	(revision 52573)
+++ trunk/src/VBox/Main/include/DisplayImpl.h	(revision 52574)
@@ -47,5 +47,5 @@
     bool fDisabled;
 
-    FramebufferUpdateMode_T enmFramebufferUpdateMode;
+    uint32_t u32Caps;
 
     struct
@@ -232,6 +232,4 @@
     virtual HRESULT querySourceBitmap(ULONG aScreenId,
                                       ComPtr<IDisplaySourceBitmap> &aDisplaySourceBitmap);
-    virtual HRESULT setFramebufferUpdateMode(ULONG aScreenId,
-                                             FramebufferUpdateMode_T aFramebufferUpdateMode);
 
     // Wrapped IEventListener properties
Index: trunk/src/VBox/Main/src-client/DisplayImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 52573)
+++ trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 52574)
@@ -595,5 +595,5 @@
         maFramebuffers[ul].fDisabled = ul > 0;
 
-        maFramebuffers[ul].enmFramebufferUpdateMode = FramebufferUpdateMode_NotifyUpdate;
+        maFramebuffers[ul].u32Caps = 0;
 
         maFramebuffers[ul].updateImage.pu8Address = NULL;
@@ -855,9 +855,13 @@
     }
 
-    SetFramebufferUpdateMode(uScreenId, FramebufferUpdateMode_NotifyUpdate);
+    DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId];
+
+    /* Reset the update mode. */
+    pFBInfo->updateImage.pSourceBitmap.setNull();
+    pFBInfo->updateImage.pu8Address = NULL;
+    pFBInfo->updateImage.cbLine = 0;
 
     if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
     {
-        DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId];
         pFBInfo->w = w;
         pFBInfo->h = h;
@@ -892,4 +896,33 @@
 
     i_handleResizeCompletedEMT(uScreenId, TRUE);
+
+    bool fUpdateImage = RT_BOOL(pFBInfo->u32Caps & FramebufferCapabilities_UpdateImage);
+    if (fUpdateImage && !pFBInfo->pFramebuffer.isNull())
+    {
+        ComPtr<IDisplaySourceBitmap> pSourceBitmap;
+        HRESULT hr = QuerySourceBitmap(uScreenId, pSourceBitmap.asOutParam());
+        if (SUCCEEDED(hr))
+        {
+            BYTE *pAddress = NULL;
+            ULONG ulWidth = 0;
+            ULONG ulHeight = 0;
+            ULONG ulBitsPerPixel = 0;
+            ULONG ulBytesPerLine = 0;
+            ULONG ulPixelFormat = 0;
+
+            hr = pSourceBitmap->QueryBitmapInfo(&pAddress,
+                                                &ulWidth,
+                                                &ulHeight,
+                                                &ulBitsPerPixel,
+                                                &ulBytesPerLine,
+                                                &ulPixelFormat);
+            if (SUCCEEDED(hr))
+            {
+                pFBInfo->updateImage.pSourceBitmap = pSourceBitmap;
+                pFBInfo->updateImage.pu8Address = pAddress;
+                pFBInfo->updateImage.cbLine = ulBytesPerLine;
+            }
+        }
+    }
 
     return VINF_SUCCESS;
@@ -1053,9 +1086,10 @@
         if (w != 0 && h != 0)
         {
-            if (RT_LIKELY(maFramebuffers[uScreenId].enmFramebufferUpdateMode == FramebufferUpdateMode_NotifyUpdate))
+            bool fUpdateImage = RT_BOOL(maFramebuffers[uScreenId].u32Caps & FramebufferCapabilities_UpdateImage);
+            if (RT_LIKELY(!fUpdateImage))
             {
                 pFramebuffer->NotifyUpdate(x, y, w, h);
             }
-            else if (maFramebuffers[uScreenId].enmFramebufferUpdateMode == FramebufferUpdateMode_NotifyUpdateImage)
+            else
             {
                 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -1195,5 +1229,6 @@
         DISPLAYFBINFO *pFBInfo = &maFramebuffers[uScreenId];
 
-        if (!pFBInfo->pFramebuffer.isNull())
+        if (  !pFBInfo->pFramebuffer.isNull()
+            & RT_BOOL(pFBInfo->u32Caps & FramebufferCapabilities_VisibleRegion))
         {
             /* Prepare a new array of rectangles which intersect with the framebuffer.
@@ -2255,4 +2290,11 @@
 
     pFBInfo->pFramebuffer = aFramebuffer;
+
+    SafeArray<FramebufferCapabilities_T> caps;
+    pFBInfo->pFramebuffer->COMGETTER(Capabilities)(ComSafeArrayAsOutParam(caps));
+    pFBInfo->u32Caps = 0;
+    size_t i;
+    for (i = 0; i < caps.size(); ++i)
+        pFBInfo->u32Caps |= caps[i];
 
     alock.release();
@@ -3438,62 +3480,4 @@
 }
 
-HRESULT Display::setFramebufferUpdateMode(ULONG aScreenId, FramebufferUpdateMode_T aFramebufferUpdateMode)
-{
-    LogRelFlowFunc(("aScreenId %d, aFramebufferUpdateMode %d\n", aScreenId, aFramebufferUpdateMode));
-
-    HRESULT hr = S_OK;
-
-    /* Prepare without taking a lock. API has it's own locking. */
-    ComPtr<IDisplaySourceBitmap> pSourceBitmap;
-    if (aFramebufferUpdateMode == FramebufferUpdateMode_NotifyUpdateImage)
-    {
-        /* A source bitmap will be needed. */
-        hr = QuerySourceBitmap(aScreenId, pSourceBitmap.asOutParam());
-    }
-
-    if (FAILED(hr))
-        return hr;
-
-    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    if (aScreenId >= mcMonitors)
-        return setError(E_INVALIDARG, tr("SetFramebufferUpdateMode: Invalid screen %d (total %d)"),
-                        aScreenId, mcMonitors);
-
-    DISPLAYFBINFO *pFBInfo = &maFramebuffers[aScreenId];
-
-    /* Reset the update mode. */
-    pFBInfo->updateImage.pSourceBitmap.setNull();
-    pFBInfo->updateImage.pu8Address = NULL;
-    pFBInfo->updateImage.cbLine = 0;
-
-    if (aFramebufferUpdateMode == FramebufferUpdateMode_NotifyUpdateImage)
-    {
-        BYTE *pAddress = NULL;
-        ULONG ulWidth = 0;
-        ULONG ulHeight = 0;
-        ULONG ulBitsPerPixel = 0;
-        ULONG ulBytesPerLine = 0;
-        ULONG ulPixelFormat = 0;
-
-        hr = pSourceBitmap->QueryBitmapInfo(&pAddress,
-                                            &ulWidth,
-                                            &ulHeight,
-                                            &ulBitsPerPixel,
-                                            &ulBytesPerLine,
-                                            &ulPixelFormat);
-        if (SUCCEEDED(hr))
-        {
-            pFBInfo->updateImage.pSourceBitmap = pSourceBitmap;
-            pFBInfo->updateImage.pu8Address = pAddress;
-            pFBInfo->updateImage.cbLine = ulBytesPerLine;
-        }
-    }
-
-    pFBInfo->enmFramebufferUpdateMode = aFramebufferUpdateMode;
-
-    return S_OK;
-}
-
 // wrapped IEventListener method
 HRESULT Display::handleEvent(const ComPtr<IEvent> &aEvent)
@@ -4111,7 +4095,8 @@
     AutoReadLock arlock(this COMMA_LOCKVAL_SRC_POS);
     pFramebuffer = maFramebuffers[id].pFramebuffer;
+    bool fVHWASupported = RT_BOOL(maFramebuffers[id].u32Caps & FramebufferCapabilities_VHWA);
     arlock.release();
 
-    if (pFramebuffer == NULL)
+    if (pFramebuffer == NULL || !fVHWASupported)
         return VERR_NOT_IMPLEMENTED; /* Implementation is not available. */
 
