VirtualBox

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

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

wddm/3d: wine: flush implementation basics

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

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