Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 33364)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3D.cpp	(revision 33365)
@@ -5665,4 +5665,37 @@
         hr = pDevice->RtCallbacks.pfnSetDisplayModeCb(pDevice->hDevice, &DdiDm);
         Assert(hr == S_OK);
+#if 0
+        if (hr == S_OK)
+        {
+            D3DDDICB_LOCK DdiLock = {0};
+            DdiLock.hAllocation = pAlloc->hAllocation;
+            DdiLock.Flags.LockEntire = 1;
+            DdiLock.Flags.ReadOnly = 1;
+            hr = pDevice->RtCallbacks.pfnLockCb(pDevice->hDevice, &DdiLock);
+            Assert(hr == S_OK);
+            if (hr == S_OK)
+            {
+                D3DLOCKED_RECT LockRect;
+                IDirect3DSurface9 *pD3DIfSurf = (IDirect3DSurface9*)pAlloc->pD3DIf;
+                hr = pD3DIfSurf->LockRect(&LockRect, NULL /* RECT*/, D3DLOCK_DISCARD);
+                Assert(hr == S_OK);
+                if (hr == S_OK)
+                {
+                    /** @todo: take pitch into account */
+                    Assert(pAlloc->SurfDesc.pitch == LockRect.Pitch);
+                    memcpy(LockRect.pBits, DdiLock.pData, LockRect.Pitch * pAlloc->SurfDesc.height);
+                    hr = pD3DIfSurf->UnlockRect();
+                    Assert(hr == S_OK);
+                }
+
+                D3DDDICB_UNLOCK DdiUnlock = {0};
+                DdiUnlock.NumAllocations = 1;
+                DdiUnlock.phAllocations = &pAlloc->hAllocation;
+                hr = pDevice->RtCallbacks.pfnUnlockCb(pDevice->hDevice, &DdiUnlock);
+                Assert(hr == S_OK);
+            }
+            hr = S_OK;
+#endif
+        }
     }
 
@@ -7652,5 +7685,5 @@
                         }
     #else
-    //# define VBOXDISP_TEST_SWAPCHAIN
+    # define VBOXDISP_TEST_SWAPCHAIN
     # ifdef VBOXDISP_TEST_SWAPCHAIN
                         VBOXDISP_D3DEV(pDevice);
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 33364)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp	(revision 33365)
@@ -1761,5 +1761,5 @@
     DXGKARG_DESCRIBEALLOCATION*  pDescribeAllocation)
 {
-    dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
+//    dfprintf(("==> "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
 
     vboxVDbgBreakFv();
@@ -1774,5 +1774,5 @@
     pDescribeAllocation->PrivateDriverFormatAttribute = 0;
 
-    dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
+//    dfprintf(("<== "__FUNCTION__ ", hAdapter(0x%x)\n", hAdapter));
 
     return STATUS_SUCCESS;
Index: trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 33364)
+++ trunk/src/VBox/GuestHost/OpenGL/util/vboxhgcm.c	(revision 33365)
@@ -46,4 +46,114 @@
 #include <VBox/HostServices/VBoxCrOpenGLSvc.h>
 
