VirtualBox

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

Last change on this file since 27708 was 27708, checked in by vboxsync, 15 years ago

crOpenGL: some initial support for new multimonitor code

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