static void stubWindowCheckOwnerCB(unsigned long key, void *data1, void *data2) { WindowInfo *pWindow = (WindowInfo *) data1; ContextInfo *pCtx = (ContextInfo *) data2; if (pWindow->pOwner == pCtx) { #ifdef WINDOWS /* Note: can't use WindowFromDC(context->pOwnWindow->drawable) here because GL context is already released from DC and actual guest window could be destroyed. */ stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->hWnd); #else stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->drawable); #endif } }
static void stubCheckWindowsCB(unsigned long key, void *data1, void *data2) { WindowInfo *pWindow = (WindowInfo *) data1; ContextInfo *pCtx = (ContextInfo *) data2; if (pWindow == pCtx->currentDrawable || pWindow->type!=CHROMIUM || pWindow->pOwner!=pCtx) { return; } if (!stubSystemWindowExist(pWindow)) { #ifdef WINDOWS stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->hWnd); #else stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->drawable); #endif return; } stubCheckWindowState(pWindow, GL_FALSE); }
DECLEXPORT(void) WINAPI VBoxFlushToHost ( HGLRC hglrc ) { ContextInfo *context; CR_DDI_PROLOGUE(); // crHashtableLock(stub.windowTable); crHashtableLock(stub.contextTable); context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc); if (context) stubConFlush(CR_CTX_CON(context)); crHashtableUnlock(stub.contextTable); // crHashtableUnlock(stub.windowTable); }
DECLEXPORT(BOOL) WINAPI wglShareLists_prox( HGLRC hglrc1, HGLRC hglrc2 ) { ContextInfo *context1, *context2; GLint aSpuContexts[2]; CR_DDI_PROLOGUE(); // crHashtableLock(stub.windowTable); crHashtableLock(stub.contextTable); context1 = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc1); if (!context1) { WARN(("invalid hglrc1")); return FALSE; } stubCtxCheckCreate(context1); context2 = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc2); if (!context2) { WARN(("invalid hglrc2")); return FALSE; } stubCtxCheckCreate(context2); aSpuContexts[0] = context1->spuContext; aSpuContexts[1] = context2->spuContext; stubConChromiumParametervCR(CR_CTX_CON(context2), GL_SHARE_LISTS_CR, GL_INT, 2, aSpuContexts); crHashtableUnlock(stub.contextTable); return TRUE; }
DECLEXPORT(void) WINAPI VBoxCtxChromiumParameteriCR(HGLRC hglrc, GLenum param, GLint value) { ContextInfo *context; CR_DDI_PROLOGUE(); // crHashtableLock(stub.windowTable); crHashtableLock(stub.contextTable); context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc); if (context) { stubCtxCheckCreate(context); stubConChromiumParameteriCR(CR_CTX_CON(context), param, value); } else crWarning("invalid context %#x", hglrc); crHashtableUnlock(stub.contextTable); // crHashtableUnlock(stub.windowTable); }
GLboolean stubMakeCurrent( WindowInfo *window, ContextInfo *context ) { GLboolean retVal; /* * Get WindowInfo and ContextInfo pointers. */ if (!context || !window) { ContextInfo * currentContext = stubGetCurrentContext(); if (currentContext) currentContext->currentDrawable = NULL; if (context) context->currentDrawable = NULL; stubSetCurrentContext(NULL); return GL_TRUE; /* OK */ } #ifdef CHROMIUM_THREADSAFE stubCheckMultithread(); #endif if (context->type == UNDECIDED) { /* Here's where we really create contexts */ #ifdef CHROMIUM_THREADSAFE crLockMutex(&stub.mutex); #endif if (stubCheckUseChromium(window)) { GLint spuConnection = 0; if (!stubCtxCreate(context)) { crWarning("stubCtxCreate failed"); return GL_FALSE; } #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) spuConnection = context->spuConnection; #endif if (window->spuWindow == -1) { /*crDebug("(1)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/ window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(spuConnection, window->dpyName, context->visBits ); #ifdef CR_NEWWINTRACK window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(spuConnection); #endif } } else { /* * Create a native OpenGL context. */ if (!InstantiateNativeContext(window, context)) { #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&stub.mutex); #endif return 0; /* false */ } context->type = NATIVE; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&stub.mutex); #endif } if (context->type == NATIVE) { /* * Native OpenGL MakeCurrent(). */ #ifdef WINDOWS retVal = (GLboolean) stub.wsInterface.wglMakeCurrent( window->drawable, context->hglrc ); #elif defined(Darwin) // XXX \todo We need to differentiate between these two.. retVal = ( stub.wsInterface.CGLSetSurface(context->cglc, window->connection, window->drawable, window->surface) == noErr ); retVal = ( stub.wsInterface.CGLSetCurrentContext(context->cglc) == noErr ); #elif defined(GLX) retVal = (GLboolean) stub.wsInterface.glXMakeCurrent( window->dpy, window->drawable, context->glxContext ); #endif } else { /* * SPU chain MakeCurrent(). */ CRASSERT(context->type == CHROMIUM); CRASSERT(context->spuContext >= 0); /*if (context->currentDrawable && context->currentDrawable != window) crDebug("Rebinding context %p to a different window", context);*/ if (window->type == NATIVE) { crWarning("Can't rebind a chromium context to a native window\n"); retVal = 0; } else { if (window->spuWindow == -1) { /*crDebug("(2)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/ window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) context->spuConnection, #else 0, #endif window->dpyName, context->visBits ); #ifdef CR_NEWWINTRACK window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID( # if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) context->spuConnection # else 0 # endif ); #endif if (context->currentDrawable && context->currentDrawable->type==CHROMIUM && context->currentDrawable->pOwner==context) { #ifdef WINDOWS if (context->currentDrawable->hWnd!=WindowFromDC(context->currentDrawable->drawable)) { stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->hWnd); } #else Window root; int x, y; unsigned int border, depth, w, h; XLOCK(context->currentDrawable->dpy); if (!XGetGeometry(context->currentDrawable->dpy, context->currentDrawable->drawable, &root, &x, &y, &w, &h, &border, &depth)) { stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->drawable); } XUNLOCK(context->currentDrawable->dpy); #endif } } if (window->spuWindow != (GLint)window->drawable) stub.spu->dispatch_table.MakeCurrent( window->spuWindow, (GLint) window->drawable, context->spuContext ); else stub.spu->dispatch_table.MakeCurrent( window->spuWindow, 0, /* native window handle */ context->spuContext ); retVal = 1; } } window->type = context->type; window->pOwner = context; context->currentDrawable = window; stubSetCurrentContext(context); if (retVal) { /* Now, if we've transitions from Chromium to native rendering, or * vice versa, we have to change all the OpenGL entrypoint pointers. */ if (context->type == NATIVE) { /* Switch to native API */ /*printf(" Switching to native API\n");*/ stubSetDispatch(&stub.nativeDispatch); } else if (context->type == CHROMIUM) { /* Switch to stub (SPU) API */ /*printf(" Switching to spu API\n");*/ stubSetDispatch(&stub.spuDispatch); } else { /* no API switch needed */ } } if (!window->width && window->type == CHROMIUM) { /* One time window setup */ int x, y; unsigned int winW, winH; stubGetWindowGeometry( window, &x, &y, &winW, &winH ); /* If we're not using GLX/WGL (no app window) we'll always get * a width and height of zero here. In that case, skip the viewport * call since we're probably using a tilesort SPU with fake_window_dims * which the tilesort SPU will use for the viewport. */ window->width = winW; window->height = winH; #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) if (stubIsWindowVisible(window)) #endif { if (stub.trackWindowSize) stub.spuDispatch.WindowSize( window->spuWindow, winW, winH ); if (stub.trackWindowPos) stub.spuDispatch.WindowPosition(window->spuWindow, x, y); if (winW > 0 && winH > 0) stub.spu->dispatch_table.Viewport( 0, 0, winW, winH ); } #ifdef VBOX_WITH_WDDM if (stub.trackWindowVisibleRgn) stub.spu->dispatch_table.WindowVisibleRegion(window->spuWindow, 0, NULL); #endif } /* Update window mapping state. * Basically, this lets us hide render SPU windows which correspond * to unmapped application windows. Without this, "pertly" (for example) * opens *lots* of temporary windows which otherwise clutter the screen. */ if (stub.trackWindowVisibility && window->type == CHROMIUM && window->drawable) { const int mapped = stubIsWindowVisible(window); if (mapped != window->mapped) { crDebug("Dispatched: WindowShow(%i, %i)", window->spuWindow, mapped); stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped); window->mapped = mapped; } } return retVal; }