LRESULT CALLBACK stubCBWindowMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) lParam; if (nCode>=0 && pMsgInfo) { switch (pMsgInfo->message) { case WM_MOVING: case WM_SIZING: case WM_MOVE: case WM_ACTIVATEAPP: case WM_NCPAINT: case WM_NCACTIVATE: case WM_ERASEBKGND: case WM_CREATE: case WM_SIZE: case WM_SHOWWINDOW: { crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam); break; } /* @todo remove it*/ default: { /*crDebug("hook: unknown message (%d)", pMsgInfo->message);*/ crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam); break; } } } return CallNextHookEx(stub.hMessageHook, nCode, wParam, lParam); }
DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID) { crDebug("crVBoxServerMapScreen(%i) [%i,%i:%u,%u %x]", sIndex, x, y, w, h, winID); if (sIndex<0 || sIndex>=cr_server.screenCount) return VERR_INVALID_PARAMETER; if (MAPPED(SCREEN(sIndex)) && SCREEN(sIndex).winID!=winID) { crDebug("Mapped screen[%i] is being remapped.", sIndex); crVBoxServerUnmapScreen(sIndex); } SCREEN(sIndex).winID = winID; SCREEN(sIndex).x = x; SCREEN(sIndex).y = y; SCREEN(sIndex).w = w; SCREEN(sIndex).h = h; renderspuSetWindowId(SCREEN(sIndex).winID); crHashtableWalk(cr_server.muralTable, crVBoxServerReparentMuralCB, &sIndex); renderspuSetWindowId(SCREEN(0).winID); crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL); #ifndef WINDOWS /*Restore FB content for clients, which have current window on a screen being remapped*/ { GLint i; for (i = 0; i < cr_server.numClients; i++) { cr_server.curClient = cr_server.clients[i]; if (cr_server.curClient->currentCtx && (cr_server.curClient->currentCtx->buffer.pFrontImg || cr_server.curClient->currentCtx->buffer.pBackImg) && cr_server.curClient->currentMural && cr_server.curClient->currentMural->screenId == sIndex && cr_server.curClient->currentCtx->buffer.storedHeight == h && cr_server.curClient->currentCtx->buffer.storedWidth == w) { int clientWindow = cr_server.curClient->currentWindow; int clientContext = cr_server.curClient->currentContextNumber; if (clientWindow && clientWindow != cr_server.currentWindow) { crServerDispatchMakeCurrent(clientWindow, 0, clientContext); } crStateApplyFBImage(cr_server.curClient->currentCtx); } } cr_server.curClient = NULL; } #endif return VINF_SUCCESS; }
DECLEXPORT(void) STATE_APIENTRY crStateLinkProgram(GLuint program) { CRGLSLProgram *pProgram = crStateGetProgramObj(program); GLuint i; if (!pProgram) { crWarning("Unknown program %d", program); return; } pProgram->linked = GL_TRUE; /*Free program's active state*/ if (pProgram->activeState.attachedShaders) { crHashtableWalk(pProgram->activeState.attachedShaders, crStateFakeDecRefCountCB, NULL); crFreeHashtable(pProgram->activeState.attachedShaders, crStateFreeGLSLShader); pProgram->activeState.attachedShaders = NULL; } for (i=0; i<pProgram->activeState.cAttribs; ++i) { crFree(pProgram->activeState.pAttribs[i].name); } if (pProgram->activeState.pAttribs) crFree(pProgram->activeState.pAttribs); /*copy current state to active state*/ crMemcpy(&pProgram->activeState, &pProgram->currentState, sizeof(CRGLSLProgramState)); pProgram->activeState.attachedShaders = crAllocHashtable(); if (!pProgram->activeState.attachedShaders) { crWarning("crStateLinkProgram: Out of memory!"); return; } crHashtableWalk(pProgram->currentState.attachedShaders, crStateCopyShaderCB, pProgram); /*that's not a bug, note the memcpy above*/ if (pProgram->activeState.pAttribs) { pProgram->activeState.pAttribs = (CRGLSLAttrib *) crAlloc(pProgram->activeState.cAttribs * sizeof(CRGLSLAttrib)); } for (i=0; i<pProgram->activeState.cAttribs; ++i) { crMemcpy(&pProgram->activeState.pAttribs[i], &pProgram->currentState.pAttribs[i], sizeof(CRGLSLAttrib)); pProgram->activeState.pAttribs[i].name = crStrdup(pProgram->currentState.pAttribs[i].name); } crStateFreeProgramUniforms(pProgram); }
static void stubDestroyContextLocked( ContextInfo *context ) { unsigned long contextId = context->id; if (context->type == NATIVE) { #ifdef WINDOWS stub.wsInterface.wglDeleteContext( context->hglrc ); #elif defined(Darwin) stub.wsInterface.CGLDestroyContext( context->cglc ); #elif defined(GLX) stub.wsInterface.glXDestroyContext( context->dpy, context->glxContext ); #endif } else if (context->type == CHROMIUM) { /* Have pack SPU or tilesort SPU, etc. destroy the context */ CRASSERT(context->spuContext >= 0); stub.spu->dispatch_table.DestroyContext( context->spuContext ); crHashtableWalk(stub.windowTable, stubWindowCheckOwnerCB, context); #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) if (context->spuConnection) { stub.spu->dispatch_table.VBoxConDestroy(context->spuConnection); context->spuConnection = 0; } #endif } #ifdef GLX crFreeHashtable(context->pGLXPixmapsHash, crFree); #endif crHashtableDelete(stub.contextTable, contextId, NULL); }
static void RENDER_APIENTRY renderspuWindowDestroy( GLint win ) { WindowInfo *window; GET_CONTEXT(pOldCtx); CRASSERT(win >= 0); window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win); if (window) { crDebug("Render SPU: Destroy window (%d)", win); renderspu_SystemDestroyWindow( window ); /* remove window info from hash table, and free it */ crHashtableDelete(render_spu.windowTable, win, crFree); /* check if this window is bound to some ctx. Note: window pointer is already freed here */ crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window); /* restore current context */ { GET_CONTEXT(pNewCtx); if (pNewCtx!=pOldCtx) { renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->id:0, 0, pOldCtx ? pOldCtx->id:0); } } } else { crDebug("Render SPU: Attempt to destroy invalid window (%d)", win); } }
static void stubCheckWindowsState(void) { ContextInfo *context = stubGetCurrentContext(); CRASSERT(stub.trackWindowSize || stub.trackWindowPos); if (!context) return; #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) if (stub.bRunningUnderWDDM) return; #endif #if defined(CR_NEWWINTRACK) && !defined(WINDOWS) crLockMutex(&stub.mutex); #endif stubCheckWindowState(context->currentDrawable, GL_TRUE); crHashtableWalk(stub.windowTable, stubCheckWindowsCB, context); #if defined(CR_NEWWINTRACK) && !defined(WINDOWS) crUnlockMutex(&stub.mutex); #endif }
DECLEXPORT(void) renderspuSetRootVisibleRegion(GLint cRects, GLint *pRects) { #ifdef RT_OS_DARWIN renderspu_SystemSetRootVisibleRegion(cRects, pRects); crHashtableWalk(render_spu.windowTable, renderspuWindowVisibleRegionCB, NULL); #endif }
DECLEXPORT(void) STATE_APIENTRY crStateGLSLSwitch(CRContext *from, CRContext *to) { if (to->glsl.bResyncNeeded) { to->glsl.bResyncNeeded = GL_FALSE; crHashtableWalk(to->glsl.shaders, crStateGLSLCreateShadersCB, to); crHashtableWalk(to->glsl.programs, crStateGLSLCreateProgramCB, to); crHashtableWalk(to->glsl.shaders, crStateGLSLSyncShadersCB, NULL); } if (to->glsl.activeProgram != from->glsl.activeProgram) { diff_api.UseProgram(to->glsl.activeProgram ? to->glsl.activeProgram->hwid : 0); } }
DECLEXPORT(GLuint) STATE_APIENTRY crStateBufferHWIDtoID(GLuint hwid) { CRContext *g = GetCurrentContext(); crCheckIDHWID_t parms; parms.id = hwid; parms.hwid = hwid; crHashtableWalk(g->shared->buffersTable, crStateCheckBufferHWIDCB, &parms); return parms.id; }
DECLEXPORT(GLuint) STATE_APIENTRY crStateGLSLProgramHWIDtoID(GLuint hwid) { CRContext *g = GetCurrentContext(); crCheckIDHWID_t parms; parms.id = hwid; parms.hwid = hwid; crHashtableWalk(g->glsl.programs, crStateCheckProgramHWIDCB, &parms); return parms.id; }
int32_t DLM_APIENTRY crDLMSaveState(void) { CRDLMContextState *pListState = CURRENT_STATE(); if (pListState) crHashtableWalk(pListState->dlm->displayLists, crDLMSaveListsCb, (void *)NULL); else crDebug("Saving Display Lists: no data to save."); return 0; }
void DLM_APIENTRY crDLMSendAllDLMLists(CRDLM *dlm, SPUDispatchTable *dispatchTable) { struct sendListsCallbackParms parms; /* This is how we pass our parameter information to the callback routine - * through a pointer to this local structure. */ parms.dlm = dlm; parms.dispatchTable = dispatchTable; crHashtableWalk(dlm->displayLists, sendListsCallback, (void *)&parms); }
/** * This is called when we exit. * We call all the SPU's cleanup functions. */ static void stubSPUTearDownLocked(void) { crDebug("stubSPUTearDownLocked"); #ifdef WINDOWS # ifndef CR_NEWWINTRACK stubUninstallWindowMessageHook(); # endif #endif #ifdef CR_NEWWINTRACK ASMAtomicWriteBool(&stub.bShutdownSyncThread, true); #endif //delete all created contexts stubMakeCurrent( NULL, NULL); /* the lock order is windowTable->contextTable (see wglMakeCurrent_prox, glXMakeCurrent) * this is why we need to take a windowTable lock since we will later do stub.windowTable access & locking */ crHashtableLock(stub.windowTable); crHashtableWalk(stub.contextTable, hsWalkStubDestroyContexts, NULL); crHashtableUnlock(stub.windowTable); /* shutdown, now trap any calls to a NULL dispatcher */ crSPUCopyDispatchTable(&glim, &stubNULLDispatch); crSPUUnloadChain(stub.spu); stub.spu = NULL; #ifndef Linux crUnloadOpenGL(); #endif #ifndef WINDOWS crNetTearDown(); #endif #ifdef GLX if (stub.xshmSI.shmid>=0) { shmctl(stub.xshmSI.shmid, IPC_RMID, 0); shmdt(stub.xshmSI.shmaddr); } crFreeHashtable(stub.pGLXPixmapsHash, crFree); #endif crFreeHashtable(stub.windowTable, crFree); crFreeHashtable(stub.contextTable, NULL); crMemset(&stub, 0, sizeof(stub)); }
DECLEXPORT(void) STATE_APIENTRY crStateGLSLSwitch(CRContext *from, CRContext *to) { GLboolean fForceUseProgramSet = GL_FALSE; if (to->glsl.bResyncNeeded) { to->glsl.bResyncNeeded = GL_FALSE; crHashtableWalk(to->glsl.shaders, crStateGLSLCreateShadersCB, to); crHashtableWalk(to->glsl.programs, crStateGLSLCreateProgramCB, to); /* crStateGLSLCreateProgramCB changes the current program, ensure we have the proper program re-sored */ fForceUseProgramSet = GL_TRUE; crHashtableWalk(to->glsl.shaders, crStateGLSLSyncShadersCB, NULL); } if (to->glsl.activeProgram != from->glsl.activeProgram || fForceUseProgramSet) { diff_api.UseProgram(to->glsl.activeProgram ? to->glsl.activeProgram->hwid : 0); } }
static void replicatespuReplicateTextures(CRContext *tempState, CRContext *state) { CRTextureState *texstate = &(state->texture); /* use unit 0 for sending textures */ if (replicate_spu.swap) crPackActiveTextureARBSWAP(GL_TEXTURE0); else crPackActiveTextureARB(GL_TEXTURE0); /* replicate all texture objects */ crHashtableWalk(state->shared->textureTable, TextureObjDiffCallback, tempState); /* default texture objects */ { CRbitvalue *bitID = NULL, *nbitID = NULL; /* not used */ GLboolean alwaysDirty = GL_TRUE; crStateTextureObjectDiff(tempState, bitID, nbitID, &texstate->base1D, alwaysDirty); crStateTextureObjectDiff(tempState, bitID, nbitID, &texstate->base2D, alwaysDirty); crStateTextureObjectDiff(tempState, bitID, nbitID, &texstate->base3D, alwaysDirty); crStateTextureObjectDiff(tempState, bitID, nbitID, &texstate->baseCubeMap, alwaysDirty); crStateTextureObjectDiff(tempState, bitID, nbitID, &texstate->baseRect, alwaysDirty); } /* restore unit 0 bindings */ if (replicate_spu.swap) { crPackActiveTextureARBSWAP(GL_TEXTURE0); crPackBindTextureSWAP(GL_TEXTURE_1D, texstate->unit[0].currentTexture1D->name); crPackBindTextureSWAP(GL_TEXTURE_2D, texstate->unit[0].currentTexture2D->name); crPackBindTextureSWAP(GL_TEXTURE_3D, texstate->unit[0].currentTexture3D->name); crPackBindTextureSWAP(GL_TEXTURE_CUBE_MAP_ARB, texstate->unit[0].currentTextureCubeMap->name); crPackBindTextureSWAP(GL_TEXTURE_RECTANGLE_NV, texstate->unit[0].currentTextureRect->name); } else { crPackActiveTextureARB(GL_TEXTURE0); crPackBindTexture(GL_TEXTURE_1D, texstate->unit[0].currentTexture1D->name); crPackBindTexture(GL_TEXTURE_2D, texstate->unit[0].currentTexture2D->name); crPackBindTexture(GL_TEXTURE_3D, texstate->unit[0].currentTexture3D->name); crPackBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texstate->unit[0].currentTextureCubeMap->name); crPackBindTexture(GL_TEXTURE_RECTANGLE_NV, texstate->unit[0].currentTextureRect->name); } /* finally, set active texture unit again */ crPackActiveTextureARB(GL_TEXTURE0 + texstate->curTextureUnit); }
int32_t DLM_APIENTRY crDLMSaveState(CRDLM *dlm, PSSMHANDLE pSSM) { uint32_t ui32; int32_t rc; CRDLMSaveListsCbArg arg; arg.pSSM = pSSM; arg.err = 0; /* Save number of Display Lists assigned to current DLM context. */ ui32 = (uint32_t)crHashtableNumElements(dlm->displayLists); rc = SSMR3PutU32(pSSM, ui32); AssertRCReturn(rc, rc); crHashtableWalk(dlm->displayLists, crDLMSaveListsCb, (void *)&arg); return arg.err == 0; }
DECLEXPORT(int32_t) crVBoxServerSetOffscreenRendering(GLboolean value) { if (cr_server.bForceOffscreenRendering==value) { return VINF_SUCCESS; } if (value && !crServerSupportRedirMuralFBO()) { return VERR_NOT_SUPPORTED; } cr_server.bForceOffscreenRendering=value; crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL); return VINF_SUCCESS; }
DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex) { crDebug("crVBoxServerUnmapScreen(%i)", sIndex); if (sIndex<0 || sIndex>=cr_server.screenCount) return VERR_INVALID_PARAMETER; if (MAPPED(SCREEN(sIndex))) { SCREEN(sIndex).winID = 0; renderspuSetWindowId(0); crHashtableWalk(cr_server.muralTable, crVBoxServerReparentMuralCB, &sIndex); } renderspuSetWindowId(SCREEN(0).winID); return VINF_SUCCESS; }
static void crStateFreeGLSLProgram(void *data) { CRGLSLProgram* pProgram = (CRGLSLProgram *) data; crFreeHashtable(pProgram->currentState.attachedShaders, crStateShaderDecRefCount); if (pProgram->activeState.attachedShaders) { CRContext *g = GetCurrentContext(); crHashtableWalk(pProgram->activeState.attachedShaders, crStateFakeDecRefCountCB, g); crFreeHashtable(pProgram->activeState.attachedShaders, crStateFreeGLSLShader); } crStateFreeProgramAttribs(pProgram); crStateFreeProgramUniforms(pProgram); crFree(pProgram); }
void renderspuWindowTerm( WindowInfo *window ) { GET_CONTEXT(pOldCtx); /* ensure no concurrent draws can take place */ renderspuVBoxCompositorSet(window, NULL); renderspuVBoxPresentBlitterCleanup(window); renderspu_SystemDestroyWindow( window ); RTCritSectDelete(&window->CompositorLock); /* check if this window is bound to some ctx. Note: window pointer is already freed here */ crHashtableWalk(render_spu.contextTable, renderspuCheckCurrentCtxWindowCB, window); /* restore current context */ { GET_CONTEXT(pNewCtx); if (pNewCtx!=pOldCtx) { renderspuMakeCurrent(pOldCtx&&pOldCtx->currentWindow ? pOldCtx->currentWindow->BltInfo.Base.id:CR_RENDER_DEFAULT_WINDOW_ID, 0, pOldCtx ? pOldCtx->BltInfo.Base.id:CR_RENDER_DEFAULT_CONTEXT_ID); } } }
int DLM_APIENTRY crDLMGetReferences(CRDLM *dlm, unsigned long listIdentifier, int firstIndex, int sizeofBuffer, unsigned int *buffer) { DLMListInfo *listInfo; listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listIdentifier); if (listInfo) { struct getRefsCallbackParms cbParms; cbParms.remainingOffset = firstIndex; cbParms.remainingCount = sizeofBuffer; cbParms.buffer = buffer; cbParms.totalCount = 0; crHashtableWalk(listInfo->references, getRefsCallback, (void *)&cbParms); return cbParms.totalCount; } else { /* No list exists; it therefore has no references */ return 0; } }
void stubDestroyWindow( GLint con, GLint window ) { WindowInfo *winInfo = (WindowInfo *) crHashtableSearch(stub.windowTable, (unsigned int) window); if (winInfo && winInfo->type == CHROMIUM && stub.spu) { crHashtableLock(stub.windowTable); stub.spu->dispatch_table.VBoxWindowDestroy(con, winInfo->spuWindow ); #ifdef WINDOWS if (winInfo->hVisibleRegion != INVALID_HANDLE_VALUE) { DeleteObject(winInfo->hVisibleRegion); } #elif defined(GLX) if (winInfo->pVisibleRegions) { XFree(winInfo->pVisibleRegions); } # ifdef CR_NEWWINTRACK if (winInfo->syncDpy) { XCloseDisplay(winInfo->syncDpy); } # endif #endif stubForcedFlush(con); crHashtableWalk(stub.contextTable, stubWindowCleanupForContextsCB, winInfo); crHashtableDelete(stub.windowTable, window, crFree); crHashtableUnlock(stub.windowTable); } }
static int renderSPUCleanup(void) { renderspuVBoxCompositorClearAll(); if (render_spu.blitterTable) { crFreeHashtable(render_spu.blitterTable, DeleteBlitterCallback); render_spu.blitterTable = NULL; } else { crHashtableWalk(render_spu.windowTable, renderspuBlitterCleanupCB, NULL); crHashtableWalk(render_spu.dummyWindowTable, renderspuBlitterCleanupCB, NULL); } renderspuSetDefaultSharedContext(NULL); crFreeHashtable(render_spu.contextTable, DeleteContextCallback); render_spu.contextTable = NULL; crFreeHashtable(render_spu.windowTable, DeleteWindowCallback); render_spu.windowTable = NULL; crFreeHashtable(render_spu.dummyWindowTable, DeleteWindowCallback); render_spu.dummyWindowTable = NULL; crFreeHashtable(render_spu.barrierHash, crFree); render_spu.barrierHash = NULL; #ifdef RT_OS_DARWIN # ifndef VBOX_WITH_COCOA_QT render_spu.fInit = false; DisposeEventHandlerUPP(render_spu.hParentEventHandler); ReleaseWindowGroup(render_spu.pMasterGroup); ReleaseWindowGroup(render_spu.pParentGroup); if (render_spu.hRootVisibleRegion) { DisposeRgn(render_spu.hRootVisibleRegion); render_spu.hRootVisibleRegion = 0; } render_spu.currentBufferName = 1; render_spu.uiDockUpdateTS = 0; RTSemFastMutexDestroy(render_spu.syncMutex); # else /* VBOX_WITH_COCOA_QT */ # endif /* VBOX_WITH_COCOA_QT */ #endif /* RT_OS_DARWIN */ #ifdef RT_OS_WINDOWS if (render_spu.dwWinThreadId) { HANDLE hNative; hNative = OpenThread(SYNCHRONIZE|THREAD_QUERY_INFORMATION|THREAD_TERMINATE, false, render_spu.dwWinThreadId); if (!hNative) { crWarning("Failed to get handle for window thread(%#x)", GetLastError()); } if (PostThreadMessage(render_spu.dwWinThreadId, WM_QUIT, 0, 0)) { WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE); /*wait for os thread to actually finish*/ if (hNative && WaitForSingleObject(hNative, 3000)==WAIT_TIMEOUT) { crDebug("Wait failed, terminating"); if (!TerminateThread(hNative, 1)) { crWarning("TerminateThread failed"); } } } if (hNative) { CloseHandle(hNative); } } CloseHandle(render_spu.hWinThreadReadyEvent); render_spu.hWinThreadReadyEvent = NULL; #endif crUnloadOpenGL(); #ifdef CHROMIUM_THREADSAFE crFreeTSD(&_RenderTSD); #endif return 1; }
void SERVER_DISPATCH_APIENTRY crServerDispatchDestroyContext( GLint ctx ) { CRContextInfo *crCtxInfo; CRContext *crCtx; int32_t client; CRClientNode *pNode; int found=false; crCtxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, ctx); if (!crCtxInfo) { crWarning("CRServer: DestroyContext invalid context %d", ctx); return; } crCtx = crCtxInfo->pContext; CRASSERT(crCtx); crDebug("CRServer: DestroyContext context %d", ctx); if (cr_server.currentCtxInfo == crCtxInfo) { CRMuralInfo *dummyMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits); crServerPerformMakeCurrent(dummyMural, &cr_server.MainContextInfo); CRASSERT(cr_server.currentCtxInfo == &cr_server.MainContextInfo); } crHashtableWalk(cr_server.muralTable, crServerCleanupMuralCtxUsageCB, crCtx); crCtxInfo->currentMural = NULL; crHashtableDelete(cr_server.contextTable, ctx, NULL); crStateDestroyContext( crCtx ); if (crCtxInfo->CreateInfo.pszDpyName) crFree(crCtxInfo->CreateInfo.pszDpyName); if (crCtxInfo->SpuContext >= 0) cr_server.head_spu->dispatch_table.DestroyContext(crCtxInfo->SpuContext); crFree(crCtxInfo); if (cr_server.curClient) { /* If we delete our current context, default back to the null context */ if (cr_server.curClient->currentCtxInfo == crCtxInfo) { cr_server.curClient->currentContextNumber = -1; cr_server.curClient->currentCtxInfo = &cr_server.MainContextInfo; } found = crServerRemoveClientContext(cr_server.curClient, ctx); /*Some application call destroy context not in a thread where it was created...have do deal with it.*/ if (!found) { for (client=0; client<cr_server.numClients; ++client) { if (cr_server.clients[client]==cr_server.curClient) continue; found = crServerRemoveClientContext(cr_server.clients[client], ctx); if (found) break; } } if (!found) { pNode=cr_server.pCleanupClient; while (pNode && !found) { found = crServerRemoveClientContext(pNode->pClient, ctx); pNode = pNode->next; } } CRASSERT(found); } /*Make sure this context isn't active in other clients*/ for (client=0; client<cr_server.numClients; ++client) { if (cr_server.clients[client]->currentCtxInfo == crCtxInfo) { cr_server.clients[client]->currentContextNumber = -1; cr_server.clients[client]->currentCtxInfo = &cr_server.MainContextInfo; } } pNode=cr_server.pCleanupClient; while (pNode) { if (pNode->pClient->currentCtxInfo == crCtxInfo) { pNode->pClient->currentContextNumber = -1; pNode->pClient->currentCtxInfo = &cr_server.MainContextInfo; } pNode = pNode->next; } CRASSERT(cr_server.currentCtxInfo != crCtxInfo); }
/* * XXX this function might need some testing/fixing. */ void crStateBufferObjectSwitch(CRBufferObjectBits *bb, CRbitvalue *bitID, CRContext *fromCtx, CRContext *toCtx) { const CRBufferObjectState *from = &(fromCtx->bufferobject); CRBufferObjectState *to = &(toCtx->bufferobject); int i; if (!HaveBufferObjectExtension()) return; if (toCtx->shared->bVBOResyncNeeded) { CRClientPointer *cp; GLboolean locked = toCtx->client.array.locked; crHashtableWalk(toCtx->shared->buffersTable, crStateBufferObjectSyncCB, to); toCtx->shared->bVBOResyncNeeded = GL_FALSE; /*@todo, move to state_client.c*/ cp = &toCtx->client.array.v; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.VertexPointer(cp->size, cp->type, cp->stride, cp->p); } cp = &toCtx->client.array.c; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.ColorPointer(cp->size, cp->type, cp->stride, cp->p); } cp = &toCtx->client.array.f; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.FogCoordPointerEXT(cp->type, cp->stride, cp->p); } cp = &toCtx->client.array.s; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.SecondaryColorPointerEXT(cp->size, cp->type, cp->stride, cp->p); } cp = &toCtx->client.array.e; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.EdgeFlagPointer(cp->stride, cp->p); } cp = &toCtx->client.array.i; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.IndexPointer(cp->type, cp->stride, cp->p); } cp = &toCtx->client.array.n; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.NormalPointer(cp->type, cp->stride, cp->p); } for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++) { cp = &toCtx->client.array.t[i]; if (cp->buffer && (cp->buffer->id || locked)) { if (diff_api.ActiveTextureARB) diff_api.ActiveTextureARB(i+GL_TEXTURE0_ARB); diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.TexCoordPointer(cp->size, cp->type, cp->stride, cp->p); } } if (diff_api.ActiveTextureARB) diff_api.ActiveTextureARB(toCtx->client.curClientTextureUnit+GL_TEXTURE0_ARB); #ifdef CR_NV_vertex_program for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++) { cp = &toCtx->client.array.a[i]; if (cp->buffer && (cp->buffer->id || locked)) { diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, cp->buffer->hwid); diff_api.VertexAttribPointerARB(i, cp->size, cp->type, cp->normalized, cp->stride, cp->p); } } #endif diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, to->arrayBuffer->hwid); diff_api.BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, to->elementsBuffer->hwid); #ifdef CR_ARB_pixel_buffer_object diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, to->packBuffer->hwid); diff_api.BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, to->unpackBuffer->hwid); #endif } else { crStateBufferObjectIntCmp(bb, bitID, fromCtx, toCtx, GL_TRUE); } }
DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM) { int32_t rc, i; uint32_t ui32; GLboolean b; unsigned long key; #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE unsigned long ctxID=-1, winID=-1; #endif /* We shouldn't be called if there's no clients at all*/ CRASSERT(cr_server.numClients>0); /* @todo it's hack atm */ /* We want to be called only once to save server state but atm we're being called from svcSaveState * for every connected client (e.g. guest opengl application) */ if (!cr_server.bIsInSavingState) /* It's first call */ { cr_server.bIsInSavingState = GL_TRUE; /* Store number of clients */ rc = SSMR3PutU32(pSSM, (uint32_t) cr_server.numClients); AssertRCReturn(rc, rc); g_hackVBoxServerSaveLoadCallsLeft = cr_server.numClients; } g_hackVBoxServerSaveLoadCallsLeft--; /* Do nothing until we're being called last time */ if (g_hackVBoxServerSaveLoadCallsLeft>0) { return VINF_SUCCESS; } /* Save rendering contexts creation info */ ui32 = crHashtableNumElements(cr_server.pContextCreateInfoTable); rc = SSMR3PutU32(pSSM, (uint32_t) ui32); AssertRCReturn(rc, rc); crHashtableWalk(cr_server.pContextCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM); #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE /* Save current win and ctx IDs, as we'd rebind contexts when saving textures */ if (cr_server.curClient) { ctxID = cr_server.curClient->currentContextNumber; winID = cr_server.curClient->currentWindow; } #endif /* Save contexts state tracker data */ /* @todo For now just some blind data dumps, * but I've a feeling those should be saved/restored in a very strict sequence to * allow diff_api to work correctly. * Should be tested more with multiply guest opengl apps working when saving VM snapshot. */ crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, pSSM); #ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE /* Restore original win and ctx IDs*/ if (cr_server.curClient) { crServerDispatchMakeCurrent(winID, 0, ctxID); } #endif /* Save windows creation info */ ui32 = crHashtableNumElements(cr_server.pWindowCreateInfoTable); rc = SSMR3PutU32(pSSM, (uint32_t) ui32); AssertRCReturn(rc, rc); crHashtableWalk(cr_server.pWindowCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM); /* Save cr_server.muralTable * @todo we don't need it all, just geometry info actually */ ui32 = crHashtableNumElements(cr_server.muralTable); /* There should be default mural always */ CRASSERT(ui32>=1); rc = SSMR3PutU32(pSSM, (uint32_t) ui32-1); AssertRCReturn(rc, rc); crHashtableWalk(cr_server.muralTable, crVBoxServerSaveMuralCB, pSSM); /* Save starting free context and window IDs */ rc = SSMR3PutMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool)); AssertRCReturn(rc, rc); /* Save clients info */ for (i = 0; i < cr_server.numClients; i++) { if (cr_server.clients[i] && cr_server.clients[i]->conn) { CRClient *pClient = cr_server.clients[i]; rc = SSMR3PutU32(pSSM, pClient->conn->u32ClientID); AssertRCReturn(rc, rc); rc = SSMR3PutU32(pSSM, pClient->conn->vMajor); AssertRCReturn(rc, rc); rc = SSMR3PutU32(pSSM, pClient->conn->vMinor); AssertRCReturn(rc, rc); rc = SSMR3PutMem(pSSM, pClient, sizeof(*pClient)); AssertRCReturn(rc, rc); if (pClient->currentCtx && pClient->currentContextNumber>=0) { b = crHashtableGetDataKey(cr_server.contextTable, pClient->currentCtx, &key); CRASSERT(b); rc = SSMR3PutMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); } if (pClient->currentMural && pClient->currentWindow>=0) { b = crHashtableGetDataKey(cr_server.muralTable, pClient->currentMural, &key); CRASSERT(b); rc = SSMR3PutMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); } } } cr_server.bIsInSavingState = GL_FALSE; return VINF_SUCCESS; }
DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version) { int32_t rc, i; uint32_t ui, uiNumElems; unsigned long key; if (!cr_server.bIsInLoadingState) { /* AssertRCReturn(...) will leave us in loading state, but it doesn't matter as we'd be failing anyway */ cr_server.bIsInLoadingState = GL_TRUE; /* Read number of clients */ rc = SSMR3GetU32(pSSM, &g_hackVBoxServerSaveLoadCallsLeft); AssertRCReturn(rc, rc); } g_hackVBoxServerSaveLoadCallsLeft--; /* Do nothing until we're being called last time */ if (g_hackVBoxServerSaveLoadCallsLeft>0) { return VINF_SUCCESS; } if (version!=SHCROGL_SSM_VERSION) { return VERR_SSM_DATA_UNIT_FORMAT_CHANGED; } /* Load and recreate rendering contexts */ rc = SSMR3GetU32(pSSM, &uiNumElems); AssertRCReturn(rc, rc); for (ui=0; ui<uiNumElems; ++ui) { CRCreateInfo_t createInfo; char psz[200]; GLint ctxID; CRContext* pContext; rc = SSMR3GetMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo)); AssertRCReturn(rc, rc); if (createInfo.pszDpyName) { rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL); AssertRCReturn(rc, rc); createInfo.pszDpyName = psz; } ctxID = crServerDispatchCreateContextEx(createInfo.pszDpyName, createInfo.visualBits, 0, key, createInfo.internalID); CRASSERT((int64_t)ctxID == (int64_t)key); pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key); CRASSERT(pContext); pContext->shared->id=-1; } /* Restore context state data */ for (ui=0; ui<uiNumElems; ++ui) { CRContext *pContext; rc = SSMR3GetMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key); CRASSERT(pContext); rc = crStateLoadContext(pContext, cr_server.contextTable, pSSM); AssertRCReturn(rc, rc); } /* Load windows */ rc = SSMR3GetU32(pSSM, &uiNumElems); AssertRCReturn(rc, rc); for (ui=0; ui<uiNumElems; ++ui) { CRCreateInfo_t createInfo; char psz[200]; GLint winID; unsigned long key; rc = SSMR3GetMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo)); AssertRCReturn(rc, rc); if (createInfo.pszDpyName) { rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL); AssertRCReturn(rc, rc); createInfo.pszDpyName = psz; } winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key); CRASSERT((int64_t)winID == (int64_t)key); } /* Load cr_server.muralTable */ rc = SSMR3GetU32(pSSM, &uiNumElems); AssertRCReturn(rc, rc); for (ui=0; ui<uiNumElems; ++ui) { CRMuralInfo muralInfo; rc = SSMR3GetMem(pSSM, &key, sizeof(key)); AssertRCReturn(rc, rc); rc = SSMR3GetMem(pSSM, &muralInfo, sizeof(muralInfo)); AssertRCReturn(rc, rc); if (muralInfo.pVisibleRects) { muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects); if (!muralInfo.pVisibleRects) { return VERR_NO_MEMORY; } rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects); AssertRCReturn(rc, rc); } /* Restore windows geometry info */ crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height); crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY); /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/ if (muralInfo.bReceivedRects) { crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects); } crServerDispatchWindowShow(key, muralInfo.bVisible); if (muralInfo.pVisibleRects) { crFree(muralInfo.pVisibleRects); } } /* Load starting free context and window IDs */ rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool)); CRASSERT(rc == VINF_SUCCESS); /* Load clients info */ for (i = 0; i < cr_server.numClients; i++) { if (cr_server.clients[i] && cr_server.clients[i]->conn) { CRClient *pClient = cr_server.clients[i]; CRClient client; unsigned long ctxID=-1, winID=-1; rc = SSMR3GetU32(pSSM, &ui); AssertRCReturn(rc, rc); /* If this assert fires, then we should search correct client in the list first*/ CRASSERT(ui == pClient->conn->u32ClientID); if (version>=4) { rc = SSMR3GetU32(pSSM, &pClient->conn->vMajor); AssertRCReturn(rc, rc); rc = SSMR3GetU32(pSSM, &pClient->conn->vMinor); AssertRCReturn(rc, rc); } rc = SSMR3GetMem(pSSM, &client, sizeof(client)); CRASSERT(rc == VINF_SUCCESS); client.conn = pClient->conn; /* We can't reassign client number, as we'd get wrong results in TranslateTextureID * and fail to bind old textures. */ /*client.number = pClient->number;*/ *pClient = client; pClient->currentContextNumber = -1; pClient->currentCtx = cr_server.DummyContext; pClient->currentMural = NULL; pClient->currentWindow = -1; cr_server.curClient = pClient; if (client.currentCtx && client.currentContextNumber>=0) { rc = SSMR3GetMem(pSSM, &ctxID, sizeof(ctxID)); AssertRCReturn(rc, rc); client.currentCtx = (CRContext*) crHashtableSearch(cr_server.contextTable, ctxID); CRASSERT(client.currentCtx); //pClient->currentCtx = client.currentCtx; //pClient->currentContextNumber = ctxID; } if (client.currentMural && client.currentWindow>=0) { rc = SSMR3GetMem(pSSM, &winID, sizeof(winID)); AssertRCReturn(rc, rc); client.currentMural = (CRMuralInfo*) crHashtableSearch(cr_server.muralTable, winID); CRASSERT(client.currentMural); //pClient->currentMural = client.currentMural; //pClient->currentWindow = winID; } /* Restore client active context and window */ crServerDispatchMakeCurrent(winID, 0, ctxID); if (0) { CRContext *tmpCtx; CRCreateInfo_t *createInfo; GLfloat one[4] = { 1, 1, 1, 1 }; GLfloat amb[4] = { 0.4f, 0.4f, 0.4f, 1.0f }; crServerDispatchMakeCurrent(winID, 0, ctxID); crHashtableWalk(client.currentCtx->shared->textureTable, crVBoxServerSyncTextureCB, client.currentCtx); crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base1D, GL_TRUE); crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base2D, GL_TRUE); crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base3D, GL_TRUE); #ifdef CR_ARB_texture_cube_map crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseCubeMap, GL_TRUE); #endif #ifdef CR_NV_texture_rectangle //@todo this doesn't work as expected //crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseRect, GL_TRUE); #endif /*cr_server.head_spu->dispatch_table.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); cr_server.head_spu->dispatch_table.LightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); cr_server.head_spu->dispatch_table.Lightfv(GL_LIGHT1, GL_DIFFUSE, one); cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING); cr_server.head_spu->dispatch_table.Enable(GL_LIGHT0); cr_server.head_spu->dispatch_table.Enable(GL_LIGHT1); cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE); cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);*/ //crStateViewport( 0, 0, 600, 600 ); //pClient->currentMural->viewportValidated = GL_FALSE; //cr_server.head_spu->dispatch_table.Viewport( 0, 0, 600, 600 ); //crStateMatrixMode(GL_PROJECTION); //cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION); //crStateLoadIdentity(); //cr_server.head_spu->dispatch_table.LoadIdentity(); //crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0); //cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0); //crStateMatrixMode(GL_MODELVIEW); //cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW); //crServerDispatchLoadIdentity(); //crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0); //cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0); //crServerDispatchLoadIdentity(); /*createInfo = (CRCreateInfo_t *) crHashtableSearch(cr_server.pContextCreateInfoTable, ctxID); CRASSERT(createInfo); tmpCtx = crStateCreateContext(NULL, createInfo->visualBits, NULL); CRASSERT(tmpCtx); crStateDiffContext(tmpCtx, client.currentCtx); crStateDestroyContext(tmpCtx);*/ } } } //crServerDispatchMakeCurrent(-1, 0, -1); cr_server.curClient = NULL; { GLenum err = crServerDispatchGetError(); if (err != GL_NO_ERROR) { crWarning("crServer: glGetError %d after loading snapshot", err); } } cr_server.bIsInLoadingState = GL_FALSE; return VINF_SUCCESS; }
static void crStateGLSLCreateProgramCB(unsigned long key, void *data1, void *data2) { CRGLSLProgram *pProgram = (CRGLSLProgram*) data1; CRContext *ctx = (CRContext *) data2; GLuint i; pProgram->hwid = diff_api.CreateProgram(); if (pProgram->linked) { CRASSERT(pProgram->activeState.attachedShaders); crHashtableWalk(pProgram->activeState.attachedShaders, crStateFixAttachedShaderHWIDsCB, ctx); crHashtableWalk(pProgram->activeState.attachedShaders, crStateAttachShaderCB, pProgram); for (i=0; i<pProgram->activeState.cAttribs; ++i) { diff_api.BindAttribLocation(pProgram->hwid, pProgram->activeState.pAttribs[i].index, pProgram->activeState.pAttribs[i].name); } if (pProgram->validated) diff_api.ValidateProgram(pProgram->hwid); diff_api.LinkProgram(pProgram->hwid); } diff_api.UseProgram(pProgram->hwid); for (i=0; i<pProgram->cUniforms; ++i) { GLint location; GLfloat *pFdata = (GLfloat*)pProgram->pUniforms[i].data; GLint *pIdata = (GLint*)pProgram->pUniforms[i].data; location = diff_api.GetUniformLocation(pProgram->hwid, pProgram->pUniforms[i].name); switch (pProgram->pUniforms[i].type) { case GL_FLOAT: diff_api.Uniform1fv(location, 1, pFdata); break; case GL_FLOAT_VEC2: diff_api.Uniform2fv(location, 1, pFdata); break; case GL_FLOAT_VEC3: diff_api.Uniform3fv(location, 1, pFdata); break; case GL_FLOAT_VEC4: diff_api.Uniform4fv(location, 1, pFdata); break; case GL_INT: case GL_BOOL: diff_api.Uniform1iv(location, 1, pIdata); break; case GL_INT_VEC2: case GL_BOOL_VEC2: diff_api.Uniform2iv(location, 1, pIdata); break; case GL_INT_VEC3: case GL_BOOL_VEC3: diff_api.Uniform3iv(location, 1, pIdata); break; case GL_INT_VEC4: case GL_BOOL_VEC4: diff_api.Uniform4iv(location, 1, pIdata); break; case GL_FLOAT_MAT2: diff_api.UniformMatrix2fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT3: diff_api.UniformMatrix3fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT4: diff_api.UniformMatrix4fv(location, 1, GL_FALSE, pFdata); break; case GL_SAMPLER_1D: case GL_SAMPLER_2D: case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: case GL_SAMPLER_1D_SHADOW: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_2D_RECT_ARB: case GL_SAMPLER_2D_RECT_SHADOW_ARB: diff_api.Uniform1iv(location, 1, pIdata); break; #ifdef CR_OPENGL_VERSION_2_1 case GL_FLOAT_MAT2x3: diff_api.UniformMatrix2x3fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT2x4: diff_api.UniformMatrix2x4fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT3x2: diff_api.UniformMatrix3x2fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT3x4: diff_api.UniformMatrix3x4fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT4x2: diff_api.UniformMatrix4x2fv(location, 1, GL_FALSE, pFdata); break; case GL_FLOAT_MAT4x3: diff_api.UniformMatrix4x3fv(location, 1, GL_FALSE, pFdata); break; #endif default: crWarning("crStateGLSLCreateProgramCB: unknown uniform type 0x%x", (GLint)pProgram->pUniforms[i].type); break; } crFree(pProgram->pUniforms[i].data); crFree(pProgram->pUniforms[i].name); } /*for (i=0; i<pProgram->cUniforms; ++i)*/ if (pProgram->pUniforms) crFree(pProgram->pUniforms); pProgram->pUniforms = NULL; pProgram->cUniforms = 0; crHashtableWalk(pProgram->activeState.attachedShaders, crStateDetachShaderCB, pProgram); crHashtableWalk(pProgram->currentState.attachedShaders, crStateAttachShaderCB, pProgram); }
/** * Get current clip rects intersected with dirty regions for whole screen. */ void vncspuGetScreenRects(RegionPtr reg) { REGION_EMPTY(reg); crHashtableWalk(vnc_spu.windowTable, WindowDirtyUnionCB, reg); }
static DECLCALLBACK(int) stubSyncThreadProc(RTTHREAD ThreadSelf, void *pvUser) { #ifdef WINDOWS MSG msg; # ifdef VBOX_WITH_WDDM static VBOXDISPMP_CALLBACKS VBoxDispMpTstCallbacks = {NULL, NULL, NULL}; HMODULE hVBoxD3D = NULL; VBOXCR_UPDATEWNDCB RegionsData; HRESULT hr; GLint spuConnection = 0; # endif #endif (void) pvUser; crDebug("Sync thread started"); #ifdef WINDOWS PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); # ifdef VBOX_WITH_WDDM hVBoxD3D = GetModuleHandle(VBOX_MODNAME_DISPD3D); if (hVBoxD3D) { hVBoxD3D = LoadLibrary(VBOX_MODNAME_DISPD3D); } if (hVBoxD3D) { PFNVBOXDISPMP_GETCALLBACKS pfnVBoxDispMpGetCallbacks; pfnVBoxDispMpGetCallbacks = (PFNVBOXDISPMP_GETCALLBACKS)GetProcAddress(hVBoxD3D, TEXT("VBoxDispMpGetCallbacks")); if (pfnVBoxDispMpGetCallbacks) { hr = pfnVBoxDispMpGetCallbacks(VBOXDISPMP_VERSION, &VBoxDispMpTstCallbacks); if (S_OK==hr) { CRASSERT(VBoxDispMpTstCallbacks.pfnEnableEvents); CRASSERT(VBoxDispMpTstCallbacks.pfnDisableEvents); CRASSERT(VBoxDispMpTstCallbacks.pfnGetRegions); hr = VBoxDispMpTstCallbacks.pfnEnableEvents(); if (hr != S_OK) { crWarning("VBoxDispMpTstCallbacks.pfnEnableEvents failed"); } else { crDebug("running with " VBOX_MODNAME_DISPD3D); stub.trackWindowVisibleRgn = 0; stub.bRunningUnderWDDM = true; #ifdef VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS crError("should not be here, visible rects should be processed in miniport!"); #endif } } else { crWarning("VBoxDispMpGetCallbacks failed"); } } } # endif /* VBOX_WITH_WDDM */ #endif /* WINDOWS */ crLockMutex(&stub.mutex); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) spuConnection = #endif stub.spu->dispatch_table.VBoxPackSetInjectThread(NULL); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) if (stub.bRunningUnderWDDM && !spuConnection) { crError("VBoxPackSetInjectThread failed!"); } #endif crUnlockMutex(&stub.mutex); RTThreadUserSignal(ThreadSelf); while(!stub.bShutdownSyncThread) { #ifdef WINDOWS if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { # ifdef VBOX_WITH_WDDM if (VBoxDispMpTstCallbacks.pfnGetRegions) { hr = VBoxDispMpTstCallbacks.pfnGetRegions(&RegionsData.Regions, 50); if (S_OK==hr) { RegionsData.fSendUpdateMsg = false; # if 0 uint32_t i; crDebug(">>>Regions for HWND(0x%x)>>>", RegionsData.Regions.hWnd); crDebug("Flags(0x%x)", RegionsData.Regions.pRegions->fFlags.Value); for (i = 0; i < RegionsData.Regions.pRegions->RectsInfo.cRects; ++i) { RECT *pRect = &RegionsData.Regions.pRegions->RectsInfo.aRects[i]; crDebug("Rect(%d): left(%d), top(%d), right(%d), bottom(%d)", i, pRect->left, pRect->top, pRect->right, pRect->bottom); } crDebug("<<<<<"); # endif /*hacky way to make sure window wouldn't be deleted in another thread as we hold hashtable lock here*/ crHashtableWalk(stub.windowTable, stubSyncTrUpdateWindowCB, &RegionsData); if (RegionsData.fSendUpdateMsg) { SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_NORMAL, 1000, NULL); } } else { if (WAIT_TIMEOUT!=hr) { crWarning("VBoxDispMpTstCallbacks.pfnGetRegions failed with 0x%x", hr); } crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL); } } else # endif { crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL); RTThreadSleep(50); } } else { if (WM_QUIT==msg.message) { crDebug("Sync thread got WM_QUIT"); break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } #else crLockMutex(&stub.mutex); crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL); crUnlockMutex(&stub.mutex); RTThreadSleep(50); #endif } #ifdef VBOX_WITH_WDDM if (VBoxDispMpTstCallbacks.pfnDisableEvents) { VBoxDispMpTstCallbacks.pfnDisableEvents(); } if (spuConnection) { stub.spu->dispatch_table.VBoxConDestroy(spuConnection); } if (hVBoxD3D) { FreeLibrary(hVBoxD3D); } #endif crDebug("Sync thread stopped"); return 0; }