VirtualBox

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

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

crOpenGL: host 3d window repaint impl for Win host; enable offscreen rendering for Win; 3D window repaint generics

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 44.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 "cr_environment.h"
13#include "renderspu.h"
14#include "cr_extstring.h"
15
16
17static void
18DoSync(void)
19{
20 CRMessage *in, out;
21
22 out.header.type = CR_MESSAGE_OOB;
23
24 if (render_spu.is_swap_master)
25 {
26 int a;
27
28 for (a = 0; a < render_spu.num_swap_clients; a++)
29 {
30 crNetGetMessage( render_spu.swap_conns[a], &in );
31 crNetFree( render_spu.swap_conns[a], in);
32 }
33
34 for (a = 0; a < render_spu.num_swap_clients; a++)
35 crNetSend( render_spu.swap_conns[a], NULL, &out, sizeof(CRMessage));
36 }
37 else
38 {
39 crNetSend( render_spu.swap_conns[0], NULL, &out, sizeof(CRMessage));
40
41 crNetGetMessage( render_spu.swap_conns[0], &in );
42 crNetFree( render_spu.swap_conns[0], in);
43 }
44}
45
46
47
48/*
49 * Visual functions
50 */
51
52/**
53 * used for debugging and giving info to the user.
54 */
55void
56renderspuMakeVisString( GLbitfield visAttribs, char *s )
57{
58 s[0] = 0;
59
60 if (visAttribs & CR_RGB_BIT)
61 crStrcat(s, "RGB");
62 if (visAttribs & CR_ALPHA_BIT)
63 crStrcat(s, "A");
64 if (visAttribs & CR_DOUBLE_BIT)
65 crStrcat(s, ", Doublebuffer");
66 if (visAttribs & CR_STEREO_BIT)
67 crStrcat(s, ", Stereo");
68 if (visAttribs & CR_DEPTH_BIT)
69 crStrcat(s, ", Z");
70 if (visAttribs & CR_STENCIL_BIT)
71 crStrcat(s, ", Stencil");
72 if (visAttribs & CR_ACCUM_BIT)
73 crStrcat(s, ", Accum");
74 if (visAttribs & CR_MULTISAMPLE_BIT)
75 crStrcat(s, ", Multisample");
76 if (visAttribs & CR_OVERLAY_BIT)
77 crStrcat(s, ", Overlay");
78 if (visAttribs & CR_PBUFFER_BIT)
79 crStrcat(s, ", PBuffer");
80}
81
82
83/*
84 * Find a VisualInfo which matches the given display name and attribute
85 * bitmask, or return a pointer to a new visual.
86 */
87VisualInfo *
88renderspuFindVisual(const char *displayName, GLbitfield visAttribs)
89{
90 int i;
91
92 if (!displayName)
93 displayName = "";
94
95 /* first, try to find a match */
96#if defined(WINDOWS) || defined(DARWIN)
97 for (i = 0; i < render_spu.numVisuals; i++) {
98 if (visAttribs == render_spu.visuals[i].visAttribs) {
99 return &(render_spu.visuals[i]);
100 }
101 }
102#elif defined(GLX)
103 for (i = 0; i < render_spu.numVisuals; i++) {
104 if (crStrcmp(displayName, render_spu.visuals[i].displayName) == 0
105 && visAttribs == render_spu.visuals[i].visAttribs) {
106 return &(render_spu.visuals[i]);
107 }
108 }
109#endif
110
111 if (render_spu.numVisuals >= MAX_VISUALS)
112 {
113 crWarning("Render SPU: Couldn't create a visual, too many visuals already");
114 return NULL;
115 }
116
117 /* create a new visual */
118 i = render_spu.numVisuals;
119 render_spu.visuals[i].displayName = crStrdup(displayName);
120 render_spu.visuals[i].visAttribs = visAttribs;
121 if (renderspu_SystemInitVisual(&(render_spu.visuals[i]))) {
122 render_spu.numVisuals++;
123 return &(render_spu.visuals[i]);
124 }
125 else {
126 crWarning("Render SPU: Couldn't get a visual, renderspu_SystemInitVisual failed");
127 return NULL;
128 }
129}
130
131static ContextInfo * renderspuCreateContextInternal(const char *dpyName, GLint visBits, GLint idCtx, ContextInfo * sharedContext)
132{
133 ContextInfo *context;
134 VisualInfo *visual;
135
136 if (idCtx <= 0)
137 {
138 idCtx = (GLint)crHashtableAllocKeys(render_spu.contextTable, 1);
139 if (idCtx <= 0)
140 {
141 crWarning("failed to allocate context id");
142 return NULL;
143 }
144 }
145 else
146 {
147 if (crHashtableIsKeyUsed(render_spu.contextTable, idCtx))
148 {
149 crWarning("the specified ctx key %d is in use", idCtx);
150 return NULL;
151 }
152 }
153
154
155 if (!dpyName || crStrlen(render_spu.display_string)>0)
156 dpyName = render_spu.display_string;
157
158 visual = renderspuFindVisual(dpyName, visBits);
159 if (!visual)
160 return NULL;
161
162 context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
163 if (!context)
164 return NULL;
165 context->BltInfo.Base.id = idCtx;
166 context->shared = sharedContext;
167 if (!renderspu_SystemCreateContext(visual, context, sharedContext))
168 return NULL;
169
170 crHashtableAdd(render_spu.contextTable, idCtx, context);
171
172 context->BltInfo.Base.visualBits = visual->visAttribs;
173 /*
174 crDebug("Render SPU: CreateContext(%s, 0x%x) returning %d",
175 dpyName, visBits, context->BltInfo.Base.id);
176 */
177
178 return context;
179}
180
181GLint renderspuCreateContextEx(const char *dpyName, GLint visBits, GLint id, GLint shareCtx)
182{
183 ContextInfo *context, *sharedContext = NULL;
184
185 if (shareCtx) {
186 sharedContext
187 = (ContextInfo *) crHashtableSearch(render_spu.contextTable, shareCtx);
188 CRASSERT(sharedContext);
189 }
190
191 context = renderspuCreateContextInternal(dpyName, visBits, id, sharedContext);
192 if (context)
193 return context->BltInfo.Base.id;
194 return -1;
195}
196
197/*
198 * Context functions
199 */
200
201GLint RENDER_APIENTRY
202renderspuCreateContext(const char *dpyName, GLint visBits, GLint shareCtx)
203{
204 return renderspuCreateContextEx(dpyName, visBits, 0, shareCtx);
205}
206
207static void RENDER_APIENTRY
208renderspuDestroyContext( GLint ctx )
209{
210 ContextInfo *context, *curCtx;
211
212 CRASSERT(ctx);
213
214 if (ctx == CR_RENDER_DEFAULT_CONTEXT_ID)
215 {
216 crWarning("request to destroy a default context, ignoring");
217 return;
218 }
219
220 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
221 CRASSERT(context);
222
223 curCtx = GET_CONTEXT_VAL();
224 CRASSERT(curCtx);
225 if (curCtx == context)
226 {
227 renderspuMakeCurrent( CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID );
228 curCtx = GET_CONTEXT_VAL();
229 Assert(curCtx);
230 Assert(curCtx != context);
231 }
232
233 renderspu_SystemDestroyContext( context );
234 if (context->extensionString) {
235 crFree(context->extensionString);
236 context->extensionString = NULL;
237 }
238 crHashtableDelete(render_spu.contextTable, ctx, crFree);
239}
240
241
242void RENDER_APIENTRY
243renderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
244{
245 WindowInfo *window;
246 ContextInfo *context;
247
248 /*
249 crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx);
250 */
251
252 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow);
253 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
254
255 if (window && context)
256 {
257#ifdef CHROMIUM_THREADSAFE
258 crSetTSD(&_RenderTSD, context);
259#else
260 render_spu.currentContext = context;
261#endif
262 context->currentWindow = window;
263 if (!window)
264 {
265 crDebug("Render SPU: MakeCurrent invalid window id: %d", crWindow);
266 return;
267 }
268 if (!context)
269 {
270 crDebug("Render SPU: MakeCurrent invalid context id: %d", ctx);
271 return;
272 }
273
274 renderspu_SystemMakeCurrent( window, nativeWindow, context );
275 if (!context->everCurrent) {
276 /* print OpenGL info */
277 const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS );
278 /*
279 crDebug( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
280 */
281 crInfo( "Render SPU: GL_VENDOR: %s", render_spu.ws.glGetString( GL_VENDOR ) );
282 crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) );
283 crInfo( "Render SPU: GL_VERSION: %s", render_spu.ws.glGetString( GL_VERSION ) );
284 crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
285 if (crStrstr(extString, "GL_ARB_window_pos"))
286 context->haveWindowPosARB = GL_TRUE;
287 else
288 context->haveWindowPosARB = GL_FALSE;
289 context->everCurrent = GL_TRUE;
290 }
291 if (crWindow == CR_RENDER_DEFAULT_WINDOW_ID && window->mapPending &&
292 !render_spu.render_to_app_window && !render_spu.render_to_crut_window) {
293 /* Window[CR_RENDER_DEFAULT_CONTEXT_ID] is special, it's the default window and normally hidden.
294 * If the mapPending flag is set, then we should now make the window
295 * visible.
296 */
297 /*renderspu_SystemShowWindow( window, GL_TRUE );*/
298 window->mapPending = GL_FALSE;
299 }
300 window->everCurrent = GL_TRUE;
301 }
302 else if (!crWindow && !ctx)
303 {
304#ifdef CHROMIUM_THREADSAFE
305 crSetTSD(&_RenderTSD, NULL);
306#else
307 render_spu.currentContext = NULL;
308#endif
309 renderspu_SystemMakeCurrent( NULL, 0, NULL );
310 }
311 else
312 {
313 crError("renderspuMakeCurrent invalid ids: crWindow(%d), ctx(%d)", crWindow, ctx);
314 }
315}
316
317
318/*
319 * Window functions
320 */
321
322GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
323{
324 WindowInfo *window;
325 VisualInfo *visual;
326 GLboolean showIt;
327
328 if (id <= 0)
329 {
330 id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
331 if (id <= 0)
332 {
333 crWarning("failed to allocate window id");
334 return -1;
335 }
336 }
337 else
338 {
339 if (crHashtableIsKeyUsed(render_spu.windowTable, id))
340 {
341 crWarning("the specified window key %d is in use", id);
342 return -1;
343 }
344 }
345
346
347 if (!dpyName || crStrlen(render_spu.display_string) > 0)
348 dpyName = render_spu.display_string;
349
350 visual = renderspuFindVisual( dpyName, visBits );
351 if (!visual)
352 {
353 crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
354 return -1;
355 }
356
357 /* Allocate WindowInfo */
358 window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
359 if (!window)
360 {
361 crWarning( "Render SPU: Couldn't create a window" );
362 return -1;
363 }
364
365 RTCritSectInit(&window->CompositorLock);
366 window->pCompositor = NULL;
367
368 crHashtableAdd(render_spu.windowTable, id, window);
369 window->BltInfo.Base.id = id;
370
371 window->x = render_spu.defaultX;
372 window->y = render_spu.defaultY;
373 window->BltInfo.width = render_spu.defaultWidth;
374 window->BltInfo.height = render_spu.defaultHeight;
375
376 if (render_spu.force_hidden_wdn_create
377 || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
378 showIt = 0;
379 else
380 showIt = window->BltInfo.Base.id != CR_RENDER_DEFAULT_WINDOW_ID;
381
382 /* Set window->title, replacing %i with the window ID number */
383 {
384 const char *s = crStrstr(render_spu.window_title, "%i");
385 if (s) {
386 int i, j, k;
387 window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
388 for (i = 0; render_spu.window_title[i] != '%'; i++)
389 window->title[i] = render_spu.window_title[i];
390 k = sprintf(window->title + i, "%d", window->BltInfo.Base.id);
391 CRASSERT(k < 10);
392 i++; /* skip the 'i' after the '%' */
393 j = i + k;
394 for (; (window->title[j] = s[i]) != 0; i++, j++)
395 ;
396 }
397 else {
398 window->title = crStrdup(render_spu.window_title);
399 }
400 }
401
402 /*
403 crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
404 */
405 /* Have GLX/WGL/AGL create the window */
406 if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
407 {
408 crFree(window);
409 crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
410 return -1;
411 }
412
413 CRASSERT(window->visual == visual);
414
415 window->BltInfo.Base.visualBits = visual->visAttribs;
416
417 return window->BltInfo.Base.id;
418}
419
420GLint RENDER_APIENTRY
421renderspuWindowCreate( const char *dpyName, GLint visBits )
422{
423 return renderspuWindowCreateEx( dpyName, visBits, 0 );
424}
425
426static void renderspuCheckCurrentCtxWindowCB(unsigned long key, void *data1, void *data2)
427{
428 ContextInfo *pCtx = (ContextInfo *) data1;
429 WindowInfo *pWindow = data2;
430 (void) key;
431
432 if (pCtx->currentWindow==pWindow)
433 {
434 renderspuMakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, pCtx->BltInfo.Base.id);
435 pCtx->currentWindow=0;
436 }
437}
438
439void
440RENDER_APIENTRY renderspuWindowDestroy( GLint win )
441{
442 WindowInfo *window;
443 GET_CONTEXT(pOldCtx);
444
445 CRASSERT(win >= 0);
446 if (win == CR_RENDER_DEFAULT_WINDOW_ID)
447 {
448 crWarning("request to destroy a default mural, ignoring");
449 return;
450 }
451 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
452 if (window) {
453 crDebug("Render SPU: Destroy window (%d)", win);
454 renderspu_SystemDestroyWindow( window );
455
456 RTCritSectDelete(&window->CompositorLock);
457 window->pCompositor = NULL;
458
459 /* remove window info from hash table, and free it */
460 crHashtableDelete(render_spu.windowTable, win, crFree);
461
462 /* check if this window is bound to some ctx. Note: window pointer is already freed here */
463 crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
464
465 /* restore current context */
466 {
467 GET_CONTEXT(pNewCtx);
468 if (pNewCtx!=pOldCtx)
469 {
470 renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
471 pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
472 }
473 }
474 }
475 else {
476 crDebug("Render SPU: Attempt to destroy invalid window (%d)", win);
477 }
478}
479
480
481static void RENDER_APIENTRY
482renderspuWindowSize( GLint win, GLint w, GLint h )
483{
484 WindowInfo *window;
485 CRASSERT(win >= 0);
486 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
487 if (window) {
488 renderspu_SystemWindowSize( window, w, h );
489 window->BltInfo.width = w;
490 window->BltInfo.height = h;
491 }
492 else {
493 crDebug("Render SPU: Attempt to resize invalid window (%d)", win);
494 }
495}
496
497
498static void RENDER_APIENTRY
499renderspuWindowPosition( GLint win, GLint x, GLint y )
500{
501 if (!render_spu.ignore_window_moves) {
502 WindowInfo *window;
503 CRASSERT(win >= 0);
504 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
505 if (window) {
506 renderspu_SystemWindowPosition( window, x, y );
507 window->x = x;
508 window->y = y;
509 }
510 else {
511 crDebug("Render SPU: Attempt to move invalid window (%d)", win);
512 }
513 }
514}
515
516static void RENDER_APIENTRY
517renderspuWindowVisibleRegion(GLint win, GLint cRects, GLint *pRects)
518{
519 WindowInfo *window;
520 CRASSERT(win >= 0);
521 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
522 if (window) {
523 renderspu_SystemWindowVisibleRegion( window, cRects, pRects );
524 }
525 else {
526 crDebug("Render SPU: Attempt to set VisibleRegion for invalid window (%d)", win);
527 }
528}
529
530static void RENDER_APIENTRY
531renderspuWindowShow( GLint win, GLint flag )
532{
533 WindowInfo *window;
534 CRASSERT(win >= 0);
535 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
536 if (window) {
537 if (window->nativeWindow) {
538 /* We're rendering back to the native app window instead of the
539 * new window which we (the Render SPU) created earlier.
540 * So, we never want to show the Render SPU's window.
541 */
542 flag = 0;
543 }
544 renderspu_SystemShowWindow( window, (GLboolean) flag );
545 }
546 else {
547 crDebug("Render SPU: Attempt to hide/show invalid window (%d)", win);
548 }
549}
550
551static void RENDER_APIENTRY
552renderspuVBoxPresentComposition( GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
553{
554 WindowInfo *window;
555 CRASSERT(win >= 0);
556 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
557 if (window) {
558 renderspuVBoxCompositorSet( window, pCompositor);
559 /* renderspuVBoxPresentComposition can be invoked from the chromium thread only and is not reentrant,
560 * no need to acquire a compositor lock here */
561 renderspu_SystemVBoxPresentComposition(window, pCompositor, pChangedEntry);
562 }
563 else {
564 crDebug("Render SPU: Attempt to PresentComposition for invalid window (%d)", win);
565 }
566}
567
568void renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)
569{
570 VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
571 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
572 CrVrScrCompositorIterInit(pCompositor, &CIter);
573 while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
574 {
575 uint32_t cRegions;
576 const RTRECT *paSrcRegions, *paDstRegions;
577 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions);
578 if (RT_SUCCESS(rc))
579 {
580 uint32_t i;
581 for (i = 0; i < pEntry->cRects; ++i)
582 {
583 RTRECT DstRect;
584 DstRect.xLeft = paDstRegions[i].xLeft * scaleX;
585 DstRect.yTop = paDstRegions[i].yTop * scaleY;
586 DstRect.xRight = paDstRegions[i].xRight * scaleX;
587 DstRect.yBottom = paDstRegions[i].yBottom * scaleY;
588 CrBltBlitTexMural(pBlitter, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, CRBLT_F_LINEAR);
589 }
590 }
591 else
592 {
593 crWarning("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
594 }
595 }
596}
597
598void renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)
599{
600 VBOXVR_SCR_COMPOSITOR_ITERATOR CIter;
601 PVBOXVR_SCR_COMPOSITOR_ENTRY pEntry;
602 CrVrScrCompositorIterInit(pCompositor, &CIter);
603 while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
604 {
605 uint32_t cRegions;
606 const RTRECT *paSrcRegions, *paDstRegions;
607 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions);
608 if (RT_SUCCESS(rc))
609 {
610 CrBltBlitTexMural(pBlitter, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, CRBLT_F_LINEAR);
611 }
612 else
613 {
614 crWarning("Blit: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
615 }
616 }
617}
618
619PCR_BLITTER renderspuVBoxPresentBlitterGet( WindowInfo *window )
620{
621 PCR_BLITTER pBlitter = window->pBlitter;
622 if (!pBlitter)
623 {
624 if (render_spu.blitterTable)
625 {
626 crHashtableLock(render_spu.blitterTable);
627 pBlitter = (PCR_BLITTER)crHashtableSearch(render_spu.blitterTable, window->visual->visAttribs);
628 }
629
630 if (!pBlitter)
631 {
632 int rc;
633 CR_BLITTER_CONTEXT ctx;
634 pBlitter = (PCR_BLITTER)crCalloc(sizeof (*pBlitter));
635 if (!pBlitter)
636 {
637 crWarning("failed to allocate blitter");
638 return NULL;
639 }
640
641 /* @todo: this is the assumption that crserverlib uses context 1 as a default one
642 * need to do it in a more proper way */
643 ctx.Base.id = 1;
644 ctx.Base.visualBits = window->visual->visAttribs;
645 rc = CrBltInit(pBlitter, &ctx, true, render_spu.blitterDispatch);
646 if (!RT_SUCCESS(rc))
647 {
648 crWarning("CrBltInit failed, rc %d", rc);
649 crFree(pBlitter);
650 return NULL;
651 }
652
653 if (render_spu.blitterTable)
654 {
655 crHashtableAdd( render_spu.blitterTable, window->visual->visAttribs, pBlitter );
656 }
657 }
658
659 if (render_spu.blitterTable)
660 crHashtableUnlock(render_spu.blitterTable);
661
662 Assert(pBlitter);
663 window->pBlitter = pBlitter;
664 }
665
666 CrBltMuralSetCurrent(pBlitter, &window->BltInfo);
667 return pBlitter;
668}
669
670int renderspuVBoxPresentBlitterEnter( PCR_BLITTER pBlitter )
671{
672 int rc;
673 PCR_BLITTER_CONTEXT pCtxInfo = NULL;
674 PCR_BLITTER_WINDOW pWindowInfo = NULL;
675 GET_CONTEXT(pCtx);
676
677 if (pCtx)
678 {
679 if (pCtx->currentWindow)
680 {
681 pCtxInfo = &pCtx->BltInfo;
682 pWindowInfo = &pCtx->currentWindow->BltInfo;
683 }
684 }
685
686 rc = CrBltEnter(pBlitter, pCtxInfo, pWindowInfo);
687 if (!RT_SUCCESS(rc))
688 {
689 crWarning("CrBltEnter failed, rc %d", rc);
690 return rc;
691 }
692 return VINF_SUCCESS;
693}
694
695PCR_BLITTER renderspuVBoxPresentBlitterGetAndEnter( WindowInfo *window )
696{
697 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGet(window);
698 if (pBlitter)
699 {
700 int rc = renderspuVBoxPresentBlitterEnter(pBlitter);
701 if (RT_SUCCESS(rc))
702 {
703 return pBlitter;
704 }
705 }
706 return NULL;
707}
708
709PCR_BLITTER renderspuVBoxPresentBlitterEnsureCreated( WindowInfo *window )
710{
711 if (!window->pBlitter)
712 {
713 struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor;
714 /* just use compositor lock to synchronize */
715 pTmpCompositor = renderspuVBoxCompositorAcquire(window);
716 CRASSERT(pTmpCompositor);
717 if (pTmpCompositor)
718 {
719 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGet( window );
720 if (pBlitter)
721 {
722 if (!CrBltIsEverEntered(pBlitter))
723 {
724 int rc = renderspuVBoxPresentBlitterEnter(pBlitter);
725 if (RT_SUCCESS(rc))
726 {
727 CrBltLeave(pBlitter);
728 }
729 else
730 {
731 crWarning("renderspuVBoxPresentBlitterEnter failed rc %d", rc);
732 }
733 }
734 }
735 else
736 {
737 crWarning("renderspuVBoxPresentBlitterGet failed");
738 }
739
740 renderspuVBoxCompositorRelease(window);
741 }
742 else
743 {
744 crWarning("renderspuVBoxCompositorAcquire failed");
745 }
746 }
747 return window->pBlitter;
748}
749
750void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
751{
752 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGetAndEnter(window);
753 if (!pBlitter)
754 return;
755
756 renderspuVBoxCompositorBlit(pCompositor, pBlitter);
757
758 renderspu_SystemSwapBuffers(window, 0);
759
760 CrBltLeave(pBlitter);
761}
762
763void renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor)
764{
765 int rc;
766 /* renderspuVBoxCompositorSet can be invoked from the chromium thread only and is not reentrant,
767 * no need to synch here
768 * the lock is actually needed to ensure we're in synch with the redraw thread */
769 if (window->pCompositor == pCompositor)
770 return;
771 rc = RTCritSectEnter(&window->CompositorLock);
772 if (RT_SUCCESS(rc))
773 {
774 window->pCompositor = pCompositor;
775 RTCritSectLeave(&window->CompositorLock);
776 return;
777 }
778 else
779 {
780 crWarning("RTCritSectEnter failed rc %d", rc);
781 }
782}
783
784struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)
785{
786 int rc = RTCritSectEnter(&window->CompositorLock);
787 if (RT_SUCCESS(rc))
788 {
789 VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;
790 if (pCompositor)
791 return pCompositor;
792
793 /* if no compositor is set, release the lock and return */
794 RTCritSectLeave(&window->CompositorLock);
795 }
796 else
797 {
798 crWarning("RTCritSectEnter failed rc %d", rc);
799 }
800 return NULL;
801}
802
803int renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
804{
805 int rc = RTCritSectTryEnter(&window->CompositorLock);
806 if (RT_SUCCESS(rc))
807 {
808 *ppCompositor = window->pCompositor;
809 if (*ppCompositor)
810 return VINF_SUCCESS;
811
812 /* if no compositor is set, release the lock and return */
813 RTCritSectLeave(&window->CompositorLock);
814 rc = VERR_INVALID_STATE;
815 }
816 else
817 {
818 *ppCompositor = NULL;
819 crWarning("RTCritSectTryEnter failed rc %d", rc);
820 }
821 return rc;
822}
823
824void renderspuVBoxCompositorRelease( WindowInfo *window)
825{
826 int rc;
827 Assert(window->pCompositor);
828 rc = RTCritSectLeave(&window->CompositorLock);
829 if (!RT_SUCCESS(rc))
830 {
831 crWarning("RTCritSectLeave failed rc %d", rc);
832 }
833}
834
835
836/*
837 * Set the current raster position to the given window coordinate.
838 */
839static void
840SetRasterPos( GLint winX, GLint winY )
841{
842 GLfloat fx, fy;
843
844 /* Push current matrix mode and viewport attributes */
845 render_spu.self.PushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
846
847 /* Setup projection parameters */
848 render_spu.self.MatrixMode( GL_PROJECTION );
849 render_spu.self.PushMatrix();
850 render_spu.self.LoadIdentity();
851 render_spu.self.MatrixMode( GL_MODELVIEW );
852 render_spu.self.PushMatrix();
853 render_spu.self.LoadIdentity();
854
855 render_spu.self.Viewport( winX - 1, winY - 1, 2, 2 );
856
857 /* set the raster (window) position */
858 /* huh ? */
859 fx = (GLfloat) (winX - (int) winX);
860 fy = (GLfloat) (winY - (int) winY);
861 render_spu.self.RasterPos4f( fx, fy, 0.0, 1.0 );
862
863 /* restore matrices, viewport and matrix mode */
864 render_spu.self.PopMatrix();
865 render_spu.self.MatrixMode( GL_PROJECTION );
866 render_spu.self.PopMatrix();
867
868 render_spu.self.PopAttrib();
869}
870
871
872/*
873 * Draw the mouse pointer bitmap at (x,y) in window coords.
874 */
875static void DrawCursor( GLint x, GLint y )
876{
877#define POINTER_WIDTH 32
878#define POINTER_HEIGHT 32
879 /* Somebody artistic could probably do better here */
880 static const char *pointerImage[POINTER_HEIGHT] =
881 {
882 "XX..............................",
883 "XXXX............................",
884 ".XXXXX..........................",
885 ".XXXXXXX........................",
886 "..XXXXXXXX......................",
887 "..XXXXXXXXXX....................",
888 "...XXXXXXXXXXX..................",
889 "...XXXXXXXXXXXXX................",
890 "....XXXXXXXXXXXXXX..............",
891 "....XXXXXXXXXXXXXXXX............",
892 ".....XXXXXXXXXXXXXXXXX..........",
893 ".....XXXXXXXXXXXXXXXXXXX........",
894 "......XXXXXXXXXXXXXXXXXXXX......",
895 "......XXXXXXXXXXXXXXXXXXXXXX....",
896 ".......XXXXXXXXXXXXXXXXXXXXXXX..",
897 ".......XXXXXXXXXXXXXXXXXXXXXXXX.",
898 "........XXXXXXXXXXXXX...........",
899 "........XXXXXXXX.XXXXX..........",
900 ".........XXXXXX...XXXXX.........",
901 ".........XXXXX.....XXXXX........",
902 "..........XXX.......XXXXX.......",
903 "..........XX.........XXXXX......",
904 "......................XXXXX.....",
905 ".......................XXXXX....",
906 "........................XXX.....",
907 ".........................X......",
908 "................................",
909 "................................",
910 "................................",
911 "................................",
912 "................................",
913 "................................"
914
915 };
916 static GLubyte pointerBitmap[POINTER_HEIGHT][POINTER_WIDTH / 8];
917 static GLboolean firstCall = GL_TRUE;
918 GLboolean lighting, depthTest, scissorTest;
919
920 if (firstCall) {
921 /* Convert pointerImage into pointerBitmap */
922 GLint i, j;
923 for (i = 0; i < POINTER_HEIGHT; i++) {
924 for (j = 0; j < POINTER_WIDTH; j++) {
925 if (pointerImage[POINTER_HEIGHT - i - 1][j] == 'X') {
926 GLubyte bit = 128 >> (j & 0x7);
927 pointerBitmap[i][j / 8] |= bit;
928 }
929 }
930 }
931 firstCall = GL_FALSE;
932 }
933
934 render_spu.self.GetBooleanv(GL_LIGHTING, &lighting);
935 render_spu.self.GetBooleanv(GL_DEPTH_TEST, &depthTest);
936 render_spu.self.GetBooleanv(GL_SCISSOR_TEST, &scissorTest);
937 render_spu.self.Disable(GL_LIGHTING);
938 render_spu.self.Disable(GL_DEPTH_TEST);
939 render_spu.self.Disable(GL_SCISSOR_TEST);
940 render_spu.self.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
941
942 render_spu.self.Color3f(1, 1, 1);
943
944 /* save current raster pos */
945 render_spu.self.PushAttrib(GL_CURRENT_BIT);
946 SetRasterPos(x, y);
947 render_spu.self.Bitmap(POINTER_WIDTH, POINTER_HEIGHT, 1.0, 31.0, 0, 0,
948 (const GLubyte *) pointerBitmap);
949 /* restore current raster pos */
950 render_spu.self.PopAttrib();
951
952 if (lighting)
953 render_spu.self.Enable(GL_LIGHTING);
954 if (depthTest)
955 render_spu.self.Enable(GL_DEPTH_TEST);
956 if (scissorTest)
957 render_spu.self.Enable(GL_SCISSOR_TEST);
958}
959
960void RENDER_APIENTRY renderspuSwapBuffers( GLint window, GLint flags )
961{
962 WindowInfo *w = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
963
964 if (!w)
965 {
966 crDebug("Render SPU: SwapBuffers invalid window id: %d", window);
967 return;
968 }
969
970 if (flags & CR_SUPPRESS_SWAP_BIT)
971 {
972 render_spu.self.Finish();
973 return;
974 }
975
976 if (render_spu.drawCursor)
977 DrawCursor( render_spu.cursorX, render_spu.cursorY );
978
979 if (render_spu.swap_master_url)
980 DoSync();
981
982 renderspu_SystemSwapBuffers( w, flags );
983}
984
985
986/*
987 * Barrier functions
988 * Normally, we'll have a crserver somewhere that handles the barrier calls.
989 * However, if we're running the render SPU on the client node, then we
990 * should handle barriers here. The threadtest demo illustrates this.
991 * If we have N threads calling using this SPU we need these barrier
992 * functions to synchronize them.
993 */
994
995static void RENDER_APIENTRY renderspuBarrierCreateCR( GLuint name, GLuint count )
996{
997 Barrier *b;
998
999 if (render_spu.ignore_papi)
1000 return;
1001
1002 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
1003 if (b) {
1004 /* HACK -- this allows everybody to create a barrier, and all
1005 but the first creation are ignored, assuming the count
1006 match. */
1007 if ( b->count != count ) {
1008 crError( "Render SPU: Barrier name=%u created with count=%u, but already "
1009 "exists with count=%u", name, count, b->count );
1010 }
1011 }
1012 else {
1013 b = (Barrier *) crAlloc( sizeof(Barrier) );
1014 b->count = count;
1015 crInitBarrier( &b->barrier, count );
1016 crHashtableAdd( render_spu.barrierHash, name, b );
1017 }
1018}
1019
1020static void RENDER_APIENTRY renderspuBarrierDestroyCR( GLuint name )
1021{
1022 if (render_spu.ignore_papi)
1023 return;
1024 crHashtableDelete( render_spu.barrierHash, name, crFree );
1025}
1026
1027static void RENDER_APIENTRY renderspuBarrierExecCR( GLuint name )
1028{
1029 Barrier *b;
1030
1031 if (render_spu.ignore_papi)
1032 return;
1033
1034 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
1035 if (b) {
1036 crWaitBarrier( &(b->barrier) );
1037 }
1038 else {
1039 crWarning("Render SPU: Bad barrier name %d in BarrierExec()", name);
1040 }
1041}
1042
1043
1044/*
1045 * Semaphore functions
1046 * XXX we should probably implement these too, for the same reason as
1047 * barriers (see above).
1048 */
1049
1050static void RENDER_APIENTRY renderspuSemaphoreCreateCR( GLuint name, GLuint count )
1051{
1052 (void) name;
1053 (void) count;
1054}
1055
1056static void RENDER_APIENTRY renderspuSemaphoreDestroyCR( GLuint name )
1057{
1058 (void) name;
1059}
1060
1061static void RENDER_APIENTRY renderspuSemaphorePCR( GLuint name )
1062{
1063 (void) name;
1064}
1065
1066static void RENDER_APIENTRY renderspuSemaphoreVCR( GLuint name )
1067{
1068 (void) name;
1069}
1070
1071
1072/*
1073 * Misc functions
1074 */
1075
1076
1077
1078static void RENDER_APIENTRY renderspuChromiumParameteriCR(GLenum target, GLint value)
1079{
1080
1081 switch (target)
1082 {
1083 case GL_HOST_WND_CREATED_HIDDEN:
1084 render_spu.force_hidden_wdn_create = value ? GL_TRUE : GL_FALSE;
1085 break;
1086 default:
1087// crWarning("Unhandled target in renderspuChromiumParameteriCR()");
1088 break;
1089 }
1090}
1091
1092static void RENDER_APIENTRY
1093renderspuChromiumParameterfCR(GLenum target, GLfloat value)
1094{
1095 (void) target;
1096 (void) value;
1097
1098#if 0
1099 switch (target) {
1100 default:
1101 crWarning("Unhandled target in renderspuChromiumParameterfCR()");
1102 break;
1103 }
1104#endif
1105}
1106
1107
1108static void RENDER_APIENTRY
1109renderspuChromiumParametervCR(GLenum target, GLenum type, GLsizei count,
1110 const GLvoid *values)
1111{
1112 int client_num;
1113 unsigned short port;
1114 CRMessage *msg, pingback;
1115 unsigned char *privbuf = NULL;
1116
1117 switch (target) {
1118
1119 case GL_GATHER_CONNECT_CR:
1120 if (render_spu.gather_userbuf_size)
1121 privbuf = (unsigned char *)crAlloc(1024*768*4);
1122
1123 port = ((GLint *) values)[0];
1124
1125 if (render_spu.gather_conns == NULL)
1126 render_spu.gather_conns = crAlloc(render_spu.server->numClients*sizeof(CRConnection *));
1127 else
1128 {
1129 crError("Oh bother! duplicate GL_GATHER_CONNECT_CR getting through");
1130 }
1131
1132 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1133 {
1134 switch (render_spu.server->clients[client_num]->conn->type)
1135 {
1136 case CR_TCPIP:
1137 crDebug("Render SPU: AcceptClient from %s on %d",
1138 render_spu.server->clients[client_num]->conn->hostname, render_spu.gather_port);
1139 render_spu.gather_conns[client_num] =
1140 crNetAcceptClient("tcpip", NULL, port, 1024*1024, 1);
1141 break;
1142
1143 case CR_GM:
1144 render_spu.gather_conns[client_num] =
1145 crNetAcceptClient("gm", NULL, port, 1024*1024, 1);
1146 break;
1147
1148 default:
1149 crError("Render SPU: Unknown Network Type to Open Gather Connection");
1150 }
1151
1152
1153 if (render_spu.gather_userbuf_size)
1154 {
1155 render_spu.gather_conns[client_num]->userbuf = privbuf;
1156 render_spu.gather_conns[client_num]->userbuf_len = render_spu.gather_userbuf_size;
1157 }
1158 else
1159 {
1160 render_spu.gather_conns[client_num]->userbuf = NULL;
1161 render_spu.gather_conns[client_num]->userbuf_len = 0;
1162 }
1163
1164 if (render_spu.gather_conns[client_num])
1165 {
1166 crDebug("Render SPU: success! from %s", render_spu.gather_conns[client_num]->hostname);
1167 }
1168 }
1169
1170 break;
1171
1172 case GL_GATHER_DRAWPIXELS_CR:
1173 pingback.header.type = CR_MESSAGE_OOB;
1174
1175 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1176 {
1177 crNetGetMessage(render_spu.gather_conns[client_num], &msg);
1178 if (msg->header.type == CR_MESSAGE_GATHER)
1179 {
1180 crNetFree(render_spu.gather_conns[client_num], msg);
1181 }
1182 else
1183 {
1184 crError("Render SPU: expecting MESSAGE_GATHER. got crap! (%d of %d)",
1185 client_num, render_spu.server->numClients-1);
1186 }
1187 }
1188
1189 /*
1190 * We're only hitting the case if we're not actually calling
1191 * child.SwapBuffers from readback, so a switch about which
1192 * call to DoSync() we really want [this one, or the one
1193 * in SwapBuffers above] is not necessary -- karl
1194 */
1195
1196 if (render_spu.swap_master_url)
1197 DoSync();
1198
1199 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1200 crNetSend(render_spu.gather_conns[client_num], NULL, &pingback,
1201 sizeof(CRMessageHeader));
1202
1203 render_spu.self.RasterPos2i(((GLint *)values)[0], ((GLint *)values)[1]);
1204 render_spu.self.DrawPixels( ((GLint *)values)[2], ((GLint *)values)[3],
1205 ((GLint *)values)[4], ((GLint *)values)[5],
1206 render_spu.gather_conns[0]->userbuf);
1207
1208
1209 render_spu.self.SwapBuffers(((GLint *)values)[6], 0);
1210 break;
1211
1212 case GL_CURSOR_POSITION_CR:
1213 if (type == GL_INT && count == 2) {
1214 render_spu.cursorX = ((GLint *) values)[0];
1215 render_spu.cursorY = ((GLint *) values)[1];
1216 crDebug("Render SPU: GL_CURSOR_POSITION_CR (%d, %d)", render_spu.cursorX, render_spu.cursorY);
1217 }
1218 else {
1219 crWarning("Render SPU: Bad type or count for ChromiumParametervCR(GL_CURSOR_POSITION_CR)");
1220 }
1221 break;
1222
1223 case GL_WINDOW_SIZE_CR:
1224 /* XXX this is old code that should be removed.
1225 * NOTE: we can only resize the default (id=CR_RENDER_DEFAULT_WINDOW_ID) window!!!
1226 */
1227 {
1228 GLint w, h;
1229 WindowInfo *window;
1230 CRASSERT(type == GL_INT);
1231 CRASSERT(count == 2);
1232 CRASSERT(values);
1233 w = ((GLint*)values)[0];
1234 h = ((GLint*)values)[1];
1235 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, CR_RENDER_DEFAULT_WINDOW_ID);
1236 if (window)
1237 {
1238 renderspu_SystemWindowSize(window, w, h);
1239 }
1240 }
1241 break;
1242
1243 default:
1244#if 0
1245 crWarning("Unhandled target in renderspuChromiumParametervCR(0x%x)", (int) target);
1246#endif
1247 break;
1248 }
1249}
1250
1251
1252static void RENDER_APIENTRY
1253renderspuGetChromiumParametervCR(GLenum target, GLuint index, GLenum type,
1254 GLsizei count, GLvoid *values)
1255{
1256 switch (target) {
1257 case GL_WINDOW_SIZE_CR:
1258 {
1259 GLint x, y, w, h, *size = (GLint *) values;
1260 WindowInfo *window;
1261 CRASSERT(type == GL_INT);
1262 CRASSERT(count == 2);
1263 CRASSERT(values);
1264 size[0] = size[1] = 0; /* default */
1265 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1266 if (window)
1267 {
1268 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1269 size[0] = w;
1270 size[1] = h;
1271 }
1272 }
1273 break;
1274 case GL_WINDOW_POSITION_CR:
1275 /* return window position, as a screen coordinate */
1276 {
1277 GLint *pos = (GLint *) values;
1278 GLint x, y, w, h;
1279 WindowInfo *window;
1280 CRASSERT(type == GL_INT);
1281 CRASSERT(count == 2);
1282 CRASSERT(values);
1283 pos[0] = pos[1] = 0; /* default */
1284 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1285 if (window)
1286 {
1287 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1288 pos[0] = x;/*window->x;*/
1289 pos[1] = y;/*window->y;*/
1290 }
1291 }
1292 break;
1293 case GL_MAX_WINDOW_SIZE_CR:
1294 {
1295 GLint *maxSize = (GLint *) values;
1296 WindowInfo *window;
1297 CRASSERT(type == GL_INT);
1298 CRASSERT(count == 2);
1299 CRASSERT(values);
1300 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1301 if (window)
1302 {
1303 renderspu_SystemGetMaxWindowSize(window, maxSize + 0, maxSize + 1);
1304 }
1305 }
1306 break;
1307 default:
1308 ; /* nothing - silence compiler */
1309 }
1310}
1311
1312
1313static void RENDER_APIENTRY
1314renderspuBoundsInfoCR( CRrecti *bounds, GLbyte *payload, GLint len,
1315 GLint num_opcodes )
1316{
1317 (void) bounds;
1318 (void) payload;
1319 (void) len;
1320 (void) num_opcodes;
1321 /* draw the bounding box */
1322 if (render_spu.draw_bbox) {
1323 GET_CONTEXT(context);
1324 WindowInfo *window = context->currentWindow;
1325 GLint x, y, w, h;
1326
1327 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1328
1329 render_spu.self.PushMatrix();
1330 render_spu.self.LoadIdentity();
1331 render_spu.self.MatrixMode(GL_PROJECTION);
1332 render_spu.self.PushMatrix();
1333 render_spu.self.LoadIdentity();
1334 render_spu.self.Ortho(0, w, 0, h, -1, 1);
1335 render_spu.self.Color3f(1, 1, 1);
1336 render_spu.self.Begin(GL_LINE_LOOP);
1337 render_spu.self.Vertex2i(bounds->x1, bounds->y1);
1338 render_spu.self.Vertex2i(bounds->x2, bounds->y1);
1339 render_spu.self.Vertex2i(bounds->x2, bounds->y2);
1340 render_spu.self.Vertex2i(bounds->x1, bounds->y2);
1341 render_spu.self.End();
1342 render_spu.self.PopMatrix();
1343 render_spu.self.MatrixMode(GL_MODELVIEW);
1344 render_spu.self.PopMatrix();
1345 }
1346}
1347
1348
1349static void RENDER_APIENTRY
1350renderspuWriteback( GLint *writeback )
1351{
1352 (void) writeback;
1353}
1354
1355
1356static void
1357remove_trailing_space(char *s)
1358{
1359 int k = crStrlen(s);
1360 while (k > 0 && s[k-1] == ' ')
1361 k--;
1362 s[k] = 0;
1363}
1364
1365static const GLubyte * RENDER_APIENTRY
1366renderspuGetString(GLenum pname)
1367{
1368 static char tempStr[1000];
1369 GET_CONTEXT(context);
1370
1371 if (pname == GL_EXTENSIONS)
1372 {
1373 const char *nativeExt;
1374 char *crExt, *s1, *s2;
1375
1376 if (!render_spu.ws.glGetString)
1377 return NULL;
1378
1379 nativeExt = (const char *) render_spu.ws.glGetString(GL_EXTENSIONS);
1380 if (!nativeExt) {
1381 /* maybe called w/out current context. */
1382 return NULL;
1383 }
1384
1385 crExt = crStrjoin3(crExtensions, " ", crAppOnlyExtensions);
1386 s1 = crStrIntersect(nativeExt, crExt);
1387 remove_trailing_space(s1);
1388 s2 = crStrjoin3(s1, " ", crChromiumExtensions);
1389 remove_trailing_space(s2);
1390 crFree(crExt);
1391 crFree(s1);
1392 if (context->extensionString)
1393 crFree(context->extensionString);
1394 context->extensionString = s2;
1395 return (const GLubyte *) s2;
1396 }
1397 else if (pname == GL_VENDOR)
1398 return (const GLubyte *) CR_VENDOR;
1399 else if (pname == GL_VERSION)
1400 return render_spu.ws.glGetString(GL_VERSION);
1401 else if (pname == GL_RENDERER) {
1402#ifdef VBOX
1403 snprintf(tempStr, sizeof(tempStr), "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1404#else
1405 sprintf(tempStr, "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1406#endif
1407 return (const GLubyte *) tempStr;
1408 }
1409#ifdef CR_OPENGL_VERSION_2_0
1410 else if (pname == GL_SHADING_LANGUAGE_VERSION)
1411 return render_spu.ws.glGetString(GL_SHADING_LANGUAGE_VERSION);
1412#endif
1413#ifdef GL_CR_real_vendor_strings
1414 else if (pname == GL_REAL_VENDOR)
1415 return render_spu.ws.glGetString(GL_VENDOR);
1416 else if (pname == GL_REAL_VERSION)
1417 return render_spu.ws.glGetString(GL_VERSION);
1418 else if (pname == GL_REAL_RENDERER)
1419 return render_spu.ws.glGetString(GL_RENDERER);
1420 else if (pname == GL_REAL_EXTENSIONS)
1421 return render_spu.ws.glGetString(GL_EXTENSIONS);
1422#endif
1423 else
1424 return NULL;
1425}
1426
1427DECLEXPORT(void) renderspuReparentWindow(GLint window)
1428{
1429 WindowInfo *pWindow;
1430 CRASSERT(window >= 0);
1431
1432 pWindow = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
1433
1434 if (!pWindow)
1435 {
1436 crDebug("Render SPU: Attempt to reparent invalid window (%d)", window);
1437 return;
1438 }
1439
1440 renderspu_SystemReparentWindow(pWindow);
1441}
1442
1443#define FILLIN( NAME, FUNC ) \
1444 table[i].name = crStrdup(NAME); \
1445 table[i].fn = (SPUGenericFunction) FUNC; \
1446 i++;
1447
1448
1449/* These are the functions which the render SPU implements, not OpenGL.
1450 */
1451int
1452renderspuCreateFunctions(SPUNamedFunctionTable table[])
1453{
1454 int i = 0;
1455 FILLIN( "SwapBuffers", renderspuSwapBuffers );
1456 FILLIN( "CreateContext", renderspuCreateContext );
1457 FILLIN( "DestroyContext", renderspuDestroyContext );
1458 FILLIN( "MakeCurrent", renderspuMakeCurrent );
1459 FILLIN( "WindowCreate", renderspuWindowCreate );
1460 FILLIN( "WindowDestroy", renderspuWindowDestroy );
1461 FILLIN( "WindowSize", renderspuWindowSize );
1462 FILLIN( "WindowPosition", renderspuWindowPosition );
1463 FILLIN( "WindowVisibleRegion", renderspuWindowVisibleRegion );
1464 FILLIN( "WindowShow", renderspuWindowShow );
1465 FILLIN( "BarrierCreateCR", renderspuBarrierCreateCR );
1466 FILLIN( "BarrierDestroyCR", renderspuBarrierDestroyCR );
1467 FILLIN( "BarrierExecCR", renderspuBarrierExecCR );
1468 FILLIN( "BoundsInfoCR", renderspuBoundsInfoCR );
1469 FILLIN( "SemaphoreCreateCR", renderspuSemaphoreCreateCR );
1470 FILLIN( "SemaphoreDestroyCR", renderspuSemaphoreDestroyCR );
1471 FILLIN( "SemaphorePCR", renderspuSemaphorePCR );
1472 FILLIN( "SemaphoreVCR", renderspuSemaphoreVCR );
1473 FILLIN( "Writeback", renderspuWriteback );
1474 FILLIN( "ChromiumParameteriCR", renderspuChromiumParameteriCR );
1475 FILLIN( "ChromiumParameterfCR", renderspuChromiumParameterfCR );
1476 FILLIN( "ChromiumParametervCR", renderspuChromiumParametervCR );
1477 FILLIN( "GetChromiumParametervCR", renderspuGetChromiumParametervCR );
1478 FILLIN( "GetString", renderspuGetString );
1479 FILLIN( "VBoxPresentComposition", renderspuVBoxPresentComposition );
1480
1481 return i;
1482}
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