GLboolean STATE_APIENTRY
crStateIsBufferARB(GLuint buffer)
{
    CRContext *g = GetCurrentContext();
    CRBufferObjectState *b = &g->bufferobject;

    FLUSH();

    if (g->current.inBeginEnd) {
        crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
                                 "glIsBufferARB called in begin/end");
        return GL_FALSE;
    }

    if (buffer && crHashtableSearch(g->shared->buffersTable, buffer))
        return GL_TRUE;
    else
        return GL_FALSE;
}
Beispiel #2
0
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));
    else
        crWarning("invalid context %#x", hglrc);

    crHashtableUnlock(stub.contextTable);
//    crHashtableUnlock(stub.windowTable);
}
Beispiel #3
0
static void RENDER_APIENTRY
renderspuWindowShow( GLint win, GLint flag )
{
	WindowInfo *window;
	CRASSERT(win >= 0);
	window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
	if (window) {
		if (window->nativeWindow) {
			/* We're rendering back to the native app window instead of the
			 * new window which we (the Render SPU) created earlier.
			 * So, we never want to show the Render SPU's window.
			 */
			flag = 0;
		}
		renderspu_SystemShowWindow( window, (GLboolean) flag );
	}
	else {
		crDebug("Render SPU: Attempt to hide/show invalid window (%d)", win);
	}
}
DECLEXPORT(void) STATE_APIENTRY
crStateBindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
    CRContext *g = GetCurrentContext();
    CRFramebufferObjectState *fbo = &g->framebufferobject;

    CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end");
    CRSTATE_CHECKERR(target!=GL_RENDERBUFFER_EXT, GL_INVALID_ENUM, "invalid target");

    if (renderbuffer)
    {
        fbo->renderbuffer = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffer);
        if (!fbo->renderbuffer)
        {
            CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->rbTable, renderbuffer), GL_INVALID_OPERATION, "name is not a renderbuffer");
            fbo->renderbuffer = crStateRenderbufferAllocate(g, renderbuffer);
        }
        CR_STATE_SHAREDOBJ_USAGE_SET(fbo->renderbuffer, g);
    }
    else fbo->renderbuffer = NULL;
}
Beispiel #5
0
static void MATTESPU_APIENTRY matteDestroyContext(GLint ctx)
{
    ContextInfo *contextInfo;
    GET_CONTEXT_INFO(currentContextInfo);

    /* If we're destroying the current context, the current
     * context goes to NULL.
     */
    contextInfo = crHashtableSearch(matte_spu.contextTable, ctx);
    if (contextInfo == currentContextInfo) {
	SET_CONTEXT_INFO(NULL);
    }

    /* Destroy the context info record */
    if (contextInfo != NULL) {
	crHashtableDelete(matte_spu.contextTable, ctx, matteFreeContextInfo);
    }

    /* Pass it along */
    matte_spu.super.DestroyContext(ctx);
}
void SERVER_DISPATCH_APIENTRY crServerDispatchSemaphoreCreateCR( GLuint name, GLuint count )
{
	CRServerSemaphore *sema;

	if (cr_server.ignore_papi)
	{
		cr_server.head_spu->dispatch_table.SemaphoreCreateCR( name, count );
		return;
	}

	sema = crHashtableSearch(cr_server.semaphores, name);
	if (sema)
		return; /* already created */

	sema = (CRServerSemaphore *) crAlloc( sizeof( *sema ) );
	crHashtableAdd( cr_server.semaphores, name, sema );
	sema->count = count;
	sema->waiting = sema->tail = NULL;
	if (cr_server.debug_barriers)
		crDebug("crserver: SemaphoreCreate(id=%d, count=%d)", name, count);
}
Beispiel #7
0
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);
}
Beispiel #8
0
GLuint crHashtableAllocKeys( CRHashTable *h,  GLsizei range)
{
    GLuint res;
    int i;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&h->mutex);
#endif
    res = crHashIdPoolAllocBlock (h->idPool, range);
#ifdef DEBUG_misha
    Assert(res);
    for (i = 0; i < range; ++i)
    {
        void *search = crHashtableSearch( h, res+i );
        Assert(!search);
    }
