static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( crThreadID() ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; packspuCreateFunctions(); crStateInit(); return &pack_functions; }
static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif #ifdef CHROMIUM_THREADSAFE crInitTSD(&_PackerTSD); crInitTSD(&_PackTSD); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) pack_spu.bIsWDDMCrHgsmi = isVBoxWDDMCrHgsmi(); #endif #ifdef VBOX_WITH_CRPACKSPU_DUMPER memset(&pack_spu.Dumper, 0, sizeof (pack_spu.Dumper)); #endif if (!CRPACKSPU_IS_WDDM_CRHGSMI()) { /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) NULL #endif ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; } packspuCreateFunctions(); crStateInit(); return &pack_functions; }
static SPUFunctions * packSPUInit( int id, SPU *child, SPU *self, unsigned int context_id, unsigned int num_contexts ) { ThreadInfo *thread; (void) context_id; (void) num_contexts; (void) child; (void) self; #if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS) crInitMutex(&_PackMutex); #endif pack_spu.id = id; packspuSetVBoxConfiguration( child ); #if defined(WINDOWS) && defined(VBOX_WITH_WDDM) pack_spu.bRunningUnderWDDM = !!GetModuleHandle(VBOX_MODNAME_DISPD3D); #endif if (!CRPACKSPU_IS_WDDM_CRHGSMI()) { /* This connects to the server, sets up the packer, etc. */ thread = packspuNewThread( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) NULL #endif ); if (!thread) { return NULL; } CRASSERT( thread == &(pack_spu.thread[0]) ); pack_spu.idxThreadInUse = 0; } packspuCreateFunctions(); crStateInit(); return &pack_functions; }
GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits ) { GET_THREAD(thread); static int num_calls = 0; int writeback = pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network; GLint return_val = (GLint) 0; if (!thread) { thread = packspuNewThread( crThreadID() ); } CRASSERT(thread); CRASSERT(thread->packer); crPackSetContext(thread->packer); if (pack_spu.swap) { crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback ); } else { crPackWindowCreate( dpyName, visBits, &return_val, &writeback ); } packspuFlush(thread); if (!(thread->netServer.conn->actual_network)) { return num_calls++; } else { while (writeback) crNetRecv(); if (pack_spu.swap) { return_val = (GLint) SWAP32(return_val); } return return_val; } }
GLint PACKSPU_APIENTRY packspu_VBoxWindowCreate( GLint con, const char *dpyName, GLint visBits ) { GET_THREAD(thread); static int num_calls = 0; int writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network; GLint return_val = (GLint) 0; ThreadInfo *curThread = thread; GLint retVal; if (CRPACKSPU_IS_WDDM_CRHGSMI()) { if (!con) { crError("connection expected!"); return 0; } thread = GET_THREAD_VAL_ID(con); } else { CRASSERT(!con); if (!thread) { thread = packspuNewThread( #if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST) NULL #endif ); } } CRASSERT(thread); CRASSERT(thread->packer); CRASSERT(crPackGetContext() == (curThread ? curThread->packer : NULL)); crPackSetContext(thread->packer); if (pack_spu.swap) { crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback ); } else { crPackWindowCreate( dpyName, visBits, &return_val, &writeback ); } packspuFlush(thread); if (!(thread->netServer.conn->actual_network)) { retVal = num_calls++; } else { CRPACKSPU_WRITEBACK_WAIT(thread, writeback); if (pack_spu.swap) { return_val = (GLint) SWAP32(return_val); } retVal = return_val; } if (CRPACKSPU_IS_WDDM_CRHGSMI()) { if (thread != curThread) { if (curThread) crPackSetContext(curThread->packer); else crPackSetContext(NULL); } } return retVal; }
GLint PACKSPU_APIENTRY packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx ) { GET_THREAD(thread); int writeback = 1; GLint serverCtx = (GLint) -1; int slot; #ifdef CHROMIUM_THREADSAFE crLockMutex(&_PackMutex); #endif if (!thread) { thread = packspuNewThread(crThreadID()); } CRASSERT(thread); CRASSERT(thread->packer); if (shareCtx > 0) { /* translate to server ctx id */ shareCtx -= MAGIC_OFFSET; if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) { shareCtx = pack_spu.context[shareCtx].serverCtx; } } crPackSetContext( thread->packer ); /* Pack the command */ if (pack_spu.swap) crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback ); else crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback ); /* Flush buffer and get return value */ packspuFlush(thread); if (!(thread->netServer.conn->actual_network)) { /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING * * The hack exists solely to make file networking work for now. This * is totally gross, but since the server expects the numbers to start * from 5000, we need to write them out this way. This would be * marginally less gross if the numbers (500 and 5000) were maybe * some sort of #define'd constants somewhere so the client and the * server could be aware of how each other were numbering things in * cases like file networking where they actually * care. * * -Humper * */ serverCtx = 5000; } else { while (writeback) crNetRecv(); if (pack_spu.swap) { serverCtx = (GLint) SWAP32(serverCtx); } if (serverCtx < 0) { #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_PackMutex); #endif crWarning("Failure in packspu_CreateContext"); return -1; /* failed */ } } /* find an empty context slot */ for (slot = 0; slot < pack_spu.numContexts; slot++) { if (!pack_spu.context[slot].clientState) { /* found empty slot */ break; } } if (slot == pack_spu.numContexts) { pack_spu.numContexts++; } /* Fill in the new context info */ /* XXX fix-up sharedCtx param here */ pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL); pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE; pack_spu.context[slot].serverCtx = serverCtx; #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_PackMutex); #endif return MAGIC_OFFSET + slot; }
void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx ) { GET_THREAD(thread); GLint serverCtx; ContextInfo *newCtx; if (!thread) { thread = packspuNewThread( crThreadID() ); } CRASSERT(thread); CRASSERT(thread->packer); if (ctx) { const int slot = ctx - MAGIC_OFFSET; CRASSERT(slot >= 0); CRASSERT(slot < pack_spu.numContexts); newCtx = &pack_spu.context[slot]; CRASSERT(newCtx->clientState); /* verify valid */ if (newCtx->fAutoFlush) { if (newCtx->currentThread && newCtx->currentThread != thread) { crLockMutex(&_PackMutex); /* do a flush for the previusly assigned thread * to ensure all commands issued there are submitted */ if (newCtx->currentThread && newCtx->currentThread->inUse && newCtx->currentThread->netServer.conn && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer) { packspuFlush((void *) newCtx->currentThread); } crUnlockMutex(&_PackMutex); } newCtx->currentThread = thread; } thread->currentContext = newCtx; crPackSetContext( thread->packer ); crStateMakeCurrent( newCtx->clientState ); //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current); serverCtx = pack_spu.context[slot].serverCtx; } else { thread->currentContext = NULL; crStateMakeCurrent( NULL ); newCtx = NULL; serverCtx = 0; } if (pack_spu.swap) crPackMakeCurrentSWAP( window, nativeWindow, serverCtx ); else crPackMakeCurrent( window, nativeWindow, serverCtx ); { GET_THREAD(t); (void) t; CRASSERT(t); } }