+//#if defined(IN_GUEST)
+//#define VBOX_WITH_CRHGSMIPROFILE
+//#endif
+#ifdef VBOX_WITH_CRHGSMIPROFILE
+#include <iprt/time.h>
+#include <stdio.h>
+
+#ifdef VBOX_WITH_CRHGSMI
+#include <VBox/VBoxCrHgsmi.h>
+#endif
+
+typedef struct VBOXCRHGSMIPROFILE
+{
+    uint64_t cStartTime;
+    uint64_t cStepsTime;
+    uint64_t cSteps;
+} VBOXCRHGSMIPROFILE, *PVBOXCRHGSMIPROFILE;
+
+#define VBOXCRHGSMIPROFILE_GET_TIME_NANO() RTTimeNanoTS()
+#define VBOXCRHGSMIPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
+
+/* 10 sec */
+#define VBOXCRHGSMIPROFILE_LOG_STEP_TIME (10000000000.)
+
+DECLINLINE(void) vboxCrHgsmiProfileStart(PVBOXCRHGSMIPROFILE pProfile)
+{
+    pProfile->cStepsTime = 0;
+    pProfile->cSteps = 0;
+    pProfile->cStartTime = VBOXCRHGSMIPROFILE_GET_TIME_NANO();
+}
+
+DECLINLINE(void) vboxCrHgsmiProfileStep(PVBOXCRHGSMIPROFILE pProfile, uint64_t cStepTime)
+{
+    pProfile->cStepsTime += cStepTime;
+    ++pProfile->cSteps;
+}
+
+typedef struct VBOXCRHGSMIPROFILE_SCOPE
+{
+    uint64_t cStartTime;
+//    bool bDisable;
+} VBOXCRHGSMIPROFILE_SCOPE, *PVBOXCRHGSMIPROFILE_SCOPE;
+
+static VBOXCRHGSMIPROFILE g_VBoxProfile;
+
+static void vboxCrHgsmiLog(char * szString, ...)
+{
+    char szBuffer[4096] = {0};
+     va_list pArgList;
+     va_start(pArgList, szString);
+     _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), szString, pArgList);
+     va_end(pArgList);
+
+#ifdef VBOX_WITH_CRHGSMI
+     VBoxCrHgsmiLog(szBuffer);
+#else
+     OutputDebugString(szBuffer);
+#endif
+}
+
+DECLINLINE(void) vboxCrHgsmiProfileLog(PVBOXCRHGSMIPROFILE pProfile, uint64_t cTime)
+{
+    uint64_t profileTime = cTime - pProfile->cStartTime;
+    double percent = ((double)100.0) * pProfile->cStepsTime / profileTime;
+    double cps = ((double)1000000000.) * pProfile->cSteps / profileTime;
+    vboxCrHgsmiLog("hgcm: cps: %.1f, host %.1f%%\n", cps, percent);
+}
+
+DECLINLINE(void) vboxCrHgsmiProfileScopeEnter(PVBOXCRHGSMIPROFILE_SCOPE pScope)
+{
+//    pScope->bDisable = false;
+    pScope->cStartTime = VBOXCRHGSMIPROFILE_GET_TIME_NANO();
+}
+
+DECLINLINE(void) vboxCrHgsmiProfileScopeExit(PVBOXCRHGSMIPROFILE_SCOPE pScope)
+{
+//    if (!pScope->bDisable)
+    {
+        uint64_t cTime = VBOXCRHGSMIPROFILE_GET_TIME_NANO();
+        vboxCrHgsmiProfileStep(&g_VBoxProfile, cTime - pScope->cStartTime);
+        if (VBOXCRHGSMIPROFILE_LOG_STEP_TIME < cTime - g_VBoxProfile.cStartTime)
+        {
+            vboxCrHgsmiProfileLog(&g_VBoxProfile, cTime);
+            vboxCrHgsmiProfileStart(&g_VBoxProfile);
+        }
+    }
+}
+
+
+#define VBOXCRHGSMIPROFILE_INIT() vboxCrHgsmiProfileStart(&g_VBoxProfile)
+#define VBOXCRHGSMIPROFILE_TERM() do {} while (0)
+
+#define VBOXCRHGSMIPROFILE_FUNC_PROLOGUE() \
+        VBOXCRHGSMIPROFILE_SCOPE __vboxCrHgsmiProfileScope; \
+        vboxCrHgsmiProfileScopeEnter(&__vboxCrHgsmiProfileScope);
+
+#define VBOXCRHGSMIPROFILE_FUNC_EPILOGUE() \
+        vboxCrHgsmiProfileScopeExit(&__vboxCrHgsmiProfileScope); \
+
+
+#else
+#ifdef IN_GUEST
+#error "should not happen!"
+#endif
+#define VBOXCRHGSMIPROFILE_INIT() do {} while (0)
+#define VBOXCRHGSMIPROFILE_TERM() do {} while (0)
+#define VBOXCRHGSMIPROFILE_FUNC_PROLOGUE() do {} while (0)
+#define VBOXCRHGSMIPROFILE_FUNC_EPILOGUE() do {} while (0)
+#endif
+
 typedef struct {
     int                  initialized;
@@ -95,5 +205,5 @@
 
 /* Some forward declarations */
-static void crVBoxHGCMReceiveMessage(CRConnection *conn);
+static void _crVBoxHGCMReceiveMessage(CRConnection *conn);
 
 #ifndef IN_GUEST
@@ -233,5 +343,5 @@
 }
 