#endif
#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&h->mutex);
#endif
    return res;
}
/* Semaphore signal */
void SERVER_DISPATCH_APIENTRY crServerDispatchSemaphoreVCR( GLuint name )
{
	CRServerSemaphore *sema;

	if (cr_server.ignore_papi)
	{
		cr_server.head_spu->dispatch_table.SemaphoreVCR( name );
		return;
	}

	sema = (CRServerSemaphore *) crHashtableSearch( cr_server.semaphores, name );
	if (!sema)
	{
		crError( "No such semaphore: %d", name );
	}
	if (sema->waiting)
	{
		wqnode *temp = sema->waiting;
		if (cr_server.debug_barriers)
			crDebug("crserver: SemaphoreV(client=%p, id=%d, count=%d) - unblock.",
							cr_server.curClient, name, sema->count);
		/* unblock one waiter */
		temp->q->blocked = 0;
		sema->waiting = temp->next;
		crFree( temp );
		if (!sema->waiting)
		{
			sema->tail = NULL;
		}
	}
	else
	{
		/* nobody's waiting */
		if (cr_server.debug_barriers)
			crDebug("crserver: SemaphoreV(client=%p, id=%d, count=%d) - increment to %d",
							cr_server.curClient, name, sema->count, sema->count + 1);
		sema->count++;
	}
}
Beispiel #10
0
static void RENDER_APIENTRY
renderspuVBoxPresentComposition( GLint win, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
{
    WindowInfo *window;
    CRASSERT(win >= 0);
    window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
    if (window) {
        if (pCompositor && CrVrScrCompositorIsEmpty(pCompositor) && !window->fCompositorPresentEmpty)
            pCompositor = NULL;

        if (pCompositor)
            window->fCompositorPresentEmpty = GL_FALSE;

        renderspuVBoxCompositorSet( window, pCompositor);
        if (pCompositor)
        {
            renderspu_SystemVBoxPresentComposition(window, pChangedEntry);
        }
    }
    else {
        crDebug("Render SPU: Attempt to PresentComposition for invalid window (%d)", win);
    }
}
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;
    }
}
Beispiel #12
0
stubGetWindowInfo( Display *dpy, GLXDrawable drawable )
#endif
{
    WindowInfo *winInfo = (WindowInfo *) crHashtableSearch(stub.windowTable, (unsigned int) drawable);
    if (!winInfo) {
	winInfo = (WindowInfo *) crCalloc(sizeof(WindowInfo));
	if (!winInfo)
	    return NULL;
#ifdef GLX
	crStrncpy(winInfo->dpyName, DisplayString(dpy), MAX_DPY_NAME);
	winInfo->dpyName[MAX_DPY_NAME-1] = 0;
	winInfo->dpy = dpy;
#elif defined(Darwin)
	winInfo->connection = _CGSDefaultConnection(); // store our connection as default
#endif
	winInfo->drawable = drawable;
	winInfo->type = UNDECIDED;
	winInfo->spuWindow = -1;
	winInfo->mapped = -1; /* don't know */
	crHashtableAdd(stub.windowTable, (unsigned int) drawable, winInfo);
    }
    return winInfo;
}
Beispiel #13
0
static void RENDER_APIENTRY
renderspuWindowSize( GLint win, GLint w, GLint h )
{
    WindowInfo *window;
    CRASSERT(win >= 0);
    window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
    if (window) {
        if (w != window->BltInfo.width
                || h != window->BltInfo.height)
        {
            /* window is resized, compositor data is no longer valid
             * this set also ensures all redraw operations are done in the redraw thread
             * and that no redraw is started until new Present request comes containing a valid presentation data */
            renderspuVBoxCompositorSet( window, NULL);
            renderspu_SystemWindowSize( window, w, h );
            window->BltInfo.width  = w;
            window->BltInfo.height = h;
        }
    }
    else {
        crDebug("Render SPU: Attempt to resize invalid window (%d)", win);
    }
}
Beispiel #14
0
static void RENDER_APIENTRY
renderspuDestroyContext( GLint ctx )
{
    ContextInfo *context, *curCtx;

    CRASSERT(ctx);

    if (ctx == CR_RENDER_DEFAULT_CONTEXT_ID)
    {
        crWarning("request to destroy a default context, ignoring");
        return;
    }

    context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);
    CRASSERT(context);
    {
        if (!context)
        {
            crWarning("request to delete inexistent context");
            return;
        }
    }

    curCtx = GET_CONTEXT_VAL();
    CRASSERT(curCtx);
    if (curCtx == context)
    {
        renderspuMakeCurrent( CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID );
        curCtx = GET_CONTEXT_VAL();
		Assert(curCtx);
		Assert(curCtx != context);
    }

    crHashtableDelete(render_spu.contextTable, ctx, NULL);

    renderspuContextMarkDeletedAndRelease(context);
}
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);
    }
}
void
stubDestroyContext( unsigned long contextId )
{
    ContextInfo *context;

    if (!stub.contextTable) {
        return;
    }

    /* 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);
    crHashtableLock(stub.contextTable);

    context = (ContextInfo *) crHashtableSearch(stub.contextTable, contextId);
    if (context)
        stubDestroyContextLocked(context);
    else
        crError("No context.");

#ifdef CHROMIUM_THREADSAFE
    if (stubGetCurrentContext() == context) {
        stubSetCurrentContext(NULL);
    }

    VBoxTlsRefMarkDestroy(context);
    VBoxTlsRefRelease(context);
#else
    if (stubGetCurrentContext() == context) {
        stubSetCurrentContext(NULL);
    }
    stubContextFree(context);
#endif
    crHashtableUnlock(stub.contextTable);
    crHashtableUnlock(stub.windowTable);
}
Beispiel #17
0
void STATE_APIENTRY
crStateGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
{
	CRContext *g = GetCurrentContext();
	CROcclusionState *o = &(g->occlusion);
	CROcclusionObject *q;

	FLUSH();

	if (g->current.inBeginEnd) {
		crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
								 "glGetGetQueryObjectuivARB called in begin/end");
		return;
	}

	q = (CROcclusionObject *) crHashtableSearch(o->objects, id);
	if (!q || q->active) {
		crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
								"glGetQueryObjectuivARB");
		return;
	}

	switch (pname) {
	case GL_QUERY_RESULT_ARB:
		*params = q->passedCounter;
		break;
	case GL_QUERY_RESULT_AVAILABLE_ARB:
		/* XXX revisit when we have a hardware implementation! */
		*params = GL_TRUE;
		break;
	default:
		crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
								 "glGetQueryObjectuivARB(pname)");
		return;
   }
}
Beispiel #18
0
GLint RENDER_APIENTRY
renderspuCreateContext(const char *dpyName, GLint visBits, GLint shareCtx)
{
	ContextInfo *context, *sharedContext = NULL;
	VisualInfo *visual;

	if (shareCtx > 0) {
		sharedContext
			= (ContextInfo *) crHashtableSearch(render_spu.contextTable, shareCtx);
	}

	if (!dpyName || crStrlen(render_spu.display_string)>0)
		dpyName = render_spu.display_string;

	visual = renderspuFindVisual(dpyName, visBits);
	if (!visual)
		return -1;

	context = (ContextInfo *) crCalloc(sizeof(ContextInfo));
	if (!context)
		return -1;
	context->id = render_spu.context_id;
	context->shared = sharedContext;
	if (!renderspu_SystemCreateContext(visual, context, sharedContext))
		return -1;

	crHashtableAdd(render_spu.contextTable, render_spu.context_id, context);
	render_spu.context_id++;

	/*
	crDebug("Render SPU: CreateContext(%s, 0x%x) returning %d",
					dpyName, visBits, context->id);
	*/

	return context->id;
}
Beispiel #19
0
void REPLICATESPU_APIENTRY
replicatespu_WindowSize( GLint win, GLint w, GLint h )
{
	WindowInfo *winInfo = (WindowInfo *) crHashtableSearch( replicate_spu.windowTable, win );
	GET_THREAD(thread);
	int i;

	winInfo->width = w;
	winInfo->height = h;

	replicatespuFlushAll( (void *) thread );

	for (i = 0; i < CR_MAX_REPLICANTS; i++) {
		if (!IS_CONNECTED(replicate_spu.rserver[i].conn))
			continue;

		if (replicate_spu.swap)
			crPackWindowSizeSWAP( winInfo->id[i], w, h );
		else
			crPackWindowSize( winInfo->id[i], w, h );

		replicatespuFlushOne(thread, i);
	}
}
Beispiel #20
0
static void MATTESPU_APIENTRY matteMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
{
    ContextInfo *contextInfo;

    matte_spu.super.MakeCurrent(crWindow, nativeWindow, ctx);

    /* If we've already got a context record for this, use it.
     * Otherwise, make a new one.
     */
    contextInfo = crHashtableSearch(matte_spu.contextTable, ctx);
    if (contextInfo == NULL) {
	/* Make our own. */
	contextInfo = crCalloc(sizeof(ContextInfo));
	if (contextInfo == NULL) {
	    crError("matte: could not allocate context info record for context %d", ctx);
	    return;
	}

	crHashtableAdd(matte_spu.contextTable, ctx, contextInfo);
    }

    /* Set this a s the current context */
    SET_CONTEXT_INFO(contextInfo);
}
Beispiel #21
0
void
RENDER_APIENTRY renderspuWindowDestroy( GLint win )
{
    WindowInfo *window;

    CRASSERT(win >= 0);
    if (win == CR_RENDER_DEFAULT_WINDOW_ID)
    {
        crWarning("request to destroy a default mural, ignoring");
        return;
    }
    window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, win);
    if (window) {
        crDebug("Render SPU: Destroy window (%d)", win);
        renderspuWindowTerm( window );

        /* remove window info from hash table, and free it */
        crHashtableDelete(render_spu.windowTable, win, crFree);

    }
    else {
        crDebug("Render SPU: Attempt to destroy invalid window (%d)", win);
    }
}
Beispiel #22
0
//we're not going to change icdTable at runtime, so callback is unused
PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)
{
    ContextInfo *context;
    WindowInfo *window;
    BOOL ret;

    CR_DDI_PROLOGUE();

    /*crDebug( "DrvSetContext called(0x%x, 0x%x)", hdc, hglrc );*/
    (void) (callback);

    crHashtableLock(stub.windowTable);
    crHashtableLock(stub.contextTable);

    context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
    window = stubGetWindowInfo(hdc);

    ret = stubMakeCurrent(window, context);

    crHashtableUnlock(stub.contextTable);
    crHashtableUnlock(stub.windowTable);

    return ret ? &icdTable:NULL;
}
Beispiel #23
0
void crServerSetVBoxConfigurationHGCM()
{
    CRMuralInfo *defaultMural;

    int spu_ids[1]     = {0};
    char *spu_names[1] = {"render"};
    char *spu_dir = NULL;
    int i;
    GLint dims[4];
    const char * env;

    defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
    CRASSERT(defaultMural);

    //@todo should be moved to addclient so we have a chain for each client

    setDefaults();
    
    /* Load the SPUs */    
    cr_server.head_spu = crSPULoadChain(1, spu_ids, spu_names, spu_dir, &cr_server);

    if (!cr_server.head_spu)
        return;

    env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
    if (env != NULL)
    {
        GLubyte redir = (env[0] - 0x30);
        if (redir <= CR_SERVER_REDIR_MAXVAL)
        {
            int rc = crServerSetOffscreenRenderingMode(redir);
            if (!RT_SUCCESS(rc))
                            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
        }
        else
            crWarning("invalid redir option %c", redir);
    }
#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    else
    {
        int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_FBO_BLT);
        if (!RT_SUCCESS(rc))
            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");

    }
