VirtualBox

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

Last change on this file since 78196 was 78190, checked in by vboxsync, 6 years ago

Merge first stage of the Chromium cleanup from the branch:

  • r129818 (Remove VBOX_WITH_CR_DISPLAY_LISTS and accompanying code as it was disabled since r108676 and was never brought back (see ​bugref:3456 and ​bugref:8485))
  • r129819 (HostServices/SharedOpenGL: Remove unused main entry point from upstream server process based implementation)
  • r129820 (HostServices/SharedOpenGL: Started eliminating all backends other than HGCM. They are not used and probably wouldn't work anymore anyway)
  • r129821 (HostServices/SharedOpenGL,GuestHost/OpenGLAdditions/common/crOpenGL: Kill crTimer* API as it is not used anywhere)
  • r129822 (HostServices/SharedOpenGL,GuestHost/OpenGLAdditions/common/crOpenGL: Kill most from cr_process.h apart from two used methods)
  • r129823 (HostServices/SharedOpenGL,GuestHost/OpenGLAdditions/common/crOpenGL: Kill crList* API as it is unused)
  • r129824 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Kill crHullInteriorBox API as it is unused)
  • r129825 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Kill crWarpPoint API as it is unused)
  • r129826 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Kill CrSa* API as it is unused and not even compiled in)
  • r129827 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Kill cr_bbox.h as it is unused)
  • r129828 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove a few crParseUrl() two uses)
  • r129829 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove last crParseURL() use)
  • r129830 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove crParseURL())
  • r129831 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove VBOX_WITH_COCOA_QT and related code when not set as it is the default for years now and we don't support anything else anymore)
  • r129832 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused cr_logo.h)
  • r129833 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused crut_api.h and crut_clientapi.h)
  • r129834 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused cr_dmx.h)
  • r129835 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused cr_perf.h)
  • r129836 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove cr_rand.h and friends as it is not actively used anywhere)
  • r129837 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of all the swapped versions in the packer SPU, we never change endianess from guest to host and don't need it)
  • r129838 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove more swapper versions in the packer related code)
  • r129839 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove more swapper versions in the packer related code)
  • r129840 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused pack_pica.c)
  • r129841 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove more swapper versions in the packer related code)
  • r129842 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of cr_endianess.h and friends)
  • r129843 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of unused lowercase.py)
  • r129844 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of unused cr_calllists.h and friends)
  • r129845 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of completely unused idpool.c, not even compiled in)
  • r129846 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of unused cr_debugopcodes.h and friends)
  • r129847 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Make the cr_mem.h API inline and get rid of the implementation in the util library)
  • r129848 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of SPUOptions and related code as it is of no use for us)
  • r129849 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of cr_environment.h and friends and convert usage to RTEnv* APIs)
  • r129850 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of unused renderspu_agl.c)
  • r129851 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Remove unused code in cr_htable.h)
  • r129853 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Introduce a state paremeter for the unpacker workers instead of reyling on global variables, work in progress)
  • r129854 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Let the caller of crUnpack set up the initial state. This allows to get rid of the global return_ptr and writeback_ptr as they get supplied in the unpacker state by the server)
  • r129855 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of the cr_lastDispatch and cr_unpackDispatch as they are of no use now)
  • r129856 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Get rid of the global cr_unpackData and cr_unpackDataEnd symbols by indtroducing another hack to make it possible for certail server dispatch callbacks to access the data buffer)
  • r129857 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: build fix for release builds)
  • r129858 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Make the pointer to the unpacker state non const (is required for the access verification))
  • r129859 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: First iteration of the buffer size validation to prevent out of bound read access + added todos for places where additional checks are needed)
  • r129860 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Working on remaining verification todos)
  • r129861 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Working on remaining verification todos)
  • r129871 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Working on remaining verification todos)
  • r129872 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Stop as soon as the unpacker encountered an error)
  • r129876 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Working on remaining verification todos)
  • r129880 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Working on remaining verification todos)
  • r129882 (HostServices/SharedOpenGL,GuestHost/OpenGL,Additions/common/crOpenGL: Fixed some offsets in unpack_texture.c, 3DMark03 renders correctly again)
  • r130013 (HostServices/SharedOpenGL: Convert files to C++ so we can use C99 featuers on Windows with cl.exe)
  • r130014 (HostServices/SharedOpenGL,GuestHost/OpenGL: WIndows build fixes)
  • r130015 (HostServices/SharedOpenGL,GuestHost/OpenGL: More Windows build fixes)
  • r130036 (Config.kmk: Fix linker error on Windows by temporarily disabling the use of VBoxGuestR3DllMinW2K)
  • r130094 (src/VBox/GuestHost/OpenGL: Revert inlining the allocation/free functions in R3 completely as it doesn't work on Windows if memory is allocated and freed across different DLLs which don't share a common CRT, causes crashes in RtlValidtaeHeap())
  • r130095 (src/VBox/GuestHost/OpenGL,src/VBox/Additions/common/crOpenGL/pack: Don't use floating point specifiers in packspu_GetString() to avoid R6002 errors (couldn't fully understand why they occur suddenly after the rework but this gets rid of it))
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 56.7 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_string.h"
8#include "cr_error.h"
9#include "cr_mem.h"
10#include "cr_spu.h"
11#include "renderspu.h"
12#include "cr_extstring.h"
13
14#include <iprt/asm.h>
15
16#include <stdio.h> /*sprintf*/
17
18uint32_t renderspuContextRelease(ContextInfo *context);
19uint32_t renderspuContextRetain(ContextInfo *context);
20
21static void
22DoSync(void)
23{
24 CRMessage *in, out;
25
26 out.header.type = CR_MESSAGE_OOB;
27
28 crNetSend( render_spu.swap_conns[0], NULL, &out, sizeof(CRMessage));
29
30 crNetGetMessage( render_spu.swap_conns[0], &in );
31 crNetFree( render_spu.swap_conns[0], in);
32}
33
34
35
36/*
37 * Visual functions
38 */
39
40/**
41 * used for debugging and giving info to the user.
42 */
43void
44renderspuMakeVisString( GLbitfield visAttribs, char *s )
45{
46 s[0] = 0;
47
48 if (visAttribs & CR_RGB_BIT)
49 crStrcat(s, "RGB");
50 if (visAttribs & CR_ALPHA_BIT)
51 crStrcat(s, "A");
52 if (visAttribs & CR_DOUBLE_BIT)
53 crStrcat(s, ", Doublebuffer");
54 if (visAttribs & CR_STEREO_BIT)
55 crStrcat(s, ", Stereo");
56 if (visAttribs & CR_DEPTH_BIT)
57 crStrcat(s, ", Z");
58 if (visAttribs & CR_STENCIL_BIT)
59 crStrcat(s, ", Stencil");
60 if (visAttribs & CR_ACCUM_BIT)
61 crStrcat(s, ", Accum");
62 if (visAttribs & CR_MULTISAMPLE_BIT)
63 crStrcat(s, ", Multisample");
64 if (visAttribs & CR_OVERLAY_BIT)
65 crStrcat(s, ", Overlay");
66 if (visAttribs & CR_PBUFFER_BIT)
67 crStrcat(s, ", PBuffer");
68}
69
70GLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs)
71{
72 pVisInfo->displayName = crStrdup(displayName);
73 pVisInfo->visAttribs = visAttribs;
74 return renderspu_SystemInitVisual(pVisInfo);
75}
76
77/*
78 * Find a VisualInfo which matches the given display name and attribute
79 * bitmask, or return a pointer to a new visual.
80 */
81VisualInfo *
82renderspuFindVisual(const char *displayName, GLbitfield visAttribs)
83{
84 int i;
85
86 if (!displayName)
87 displayName = "";
88
89 /* first, try to find a match */
90#if defined(WINDOWS) || defined(DARWIN)
91 for (i = 0; i < render_spu.numVisuals; i++) {
92 if (visAttribs == render_spu.visuals[i].visAttribs) {
93 return &(render_spu.visuals[i]);
94 }
95 }
96#elif defined(GLX)
97 for (i = 0; i < render_spu.numVisuals; i++) {
98 if (crStrcmp(displayName, render_spu.visuals[i].displayName) == 0
99 && visAttribs == render_spu.visuals[i].visAttribs) {
100 return &(render_spu.visuals[i]);
101 }
102 }
103#endif
104
105 if (render_spu.numVisuals >= MAX_VISUALS)
106 {
107 crWarning("Render SPU: Couldn't create a visual, too many visuals already");
108 return NULL;
109 }
110
111 /* create a new visual */
112 i = render_spu.numVisuals;
113 if (renderspuInitVisual(&(render_spu.visuals[i]), displayName, visAttribs)) {
114 render_spu.numVisuals++;
115 return &(render_spu.visuals[i]);
116 }
117 else {
118 crWarning("Render SPU: Couldn't get a visual, renderspu_SystemInitVisual failed");
119 return NULL;
120 }
121}
122
123static ContextInfo * renderspuCreateContextInternal(const char *dpyName, GLint visBits, GLint idCtx, ContextInfo * sharedContext)
124{
125 ContextInfo *context;
126 VisualInfo *visual;
127
128 if (idCtx <= 0)
129 {
130 idCtx = (GLint)crHashtableAllocKeys(render_spu.contextTable, 1);
131 if (idCtx <= 0)
132 {
133 crWarning("failed to allocate context id");
134 return NULL;
135 }
136 }
137 else
138 {
139 if (crHashtableIsKeyUsed(render_spu.contextTable, idCtx))
140 {
141 crWarning("the specified ctx key %d is in use", idCtx);
142 return NULL;
143 }
144 }
145
146
147 if (!dpyName || crStrlen(render_spu.display_string)>0)
148 dpyName = render_spu.display_string;
149
150 visual = renderspuFindVisual(dpyName, visBits);
151 if (!visual)
152 return NULL;
153
154 context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
155 if (!context)
156 return NULL;
157 context->BltInfo.Base.id = idCtx;
158 context->shared = sharedContext;
159 if (!renderspu_SystemCreateContext(visual, context, sharedContext))
160 return NULL;
161
162 crHashtableAdd(render_spu.contextTable, idCtx, context);
163
164 context->BltInfo.Base.visualBits = visual->visAttribs;
165 /*
166 crDebug("Render SPU: CreateContext(%s, 0x%x) returning %d",
167 dpyName, visBits, context->BltInfo.Base.id);
168 */
169
170 if (sharedContext)
171 renderspuContextRetain(sharedContext);
172
173 context->cRefs = 1;
174
175 return context;
176}
177
178GLint renderspuCreateContextEx(const char *dpyName, GLint visBits, GLint id, GLint shareCtx)
179{
180 ContextInfo *context, *sharedContext = NULL;
181
182 if (shareCtx) {
183 sharedContext
184 = (ContextInfo *) crHashtableSearch(render_spu.contextTable, shareCtx);
185 CRASSERT(sharedContext);
186 }
187
188 context = renderspuCreateContextInternal(dpyName, visBits, id, sharedContext);
189 if (context)
190 return context->BltInfo.Base.id;
191 return -1;
192}
193
194/*
195 * Context functions
196 */
197
198GLint RENDER_APIENTRY
199renderspuCreateContext(const char *dpyName, GLint visBits, GLint shareCtx)
200{
201 return renderspuCreateContextEx(dpyName, visBits, 0, shareCtx);
202}
203
204static void renderspuDestroyContextTerminate( ContextInfo *context )
205{
206 CRASSERT(context->BltInfo.Base.id == -1);
207 renderspu_SystemDestroyContext( context );
208 if (context->extensionString) {
209 crFree(context->extensionString);
210 context->extensionString = NULL;
211 }
212
213 if (context->shared)
214 renderspuContextRelease( context->shared );
215
216 crFree(context);
217}
218
219uint32_t renderspuContextRetain( ContextInfo *context )
220{
221 Assert(context->cRefs);
222 return ASMAtomicIncU32(&context->cRefs);
223}
224
225uint32_t renderspuContextRelease( ContextInfo *context )
226{
227 uint32_t cRefs = ASMAtomicDecU32(&context->cRefs);
228 if (!cRefs)
229 renderspuDestroyContextTerminate( context );
230 else
231 CRASSERT(cRefs < UINT32_MAX/2);
232 return cRefs;
233}
234
235uint32_t renderspuContextMarkDeletedAndRelease( ContextInfo *context )
236{
237 /* invalidate the context id to mark it as deleted */
238 context->BltInfo.Base.id = -1;
239
240 /* some drivers do not like when the base (shared) context is deleted before its referals,
241 * this is why we keep a context refference counting the base (shared) context will be destroyed as soon as*/
242 return renderspuContextRelease( context );
243}
244
245ContextInfo * renderspuDefaultSharedContextAcquire()
246{
247 ContextInfo * pCtx = render_spu.defaultSharedContext;
248 if (!pCtx)
249 return NULL;
250
251 renderspuContextRetain(pCtx);
252 return pCtx;
253}
254
255void renderspuDefaultSharedContextRelease(ContextInfo * pCtx)
256{
257 renderspuContextRelease(pCtx);
258}
259
260
261static void RENDER_APIENTRY
262renderspuDestroyContext( GLint ctx )
263{
264 ContextInfo *context, *curCtx;
265
266 CRASSERT(ctx);
267
268 if (ctx == CR_RENDER_DEFAULT_CONTEXT_ID)
269 {
270 crWarning("request to destroy a default context, ignoring");
271 return;
272 }
273
274 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
275
276 if (!context)
277 {
278 crWarning("request to delete inexistent context");
279 return;
280 }
281
282 if (render_spu.defaultSharedContext == context)
283 {
284 renderspuSetDefaultSharedContext(NULL);
285 }
286
287 curCtx = GET_CONTEXT_VAL();
288// CRASSERT(curCtx);
289 if (curCtx == context)
290 {
291 renderspuMakeCurrent( CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID );
292 curCtx = GET_CONTEXT_VAL();
293 Assert(curCtx);
294 Assert(curCtx != context);
295 }
296
297 crHashtableDelete(render_spu.contextTable, ctx, NULL);
298
299 renderspuContextMarkDeletedAndRelease(context);
300}
301
302WindowInfo* renderspuWinCreate(GLint visBits, GLint id)
303{
304 WindowInfo* window = (WindowInfo *)crAlloc(sizeof (*window));
305 if (!window)
306 {
307 crWarning("crAlloc failed");
308 return NULL;
309 }
310
311 if (!renderspuWinInit(window, NULL, visBits, id))
312 {
313 crWarning("renderspuWinInit failed");
314 crFree(window);
315 return NULL;
316 }
317
318 return window;
319}
320
321void renderspuWinTermOnShutdown(WindowInfo *window)
322{
323 renderspuVBoxCompositorSet(window, NULL);
324 renderspuVBoxPresentBlitterCleanup(window);
325 window->BltInfo.Base.id = -1;
326 renderspu_SystemDestroyWindow( window );
327}
328
329static void renderspuCheckCurrentCtxWindowCB(unsigned long key, void *data1, void *data2)
330{
331 ContextInfo *pCtx = (ContextInfo *) data1;
332 WindowInfo *pWindow = data2;
333 (void) key;
334
335 if (pCtx->currentWindow==pWindow)
336 {
337 WindowInfo* pDummy = renderspuGetDummyWindow(pCtx->BltInfo.Base.visualBits);
338 if (pDummy)
339 {
340 renderspuPerformMakeCurrent(pDummy, 0, pCtx);
341 }
342 else
343 {
344 crWarning("failed to get dummy window");
345 renderspuMakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, pCtx->BltInfo.Base.id);
346 }
347 }
348}
349
350void renderspuWinTerm( WindowInfo *window )
351{
352 if (!renderspuWinIsTermed(window))
353 {
354
355 GET_CONTEXT(pOldCtx);
356 WindowInfo * pOldWindow = pOldCtx ? pOldCtx->currentWindow : NULL;
357 CRASSERT(!pOldCtx == !pOldWindow);
358 /* ensure no concurrent draws can take place */
359 renderspuWinTermOnShutdown(window);
360 /* check if this window is bound to some ctx. Note: window pointer is already freed here */
361 crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
362 /* restore current context */
363 {
364 GET_CONTEXT(pNewCtx);
365 WindowInfo * pNewWindow = pNewCtx ? pNewCtx->currentWindow : NULL;
366 CRASSERT(!pNewCtx == !pNewWindow);
367
368 if (pOldWindow == window)
369 renderspuMakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
370 else if (pNewCtx != pOldCtx || pOldWindow != pNewWindow)
371 {
372 if (pOldCtx)
373 renderspuPerformMakeCurrent(pOldWindow, 0, pOldCtx);
374 else
375 renderspuMakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
376 }
377 }
378
379 }
380}
381
382void renderspuWinCleanup(WindowInfo *window)
383{
384 renderspuWinTerm( window );
385 RTCritSectDelete(&window->CompositorLock);
386}
387
388void renderspuWinDestroy(WindowInfo *window)
389{
390 renderspuWinCleanup(window);
391 crFree(window);
392}
393
394WindowInfo* renderspuGetDummyWindow(GLint visBits)
395{
396 WindowInfo *window = (WindowInfo *) crHashtableSearch(render_spu.dummyWindowTable, visBits);
397 if (!window)
398 {
399 window = renderspuWinCreate(visBits, -1);
400 if (!window)
401 {
402 WARN(("renderspuWinCreate failed"));
403 return NULL;
404 }
405
406 crHashtableAdd(render_spu.dummyWindowTable, visBits, window);
407 }
408
409 return window;
410}
411
412/* Check that OpenGL extensions listed in pszRequiredExts string also exist in the pszAvailableExts string. */
413static void renderCompareGLExtensions(const char *pszAvailableExts, const char *pszRequiredExts)
414{
415 unsigned char fPrintHeader = 1;
416 const char *pszExt = pszRequiredExts;
417
418 for (;;)
419 {
420 const char *pszSrc = pszAvailableExts;
421 size_t offExtEnd;
422
423 while (*pszExt == ' ')
424 ++pszExt;
425
426 if (!*pszExt)
427 break;
428
429 offExtEnd = RTStrOffCharOrTerm(pszExt, ' ');
430
431 for (;;)
432 {
433 size_t offSrcEnd;
434
435 while (*pszSrc == ' ')
436 ++pszSrc;
437
438 if (!*pszSrc)
439 break;
440
441 offSrcEnd = RTStrOffCharOrTerm(pszSrc, ' ');
442
443 if ( offSrcEnd == offExtEnd
444 && memcmp(pszSrc, pszExt, offSrcEnd) == 0)
445 break;
446
447 pszSrc += offSrcEnd;
448 }
449
450 if (!*pszSrc)
451 {
452 if (fPrintHeader)
453 {
454 fPrintHeader = 0;
455 crInfo("Host does not support OpenGL extension(s):");
456 }
457 crInfo(" %.*s", offExtEnd, pszExt);
458 }
459
460 pszExt += offExtEnd;
461 }
462}
463
464void renderspuPerformMakeCurrent(WindowInfo *window, GLint nativeWindow, ContextInfo *context)
465{
466 if (window && context)
467 {
468#ifdef CHROMIUM_THREADSAFE
469 crSetTSD(&_RenderTSD, context);
470#else
471 render_spu.currentContext = context;
472#endif
473 context->currentWindow = window;
474
475 renderspu_SystemMakeCurrent( window, nativeWindow, context );
476 if (!context->everCurrent) {
477 static volatile uint32_t u32ExtCompared = 0;
478 /* print OpenGL info */
479 const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS );
480 /*
481 crDebug( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
482 */
483 crInfo( "Render SPU: GL_VENDOR: %s", render_spu.ws.glGetString( GL_VENDOR ) );
484 crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) );
485 crInfo( "Render SPU: GL_VERSION: %s", render_spu.ws.glGetString( GL_VERSION ) );
486 crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
487
488 if (ASMAtomicCmpXchgU32(&u32ExtCompared, 1, 0))
489 renderCompareGLExtensions(extString, crExtensions);
490
491 if (crStrstr(extString, "GL_ARB_window_pos"))
492 context->haveWindowPosARB = GL_TRUE;
493 else
494 context->haveWindowPosARB = GL_FALSE;
495 context->everCurrent = GL_TRUE;
496 }
497 if (window->BltInfo.Base.id == CR_RENDER_DEFAULT_WINDOW_ID && window->mapPending &&
498 !render_spu.render_to_app_window && !render_spu.render_to_crut_window) {
499 /* Window[CR_RENDER_DEFAULT_CONTEXT_ID] is special, it's the default window and normally hidden.
500 * If the mapPending flag is set, then we should now make the window
501 * visible.
502 */
503 /*renderspu_SystemShowWindow( window, GL_TRUE );*/
504 window->mapPending = GL_FALSE;
505 }
506 window->everCurrent = GL_TRUE;
507 }
508 else if (!window && !context)
509 {
510 renderspu_SystemMakeCurrent( NULL, 0, NULL );
511#ifdef CHROMIUM_THREADSAFE
512 crSetTSD(&_RenderTSD, NULL);
513#else
514 render_spu.currentContext = NULL;
515#endif
516 }
517 else
518 {
519 crError("renderspuMakeCurrent invalid ids: crWindow(%d), ctx(%d)",
520 window ? window->BltInfo.Base.id : 0,
521 context ? context->BltInfo.Base.id : 0);
522 }
523}
524
525void RENDER_APIENTRY
526renderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
527{
528 WindowInfo *window = NULL;
529 ContextInfo *context = NULL;
530
531 /*
532 crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx);
533 */
534
535 if (crWindow)
536 {
537 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow);
538 if (!window)
539 {
540 crWarning("invalid window %d specified", crWindow);
541 return;
542 }
543 }
544
545 if (ctx)
546 {
547 context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
548 if (!context)
549 {
550 crWarning("invalid context %d specified", ctx);
551 return;
552 }
553 }
554
555 if (!context != !window)
556 {
557 crWarning("either window %d or context %d are zero", crWindow, ctx);
558 return;
559 }
560
561 renderspuPerformMakeCurrent(window, nativeWindow, context);
562}
563
564GLboolean renderspuWinInitWithVisual( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id )
565{
566 crMemset(window, 0, sizeof (*window));
567 RTCritSectInit(&window->CompositorLock);
568 window->pCompositor = NULL;
569
570 window->BltInfo.Base.id = id;
571
572 window->x = render_spu.defaultX;
573 window->y = render_spu.defaultY;
574 window->BltInfo.width = render_spu.defaultWidth;
575 window->BltInfo.height = render_spu.defaultHeight;
576
577 /* Set window->title, replacing %i with the window ID number */
578 {
579 const char *s = crStrstr(render_spu.window_title, "%i");
580 if (s) {
581 int i, j, k;
582 window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
583 for (i = 0; render_spu.window_title[i] != '%'; i++)
584 window->title[i] = render_spu.window_title[i];
585 k = sprintf(window->title + i, "%d", window->BltInfo.Base.id);
586 CRASSERT(k < 10);
587 i++; /* skip the 'i' after the '%' */
588 j = i + k;
589 for (; (window->title[j] = s[i]) != 0; i++, j++)
590 ;
591 }
592 else {
593 window->title = crStrdup(render_spu.window_title);
594 }
595 }
596
597 window->BltInfo.Base.visualBits = visual->visAttribs;
598
599 window->cRefs = 1;
600
601 /*
602 crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
603 */
604 /* Have GLX/WGL/AGL create the window */
605 if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
606 {
607 crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
608 return GL_FALSE;
609 }
610
611 window->visible = !!showIt;
612
613 CRASSERT(window->visual == visual);
614 return GL_TRUE;
615}
616
617/*
618 * Window functions
619 */
620GLboolean renderspuWinInit(WindowInfo *pWindow, const char *dpyName, GLint visBits, GLint id)
621{
622 VisualInfo *visual;
623
624 crMemset(pWindow, 0, sizeof (*pWindow));
625
626 if (!dpyName || crStrlen(render_spu.display_string) > 0)
627 dpyName = render_spu.display_string;
628
629 visual = renderspuFindVisual( dpyName, visBits );
630 if (!visual)
631 {
632 crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
633 return GL_FALSE;
634 }
635
636 /*
637 crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
638 */
639 /* Have GLX/WGL/AGL create the window */
640 if (!renderspuWinInitWithVisual( pWindow, visual, 0, id ))
641 {
642 crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
643 return GL_FALSE;
644 }
645
646 return GL_TRUE;
647}
648
649GLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
650{
651 WindowInfo *window;
652
653 if (id <= 0)
654 {
655 id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
656 if (id <= 0)
657 {
658 crWarning("failed to allocate window id");
659 return -1;
660 }
661 }
662 else
663 {
664 if (crHashtableIsKeyUsed(render_spu.windowTable, id))
665 {
666 crWarning("the specified window key %d is in use", id);
667 return -1;
668 }
669 }
670
671 /* Allocate WindowInfo */
672 window = renderspuWinCreate(visBits, id);
673
674 if (!window)
675 {
676 crWarning("renderspuWinCreate failed");
677 crFree(window);
678 return -1;
679 }
680
681 crHashtableAdd(render_spu.windowTable, id, window);
682 return window->BltInfo.Base.id;
683}
684
685GLint RENDER_APIENTRY
686renderspuWindowCreate( const char *dpyName, GLint visBits )
687{
688 return renderspuWindowCreateEx( dpyName, visBits, 0 );
689}
690
691void renderspuWinReleaseCb(void*pvWindow)
692{
693 renderspuWinRelease((WindowInfo*)pvWindow);
694}
695
696void
697RENDER_APIENTRY renderspuWindowDestroy( GLint win )
698{
699 WindowInfo *window;
700
701 CRASSERT(win >= 0);
702 if (win == CR_RENDER_DEFAULT_WINDOW_ID)
703 {
704 crWarning("request to destroy a default mural, ignoring");
705 return;
706 }
707 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
708 if (window) {
709 crDebug("Render SPU: Destroy window (%d)", win);
710 /* since os-specific backend can hold its own reference to the window object (e.g. on OSX),
711 * we need to explicitly issue a window destroy command
712 * this ensures the backend will eventually release the reference,
713 * the window object itself will remain valid until its ref count reaches zero */
714 renderspuWinTerm( window );
715
716 /* remove window info from hash table, and free it */
717 crHashtableDelete(render_spu.windowTable, win, renderspuWinReleaseCb);
718
719 }
720 else {
721 crDebug("Render SPU: Attempt to destroy invalid window (%d)", win);
722 }
723}
724
725
726static void RENDER_APIENTRY
727renderspuWindowSize( GLint win, GLint w, GLint h )
728{
729 WindowInfo *window;
730 CRASSERT(win >= 0);
731 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
732 if (window) {
733 if (w != window->BltInfo.width
734 || h != window->BltInfo.height)
735 {
736 /* window is resized, compositor data is no longer valid
737 * this set also ensures all redraw operations are done in the redraw thread
738 * and that no redraw is started until new Present request comes containing a valid presentation data */
739 renderspuVBoxCompositorSet( window, NULL);
740 renderspu_SystemWindowSize( window, w, h );
741 window->BltInfo.width = w;
742 window->BltInfo.height = h;
743 }
744 }
745 else {
746 WARN(("Render SPU: Attempt to resize invalid window (%d)", win));
747 }
748}
749
750
751static void RENDER_APIENTRY
752renderspuWindowPosition( GLint win, GLint x, GLint y )
753{
754 if (!render_spu.ignore_window_moves) {
755 WindowInfo *window;
756 CRASSERT(win >= 0);
757 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
758 if (window) {
759 renderspu_SystemWindowPosition( window, x, y );
760 window->x = x;
761 window->y = y;
762 }
763 else {
764 crDebug("Render SPU: Attempt to move invalid window (%d)", win);
765 }
766 }
767}
768
769#ifdef DEBUG_misha
770# define CR_DBG_DUMP_VISIBLE_REGIONS
771#endif
772
773#ifdef CR_DBG_DUMP_VISIBLE_REGIONS
774static void renderspuDbgDumpVisibleRegion(GLint win, GLint cRects, const GLint *pRects)
775{
776 GLint i;
777 const RTRECT *pRtRects = (const RTRECT *)((const void*)pRects);
778
779 crInfo("Window %d, Vidible Regions%d", win, cRects);
780 for (i = 0; i < cRects; ++i)
781 {
782 crInfo("%d: (%d,%d), (%d,%d)", i, pRtRects[i].xLeft, pRtRects[i].yTop, pRtRects[i].xRight, pRtRects[i].yBottom);
783 }
784 crInfo("======");
785}
786#endif
787
788static void RENDER_APIENTRY
789renderspuWindowVisibleRegion(GLint win, GLint cRects, const GLint *pRects)
790{
791 WindowInfo *window;
792 CRASSERT(win >= 0);
793
794#ifdef CR_DBG_DUMP_VISIBLE_REGIONS
795 renderspuDbgDumpVisibleRegion(win, cRects, pRects);
796#endif
797
798 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
799 if (window) {
800 renderspu_SystemWindowVisibleRegion( window, cRects, pRects );
801 }
802 else {
803 crWarning("Render SPU: Attempt to set VisibleRegion for invalid window (%d)", win);
804 }
805}
806
807static void RENDER_APIENTRY
808renderspuWindowShow( GLint win, GLint flag )
809{
810 WindowInfo *window;
811 CRASSERT(win >= 0);
812 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
813 if (window) {
814 GLboolean visible;
815 if (window->nativeWindow) {
816 /* We're rendering back to the native app window instead of the
817 * new window which we (the Render SPU) created earlier.
818 * So, we never want to show the Render SPU's window.
819 */
820 flag = 0;
821 }
822
823 visible = !!flag;
824
825// if (window->visible != visible)
826 {
827 renderspu_SystemShowWindow( window, visible );
828 window->visible = visible;
829 }
830 }
831 else {
832 crDebug("Render SPU: Attempt to hide/show invalid window (%d)", win);
833 }
834}
835
836static void RENDER_APIENTRY
837renderspuVBoxPresentComposition( GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
838{
839 WindowInfo *window;
840 CRASSERT(win >= 0);
841 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
842 if (window) {
843 if (renderspuVBoxCompositorSet(window, pCompositor))
844 {
845 renderspu_SystemVBoxPresentComposition(window, pChangedEntry);
846 }
847 }
848 else {
849 crDebug("Render SPU: Attempt to PresentComposition for invalid window (%d)", win);
850 }
851}
852
853void renderspuVBoxCompositorBlitStretched ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)
854{
855 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
856 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
857 CrVrScrCompositorConstIterInit(pCompositor, &CIter);
858 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
859 {
860 uint32_t cRegions;
861 const RTRECT *paSrcRegions, *paDstRegions;
862 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
863 uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
864 if (RT_SUCCESS(rc))
865 {
866 uint32_t i;
867 for (i = 0; i < cRegions; ++i)
868 {
869 RTRECT DstRect;
870 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
871 DstRect.xLeft = paDstRegions[i].xLeft * scaleX;
872 DstRect.yTop = paDstRegions[i].yTop * scaleY;
873 DstRect.xRight = paDstRegions[i].xRight * scaleX;
874 DstRect.yBottom = paDstRegions[i].yBottom * scaleY;
875 CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), &paSrcRegions[i], &DstRect, 1, fFlags);
876 }
877 }
878 else
879 {
880 crWarning("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
881 }
882 }
883}
884
885void renderspuVBoxCompositorBlit ( const struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)
886{
887 VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR CIter;
888 const VBOXVR_SCR_COMPOSITOR_ENTRY *pEntry;
889 CrVrScrCompositorConstIterInit(pCompositor, &CIter);
890 while ((pEntry = CrVrScrCompositorConstIterNext(&CIter)) != NULL)
891 {
892 uint32_t cRegions;
893 const RTRECT *paSrcRegions, *paDstRegions;
894 int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions, NULL);
895 uint32_t fFlags = CrVrScrCompositorEntryFlagsCombinedGet(pCompositor, pEntry);
896 if (RT_SUCCESS(rc))
897 {
898 const CR_TEXDATA *pTexData = CrVrScrCompositorEntryTexGet(pEntry);
899 CrBltBlitTexMural(pBlitter, true, CrTdTexGet(pTexData), paSrcRegions, paDstRegions, cRegions, fFlags);
900 }
901 else
902 {
903 crWarning("Blit: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
904 }
905 }
906}
907
908void renderspuVBoxPresentBlitterCleanup( WindowInfo *window )
909{
910 if (!window->pBlitter)
911 return;
912
913 if (render_spu.blitterTable)
914 {
915 const CR_BLITTER_WINDOW * pBltInfo = CrBltMuralGetCurrentInfo(window->pBlitter);
916 if (pBltInfo && pBltInfo->Base.id == window->BltInfo.Base.id)
917 {
918 CrBltMuralSetCurrentInfo(window->pBlitter, NULL);
919 }
920 }
921 else
922 {
923 CRASSERT(CrBltMuralGetCurrentInfo(window->pBlitter)->Base.id == window->BltInfo.Base.id);
924 CrBltMuralSetCurrentInfo(window->pBlitter, NULL);
925 CrBltTerm(window->pBlitter);
926 }
927 window->pBlitter = NULL;
928}
929
930PCR_BLITTER renderspuVBoxPresentBlitterGet( WindowInfo *window )
931{
932 PCR_BLITTER pBlitter = window->pBlitter;
933 if (!pBlitter)
934 {
935 if (render_spu.blitterTable)
936 {
937 crHashtableLock(render_spu.blitterTable);
938 pBlitter = (PCR_BLITTER)crHashtableSearch(render_spu.blitterTable, window->visual->visAttribs);
939 }
940
941 if (!pBlitter)
942 {
943 int rc;
944 ContextInfo * pDefaultCtxInfo;
945
946 pBlitter = (PCR_BLITTER)crCalloc(sizeof (*pBlitter));
947 if (!pBlitter)
948 {
949 crWarning("failed to allocate blitter");
950 return NULL;
951 }
952
953 pDefaultCtxInfo = renderspuDefaultSharedContextAcquire();
954 if (!pDefaultCtxInfo)
955 {
956 crWarning("no default ctx info!");
957 crFree(pBlitter);
958 return NULL;
959 }
960
961 rc = CrBltInit(pBlitter, &pDefaultCtxInfo->BltInfo, true, true, NULL, &render_spu.blitterDispatch);
962
963 /* we can release it either way, since it will be retained when used as a shared context */
964 renderspuDefaultSharedContextRelease(pDefaultCtxInfo);
965
966 if (!RT_SUCCESS(rc))
967 {
968 crWarning("CrBltInit failed, rc %d", rc);
969 crFree(pBlitter);
970 return NULL;
971 }
972
973 if (render_spu.blitterTable)
974 {
975 crHashtableAdd( render_spu.blitterTable, window->visual->visAttribs, pBlitter );
976 }
977 }
978
979 if (render_spu.blitterTable)
980 crHashtableUnlock(render_spu.blitterTable);
981
982 Assert(pBlitter);
983 window->pBlitter = pBlitter;
984 }
985
986 CrBltMuralSetCurrentInfo(pBlitter, &window->BltInfo);
987 return pBlitter;
988}
989
990int renderspuVBoxPresentBlitterEnter( PCR_BLITTER pBlitter, int32_t i32MakeCurrentUserData)
991{
992 int rc;
993
994 CrBltSetMakeCurrentUserData(pBlitter, i32MakeCurrentUserData);
995
996 rc = CrBltEnter(pBlitter);
997 if (!RT_SUCCESS(rc))
998 {
999 crWarning("CrBltEnter failed, rc %d", rc);
1000 return rc;
1001 }
1002 return VINF_SUCCESS;
1003}
1004
1005PCR_BLITTER renderspuVBoxPresentBlitterGetAndEnter( WindowInfo *window, int32_t i32MakeCurrentUserData, bool fRedraw )
1006{
1007 PCR_BLITTER pBlitter = fRedraw ? window->pBlitter : renderspuVBoxPresentBlitterGet(window);
1008 if (pBlitter)
1009 {
1010 int rc = renderspuVBoxPresentBlitterEnter(pBlitter, i32MakeCurrentUserData);
1011 if (RT_SUCCESS(rc))
1012 {
1013 return pBlitter;
1014 }
1015 }
1016 return NULL;
1017}
1018
1019PCR_BLITTER renderspuVBoxPresentBlitterEnsureCreated( WindowInfo *window, int32_t i32MakeCurrentUserData )
1020{
1021 if (!window->pBlitter)
1022 {
1023 const struct VBOXVR_SCR_COMPOSITOR * pTmpCompositor;
1024 /* just use compositor lock to synchronize */
1025 pTmpCompositor = renderspuVBoxCompositorAcquire(window);
1026 CRASSERT(pTmpCompositor);
1027 if (pTmpCompositor)
1028 {
1029 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGet( window );
1030 if (pBlitter)
1031 {
1032 if (!CrBltIsEverEntered(pBlitter))
1033 {
1034 int rc = renderspuVBoxPresentBlitterEnter(pBlitter, i32MakeCurrentUserData);
1035 if (RT_SUCCESS(rc))
1036 {
1037 CrBltLeave(pBlitter);
1038 }
1039 else
1040 {
1041 crWarning("renderspuVBoxPresentBlitterEnter failed rc %d", rc);
1042 }
1043 }
1044 }
1045 else
1046 {
1047 crWarning("renderspuVBoxPresentBlitterGet failed");
1048 }
1049
1050 renderspuVBoxCompositorRelease(window);
1051 }
1052 else
1053 {
1054 crWarning("renderspuVBoxCompositorAcquire failed");
1055 }
1056 }
1057 return window->pBlitter;
1058}
1059
1060void renderspuVBoxPresentCompositionGeneric( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor,
1061 const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry, int32_t i32MakeCurrentUserData,
1062 bool fRedraw )
1063{
1064 PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGetAndEnter(window, i32MakeCurrentUserData, fRedraw);
1065 if (!pBlitter)
1066 return;
1067
1068 renderspuVBoxCompositorBlit(pCompositor, pBlitter);
1069
1070 renderspu_SystemSwapBuffers(window, 0);
1071
1072 CrBltLeave(pBlitter);
1073}
1074
1075GLboolean renderspuVBoxCompositorSet( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR * pCompositor)
1076{
1077 int rc;
1078 GLboolean fEmpty = pCompositor && CrVrScrCompositorIsEmpty(pCompositor);
1079 GLboolean fNeedPresent;
1080
1081 /* renderspuVBoxCompositorSet can be invoked from the chromium thread only and is not reentrant,
1082 * no need to synch here
1083 * the lock is actually needed to ensure we're in synch with the redraw thread */
1084 if (window->pCompositor == pCompositor && !fEmpty)
1085 return !!pCompositor;
1086
1087 rc = RTCritSectEnter(&window->CompositorLock);
1088 if (RT_SUCCESS(rc))
1089 {
1090 if (!fEmpty)
1091 fNeedPresent = !!pCompositor;
1092 else
1093 {
1094 fNeedPresent = renderspu_SystemWindowNeedEmptyPresent(window);
1095 pCompositor = NULL;
1096 }
1097
1098 window->pCompositor = !fEmpty ? pCompositor : NULL;
1099 RTCritSectLeave(&window->CompositorLock);
1100 return fNeedPresent;
1101 }
1102 else
1103 {
1104 WARN(("RTCritSectEnter failed rc %d", rc));
1105 }
1106
1107 return GL_FALSE;
1108}
1109
1110static void renderspuVBoxCompositorClearAllCB(unsigned long key, void *data1, void *data2)
1111{
1112 WindowInfo *window = (WindowInfo *) data1;
1113 renderspuVBoxCompositorSet(window, NULL);
1114}
1115
1116void renderspuVBoxCompositorClearAll()
1117{
1118 /* we need to clear window compositor, which is not that trivial though,
1119 * since the lock order used in presentation thread is compositor lock() -> hash table lock (aquired for id->window resolution)
1120 * this is why, to prevent potential deadlocks, we use crHashtableWalkUnlocked that does not hold the table lock
1121 * we are can be sure noone will modify the table here since renderspuVBoxCompositorClearAll can be called in the command (hgcm) thread only,
1122 * and the table can be modified from that thread only as well */
1123 crHashtableWalkUnlocked(render_spu.windowTable, renderspuVBoxCompositorClearAllCB, NULL);
1124}
1125
1126const struct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)
1127{
1128 int rc = RTCritSectEnter(&window->CompositorLock);
1129 if (RT_SUCCESS(rc))
1130 {
1131 const VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;
1132 if (pCompositor)
1133 {
1134 Assert(!CrVrScrCompositorIsEmpty(window->pCompositor));
1135 return pCompositor;
1136 }
1137
1138 /* if no compositor is set, release the lock and return */
1139 RTCritSectLeave(&window->CompositorLock);
1140 }
1141 else
1142 {
1143 crWarning("RTCritSectEnter failed rc %d", rc);
1144 }
1145 return NULL;
1146}
1147
1148int renderspuVBoxCompositorLock(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
1149{
1150 int rc = RTCritSectEnter(&window->CompositorLock);
1151 if (RT_SUCCESS(rc))
1152 {
1153 if (ppCompositor)
1154 *ppCompositor = window->pCompositor;
1155 }
1156 else
1157 WARN(("RTCritSectEnter failed %d", rc));
1158 return rc;
1159}
1160
1161int renderspuVBoxCompositorUnlock(WindowInfo *window)
1162{
1163 int rc = RTCritSectLeave(&window->CompositorLock);
1164 AssertRC(rc);
1165 return rc;
1166}
1167
1168int renderspuVBoxCompositorTryAcquire(WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
1169{
1170 int rc = RTCritSectTryEnter(&window->CompositorLock);
1171 if (RT_SUCCESS(rc))
1172 {
1173 *ppCompositor = window->pCompositor;
1174 if (*ppCompositor)
1175 {
1176 Assert(!CrVrScrCompositorIsEmpty(window->pCompositor));
1177 return VINF_SUCCESS;
1178 }
1179
1180 /* if no compositor is set, release the lock and return */
1181 RTCritSectLeave(&window->CompositorLock);
1182 rc = VERR_INVALID_STATE;
1183 }
1184 else
1185 {
1186 *ppCompositor = NULL;
1187 }
1188 return rc;
1189}
1190
1191void renderspuVBoxCompositorRelease( WindowInfo *window)
1192{
1193 int rc;
1194 Assert(window->pCompositor);
1195 Assert(!CrVrScrCompositorIsEmpty(window->pCompositor));
1196 rc = RTCritSectLeave(&window->CompositorLock);
1197 if (!RT_SUCCESS(rc))
1198 {
1199 crWarning("RTCritSectLeave failed rc %d", rc);
1200 }
1201}
1202
1203
1204/*
1205 * Set the current raster position to the given window coordinate.
1206 */
1207static void
1208SetRasterPos( GLint winX, GLint winY )
1209{
1210 GLfloat fx, fy;
1211
1212 /* Push current matrix mode and viewport attributes */
1213 render_spu.self.PushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
1214
1215 /* Setup projection parameters */
1216 render_spu.self.MatrixMode( GL_PROJECTION );
1217 render_spu.self.PushMatrix();
1218 render_spu.self.LoadIdentity();
1219 render_spu.self.MatrixMode( GL_MODELVIEW );
1220 render_spu.self.PushMatrix();
1221 render_spu.self.LoadIdentity();
1222
1223 render_spu.self.Viewport( winX - 1, winY - 1, 2, 2 );
1224
1225 /* set the raster (window) position */
1226 /* huh ? */
1227 fx = (GLfloat) (winX - (int) winX);
1228 fy = (GLfloat) (winY - (int) winY);
1229 render_spu.self.RasterPos4f( fx, fy, 0.0, 1.0 );
1230
1231 /* restore matrices, viewport and matrix mode */
1232 render_spu.self.PopMatrix();
1233 render_spu.self.MatrixMode( GL_PROJECTION );
1234 render_spu.self.PopMatrix();
1235
1236 render_spu.self.PopAttrib();
1237}
1238
1239
1240/*
1241 * Draw the mouse pointer bitmap at (x,y) in window coords.
1242 */
1243static void DrawCursor( GLint x, GLint y )
1244{
1245#define POINTER_WIDTH 32
1246#define POINTER_HEIGHT 32
1247 /* Somebody artistic could probably do better here */
1248 static const char *pointerImage[POINTER_HEIGHT] =
1249 {
1250 "XX..............................",
1251 "XXXX............................",
1252 ".XXXXX..........................",
1253 ".XXXXXXX........................",
1254 "..XXXXXXXX......................",
1255 "..XXXXXXXXXX....................",
1256 "...XXXXXXXXXXX..................",
1257 "...XXXXXXXXXXXXX................",
1258 "....XXXXXXXXXXXXXX..............",
1259 "....XXXXXXXXXXXXXXXX............",
1260 ".....XXXXXXXXXXXXXXXXX..........",
1261 ".....XXXXXXXXXXXXXXXXXXX........",
1262 "......XXXXXXXXXXXXXXXXXXXX......",
1263 "......XXXXXXXXXXXXXXXXXXXXXX....",
1264 ".......XXXXXXXXXXXXXXXXXXXXXXX..",
1265 ".......XXXXXXXXXXXXXXXXXXXXXXXX.",
1266 "........XXXXXXXXXXXXX...........",
1267 "........XXXXXXXX.XXXXX..........",
1268 ".........XXXXXX...XXXXX.........",
1269 ".........XXXXX.....XXXXX........",
1270 "..........XXX.......XXXXX.......",
1271 "..........XX.........XXXXX......",
1272 "......................XXXXX.....",
1273 ".......................XXXXX....",
1274 "........................XXX.....",
1275 ".........................X......",
1276 "................................",
1277 "................................",
1278 "................................",
1279 "................................",
1280 "................................",
1281 "................................"
1282
1283 };
1284 static GLubyte pointerBitmap[POINTER_HEIGHT][POINTER_WIDTH / 8];
1285 static GLboolean firstCall = GL_TRUE;
1286 GLboolean lighting, depthTest, scissorTest;
1287
1288 if (firstCall) {
1289 /* Convert pointerImage into pointerBitmap */
1290 GLint i, j;
1291 for (i = 0; i < POINTER_HEIGHT; i++) {
1292 for (j = 0; j < POINTER_WIDTH; j++) {
1293 if (pointerImage[POINTER_HEIGHT - i - 1][j] == 'X') {
1294 GLubyte bit = 128 >> (j & 0x7);
1295 pointerBitmap[i][j / 8] |= bit;
1296 }
1297 }
1298 }
1299 firstCall = GL_FALSE;
1300 }
1301
1302 render_spu.self.GetBooleanv(GL_LIGHTING, &lighting);
1303 render_spu.self.GetBooleanv(GL_DEPTH_TEST, &depthTest);
1304 render_spu.self.GetBooleanv(GL_SCISSOR_TEST, &scissorTest);
1305 render_spu.self.Disable(GL_LIGHTING);
1306 render_spu.self.Disable(GL_DEPTH_TEST);
1307 render_spu.self.Disable(GL_SCISSOR_TEST);
1308 render_spu.self.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
1309
1310 render_spu.self.Color3f(1, 1, 1);
1311
1312 /* save current raster pos */
1313 render_spu.self.PushAttrib(GL_CURRENT_BIT);
1314 SetRasterPos(x, y);
1315 render_spu.self.Bitmap(POINTER_WIDTH, POINTER_HEIGHT, 1.0, 31.0, 0, 0,
1316 (const GLubyte *) pointerBitmap);
1317 /* restore current raster pos */
1318 render_spu.self.PopAttrib();
1319
1320 if (lighting)
1321 render_spu.self.Enable(GL_LIGHTING);
1322 if (depthTest)
1323 render_spu.self.Enable(GL_DEPTH_TEST);
1324 if (scissorTest)
1325 render_spu.self.Enable(GL_SCISSOR_TEST);
1326}
1327
1328void RENDER_APIENTRY renderspuSwapBuffers( GLint window, GLint flags )
1329{
1330 WindowInfo *w = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
1331
1332 if (!w)
1333 {
1334 crDebug("Render SPU: SwapBuffers invalid window id: %d", window);
1335 return;
1336 }
1337
1338 if (flags & CR_SUPPRESS_SWAP_BIT)
1339 {
1340 render_spu.self.Finish();
1341 return;
1342 }
1343
1344 if (render_spu.drawCursor)
1345 DrawCursor( render_spu.cursorX, render_spu.cursorY );
1346
1347 renderspu_SystemSwapBuffers( w, flags );
1348}
1349
1350
1351/*
1352 * Barrier functions
1353 * Normally, we'll have a crserver somewhere that handles the barrier calls.
1354 * However, if we're running the render SPU on the client node, then we
1355 * should handle barriers here. The threadtest demo illustrates this.
1356 * If we have N threads calling using this SPU we need these barrier
1357 * functions to synchronize them.
1358 */
1359
1360static void RENDER_APIENTRY renderspuBarrierCreateCR( GLuint name, GLuint count )
1361{
1362 Barrier *b;
1363
1364 if (render_spu.ignore_papi)
1365 return;
1366
1367 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
1368 if (b) {
1369 /* HACK -- this allows everybody to create a barrier, and all
1370 but the first creation are ignored, assuming the count
1371 match. */
1372 if ( b->count != count ) {
1373 crError( "Render SPU: Barrier name=%u created with count=%u, but already "
1374 "exists with count=%u", name, count, b->count );
1375 }
1376 }
1377 else {
1378 b = (Barrier *) crAlloc( sizeof(Barrier) );
1379 b->count = count;
1380 crInitBarrier( &b->barrier, count );
1381 crHashtableAdd( render_spu.barrierHash, name, b );
1382 }
1383}
1384
1385static void RENDER_APIENTRY renderspuBarrierDestroyCR( GLuint name )
1386{
1387 if (render_spu.ignore_papi)
1388 return;
1389 crHashtableDelete( render_spu.barrierHash, name, crFree );
1390}
1391
1392static void RENDER_APIENTRY renderspuBarrierExecCR( GLuint name )
1393{
1394 Barrier *b;
1395
1396 if (render_spu.ignore_papi)
1397 return;
1398
1399 b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
1400 if (b) {
1401 crWaitBarrier( &(b->barrier) );
1402 }
1403 else {
1404 crWarning("Render SPU: Bad barrier name %d in BarrierExec()", name);
1405 }
1406}
1407
1408
1409/*
1410 * Semaphore functions
1411 * XXX we should probably implement these too, for the same reason as
1412 * barriers (see above).
1413 */
1414
1415static void RENDER_APIENTRY renderspuSemaphoreCreateCR( GLuint name, GLuint count )
1416{
1417 (void) name;
1418 (void) count;
1419}
1420
1421static void RENDER_APIENTRY renderspuSemaphoreDestroyCR( GLuint name )
1422{
1423 (void) name;
1424}
1425
1426static void RENDER_APIENTRY renderspuSemaphorePCR( GLuint name )
1427{
1428 (void) name;
1429}
1430
1431static void RENDER_APIENTRY renderspuSemaphoreVCR( GLuint name )
1432{
1433 (void) name;
1434}
1435
1436
1437/*
1438 * Misc functions
1439 */
1440void renderspuSetDefaultSharedContext(ContextInfo *pCtx)
1441{
1442 if (pCtx == render_spu.defaultSharedContext)
1443 return;
1444
1445 renderspu_SystemDefaultSharedContextChanged(render_spu.defaultSharedContext, pCtx);
1446
1447 if (render_spu.defaultSharedContext)
1448 renderspuContextRelease(render_spu.defaultSharedContext);
1449
1450 if (pCtx)
1451 renderspuContextRetain(pCtx);
1452 render_spu.defaultSharedContext = pCtx;
1453}
1454
1455static void RENDER_APIENTRY renderspuChromiumParameteriCR(GLenum target, GLint value)
1456{
1457 switch (target)
1458 {
1459 case GL_HH_SET_DEFAULT_SHARED_CTX:
1460 {
1461 ContextInfo * pCtx = NULL;
1462 if (value)
1463 pCtx = (ContextInfo *)crHashtableSearch(render_spu.contextTable, value);
1464 else
1465 crWarning("invalid default shared context id %d", value);
1466
1467 renderspuSetDefaultSharedContext(pCtx);
1468 break;
1469 }
1470 case GL_HH_RENDERTHREAD_INFORM:
1471 {
1472 if (value)
1473 {
1474 int rc = renderspuDefaultCtxInit();
1475 if (RT_FAILURE(rc))
1476 {
1477 WARN(("renderspuDefaultCtxInit failed"));
1478 break;
1479 }
1480 }
1481 else
1482 {
1483 renderspuCleanupBase(false);
1484 }
1485 break;
1486 }
1487 default:
1488// crWarning("Unhandled target in renderspuChromiumParameteriCR()");
1489 break;
1490 }
1491}
1492
1493static void RENDER_APIENTRY
1494renderspuChromiumParameterfCR(GLenum target, GLfloat value)
1495{
1496 (void) target;
1497 (void) value;
1498
1499#if 0
1500 switch (target) {
1501 default:
1502 crWarning("Unhandled target in renderspuChromiumParameterfCR()");
1503 break;
1504 }
1505#endif
1506}
1507
1508bool renderspuCalloutAvailable()
1509{
1510 return render_spu.pfnClientCallout != NULL;
1511}
1512
1513bool renderspuCalloutClient(PFNVCRSERVER_CLIENT_CALLOUT_CB pfnCb, void *pvCb)
1514{
1515 if (render_spu.pfnClientCallout)
1516 {
1517 render_spu.pfnClientCallout(pfnCb, pvCb);
1518 return true;
1519 }
1520 return false;
1521}
1522
1523static void RENDER_APIENTRY
1524renderspuChromiumParametervCR(GLenum target, GLenum type, GLsizei count,
1525 const GLvoid *values)
1526{
1527 int client_num;
1528 unsigned short port;
1529 CRMessage *msg, pingback;
1530 unsigned char *privbuf = NULL;
1531
1532 switch (target) {
1533 case GL_HH_SET_CLIENT_CALLOUT:
1534 render_spu.pfnClientCallout = (PFNVCRSERVER_CLIENT_CALLOUT)values;
1535 break;
1536 case GL_GATHER_CONNECT_CR:
1537 if (render_spu.gather_userbuf_size)
1538 privbuf = (unsigned char *)crAlloc(1024*768*4);
1539
1540 port = ((GLint *) values)[0];
1541
1542 if (render_spu.gather_conns == NULL)
1543 render_spu.gather_conns = crAlloc(render_spu.server->numClients*sizeof(CRConnection *));
1544 else
1545 {
1546 crError("Oh bother! duplicate GL_GATHER_CONNECT_CR getting through");
1547 }
1548
1549 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1550 {
1551 switch (render_spu.server->clients[client_num]->conn->type)
1552 {
1553 default:
1554 crError("Render SPU: Unknown Network Type to Open Gather Connection");
1555 }
1556
1557
1558 if (render_spu.gather_userbuf_size)
1559 {
1560 render_spu.gather_conns[client_num]->userbuf = privbuf;
1561 render_spu.gather_conns[client_num]->userbuf_len = render_spu.gather_userbuf_size;
1562 }
1563 else
1564 {
1565 render_spu.gather_conns[client_num]->userbuf = NULL;
1566 render_spu.gather_conns[client_num]->userbuf_len = 0;
1567 }
1568
1569 if (render_spu.gather_conns[client_num])
1570 {
1571 crDebug("Render SPU: success!");
1572 }
1573 }
1574
1575 break;
1576
1577 case GL_GATHER_DRAWPIXELS_CR:
1578 pingback.header.type = CR_MESSAGE_OOB;
1579
1580 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1581 {
1582 crNetGetMessage(render_spu.gather_conns[client_num], &msg);
1583 if (msg->header.type == CR_MESSAGE_GATHER)
1584 {
1585 crNetFree(render_spu.gather_conns[client_num], msg);
1586 }
1587 else
1588 {
1589 crError("Render SPU: expecting MESSAGE_GATHER. got crap! (%d of %d)",
1590 client_num, render_spu.server->numClients-1);
1591 }
1592 }
1593
1594 /*
1595 * We're only hitting the case if we're not actually calling
1596 * child.SwapBuffers from readback, so a switch about which
1597 * call to DoSync() we really want [this one, or the one
1598 * in SwapBuffers above] is not necessary -- karl
1599 */
1600 for (client_num=0; client_num< render_spu.server->numClients; client_num++)
1601 crNetSend(render_spu.gather_conns[client_num], NULL, &pingback,
1602 sizeof(CRMessageHeader));
1603
1604 render_spu.self.RasterPos2i(((GLint *)values)[0], ((GLint *)values)[1]);
1605 render_spu.self.DrawPixels( ((GLint *)values)[2], ((GLint *)values)[3],
1606 ((GLint *)values)[4], ((GLint *)values)[5],
1607 render_spu.gather_conns[0]->userbuf);
1608
1609
1610 render_spu.self.SwapBuffers(((GLint *)values)[6], 0);
1611 break;
1612
1613 case GL_CURSOR_POSITION_CR:
1614 if (type == GL_INT && count == 2) {
1615 render_spu.cursorX = ((GLint *) values)[0];
1616 render_spu.cursorY = ((GLint *) values)[1];
1617 crDebug("Render SPU: GL_CURSOR_POSITION_CR (%d, %d)", render_spu.cursorX, render_spu.cursorY);
1618 }
1619 else {
1620 crWarning("Render SPU: Bad type or count for ChromiumParametervCR(GL_CURSOR_POSITION_CR)");
1621 }
1622 break;
1623
1624 case GL_WINDOW_SIZE_CR:
1625 /* XXX this is old code that should be removed.
1626 * NOTE: we can only resize the default (id=CR_RENDER_DEFAULT_WINDOW_ID) window!!!
1627 */
1628 {
1629 GLint w, h;
1630 WindowInfo *window;
1631 CRASSERT(type == GL_INT);
1632 CRASSERT(count == 2);
1633 CRASSERT(values);
1634 w = ((GLint*)values)[0];
1635 h = ((GLint*)values)[1];
1636 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, CR_RENDER_DEFAULT_WINDOW_ID);
1637 if (window)
1638 {
1639 renderspu_SystemWindowSize(window, w, h);
1640 }
1641 }
1642 break;
1643
1644 case GL_HH_SET_TMPCTX_MAKE_CURRENT:
1645 if (type == GL_BYTE && count == sizeof (void*))
1646 memcpy(&render_spu.blitterDispatch.MakeCurrent, values, count);
1647 else
1648 WARN(("unexpected type(%#x) - count(%d) pair", type, count));
1649 break;
1650
1651 default:
1652#if 0
1653 WARN(("Unhandled target in renderspuChromiumParametervCR(0x%x)", (int) target));
1654#endif
1655 break;
1656 }
1657}
1658
1659
1660static void RENDER_APIENTRY
1661renderspuGetChromiumParametervCR(GLenum target, GLuint index, GLenum type,
1662 GLsizei count, GLvoid *values)
1663{
1664 switch (target) {
1665 case GL_WINDOW_SIZE_CR:
1666 {
1667 GLint x, y, w, h, *size = (GLint *) values;
1668 WindowInfo *window;
1669 CRASSERT(type == GL_INT);
1670 CRASSERT(count == 2);
1671 CRASSERT(values);
1672 size[0] = size[1] = 0; /* default */
1673 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1674 if (window)
1675 {
1676 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1677 size[0] = w;
1678 size[1] = h;
1679 }
1680 }
1681 break;
1682 case GL_WINDOW_POSITION_CR:
1683 /* return window position, as a screen coordinate */
1684 {
1685 GLint *pos = (GLint *) values;
1686 GLint x, y, w, h;
1687 WindowInfo *window;
1688 CRASSERT(type == GL_INT);
1689 CRASSERT(count == 2);
1690 CRASSERT(values);
1691 pos[0] = pos[1] = 0; /* default */
1692 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1693 if (window)
1694 {
1695 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1696 pos[0] = x;/*window->x;*/
1697 pos[1] = y;/*window->y;*/
1698 }
1699 }
1700 break;
1701 case GL_MAX_WINDOW_SIZE_CR:
1702 {
1703 GLint *maxSize = (GLint *) values;
1704 WindowInfo *window;
1705 CRASSERT(type == GL_INT);
1706 CRASSERT(count == 2);
1707 CRASSERT(values);
1708 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1709 if (window)
1710 {
1711 renderspu_SystemGetMaxWindowSize(window, maxSize + 0, maxSize + 1);
1712 }
1713 }
1714 break;
1715 case GL_WINDOW_VISIBILITY_CR:
1716 {
1717 GLint *vis = (GLint *) values;
1718 WindowInfo *window;
1719 CRASSERT(type == GL_INT);
1720 CRASSERT(count == 1);
1721 CRASSERT(values);
1722 vis[0] = 0; /* default */
1723 window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
1724 if (window)
1725 {
1726 vis[0] = window->visible;
1727 }
1728 }
1729 break;
1730 default:
1731 ; /* nothing - silence compiler */
1732 }
1733}
1734
1735
1736static void RENDER_APIENTRY
1737renderspuBoundsInfoCR( CRrecti *bounds, GLbyte *payload, GLint len,
1738 GLint num_opcodes )
1739{
1740 (void) bounds;
1741 (void) payload;
1742 (void) len;
1743 (void) num_opcodes;
1744 /* draw the bounding box */
1745 if (render_spu.draw_bbox) {
1746 GET_CONTEXT(context);
1747 WindowInfo *window = context->currentWindow;
1748 GLint x, y, w, h;
1749
1750 renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1751
1752 render_spu.self.PushMatrix();
1753 render_spu.self.LoadIdentity();
1754 render_spu.self.MatrixMode(GL_PROJECTION);
1755 render_spu.self.PushMatrix();
1756 render_spu.self.LoadIdentity();
1757 render_spu.self.Ortho(0, w, 0, h, -1, 1);
1758 render_spu.self.Color3f(1, 1, 1);
1759 render_spu.self.Begin(GL_LINE_LOOP);
1760 render_spu.self.Vertex2i(bounds->x1, bounds->y1);
1761 render_spu.self.Vertex2i(bounds->x2, bounds->y1);
1762 render_spu.self.Vertex2i(bounds->x2, bounds->y2);
1763 render_spu.self.Vertex2i(bounds->x1, bounds->y2);
1764 render_spu.self.End();
1765 render_spu.self.PopMatrix();
1766 render_spu.self.MatrixMode(GL_MODELVIEW);
1767 render_spu.self.PopMatrix();
1768 }
1769}
1770
1771
1772static void RENDER_APIENTRY
1773renderspuWriteback( GLint *writeback )
1774{
1775 (void) writeback;
1776}
1777
1778
1779static void
1780remove_trailing_space(char *s)
1781{
1782 int k = crStrlen(s);
1783 while (k > 0 && s[k-1] == ' ')
1784 k--;
1785 s[k] = 0;
1786}
1787
1788static const GLubyte * RENDER_APIENTRY
1789renderspuGetString(GLenum pname)
1790{
1791 static char tempStr[1000];
1792 GET_CONTEXT(context);
1793
1794 if (pname == GL_EXTENSIONS)
1795 {
1796 const char *nativeExt;
1797 char *crExt, *s1, *s2;
1798
1799 if (!render_spu.ws.glGetString)
1800 return NULL;
1801
1802 nativeExt = (const char *) render_spu.ws.glGetString(GL_EXTENSIONS);
1803 if (!nativeExt) {
1804 /* maybe called w/out current context. */
1805 return NULL;
1806 }
1807
1808 if (!context)
1809 return (const GLubyte *)nativeExt;
1810
1811 crExt = crStrjoin3(crExtensions, " ", crAppOnlyExtensions);
1812 s1 = crStrIntersect(nativeExt, crExt);
1813 remove_trailing_space(s1);
1814 s2 = crStrjoin3(s1, " ", crChromiumExtensions);
1815 remove_trailing_space(s2);
1816 crFree(crExt);
1817 crFree(s1);
1818 if (context->extensionString)
1819 crFree(context->extensionString);
1820 context->extensionString = s2;
1821 return (const GLubyte *) s2;
1822 }
1823 else if (pname == GL_VENDOR)
1824 return (const GLubyte *) CR_VENDOR;
1825 else if (pname == GL_VERSION)
1826 return render_spu.ws.glGetString(GL_VERSION);
1827 else if (pname == GL_RENDERER) {
1828#ifdef VBOX
1829 snprintf(tempStr, sizeof(tempStr), "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1830#else
1831 sprintf(tempStr, "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
1832#endif
1833 return (const GLubyte *) tempStr;
1834 }
1835#ifdef CR_OPENGL_VERSION_2_0
1836 else if (pname == GL_SHADING_LANGUAGE_VERSION)
1837 return render_spu.ws.glGetString(GL_SHADING_LANGUAGE_VERSION);
1838#endif
1839#ifdef GL_CR_real_vendor_strings
1840 else if (pname == GL_REAL_VENDOR)
1841 return render_spu.ws.glGetString(GL_VENDOR);
1842 else if (pname == GL_REAL_VERSION)
1843 return render_spu.ws.glGetString(GL_VERSION);
1844 else if (pname == GL_REAL_RENDERER)
1845 return render_spu.ws.glGetString(GL_RENDERER);
1846 else if (pname == GL_REAL_EXTENSIONS)
1847 return render_spu.ws.glGetString(GL_EXTENSIONS);
1848#endif
1849 else
1850 return NULL;
1851}
1852
1853static void renderspuReparentWindowCB(unsigned long key, void *data1, void *data2)
1854{
1855 WindowInfo *pWindow = (WindowInfo *)data1;
1856
1857 renderspu_SystemReparentWindow(pWindow);
1858}
1859
1860DECLEXPORT(void) renderspuReparentWindow(GLint window)
1861{
1862 WindowInfo *pWindow;
1863 CRASSERT(window >= 0);
1864
1865 pWindow = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
1866
1867 if (!pWindow)
1868 {
1869 crDebug("Render SPU: Attempt to reparent invalid window (%d)", window);
1870 return;
1871 }
1872
1873 renderspu_SystemReparentWindow(pWindow);
1874
1875 /* special case: reparent all internal windows as well */
1876 if (window == CR_RENDER_DEFAULT_WINDOW_ID)
1877 {
1878 crHashtableWalk(render_spu.dummyWindowTable, renderspuReparentWindowCB, NULL);
1879 }
1880}
1881
1882DECLEXPORT(void) renderspuSetUnscaledHiDPI(bool fEnable)
1883{
1884 render_spu.fUnscaledHiDPI = fEnable;
1885}
1886
1887#define FILLIN( NAME, FUNC ) \
1888 table[i].name = crStrdup(NAME); \
1889 table[i].fn = (SPUGenericFunction) FUNC; \
1890 i++;
1891
1892
1893/* These are the functions which the render SPU implements, not OpenGL.
1894 */
1895int
1896renderspuCreateFunctions(SPUNamedFunctionTable table[])
1897{
1898 int i = 0;
1899 FILLIN( "SwapBuffers", renderspuSwapBuffers );
1900 FILLIN( "CreateContext", renderspuCreateContext );
1901 FILLIN( "DestroyContext", renderspuDestroyContext );
1902 FILLIN( "MakeCurrent", renderspuMakeCurrent );
1903 FILLIN( "WindowCreate", renderspuWindowCreate );
1904 FILLIN( "WindowDestroy", renderspuWindowDestroy );
1905 FILLIN( "WindowSize", renderspuWindowSize );
1906 FILLIN( "WindowPosition", renderspuWindowPosition );
1907 FILLIN( "WindowVisibleRegion", renderspuWindowVisibleRegion );
1908 FILLIN( "WindowShow", renderspuWindowShow );
1909 FILLIN( "BarrierCreateCR", renderspuBarrierCreateCR );
1910 FILLIN( "BarrierDestroyCR", renderspuBarrierDestroyCR );
1911 FILLIN( "BarrierExecCR", renderspuBarrierExecCR );
1912 FILLIN( "BoundsInfoCR", renderspuBoundsInfoCR );
1913 FILLIN( "SemaphoreCreateCR", renderspuSemaphoreCreateCR );
1914 FILLIN( "SemaphoreDestroyCR", renderspuSemaphoreDestroyCR );
1915 FILLIN( "SemaphorePCR", renderspuSemaphorePCR );
1916 FILLIN( "SemaphoreVCR", renderspuSemaphoreVCR );
1917 FILLIN( "Writeback", renderspuWriteback );
1918 FILLIN( "ChromiumParameteriCR", renderspuChromiumParameteriCR );
1919 FILLIN( "ChromiumParameterfCR", renderspuChromiumParameterfCR );
1920 FILLIN( "ChromiumParametervCR", renderspuChromiumParametervCR );
1921 FILLIN( "GetChromiumParametervCR", renderspuGetChromiumParametervCR );
1922 FILLIN( "GetString", renderspuGetString );
1923 FILLIN( "VBoxPresentComposition", renderspuVBoxPresentComposition );
1924 return i;
1925}
Note: See TracBrowser for help on using the repository browser.

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