VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu.c@ 43748

Last change on this file since 43748 was 43748, checked in by vboxsync, 12 years ago

crOpenGL: proper renderspu tsd cleanup on context destruction

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 34.0 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_environment.h"
8#include "cr_string.h"
9#include "cr_error.h"
10#include "cr_mem.h"
11#include "cr_spu.h"
12#include "renderspu.h"
13#include "cr_extstring.h"
14
15
16static void
17DoSync(void)
18{
19 CRMessage *in, out;
20
21 out.header.type = CR_MESSAGE_OOB;
22
23 if (render_spu.is_swap_master)
24 {
25 int a;
26
27 for (a = 0; a < render_spu.num_swap_clients; a++)
28 {
29 crNetGetMessage( render_spu.swap_conns[a], &in );
30 crNetFree( render_spu.swap_conns[a], in);
31 }
32
33 for (a = 0; a < render_spu.num_swap_clients; a++)
34 crNetSend( render_spu.swap_conns[a], NULL, &out, sizeof(CRMessage));
35 }
36 else
37 {
38 crNetSend( render_spu.swap_conns[0], NULL, &out, sizeof(CRMessage));
39
40 crNetGetMessage( render_spu.swap_conns[0], &in );
41 crNetFree( render_spu.swap_conns[0], in);
42 }
43}
44
45
46
47/*
48 * Visual functions
49 */
50
51/**
52 * used for debugging and giving info to the user.
53 */
54void
55renderspuMakeVisString( GLbitfield visAttribs, char *s )
56{
57 s[0] = 0;
58
59 if (visAttribs & CR_RGB_BIT)
60 crStrcat(s, "RGB");
61 if (visAttribs & CR_ALPHA_BIT)
62 crStrcat(s, "A");
63 if (visAttribs & CR_DOUBLE_BIT)
64 crStrcat(s, ", Doublebuffer");
65 if (visAttribs & CR_STEREO_BIT)
66 crStrcat(s, ", Stereo");
67 if (visAttribs & CR_DEPTH_BIT)
68 crStrcat(s, ", Z");
69 if (visAttribs & CR_STENCIL_BIT)
70 crStrcat(s, ", Stencil");
71 if (visAttribs & CR_ACCUM_BIT)
72 crStrcat(s, ", Accum");
73 if (visAttribs & CR_MULTISAMPLE_BIT)
74 crStrcat(s, ", Multisample");
75 if (visAttribs & CR_OVERLAY_BIT)
76 crStrcat(s, ", Overlay");
77 if (visAttribs & CR_PBUFFER_BIT)
78 crStrcat(s, ", PBuffer");
79}
80
81
82/*
83 * Find a VisualInfo which matches the given display name and attribute
84 * bitmask, or return a pointer to a new visual.
85 */
86VisualInfo *
87renderspuFindVisual(const char *displayName, GLbitfield visAttribs)
88{
89 int i;
90
91 if (!displayName)
92 displayName = "";
93
94 /* first, try to find a match */
95#if defined(WINDOWS) || defined(DARWIN)
96 for (i = 0; i < render_spu.numVisuals; i++) {
97 if (visAttribs == render_spu.visuals[i].visAttribs) {
98 return &(render_spu.visuals[i]);
99 }
100 }
101#elif defined(GLX)
102 for (i = 0; i < render_spu.numVisuals; i++) {
103 if (crStrcmp(displayName, render_spu.visuals[i].displayName) == 0
104 && visAttribs == render_spu.visuals[i].visAttribs) {
105 return &(render_spu.visuals[i]);
106 }
107 }
108#endif
109
110 if (render_spu.numVisuals >= MAX_VISUALS)
111 {
112 crWarning("Render SPU: Couldn't create a visual, too many visuals already");
113 return NULL;
114 }
115
116 /* create a new visual */
117 i = render_spu.numVisuals;
118 render_spu.visuals[i].displayName = crStrdup(displayName);
119 render_spu.visuals[i].visAttribs = visAttribs;
120 if (renderspu_SystemInitVisual(&(render_spu.visuals[i]))) {
121 render_spu.numVisuals++;
122 return &(render_spu.visuals[i]);
123 }
124 else {
125 crWarning("Render SPU: Couldn't get a visual, renderspu_SystemInitVisual failed");
126 return NULL;
127 }
128}
129
130/*
131 * Context functions
132 */
133
134GLint RENDER_APIENTRY
135renderspuCreateContext(const char *dpyName, GLint visBits, GLint shareCtx)
136{
137 ContextInfo *context, *sharedContext = NULL;
138 VisualInfo *visual;
139
140 if (shareCtx > 0) {
141 sharedContext
142 = (ContextInfo *) crHashtableSearch(render_spu.contextTable, shareCtx);
143 }
144
145 if (!dpyName || crStrlen(render_spu.display_string)>0)
146 dpyName = render_spu.display_string;
147
148 visual = renderspuFindVisual(dpyName, visBits);
149 if (!visual)
150 return -1;
151
152 context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
153 if (!context)
154 return -1;
155 context->id = render_spu.context_id;
156 context->shared = sharedContext;
157 if (!renderspu_SystemCreateContext(visual, context, sharedContext))
158 return -1;
159
160 crHashtableAdd(render_spu.contextTable, render_spu.context_id, context);
161 render_spu.context_id++;
162
163 /*
164 crDebug("Render SPU: CreateContext(%s, 0x%x) returning %d",
165 dpyName, visBits, context->id);
166 */
167
168 return context->id;
169}
170
171
172static void RENDER_APIENTRY
173renderspuDestroyContext( GLint ctx )
174{
175 ContextInfo *context, *curCtx;
176
177 CRASSERT(ctx);
178
179 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
180 CRASSERT(context);
181 renderspu_SystemDestroyContext( context );
182 if (context->extensionString) {
183 crFree(context->extensionString);
184 context->extensionString = NULL;
185 }
186 crHashtableDelete(render_spu.contextTable, ctx, crFree);
187
188 curCtx = GET_CONTEXT_VAL();
189 if (curCtx == context)
190 SET_CONTEXT_VAL(NULL);
191}
192
193
194void RENDER_APIENTRY
195renderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
196{
197 WindowInfo *window;
198 ContextInfo *context;
199
200 /*
201 crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx);
202 */
203
204 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow);
205 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
206
207 if (window && context)
208 {
209#ifdef CHROMIUM_THREADSAFE
210 crSetTSD(&_RenderTSD, context);
211#else
212 render_spu.currentContext = context;
213#endif
214 context->currentWindow = window;
215 if (!window)
216 {
217 crDebug("Render SPU: MakeCurrent invalid window id: %d", crWindow);
218 return;
219 }
220 if (!context)
221 {
222 crDebug("Render SPU: MakeCurrent invalid context id: %d", ctx);
223 return;
224 }
225
226 renderspu_SystemMakeCurrent( window, nativeWindow, context );
227 if (!context->everCurrent) {
228 /* print OpenGL info */
229 const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS );
230 /*
231 crDebug( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
232 */
233 crInfo( "Render SPU: GL_VENDOR: %s", render_spu.ws.glGetString( GL_VENDOR ) );
234 crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) );
235 crInfo( "Render SPU: GL_VERSION: %s", render_spu.ws.glGetString( GL_VERSION ) );
236 crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
237 if (crStrstr(extString, "GL_ARB_window_pos"))
238 context->haveWindowPosARB = GL_TRUE;
239 else
240 context->haveWindowPosARB = GL_FALSE;
241 context->everCurrent = GL_TRUE;
242 }
243 if (crWindow == 0 && window->mapPending &&
244 !render_spu.render_to_app_window && !render_spu.render_to_crut_window) {
245 /* Window[0] is special, it's the default window and normally hidden.
246 * If the mapPending flag is set, then we should now make the window
247 * visible.
248 */
249 /*renderspu_SystemShowWindow( window, GL_TRUE );*/
250 window->mapPending = GL_FALSE;
251 }
252 window->everCurrent = GL_TRUE;
253 }
254 else
255 {
256#ifdef CHROMIUM_THREADSAFE
257 crSetTSD(&_RenderTSD, NULL);
258#else
259 render_spu.currentContext = NULL;
260#endif
261 }
262}
263
264
265/*
266 * Window functions
267 */
268
269GLint RENDER_APIENTRY
270renderspuWindowCreate( const char *dpyName, GLint visBits )
271{
272 WindowInfo *window;
273 VisualInfo *visual;
274 GLboolean showIt;
275
276 if (!dpyName || crStrlen(render_spu.display_string) > 0)
277 dpyName = render_spu.display_string;
278
279 visual = renderspuFindVisual( dpyName, visBits );
280 if (!visual)
281 {
282 crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
283 return -1;
284 }
285
286 /* Allocate WindowInfo */
287 window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
288 if (!window)
289 {
290 crWarning( "Render SPU: Couldn't create a window" );
291 return -1;
292 }
293
294 crHashtableAdd(render_spu.windowTable, render_spu.window_id, window);
295 window->id = render_spu.window_id;
296 render_spu.window_id++;
297
298 window->x = render_spu.defaultX;
299 window->y = render_spu.defaultY;
300 window->width = render_spu.defaultWidth;
301 window->height = render_spu.defaultHeight;
302
303 if (render_spu.force_hidden_wdn_create
304 || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
305 showIt = 0;
306 else
307 showIt = window->id > 0;
308
309 /* Set window->title, replacing %i with the window ID number */
310 {
311 const char *s = crStrstr(render_spu.window_title, "%i");
312 if (s) {
313 int i, j, k;
314 window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
315 for (i = 0; render_spu.window_title[i] != '%'; i++)
316 window->title[i] = render_spu.window_title[i];
317 k = sprintf(window->title + i, "%d", window->id);
318 CRASSERT(k < 10);
319 i++; /* skip the 'i' after the '%' */
320 j = i + k;
321 for (; (window->title[j] = s[i]) != 0; i++, j++)
322 ;
323 }
324 else {
325 window->title = crStrdup(render_spu.window_title);
326 }
327 }
328
329 /*
330 crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->id);
331 */
332 /* Have GLX/WGL/AGL create the window */
333 if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
334 {
335 crFree(window);
336 crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
337 return -1;
338 }
339
340 CRASSERT(window->visual == visual);
341
342 return window->id;
343}
344
345static void renderspuCheckCurrentCtxWindowCB(unsigned long key, void *data1, void *data2)
346{
347 ContextInfo *pCtx = (ContextInfo *) data1;
348 WindowInfo *pWindow = data2;
349 (void) key;
350
351 if (pCtx->currentWindow==pWindow)
352 {
353 renderspuMakeCurrent(0, 0, pCtx->id);
354 }
355}
356
357void
358RENDER_APIENTRY renderspuWindowDestroy( GLint win )
359{
360 WindowInfo *window;
361 GET_CONTEXT(pOldCtx);
362
363 CRASSERT(win >= 0);
364 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
365 if (window) {
366 crDebug("Render SPU: Destroy window (%d)", win);
367 renderspu_SystemDestroyWindow( window );
368 /* remove window info from hash table, and free it */
369 crHashtableDelete(render_spu.windowTable, win, crFree);
370
371 /* check if this window is bound to some ctx. Note: window pointer is already freed here */
372 crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
373
374 /* restore current context */
375 {
376 GET_CONTEXT(pNewCtx);
377 if (pNewCtx!=pOldCtx)
378 {
379 renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->id:0, 0,
380 pOldCtx ? pOldCtx->id:0);
381 }
382 }
383 }
384 else {
385 crDebug("Render SPU: Attempt to destroy invalid window (%d)", win);
386 }
387}
388
389
390static void RENDER_APIENTRY
391renderspuWindowSize( GLint win, GLint w, GLint h )
392{
393 WindowInfo *window;
394 CRASSERT(win >= 0);
395 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
396 if (window) {
397 renderspu_SystemWindowSize( window, w, h );
398 }
399 else {
400 crDebug("Render SPU: Attempt to resize invalid window (%d)", win);
401 }
402}
403
404
405static void RENDER_APIENTRY
406renderspuWindowPosition( GLint win, GLint x, GLint y )
407{
408 if (!render_spu.ignore_window_moves) {
409 WindowInfo *window;
410 CRASSERT(win >= 0);
411 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
412 if (window) {
413 renderspu_SystemWindowPosition( window, x, y );
414 window->x = x;
415 window->y = y;
416 }
417 else {
418 crDebug("Render SPU: Attempt to move invalid window (%d)", win);
419 }
420 }
421}
422
423static void RENDER_APIENTRY
424renderspuWindowVisibleRegion(GLint win, GLint cRects, GLint *pRects)
425{
426 WindowInfo *window;
427 CRASSERT(win >= 0);
428 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
429 if (window) {
430 renderspu_SystemWindowVisibleRegion( window, cRects, pRects );
431 }
432 else {
433 crDebug("Render SPU: Attempt to set VisibleRegion for invalid window (%d)", win);
434 }
435}
436
437static void RENDER_APIENTRY
438renderspuWindowShow( GLint win, GLint flag )
439{
440 WindowInfo *window;
441 CRASSERT(win >= 0);
442 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
443 if (window) {
444 if (window->nativeWindow) {
445 /* We're rendering back to the native app window instead of the
446 * new window which we (the Render SPU) created earlier.
447 * So, we never want to show the Render SPU's window.
448 */
449 flag = 0;
450 }
451 renderspu_SystemShowWindow( window, (GLboolean) flag );
452 }
453 else {
454 crDebug("Render SPU: Attempt to hide/show invalid window (%d)", win);
455 }
456}
457
458
459/*
460 * Set the current raster position to the given window coordinate.
461 */
462static void
463SetRasterPos( GLint winX, GLint winY )
464{
465 GLfloat fx, fy;
466
467 /* Push current matrix mode and viewport attributes */
468 render_spu.self.PushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
469
470 /* Setup projection parameters */
471 render_spu.self.MatrixMode( GL_PROJECTION );
472 render_spu.self.PushMatrix();
473 render_spu.self.LoadIdentity();
474 render_spu.self.MatrixMode( GL_MODELVIEW );
475 render_spu.self.PushMatrix();
476 render_spu.self.LoadIdentity();
477
478 render_spu.self.Viewport( winX - 1, winY - 1, 2, 2 );
479
480 /* set the raster (window) position */
481 /* huh ? */
482 fx = (GLfloat) (winX - (int) winX);
483 fy = (GLfloat) (winY - (int) winY);
484 render_spu.self.RasterPos4f( fx, fy, 0.0, 1.0 );
485
486 /* restore matrices, viewport and matrix mode */
487 render_spu.self.PopMatrix();
488 render_spu.self.MatrixMode( GL_PROJECTION );
489 render_spu.self.PopMatrix();
490
491 render_spu.self.PopAttrib();
492}
493
494
495/*
496 * Draw the mouse pointer bitmap at (x,y) in window coords.
497 */
498static void DrawCursor( GLint x, GLint y )
499{
500#define POINTER_WIDTH 32
501#define POINTER_HEIGHT 32
502 /* Somebody artistic could probably do better here */
503 static const char *pointerImage[POINTER_HEIGHT] =
504 {
505 "XX..............................",
506 "XXXX............................",
507 ".XXXXX..........................",
508 ".XXXXXXX........................",
509 "..XXXXXXXX......................",
510 "..XXXXXXXXXX....................",
511 "...XXXXXXXXXXX..................",
512 "...XXXXXXXXXXXXX................",
513 "....XXXXXXXXXXXXXX..............",
514 "....XXXXXXXXXXXXXXXX............",
515 ".....XXXXXXXXXXXXXXXXX..........",
516 ".....XXXXXXXXXXXXXXXXXXX........",
517 "......XXXXXXXXXXXXXXXXXXXX......",
518 "......XXXXXXXXXXXXXXXXXXXXXX....",
519 ".......XXXXXXXXXXXXXXXXXXXXXXX..",
520 ".......XXXXXXXXXXXXXXXXXXXXXXXX.",
521 "........XXXXXXXXXXXXX...........",
522 "........XXXXXXXX.XXXXX..........",
523 ".........XXXXXX...XXXXX.........",
524 ".........XXXXX.....XXXXX........",
525 "..........XXX.......XXXXX.......",
526 "..........XX.........XXXXX......",
527 "......................XXXXX.....",
528 ".......................XXXXX....",
529 "........................XXX.....",
530 ".........................X......",
531 "................................",
532 "................................",
533 "................................",
534 "................................",
535 "................................",
536 "................................"
537
538 };
539 static GLubyte pointerBitmap[POINTER_HEIGHT][POINTER_WIDTH / 8];
540 static GLboolean firstCall = GL_TRUE;
541 GLboolean lighting, depthTest, scissorTest;
542
543 if (firstCall) {
544 /* Convert pointerImage into pointerBitmap */
545 GLint i, j;
546 for (i = 0; i < POINTER_HEIGHT; i++) {
547 for (j = 0; j < POINTER_WIDTH; j++) {
548 if (pointerImage[POINTER_HEIGHT - i - 1][j] == 'X') {
549 GLubyte bit = 128 >> (j & 0x7);
550 pointerBitmap[i][j / 8] |= bit;
551 }
552 }
553 }
554 firstCall = GL_FALSE;
555 }
556
557 render_spu.self.GetBooleanv(GL_LIGHTING, &lighting);
558 render_spu.self.GetBooleanv(GL_DEPTH_TEST, &depthTest);
559 render_spu.self.GetBooleanv(GL_SCISSOR_TEST, &scissorTest);
560 render_spu.self.Disable(GL_LIGHTING);
561 render_spu.self.Disable(GL_DEPTH_TEST);
562 render_spu.self.Disable(GL_SCISSOR_TEST);
563 render_spu.self.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
564
565 render_spu.self.Color3f(1, 1, 1);
566
567 /* save current raster pos */
568 render_spu.self.PushAttrib(GL_CURRENT_BIT);
569 SetRasterPos(x, y);
570 render_spu.self.Bitmap(POINTER_WIDTH, POINTER_HEIGHT, 1.0, 31.0, 0, 0,
571 (const GLubyte *) pointerBitmap);
572 /* restore current raster pos */
573 render_spu.self.PopAttrib();
574
575 if (lighting)
576 render_spu.self.Enable(GL_LIGHTING);
577 if (depthTest)
578 render_spu.self.Enable(GL_DEPTH_TEST);
579 if (scissorTest)
580 render_spu.self.Enable(GL_SCISSOR_TEST);
581}
582
583void RENDER_APIENTRY renderspuSwapBuffers( GLint window, GLint flags )
584{
585 WindowInfo *w = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
586
587 if (!w)
588 {
589 crDebug("Render SPU: SwapBuffers invalid window id: %d", window);
590 return;
591 }
592
593 if (flags & CR_SUPPRESS_SWAP_BIT)
594 {
595 render_spu.self.Finish();
596 return;
597 }
598
599 if (render_spu.drawCursor)
600 DrawCursor( render_spu.cursorX, render_spu.cursorY );
601
602 if (render_spu.swap_master_url)
603 DoSync();
604
605 renderspu_SystemSwapBuffers( w, flags );
606}
607
608
609/*
610 * Barrier functions
611 * Normally, we'll have a crserver somewhere that handles the barrier calls.
612 * However, if we're running the render SPU on the client node, then we
613 * should handle barriers here. The threadtest demo illustrates this.
614 * If we have N threads calling using this SPU we need these barrier
615 * functions to synchronize them.
616 */
617
618static void RENDER_APIENTRY renderspuBarrierCreateCR( GLuint name, GLuint count )
619{
620 Barrier *b;
621
622 if (render_spu.ignore_papi)
623 return;
624
625 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
626 if (b) {
627 /* HACK -- this allows everybody to create a barrier, and all
628 but the first creation are ignored, assuming the count
629 match. */
630 if ( b->count != count ) {
631 crError( "Render SPU: Barrier name=%u created with count=%u, but already "
632 "exists with count=%u", name, count, b->count );
633 }
634 }
635 else {
636 b = (Barrier *) crAlloc( sizeof(Barrier) );
637 b->count = count;
638 crInitBarrier( &b->barrier, count );
639 crHashtableAdd( render_spu.barrierHash, name, b );
640 }
641}
642
643static void RENDER_APIENTRY renderspuBarrierDestroyCR( GLuint name )
644{
645 if (render_spu.ignore_papi)
646 return;
647 crHashtableDelete( render_spu.barrierHash, name, crFree );
648}
649
650static void RENDER_APIENTRY renderspuBarrierExecCR( GLuint name )
651{
652 Barrier *b;
653
654 if (render_spu.ignore_papi)
655 return;
656
657 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
658 if (b) {
659 crWaitBarrier( &(b->barrier) );
660 }
661 else {
662 crWarning("Render SPU: Bad barrier name %d in BarrierExec()", name);
663 }
664}
665
666
667/*
668 * Semaphore functions
669 * XXX we should probably implement these too, for the same reason as
670 * barriers (see above).
671 */
672
673static void RENDER_APIENTRY renderspuSemaphoreCreateCR( GLuint name, GLuint count )
674{
675 (void) name;
676 (void) count;
677}
678
679static void RENDER_APIENTRY renderspuSemaphoreDestroyCR( GLuint name )
680{
681 (void) name;
682}
683
684static void RENDER_APIENTRY renderspuSemaphorePCR( GLuint name )
685{
686 (void) name;
687}
688
689static void RENDER_APIENTRY renderspuSemaphoreVCR( GLuint name )
690{
691 (void) name;
692}
693
694
695/*
696 * Misc functions
697 */
698
699
700
701static void RENDER_APIENTRY renderspuChromiumParameteriCR(GLenum target, GLint value)
702{
703
704 switch (target)
705 {
706 case GL_HOST_WND_CREATED_HIDDEN:
707 render_spu.force_hidden_wdn_create = value ? GL_TRUE : GL_FALSE;
708 break;
709 default:
710// crWarning("Unhandled target in renderspuChromiumParameteriCR()");
711 break;
712 }
713}
714
715static void RENDER_APIENTRY
716renderspuChromiumParameterfCR(GLenum target, GLfloat value)
717{
718 (void) target;
719 (void) value;
720
721#if 0
722 switch (target) {
723 default:
724 crWarning("Unhandled target in renderspuChromiumParameterfCR()");
725 break;
726 }
727#endif
728}
729
730
731static void RENDER_APIENTRY
732renderspuChromiumParametervCR(GLenum target, GLenum type, GLsizei count,
733 const GLvoid *values)
734{
735 int client_num;
736 unsigned short port;
737 CRMessage *msg, pingback;
738 unsigned char *privbuf = NULL;
739
740 switch (target) {
741
742 case GL_GATHER_CONNECT_CR:
743 if (render_spu.gather_userbuf_size)
744 privbuf = (unsigned char *)crAlloc(1024*768*4);
745
746 port = ((GLint *) values)[0];
747
748 if (render_spu.gather_conns == NULL)
749 render_spu.gather_conns = crAlloc(render_spu.server->numClients*sizeof(CRConnection *));
750 else
751 {
752 crError("Oh bother! duplicate GL_GATHER_CONNECT_CR getting through");
753 }
754
755 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
756 {
757 switch (render_spu.server->clients[client_num]->conn->type)
758 {
759 case CR_TCPIP:
760 crDebug("Render SPU: AcceptClient from %s on %d",
761 render_spu.server->clients[client_num]->conn->hostname, render_spu.gather_port);
762 render_spu.gather_conns[client_num] =
763 crNetAcceptClient("tcpip", NULL, port, 1024*1024, 1);
764 break;
765
766 case CR_GM:
767 render_spu.gather_conns[client_num] =
768 crNetAcceptClient("gm", NULL, port, 1024*1024, 1);
769 break;
770
771 default:
772 crError("Render SPU: Unknown Network Type to Open Gather Connection");
773 }
774
775
776 if (render_spu.gather_userbuf_size)
777 {
778 render_spu.gather_conns[client_num]->userbuf = privbuf;
779 render_spu.gather_conns[client_num]->userbuf_len = render_spu.gather_userbuf_size;
780 }
781 else
782 {
783 render_spu.gather_conns[client_num]->userbuf = NULL;
784 render_spu.gather_conns[client_num]->userbuf_len = 0;
785 }
786
787 if (render_spu.gather_conns[client_num])
788 {
789 crDebug("Render SPU: success! from %s", render_spu.gather_conns[client_num]->hostname);
790 }
791 }
792
793 break;
794
795 case GL_GATHER_DRAWPIXELS_CR:
796 pingback.header.type = CR_MESSAGE_OOB;
797
798 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
799 {
800 crNetGetMessage(render_spu.gather_conns[client_num], &msg);
801 if (msg->header.type == CR_MESSAGE_GATHER)
802 {
803 crNetFree(render_spu.gather_conns[client_num], msg);
804 }
805 else
806 {
807 crError("Render SPU: expecting MESSAGE_GATHER. got crap! (%d of %d)",
808 client_num, render_spu.server->numClients-1);
809 }
810 }
811
812 /*
813 * We're only hitting the case if we're not actually calling
814 * child.SwapBuffers from readback, so a switch about which
815 * call to DoSync() we really want [this one, or the one
816 * in SwapBuffers above] is not necessary -- karl
817 */
818
819 if (render_spu.swap_master_url)
820 DoSync();
821
822 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
823 crNetSend(render_spu.gather_conns[client_num], NULL, &pingback,
824 sizeof(CRMessageHeader));
825
826 render_spu.self.RasterPos2i(((GLint *)values)[0], ((GLint *)values)[1]);
827 render_spu.self.DrawPixels( ((GLint *)values)[2], ((GLint *)values)[3],
828 ((GLint *)values)[4], ((GLint *)values)[5],
829 render_spu.gather_conns[0]->userbuf);
830
831
832 render_spu.self.SwapBuffers(((GLint *)values)[6], 0);
833 break;
834
835 case GL_CURSOR_POSITION_CR:
836 if (type == GL_INT && count == 2) {
837 render_spu.cursorX = ((GLint *) values)[0];
838 render_spu.cursorY = ((GLint *) values)[1];
839 crDebug("Render SPU: GL_CURSOR_POSITION_CR (%d, %d)", render_spu.cursorX, render_spu.cursorY);
840 }
841 else {
842 crWarning("Render SPU: Bad type or count for ChromiumParametervCR(GL_CURSOR_POSITION_CR)");
843 }
844 break;
845
846 case GL_WINDOW_SIZE_CR:
847 /* XXX this is old code that should be removed.
848 * NOTE: we can only resize the default (id=0) window!!!
849 */
850 {
851 GLint w, h;
852 WindowInfo *window;
853 CRASSERT(type == GL_INT);
854 CRASSERT(count == 2);
855 CRASSERT(values);
856 w = ((GLint*)values)[0];
857 h = ((GLint*)values)[1];
858 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, 0);
859 if (window)
860 {
861 renderspu_SystemWindowSize(window, w, h);
862 }
863 }
864 break;
865
866 default:
867#if 0
868 crWarning("Unhandled target in renderspuChromiumParametervCR(0x%x)", (int) target);
869#endif
870 break;
871 }
872}
873
874
875static void RENDER_APIENTRY
876renderspuGetChromiumParametervCR(GLenum target, GLuint index, GLenum type,
877 GLsizei count, GLvoid *values)
878{
879 switch (target) {
880 case GL_WINDOW_SIZE_CR:
881 {
882 GLint x, y, w, h, *size = (GLint *) values;
883 WindowInfo *window;
884 CRASSERT(type == GL_INT);
885 CRASSERT(count == 2);
886 CRASSERT(values);
887 size[0] = size[1] = 0; /* default */
888 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
889 if (window)
890 {
891 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
892 size[0] = w;
893 size[1] = h;
894 }
895 }
896 break;
897 case GL_WINDOW_POSITION_CR:
898 /* return window position, as a screen coordinate */
899 {
900 GLint *pos = (GLint *) values;
901 GLint x, y, w, h;
902 WindowInfo *window;
903 CRASSERT(type == GL_INT);
904 CRASSERT(count == 2);
905 CRASSERT(values);
906 pos[0] = pos[1] = 0; /* default */
907 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
908 if (window)
909 {
910 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
911 pos[0] = x;/*window->x;*/
912 pos[1] = y;/*window->y;*/
913 }
914 }
915 break;
916 case GL_MAX_WINDOW_SIZE_CR:
917 {
918 GLint *maxSize = (GLint *) values;
919 WindowInfo *window;
920 CRASSERT(type == GL_INT);
921 CRASSERT(count == 2);
922 CRASSERT(values);
923 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
924 if (window)
925 {
926 renderspu_SystemGetMaxWindowSize(window, maxSize + 0, maxSize + 1);
927 }
928 }
929 break;
930 default:
931 ; /* nothing - silence compiler */
932 }
933}
934
935
936static void RENDER_APIENTRY
937renderspuBoundsInfoCR( CRrecti *bounds, GLbyte *payload, GLint len,
938 GLint num_opcodes )
939{
940 (void) bounds;
941 (void) payload;
942 (void) len;
943 (void) num_opcodes;
944 /* draw the bounding box */
945 if (render_spu.draw_bbox) {
946 GET_CONTEXT(context);
947 WindowInfo *window = context->currentWindow;
948 GLint x, y, w, h;
949
950 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
951
952 render_spu.self.PushMatrix();
953 render_spu.self.LoadIdentity();
954 render_spu.self.MatrixMode(GL_PROJECTION);
955 render_spu.self.PushMatrix();
956 render_spu.self.LoadIdentity();
957 render_spu.self.Ortho(0, w, 0, h, -1, 1);
958 render_spu.self.Color3f(1, 1, 1);
959 render_spu.self.Begin(GL_LINE_LOOP);
960 render_spu.self.Vertex2i(bounds->x1, bounds->y1);
961 render_spu.self.Vertex2i(bounds->x2, bounds->y1);
962 render_spu.self.Vertex2i(bounds->x2, bounds->y2);
963 render_spu.self.Vertex2i(bounds->x1, bounds->y2);
964 render_spu.self.End();
965 render_spu.self.PopMatrix();
966 render_spu.self.MatrixMode(GL_MODELVIEW);
967 render_spu.self.PopMatrix();
968 }
969}
970
971
972static void RENDER_APIENTRY
973renderspuWriteback( GLint *writeback )
974{
975 (void) writeback;
976}
977
978
979static void
980remove_trailing_space(char *s)
981{
982 int k = crStrlen(s);
983 while (k > 0 && s[k-1] == ' ')
984 k--;
985 s[k] = 0;
986}
987
988static const GLubyte * RENDER_APIENTRY
989renderspuGetString(GLenum pname)
990{
991 static char tempStr[1000];
992 GET_CONTEXT(context);
993
994 if (pname == GL_EXTENSIONS)
995 {
996 const char *nativeExt;
997 char *crExt, *s1, *s2;
998
999 if (!render_spu.ws.glGetString)
1000 return NULL;
1001
1002 nativeExt = (const char *) render_spu.ws.glGetString(GL_EXTENSIONS);
1003 if (!nativeExt) {
1004 /* maybe called w/out current context. */
1005 return NULL;
1006 }
1007
1008 crExt = crStrjoin3(crExtensions, " ", crAppOnlyExtensions);
1009 s1 = crStrIntersect(nativeExt, crExt);
1010 remove_trailing_space(s1);
1011 s2 = crStrjoin3(s1, " ", crChromiumExtensions);
1012 remove_trailing_space(s2);
1013 crFree(crExt);
1014 crFree(s1);
1015 if (context->extensionString)
1016 crFree(context->extensionString);
1017 context->extensionString = s2;
1018 return (const GLubyte *) s2;
1019 }
1020 else if (pname == GL_VENDOR)
1021 return (const GLubyte *) CR_VENDOR;
1022 else if (pname == GL_VERSION)
1023 return render_spu.ws.glGetString(GL_VERSION);
1024 else if (pname == GL_RENDERER) {
1025#ifdef VBOX
1026 snprintf(tempStr, sizeof(tempStr), "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1027#else
1028 sprintf(tempStr, "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1029#endif
1030 return (const GLubyte *) tempStr;
1031 }
1032#ifdef CR_OPENGL_VERSION_2_0
1033 else if (pname == GL_SHADING_LANGUAGE_VERSION)
1034 return render_spu.ws.glGetString(GL_SHADING_LANGUAGE_VERSION);
1035#endif
1036#ifdef GL_CR_real_vendor_strings
1037 else if (pname == GL_REAL_VENDOR)
1038 return render_spu.ws.glGetString(GL_VENDOR);
1039 else if (pname == GL_REAL_VERSION)
1040 return render_spu.ws.glGetString(GL_VERSION);
1041 else if (pname == GL_REAL_RENDERER)
1042 return render_spu.ws.glGetString(GL_RENDERER);
1043 else if (pname == GL_REAL_EXTENSIONS)
1044 return render_spu.ws.glGetString(GL_EXTENSIONS);
1045#endif
1046 else
1047 return NULL;
1048}
1049
1050DECLEXPORT(void) renderspuReparentWindow(GLint window)
1051{
1052 WindowInfo *pWindow;
1053 CRASSERT(window >= 0);
1054
1055 pWindow = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
1056
1057 if (!pWindow)
1058 {
1059 crDebug("Render SPU: Attempt to reparent invalid window (%d)", window);
1060 return;
1061 }
1062
1063 renderspu_SystemReparentWindow(pWindow);
1064}
1065
1066#if defined(DARWIN)
1067# ifdef VBOX_WITH_COCOA_QT
1068void renderspuFlush()
1069{
1070 renderspu_SystemFlush();
1071}
1072
1073void renderspuFinish()
1074{
1075 renderspu_SystemFinish();
1076}
1077
1078void renderspuBindFramebufferEXT(GLenum target, GLuint framebuffer)
1079{
1080 renderspu_SystemBindFramebufferEXT(target, framebuffer);
1081}
1082
1083void renderspuCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1084{
1085 renderspu_SystemCopyPixels(x, y, width, height, type);
1086}
1087
1088void renderspuGetIntegerv(GLenum pname, GLint * params)
1089{
1090 renderspu_SystemGetIntegerv(pname, params);
1091}
1092
1093void renderspuDrawBuffer(GLenum mode)
1094{
1095 renderspu_SystemDrawBuffer(mode);
1096}
1097
1098void renderspuReadBuffer(GLenum mode)
1099{
1100 renderspu_SystemReadBuffer(mode);
1101}
1102# endif
1103#endif
1104
1105#define FILLIN( NAME, FUNC ) \
1106 table[i].name = crStrdup(NAME); \
1107 table[i].fn = (SPUGenericFunction) FUNC; \
1108 i++;
1109
1110
1111/* These are the functions which the render SPU implements, not OpenGL.
1112 */
1113int
1114renderspuCreateFunctions(SPUNamedFunctionTable table[])
1115{
1116 int i = 0;
1117 FILLIN( "SwapBuffers", renderspuSwapBuffers );
1118 FILLIN( "CreateContext", renderspuCreateContext );
1119 FILLIN( "DestroyContext", renderspuDestroyContext );
1120 FILLIN( "MakeCurrent", renderspuMakeCurrent );
1121 FILLIN( "WindowCreate", renderspuWindowCreate );
1122 FILLIN( "WindowDestroy", renderspuWindowDestroy );
1123 FILLIN( "WindowSize", renderspuWindowSize );
1124 FILLIN( "WindowPosition", renderspuWindowPosition );
1125 FILLIN( "WindowVisibleRegion", renderspuWindowVisibleRegion );
1126 FILLIN( "WindowShow", renderspuWindowShow );
1127 FILLIN( "BarrierCreateCR", renderspuBarrierCreateCR );
1128 FILLIN( "BarrierDestroyCR", renderspuBarrierDestroyCR );
1129 FILLIN( "BarrierExecCR", renderspuBarrierExecCR );
1130 FILLIN( "BoundsInfoCR", renderspuBoundsInfoCR );
1131 FILLIN( "SemaphoreCreateCR", renderspuSemaphoreCreateCR );
1132 FILLIN( "SemaphoreDestroyCR", renderspuSemaphoreDestroyCR );
1133 FILLIN( "SemaphorePCR", renderspuSemaphorePCR );
1134 FILLIN( "SemaphoreVCR", renderspuSemaphoreVCR );
1135 FILLIN( "Writeback", renderspuWriteback );
1136 FILLIN( "ChromiumParameteriCR", renderspuChromiumParameteriCR );
1137 FILLIN( "ChromiumParameterfCR", renderspuChromiumParameterfCR );
1138 FILLIN( "ChromiumParametervCR", renderspuChromiumParametervCR );
1139 FILLIN( "GetChromiumParametervCR", renderspuGetChromiumParametervCR );
1140 FILLIN( "GetString", renderspuGetString );
1141#if defined(DARWIN)
1142# ifdef VBOX_WITH_COCOA_QT
1143 FILLIN( "Flush", renderspuFlush );
1144 FILLIN( "Finish", renderspuFinish );
1145 FILLIN( "BindFramebufferEXT", renderspuBindFramebufferEXT );
1146 FILLIN( "CopyPixels", renderspuCopyPixels );
1147 FILLIN( "GetIntegerv", renderspuGetIntegerv );
1148 FILLIN( "ReadBuffer", renderspuReadBuffer );
1149 FILLIN( "DrawBuffer", renderspuDrawBuffer );
1150# endif
1151#endif
1152 return i;
1153}
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