#endif
    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;

    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, &dims[2]);
    
    defaultMural->gX = dims[0];
    defaultMural->gY = dims[1];
    defaultMural->width = dims[2];
    defaultMural->height = dims[3];

    cr_server.mtu = 1024 * 250;

    cr_server.numClients = 0;
    strcpy(cr_server.protocol, "vboxhgcm");

    for (i = 0; i < cr_server.numClients; i++)
    {
        CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient));
        newClient->spu_id = 0;
        newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
                                            cr_server.tcpip_port,
                                            cr_server.mtu, 0);
        newClient->currentCtxInfo = &cr_server.MainContextInfo;
        crServerAddToRunQueue(newClient);

        cr_server.clients[i] = newClient;
    }

    /* set default client and mural */
    if (cr_server.numClients > 0) {
         cr_server.curClient = cr_server.clients[0];
         cr_server.curClient->currentMural = defaultMural;
         cr_server.client_spu_id =cr_server.clients[0]->spu_id;
    }
}
/**
 * Allocate a new ContextInfo object, initialize it, put it into the
 * context hash table.  If type==CHROMIUM, call the head SPU's
 * CreateContext() function too.
 */
    ContextInfo *
stubNewContext(char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        , struct VBOXUHGSMI *pHgsmi
#endif
    )
{
    GLint spuContext = -1, spuShareCtx = 0, spuConnection = 0;
    ContextInfo *context;

    if (shareCtx > 0) {
    /* translate shareCtx to a SPU context ID */
    context = (ContextInfo *)
        crHashtableSearch(stub.contextTable, shareCtx);
        if (context)
            spuShareCtx = context->spuContext;
    }

    if (type == CHROMIUM) {
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        if (pHgsmi)
        {
            spuConnection = stub.spu->dispatch_table.VBoxConCreate(pHgsmi);
            if (!spuConnection)
            {
                crWarning("VBoxConCreate failed");
                return NULL;
            }
        }
#endif
        spuContext
            = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, dpyName, visBits, spuShareCtx);
        if (spuContext < 0)
        {
            crWarning("VBoxCreateContext failed");
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
            if (spuConnection)
                stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
#endif
            return NULL;
        }
    }

    context = crCalloc(sizeof(ContextInfo));
    if (!context) {
        stub.spu->dispatch_table.DestroyContext(spuContext);
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        if (spuConnection)
            stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
#endif
        return NULL;
    }

    if (!dpyName)
        dpyName = "";

    context->id = stub.freeContextNumber++;
    context->type = type;
    context->spuContext = spuContext;
    context->visBits = visBits;
    context->currentDrawable = NULL;
    crStrncpy(context->dpyName, dpyName, MAX_DPY_NAME);
    context->dpyName[MAX_DPY_NAME-1] = 0;

#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
    context->spuConnection = spuConnection;
    context->pHgsmi = pHgsmi;
#endif

#ifdef CHROMIUM_THREADSAFE
    VBoxTlsRefInit(context, stubContextDtor);
#endif

#if defined(GLX) || defined(DARWIN)
    context->share = (ContextInfo *)
        crHashtableSearch(stub.contextTable, (unsigned long) shareCtx);
#endif

#ifdef GLX
    context->pGLXPixmapsHash = crAllocHashtable();
    context->damageQueryFailed = GL_FALSE;
    context->damageEventsBase = 0;
#endif

    crHashtableAdd(stub.contextTable, context->id, (void *) context);

    return context;
}
Beispiel #25
0
void RENDER_APIENTRY
renderspuMakeCurrent(GLint crWindow, GLint nativeWindow, GLint ctx)
{
    WindowInfo *window;
    ContextInfo *context;

    /*
    crDebug("%s win=%d native=0x%x ctx=%d", __FUNCTION__, crWindow, (int) nativeWindow, ctx);
    */

    window = (WindowInfo *) crHashtableSearch(render_spu.windowTable, crWindow);
    context = (ContextInfo *) crHashtableSearch(render_spu.contextTable, ctx);

    if (window && context)
    {
#ifdef CHROMIUM_THREADSAFE
        crSetTSD(&_RenderTSD, context);
#else
        render_spu.currentContext = context;
#endif
        context->currentWindow = window;
        if (!window)
        {
            crDebug("Render SPU: MakeCurrent invalid window id: %d", crWindow);
            return;
        }
        if (!context)
        {
            crDebug("Render SPU: MakeCurrent invalid context id: %d", ctx);
            return;
        }

        renderspu_SystemMakeCurrent( window, nativeWindow, context );
        if (!context->everCurrent) {
            /* print OpenGL info */
            const char *extString = (const char *) render_spu.ws.glGetString( GL_EXTENSIONS );
            /*
            crDebug( "Render SPU: GL_EXTENSIONS:   %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
            */
            crInfo( "Render SPU: GL_VENDOR:   %s", render_spu.ws.glGetString( GL_VENDOR ) );
            crInfo( "Render SPU: GL_RENDERER: %s", render_spu.ws.glGetString( GL_RENDERER ) );
            crInfo( "Render SPU: GL_VERSION:  %s", render_spu.ws.glGetString( GL_VERSION ) );
            crInfo( "Render SPU: GL_EXTENSIONS: %s", render_spu.ws.glGetString( GL_EXTENSIONS ) );
            if (crStrstr(extString, "GL_ARB_window_pos"))
                context->haveWindowPosARB = GL_TRUE;
            else
                context->haveWindowPosARB = GL_FALSE;
            context->everCurrent = GL_TRUE;
        }
        if (crWindow == CR_RENDER_DEFAULT_WINDOW_ID && window->mapPending &&
                !render_spu.render_to_app_window && !render_spu.render_to_crut_window) {
            /* Window[CR_RENDER_DEFAULT_CONTEXT_ID] is special, it's the default window and normally hidden.
             * If the mapPending flag is set, then we should now make the window
             * visible.
             */
            /*renderspu_SystemShowWindow( window, GL_TRUE );*/
            window->mapPending = GL_FALSE;
        }
        window->everCurrent = GL_TRUE;
    }
    else if (!crWindow && !ctx)
    {
        renderspu_SystemMakeCurrent( NULL, 0, NULL );
#ifdef CHROMIUM_THREADSAFE
        crSetTSD(&_RenderTSD, NULL);
#else
        render_spu.currentContext = NULL;
#endif
    }
    else
    {
        crError("renderspuMakeCurrent invalid ids: crWindow(%d), ctx(%d)", crWindow, ctx);
    }
}
Beispiel #26
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 #27
0
void SERVER_DISPATCH_APIENTRY
crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
{
    CRMuralInfo *mural, *oldMural;
    CRContextInfo *ctxInfo = NULL;
    CRContext *ctx, *oldCtx = NULL;

    if (context >= 0 && window >= 0) {
        mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
        if (!mural)
        {
            crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
            return;
        }

        /* Update the state tracker's current context */
        ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context);
        if (!ctxInfo) {
            crWarning("CRserver: NULL context in MakeCurrent %d", context);
            return;
        }
    }
    else {
#if 0
        oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
        if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
        {
            if (!crStateGetCurrent()->framebufferobject.drawFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
            }
            if (!crStateGetCurrent()->framebufferobject.readFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
            }
        }

        ctxInfo = &cr_server.MainContextInfo;
        window = -1;
        mural = NULL;
#endif
        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
        return;
    }

    cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE;

    ctx = ctxInfo->pContext;
    CRASSERT(ctx);

    oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);

    /* Ubuntu 11.04 hosts misbehave if context window switch is
     * done with non-default framebuffer object settings.
     * crStateSwichPrepare & crStateSwichPostprocess are supposed to work around this problem
     * crStateSwichPrepare restores the FBO state to its default values before the context window switch,
     * while crStateSwichPostprocess restores it back to the original values */
    oldCtx = crStateSwichPrepare(ctx, cr_server.bUseMultipleContexts, oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO() ? oldMural->idFBO : 0);

    /*
    crDebug("**** %s client %d  curCtx=%d curWin=%d", __func__,
                    cr_server.curClient->number, ctxPos, window);
    */
    cr_server.curClient->currentContextNumber = context;
    cr_server.curClient->currentCtxInfo = ctxInfo;
    cr_server.curClient->currentMural = mural;
    cr_server.curClient->currentWindow = window;

    CRASSERT(cr_server.curClient->currentCtxInfo);
    CRASSERT(cr_server.curClient->currentCtxInfo->pContext);

    /* This is a hack to force updating the 'current' attribs */
    crStateUpdateColorBits();

    if (ctx)
        crStateSetCurrentPointers( ctx, &(cr_server.current) );

    /* check if being made current for first time, update viewport */
