void FEEDBACKSPU_APIENTRY feedbackspu_DestroyContext( GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&feedback_spu.mutex); #endif feedback_spu.child.DestroyContext(ctx); if (ctx) { int slot; for (slot=0; slot<feedback_spu.numContexts; ++slot) if (feedback_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < feedback_spu.numContexts); crStateDestroyContext(feedback_spu.context[slot].clientState); feedback_spu.context[slot].clientState = NULL; feedback_spu.context[slot].clientCtx = 0; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&feedback_spu.mutex); #endif }
static void ARRAYSPU_APIENTRY arrayspu_DestroyContext( GLint ctx ) { #ifdef CHROMIUM_THREADSAFE crLockMutex(&_ArrayMutex); #endif array_spu.child.DestroyContext(ctx); if (ctx) { int slot; for (slot=0; slot<array_spu.numContexts; ++slot) if (array_spu.context[slot].clientCtx == ctx) break; CRASSERT(slot < array_spu.numContexts); crStateDestroyContext(array_spu.context[slot].clientState); array_spu.context[slot].clientState = NULL; array_spu.context[slot].clientCtx = 0; } #ifdef CHROMIUM_THREADSAFE crUnlockMutex(&_ArrayMutex); #endif }
void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx ) { const int slot = ctx - MAGIC_OFFSET; ContextInfo *context; GET_THREAD(thread); CRASSERT(slot >= 0); CRASSERT(slot < pack_spu.numContexts); CRASSERT(thread); context = &(pack_spu.context[slot]); if (pack_spu.swap) crPackDestroyContextSWAP( context->serverCtx ); else crPackDestroyContext( context->serverCtx ); crStateDestroyContext( context->clientState ); context->clientState = NULL; context->serverCtx = 0; if (thread->currentContext == context) { thread->currentContext = NULL; crStateMakeCurrent( NULL ); } }
void REPLICATESPU_APIENTRY replicatespu_DestroyContext( GLint ctx ) { unsigned int i; ContextInfo *context = (ContextInfo *) crHashtableSearch(replicate_spu.contextTable, ctx); GET_THREAD(thread); if (!context) { crWarning("Replicate SPU: DestroyContext, bad context %d", ctx); return; } CRASSERT(thread); replicatespuFlushAll( (void *)thread ); for (i = 0; i < CR_MAX_REPLICANTS; i++) { if (!IS_CONNECTED(replicate_spu.rserver[i].conn)) continue; if (replicate_spu.swap) crPackDestroyContextSWAP( context->rserverCtx[i] ); else crPackDestroyContext( context->rserverCtx[i] ); replicatespuFlushOne(thread, i); } crStateDestroyContext( context->State ); /* Although we only allocate a display list manager once, * we free it every time; this is okay since the DLM itself * will track its uses and will only release the resources * when the last user has relinquished it. */ crDLMFreeDLM(context->displayListManager); crDLMFreeContext(context->dlmState); if (thread->currentContext == context) { thread->currentContext = NULL; crStateMakeCurrent( NULL ); crDLMSetCurrentState(NULL); } /* zero, just to be safe */ crMemZero(context, sizeof(ContextInfo)); /* Delete from both the context table, and the context list. */ crHashtableDelete(replicate_spu.contextTable, ctx, crFree); { CRListIterator *foundElement = crListFind(replicate_spu.contextList, (void *)ctx, CompareIntegers); if (foundElement != NULL) { crListErase(replicate_spu.contextList, foundElement); } } }
static void deleteContextCallback( void *data ) { CRContext *c = (CRContext *) data; crStateDestroyContext(c); }
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); 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; } }
/** * Replicate our contexts on a new server (indicated by NewServerIndex). * XXX It may be a problem if we try to attach to a shared context, * when that shared context has not yet been created. */ static void replicatespuReplicateContext(void *element, void *arg) { GLint ctx = (GLint) element; ThreadInfo *thread = (ThreadInfo *) arg; ContextInfo *context = crHashtableSearch(replicate_spu.contextTable, ctx); ContextInfo *sharedContext = NULL; CRContext *tempState; GLint return_val = 0, shareCtx = context->shareCtx, sharedServerCtx = 0; int writeback; if (!context->State) { /* XXX need this? */ crWarning("ReplicateSPU: replicating context with no state!"); return; } if (shareCtx > 0) { sharedContext = (ContextInfo *) crHashtableSearch(replicate_spu.contextTable, shareCtx); if (sharedContext) sharedServerCtx = sharedContext->rserverCtx[NewServerIndex]; } /* * Send CreateContext to new server and get return value */ if (replicate_spu.swap) crPackCreateContextSWAP( replicate_spu.dpyName, context->visBits, sharedServerCtx, &return_val, &writeback); else crPackCreateContext( replicate_spu.dpyName, context->visBits, sharedServerCtx, &return_val, &writeback); replicatespuFlushOne(thread, NewServerIndex); writeback = 1; while (writeback) crNetRecv(); if (replicate_spu.swap) return_val = (GLint) SWAP32(return_val); if (return_val <= 0) { crWarning("Replicate SPU: CreateContext failed"); return; } context->rserverCtx[NewServerIndex] = return_val; /* * Create a new CRContext record representing the state of the new * server (all default state). We'll diff against this to send all the * needed state to the server. * When done, we can dispose of this context. */ tempState = crStateCreateContext(NULL, context->visBits, NULL); /* Bind the remote context. The window's not really significant. */ { int serverWindow; if (context->currentWindow) serverWindow = context->currentWindow->id[NewServerIndex]; else serverWindow = 0; if (replicate_spu.swap) crPackMakeCurrentSWAP( serverWindow, 0, return_val ); else crPackMakeCurrent( serverWindow, 0, return_val ); } /* Send state differences, all texture objects and all display lists * to the new server. * XXX We could be more efficient; in the case of a shared context, * we only need to replicate textures and display lists once... */ crStateDiffContext( tempState, context->State ); replicatespuReplicateTextures(tempState, context->State); replicatespuReplicateLists(tempState, context->displayListManager); /* XXX this call may not be needed */ replicatespuFlushOne(thread, NewServerIndex); /* Destroy the temporary context, no longer needed */ crStateDestroyContext( tempState ); }