VirtualBox

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

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

crOpenGL: context destruction fix

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