#if 0
    if (ctx) {
        /* initialize the viewport */
        if (ctx->viewport.viewportW == 0) {
            ctx->viewport.viewportW = mural->width;
            ctx->viewport.viewportH = mural->height;
            ctx->viewport.scissorW = mural->width;
            ctx->viewport.scissorH = mural->height;
        }
    }
#endif

    /*
    crDebug("**** %s  currentWindow %d  newWindow %d", __func__,
                    cr_server.currentWindow, window);
    */

    if (1/*cr_server.firstCallMakeCurrent ||
            cr_server.currentWindow != window ||
            cr_server.currentNativeWindow != nativeWindow*/) {
        /* Since the cr server serialized all incoming contexts/clients into
         * one output stream of GL commands, we only need to call the head
         * SPU's MakeCurrent() function once.
         * BUT, if we're rendering to multiple windows, we do have to issue
         * MakeCurrent() calls sometimes.  The same GL context will always be
         * used though.
         */
        cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow,
                                                        nativeWindow,
                                                        ctxInfo->SpuContext >= 0
                                                            ? ctxInfo->SpuContext
                                                              : cr_server.MainContextInfo.SpuContext);
        cr_server.firstCallMakeCurrent = GL_FALSE;
        cr_server.currentCtxInfo = ctxInfo;
        cr_server.currentWindow = window;
        cr_server.currentNativeWindow = nativeWindow;
    }

    /* This used to be earlier, after crStateUpdateColorBits() call */
    crStateMakeCurrent( ctx );

    crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->bUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0);

    if (!ctx->framebufferobject.drawFB
            && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT))
        cr_server.curClient->currentMural->bFbDraw = GL_TRUE;

    if (!mural->bUseFBO)
    {
        ctx->buffer.width = mural->width;
        ctx->buffer.height = mural->height;
    }
    else
    {
        ctx->buffer.width = 0;
        ctx->buffer.height = 0;
    }
}
static SPUFunctions *
renderSPUInit( int id, SPU *child, SPU *self,
               unsigned int context_id, unsigned int num_contexts )
{
    int numFuncs, numSpecial;
    GLint defaultWin, defaultCtx;
    WindowInfo *windowInfo;
    const char * pcpwSetting;
    int rc;

    (void) child;
    (void) context_id;
    (void) num_contexts;

    self->privatePtr = (void *) &render_spu;

#ifdef CHROMIUM_THREADSAFE
    crDebug("Render SPU: thread-safe");
#endif

    crMemZero(&render_spu, sizeof(render_spu));

    render_spu.id = id;
    renderspuSetVBoxConfiguration(&render_spu);

    if (render_spu.swap_master_url)
        swapsyncConnect();


    /* Get our special functions. */
    numSpecial = renderspuCreateFunctions( _cr_render_table );

#ifdef RT_OS_WINDOWS
    /* Start thread to create windows and process window messages */
    crDebug("RenderSPU: Starting windows serving thread");
    render_spu.hWinThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (!render_spu.hWinThreadReadyEvent)
    {
        crError("RenderSPU: Failed to create WinThreadReadyEvent! (%x)", GetLastError());
        return NULL;
    }

    if (!CreateThread(NULL, 0, renderSPUWindowThreadProc, 0, 0, &render_spu.dwWinThreadId))
    {
        crError("RenderSPU: Failed to start windows thread! (%x)", GetLastError());
        return NULL;
    }
    WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);