-static void *crVBoxHGCMAlloc(CRConnection *conn)
+static void *_crVBoxHGCMAlloc(CRConnection *conn)
 {
     CRVBOXHGCMBUFFER *buf;
@@ -358,5 +468,14 @@
 }
 
-static void crVBoxHGCMWriteExact(CRConnection *conn, const void *buf, unsigned int len)
+static void *crVBoxHGCMAlloc(CRConnection *conn)
+{
+    void *pvBuff;
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+    pvBuff = _crVBoxHGCMAlloc(conn);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+    return pvBuff;
+}
+
+static void _crVBoxHGCMWriteExact(CRConnection *conn, const void *buf, unsigned int len)
 {
     int rc;
@@ -407,4 +526,11 @@
 }
 
+static void crVBoxHGCMWriteExact(CRConnection *conn, const void *buf, unsigned int len)
+{
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+    _crVBoxHGCMWriteExact(conn, buf, len);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+}
+
 static void crVBoxHGCMReadExact( CRConnection *conn, const void *buf, unsigned int len )
 {
@@ -441,5 +567,5 @@
 
     if (conn->cbBuffer)
-        crVBoxHGCMReceiveMessage(conn);
+        _crVBoxHGCMReceiveMessage(conn);
 
 }
@@ -517,5 +643,5 @@
 
     if (conn->cbBuffer)
-        crVBoxHGCMReceiveMessage(conn);
+        _crVBoxHGCMReceiveMessage(conn);
 }
 
@@ -524,4 +650,5 @@
 {
     CRVBOXHGCMBUFFER *hgcm_buffer;
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
 
     if (!bufp) /* We're sending a user-allocated buffer. */
@@ -536,4 +663,5 @@
             crVBoxHGCMWriteReadExact(conn, start, len, CR_VBOXHGCM_USERALLOCATED);
 #endif
+            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
         return;
     }
@@ -553,5 +681,5 @@
     if (conn->u32InjectClientID)
     {
-        crVBoxHGCMWriteExact(conn, start, len);
+        _crVBoxHGCMWriteExact(conn, start, len);
     }
     else
@@ -573,4 +701,6 @@
      */
     *bufp = NULL;
+
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 }
 
@@ -611,8 +741,10 @@
 static void crVBoxHGCMSingleRecv(CRConnection *conn, void *buf, unsigned int len)
 {
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     crVBoxHGCMReadExact(conn, buf, len);
-}
-
-static void crVBoxHGCMFree(CRConnection *conn, void *buf)
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+}
+
+static void _crVBoxHGCMFree(CRConnection *conn, void *buf)
 {
     CRVBOXHGCMBUFFER *hgcm_buffer = (CRVBOXHGCMBUFFER *) buf - 1;
@@ -653,5 +785,12 @@
 }
 
