VirtualBox

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

最後變更 在這個檔案從43182是 41929,由 vboxsync 提交於 13 年 前

crOpenGL,wddm/3d: create windows hidden initially to avoid flikering

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette