Beispiel #1
0
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
}
Beispiel #2
0
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 );
    }
}
Beispiel #4
0
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);
	    }
	}
}
Beispiel #5
0
static void deleteContextCallback( void *data )
{
    CRContext *c = (CRContext *) data;
    crStateDestroyContext(c);
}
Beispiel #6
0
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;
    }
}
Beispiel #7
0
/**
 * 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 );
}