VirtualBox

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

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

wddm/3d: Aero: fix gdi-backend textures update, avoid extra memcpy for sysmem textures Lock/Unlock

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