VirtualBox

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

Last change on this file since 10895 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
File size: 14.2 KB
Line 
1/** @file
2 * VBox OpenGL
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17 * Clara, CA 95054 USA or visit http://www.sun.com if you need
18 * additional information or have any questions.
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 * Global deinit of VBox OpenGL
135 *
136 * @returns VBox error code
137 */
138int vboxglGlobalUnload()
139{
140 Log(("vboxglGlobalUnload"));
141
142 return VINF_SUCCESS;
143}
144
145/**
146 * Enable OpenGL
147 *
148 * @returns VBox error code
149 * @param pClient Client context
150 */
151int vboxglEnableOpenGL(PVBOXOGLCTX pClient)
152{
153 PIXELFORMATDESCRIPTOR pfd;
154 int iFormat;
155
156 /** @todo should NOT use the desktop window -> crashes the Intel OpenGL driver */
157 pClient->enable.hdc = GetDC(0);
158
159 ZeroMemory(&pfd, sizeof(pfd));
160 pfd.nSize = sizeof(pfd);
161 pfd.nVersion = 1;
162 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
163 pfd.iPixelType = PFD_TYPE_RGBA;
164 pfd.cColorBits = 24;
165 pfd.cDepthBits = 16;
166 pfd.iLayerType = PFD_MAIN_PLANE;
167 iFormat = ChoosePixelFormat(pClient->enable.hdc, &pfd);
168 SetPixelFormat(pClient->enable.hdc, iFormat, &pfd);
169
170 pClient->enable.hglrc = wglCreateContext(pClient->enable.hdc);
171 wglMakeCurrent(pClient->enable.hdc, pClient->enable.hglrc);
172 return VINF_SUCCESS;
173}
174
175
176/**
177 * Disable OpenGL
178 *
179 * @returns VBox error code
180 * @param pClient Client context
181 */
182int vboxglDisableOpenGL(PVBOXOGLCTX pClient)
183{
184 wglMakeCurrent(NULL, NULL);
185 wglDeleteContext(pClient->enable.hglrc);
186 ReleaseDC(0, pClient->enable.hdc);
187 return VINF_SUCCESS;
188}
189
190/**
191 * Client connect init
192 *
193 * @returns VBox error code
194 * @param pClient Client context
195 */
196int vboxglConnect(PVBOXOGLCTX pClient)
197{
198 Log(("vboxglConnect\n"));
199 return VINF_SUCCESS;
200}
201
202/**
203 * Client disconnect cleanup
204 *
205 * @returns VBox error code
206 * @param pClient Client context
207 */
208int vboxglDisconnect(PVBOXOGLCTX pClient)
209{
210 Log(("vboxglDisconnect\n"));
211#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
212 if (pClient->hwnd)
213 {
214 if (pClient->hdc)
215 ReleaseDC(pClient->hwnd, pClient->hdc);
216 PostMessage(pClient->hwnd, WM_CLOSE, 0, 0);
217 pClient->hwnd = 0;
218 }
219#endif
220 return VINF_SUCCESS;
221}
222
223
224/* Driver functions */
225void vboxglDrvCreateContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
226{
227 HGLRC glrc = 0;
228
229 OGL_CMD(DrvCreateContext, 1);
230 OGL_PARAM(HDC, hdc);
231
232 Log(("DrvCreateContext %x\n", hdc));
233 Assert(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
234 glrc = wglCreateContext(pClient->hdc);
235
236 pClient->lastretval = (uint64_t)glrc;
237 pClient->fHasLastError = true;
238 pClient->ulLastError = GetLastError();
239}
240
241void vboxglDrvSetContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
242{
243 OGL_CMD(DrvSetContext, 2);
244 OGL_PARAM(HDC, hdc);
245 OGL_PARAM(HGLRC, hglrc);
246
247 Log(("DrvSetyContext %x %x\n", hdc, hglrc));
248 pClient->lastretval = wglMakeCurrent(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), hglrc);
249 if (!pClient->lastretval)
250 Log(("wglMakeCurrent failed with %d\n", GetLastError()));
251
252 pClient->fHasLastError = true;
253 pClient->ulLastError = GetLastError();
254}
255
256void vboxglDrvCopyContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
257{
258 OGL_CMD(DrvDeleteContext, 3);
259 OGL_PARAM(HGLRC, hglrcSrc);
260 OGL_PARAM(HGLRC, hglrcDst);
261 OGL_PARAM(UINT, mask);
262 Log(("DrvCopyContext %x %x %x\n", hglrcSrc, hglrcDst, mask));
263 pClient->lastretval = wglCopyContext(hglrcSrc, hglrcDst, mask);
264 if (!pClient->lastretval)
265 Log(("wglCopyContext failed with %d\n", GetLastError()));
266
267 pClient->fHasLastError = true;
268 pClient->ulLastError = GetLastError();
269}
270
271void vboxglDrvReleaseContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
272{
273 OGL_CMD(DrvReleaseContext, 1);
274 OGL_PARAM(HGLRC, hglrc);
275
276 Log(("DrvReleaseContext %x\n", hglrc));
277 /* clear current selection */
278 pClient->lastretval = wglMakeCurrent(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), NULL);
279 if (!pClient->lastretval)
280 Log(("wglMakeCurrent failed with %d\n", GetLastError()));
281 pClient->fHasLastError = true;
282 pClient->ulLastError = GetLastError();
283}
284
285void vboxglDrvDeleteContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
286{
287 OGL_CMD(DrvDeleteContext, 1);
288 OGL_PARAM(HGLRC, hglrc);
289
290 Log(("DrvDeleteContext %x\n", hglrc));
291 pClient->lastretval = wglDeleteContext(hglrc);
292 if (!pClient->lastretval)
293 Log(("wglDeleteContext failed with %d\n", GetLastError()));
294 pClient->fHasLastError = true;
295 pClient->ulLastError = GetLastError();
296}
297
298void vboxglDrvCreateLayerContext(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
299{
300 HGLRC glrc = 0;
301
302 OGL_CMD(DrvCreateLayerContext, 2);
303 OGL_PARAM(HDC, hdc);
304 OGL_PARAM(int, iLayerPlane);
305
306 Log(("DrvCreateLayerContext %x %d\n", hdc, iLayerPlane));
307 Assert(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
308 glrc = wglCreateLayerContext(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane);
309
310 pClient->lastretval = (uint64_t)glrc;
311 pClient->fHasLastError = true;
312 pClient->ulLastError = GetLastError();
313}
314
315void vboxglDrvShareLists(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
316{
317 OGL_CMD(DrvShareLists, 3);
318 OGL_PARAM(HGLRC, hglrc1);
319 OGL_PARAM(HGLRC, hglrc2);
320
321 Log(("DrvShareLists %x %x\n", hglrc1, hglrc2));
322 pClient->lastretval = wglShareLists(hglrc1, hglrc2);
323 pClient->fHasLastError = true;
324 pClient->ulLastError = GetLastError();
325}
326
327
328void vboxglDrvRealizeLayerPalette(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
329{
330 OGL_CMD(DrvRealizeLayerPalette, 3);
331 OGL_PARAM(HDC, hdc);
332 OGL_PARAM(int, iLayerPlane);
333 OGL_PARAM(BOOL, bRealize);
334 Log(("DrvRealizeLayerPalette %x %d %d\n", hdc, iLayerPlane, bRealize));
335 pClient->lastretval = wglRealizeLayerPalette(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, bRealize);
336 pClient->fHasLastError = true;
337 pClient->ulLastError = GetLastError();
338}
339
340void vboxglDrvSwapLayerBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
341{
342 OGL_CMD(DrvSwapLayerBuffers, 2);
343 OGL_PARAM(HDC, hdc);
344 OGL_PARAM(UINT, fuPlanes);
345 Log(("DrvSwapLayerBuffers %x %d\n", hdc, fuPlanes));
346 pClient->lastretval = wglSwapLayerBuffers(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), fuPlanes);
347 pClient->fHasLastError = true;
348 pClient->ulLastError = GetLastError();
349}
350
351void vboxglDrvSetPixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
352{
353 int rc;
354 PIXELFORMATDESCRIPTOR pfd;
355
356 OGL_CMD(DrvSetPixelFormat, 4);
357 OGL_PARAM(HDC, hdc);
358 OGL_PARAM(int, iPixelFormat);
359 OGL_PARAM(uint32_t, cx);
360 OGL_PARAM(uint32_t, cy);
361
362#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
363 if (!pClient->hwnd)
364 {
365 RTThreadCreate(NULL, vboxWndThread, pClient, 0, RTTHREADTYPE_DEFAULT, 0, "OpenGLWnd");
366 while (!pClient->hwnd)
367 RTThreadSleep(100);
368 }
369 SetWindowPos(pClient->hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
370
371 pClient->hdc = GetDC(pClient->hwnd);
372
373 rc = DescribePixelFormat(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, sizeof(pfd), &pfd);
374 if (rc)
375 {
376 pClient->lastretval = SetPixelFormat(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, &pfd);
377 }
378 else
379 {
380 Log(("DescribePixelFormat %d failed with 0 (%d)\n", iPixelFormat, GetLastError()));
381 pClient->lastretval = 0;
382 }
383
384#else
385 AssertFailed();
386#endif
387
388 Log(("DrvSetPixelFormat %x %d (%d,%d)\n", hdc, iPixelFormat, cx, cy));
389 pClient->fHasLastError = true;
390 pClient->ulLastError = GetLastError();
391}
392
393void vboxglDrvSwapBuffers(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
394{
395 OGL_CMD(DrvSwapBuffers, 1);
396 OGL_PARAM(HDC, hdc);
397
398 Log(("DrvSwapBuffers %x\n", hdc));
399 pClient->lastretval = SwapBuffers(VBOX_OGL_GUEST_TO_HOST_HDC(hdc));
400 if (!pClient->lastretval)
401 Log(("SwapBuffers failed with %d\n", GetLastError()));
402
403 /** @todo sync bitmap/screen contents */
404 pClient->fHasLastError = true;
405 pClient->ulLastError = GetLastError();
406}
407
408void vboxglDrvDescribeLayerPlane(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
409{
410 PLAYERPLANEDESCRIPTOR plpd;
411
412 OGL_CMD(DrvDescribeLayerPlane, 4);
413 OGL_PARAM(HDC, hdc);
414 OGL_PARAM(int, iPixelFormat);
415 OGL_PARAM(int, iLayerPlane);
416 OGL_PARAM(UINT, nBytes);
417 Assert(pClient->cbLastParam == nBytes);
418 plpd = (PLAYERPLANEDESCRIPTOR)pClient->pLastParam;
419
420 Log(("DrvDescribeLayerPlane %x %d %d %d %x\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd));
421 pClient->lastretval = wglDescribeLayerPlane(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iPixelFormat, iLayerPlane, nBytes, plpd);
422 if (!pClient->lastretval)
423 Log(("wglDescribeLayerPlane failed with %d\n", GetLastError()));
424 pClient->fHasLastError = true;
425 pClient->ulLastError = GetLastError();
426}
427
428void vboxglDrvSetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
429{
430 OGL_CMD(DrvSetLayerPaletteEntries, 5);
431 OGL_PARAM(HDC, hdc);
432 OGL_PARAM(int, iLayerPlane);
433 OGL_PARAM(int, iStart);
434 OGL_PARAM(int, cEntries);
435 OGL_MEMPARAM(COLORREF, pcr);
436
437 Log(("DrvSetLayerPaletteEntries %x %d %d %d %x\n", hdc, iLayerPlane, iStart, cEntries, pcr));
438 pClient->lastretval = wglSetLayerPaletteEntries(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, iStart, cEntries, pcr);
439 if (!pClient->lastretval)
440 Log(("wglSetLayerPaletteEntries failed with %d\n", GetLastError()));
441 pClient->fHasLastError = true;
442 pClient->ulLastError = GetLastError();
443}
444
445void vboxglDrvGetLayerPaletteEntries(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
446{
447 COLORREF *pcr;
448
449 OGL_CMD(DrvGetLayerPaletteEntries, 4);
450 OGL_PARAM(HDC, hdc);
451 OGL_PARAM(int, iLayerPlane);
452 OGL_PARAM(int, iStart);
453 OGL_PARAM(int, cEntries);
454
455 Assert(pClient->cbLastParam == sizeof(COLORREF)*cEntries);
456 pcr = (COLORREF *)pClient->pLastParam;
457
458 Log(("DrvGetLayerPaletteEntries %x %d %d %d %x\n", hdc, iLayerPlane, iStart, cEntries, pcr));
459 pClient->lastretval = wglGetLayerPaletteEntries(VBOX_OGL_GUEST_TO_HOST_HDC(hdc), iLayerPlane, iStart, cEntries, pcr);
460 if (!pClient->lastretval)
461 Log(("wglGetLayerPaletteEntries failed with %d\n", GetLastError()));
462 pClient->fHasLastError = true;
463 pClient->ulLastError = GetLastError();
464}
465
466void vboxglDrvDescribePixelFormat(VBOXOGLCTX *pClient, uint8_t *pCmdBuffer)
467{
468 LPPIXELFORMATDESCRIPTOR ppfd;
469
470 OGL_CMD(DrvDescribePixelFormat, 3);
471 OGL_PARAM(HDC, hdc);
472 OGL_PARAM(int, iPixelFormat);
473 OGL_PARAM(UINT, nBytes);
474 Assert(pClient->cbLastParam == nBytes);
475 ppfd = (LPPIXELFORMATDESCRIPTOR)pClient->pLastParam;
476
477 hdc = VBOX_OGL_GUEST_TO_HOST_HDC(hdc);
478 if (!hdc)
479 hdc = GetDC(0);
480
481 Log(("DrvDescribePixelFormat %x %d %d %x\n", hdc, iPixelFormat, nBytes, ppfd));
482 pClient->lastretval = DescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
483 if (!pClient->lastretval)
484 Log(("DescribePixelFormat failed with %d\n", GetLastError()));
485
486 pClient->fHasLastError = true;
487 pClient->ulLastError = GetLastError();
488
489 if (!VBOX_OGL_GUEST_TO_HOST_HDC(hdc))
490 ReleaseDC(0, pClient->hdc);
491}
492
493RTUINTPTR vboxDrvIsExtensionAvailable(char *pszExtFunctionName)
494{
495 RTUINTPTR pfnProc = (RTUINTPTR)wglGetProcAddress(pszExtFunctionName);
496
497 Log(("vboxDrvIsExtensionAvailable %s -> %d\n", pszExtFunctionName, !!pfnProc));
498 return pfnProc;
499}
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