renderspu.c revision bf51ba1739a9eb4abd3bbf2fbeda16c90cdd2c19
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync/* Copyright (c) 2001, Stanford University
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * All rights reserved
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * See the file LICENSE.txt for information on redistributing this software.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetSend( render_spu.swap_conns[a], NULL, &out, sizeof(CRMessage));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetSend( render_spu.swap_conns[0], NULL, &out, sizeof(CRMessage));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Visual functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * used for debugging and giving info to the user.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuMakeVisString( GLbitfield visAttribs, char *s )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncGLboolean renderspuInitVisual(VisualInfo *pVisInfo, const char *displayName, GLbitfield visAttribs)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Find a VisualInfo which matches the given display name and attribute
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * bitmask, or return a pointer to a new visual.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuFindVisual(const char *displayName, GLbitfield visAttribs)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* first, try to find a match */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (visAttribs == render_spu.visuals[i].visAttribs) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (crStrcmp(displayName, render_spu.visuals[i].displayName) == 0
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync && visAttribs == render_spu.visuals[i].visAttribs) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Render SPU: Couldn't create a visual, too many visuals already");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* create a new visual */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (renderspuInitVisual(&(render_spu.visuals[i]), displayName, visAttribs)) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Render SPU: Couldn't get a visual, renderspu_SystemInitVisual failed");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic ContextInfo * renderspuCreateContextInternal(const char *dpyName, GLint visBits, GLint idCtx, ContextInfo * sharedContext)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync idCtx = (GLint)crHashtableAllocKeys(render_spu.contextTable, 1);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (crHashtableIsKeyUsed(render_spu.contextTable, idCtx))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("the specified ctx key %d is in use", idCtx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (!dpyName || crStrlen(render_spu.display_string)>0)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (!renderspu_SystemCreateContext(visual, context, sharedContext))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableAdd(render_spu.contextTable, idCtx, context);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync context->BltInfo.Base.visualBits = visual->visAttribs;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: CreateContext(%s, 0x%x) returning %d",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync dpyName, visBits, context->BltInfo.Base.id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncGLint renderspuCreateContextEx(const char *dpyName, GLint visBits, GLint id, GLint shareCtx)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync = (ContextInfo *) crHashtableSearch(render_spu.contextTable, shareCtx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync context = renderspuCreateContextInternal(dpyName, visBits, id, sharedContext);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Context functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuCreateContext(const char *dpyName, GLint visBits, GLint shareCtx)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync return renderspuCreateContextEx(dpyName, visBits, 0, shareCtx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("request to destroy a default context, ignoring");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
10258d88c40d8254a2a0d89e9b6c1f3b487f5c2dvboxsync renderspuMakeCurrent( CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableDelete(render_spu.contextTable, ctx, crFree);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: MakeCurrent invalid window id: %d", crWindow);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: MakeCurrent invalid context id: %d", ctx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemMakeCurrent( window, nativeWindow, context );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* print OpenGL info */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
10258d88c40d8254a2a0d89e9b6c1f3b487f5c2dvboxsync crInfo( "Render SPU: GL_VENDOR: %s", render_spu.ws.glGetString( GL_VENDOR ) );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crInfo( "Render SPU: GL_VERSION: %s", render_spu.ws.glGetString( GL_VERSION ) );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (crWindow == CR_RENDER_DEFAULT_WINDOW_ID && window->mapPending &&
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync !render_spu.render_to_app_window && !render_spu.render_to_crut_window) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Window[CR_RENDER_DEFAULT_CONTEXT_ID] is special, it's the default window and normally hidden.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * If the mapPending flag is set, then we should now make the window
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /*renderspu_SystemShowWindow( window, GL_TRUE );*/
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crError("renderspuMakeCurrent invalid ids: crWindow(%d), ctx(%d)", crWindow, ctx);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncGLboolean renderspuWindowInit( WindowInfo *window, VisualInfo *visual, GLboolean showIt, GLint id )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Set window->title, replacing %i with the window ID number */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync const char *s = crStrstr(render_spu.window_title, "%i");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int i, j, k;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (i = 0; render_spu.window_title[i] != '%'; i++)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync k = sprintf(window->title + i, "%d", window->BltInfo.Base.id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync i++; /* skip the 'i' after the '%' */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window->BltInfo.Base.visualBits = visual->visAttribs;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Have GLX/WGL/AGL create the window */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (!renderspu_SystemVBoxCreateWindow( visual, showIt, window ))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Window functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncGLint renderspuWindowCreateEx( const char *dpyName, GLint visBits, GLint id )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync id = (GLint)crHashtableAllocKeys(render_spu.windowTable, 1);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (crHashtableIsKeyUsed(render_spu.windowTable, id))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("the specified window key %d is in use", id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (!dpyName || crStrlen(render_spu.display_string) > 0)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Allocate WindowInfo */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning( "Render SPU: Couldn't create a window" );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableAdd(render_spu.windowTable, id, window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync || ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER")))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->BltInfo.Base.id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Have GLX/WGL/AGL create the window */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (!renderspuWindowInit( window, visual, showIt, id ))
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuWindowCreate( const char *dpyName, GLint visBits )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync return renderspuWindowCreateEx( dpyName, visBits, 0 );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void renderspuCheckCurrentCtxWindowCB(unsigned long key, void *data1, void *data2)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspuMakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, pCtx->BltInfo.Base.id);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* ensure no concurrent draws can take place */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* check if this window is bound to some ctx. Note: window pointer is already freed here */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* restore current context */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("request to destroy a default mural, ignoring");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* remove window info from hash table, and free it */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableDelete(render_spu.windowTable, win, crFree);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to destroy invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* window is resized, compositor data is no longer valid
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * this set also ensures all redraw operations are done in the redraw thread
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * and that no redraw is started until new Present request comes containing a valid presentation data */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to resize invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuWindowPosition( GLint win, GLint x, GLint y )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to move invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuWindowVisibleRegion(GLint win, GLint cRects, GLint *pRects)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemWindowVisibleRegion( window, cRects, pRects );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to set VisibleRegion for invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* We're rendering back to the native app window instead of the
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * new window which we (the Render SPU) created earlier.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * So, we never want to show the Render SPU's window.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemShowWindow( window, (GLboolean) flag );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to hide/show invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuVBoxPresentComposition( GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemVBoxPresentComposition(window, pCompositor, pChangedEntry);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: Attempt to PresentComposition for invalid window (%d)", win);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid renderspuVBoxCompositorBlitStretched ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter, GLfloat scaleX, GLfloat scaleY)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync DstRect.yBottom = paDstRegions[i].yBottom * scaleY;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync CrBltBlitTexMural(pBlitter, &pEntry->Tex, &paSrcRegions[i], &DstRect, 1, CRBLT_F_LINEAR);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("BlitStretched: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid renderspuVBoxCompositorBlit ( struct VBOXVR_SCR_COMPOSITOR * pCompositor, PCR_BLITTER pBlitter)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync while ((pEntry = CrVrScrCompositorIterNext(&CIter)) != NULL)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int rc = CrVrScrCompositorEntryRegionsGet(pCompositor, pEntry, &cRegions, &paSrcRegions, &paDstRegions);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync CrBltBlitTexMural(pBlitter, &pEntry->Tex, paSrcRegions, paDstRegions, cRegions, CRBLT_F_LINEAR);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Blit: CrVrScrCompositorEntryRegionsGet failed rc %d", rc);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncPCR_BLITTER renderspuVBoxPresentBlitterGet( WindowInfo *window )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync pBlitter = (PCR_BLITTER)crHashtableSearch(render_spu.blitterTable, window->visual->visAttribs);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync pBlitter = (PCR_BLITTER)crCalloc(sizeof (*pBlitter));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* @todo: this is the assumption that crserverlib uses context 1 as a default one
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * need to do it in a more proper way */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync rc = CrBltInit(pBlitter, &ctx, true, render_spu.blitterDispatch);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableAdd( render_spu.blitterTable, window->visual->visAttribs, pBlitter );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncint renderspuVBoxPresentBlitterEnter( PCR_BLITTER pBlitter )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncPCR_BLITTER renderspuVBoxPresentBlitterGetAndEnter( WindowInfo *window )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGet(window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int rc = renderspuVBoxPresentBlitterEnter(pBlitter);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncPCR_BLITTER renderspuVBoxPresentBlitterEnsureCreated( WindowInfo *window )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* just use compositor lock to synchronize */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync pTmpCompositor = renderspuVBoxCompositorAcquire(window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGet( window );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int rc = renderspuVBoxPresentBlitterEnter(pBlitter);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("renderspuVBoxPresentBlitterEnter failed rc %d", rc);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("renderspuVBoxPresentBlitterGet failed");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("renderspuVBoxCompositorAcquire failed");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid renderspuVBoxPresentCompositionGeneric( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync PCR_BLITTER pBlitter = renderspuVBoxPresentBlitterGetAndEnter(window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspuVBoxCompositorBlit(pCompositor, pBlitter);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid renderspuVBoxCompositorSet( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* renderspuVBoxCompositorSet can be invoked from the chromium thread only and is not reentrant,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * no need to synch here
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * the lock is actually needed to ensure we're in synch with the redraw thread */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void renderspuVBoxCompositorClearAllCB(unsigned long key, void *data1, void *data2)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* we need to clear window compositor, which is not that trivial though,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * since the lock order used in presentation thread is compositor lock() -> hash table lock (aquired for id->window resolution)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * this is why, to prevent potential deadlocks, we use crHashtableWalkUnlocked that does not hold the table lock
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * we are can be sure noone will modify the table here since renderspuVBoxCompositorClearAll can be called in the command (hgcm) thread only,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * and the table can be modified from that thread only as well */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableWalkUnlocked(render_spu.windowTable, renderspuVBoxCompositorClearAllCB, NULL);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstruct VBOXVR_SCR_COMPOSITOR * renderspuVBoxCompositorAcquire( WindowInfo *window)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync VBOXVR_SCR_COMPOSITOR * pCompositor = window->pCompositor;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* if no compositor is set, release the lock and return */
7b2cd67e9d38011fddd62967b7e9d26d88a28133vboxsyncint renderspuVBoxCompositorTryAcquire(WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR **ppCompositor)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync int rc = RTCritSectTryEnter(&window->CompositorLock);
7b2cd67e9d38011fddd62967b7e9d26d88a28133vboxsync /* if no compositor is set, release the lock and return */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid renderspuVBoxCompositorRelease( WindowInfo *window)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Set the current raster position to the given window coordinate.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Push current matrix mode and viewport attributes */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.PushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Setup projection parameters */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.Viewport( winX - 1, winY - 1, 2, 2 );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* set the raster (window) position */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* huh ? */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* restore matrices, viewport and matrix mode */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Draw the mouse pointer bitmap at (x,y) in window coords.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Somebody artistic could probably do better here */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "XX..............................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "XXXX............................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".XXXXX..........................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".XXXXXXX........................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "..XXXXXXXX......................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "..XXXXXXXXXX....................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "...XXXXXXXXXXX..................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "...XXXXXXXXXXXXX................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "....XXXXXXXXXXXXXX..............",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "....XXXXXXXXXXXXXXXX............",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".....XXXXXXXXXXXXXXXXX..........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".....XXXXXXXXXXXXXXXXXXX........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "......XXXXXXXXXXXXXXXXXXXX......",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "......XXXXXXXXXXXXXXXXXXXXXX....",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".......XXXXXXXXXXXXXXXXXXXXXXX..",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".......XXXXXXXXXXXXXXXXXXXXXXXX.",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "........XXXXXXXXXXXXX...........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "........XXXXXXXX.XXXXX..........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".........XXXXXX...XXXXX.........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".........XXXXX.....XXXXX........",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "..........XXX.......XXXXX.......",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "..........XX.........XXXXX......",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "......................XXXXX.....",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".......................XXXXX....",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "........................XXX.....",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ".........................X......",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync "................................"
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync static GLubyte pointerBitmap[POINTER_HEIGHT][POINTER_WIDTH / 8];
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* Convert pointerImage into pointerBitmap */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (i = 0; i < POINTER_HEIGHT; i++) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (j = 0; j < POINTER_WIDTH; j++) {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync if (pointerImage[POINTER_HEIGHT - i - 1][j] == 'X') {
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.GetBooleanv(GL_LIGHTING, &lighting);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.GetBooleanv(GL_DEPTH_TEST, &depthTest);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.GetBooleanv(GL_SCISSOR_TEST, &scissorTest);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* save current raster pos */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.Bitmap(POINTER_WIDTH, POINTER_HEIGHT, 1.0, 31.0, 0, 0,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* restore current raster pos */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncvoid RENDER_APIENTRY renderspuSwapBuffers( GLint window, GLint flags )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync WindowInfo *w = (WindowInfo *) crHashtableSearch(render_spu.windowTable, window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: SwapBuffers invalid window id: %d", window);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync DrawCursor( render_spu.cursorX, render_spu.cursorY );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Barrier functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Normally, we'll have a crserver somewhere that handles the barrier calls.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * However, if we're running the render SPU on the client node, then we
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * should handle barriers here. The threadtest demo illustrates this.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * If we have N threads calling using this SPU we need these barrier
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * functions to synchronize them.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuBarrierCreateCR( GLuint name, GLuint count )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* HACK -- this allows everybody to create a barrier, and all
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync but the first creation are ignored, assuming the count
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crError( "Render SPU: Barrier name=%u created with count=%u, but already "
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuBarrierDestroyCR( GLuint name )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crHashtableDelete( render_spu.barrierHash, name, crFree );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuBarrierExecCR( GLuint name )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync b = (Barrier *) crHashtableSearch( render_spu.barrierHash, name );
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Render SPU: Bad barrier name %d in BarrierExec()", name);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Semaphore functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * XXX we should probably implement these too, for the same reason as
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * barriers (see above).
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuSemaphoreCreateCR( GLuint name, GLuint count )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuSemaphoreDestroyCR( GLuint name )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuSemaphorePCR( GLuint name )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuSemaphoreVCR( GLuint name )
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * Misc functions
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncstatic void RENDER_APIENTRY renderspuChromiumParameteriCR(GLenum target, GLint value)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.force_hidden_wdn_create = value ? GL_TRUE : GL_FALSE;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync// crWarning("Unhandled target in renderspuChromiumParameteriCR()");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuChromiumParameterfCR(GLenum target, GLfloat value)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Unhandled target in renderspuChromiumParameterfCR()");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuChromiumParametervCR(GLenum target, GLenum type, GLsizei count,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync unsigned short port;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.gather_conns = crAlloc(render_spu.server->numClients*sizeof(CRConnection *));
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crError("Oh bother! duplicate GL_GATHER_CONNECT_CR getting through");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (client_num=0; client_num< render_spu.server->numClients; client_num++)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync switch (render_spu.server->clients[client_num]->conn->type)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.server->clients[client_num]->conn->hostname, render_spu.gather_port);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetAcceptClient("tcpip", NULL, port, 1024*1024, 1);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crError("Render SPU: Unknown Network Type to Open Gather Connection");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.gather_conns[client_num]->userbuf = privbuf;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.gather_conns[client_num]->userbuf_len = render_spu.gather_userbuf_size;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.gather_conns[client_num]->userbuf = NULL;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.gather_conns[client_num]->userbuf_len = 0;
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: success! from %s", render_spu.gather_conns[client_num]->hostname);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (client_num=0; client_num< render_spu.server->numClients; client_num++)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetGetMessage(render_spu.gather_conns[client_num], &msg);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetFree(render_spu.gather_conns[client_num], msg);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crError("Render SPU: expecting MESSAGE_GATHER. got crap! (%d of %d)",
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * We're only hitting the case if we're not actually calling
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * child.SwapBuffers from readback, so a switch about which
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * call to DoSync() we really want [this one, or the one
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * in SwapBuffers above] is not necessary -- karl
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync for (client_num=0; client_num< render_spu.server->numClients; client_num++)
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crNetSend(render_spu.gather_conns[client_num], NULL, &pingback,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.RasterPos2i(((GLint *)values)[0], ((GLint *)values)[1]);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.DrawPixels( ((GLint *)values)[2], ((GLint *)values)[3],
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync render_spu.self.SwapBuffers(((GLint *)values)[6], 0);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crDebug("Render SPU: GL_CURSOR_POSITION_CR (%d, %d)", render_spu.cursorX, render_spu.cursorY);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Render SPU: Bad type or count for ChromiumParametervCR(GL_CURSOR_POSITION_CR)");
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* XXX this is old code that should be removed.
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync * NOTE: we can only resize the default (id=CR_RENDER_DEFAULT_WINDOW_ID) window!!!
1705f7565ed8533058b8541d72d6c5d4453de00fvboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, CR_RENDER_DEFAULT_WINDOW_ID);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync crWarning("Unhandled target in renderspuChromiumParametervCR(0x%x)", (int) target);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuGetChromiumParametervCR(GLenum target, GLuint index, GLenum type,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* return window position, as a screen coordinate */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
1705f7565ed8533058b8541d72d6c5d4453de00fvboxsync window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, index);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemGetMaxWindowSize(window, maxSize + 0, maxSize + 1);
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync ; /* nothing - silence compiler */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsyncrenderspuBoundsInfoCR( CRrecti *bounds, GLbyte *payload, GLint len,
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync /* draw the bounding box */
7da9e7e719adde3baba3f6fa1d0bcfb170cf9911vboxsync renderspu_SystemGetWindowGeometry(window, &x, &y, &w, &h);
remove_trailing_space(char *s)
int k = crStrlen(s);
const char *nativeExt;
return NULL;
if (!nativeExt) {
return NULL;
#ifdef VBOX
snprintf(tempStr, sizeof(tempStr), "Chromium (%s)", (char *) render_spu.ws.glGetString(GL_RENDERER));
#ifdef CR_OPENGL_VERSION_2_0
#ifdef GL_CR_real_vendor_strings
return NULL;
if (!pWindow)