-static void crVBoxHGCMReceiveMessage(CRConnection *conn)
+static void crVBoxHGCMFree(CRConnection *conn, void *buf)
+{
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+    _crVBoxHGCMFree(conn, buf);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+}
+
+static void _crVBoxHGCMReceiveMessage(CRConnection *conn)
 {
     uint32_t len;
@@ -670,5 +809,5 @@
         CRASSERT(conn->buffer_size >= sizeof(CRMessageRedirPtr));
 
-        hgcm_buffer = (CRVBOXHGCMBUFFER *) crVBoxHGCMAlloc( conn ) - 1;
+        hgcm_buffer = (CRVBOXHGCMBUFFER *) _crVBoxHGCMAlloc( conn ) - 1;
         hgcm_buffer->len = sizeof(CRMessageRedirPtr);
 
@@ -690,5 +829,5 @@
         {
             /* put in pre-allocated buffer */
-            hgcm_buffer = (CRVBOXHGCMBUFFER *) crVBoxHGCMAlloc( conn ) - 1;
+            hgcm_buffer = (CRVBOXHGCMBUFFER *) _crVBoxHGCMAlloc( conn ) - 1;
         }
         else
@@ -728,7 +867,15 @@
         && cached_type != CR_MESSAGE_GATHER)
     {
-        crVBoxHGCMFree(conn, msg);
-    }
-}
+        _crVBoxHGCMFree(conn, msg);
+    }
+}
+
+static void crVBoxHGCMReceiveMessage(CRConnection *conn)
+{
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+    _crVBoxHGCMReceiveMessage(conn);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
+}
+
 
 /*
@@ -737,8 +884,10 @@
 static void crVBoxHGCMAccept( CRConnection *conn, const char *hostname, unsigned short port )
 {
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     CRASSERT(conn && conn->pHostBuffer);
 #ifdef IN_GUEST
     CRASSERT(FALSE);
 #endif
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 }
 
@@ -786,4 +935,6 @@
 #ifdef RT_OS_WINDOWS
     DWORD cbReturned;
+
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
 
     if (g_crvboxhgcm.hGuestDrv == INVALID_HANDLE_VALUE)
@@ -802,8 +953,10 @@
         {
             crDebug("could not open VBox Guest Additions driver! rc = %d\n", GetLastError());
+            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
             return FALSE;
         }
     }
 #else
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     if (g_crvboxhgcm.iGuestDrv == INVALID_HANDLE_VALUE)
     {
@@ -812,4 +965,5 @@
         {
             crDebug("could not open Guest Additions kernel module! rc = %d\n", errno);
+            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
             return FALSE;
         }
@@ -847,4 +1001,5 @@
             crDebug("HGCM connect was successful: client id =0x%x\n", conn->u32ClientID);
 
+            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
             return crVBoxHGCMSetVersion(conn, CR_PROTOCOL_VERSION_MAJOR, CR_PROTOCOL_VERSION_MINOR);
         }
@@ -852,4 +1007,6 @@
         {
             crDebug("HGCM connect failed with rc=0x%x\n", info.result);
+
+            VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
             return FALSE;
         }
@@ -862,7 +1019,9 @@
         crDebug("IOCTL for HGCM connect failed with rc=0x%x\n", errno);
 #endif
+        VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
         return FALSE;
     }
 
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     return TRUE;
 
@@ -884,4 +1043,6 @@
     int i;
 #endif
+
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
 
     if (conn->pHostBuffer)
@@ -964,15 +1125,21 @@
     }
 #endif /* IN_GUEST */
+
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 }
 
 static void crVBoxHGCMInstantReclaim(CRConnection *conn, CRMessage *mess)
 {
-    crVBoxHGCMFree(conn, mess);
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+    _crVBoxHGCMFree(conn, mess);
     CRASSERT(FALSE);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 }
 
 static void crVBoxHGCMHandleNewMessage( CRConnection *conn, CRMessage *msg, unsigned int len )
 {
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     CRASSERT(FALSE);
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 }
 
@@ -987,4 +1154,6 @@
         return;
     }
+
+    VBOXCRHGSMIPROFILE_INIT();
 
     g_crvboxhgcm.initialized = 1;
@@ -1142,4 +1311,6 @@
     int32_t i;
 
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
+
 #ifdef IN_GUEST
     /* we're on guest side, poll host if it got something for us */
@@ -1167,7 +1338,9 @@
         if (conn->cbBuffer>0)
         {
-            crVBoxHGCMReceiveMessage(conn);
-        }
-    }
+            _crVBoxHGCMReceiveMessage(conn);
+        }
+    }
+
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
 
     return 0;
Index: trunk/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c
===================================================================
--- trunk/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c	(revision 33364)
+++ trunk/src/VBox/GuestHost/OpenGL/util/vboxhgsmi.c	(revision 33365)
@@ -1457,5 +1457,12 @@
 
     if (!bHasHGSMI)
+    {
+#ifdef DEBUG_misha
+        AssertRelease(0);
+#endif
         return false;
+    }
+
+    return false;
 
     g_crvboxhgsmi.recv_list = rfl;
@@ -1588,4 +1595,5 @@
 {
     int32_t i;
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
 
 #ifdef IN_GUEST
@@ -1620,4 +1628,5 @@
     }
 
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     return 0;
 }
