VirtualBox

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

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

Extension detection updates

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