VirtualBox

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

Last change on this file since 3744 was 3708, checked in by vboxsync, 18 years ago

Merged Linux code from Alexander Eichner.

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