@@ -1625,7 +1634,9 @@
 CRConnection** crVBoxHGSMIDump( int *num )
 {
+    VBOXCRHGSMIPROFILE_FUNC_PROLOGUE();
     Assert(0);
     *num = g_crvboxhgsmi.num_conns;
 
+    VBOXCRHGSMIPROFILE_FUNC_EPILOGUE();
     return g_crvboxhgsmi.conns;
 }
Index: trunk/src/VBox/Main/DisplayImpl.cpp
===================================================================
--- trunk/src/VBox/Main/DisplayImpl.cpp	(revision 33364)
+++ trunk/src/VBox/Main/DisplayImpl.cpp	(revision 33365)
@@ -2915,14 +2915,5 @@
 void Display::destructCrHgsmiData(void)
 {
-    if (mhCrOglSvc)
-    {
-        VMMDev *pVMMDev = mParent->getVMMDev();
-        Assert(pVMMDev);
-        if (pVMMDev)
-        {
-            int rc = pVMMDev->hgcmHostSvcHandleDestroy(mhCrOglSvc);
-            AssertRC(rc);
-        }
-    }
+    mhCrOglSvc = NULL;
 }
 #endif
Index: trunk/src/VBox/Main/hgcm/HGCM.cpp
===================================================================
--- trunk/src/VBox/Main/hgcm/HGCM.cpp	(revision 33364)
+++ trunk/src/VBox/Main/hgcm/HGCM.cpp	(revision 33365)
@@ -108,4 +108,8 @@
         uint32_t *m_paClientIds;
 
+#ifdef VBOX_WITH_CRHGSMI
+        uint32_t m_cHandleAcquires;
+#endif
+
         HGCMSVCEXTHANDLE m_hExtension;
 
@@ -153,4 +157,6 @@
 
 #ifdef VBOX_WITH_CRHGSMI
+        int HandleAcquired();
+        int HandleReleased();
         int HostFastCallAsync (uint32_t u32Function, VBOXHGCMSVCPARM *pParm, PHGCMHOSTFASTCALLCB pfnCompletion, void *pvCompletion);
 #endif
@@ -230,4 +236,7 @@
     m_cClientsAllocated (0),
     m_paClientIds (NULL),
+#ifdef VBOX_WITH_CRHGSMI
+    m_cHandleAcquires (0),
+#endif
     m_hExtension (NULL)
 {
@@ -1109,5 +1118,16 @@
         }
 
+#ifdef VBOX_WITH_CRHGSMI
+        /* @todo: could this actually happen that the service is destroyed on ReleaseService? */
+        HGCMService *pNextSvc = pSvc->m_pSvcNext;
+        while (pSvc->m_cHandleAcquires)
+        {
+            pSvc->HandleReleased ();
+            pSvc->ReleaseService ();
+        }
+        pSvc = pNextSvc;
+#else
         pSvc = pSvc->m_pSvcNext;
+#endif
     }
 
@@ -1562,4 +1582,21 @@
         pMsg->pfnCompletion (result, pMsg->u32Function, &pMsg->Param, pMsg->pvCompletion);
     }
+}
+
+int HGCMService::HandleAcquired()
+{
+    ++m_cHandleAcquires;
+    return VINF_SUCCESS;
+}
+
+int HGCMService::HandleReleased()
+{
+    Assert(m_cHandleAcquires);
+    if (m_cHandleAcquires)
+    {
+        --m_cHandleAcquires;
+        return VINF_SUCCESS;
+    }
+    return VERR_INVALID_STATE;
 }
 
@@ -1844,5 +1881,13 @@
                 if (RT_SUCCESS(rc))
                 {
-                    pMsg->pService = pService;
+                    rc = pService->HandleAcquired ();
+                    if (RT_SUCCESS(rc))
+                    {
+                        pMsg->pService = pService;
+                    }
+                    else
+                    {
+                        pService->ReleaseService ();
+                    }
                 }
             } break;
@@ -1856,7 +1901,9 @@
                 /* Resolve the service name to the pointer to service instance. */
 
-                pMsg->pService->ReleaseService ();
-
-                rc = VINF_SUCCESS;
+                rc = pMsg->pService->HandleReleased ();
+                if (RT_SUCCESS(rc))
+                {
+                    pMsg->pService->ReleaseService ();
+                }
             } break;
 #endif
