Example #1
0
/* Intersect two strings on a word-by-word basis (separated by spaces).
 * We typically use this to intersect OpenGL extension strings.
 * Example: if s1 = "apple banana plum pear"
 *         and s2 = "plum banana orange"
 *      then return "banana plum" (or "plum banana").
 */
char *crStrIntersect( const char *s1, const char *s2 )
{
	int len1, len2;
	int resultLen;
	char *result;
	char **exten1, **exten2;
	int i, j;

	if (!s1 || !s2) {
		/* null strings, no intersection */
		return NULL;
	}

	len1 = crStrlen(s1);
	len2 = crStrlen(s2);

	/* allocate storage for result (a conservative estimate) */
	resultLen = ((len1 > len2) ? len1 : len2) + 2;
	result = (char *) crAlloc(resultLen);
	if (!result)
	{
		return NULL;
	}
	result[0] = 0;

	/* split s1 and s2 at space chars */
	exten1 = crStrSplit(s1, " ");
	exten2 = crStrSplit(s2, " ");

	for (i = 0; exten1[i]; i++)
	{
		for (j = 0; exten2[j]; j++)
		{
			if (crStrcmp(exten1[i], exten2[j]) == 0)
			{
				/* found an intersection, append to result */
				crStrcat(result, exten1[i]);
				crStrcat(result, " ");
				break;
			}
		}
	}

	/* free split strings */
	crFreeStrings( exten1 );
	crFreeStrings( exten2 );

	/*CRASSERT(crStrlen(result) < resultLen);*/

	/* all done! */
	return result;
}
Example #2
0
/**
 * Ask the mothership for a new tile layout.
 * Return: GL_TRUE if successfull, GL_FALSE otherwise.
 */
static GLboolean
getTilingFromMothership( WindowInfo *winInfo )
{
	char response[8000];
	char **n_tiles;
	char **tiles;
	int numTiles, i;
	int maxX, maxY;

	CRConnection *conn = crMothershipConnect();
	CRASSERT(conn);

	crMothershipIdentifySPU(conn, tilesort_spu.id);
	crMothershipRequestTileLayout(conn, response, winInfo->muralWidth, winInfo->muralHeight);
	crMothershipDisconnect(conn);

	crDebug("Getting tile information from mothership.");

	n_tiles = crStrSplitn(response, " ", 1);
	numTiles = crStrToInt( n_tiles[0] );
	if (numTiles <= 0)
		return GL_FALSE;  /* failure */

	/* remove old tile list */
	for (i = 0; i < tilesort_spu.num_servers; i++)
		winInfo->server[i].num_extents = 0;

	/* parse new tile string */
	maxX = maxY = 0;
	CRASSERT(n_tiles[1]);
	tiles = crStrSplit(n_tiles[1], ",");
	for (i = 0; i < numTiles; i++)
	{
		int server, x, y, w, h, t;
		sscanf(tiles[i], "%d %d %d %d %d", &server, &x, &y, &w, &h);
		/*crDebug("Tile on %d: %d %d %d %d", server, x1, y1, x2, y2);*/
		t = winInfo->server[server].num_extents;
		winInfo->server[server].extents[t].x1 = x;
		winInfo->server[server].extents[t].y1 = y;
		winInfo->server[server].extents[t].x2 = x + w;
		winInfo->server[server].extents[t].y2 = y + h;
		winInfo->server[server].num_extents = t + 1;
		/* update maxX, maxY */
		if (x + w > maxX)
			maxX = x + w;
		if (y + h > maxY)
			maxY = y + h;
	}

	return GL_TRUE;
}
static void set_lut8( RenderSPU *render_spu, const char *response )
{
    int a;  
    char **lut;
    
    if (!response[0]) return;

    lut = crStrSplit(response, ",");
    if (!lut) return;

    for (a=0; a<256; a++)
    {
        render_spu->lut8[0][a]  = crStrToInt(lut[a]);
        render_spu->lut8[1][a]  = crStrToInt(lut[256+a]);
        render_spu->lut8[2][a]  = crStrToInt(lut[512+a]);
    }

    crFreeStrings(lut);

    render_spu->use_lut8 = 1;
}
Example #4
0
void 
CRUT_APIENTRY
crutConnectToClients( CRUTAPI *crut_api )
{   
    int i, ind;     
    char response[8096], hostname[4096], protocol[4096];
    char **newclients;
    char* client;
    unsigned short port;

    crMothershipGetCRUTClients(crut_api->mothershipConn, response);

    newclients = crStrSplit(response, " ");
    crut_api->numclients = crStrToInt(newclients[0]);
    ind = 1;

    crut_api->crutclients = crAlloc(crut_api->numclients*sizeof(CRUTClientPointer));

    for (i=0; i<crut_api->numclients; i++) {
      
        client = newclients[ind++];
	
	if ( !crParseURL( client, protocol, hostname, &port, DEFAULT_CRUT_PORT ) )
	{
	    crError( "Malformed URL: \"%s\"", response );
	}   
	
	crut_api->crutclients[i].mtu = crMothershipGetMTU( crut_api->mothershipConn );
	
	crut_api->crutclients[i].send_conn = crNetAcceptClient( protocol, hostname, port, crut_api->crutclients[i].mtu, 0 );
	
	if (!crut_api->crutclients[i].send_conn)
	{
	    crError("Couldn't connect to the CRUT client");
	}
		    
    }

}
Example #5
0
/**
 * Find the index of the given enum value in the SPUOption's list of
 * possible enum values.
 * Return the enum index, or -1 if not found.
 */
