VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispMp.cpp@ 49591

Last change on this file since 49591 was 46757, checked in by vboxsync, 12 years ago

wddm/crOpenGL: r0-based visible regions handling, r0-based chromium commands submission debugged, more on new presentation mechanism, cleanup, etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 KB
Line 
1/* $Id: VBoxDispMp.cpp 46757 2013-06-24 14:30:18Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011-2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxDispD3DCmn.h"
20#include "VBoxDispMp.h"
21#if 0
22#include <iprt/assert.h>
23
24typedef struct VBOXVIDEOCM_ITERATOR
25{
26 PVBOXVIDEOCM_CMD_HDR pCur;
27 uint32_t cbRemain;
28} VBOXVIDEOCM_ITERATOR, *PVBOXVIDEOCM_ITERATOR;
29
30typedef struct VBOXDISPMP
31{
32 CRITICAL_SECTION CritSect;
33 PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd;
34 uint32_t cbEscapeCmd;
35 VBOXVIDEOCM_ITERATOR Iterator;
36} VBOXDISPMP, *PVBOXDISPMP;
37
38DECLINLINE(void) vboxVideoCmIterInit(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pStart, uint32_t cbCmds)
39{
40 pIter->pCur = pStart;
41 pIter->cbRemain= cbCmds;
42}
43
44DECLINLINE(PVBOXVIDEOCM_CMD_HDR) vboxVideoCmIterNext(PVBOXVIDEOCM_ITERATOR pIter)
45{
46 if (pIter->cbRemain)
47 {
48 PVBOXVIDEOCM_CMD_HDR pCur = pIter->pCur;
49 Assert(pIter->cbRemain >= pIter->pCur->cbCmd);
50 pIter->cbRemain -= pIter->pCur->cbCmd;
51 pIter->pCur = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pIter->pCur) + pIter->pCur->cbCmd);
52 return pCur;
53 }
54 return NULL;
55}
56
57DECLINLINE(VOID) vboxVideoCmIterCopyToBack(PVBOXVIDEOCM_ITERATOR pIter, PVBOXVIDEOCM_CMD_HDR pCur)
58{
59 memcpy((((uint8_t*)pIter->pCur) + pIter->cbRemain), pCur, pCur->cbCmd);
60 pIter->cbRemain += pCur->cbCmd;
61}
62
63DECLINLINE(bool) vboxVideoCmIterHasNext(PVBOXVIDEOCM_ITERATOR pIter)
64{
65 return !!(pIter->cbRemain);
66}
67
68static VBOXDISPMP g_VBoxDispMp;
69
70DECLCALLBACK(HRESULT) vboxDispMpEnableEvents()
71{
72 EnterCriticalSection(&g_VBoxDispMp.CritSect);
73 g_VBoxDispMp.pEscapeCmd = NULL;
74 g_VBoxDispMp.cbEscapeCmd = 0;
75 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, NULL, 0);
76 LeaveCriticalSection(&g_VBoxDispMp.CritSect);
77 return S_OK;
78}
79
80
81DECLCALLBACK(HRESULT) vboxDispMpDisableEvents()
82{
83 EnterCriticalSection(&g_VBoxDispMp.CritSect);
84 if (g_VBoxDispMp.pEscapeCmd)
85 {
86 RTMemFree(g_VBoxDispMp.pEscapeCmd);
87 g_VBoxDispMp.pEscapeCmd = NULL;
88 }
89 LeaveCriticalSection(&g_VBoxDispMp.CritSect);
90 return S_OK;
91}
92
93#define VBOXDISPMP_BUF_INITSIZE 4000
94#define VBOXDISPMP_BUF_INCREASE 4096
95#define VBOXDISPMP_BUF_MAXSIZE ((4096*4096)-96)
96
97DECLCALLBACK(HRESULT) vboxDispMpGetRegions(PVBOXDISPMP_REGIONS pRegions, DWORD dwMilliseconds)
98{
99 HRESULT hr = S_OK;
100 EnterCriticalSection(&g_VBoxDispMp.CritSect);
101 PVBOXVIDEOCM_CMD_HDR pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
102 if (!pHdr)
103 {
104 if (!g_VBoxDispMp.pEscapeCmd)
105 {
106 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(VBOXDISPMP_BUF_INITSIZE);
107 Assert(g_VBoxDispMp.pEscapeCmd);
108 if (g_VBoxDispMp.pEscapeCmd)
109 g_VBoxDispMp.cbEscapeCmd = VBOXDISPMP_BUF_INITSIZE;
110 else
111 {
112 LeaveCriticalSection(&g_VBoxDispMp.CritSect);
113 return E_OUTOFMEMORY;
114 }
115 }
116
117 do
118 {
119 hr = vboxDispCmCmdGet(g_VBoxDispMp.pEscapeCmd, g_VBoxDispMp.cbEscapeCmd, dwMilliseconds);
120 Assert(hr == S_OK || (dwMilliseconds != INFINITE && hr == WAIT_TIMEOUT));
121 if (hr == S_OK)
122 {
123 if (g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned)
124 {
125 pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)g_VBoxDispMp.pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
126 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, g_VBoxDispMp.pEscapeCmd->Hdr.cbCmdsReturned);
127 pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator);
128 Assert(pHdr);
129 break;
130 }
131 else
132 {
133 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds);
134 Assert(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
135 RTMemFree(g_VBoxDispMp.pEscapeCmd);
136 uint32_t newSize = RT_MAX(g_VBoxDispMp.cbEscapeCmd + VBOXDISPMP_BUF_INCREASE, g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingFirstCmd);
137 if (newSize < VBOXDISPMP_BUF_MAXSIZE)
138 newSize = RT_MAX(newSize, RT_MIN(g_VBoxDispMp.pEscapeCmd->Hdr.cbRemainingCmds, VBOXDISPMP_BUF_MAXSIZE));
139 Assert(g_VBoxDispMp.cbEscapeCmd < newSize);
140 g_VBoxDispMp.pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(newSize);
141 Assert(g_VBoxDispMp.pEscapeCmd);
142 if (g_VBoxDispMp.pEscapeCmd)
143 g_VBoxDispMp.cbEscapeCmd = newSize;
144 else
145 {
146 g_VBoxDispMp.pEscapeCmd = NULL;
147 g_VBoxDispMp.cbEscapeCmd = 0;
148 hr = E_OUTOFMEMORY;
149 break;
150 }
151 }
152 }
153 else
154 break;
155 } while (1);
156 }
157
158 if (hr == S_OK)
159 {
160 Assert(pHdr);
161 VBOXWDDMDISP_CONTEXT *pContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
162 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
163 PVBOXWDDMDISP_SWAPCHAIN pSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
164 /* the miniport driver should ensure all swapchain-involved commands are completed before swapchain termination,
165 * so we should have it always valid here */
166 Assert(pSwapchain);
167 Assert(pSwapchain->hWnd);
168 pRegions->hWnd = pSwapchain->hWnd;
169 pRegions->pRegions = &pCmdInternal->Cmd;
170 }
171 LeaveCriticalSection(&g_VBoxDispMp.CritSect);
172 return hr;
173}
174
175static DECLCALLBACK(void) vboxDispMpLog(LPCSTR pszMsg)
176{
177 vboxDispCmLog(pszMsg);
178}
179
180VBOXDISPMP_DECL(HRESULT) VBoxDispMpGetCallbacks(uint32_t u32Version, PVBOXDISPMP_CALLBACKS pCallbacks)
181{
182 Assert(u32Version == VBOXDISPMP_VERSION);
183 if (u32Version != VBOXDISPMP_VERSION)
184 return E_INVALIDARG;
185
186 pCallbacks->pfnEnableEvents = vboxDispMpEnableEvents;
187 pCallbacks->pfnDisableEvents = vboxDispMpDisableEvents;
188 pCallbacks->pfnGetRegions = vboxDispMpGetRegions;
189 return S_OK;
190}
191
192HRESULT vboxDispMpInternalInit()
193{
194 memset(&g_VBoxDispMp, 0, sizeof (g_VBoxDispMp));
195 InitializeCriticalSection(&g_VBoxDispMp.CritSect);
196 return S_OK;
197}
198
199HRESULT vboxDispMpInternalTerm()
200{
201 vboxDispMpDisableEvents();
202 DeleteCriticalSection(&g_VBoxDispMp.CritSect);
203 return S_OK;
204}
205
206HRESULT vboxDispMpInternalCancel(VBOXWDDMDISP_CONTEXT *pContext, PVBOXWDDMDISP_SWAPCHAIN pSwapchain)
207{
208 HRESULT hr = S_OK;
209 EnterCriticalSection(&g_VBoxDispMp.CritSect);
210 do
211 {
212 /* the pEscapeCmd is used as an indicator to whether the events capturing is active */
213 if (!g_VBoxDispMp.pEscapeCmd)
214 break;
215
216 /* copy the iterator data to restore it back later */
217 VBOXVIDEOCM_ITERATOR IterCopy = g_VBoxDispMp.Iterator;
218
219 /* first check if we have matching elements */
220 PVBOXVIDEOCM_CMD_HDR pHdr;
221 bool fHasMatch = false;
222 while (pHdr = vboxVideoCmIterNext(&g_VBoxDispMp.Iterator))
223 {
224 VBOXWDDMDISP_CONTEXT *pCurContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
225 if (pCurContext != pContext)
226 continue;
227
228 if (!pSwapchain)
229 {
230 fHasMatch = true;
231 break;
232 }
233
234 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
235 PVBOXWDDMDISP_SWAPCHAIN pCurSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
236 if (pCurSwapchain != pSwapchain)
237 continue;
238
239 fHasMatch = true;
240 break;
241 }
242
243 /* restore the iterator */
244 g_VBoxDispMp.Iterator = IterCopy;
245
246 if (!fHasMatch)
247 break;
248
249 /* there are elements to remove */
250 PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pEscapeCmd = (PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD)RTMemAlloc(g_VBoxDispMp.cbEscapeCmd);
251 if (!pEscapeCmd)
252 {
253 WARN(("no memory"));
254 hr = E_OUTOFMEMORY;
255 break;
256 }
257 /* copy the header data */
258 *pEscapeCmd = *g_VBoxDispMp.pEscapeCmd;
259 /* now copy the command data filtering out the canceled commands */
260 pHdr = (PVBOXVIDEOCM_CMD_HDR)(((uint8_t*)pEscapeCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
261 vboxVideoCmIterInit(&g_VBoxDispMp.Iterator, pHdr, 0);
262 while (pHdr = vboxVideoCmIterNext(&IterCopy))
263 {
264 VBOXWDDMDISP_CONTEXT *pCurContext = (VBOXWDDMDISP_CONTEXT*)pHdr->u64UmData;
265 if (pCurContext != pContext)
266 {
267 vboxVideoCmIterCopyToBack(&g_VBoxDispMp.Iterator, pHdr);
268 continue;
269 }
270
271 if (!pSwapchain)
272 {
273 /* match, just continue */
274 continue;
275 }
276
277 PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)(((uint8_t*)pHdr) + sizeof (VBOXVIDEOCM_CMD_HDR));
278 PVBOXWDDMDISP_SWAPCHAIN pCurSwapchain = (PVBOXWDDMDISP_SWAPCHAIN)pCmdInternal->hSwapchainUm;
279 if (pCurSwapchain != pSwapchain)
280 {
281 vboxVideoCmIterCopyToBack(&g_VBoxDispMp.Iterator, pHdr);
282 continue;
283 }
284 /* match, just continue */
285 }
286
287 Assert(g_VBoxDispMp.pEscapeCmd);
288 RTMemFree(g_VBoxDispMp.pEscapeCmd);
289 Assert(pEscapeCmd);
290 g_VBoxDispMp.pEscapeCmd = pEscapeCmd;
291 } while (0);
292
293 LeaveCriticalSection(&g_VBoxDispMp.CritSect);
294 return hr;
295}
296#endif /* 0 */
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