VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispMp.cpp@ 34346

Last change on this file since 34346 was 34345, checked in by vboxsync, 14 years ago

wddm/3d: propper hide host window on swapchain destruction

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/** @file
2 *
3 * VBoxVideo Display D3D User mode dll
4 *
5 * Copyright (C) 2010 Oracle Corporation
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 */
15#include "VBoxDispD3DCmn.h"
16#include "VBoxDispMp.h"
17
18#include <iprt/assert.h>
19
20typedef struct VBOXVIDEOCM_ITERATOR
21{
22 PVBOXVIDEOCM_CMD_HDR pCur;
23 uint32_t cbRemain;
24} VBOXVIDEOCM_ITERATOR, *PVBOXVIDEOCM_ITERATOR;
25
26typedef struct VBOXDISPMP
27{
28 PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd;
29 uint32_t cbEscapeCmd;
30 VBOXVIDEOCM_ITERATOR Iterator;
31} VBOXDISPMP, *PVBOXDISPMP;
32
33DECLINLINE(void) vboxVideoCmIterInit(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pStart, uint32_t cbCmds)
34{
35 pIter->pCur = pStart;
36 pIter->cbRemain= cbCmds;
37}
38
39DECLINLINE(PVBOXVIDEOCM_CMD_HDR) vboxVideoCmIterNext(PVBOXVIDEOCM_ITERATOR pIter)
40{
41 if (pIter->cbRemain)
42 {
43 PVBOXVIDEOCM_CMD_HDR pCur = pIter->pCur;
44 Assert(pIter->cbRemain >= pIter->pCur->cbCmd);
45 pIter->cbRemain -= pIter->pCur->cbCmd;
46 pIter->pCur = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pIter->pCur) + pIter->pCur->cbCmd);
47 return pCur;
48 }
49 return NULL;
50}
51
52DECLINLINE(bool) vboxVideoCmIterHasNext(PVBOXVIDEOCM_ITERATOR pIter)
53{
54 return !!(pIter->cbRemain);
55}
56
57static VBOXDISPMP g_VBoxDispMp;
58
59DECLCALLBACK(HRESULT) vboxDispMpEnableEvents()
60{
61 g_VBoxDispMp.pEscapeCmd = NULL;
62 g_VBoxDispMp.cbEscapeCmd = 0;
63 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, NULL, 0);
64#ifdef VBOX_WITH_CRHGSMI
65 vboxUhgsmiGlobalSetCurrent();
66#endif
67 return S_OK;
68}
69
70
71DECLCALLBACK(HRESULT) vboxDispMpDisableEvents()
72{
73 if (g_VBoxDispMp.pEscapeCmd)
74 RTMemFree(g_VBoxDispMp.pEscapeCmd);
75#ifdef VBOX_WITH_CRHGSMI
76 vboxUhgsmiGlobalClearCurrent();
77#endif
78 return S_OK;
79}
80
81#define VBOXDISPMP_BUF_INITSIZE 4000
82#define VBOXDISPMP_BUF_INCREASE 4096
83#define VBOXDISPMP_BUF_MAXSIZE ((4096*4096)-96)
84
85DECLCALLBACK(HRESULT) vboxDispMpGetRegions(PVBOXDISPMP_REGIONS pRegions, DWORD dwMilliseconds)
86{
87 HRESULT hr = S_OK;
88 PVBOXVIDEOCM_CMD_HDR pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
89 if (!pHdr)
90 {
91 if (!g_VBoxDispMp.pEscapeCmd)
92 {
93 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(VBOXDISPMP_BUF_INITSIZE);
94 Assert(g_VBoxDispMp.pEscapeCmd);
95 if (g_VBoxDispMp.pEscapeCmd)
96 g_VBoxDispMp.cbEscapeCmd = VBOXDISPMP_BUF_INITSIZE;
97 else
98 return E_OUTOFMEMORY;
99 }
100
101 do
102 {
103 hr = vboxDispCmCmdGet(g_VBoxDispMp.pEscapeCmd, g_VBoxDispMp.cbEscapeCmd, dwMilliseconds);
104 Assert(hr == S_OK || (dwMilliseconds != INFINITE && hr == WAIT_TIMEOUT));
105 if (hr == S_OK)
106 {
107 if (g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned)
108 {
109 pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)g_VBoxDispMp.pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
110 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned);
111 pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
112 Assert(pHdr);
113 break;
114 }
115 else
116 {
117 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds);
118 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
119 RTMemFree(g_VBoxDispMp.pEscapeCmd);
120 uint32_t newSize = RT_MAX(g_VBoxDispMp.cbEscapeCmd + VBOXDISPMP_BUF_INCREASE, g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
121 if (newSize < VBOXDISPMP_BUF_MAXSIZE)
122 newSize = RT_MAX(newSize, RT_MIN(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds, VBOXDISPMP_BUF_MAXSIZE));
123 Assert(g_VBoxDispMp.cbEscapeCmd < newSize);
124 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(newSize);
125 Assert(g_VBoxDispMp.pEscapeCmd);
126 if (g_VBoxDispMp.pEscapeCmd)
127 g_VBoxDispMp.cbEscapeCmd = newSize;
128 else
129 {
130 g_VBoxDispMp.pEscapeCmd = NULL;
131 g_VBoxDispMp.cbEscapeCmd = 0;
132 hr = E_OUTOFMEMORY;
133 break;
134 }
135 }
136 }
137 else
138 break;
139 } while (1);
140 }
141
142 if (hr == S_OK)
143 {
144 Assert(pHdr);
145 VBOXWDDMDISP_CONTEXT *pContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
146 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
147 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
148 /* todo: synchronization */
149 Assert(pSwapchain);
150 pRegions->hWnd = pSwapchain->hWnd;
151 pRegions->pRegions = &pCmdInternal->Cmd;
152 }
153 return hr;
154}
155
156static DECLCALLBACK(void) vboxDispMpLog(LPCSTR pszMsg)
157{
158 vboxDispCmLog(pszMsg);
159}
160
161VBOXDISPMP_DECL(HRESULT) VBoxDispMpGetCallbacks(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks)
162{
163 Assert(u32Version == VBOXDISPMP_VERSION);
164 if (u32Version != VBOXDISPMP_VERSION)
165 return E_INVALIDARG;
166
167 pCallbacks->pfnEnableEvents = vboxDispMpEnableEvents;
168 pCallbacks->pfnDisableEvents = vboxDispMpDisableEvents;
169 pCallbacks->pfnGetRegions = vboxDispMpGetRegions;
170 pCallbacks->pfnLog = vboxDispMpLog;
171 return S_OK;
172}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette