VirtualBox

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

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

*: spelling fixes, thanks Timeless!

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