VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/glwindrv.cpp@ 4849

Last change on this file since 4849 was 4753, checked in by vboxsync, 17 years ago

eol

  • Property svn:eol-style set to native
File size: 14.0 KB
Line 
1/** @file
2 * VBox OpenGL
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17
18#include <iprt/alloc.h>
19#include <iprt/string.h>
20#include <iprt/assert.h>
21#include <iprt/thread.h>
22#include <VBox/err.h>
23#include "vboxgl.h"
24
25#define LOG_GROUP LOG_GROUP_SHARED_OPENGL
26#include <VBox/log.h>
27#include "gldrv.h"
28
29#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
30LRESULT CALLBACK VBoxOGLWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
31{
32 switch (message)
33 {
34 case WM_CREATE:
35 return 0;
36
37 case WM_CLOSE:
38 PostQuitMessage( 0 );
39 return 0;
40
41 case WM_DESTROY:
42 return 0;
43
44 default:
45 return DefWindowProc( hWnd, message, wParam, lParam );
46 }
47}
48
49DECLCALLBACK(int) vboxWndThread(RTTHREAD ThreadSelf, void *pvUser)
50{
51 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvUser;
52 HWND hwnd;
53
54 hwnd = pClient->hwnd= CreateWindow("VBoxOGL", "VirtualBox OpenGL",
55 WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
56 0, 0, 0, 0,
57 NULL, NULL, 0, NULL);
58 Assert(hwnd);
59 while(true)
60 {
61 MSG msg;
62
63 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
64 {
65 if (msg.message == WM_QUIT)
66 break;
67
68 TranslateMessage(&msg);
69 DispatchMessage(&msg);
70 }
71 }
72 DestroyWindow(hwnd);
73 return VINF_SUCCESS;
74}
75
76#endif
77
78/**
79 * Global init of VBox OpenGL for windows
80 *
81 * @returns VBox error code
82 */
83int vboxglGlobalInit()
84{
85#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
86 WNDCLASS wc;
87
88 wc.style = CS_OWNDC;
89 wc.lpfnWndProc = VBoxOGLWndProc;
90 wc.cbClsExtra = 0;
91 wc.cbWndExtra = 0;
92 wc.hInstance = 0;
93 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
94 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
95 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
96 wc.lpszMenuName = NULL;
97 wc.lpszClassName = "VBoxOGL";
98 RegisterClass(&wc);
99#endif
100
101 PIXELFORMATDESCRIPTOR pfd;
102 int iFormat;
103 /** @todo should NOT use the desktop window -> crashes the Intel OpenGL driver */
104 HDC hdc = GetDC(0);
105
106 ZeroMemory(&pfd, sizeof(pfd));
107 pfd.nSize = sizeof(pfd);
108 pfd.nVersion = 1;
109 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
110 pfd.iPixelType = PFD_TYPE_RGBA;
111 pfd.cColorBits = 24;
112 pfd.cDepthBits = 16;
113 pfd.iLayerType = PFD_MAIN_PLANE;
114 iFormat = ChoosePixelFormat(hdc, &pfd);
115 SetPixelFormat(hdc, iFormat, &pfd);
116
117 HGLRC hRC = wglCreateContext(hdc);
118 wglMakeCurrent(hdc, hRC);
119
120 vboxInitOpenGLExtensions();
121
122 wglMakeCurrent(NULL, NULL);
123 wglDeleteContext(hRC);
124 ReleaseDC(0, hdc);
125
126 return VINF_SUCCESS;
127}
128
129/**
130 * Global deinit of VBox OpenGL
131 *
132 * @returns VBox error code
133 */
134int vboxglGlobalUnload()
135{
136 Log(("vboxglGlobalUnload"));
137
138 return VINF_SUCCESS;
139}
140
141/**
142 * Enable OpenGL
143 *
144 * @returns VBox error code
145 * @param pClient Client context
146 */
147int vboxglEnableOpenGL(PVBOXOGLCTX pClient)
148{
149 PIXELFORMATDESCRIPTOR pfd;
150 int iFormat;
151
152 /** @todo should NOT use the desktop window -> crashes the Intel OpenGL driver */
153 pClient->enable.hdc = GetDC(0);
154
155 ZeroMemory(&pfd, sizeof(pfd));
156 pfd.nSize = sizeof(pfd);
157 pfd.nVersion = 1;
158 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
159 pfd.iPixelType = PFD_TYPE_RGBA;
160 pfd.cColorBits = 24;
161 pfd.cDepthBits = 16;
162 pfd.iLayerType = PFD_MAIN_PLANE;
163 iFormat = ChoosePixelFormat(pClient->enable.hdc, &pfd);
164 SetPixelFormat(pClient->enable.hdc, iFormat, &pfd);
165
166 pClient->enable.hglrc = wglCreateContext(pClient->enable.hdc);
167 wglMakeCurrent(pClient->enable.hdc, pClient->enable.hglrc);
168 return VINF_SUCCESS;
169}
170
171
172/**
173 * Disable OpenGL
174 *
175 * @returns VBox error code
176 * @param pClient Client context
177 */
178int vboxglDisableOpenGL(PVBOXOGLCTX pClient)
179{
180 wglMakeCurrent(NULL, NULL);
181 wglDeleteContext(pClient->enable.hglrc);
182 ReleaseDC(0, pClient->enable.hdc);
183 return VINF_SUCCESS;
184}
185
186/**
187 * Client connect init
188 *
189 * @returns VBox error code
190 * @param pClient Client context
191 */
192int vboxglConnect(PVBOXOGLCTX pClient)
193{
194 Log(("vboxglConnect\n"));
195 return VINF_SUCCESS;
196}
197
198/**
199 * Client disconnect cleanup
200 *
201 * @returns VBox error code
202 * @param pClient Client context
203 */
204int vboxglDisconnect(PVBOXOGLCTX pClient)
205{
206 Log(("vboxglDisconnect\n"));
207#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
208 if (pClient->hwnd)
209 {
210 if (pClient->hdc)
211 ReleaseDC(pClient->hwnd, pClient->hdc);
212 PostMessage(pClient->hwnd, WM_CLOSE, 0, 0);
213 pClient->hwnd = 0;
214 }
215#endif
216 return VINF_SUCCESS;
217}
218
219
220/* Driver functions */
221void vboxglDrvCreateContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
222{
223 HGLRC glrc = 0;
224
225 OGL_CMD(DrvCreateContext, 1);
226 OGL_PARAM(HDC, hdc);
227
228 Log(("DrvCreateContext %x\n", hdc));
229 Assert(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
230 glrc = wglCreateContext(pClient->hdc);
231
232 pClient->lastretval = (uint64_t)glrc;
233 pClient->fHasLastError = true;
234 pClient->ulLastError = GetLastError();
235}
236
237void vboxglDrvSetContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
238{
239 OGL_CMD(DrvSetContext, 2);
240 OGL_PARAM(HDC, hdc);
241 OGL_PARAM(HGLRC, hglrc);
242
243 Log(("DrvSetyContext %x %x\n", hdc, hglrc));
244 pClient->lastretval = wglMakeCurrent(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), hglrc);
245 if (!pClient->lastretval)
246 Log(("wglMakeCurrent failed with %d\n", GetLastError()));
247
248 pClient->fHasLastError = true;
249 pClient->ulLastError = GetLastError();
250}
251
252void vboxglDrvCopyContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
253{
254 OGL_CMD(DrvDeleteContext, 3);
255 OGL_PARAM(HGLRC, hglrcSrc);
256 OGL_PARAM(HGLRC, hglrcDst);
257 OGL_PARAM(UINT, mask);
258 Log(("DrvCopyContext %x %x %x\n", hglrcSrc, hglrcDst, mask));
259 pClient->lastretval = wglCopyContext(hglrcSrc, hglrcDst, mask);
260 if (!pClient->lastretval)
261 Log(("wglCopyContext failed with %d\n", GetLastError()));
262
263 pClient->fHasLastError = true;
264 pClient->ulLastError = GetLastError();
265}
266
267void vboxglDrvReleaseContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
268{
269 OGL_CMD(DrvReleaseContext, 1);
270 OGL_PARAM(HGLRC, hglrc);
271
272 Log(("DrvReleaseContext %x\n", hglrc));
273 /* clear current selection */
274 pClient->lastretval = wglMakeCurrent(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), NULL);
275 if (!pClient->lastretval)
276 Log(("wglMakeCurrent failed with %d\n", GetLastError()));
277 pClient->fHasLastError = true;
278 pClient->ulLastError = GetLastError();
279}
280
281void vboxglDrvDeleteContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
282{
283 OGL_CMD(DrvDeleteContext, 1);
284 OGL_PARAM(HGLRC, hglrc);
285
286 Log(("DrvDeleteContext %x\n", hglrc));
287 pClient->lastretval = wglDeleteContext(hglrc);
288 if (!pClient->lastretval)
289 Log(("wglDeleteContext failed with %d\n", GetLastError()));
290 pClient->fHasLastError = true;
291 pClient->ulLastError = GetLastError();
292}
293
294void vboxglDrvCreateLayerContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
295{
296 HGLRC glrc = 0;
297
298 OGL_CMD(DrvCreateLayerContext, 2);
299 OGL_PARAM(HDC, hdc);
300 OGL_PARAM(int, iLayerPlane);
301
302 Log(("DrvCreateLayerContext %x %d\n", hdc, iLayerPlane));
303 Assert(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
304 glrc = wglCreateLayerContext(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane);
305
306 pClient->lastretval = (uint64_t)glrc;
307 pClient->fHasLastError = true;
308 pClient->ulLastError = GetLastError();
309}
310
311void vboxglDrvShareLists(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
312{
313 OGL_CMD(DrvShareLists, 3);
314 OGL_PARAM(HGLRC, hglrc1);
315 OGL_PARAM(HGLRC, hglrc2);
316
317 Log(("DrvShareLists %x %x\n", hglrc1, hglrc2));
318 pClient->lastretval = wglShareLists(hglrc1, hglrc2);
319 pClient->fHasLastError = true;
320 pClient->ulLastError = GetLastError();
321}
322
323
324void vboxglDrvRealizeLayerPalette(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
325{
326 OGL_CMD(DrvRealizeLayerPalette, 3);
327 OGL_PARAM(HDC, hdc);
328 OGL_PARAM(int, iLayerPlane);
329 OGL_PARAM(BOOL, bRealize);
330 Log(("DrvRealizeLayerPalette %x %d %d\n", hdc, iLayerPlane, bRealize));
331 pClient->lastretval = wglRealizeLayerPalette(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, bRealize);
332 pClient->fHasLastError = true;
333 pClient->ulLastError = GetLastError();
334}
335
336void vboxglDrvSwapLayerBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
337{
338 OGL_CMD(DrvSwapLayerBuffers, 2);
339 OGL_PARAM(HDC, hdc);
340 OGL_PARAM(UINT, fuPlanes);
341 Log(("DrvSwapLayerBuffers %x %d\n", hdc, fuPlanes));
342 pClient->lastretval = wglSwapLayerBuffers(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), fuPlanes);
343 pClient->fHasLastError = true;
344 pClient->ulLastError = GetLastError();
345}
346
347void vboxglDrvSetPixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
348{
349 int rc;
350 PIXELFORMATDESCRIPTOR pfd;
351
352 OGL_CMD(DrvSetPixelFormat, 4);
353 OGL_PARAM(HDC, hdc);
354 OGL_PARAM(int, iPixelFormat);
355 OGL_PARAM(uint32_t, cx);
356 OGL_PARAM(uint32_t, cy);
357
358#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
359 if (!pClient->hwnd)
360 {
361 RTThreadCreate(NULL, vboxWndThread, pClient, 0, RTTHREADTYPE_DEFAULT, 0, "OpenGLWnd");
362 while (!pClient->hwnd)
363 RTThreadSleep(100);
364 }
365 SetWindowPos(pClient->hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
366
367 pClient->hdc = GetDC(pClient->hwnd);
368
369 rc = DescribePixelFormat(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, sizeof(pfd), &pfd);
370 if (rc)
371 {
372 pClient->lastretval = SetPixelFormat(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, &pfd);
373 }
374 else
375 {
376 Log(("DescribePixelFormat %d failed with 0 (%d)\n", iPixelFormat, GetLastError()));
377 pClient->lastretval = 0;
378 }
379
380#else
381 AssertFailed();
382#endif
383
384 Log(("DrvSetPixelFormat %x %d (%d,%d)\n", hdc, iPixelFormat, cx, cy));
385 pClient->fHasLastError = true;
386 pClient->ulLastError = GetLastError();
387}
388
389void vboxglDrvSwapBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
390{
391 OGL_CMD(DrvSwapBuffers, 1);
392 OGL_PARAM(HDC, hdc);
393
394 Log(("DrvSwapBuffers %x\n", hdc));
395 pClient->lastretval = SwapBuffers(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
396 if (!pClient->lastretval)
397 Log(("SwapBuffers failed with %d\n", GetLastError()));
398
399 /** @todo sync bitmap/screen contents */
400 pClient->fHasLastError = true;
401 pClient->ulLastError = GetLastError();
402}
403
404void vboxglDrvDescribeLayerPlane(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
405{
406 PLAYERPLANEDESCRIPTOR plpd;
407
408 OGL_CMD(DrvDescribeLayerPlane, 4);
409 OGL_PARAM(HDC, hdc);
410 OGL_PARAM(int, iPixelFormat);
411 OGL_PARAM(int, iLayerPlane);
412 OGL_PARAM(UINT, nBytes);
413 Assert(pClient->cbLastParam == nBytes);
414 plpd = (PLAYERPLANEDESCRIPTOR)pClient->pLastParam;
415
416 Log(("DrvDescribeLayerPlane %x %d %d %d %x\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd));
417 pClient->lastretval = wglDescribeLayerPlane(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, iLayerPlane, nBytes, plpd);
418 if (!pClient->lastretval)
419 Log(("wglDescribeLayerPlane failed with %d\n", GetLastError()));
420 pClient->fHasLastError = true;
421 pClient->ulLastError = GetLastError();
422}
423
424void vboxglDrvSetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
425{
426 OGL_CMD(DrvSetLayerPaletteEntries, 5);
427 OGL_PARAM(HDC, hdc);
428 OGL_PARAM(int, iLayerPlane);
429 OGL_PARAM(int, iStart);
430 OGL_PARAM(int, cEntries);
431 OGL_MEMPARAM(COLORREF, pcr);
432
433 Log(("DrvSetLayerPaletteEntries %x %d %d %d %x\n", hdc, iLayerPlane, iStart, cEntries, pcr));
434 pClient->lastretval = wglSetLayerPaletteEntries(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, iStart, cEntries, pcr);
435 if (!pClient->lastretval)
436 Log(("wglSetLayerPaletteEntries failed with %d\n", GetLastError()));
437 pClient->fHasLastError = true;
438 pClient->ulLastError = GetLastError();
439}
440
441void vboxglDrvGetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
442{
443 COLORREF *pcr;
444
445 OGL_CMD(DrvGetLayerPaletteEntries, 4);
446 OGL_PARAM(HDC, hdc);
447 OGL_PARAM(int, iLayerPlane);
448 OGL_PARAM(int, iStart);
449 OGL_PARAM(int, cEntries);
450
451 Assert(pClient->cbLastParam == sizeof(COLORREF)*cEntries);
452 pcr = (COLORREF *)pClient->pLastParam;
453
454 Log(("DrvGetLayerPaletteEntries %x %d %d %d %x\n", hdc, iLayerPlane, iStart, cEntries, pcr));
455 pClient->lastretval = wglGetLayerPaletteEntries(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, iStart, cEntries, pcr);
456 if (!pClient->lastretval)
457 Log(("wglGetLayerPaletteEntries failed with %d\n", GetLastError()));
458 pClient->fHasLastError = true;
459 pClient->ulLastError = GetLastError();
460}
461
462void vboxglDrvDescribePixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
463{
464 LPPIXELFORMATDESCRIPTOR ppfd;
465
466 OGL_CMD(DrvDescribePixelFormat, 3);
467 OGL_PARAM(HDC, hdc);
468 OGL_PARAM(int, iPixelFormat);
469 OGL_PARAM(UINT, nBytes);
470 Assert(pClient->cbLastParam == nBytes);
471 ppfd = (LPPIXELFORMATDESCRIPTOR)pClient->pLastParam;
472
473 hdc = VBOX_OGL_GUEST_TO_HOST_HDC(hdc);
474 if (!hdc)
475 hdc = GetDC(0);
476
477 Log(("DrvDescribePixelFormat %x %d %d %x\n", hdc, iPixelFormat, nBytes, ppfd));
478 pClient->lastretval = DescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
479 if (!pClient->lastretval)
480 Log(("DescribePixelFormat failed with %d\n", GetLastError()));
481
482 pClient->fHasLastError = true;
483 pClient->ulLastError = GetLastError();
484
485 if (!VBOX_OGL_GUEST_TO_HOST_HDC(hdc))
486 ReleaseDC(0, pClient->hdc);
487}
488
489RTUINTPTR vboxDrvIsExtensionAvailable(char *pszExtFunctionName)
490{
491 RTUINTPTR pfnProc = (RTUINTPTR)wglGetProcAddress(pszExtFunctionName);
492
493 Log(("vboxDrvIsExtensionAvailable %s -> %d\n", pszExtFunctionName, !!pfnProc));
494 return pfnProc;
495}
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