int crSPUGetEnumIndex( const SPUOptions *options, const char *optName, const char *value )
{
    const SPUOptions *opt;
    const int valueLen = crStrlen(value);

    /* first, find the right option */
    for (opt = options; opt->option; opt++) {
        if (crStrcmp(opt->option, optName) == 0) {
            char **values;
            int i;

            CRASSERT(opt->type == CR_ENUM);

            /* break into array of strings */
            /* min string should be of form "'enum1', 'enum2', 'enum3', etc" */
            values = crStrSplit(opt->min, ",");

            /* search the array */
            for (i = 0; values[i]; i++) {
                /* find leading quote */
                const char *e = crStrchr(values[i], '\'');
                CRASSERT(e);
                if (e) {
                    /* test for match */
                    if (crStrncmp(value, e + 1, valueLen) == 0 &&   e[valueLen + 1] == '\'') {
                        crFreeStrings(values);
                        return i;
                    }
                }
            }

            /* enum value not found! */
            crFreeStrings(values);
            return -1;
        }
    }

    return -1;
}
Example #6
0
static void 
crutInitProxy(char *mothership)
{
    char response[8096];
    char **newserver;
    char* server;
    int mtu;
    
    crutInitAPI(&crut_api, mothership);

    crMothershipIdentifyCRUTProxy( crut_api.mothershipConn, response );

    crMothershipGetCRUTServer( crut_api.mothershipConn, response );
    newserver = crStrSplit(response, " ");
    server = newserver[1];

    mtu = crMothershipGetMTU(crut_api.mothershipConn);
 
    /* set up the connection to recv on */
    crut_proxy.recv_conn = crNetConnectToServer( server, DEFAULT_CRUT_PORT, mtu, 1 );
    crutConnectToClients( &crut_api );

}
Example #7
0
File: load.c Project: OSLL/vboxhsm
/**
 * Do one-time initializations for the faker.
 * Returns TRUE on success, FALSE otherwise.
 */
