VirtualBox

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

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

crOpenGL/glx: additional fixes

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