#endif

    /* Get the OpenGL functions. */
    numFuncs = crLoadOpenGL( &render_spu.ws, _cr_render_table + numSpecial );
    if (numFuncs == 0) {
        crError("The render SPU was unable to load the native OpenGL library");
        return NULL;
    }

    numFuncs += numSpecial;

    render_spu.contextTable = crAllocHashtableEx(1, INT32_MAX);
    render_spu.windowTable = crAllocHashtableEx(1, INT32_MAX);

    render_spu.dummyWindowTable = crAllocHashtable();

    pcpwSetting = crGetenv("CR_RENDER_ENABLE_SINGLE_PRESENT_CONTEXT");
    if (pcpwSetting)
    {
        if (pcpwSetting[0] == '0')
            pcpwSetting = NULL;
    }

    if (pcpwSetting)
    {
        /* TODO: need proper blitter synchronization, do not use so far!
         * the problem is that rendering can be done in multiple thread: the main command (hgcm) thread and the redraw thread
         * we currently use per-window synchronization, while we'll need a per-blitter synchronization if one blitter is used for multiple windows
         * this is not done currently */
        crWarning("TODO: need proper blitter synchronization, do not use so far!");
        render_spu.blitterTable = crAllocHashtable();
        CRASSERT(render_spu.blitterTable);
    }
    else
        render_spu.blitterTable = NULL;

    CRASSERT(render_spu.default_visual & CR_RGB_BIT);
    
    rc = renderspu_SystemInit();
    if (!RT_SUCCESS(rc))
    {
        crError("renderspu_SystemInit failed rc %d", rc);
        return NULL;
    }
#ifdef USE_OSMESA
    if (render_spu.use_osmesa) {
        if (!crLoadOSMesa(&render_spu.OSMesaCreateContext,
                          &render_spu.OSMesaMakeCurrent,
                          &render_spu.OSMesaDestroyContext)) {
            crError("Unable to load OSMesa library");
        }
    }
#endif

#ifdef DARWIN
# ifdef VBOX_WITH_COCOA_QT
# else /* VBOX_WITH_COCOA_QT */
    render_spu.hRootVisibleRegion = 0;
    render_spu.currentBufferName = 1;
    render_spu.uiDockUpdateTS = 0;
    /* Create a mutex for synchronizing events from the main Qt thread & this
       thread */
    RTSemFastMutexCreate(&render_spu.syncMutex);
    /* Create our window groups */
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pMasterGroup);
    CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &render_spu.pParentGroup);
    /* Make the correct z-layering */
    SendWindowGroupBehind (render_spu.pParentGroup, render_spu.pMasterGroup);
    /* and set the gParentGroup as parent for gMasterGroup. */
    SetWindowGroupParent (render_spu.pMasterGroup, render_spu.pParentGroup);
    /* Install the event handlers */
    EventTypeSpec eventList[] =
    {
        {kEventClassVBox, kEventVBoxUpdateContext}, /* Update the context after show/size/move events */
        {kEventClassVBox, kEventVBoxBoundsChanged}  /* Clip/Pos the OpenGL windows when the main window is changed in pos/size */
    };
    /* We need to process events from our main window */
    render_spu.hParentEventHandler = NewEventHandlerUPP(windowEvtHndlr);
    InstallApplicationEventHandler (render_spu.hParentEventHandler,
                                    GetEventTypeCount(eventList), eventList,
                                    NULL, NULL);
    render_spu.fInit = true;
# endif /* VBOX_WITH_COCOA_QT */
#endif /* DARWIN */

    /*
     * Create the default window and context.  Their indexes are zero and
     * a client can use them without calling CreateContext or WindowCreate.
     */
    crDebug("Render SPU: Creating default window (visBits=0x%x, id=0)",
            render_spu.default_visual);
    defaultWin = renderspuWindowCreateEx( NULL, render_spu.default_visual, CR_RENDER_DEFAULT_WINDOW_ID );
    if (defaultWin != CR_RENDER_DEFAULT_WINDOW_ID) {
        crError("Render SPU: Couldn't get a double-buffered, RGB visual with Z!");
        return NULL;
    }
    crDebug( "Render SPU: WindowCreate returned %d (0=normal)", defaultWin );

    crDebug("Render SPU: Creating default context, visBits=0x%x",
            render_spu.default_visual );
    defaultCtx = renderspuCreateContextEx( NULL, render_spu.default_visual, CR_RENDER_DEFAULT_CONTEXT_ID, 0 );
    if (defaultCtx != CR_RENDER_DEFAULT_CONTEXT_ID) {
        crError("Render SPU: failed to create default context!");
        return NULL;
    }

    renderspuMakeCurrent( defaultWin, 0, defaultCtx );

    /* Get windowInfo for the default window */
    windowInfo = (WindowInfo *) crHashtableSearch(render_spu.windowTable, CR_RENDER_DEFAULT_WINDOW_ID);
    CRASSERT(windowInfo);
    windowInfo->mapPending = GL_TRUE;

    /*
     * Get the OpenGL extension functions.
     * SIGH -- we have to wait until the very bitter end to load the
     * extensions, because the context has to be bound before
     * wglGetProcAddress will work correctly.  No such issue with GLX though.
     */
    numFuncs += crLoadOpenGLExtensions( &render_spu.ws, _cr_render_table + numFuncs );
    CRASSERT(numFuncs < 1000);