static bool
stubInitLocked(void)
{
    /* Here is where we contact the mothership to find out what we're supposed
     * to  be doing.  Networking code in a DLL initializer.  I sure hope this
     * works :)
     *
     * HOW can I pass the mothership address to this if I already know it?
     */

    CRConnection *conn = NULL;
    char response[1024];
    char **spuchain;
    int num_spus;
    int *spu_ids;
    char **spu_names;
    const char *app_id;
    int i;
    int disable_sync = 0;

    stubInitVars();

    crGetProcName(response, 1024);
    crDebug("Stub launched for %s", response);

#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
    /*@todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread
     * as at the start compiz runs our code under XGrabServer.
     */
    if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real") || !crStrcmp(response, "compiz.real")
	|| !crStrcmp(response, "compiz-bin"))
    {
        disable_sync = 1;
    }
#elif defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WDDM_MINIPORT_WITH_VISIBLE_RECTS)
    if (GetModuleHandle(VBOX_MODNAME_DISPD3D))
    {
        disable_sync = 1;
        crDebug("running with " VBOX_MODNAME_DISPD3D);
        stub.trackWindowVisibleRgn = 0;
        stub.bRunningUnderWDDM = true;
    }
#endif

    /* @todo check if it'd be of any use on other than guests, no use for windows */
    app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" );

    crNetInit( NULL, NULL );

#ifndef WINDOWS
    {
        CRNetServer ns;

        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
                );
        if (!ns.conn)
        {
            crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
            return false;
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }
#if 0 && defined(CR_NEWWINTRACK)
        {
            Status st = XInitThreads();
            if (st==0)
            {
                crWarning("XInitThreads returned %i", (int)st);
            }
        }
#endif
    }
#endif

    strcpy(response, "2 0 feedback 1 pack");
    spuchain = crStrSplit( response, " " );
    num_spus = crStrToInt( spuchain[0] );
    spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) );
    spu_names = (char **) crAlloc( num_spus * 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] );
    }

    stubSetDefaultConfigurationOptions();

    stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL );

    crFree( spuchain );
    crFree( spu_ids );
    for (i = 0; i < num_spus; ++i)
        crFree(spu_names[i]);
    crFree( spu_names );

    // spu chain load failed somewhere
    if (!stub.spu) {
        return false;
    }

    crSPUInitDispatchTable( &glim );

    /* This is unlikely to change -- We still want to initialize our dispatch
     * table with the functions of the first SPU in the chain. */
    stubInitSPUDispatch( stub.spu );

    /* we need to plug one special stub function into the dispatch table */
    glim.GetChromiumParametervCR = stub_GetChromiumParametervCR;

#if !defined(VBOX_NO_NATIVEGL)
    /* Load pointers to native OpenGL functions into stub.nativeDispatch */
    stubInitNativeDispatch();
#endif

/*crDebug("stub init");
raise(SIGINT);*/

#ifdef WINDOWS
# ifndef CR_NEWWINTRACK
    stubInstallWindowMessageHook();
# endif
#endif

#ifdef CR_NEWWINTRACK
    {
        int rc;

        RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);

        if (!disable_sync)
        {
            crDebug("Starting sync thread");

            rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
            if (RT_FAILURE(rc))
            {
                crError("Failed to start sync thread! (%x)", rc);
            }
            RTThreadUserWait(stub.hSyncThread, 60 * 1000);
            RTThreadUserReset(stub.hSyncThread);

            crDebug("Going on");
        }
    }
#endif

#ifdef GLX
    stub.xshmSI.shmid = -1;
    stub.bShmInitFailed = GL_FALSE;
    stub.pGLXPixmapsHash = crAllocHashtable();

    stub.bXExtensionsChecked = GL_FALSE;
    stub.bHaveXComposite = GL_FALSE;
    stub.bHaveXFixes = GL_FALSE;
#endif

    return true;
}
Example #8
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);
}
Example #9
0
/**
 * Get the tile information (count, extents, etc) from the servers
 * and build our corresponding data structures.
 * This is called once during SPU initialization.
 * Input: conn - mothership connection
 */
