VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_init.c@ 16281

Last change on this file since 16281 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_mem.h"
8#include "cr_spu.h"
9#include "cr_error.h"
10#include "cr_string.h"
11#include "cr_url.h"
12#include "renderspu.h"
13#include <stdio.h>
14
15static SPUNamedFunctionTable _cr_render_table[1000];
16
17SPUFunctions render_functions = {
18 NULL, /* CHILD COPY */
19 NULL, /* DATA */
20 _cr_render_table /* THE ACTUAL FUNCTIONS */
21};
22
23RenderSPU render_spu;
24unsigned int render_spu_parent_window_id;
25
26#ifdef CHROMIUM_THREADSAFE
27CRtsd _RenderTSD;
28#endif
29
30static void swapsyncConnect(void)
31{
32 char hostname[4096], protocol[4096];
33 unsigned short port;
34
35 crNetInit(NULL, NULL);
36
37 if (!crParseURL( render_spu.swap_master_url, protocol, hostname,
38 &port, 9876))
39 crError( "Bad URL: %s", render_spu.swap_master_url );
40
41 if (render_spu.is_swap_master)
42 {
43 int a;
44
45 render_spu.swap_conns = (CRConnection **)crAlloc(
46 render_spu.num_swap_clients*sizeof(CRConnection *));
47 for (a=0; a<render_spu.num_swap_clients; a++)
48 {
49 render_spu.swap_conns[a] = crNetAcceptClient( protocol, hostname, port,
50 render_spu.swap_mtu, 1);
51 }
52 }
53 else
54 {
55 render_spu.swap_conns = (CRConnection **)crAlloc(sizeof(CRConnection *));
56
57 render_spu.swap_conns[0] = crNetConnectToServer(render_spu.swap_master_url,
58 port, render_spu.swap_mtu, 1);
59 if (!render_spu.swap_conns[0])
60 crError("Failed connection");
61 }
62}
63
64#ifdef RT_OS_WINDOWS
65static DWORD WINAPI renderSPUWindowThreadProc(void* unused)
66{
67 MSG msg;
68 bool bRet;
69
70 (void) unused;
71
72 crDebug("RenderSPU: Window thread started (%x)", crThreadID());
73 SetEvent(render_spu.hWinThreadReadyEvent);
74
75 while( (bRet = GetMessage( &msg, 0, 0, 0 )) != 0)
76 {
77 if (bRet == -1)
78 {
79 crError("RenderSPU: Window thread GetMessage failed (%x)", GetLastError());
80 break;
81 }
82 else
83 {
84 if (msg.message == WM_VBOX_RENDERSPU_CREATE_WINDOW)
85 {
86 LPCREATESTRUCT pCS = (LPCREATESTRUCT) msg.lParam;
87 HWND *phWnd;
88
89 CRASSERT(msg.lParam && !msg.wParam && pCS->lpCreateParams);
90
91 phWnd = pCS->lpCreateParams;
92
93 *phWnd = CreateWindowEx(pCS->dwExStyle, pCS->lpszName, pCS->lpszClass, pCS->style,
94 pCS->x, pCS->y, pCS->cx, pCS->cy,
95 pCS->hwndParent, pCS->hMenu, pCS->hInstance, &render_spu);
96
97 SetEvent(render_spu.hWinThreadReadyEvent);
98 }
99 else if (msg.message == WM_VBOX_RENDERSPU_DESTROY_WINDOW)
100 {
101 CRASSERT(msg.lParam && !msg.wParam);
102
103 DestroyWindow(((VBOX_RENDERSPU_DESTROY_WINDOW*) msg.lParam)->hWnd);
104
105 SetEvent(render_spu.hWinThreadReadyEvent);
106 }
107 else
108 {
109 TranslateMessage(&msg);
110 DispatchMessage(&msg);
111 }
112 }
113 }
114
115 render_spu.dwWinThreadId = 0;
116
117 crDebug("RenderSPU: Window thread stopped (%x)", crThreadID());
118 SetEvent(render_spu.hWinThreadReadyEvent);
119
120 return 0;
121}
122#endif
123
124static SPUFunctions *
125renderSPUInit( int id, SPU *child, SPU *self,
126 unsigned int context_id, unsigned int num_contexts )
127{
128 int numFuncs, numSpecial;
129 GLint defaultWin, defaultCtx;
130 WindowInfo *windowInfo;
131
132 (void) child;
133 (void) context_id;
134 (void) num_contexts;
135
136 self->privatePtr = (void *) &render_spu;
137
138#ifdef CHROMIUM_THREADSAFE
139 crDebug("Render SPU: thread-safe");
140#endif
141
142 crMemZero(&render_spu, sizeof(render_spu));
143
144 render_spu.id = id;
145 renderspuSetVBoxConfiguration(&render_spu);
146
147 if (render_spu.swap_master_url)
148 swapsyncConnect();
149
150
151 /* Get our special functions. */
152 numSpecial = renderspuCreateFunctions( _cr_render_table );
153
154#ifdef RT_OS_WINDOWS
155 /* Start thread to create windows and process window messages */
156 crDebug("RenderSPU: Starting windows serving thread");
157 render_spu.hWinThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
158 if (!render_spu.hWinThreadReadyEvent)
159 {
160 crError("RenderSPU: Failed to create WinThreadReadyEvent! (%x)", GetLastError());
161 return NULL;
162 }
163
164 if (!CreateThread(NULL, 0, renderSPUWindowThreadProc, 0, 0, &render_spu.dwWinThreadId))
165 {
166 crError("RenderSPU: Failed to start windows thread! (%x)", GetLastError());
167 return NULL;
168 }
169 WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
170#endif
171
172 /* Get the OpenGL functions. */
173 numFuncs = crLoadOpenGL( &render_spu.ws, _cr_render_table + numSpecial );
174 if (numFuncs == 0) {
175 crError("The render SPU was unable to load the native OpenGL library");
176 return NULL;
177 }
178
179 numFuncs += numSpecial;
180
181#ifdef GLX
182 if (!render_spu.use_glxchoosevisual) {
183 /* sometimes want to set this option with ATI drivers */
184 render_spu.ws.glXChooseVisual = NULL;
185 }
186#endif
187
188 render_spu.window_id = 0;
189 render_spu.context_id = 0;
190 render_spu.contextTable = crAllocHashtable();
191 render_spu.windowTable = crAllocHashtable();
192
193 CRASSERT(render_spu.default_visual & CR_RGB_BIT);
194
195#ifdef USE_OSMESA
196 if (render_spu.use_osmesa) {
197 if (!crLoadOSMesa(&render_spu.OSMesaCreateContext,
198 &render_spu.OSMesaMakeCurrent,
199 &render_spu.OSMesaDestroyContext)) {
200 crError("Unable to load OSMesa library");
201 }
202 }
203#endif
204
205 /*
206 * Create the default window and context. Their indexes are zero and
207 * a client can use them without calling CreateContext or WindowCreate.
208 */
209 crDebug("Render SPU: Creating default window (visBits=0x%x, id=0)",
210 render_spu.default_visual);
211 defaultWin = renderspuWindowCreate( NULL, render_spu.default_visual );
212 if (defaultWin != 0) {
213 crError("Render SPU: Couldn't get a double-buffered, RGB visual with Z!");
214 return NULL;
215 }
216 crDebug( "Render SPU: WindowCreate returned %d (0=normal)", defaultWin );
217
218 crDebug("Render SPU: Creating default context, visBits=0x%x",
219 render_spu.default_visual );
220 defaultCtx = renderspuCreateContext( NULL, render_spu.default_visual, 0 );
221 CRASSERT(defaultCtx == 0);
222
223 renderspuMakeCurrent( defaultWin, 0, defaultCtx );
224
225 /* Get windowInfo for the default window */
226 windowInfo = (WindowInfo *) crHashtableSearch(render_spu.windowTable, 0);
227 CRASSERT(windowInfo);
228 windowInfo->mapPending = GL_TRUE;
229
230 /*
231 * Get the OpenGL extension functions.
232 * SIGH -- we have to wait until the very bitter end to load the
233 * extensions, because the context has to be bound before
234 * wglGetProcAddress will work correctly. No such issue with GLX though.
235 */
236 numFuncs += crLoadOpenGLExtensions( &render_spu.ws, _cr_render_table + numFuncs );
237 CRASSERT(numFuncs < 1000);
238
239#ifdef WINDOWS
240 /*
241 * Same problem as above, these are extensions so we need to
242 * load them after a context has been bound. As they're WGL
243 * extensions too, we can't simply tag them into the spu_loader.
244 * So we do them here for now.
245 * Grrr, NVIDIA driver uses EXT for GetExtensionsStringEXT,
246 * but ARB for others. Need furthur testing here....
247 */
248 render_spu.ws.wglGetExtensionsStringEXT =
249 (wglGetExtensionsStringEXTFunc_t)
250 render_spu.ws.wglGetProcAddress( "wglGetExtensionsStringEXT" );
251 render_spu.ws.wglChoosePixelFormatEXT =
252 (wglChoosePixelFormatEXTFunc_t)
253 render_spu.ws.wglGetProcAddress( "wglChoosePixelFormatARB" );
254 render_spu.ws.wglGetPixelFormatAttribivEXT =
255 (wglGetPixelFormatAttribivEXTFunc_t)
256 render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
257 render_spu.ws.wglGetPixelFormatAttribfvEXT =
258 (wglGetPixelFormatAttribfvEXTFunc_t)
259 render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribfvARB" );
260
261 if (render_spu.ws.wglGetProcAddress("glTexImage3D"))
262 {
263 _cr_render_table[numFuncs].name = crStrdup("TexImage3D");
264 _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexImage3D");
265 ++numFuncs;
266 crDebug("Render SPU: Found glTexImage3D function");
267 }
268
269 if (render_spu.ws.wglGetExtensionsStringEXT) {
270 crDebug("WGL - found wglGetExtensionsStringEXT\n");
271 }
272 if (render_spu.ws.wglChoosePixelFormatEXT) {
273 crDebug("WGL - found wglChoosePixelFormatEXT\n");
274 }
275#endif
276
277 render_spu.barrierHash = crAllocHashtable();
278
279 render_spu.cursorX = 0;
280 render_spu.cursorY = 0;
281 render_spu.use_L2 = 0;
282
283 render_spu.gather_conns = NULL;
284
285 crDebug("Render SPU: ---------- End of Init -------------");
286 return &render_functions;
287}
288
289
290static void renderSPUSelfDispatch(SPUDispatchTable *self)
291{
292 crSPUInitDispatchTable( &(render_spu.self) );
293 crSPUCopyDispatchTable( &(render_spu.self), self );
294
295 render_spu.server = (CRServer *)(self->server);
296}
297
298
299static void DeleteContextCallback( void *data )
300{
301 ContextInfo *context = (ContextInfo *) data;
302 renderspu_SystemDestroyContext(context);
303 crFree(context);
304}
305
306static void DeleteWindowCallback( void *data )
307{
308 WindowInfo *window = (WindowInfo *) data;
309 renderspu_SystemDestroyWindow(window);
310 crFree(window);
311}
312
313static int renderSPUCleanup(void)
314{
315 crFreeHashtable(render_spu.contextTable, DeleteContextCallback);
316 render_spu.contextTable = NULL;
317 crFreeHashtable(render_spu.windowTable, DeleteWindowCallback);
318 render_spu.windowTable = NULL;
319 crFreeHashtable(render_spu.barrierHash, crFree);
320 render_spu.barrierHash = NULL;
321
322#ifdef RT_OS_WINDOWS
323 if (render_spu.dwWinThreadId)
324 {
325 PostThreadMessage(render_spu.dwWinThreadId, WM_QUIT, 0, 0);
326 WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
327 }
328 CloseHandle(render_spu.hWinThreadReadyEvent);
329 render_spu.hWinThreadReadyEvent = NULL;
330#endif
331
332 return 1;
333}
334
335
336extern SPUOptions renderSPUOptions[];
337
338int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
339 SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
340 SPUOptionsPtr *options, int *flags )
341{
342 *name = "render";
343 *super = NULL;
344 *init = renderSPUInit;
345 *self = renderSPUSelfDispatch;
346 *cleanup = renderSPUCleanup;
347 *options = renderSPUOptions;
348 *flags = (SPU_NO_PACKER|SPU_IS_TERMINAL|SPU_MAX_SERVERS_ZERO);
349
350 return 1;
351}
352
353void renderspuSetWindowId(unsigned int winId)
354{
355 render_spu_parent_window_id = winId;
356}
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