#ifdef WINDOWS
    /*
     * Same problem as above, these are extensions so we need to
     * load them after a context has been bound. As they're WGL
     * extensions too, we can't simply tag them into the spu_loader.
     * So we do them here for now.
     * Grrr, NVIDIA driver uses EXT for GetExtensionsStringEXT,
     * but ARB for others. Need further testing here....
     */
    render_spu.ws.wglGetExtensionsStringEXT =
        (wglGetExtensionsStringEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetExtensionsStringEXT" );
    render_spu.ws.wglChoosePixelFormatEXT =
        (wglChoosePixelFormatEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglChoosePixelFormatARB" );
    render_spu.ws.wglGetPixelFormatAttribivEXT =
        (wglGetPixelFormatAttribivEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribivARB" );
    render_spu.ws.wglGetPixelFormatAttribfvEXT =
        (wglGetPixelFormatAttribfvEXTFunc_t)
        render_spu.ws.wglGetProcAddress( "wglGetPixelFormatAttribfvARB" );

    if (render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("CopyTexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glCopyTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glCopyTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glDrawRangeElements"))
    {
        _cr_render_table[numFuncs].name = crStrdup("DrawRangeElements");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glDrawRangeElements");
        ++numFuncs;
        crDebug("Render SPU: Found glDrawRangeElements function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexSubImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexSubImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexSubImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexSubImage3D function");
    }

    if (render_spu.ws.wglGetProcAddress("glTexImage3D"))
    {
        _cr_render_table[numFuncs].name = crStrdup("TexImage3D");
        _cr_render_table[numFuncs].fn = (SPUGenericFunction) render_spu.ws.wglGetProcAddress("glTexImage3D");
        ++numFuncs;
        crDebug("Render SPU: Found glTexImage3D function");
    }

    if (render_spu.ws.wglGetExtensionsStringEXT) {
        crDebug("WGL - found wglGetExtensionsStringEXT\n");
    }
    if (render_spu.ws.wglChoosePixelFormatEXT) {
        crDebug("WGL - found wglChoosePixelFormatEXT\n");
    }
#endif

    render_spu.barrierHash = crAllocHashtable();

    render_spu.cursorX = 0;
    render_spu.cursorY = 0;
    render_spu.use_L2 = 0;

    render_spu.gather_conns = NULL;

    numFuncs = renderspu_SystemPostprocessFunctions(_cr_render_table, numFuncs, RT_ELEMENTS(_cr_render_table));

    crDebug("Render SPU: ---------- End of Init -------------");

    return &render_functions;
}
Beispiel #29
0
void crServerSetVBoxConfiguration()
{
    CRMuralInfo *defaultMural;
    char response[8096];

    char **spuchain;
    int num_spus;
    int *spu_ids;
    char **spu_names;
    char *spu_dir = NULL;
    int i;
    /* Quadrics defaults */
    int my_rank = 0;
    int low_context = CR_QUADRICS_DEFAULT_LOW_CONTEXT;
    int high_context = CR_QUADRICS_DEFAULT_HIGH_CONTEXT;
    unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    char hostname[1024];
    char **clientchain, **clientlist;
    GLint dims[4];
    const char * env;

    defaultMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, 0);
    CRASSERT(defaultMural);

    setDefaults();

    /*
     * Get my hostname
     */
    if (crGetHostname(hostname, sizeof(hostname)))
    {
        crError("CRServer: Couldn't get my own hostname?");
    }

    strcpy(response, "1 0 render");
    crDebug("CRServer: my SPU chain: %s", response);

    /* response will describe the SPU chain.
     * Example "2 5 wet 6 render"
     */
    spuchain = crStrSplit(response, " ");
    num_spus = crStrToInt(spuchain[0]);
    spu_ids = (int *) crAlloc(num_spus * sizeof(*spu_ids));
    spu_names = (char **) crAlloc((num_spus + 1) * sizeof(*spu_names));
    for (i = 0; i < num_spus; i++)
    {
        spu_ids[i] = crStrToInt(spuchain[2 * i + 1]);
        spu_names[i] = crStrdup(spuchain[2 * i + 2]);
        crDebug("SPU %d/%d: (%d) \"%s\"", i + 1, num_spus, spu_ids[i],
                        spu_names[i]);
    }
    spu_names[i] = NULL;

    //spu_dir = crStrdup(response);
    crNetSetRank(0);
    crNetSetContextRange(32, 35);
    crNetSetNodeRange("iam0", "iamvis20");
    crNetSetKey(key,sizeof(key));
    crNetSetKey(key,sizeof(key));
    cr_server.tcpip_port = 7000;

        /*cr_server.optimizeBucket = crStrToInt(response);
        cr_server.localTileSpec = crStrToInt(response);
        cr_server.useL2 = crStrToInt(response);
        cr_server.ignore_papi = crStrToInt(response);
        if (crMothershipGetServerParam(conn, response, "overlap_blending"))
        {
            if (!crStrcmp(response, "blend"))
                cr_server.overlapBlending = 1;
            else if (!crStrcmp(response, "knockout"))
                cr_server.overlapBlending = 2;
        }
        if (crMothershipGetServerParam(conn, response, "overlap_levels"))
        cr_server.only_swap_once = crStrToInt(response);
        cr_server.debug_barriers = crStrToInt(response);
        cr_server.sharedDisplayLists = crStrToInt(response);
        cr_server.sharedTextureObjects = crStrToInt(response);
        cr_server.sharedPrograms = crStrToInt(response);
        cr_server.sharedWindows = crStrToInt(response);
        cr_server.uniqueWindows = crStrToInt(response);
        cr_server.useDMX = crStrToInt(response);
        if (crMothershipGetServerParam(conn, response, "vertprog_projection_param"))
        if (crMothershipGetServerParam(conn, response, "stereo_view"))
        if (crMothershipGetServerParam(conn, response, "view_matrix"))
        if (crMothershipGetServerParam(conn, response, "right_view_matrix"))
        if (crMothershipGetServerParam(conn, response, "projection_matrix"))
        if (crMothershipGetServerParam(conn, response, "right_projection_matrix"))*/

    crDebug("CRServer: my port number is %d", cr_server.tcpip_port);

    /*
     * Load the SPUs
     */
    cr_server.head_spu =
        crSPULoadChain(num_spus, spu_ids, spu_names, spu_dir, &cr_server);

    env = crGetenv( "CR_SERVER_DEFAULT_RENDER_TYPE" );
    if (env != NULL)
    {
        GLubyte redir = (env[0] - 0x30);
        if (redir <= CR_SERVER_REDIR_MAXVAL)
        {
            int rc = crServerSetOffscreenRenderingMode(redir);
            if (!RT_SUCCESS(rc))
                crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");
        }
        else
            crWarning("invalid redir option %c", redir);
    }
#if defined(RT_OS_DARWIN) || defined(RT_OS_WINDOWS) || defined(GLX)
    else
    {
        int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_FBO_BLT);
        if (!RT_SUCCESS(rc))
            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");

    }
#endif
    cr_server.bOffscreenRenderingDefault = cr_server.bForceOffscreenRendering;

    /* Need to do this as early as possible */

    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_POSITION_CR, 0, GL_INT, 2, &dims[0]);
    cr_server.head_spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, &dims[2]);
    
    defaultMural->gX = dims[0];
    defaultMural->gY = dims[1];
    defaultMural->width = dims[2];
    defaultMural->height = dims[3];

    crFree(spu_ids);
    crFreeStrings(spu_names);
    crFreeStrings(spuchain);
    if (spu_dir)
        crFree(spu_dir);

    cr_server.mtu = 1024 * 30;

    /*
     * Get a list of all the clients talking to me.
     */
    if (cr_server.vncMode) {
        /* we're inside a vnc viewer */
        /*if (!crMothershipSendString( conn, response, "getvncclient %s", hostname ))
            crError( "Bad Mothership response: %s", response );*/
    }
    else {
        //crMothershipGetClients(conn, response);
        strcpy(response, "1 tcpip 1");
    }

    crDebug("CRServer: my clients: %s", response);

    /*
     * 'response' will now contain a number indicating the number of clients
     * of this server, followed by a comma-separated list of protocol/SPU ID
     * pairs.
     * Example: "3 tcpip 1,gm 2,via 10"
     */
    clientchain = crStrSplitn(response, " ", 1);
    cr_server.numClients = crStrToInt(clientchain[0]);
    if (cr_server.numClients == 0)
    {
        crError("I have no clients!  What's a poor server to do?");
    }
    clientlist = crStrSplit(clientchain[1], ",");

    /*
     * Connect to initial set of clients.
     * Call crNetAcceptClient() for each client.
     * Also, look for a client that's _not_ using the file: protocol.
     */
    for (i = 0; i < cr_server.numClients; i++)
    {
        CRClient *newClient = (CRClient *) crCalloc(sizeof(CRClient));
#ifdef VBOX
        sscanf(clientlist[i], "%1023s %d", cr_server.protocol, &(newClient->spu_id));
#else
        sscanf(clientlist[i], "%s %d", cr_server.protocol, &(newClient->spu_id));
#endif
        newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
                                            cr_server.tcpip_port,
                                            cr_server.mtu, 0);
        newClient->currentCtxInfo = &cr_server.MainContextInfo;
        crServerAddToRunQueue(newClient);

        cr_server.clients[i] = newClient;
    }

    /* set default client and mural */
    if (cr_server.numClients > 0) {
         cr_server.curClient = cr_server.clients[0];
         cr_server.curClient->currentMural = defaultMural;
         cr_server.client_spu_id =cr_server.clients[0]->spu_id;
    }

    crFreeStrings(clientchain);
    crFreeStrings(clientlist);

    /* Ask the mothership for the tile info */
    //crServerGetTileInfoFromMothership(conn, defaultMural);

    if (cr_server.vncMode) {
        /* In vnc mode, we reset the mothership configuration so that it can be
         * used by subsequent OpenGL apps without having to spawn a new mothership
         * on a new port.
         */
        crDebug("CRServer: Resetting mothership to initial state");
        //crMothershipReset(conn);
    }

    //crMothershipDisconnect(conn);
}
void SERVER_DISPATCH_APIENTRY crServerDispatchBarrierCreateCR( GLuint name, GLuint count )
{
	CRServerBarrier *barrier;
#if DEBUG_BARRIERS
	char debug_buf[4096];
#endif

	if (cr_server.ignore_papi)
	{
		cr_server.head_spu->dispatch_table.BarrierCreateCR( name, count );
		return;
	}

	barrier = (CRServerBarrier *) crHashtableSearch( cr_server.barriers, name );

#if DEBUG_BARRIERS
	sprintf( debug_buf, "BarrierCreateCR( %d, %d )", name, count );
	cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
#endif
	if (count == 0)
	{
		count = cr_server.numClients;
#if DEBUG_BARRIERS
		sprintf( debug_buf, "changing count to %d", count );
		cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
#endif
	}


	/* we use maxBarrierCount in Clear() and SwapBuffers() and also use it
	 * in __getNextClient() for deadlock detection.  The issue is that all
	 * the existing clients may be blocked, but we might soon get another
	 * client connection to break the apparent deadlock.
	 */
	if (count > cr_server.maxBarrierCount)
		cr_server.maxBarrierCount = count;

	if ( barrier == NULL )
	{
		barrier = (CRServerBarrier *) crAlloc( sizeof(*barrier) );
		barrier->count = count;
		barrier->num_waiting = 0;
		barrier->waiting = (RunQueue **) 
			crAlloc( count * sizeof(*(barrier->waiting)) );

		crHashtableAdd( cr_server.barriers, name, barrier );
#if DEBUG_BARRIERS
		sprintf( debug_buf, "This was a new barrier!" );
		cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
#endif
	}
	else
	{
		/* HACK -- this allows everybody to create a barrier, and all
           but the first creation are ignored, assuming the count
           match. */
#if DEBUG_BARRIERS
		sprintf( debug_buf, "I already knew about this barrier." );
		cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
#endif
		if ( barrier->count != count )
		{
#if DEBUG_BARRIERS
			sprintf( debug_buf, "And someone messed up the count!." );
			cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
#endif
			crError( "Barrier name=%u created with count=%u, but already "
						 "exists with count=%u", name, count, barrier->count );
		}
	}

	if (cr_server.debug_barriers)
		crDebug("crserver: BarrierCreate(id=%d, count=%d)", name, barrier->count);
}