VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Display/wddm/VBoxDispD3DIf.cpp@ 30039

Last change on this file since 30039 was 30039, checked in by vboxsync, 15 years ago

wddm/3d: hide created window for now

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.0 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 "VBoxDispD3DIf.h"
16#include "VBoxDispD3DCmn.h"
17
18#include <iprt/assert.h>
19
20void VBoxDispD3DClose(VBOXDISPD3D *pD3D)
21{
22 FreeLibrary(pD3D->hD3DLib);
23 pD3D->hD3DLib = NULL;
24}
25
26
27HRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
28{
29 pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9.dll");
30 Assert(pD3D->hD3DLib);
31 if (pD3D->hD3DLib)
32 {
33 pD3D->pfnDirect3DCreate9Ex = (PFNVBOXDISPD3DCREATE9EX)GetProcAddress(pD3D->hD3DLib, "Direct3DCreate9Ex");
34 Assert(pD3D->pfnDirect3DCreate9Ex);
35 if (pD3D->pfnDirect3DCreate9Ex)
36 return S_OK;
37 else
38 {
39 DWORD winErr = GetLastError();
40 vboxVDbgPrintR((__FUNCTION__": GetProcAddressW (for Direct3DCreate9Ex) failed, winErr = (%d)", winErr));
41 }
42
43 VBoxDispD3DClose(pD3D);
44 }
45 else
46 {
47 DWORD winErr = GetLastError();
48 vboxVDbgPrintR((__FUNCTION__": LoadLibraryW failed, winErr = (%d)", winErr));
49 }
50
51 return E_FAIL;
52}
53
54#define WM_VBOXDISP_CALLPROC (WM_APP+1)
55
56typedef struct VBOXDISP_CALLPROC
57{
58 PFNVBOXDISPWORKERCB pfnCb;
59 void *pvCb;
60} VBOXDISP_CALLPROC;
61
62static DWORD WINAPI vboxDispWorkerThread(void *pvUser)
63{
64 VBOXDISPWORKER *pWorker = (VBOXDISPWORKER*)pvUser;
65 MSG Msg;
66
67 PeekMessage(&Msg,
68 NULL /* HWND hWnd */,
69 WM_USER /* UINT wMsgFilterMin */,
70 WM_USER /* UINT wMsgFilterMax */,
71 PM_NOREMOVE);
72 RTSemEventSignal(pWorker->hEvent);
73
74 do
75 {
76 BOOL bResult = GetMessage(&Msg,
77 0 /*HWND hWnd*/,
78 0 /*UINT wMsgFilterMin*/,
79 0 /*UINT wMsgFilterMax*/
80 );
81
82 if(!bResult) /* WM_QUIT was posted */
83 break;
84
85 Assert(bResult != -1);
86 if(bResult == -1) /* error occured */
87 break;
88
89 switch (Msg.message)
90 {
91 case WM_VBOXDISP_CALLPROC:
92 {
93 VBOXDISP_CALLPROC* pData = (VBOXDISP_CALLPROC*)Msg.lParam;
94 pData->pfnCb(pData->pvCb);
95 RTSemEventSignal(pWorker->hEvent);
96 break;
97 }
98 default:
99 TranslateMessage(&Msg);
100 DispatchMessage(&Msg);
101 }
102 } while (1);
103 return 0;
104}
105
106static int vboxDispWorkerSubmit(VBOXDISPWORKER *pWorker, UINT Msg, LPARAM lParam)
107{
108 /* need to serialize since vboxDispWorkerThread is using one pWorker->hEvent
109 * to signal job completion */
110 int rc = RTCritSectEnter(&pWorker->CritSect);
111 AssertRC(rc);
112 if (RT_SUCCESS(rc))
113 {
114 BOOL bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
115 Assert(bResult);
116 if (bResult)
117 {
118 rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
119 AssertRC(rc);
120 }
121 else
122 rc = VERR_GENERAL_FAILURE;
123
124 int tmpRc = RTCritSectLeave(&pWorker->CritSect);
125 AssertRC(tmpRc);
126 }
127 return rc;
128}
129
130HRESULT VBoxDispWorkerSubmitProc(VBOXDISPWORKER *pWorker, PFNVBOXDISPWORKERCB pfnCb, void *pvCb)
131{
132 VBOXDISP_CALLPROC Ctx;
133 Ctx.pfnCb = pfnCb;
134 Ctx.pvCb = pvCb;
135 int rc = vboxDispWorkerSubmit(pWorker, WM_VBOXDISP_CALLPROC, (LPARAM)&Ctx);
136 AssertRC(rc);
137 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
138}
139
140HRESULT VBoxDispWorkerCreate(VBOXDISPWORKER *pWorker)
141{
142 int rc = RTCritSectInit(&pWorker->CritSect);
143 AssertRC(rc);
144 if (RT_SUCCESS(rc))
145 {
146 rc = RTSemEventCreate(&pWorker->hEvent);
147 AssertRC(rc);
148 if (RT_SUCCESS(rc))
149 {
150 pWorker->hThread = CreateThread(
151 NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
152 0 /* SIZE_T dwStackSize */,
153 vboxDispWorkerThread,
154 pWorker,
155 0 /* DWORD dwCreationFlags */,
156 &pWorker->idThread);
157 Assert(pWorker->hThread);
158 if (pWorker->hThread)
159 {
160 rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
161 AssertRC(rc);
162 if (RT_SUCCESS(rc))
163 return S_OK;
164 /* destroy thread ? */
165 }
166 else
167 {
168 DWORD winErr = GetLastError();
169 vboxVDbgPrintR((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
170 rc = VERR_GENERAL_FAILURE;
171 }
172 int tmpRc = RTSemEventDestroy(pWorker->hEvent);
173 AssertRC(tmpRc);
174 }
175 int tmpRc = RTCritSectDelete(&pWorker->CritSect);
176 AssertRC(tmpRc);
177 }
178 return E_FAIL;
179}
180
181HRESULT VBoxDispWorkerDestroy(VBOXDISPWORKER *pWorker)
182{
183 int rc = VINF_SUCCESS;
184 BOOL bResult = PostThreadMessage(pWorker->idThread, WM_QUIT, 0, 0);
185 Assert(bResult);
186 if (bResult)
187 {
188 DWORD dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
189 Assert(dwErr == WAIT_OBJECT_0);
190 if (dwErr == WAIT_OBJECT_0)
191 {
192 rc = RTSemEventDestroy(pWorker->hEvent);
193 AssertRC(rc);
194 if (RT_SUCCESS(rc))
195 {
196 rc = RTCritSectDelete(&pWorker->CritSect);
197 AssertRC(rc);
198 }
199 }
200 else
201 rc = VERR_GENERAL_FAILURE;
202 }
203 else
204 rc = VERR_GENERAL_FAILURE;
205
206 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
207}
208
209static LRESULT CALLBACK WindowProc(HWND hwnd,
210 UINT uMsg,
211 WPARAM wParam,
212 LPARAM lParam
213)
214{
215 switch(uMsg)
216 {
217 case WM_CLOSE:
218 vboxVDbgPrint((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd));
219 return 0;
220 case WM_DESTROY:
221 vboxVDbgPrint((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd));
222 return 0;
223 case WM_NCHITTEST:
224 vboxVDbgPrint((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd));
225 return HTNOWHERE;
226 }
227
228 return DefWindowProc(hwnd, uMsg, wParam, lParam);
229}
230
231#define VBOXDISPWND_NAME L"VboxDispD3DWindow"
232
233HRESULT vboxDispWndDoCreate(DWORD w, DWORD h, HWND *phWnd)
234{
235 HRESULT hr = S_OK;
236 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
237 /* Register the Window Class. */
238 WNDCLASS wc;
239 if (!GetClassInfo(hInstance, VBOXDISPWND_NAME, &wc))
240 {
241 wc.style = CS_OWNDC;
242 wc.lpfnWndProc = WindowProc;
243 wc.cbClsExtra = 0;
244 wc.cbWndExtra = 0;
245 wc.hInstance = hInstance;
246 wc.hIcon = NULL;
247 wc.hCursor = NULL;
248 wc.hbrBackground = NULL;
249 wc.lpszMenuName = NULL;
250 wc.lpszClassName = VBOXDISPWND_NAME;
251 if (!RegisterClass(&wc))
252 {
253 DWORD winErr = GetLastError();
254 vboxVDbgPrint((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
255 hr = E_FAIL;
256 }
257 }
258
259 if (hr == S_OK)
260 {
261 HWND hWnd = CreateWindowEx (WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY,
262 VBOXDISPWND_NAME, VBOXDISPWND_NAME,
263 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
264#ifdef DEBUG_misha
265 -1024, -1024,
266#else
267 0, 0,
268#endif
269 w, h,
270 GetDesktopWindow() /* hWndParent */,
271 NULL /* hMenu */,
272 hInstance,
273 NULL /* lpParam */);
274 Assert(hWnd);
275 if (hWnd)
276 {
277 *phWnd = hWnd;
278 }
279 else
280 {
281 DWORD winErr = GetLastError();
282 vboxVDbgPrint((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
283 hr = E_FAIL;
284 }
285 }
286
287 return hr;
288}
289
290static HRESULT vboxDispWndDoDestroy(HWND hWnd)
291{
292 BOOL bResult = DestroyWindow(hWnd);
293 Assert(bResult);
294 if (bResult)
295 return S_OK;
296
297 DWORD winErr = GetLastError();
298 vboxVDbgPrint((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));
299
300 return E_FAIL;
301}
302
303typedef struct VBOXDISPWND_CREATE_INFO
304{
305 int hr;
306 HWND hWnd;
307 DWORD width;
308 DWORD height;
309} VBOXDISPWND_CREATE_INFO;
310
311typedef struct VBOXDISPWND_DESTROY_INFO
312{
313 int hr;
314 HWND hWnd;
315} VBOXDISPWND_DESTROY_INFO;
316
317DECLCALLBACK(void) vboxDispWndDestroyWorker(void *pvUser)
318{
319 VBOXDISPWND_DESTROY_INFO *pInfo = (VBOXDISPWND_DESTROY_INFO*)pvUser;
320 pInfo->hr = vboxDispWndDoDestroy(pInfo->hWnd);
321 Assert(pInfo->hr == S_OK);
322}
323
324DECLCALLBACK(void) vboxDispWndCreateWorker(void *pvUser)
325{
326 VBOXDISPWND_CREATE_INFO *pInfo = (VBOXDISPWND_CREATE_INFO*)pvUser;
327 pInfo->hr = vboxDispWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd);
328 Assert(pInfo->hr == S_OK);
329}
330
331
332HRESULT VBoxDispWndDestroy(PVBOXWDDMDISP_ADAPTER pAdapter, HWND hWnd)
333{
334 VBOXDISPWND_DESTROY_INFO Info;
335 Info.hr = E_FAIL;
336 Info.hWnd = hWnd;
337 HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndDestroyWorker, &Info);
338 Assert(hr == S_OK);
339 if (hr == S_OK)
340 {
341 Assert(Info.hr == S_OK);
342 return Info.hr;
343 }
344 return hr;
345}
346
347HRESULT VBoxDispWndCreate(PVBOXWDDMDISP_ADAPTER pAdapter, DWORD width, DWORD height, HWND *phWnd)
348{
349 VBOXDISPWND_CREATE_INFO Info;
350 Info.hr = E_FAIL;
351 Info.width = width;
352 Info.height = height;
353 HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndCreateWorker, &Info);
354 Assert(hr == S_OK);
355 if (hr == S_OK)
356 {
357 Assert(Info.hr == S_OK);
358 if (Info.hr == S_OK)
359 *phWnd = Info.hWnd;
360 return Info.hr;
361 }
362 return hr;
363}
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