VirtualBox

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

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

crOpenGL: typo

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