void
tilesortspuGetTilingFromServers(CRConnection *conn, WindowInfo *winInfo)
{
	ThreadInfo *thread0 = &(tilesort_spu.thread[0]);
	char response[8096];
	char **serverchain, **serverlist;
	int num_servers;
	int i;

	crDebug("Getting tile information from servers.");
	/* The response to this tells us how many servers and where they are 
	 *
	 * For example:  2 tcpip://foo tcpip://bar 
	 */
	crMothershipGetServers(conn, response);

	serverchain = crStrSplitn(response, " ", 1);
	num_servers = crStrToInt(serverchain[0]);
	CRASSERT(num_servers == tilesort_spu.num_servers);
	serverlist = crStrSplit(serverchain[1], ",");

	tilesort_spu.thread[0].netServer =
		(CRNetServer *) crCalloc(num_servers * sizeof(CRNetServer));
	tilesort_spu.thread[0].buffer =
		(CRPackBuffer *) crCalloc(num_servers * sizeof(CRPackBuffer));

	/** XXX: \todo there is lots of overlap between these cases. merge! */
	if (tilesort_spu.localTileSpec)
	{
		char **displaylist, **displaychain;
		double *corners;
		int num_displays, idx;
		double world_bbox[4];

		/* 
		 * Here we has tiles specified relative to the origin of 
		 * whichever display they happen to land in. First, gather
		 * the list of displays, then get the tiles that belong on it 
		 */
		crMothershipGetDisplays(conn, response);
		displaychain = crStrSplitn(response, " ", 1);
		displaylist = crStrSplit(displaychain[1], ",");

		num_displays = crStrToInt(displaychain[0]);

		corners = (double *) crAlloc(num_displays * 8 * sizeof(double));

		tilesort_spu.displays =
			(WarpDisplayInfo *) crAlloc(num_displays * sizeof(WarpDisplayInfo));

		idx = 0;

		for (i = 0; i < num_displays; i++)
		{
			float pnt[2], warped[2];

			sscanf(displaylist[i],
						 "%d %d %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",
						 &tilesort_spu.displays[i].id, &tilesort_spu.displays[i].width,
						 &tilesort_spu.displays[i].height,
						 &tilesort_spu.displays[i].correct[0],
						 &tilesort_spu.displays[i].correct[1],
						 &tilesort_spu.displays[i].correct[2],
						 &tilesort_spu.displays[i].correct[3],
						 &tilesort_spu.displays[i].correct[4],
						 &tilesort_spu.displays[i].correct[5],
						 &tilesort_spu.displays[i].correct[6],
						 &tilesort_spu.displays[i].correct[7],
						 &tilesort_spu.displays[i].correct[8],
						 &tilesort_spu.displays[i].correct_inv[0],
						 &tilesort_spu.displays[i].correct_inv[1],
						 &tilesort_spu.displays[i].correct_inv[2],
						 &tilesort_spu.displays[i].correct_inv[3],
						 &tilesort_spu.displays[i].correct_inv[4],
						 &tilesort_spu.displays[i].correct_inv[5],
						 &tilesort_spu.displays[i].correct_inv[6],
						 &tilesort_spu.displays[i].correct_inv[7],
						 &tilesort_spu.displays[i].correct_inv[8]);

			pnt[0] = -1;
			pnt[1] = -1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = -1;
			pnt[1] = 1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = 1;
			pnt[1] = 1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
			pnt[0] = 1;
			pnt[1] = -1;
			crWarpPoint(tilesort_spu.displays[i].correct_inv, pnt, warped);
			corners[idx] = warped[0];
			corners[idx + 1] = warped[1];
			idx += 2;
		}

		crHullInteriorBox(corners, idx / 2, world_bbox);
		crFree(corners);

		/* dummy values in case i forget to override them later */
		winInfo->muralWidth = tilesort_spu.displays[0].width;
		winInfo->muralHeight = tilesort_spu.displays[0].height;

		winInfo->passiveStereo = GL_FALSE;  /* may be set true below */

		for (i = 0; i < num_servers; i++)
		{
			char server_url[1024];
			ServerWindowInfo *servWinInfo = winInfo->server + i;
			char **tilechain, **tilelist;
			int tile;
			double cent[2], Sx, Sy;

			sscanf(serverlist[i], "%s", server_url);

			crDebug("Server %d: %s", i + 1, server_url);
			thread0->netServer[i].name = crStrdup(server_url);
			thread0->netServer[i].buffer_size = tilesort_spu.buffer_size;

			/* response is just like regular GetTiles, but each tile
			 * is preceeded by a display id */
			if (!crMothershipGetDisplayTiles(conn, response, i))
			{
				crError("No tile information for server %d!  I can't continue!", i);
			}

			tilechain = crStrSplitn(response, " ", 1);
			servWinInfo->num_extents = crStrToInt(tilechain[0]);
			tilelist = crStrSplit(tilechain[1], ",");

			servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT;
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "stereo_view", response)) {
				if (crStrcmp(response, "left") == 0) {
					servWinInfo->eyeFlags = EYE_LEFT;
					winInfo->passiveStereo = GL_TRUE;
				}
				else if (crStrcmp(response, "right") == 0) {
					servWinInfo->eyeFlags = EYE_RIGHT;
					winInfo->passiveStereo = GL_TRUE;
				}
			}

			Sx = 2.0 / (world_bbox[2] - world_bbox[0]);
			Sy = 2.0 / (world_bbox[3] - world_bbox[1]);

			cent[0] = (world_bbox[0] + world_bbox[2]) / (2.);
			cent[1] = (world_bbox[1] + world_bbox[3]) / (2.);

			for (tile = 0; tile < servWinInfo->num_extents; tile++)
			{
				int id, x, y, w, h, a;
				float disp_w, disp_h, warped[2], *align;

				sscanf(tilelist[tile], "%d %d %d %d %d", &id, &x, &y, &w, &h);

				/* this is the local coordinate tiling */
				servWinInfo->display_ndx[tile] = -1;
				for (a = 0; a < num_displays; a++)
				{
					if (tilesort_spu.displays[a].id == id)
						servWinInfo->display_ndx[tile] = a;
				}
				if (servWinInfo->display_ndx[tile] == -1)
					crError("Invalid Display ID %d", id);
				servWinInfo->extents[tile].x1 = x;
				servWinInfo->extents[tile].y1 = y;
				servWinInfo->extents[tile].x2 = x + w;
				servWinInfo->extents[tile].y2 = y + h;

				/* warp the tile to mural space */
				disp_w = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].width;
				disp_h = (float) tilesort_spu.displays[servWinInfo->display_ndx[tile]].height;

				servWinInfo->world_extents[tile][0] = (float) x / disp_w;
				servWinInfo->world_extents[tile][1] = (float) y / disp_h;

				servWinInfo->world_extents[tile][2] = (float) x / disp_w;
				servWinInfo->world_extents[tile][3] = (float) (y + h) / disp_h;

				servWinInfo->world_extents[tile][4] = (float) (x + w) / disp_w;
				servWinInfo->world_extents[tile][5] = (float) (y + h) / disp_h;

				servWinInfo->world_extents[tile][6] = (float) (x + w) / disp_w;
				servWinInfo->world_extents[tile][7] = (float) y / disp_h;

				for (a = 0; a < 8; a++)
					servWinInfo->world_extents[tile][a] =
						(float)2.0 * servWinInfo->world_extents[tile][a] - (float)1.0;

				align = tilesort_spu.displays[servWinInfo->display_ndx[tile]].correct_inv;
				for (a = 0; a < 4; a++)
				{
					crWarpPoint(align, servWinInfo->world_extents[tile] + 2 * a, warped);

					warped[0] = (warped[0] - (float)cent[0]) * (float) Sx;
					warped[1] = (warped[1] - (float)cent[1]) * (float) Sy;

					crDebug("%f %f warps to %f %f", servWinInfo->world_extents[tile][2 * a],
									servWinInfo->world_extents[tile][2 * a + 1], warped[0],
									warped[1]);

					servWinInfo->world_extents[tile][2 * a] = warped[0];
					servWinInfo->world_extents[tile][2 * a + 1] = warped[1];
				}


				/** XXX: \todo check that the tile fits w/i the display it is on */
			}
			crFreeStrings(tilechain);
			crFreeStrings(tilelist);
		}

		crFreeStrings(displaychain);
		crFreeStrings(displaylist);

		/* can't do any fancy bucketing with this */
		tilesort_spu.defaultBucketMode = WARPED_GRID;
	}
	else
	{
		/*
		 * Get the list of tiles from all servers.
		 * And compute mural size.
		 */
		winInfo->muralWidth = 0;
		winInfo->muralHeight = 0;
		for (i = 0; i < num_servers; i++)
		{
			char server_url[1024];
			ServerWindowInfo *servWinInfo = winInfo->server + i;
			char **tilechain, **tilelist;
			int tile;

			sscanf(serverlist[i], "%s", server_url);

			crDebug("Server %d: %s", i + 1, server_url);
			thread0->netServer[i].name = crStrdup(server_url);
			thread0->netServer[i].buffer_size = tilesort_spu.buffer_size;

			if (!crMothershipGetTiles(conn, response, i))
			{
				crError("No tile information for server %d!  I can't continue!", i);
			}

			tilechain = crStrSplitn(response, " ", 1);
			servWinInfo->num_extents = crStrToInt(tilechain[0]);
			tilelist = crStrSplit(tilechain[1], ",");

			for (tile = 0; tile < servWinInfo->num_extents; tile++)
			{
				int x, y, w, h;

				sscanf(tilelist[tile], "%d %d %d %d", &x, &y, &w, &h);
				servWinInfo->extents[tile].x1 = x;
				servWinInfo->extents[tile].y1 = y;
				servWinInfo->extents[tile].x2 = x + w;
				servWinInfo->extents[tile].y2 = y + h;

				/* update mural size */
				if (servWinInfo->extents[tile].x2 > (int) winInfo->muralWidth)
				{
					winInfo->muralWidth = servWinInfo->extents[tile].x2;
				}
				if (servWinInfo->extents[tile].y2 > (int) winInfo->muralHeight)
				{
					winInfo->muralHeight = servWinInfo->extents[tile].y2;
				}
			}

			crFreeStrings(tilechain);
			crFreeStrings(tilelist);

			/* Determine if the server should receieve left, right or both eye
			 * views when running in passive stereo mode.
			 */
			servWinInfo->eyeFlags = EYE_LEFT | EYE_RIGHT;
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "stereo_view", response)) {
				if (crStrcmp(response, "left") == 0) {
					servWinInfo->eyeFlags = EYE_LEFT;
					winInfo->passiveStereo = GL_TRUE;
				}
				else if (crStrcmp(response, "right") == 0) {
					servWinInfo->eyeFlags = EYE_RIGHT;
					winInfo->passiveStereo = GL_TRUE;
				}
			}

			/* get view matrices from the server */
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "view_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->viewMatrix[0], response);
				if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[0]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			if (crMothershipGetServerParamFromSPU( conn, i,
																						 "right_view_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->viewMatrix[1], response);
				if (!crMatrixIsIdentity(&servWinInfo->viewMatrix[1]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			/*
			crMatrixPrint("Left view", &servWinInfo->viewMatrix[0]);
			crMatrixPrint("Right view", &servWinInfo->viewMatrix[1]);
			*/

			/* Also get overriding projection matrix.
			 * Note that this matrix is only relevant to FRUSTUM bucketing.
			 */
			if (crMothershipGetServerParamFromSPU( conn, i,
																			 "projection_matrix", response)) {
				/** XXX \todo projection_matrix is obsolete, keep for a while though */
				crMatrixInitFromString(&servWinInfo->projectionMatrix[0], response);
				if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[0]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			if (crMothershipGetServerParamFromSPU( conn, i,
																			 "right_projection_matrix", response)) {
				crMatrixInitFromString(&servWinInfo->projectionMatrix[1], response);
				if (!crMatrixIsIdentity(&servWinInfo->projectionMatrix[1]))
					winInfo->matrixSource = MATRIX_SOURCE_SERVERS;
			}
			/*
			crMatrixPrint("Left proj", &servWinInfo->projectionMatrix[0]);
			crMatrixPrint("Right proj", &servWinInfo->projectionMatrix[1]);
			*/
		}
	}

	crFreeStrings(serverchain);
	crFreeStrings(serverlist);

	tilesortspuBucketingInit( winInfo );
}
Example #10
0
void
crServerGatherConfiguration(char *mothership)
{
	CRMuralInfo *defaultMural;
	CRConnection *conn;
	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;
	char *low_node = "none";
	char *high_node = "none";
	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;

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

	setDefaults();

	if (mothership)
	{
		crSetenv("CRMOTHERSHIP", mothership);
	}

	conn = crMothershipConnect();
	if (!conn)
	{
		crError("Couldn't connect to the mothership, I have no idea what to do!");
	}

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

	/* Identify ourselves to the mothership */
	if (cr_server.vncMode) {
		/* we're running inside a vnc viewer */
		if (!crMothershipSendString( conn, response, "vncserver %s", hostname ))
			crError( "Bad Mothership response: %s", response );
	}
	else {
		crMothershipIdentifyServer(conn, response);
	}

	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;

	/*
	 * Gather configuration options.
	 * NOTE:  when you add new options, be sure to update the
	 * mothership/tools/crtypes.py file's NetworkNode class's notion of
	 * config options.
	 * XXX Use the SPU option parser code here someday.
	 */
	if (crMothershipGetServerParam( conn, response, "spu_dir" ) && crStrlen(response) > 0)
	{
		spu_dir = crStrdup(response);
	}

	/* Quadrics networking stuff */
	if (crMothershipGetRank(conn, response))
	{
		my_rank = crStrToInt(response);
	}
	crNetSetRank(my_rank);

	if (crMothershipGetParam(conn, "low_context", response))
	{
		low_context = crStrToInt(response);
	}
	if (crMothershipGetParam(conn, "high_context", response))
	{
		high_context = crStrToInt(response);
	}
	crNetSetContextRange(low_context, high_context);

	if (crMothershipGetParam(conn, "low_node", response))
	{
		low_node = crStrdup(response);
	}
	if (crMothershipGetParam(conn, "high_node", response))
	{
		high_node = crStrdup(response);
	}
	crNetSetNodeRange(low_node, high_node);
	if (low_node)
		crFree(low_node);
	if (high_node)
		crFree(high_node);
	if (crMothershipGetParam(conn, "comm_key", response))
	{
	  unsigned int a;
	  char **words, *found;
	  
	  /* remove the silly []'s */
	  while ((found = crStrchr(response, '[')) != NULL)
	    *found = ' ';
	  while ((found = crStrchr(response, ']')) != NULL)
	    *found = ' ';
	  
	  words = crStrSplit(response, ",");
	  
	  a = 0;
	  while (words[a] != NULL && a < sizeof(key)) {
			key[a]= crStrToInt(words[a]);
			a++;
		}
	  
	  crFreeStrings(words);
	}
	crNetSetKey(key,sizeof(key));

	if (crMothershipGetServerParam(conn, response, "port"))
	{
		cr_server.tcpip_port = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "optimize_bucket"))
	{
		cr_server.optimizeBucket = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "local_tile_spec"))
	{
		cr_server.localTileSpec = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "lightning2"))
	{
		cr_server.useL2 = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "ignore_papi"))
	{
		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"))
	{
		int a;
		char **levels, *found;

		/* remove the []'s */
		while ((found = crStrchr(response, '[')))
			*found = ' ';
		while ((found = crStrchr(response, ']')))
			*found = ' ';

		levels = crStrSplit(response, ",");

		a = 0;
		while (levels[a] != NULL)
		{
			crDebug("%d: %s", a, levels[a]);
			cr_server.num_overlap_intens++;
			a++;
		}

		cr_server.overlap_intens = (float *)crAlloc(cr_server.num_overlap_intens*sizeof(float));
		for (a=0; a<cr_server.num_overlap_intens; a++)
			cr_server.overlap_intens[a] = crStrToFloat(levels[a]);

		crFreeStrings(levels);
	}
	if (crMothershipGetServerParam(conn, response, "only_swap_once"))
	{
		cr_server.only_swap_once = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "debug_barriers"))
	{
		cr_server.debug_barriers = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "shared_display_lists"))
	{
		cr_server.sharedDisplayLists = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "shared_texture_objects"))
	{
		cr_server.sharedTextureObjects = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "shared_programs"))
	{
		cr_server.sharedPrograms = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "shared_windows"))
	{
		cr_server.sharedWindows = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "unique_window_ids"))
	{
		cr_server.uniqueWindows = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "use_dmx"))
	{
		cr_server.useDMX = crStrToInt(response);
	}
	if (crMothershipGetServerParam(conn, response, "vertprog_projection_param"))
	{
		if (crIsDigit(response[0])) {
			cr_server.vpProjectionMatrixParameter = crStrToInt(response);
		}
		else {
			cr_server.vpProjectionMatrixVariable = crStrdup(response);
		}
	}
	if (crMothershipGetServerParam(conn, response, "stereo_view"))
	{
		if (crStrcmp(response, "left") == 0)
			cr_server.stereoView = 0x1;
		else if (crStrcmp(response, "right") == 0)
			cr_server.stereoView = 0x2;
		else if (crStrcmp(response, "both") == 0)
			cr_server.stereoView = 0x3;
		else
			cr_server.stereoView = 0x3;
	}
	if (crMothershipGetServerParam(conn, response, "view_matrix"))
	{
		crMatrixInitFromString(&cr_server.viewMatrix[0], response);
		cr_server.viewOverride = GL_TRUE;
	}
	if (crMothershipGetServerParam(conn, response, "right_view_matrix"))
	{
		crMatrixInitFromString(&cr_server.viewMatrix[1], response);
		cr_server.viewOverride = GL_TRUE;
	}

	if (crMothershipGetServerParam(conn, response, "projection_matrix"))
	{
		crMatrixInitFromString(&cr_server.projectionMatrix[0], response);
		cr_server.projectionOverride = GL_TRUE;
	}
	if (crMothershipGetServerParam(conn, response, "right_projection_matrix"))
	{
		crMatrixInitFromString(&cr_server.projectionMatrix[1], response);
		cr_server.projectionOverride = GL_TRUE;
	}

	if (crMothershipGetServerParam(conn, response, "exit_if_no_clients"))
	{
		cr_server.exitIfNoClients = crStrToInt(response);
	}


	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);

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

	/* XXX DMX get window size instead? */
	cr_server.head_spu->dispatch_table.GetIntegerv(GL_VIEWPORT,
															 (GLint *) defaultMural->underlyingDisplay);

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

	cr_server.mtu = crMothershipGetMTU( conn );

	/*
	 * 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);
	}

	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));
		sscanf(clientlist[i], "%s %d", cr_server.protocol, &(newClient->spu_id));
		newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
																				cr_server.tcpip_port,
																				cr_server.mtu, 1);
		newClient->currentCtx = cr_server.DummyContext;
		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);
}