VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispCm.cpp@ 30541

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

wddm/3d: enable querying visible regions only when needed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 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 "VBoxDispD3D.h"
17#include "../../../include/VBoxDisplay.h"
18
19#include <iprt/list.h>
20
21
22typedef struct VBOXDISPCM_SESSION
23{
24 HANDLE hEvent;
25 CRITICAL_SECTION CritSect;
26 RTLISTNODE CtxList;
27 bool bQueryMp;
28} VBOXDISPCM_SESSION, *PVBOXDISPCM_SESSION;
29
30typedef struct VBOXDISPCM_MGR
31{
32 VBOXDISPCM_SESSION Session;
33} VBOXDISPCM_MGR, *PVBOXDISPCM_MGR;
34
35/* the cm is one per process */
36static VBOXDISPCM_MGR g_pVBoxCmMgr;
37
38HRESULT vboxDispCmSessionTerm(PVBOXDISPCM_SESSION pSession)
39{
40 Assert(RTListIsEmpty(&pSession->CtxList));
41 BOOL bRc = CloseHandle(pSession->hEvent);
42 Assert(bRc);
43 if (bRc)
44 {
45 DeleteCriticalSection(&pSession->CritSect);
46 return S_OK;
47 }
48 DWORD winEr = GetLastError();
49 HRESULT hr = HRESULT_FROM_WIN32(winEr);
50 return hr;
51}
52
53HRESULT vboxDispCmSessionInit(PVBOXDISPCM_SESSION pSession)
54{
55 HANDLE hEvent = CreateEvent(NULL,
56 FALSE, /* BOOL bManualReset */
57 FALSE, /* BOOL bInitialState */
58 NULL /* LPCTSTR lpName */
59 );
60 Assert(hEvent);
61 if (hEvent)
62 {
63 pSession->hEvent = hEvent;
64 InitializeCriticalSection(&pSession->CritSect);
65 RTListInit(&pSession->CtxList);
66 pSession->bQueryMp = false;
67 return S_OK;
68 }
69 DWORD winEr = GetLastError();
70 HRESULT hr = HRESULT_FROM_WIN32(winEr);
71 return hr;
72}
73
74void vboxDispCmSessionCtxAdd(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
75{
76 EnterCriticalSection(&pSession->CritSect);
77 RTListAppend(&pSession->CtxList, &pContext->ListNode);
78 LeaveCriticalSection(&pSession->CritSect);
79}
80
81void vboxDispCmSessionCtxRemoveLocked(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
82{
83 RTListNodeRemove(&pContext->ListNode);
84}
85
86void vboxDispCmSessionCtxRemove(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_CONTEXT pContext)
87{
88 EnterCriticalSection(&pSession->CritSect);
89 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
90 LeaveCriticalSection(&pSession->CritSect);
91}
92
93HRESULT vboxDispCmInit()
94{
95 HRESULT hr = vboxDispCmSessionInit(&g_pVBoxCmMgr.Session);
96 Assert(hr == S_OK);
97 return hr;
98}
99
100HRESULT vboxDispCmTerm()
101{
102 HRESULT hr = vboxDispCmSessionTerm(&g_pVBoxCmMgr.Session);
103 Assert(hr == S_OK);
104 return hr;
105}
106
107HRESULT vboxDispCmCtxCreate(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
108{
109 VBOXWDDM_CREATECONTEXT_INFO Info;
110 Info.u32IfVersion = pDevice->u32IfVersion;
111 Info.u32IsD3D = VBOXDISPMODE_IS_3D(pDevice->pAdapter);
112 Info.hUmEvent = (uint64_t)g_pVBoxCmMgr.Session.hEvent;
113 Info.u64UmInfo = (uint64_t)pContext;
114
115 pContext->ContextInfo.NodeOrdinal = 0;
116 pContext->ContextInfo.EngineAffinity = 0;
117 pContext->ContextInfo.Flags.Value = 0;
118 pContext->ContextInfo.pPrivateDriverData = &Info;
119 pContext->ContextInfo.PrivateDriverDataSize = sizeof (Info);
120 pContext->ContextInfo.hContext = 0;
121 pContext->ContextInfo.pCommandBuffer = NULL;
122 pContext->ContextInfo.CommandBufferSize = 0;
123 pContext->ContextInfo.pAllocationList = NULL;
124 pContext->ContextInfo.AllocationListSize = 0;
125 pContext->ContextInfo.pPatchLocationList = NULL;
126 pContext->ContextInfo.PatchLocationListSize = 0;
127
128 HRESULT hr = S_OK;
129 hr = pDevice->RtCallbacks.pfnCreateContextCb(pDevice->hDevice, &pContext->ContextInfo);
130 Assert(hr == S_OK);
131 if (hr == S_OK)
132 {
133 Assert(pContext->ContextInfo.hContext);
134 pContext->ContextInfo.pPrivateDriverData = NULL;
135 pContext->ContextInfo.PrivateDriverDataSize = 0;
136 vboxDispCmSessionCtxAdd(&g_pVBoxCmMgr.Session, pContext);
137 pContext->pDevice = pDevice;
138 }
139 return hr;
140}
141
142HRESULT vboxDispCmSessionCtxDestroy(PVBOXDISPCM_SESSION pSession, PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
143{
144 EnterCriticalSection(&pSession->CritSect);
145 Assert(pContext->ContextInfo.hContext);
146 D3DDDICB_DESTROYCONTEXT DestroyContext;
147 Assert(pDevice->DefaultContext.ContextInfo.hContext);
148 DestroyContext.hContext = pDevice->DefaultContext.ContextInfo.hContext;
149 HRESULT hr = pDevice->RtCallbacks.pfnDestroyContextCb(pDevice->hDevice, &DestroyContext);
150 Assert(hr == S_OK);
151 if (hr == S_OK)
152 {
153 vboxDispCmSessionCtxRemoveLocked(pSession, pContext);
154 }
155 LeaveCriticalSection(&pSession->CritSect);
156 return hr;
157}
158
159HRESULT vboxDispCmCtxDestroy(PVBOXWDDMDISP_DEVICE pDevice, PVBOXWDDMDISP_CONTEXT pContext)
160{
161 return vboxDispCmSessionCtxDestroy(&g_pVBoxCmMgr.Session, pDevice, pContext);
162}
163
164static HRESULT vboxDispCmSessionCmdQueryData(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd)
165{
166
167 HRESULT hr = S_OK;
168 D3DDDICB_ESCAPE DdiEscape;
169 DdiEscape.Flags.Value = 0;
170 DdiEscape.pPrivateDriverData = pCmd;
171 DdiEscape.PrivateDriverDataSize = cbCmd;
172
173 pCmd->EscapeHdr.escapeCode = VBOXESC_GETVBOXVIDEOCMCMD;
174 /* lock to ensure the context is not distructed */
175 EnterCriticalSection(&pSession->CritSect);
176 /* use any context for identifying the kernel CmSession. We're using the first one */
177 PVBOXWDDMDISP_CONTEXT pContext = RTListNodeGetFirst(&pSession->CtxList, VBOXWDDMDISP_CONTEXT, ListNode);
178 if (pContext)
179 {
180 PVBOXWDDMDISP_DEVICE pDevice = pContext->pDevice;
181 DdiEscape.hDevice = pDevice->hDevice;
182 DdiEscape.hContext = pContext->ContextInfo.hContext;
183 Assert (DdiEscape.hContext);
184 Assert (DdiEscape.hDevice);
185 hr = pDevice->RtCallbacks.pfnEscapeCb(pDevice->pAdapter->hAdapter, &DdiEscape);
186 LeaveCriticalSection(&pSession->CritSect);
187 Assert(hr == S_OK);
188 if (hr == S_OK)
189 {
190 if (!pCmd->Hdr.cbCmdsReturned && !pCmd->Hdr.cbRemainingFirstCmd)
191 hr = S_FALSE;
192 }
193 }
194 else
195 {
196 LeaveCriticalSection(&pSession->CritSect);
197 hr = S_FALSE;
198 }
199
200 return hr;
201}
202
203HRESULT vboxDispCmSessionCmdGet(PVBOXDISPCM_SESSION pSession, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
204{
205 Assert(cbCmd >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
206 if (cbCmd < sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD))
207 return E_INVALIDARG;
208
209 do
210 {
211
212 if (pSession->bQueryMp)
213 {
214 HRESULT hr = vboxDispCmSessionCmdQueryData(pSession, pCmd, cbCmd);
215 Assert(hr == S_OK || hr == S_FALSE);
216 if (hr == S_OK || hr != S_FALSE)
217 return hr;
218
219 pSession->bQueryMp = false;
220 }
221
222 DWORD dwResult = WaitForSingleObject(pSession->hEvent, dwMilliseconds);
223 switch(dwResult)
224 {
225 case WAIT_OBJECT_0:
226 {
227 pSession->bQueryMp = true;
228 break; /* <- query commands */
229 }
230 case WAIT_TIMEOUT:
231 {
232 Assert(!pSession->bQueryMp);
233 return WAIT_TIMEOUT;
234 }
235 default:
236 AssertBreakpoint();
237 return E_FAIL;
238 }
239 } while (1);
240
241 /* should never be here */
242 AssertBreakpoint();
243 return E_FAIL;
244}
245
246HRESULT vboxDispCmCmdGet(PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd, DWORD dwMilliseconds)
247{
248 return vboxDispCmSessionCmdGet(&g_pVBoxCmMgr.Session, pCmd, cbCmd, dwMilliseconds);
249}
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