Example #1
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 && env[0] != '\0')
    {
        unsigned int redir = (unsigned int)crServerVBoxParseNumerics(env, CR_SERVER_REDIR_F_NONE);
        if (redir <= CR_SERVER_REDIR_F_ALL)
        {
            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)
    if (cr_server.fPresentMode == CR_SERVER_REDIR_F_NONE)
    {
        /* the CR_SERVER_REDIR_F_FBO_BLT is set only if parent window is received, which means we are not in headles */
        int rc = crServerSetOffscreenRenderingMode(CR_SERVER_REDIR_F_FBO | CR_SERVER_REDIR_F_DISPLAY);
        if (!RT_SUCCESS(rc))
            crWarning("offscreen rendering unsupported, no offscreen rendering will be used..");

    }
#endif
    cr_server.fPresentModeDefault = cr_server.fPresentMode;
    cr_server.fVramPresentModeDefault = CR_SERVER_REDIR_F_FBO_RAM/* | CR_SERVER_REDIR_F_FBO_RPW*/;

    /* 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 #2
0
GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID)
{
    GLint retVal = -1;
    CRContext *newCtx;
    CRContextInfo *pContextInfo;
    GLboolean fFirst = GL_FALSE;

    if (shareCtx > 0) {
        crWarning("CRServer: context sharing not implemented.");
        shareCtx = 0;
    }

    pContextInfo = (CRContextInfo *) crAlloc(sizeof (CRContextInfo));
    if (!pContextInfo)
    {
        crWarning("failed to alloc context info!");
        return -1;
    }

    pContextInfo->CreateInfo.visualBits = visualBits;

    /* Since the Cr server serialized all incoming clients/contexts into
     * one outgoing GL stream, we only need to create one context for the
     * head SPU.  We'll only have to make it current once too, below.
     */
    if (cr_server.firstCallCreateContext) {
        cr_server.MainContextInfo.CreateInfo.visualBits = visualBits;
        cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
            CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, shareCtx);
        if (cr_server.MainContextInfo.SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crFree(pContextInfo);
            return -1;
        }
        cr_server.firstCallCreateContext = GL_FALSE;
        fFirst = GL_TRUE;
    }
    else {
        /* second or third or ... context */
        if (!cr_server.bUseMultipleContexts && ((visualBits & cr_server.MainContextInfo.CreateInfo.visualBits) != visualBits)) {
            int oldSpuContext;

            /* the new context needs new visual attributes */
            cr_server.MainContextInfo.CreateInfo.visualBits |= visualBits;
            crDebug("crServerDispatchCreateContext requires new visual (0x%x).",
                    cr_server.MainContextInfo.CreateInfo.visualBits);

            /* Here, we used to just destroy the old rendering context.
             * Unfortunately, this had the side effect of destroying
             * all display lists and textures that had been loaded on
             * the old context as well.
             *
             * Now, first try to create a new context, with a suitable
             * visual, sharing display lists and textures with the
             * old context.  Then destroy the old context.
             */

            /* create new rendering context with suitable visual */
            oldSpuContext = cr_server.MainContextInfo.SpuContext;
            cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext);
            /* destroy old rendering context */
            cr_server.head_spu->dispatch_table.DestroyContext(oldSpuContext);
            if (cr_server.MainContextInfo.SpuContext < 0) {
                crWarning("crServerDispatchCreateContext() failed.");
                crFree(pContextInfo);
                return -1;
            }
        }
    }

    if (cr_server.bUseMultipleContexts) {
        pContextInfo->SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.visualBits, cr_server.MainContextInfo.SpuContext);
        if (pContextInfo->SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crStateEnableDiffOnMakeCurrent(GL_TRUE);
            cr_server.bUseMultipleContexts = GL_FALSE;
            if (!fFirst)
                crError("creating shared context failed, while it is expected to work!");
        }
        else if (fFirst)
        {
            crStateEnableDiffOnMakeCurrent(GL_FALSE);
        }
    }
    else
    {
        pContextInfo->SpuContext = -1;
    }

    /* Now create a new state-tracker context and initialize the
     * dispatch function pointers.
     */
    newCtx = crStateCreateContextEx(&cr_server.limits, visualBits, NULL, internalID);
    if (newCtx) {
        crStateSetCurrentPointers( newCtx, &(cr_server.current) );
        crStateResetCurrentPointers(&(cr_server.current));
        retVal = preloadCtxID<0 ? crServerGenerateID(&cr_server.idsPool.freeContextID) : preloadCtxID;

        pContextInfo->pContext = newCtx;
        pContextInfo->CreateInfo.visualBits = visualBits;
        pContextInfo->CreateInfo.externalID = retVal;
        pContextInfo->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
        crHashtableAdd(cr_server.contextTable, retVal, pContextInfo);
    }

    if (retVal != -1 && !cr_server.bIsInLoadingState) {
        int pos;
        for (pos = 0; pos < CR_MAX_CONTEXTS; pos++) {
            if (cr_server.curClient->contextList[pos] == 0) {
                cr_server.curClient->contextList[pos] = retVal;
                break;
            }
        }
    }

    {
        /* As we're using only one host context to serve all client contexts, newly created context will still
         * hold last error value from any previous failed opengl call. Proper solution would be to redirect any
         * client glGetError calls to our state tracker, but right now it's missing quite a lot of checks and doesn't
         * reflect host driver/gpu specific issues. Thus we just reset last opengl error at context creation.
         */
        GLint err;

        err = cr_server.head_spu->dispatch_table.GetError();
        if (err!=GL_NO_ERROR)
        {
#ifdef DEBUG_misha
            crDebug("Cleared gl error %#x on context creation", err);
#else
            crWarning("Cleared gl error %#x on context creation", err);
#endif
        }
    }

    crServerReturnValue( &retVal, sizeof(retVal) );

    return retVal;
}
Example #3
0
static void
set_format(void *foo, const char *response)
{
	saveframe_spu.format = crStrdup(response);
}
/**
 * This function is called by MakeCurrent() and determines whether or
 * not a new rendering context should be bound to Chromium or the native
 * OpenGL.
 * \return  GL_FALSE if native OpenGL should be used, or GL_TRUE if Chromium
 *          should be used.
 */
static GLboolean
stubCheckUseChromium( WindowInfo *window )
{
    int x, y;
    unsigned int w, h;

    /* If the provided window is CHROMIUM, we're clearly intended
     * to create a CHROMIUM context.
     */
    if (window->type == CHROMIUM)
        return GL_TRUE;

    if (stub.ignoreFreeglutMenus) {
        const char *glutMenuTitle = "freeglut menu";
        char title[1000];
        GetWindowTitle(window, title);
        if (crStrcmp(title, glutMenuTitle) == 0) {
            crDebug("GL faker: Ignoring freeglut menu window");
            return GL_FALSE;
        }
    }

    /*  If the user's specified a window count for Chromium, see if
        *  this window satisfies that criterium.
        */
    stub.matchChromiumWindowCounter++;
    if (stub.matchChromiumWindowCount > 0) {
        if (stub.matchChromiumWindowCounter != stub.matchChromiumWindowCount) {
            crDebug("Using native GL, app window doesn't meet match_window_count");
            return GL_FALSE;
        }
    }

    /* If the user's specified a window list to ignore, see if this
     * window satisfies that criterium.
     */
    if (stub.matchChromiumWindowID) {
        GLuint i;

        for (i = 0; i <= stub.numIgnoreWindowID; i++) {
            if (stub.matchChromiumWindowID[i] == stub.matchChromiumWindowCounter) {
                crDebug("Ignore window ID %d, using native GL", stub.matchChromiumWindowID[i]);
                return GL_FALSE;
            }
        }
    }

    /* If the user's specified a minimum window size for Chromium, see if
     * this window satisfies that criterium. 
     */
    if (stub.minChromiumWindowWidth > 0 && 
        stub.minChromiumWindowHeight > 0) {
        stubGetWindowGeometry( window, &x, &y, &w, &h );
        if (w >= stub.minChromiumWindowWidth && 
            h >= stub.minChromiumWindowHeight) {

            /* Check for maximum sized window now too */
            if (stub.maxChromiumWindowWidth && 
                stub.maxChromiumWindowHeight) {
                if (w < stub.maxChromiumWindowWidth &&
                    h < stub.maxChromiumWindowHeight)
                    return GL_TRUE;
                else 
                    return GL_FALSE;
            }

            return GL_TRUE;
        }
        crDebug("Using native GL, app window doesn't meet minimum_window_size");
        return GL_FALSE;
    }
    else if (stub.matchWindowTitle) {
        /* If the user's specified a window title for Chromium, see if this
         * window satisfies that criterium.
         */
        GLboolean wildcard = GL_FALSE;
        char title[1000];
        char *titlePattern;
        int len;
        /* check for leading '*' wildcard */
        if (stub.matchWindowTitle[0] == '*') {
            titlePattern = crStrdup( stub.matchWindowTitle + 1 );
            wildcard = GL_TRUE;
        }
        else {
            titlePattern = crStrdup( stub.matchWindowTitle );
        }
        /* check for trailing '*' wildcard */
        len = crStrlen(titlePattern);
        if (len > 0 && titlePattern[len - 1] == '*') {
            titlePattern[len - 1] = '\0'; /* terminate here */
            wildcard = GL_TRUE;
        }

        GetWindowTitle( window, title );
        if (title[0]) {
            if (wildcard) {
                if (crStrstr(title, titlePattern)) {
                    crFree(titlePattern);
                    return GL_TRUE;
                }
            }
            else if (crStrcmp(title, titlePattern) == 0) {
                crFree(titlePattern);
                return GL_TRUE;
            }
        }
        crFree(titlePattern);
        crDebug("Using native GL, app window title doesn't match match_window_title string (\"%s\" != \"%s\")", title, stub.matchWindowTitle);
        return GL_FALSE;
    }

    /* Window title and size don't matter */
    CRASSERT(stub.minChromiumWindowWidth == 0);
    CRASSERT(stub.minChromiumWindowHeight == 0);
    CRASSERT(stub.matchWindowTitle == NULL);

    /* User hasn't specified a width/height or window title.
     * We'll use chromium for this window (and context) if no other is.
     */

    return GL_TRUE;  /* use Chromium! */
}
Example #5
0
GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
{
    GLint con = 0;
    int i;
    GET_THREAD(thread);
    CRASSERT(!thread);
    crLockMutex(&_PackMutex);
    {
        CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0));
        CRASSERT(pack_spu.numThreads<MAX_THREADS);
        for (i=0; i<MAX_THREADS; ++i)
        {
            if (!pack_spu.thread[i].inUse)
            {
                thread = &pack_spu.thread[i];
                break;
            }
        }
        CRASSERT(thread);

        thread->inUse = GL_TRUE;
        if (!CRPACKSPU_IS_WDDM_CRHGSMI())
            thread->id = crThreadID();
        else
            thread->id = THREAD_OFFSET_MAGIC + i;
        thread->currentContext = NULL;
        thread->bInjectThread = GL_TRUE;

        thread->netServer.name = crStrdup(pack_spu.name);
        thread->netServer.buffer_size = 64 * 1024;

        packspuConnectToServer(&(thread->netServer)
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , pHgsmi
#endif
        );
        CRASSERT(thread->netServer.conn);

        CRASSERT(thread->packer == NULL);
        thread->packer = crPackNewContext( pack_spu.swap );
        CRASSERT(thread->packer);
        crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
                         thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
        thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;

        crPackSetBuffer( thread->packer, &thread->buffer );
        crPackFlushFunc( thread->packer, packspuFlush );
        crPackFlushArg( thread->packer, (void *) thread );
        crPackSendHugeFunc( thread->packer, packspuHuge );
        crPackSetContext( thread->packer );

        crSetTSD(&_PackTSD, thread);

        pack_spu.numThreads++;
    }
    crUnlockMutex(&_PackMutex);

    if (CRPACKSPU_IS_WDDM_CRHGSMI())
    {
        CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
                && GET_THREAD_VAL_ID(thread->id) == thread);
        con = thread->id;
    }
    return con;
}
Example #6
0
/*
 * Initialize the CRLimitsState object to Chromium's defaults.
 */
void crStateLimitsInit (CRLimitsState *l)
{
	l->maxTextureUnits = CR_MAX_TEXTURE_UNITS;
	l->maxTextureSize = CR_MAX_TEXTURE_SIZE;
	l->max3DTextureSize = CR_MAX_3D_TEXTURE_SIZE;
	l->maxCubeMapTextureSize = CR_MAX_CUBE_TEXTURE_SIZE;
#ifdef CR_NV_texture_rectangle
	l->maxRectTextureSize  = CR_MAX_RECTANGLE_TEXTURE_SIZE;
#endif
	l->maxTextureAnisotropy = CR_MAX_TEXTURE_ANISOTROPY;
	l->maxGeneralCombiners = CR_MAX_GENERAL_COMBINERS;
	l->maxLights = CR_MAX_LIGHTS;
	l->maxClipPlanes = CR_MAX_CLIP_PLANES;
	l->maxClientAttribStackDepth = CR_MAX_ATTRIB_STACK_DEPTH;
	l->maxProjectionStackDepth = CR_MAX_PROJECTION_STACK_DEPTH;
	l->maxModelviewStackDepth = CR_MAX_MODELVIEW_STACK_DEPTH;
	l->maxTextureStackDepth = CR_MAX_TEXTURE_STACK_DEPTH;
	l->maxColorStackDepth = CR_MAX_COLOR_STACK_DEPTH;
	l->maxAttribStackDepth = CR_MAX_ATTRIB_STACK_DEPTH;
	l->maxClientAttribStackDepth = CR_MAX_ATTRIB_STACK_DEPTH;
	l->maxNameStackDepth = CR_MAX_NAME_STACK_DEPTH;
	l->maxElementsIndices = CR_MAX_ELEMENTS_INDICES;
	l->maxElementsVertices = CR_MAX_ELEMENTS_VERTICES;
	l->maxEvalOrder = CR_MAX_EVAL_ORDER;
	l->maxListNesting = CR_MAX_LIST_NESTING;
	l->maxPixelMapTable = CR_MAX_PIXEL_MAP_TABLE;
	l->maxViewportDims[0] = l->maxViewportDims[1] = CR_MAX_VIEWPORT_DIM;
	l->subpixelBits = CR_SUBPIXEL_BITS;
	l->aliasedPointSizeRange[0] = CR_ALIASED_POINT_SIZE_MIN;
	l->aliasedPointSizeRange[1] = CR_ALIASED_POINT_SIZE_MAX;
	l->smoothPointSizeRange[0] = CR_SMOOTH_POINT_SIZE_MIN;
	l->smoothPointSizeRange[1] = CR_SMOOTH_POINT_SIZE_MAX;
	l->pointSizeGranularity = CR_POINT_SIZE_GRANULARITY;
	l->aliasedLineWidthRange[0] = CR_ALIASED_LINE_WIDTH_MIN;
	l->aliasedLineWidthRange[1] = CR_ALIASED_LINE_WIDTH_MAX;
	l->smoothLineWidthRange[0] = CR_SMOOTH_LINE_WIDTH_MIN;
	l->smoothLineWidthRange[1] = CR_SMOOTH_LINE_WIDTH_MAX;
	l->lineWidthGranularity = CR_LINE_WIDTH_GRANULARITY;
#ifdef CR_EXT_texture_lod_bias
	l->maxTextureLodBias = CR_MAX_TEXTURE_LOD_BIAS;
#endif
#ifdef CR_NV_fragment_program
	l->maxTextureCoords = CR_MAX_TEXTURE_COORDS;
	l->maxTextureImageUnits = CR_MAX_TEXTURE_IMAGE_UNITS;
	l->maxFragmentProgramLocalParams = CR_MAX_FRAGMENT_LOCAL_PARAMS;
#endif
#ifdef CR_NV_vertex_program
	l->maxProgramMatrixStackDepth = CR_MAX_PROGRAM_MATRIX_STACK_DEPTH;
	l->maxProgramMatrices = CR_MAX_PROGRAM_MATRICES;
#endif
#ifdef CR_ARB_fragment_program
	l->maxFragmentProgramInstructions = CR_MAX_FRAGMENT_PROGRAM_INSTRUCTIONS;
	l->maxFragmentProgramLocalParams = CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS;
	l->maxFragmentProgramEnvParams = CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS;
	l->maxFragmentProgramTemps = CR_MAX_FRAGMENT_PROGRAM_TEMPS;
	l->maxFragmentProgramAttribs = CR_MAX_FRAGMENT_PROGRAM_ATTRIBS;
	l->maxFragmentProgramAddressRegs = CR_MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
	l->maxFragmentProgramAluInstructions = CR_MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
	l->maxFragmentProgramTexInstructions = CR_MAX_FRAGMENT_PROGRAM_TEX_INSTRUCTIONS;
	l->maxFragmentProgramTexIndirections = CR_MAX_FRAGMENT_PROGRAM_TEX_INDIRECTIONS;
#endif
#ifdef CR_ARB_vertex_program
	l->maxVertexProgramInstructions = CR_MAX_VERTEX_PROGRAM_INSTRUCTIONS;
	l->maxVertexProgramLocalParams = CR_MAX_VERTEX_PROGRAM_LOCAL_PARAMS;
	l->maxVertexProgramEnvParams = CR_MAX_VERTEX_PROGRAM_ENV_PARAMS;
	l->maxVertexProgramTemps = CR_MAX_VERTEX_PROGRAM_TEMPS;
	l->maxVertexProgramAttribs = CR_MAX_VERTEX_PROGRAM_ATTRIBS;
	l->maxVertexProgramAddressRegs = CR_MAX_VERTEX_PROGRAM_ADDRESS_REGS;
#endif

	l->extensions = (GLubyte *) crStrdup(crExtensions);

	/* These will get properly set in crStateCreateContext() by examining
	 * the visBits bitfield parameter.
	 */
	l->redBits = 0;
	l->greenBits = 0;
	l->blueBits = 0;
	l->alphaBits = 0;
	l->depthBits = 0;
	l->stencilBits = 0;
	l->accumRedBits = 0;
	l->accumGreenBits = 0;
	l->accumBlueBits = 0;
	l->accumAlphaBits = 0;
	l->auxBuffers = 0;
	l->rgbaMode = GL_TRUE;
	l->doubleBuffer = GL_FALSE;
	l->stereo = GL_FALSE;
	l->sampleBuffers = 0;
	l->samples = 0;
	l->level = 0;

	(void) crAppOnlyExtensions; /* silence warning */
}
static void set_title( RenderSPU *render_spu, const char *response )
{
    crFree( render_spu->window_title );
    render_spu->window_title = crStrdup( response );
}
const GLubyte * PACKSPU_APIENTRY packspu_GetString( GLenum name )
{
    GET_CONTEXT(ctx);

    switch(name)
    {
        case GL_EXTENSIONS:
            return GetExtensions();
        case GL_VERSION:
#if 0 && defined(WINDOWS)
            if (packspuRunningUnderWine())
            {
                GetString(GL_REAL_VERSION, ctx->pszRealVersion);
                return ctx->pszRealVersion;               
            }
            else
#endif
            {
                char *oldlocale;
                float version;

                oldlocale = setlocale(LC_NUMERIC, NULL);
                oldlocale = crStrdup(oldlocale);
                setlocale(LC_NUMERIC, "C");

                version = GetVersionString();
                sprintf((char*)ctx->glVersion, "%.1f Chromium %s", version, CR_VERSION_STRING);

                if (oldlocale)
                {
                    setlocale(LC_NUMERIC, oldlocale);
                    crFree(oldlocale);
                }

                return ctx->glVersion;
            }
        case GL_VENDOR:
#ifdef WINDOWS
            if (packspuRunningUnderWine())
            {
                GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
                return ctx->pszRealVendor;
            }
            else
#endif
            {
                return crStateGetString(name);
            }
        case GL_RENDERER:
#ifdef WINDOWS
            if (packspuRunningUnderWine())
            {
                GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
                return ctx->pszRealRenderer;
            }
            else
#endif
            {
                return crStateGetString(name);
            }

#ifdef CR_OPENGL_VERSION_2_0
        case GL_SHADING_LANGUAGE_VERSION:
        {
            static GLboolean fInitialized = GL_FALSE;
            if (!fInitialized)
            {
                GetString(GL_SHADING_LANGUAGE_VERSION, gpszShadingVersion);
                fInitialized = GL_TRUE;
            }
            return gpszShadingVersion;
        }
#endif
#ifdef GL_CR_real_vendor_strings
        case GL_REAL_VENDOR:
            GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
            return ctx->pszRealVendor;
        case GL_REAL_VERSION:
            GetString(GL_REAL_VERSION, ctx->pszRealVersion);
            return ctx->pszRealVersion;
        case GL_REAL_RENDERER:
            GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
            return ctx->pszRealRenderer;
#endif
        default:
            return crStateGetString(name);
    }
}
Example #9
0
static void
crSDPAccept( CRConnection *conn, const char *hostname, unsigned short port )
{
	int err;
	socklen_t		addr_length;
	struct sockaddr_in	servaddr;
	struct sockaddr		addr;
	struct hostent		*host;
	struct in_addr		sin_addr;

	if (port != last_port)
	{
	     /* with the new OOB stuff, we can have multiple ports being 
	      * accepted on, so we need to redo the server socket every time.
	      */
		cr_sdp.server_sock = socket( AF_INET_SDP, SOCK_STREAM, 0 );
		if ( cr_sdp.server_sock == -1 )
		{
			err = crSDPErrno( );
			crError( "Couldn't create socket: %s", crSDPErrorString( err ) );
		}
		spankSocket( cr_sdp.server_sock );

		servaddr.sin_family = AF_INET;
		servaddr.sin_addr.s_addr = INADDR_ANY;
		servaddr.sin_port = htons( port );

		if ( bind( cr_sdp.server_sock, (struct sockaddr *) &servaddr, sizeof(servaddr) ) )
		{
			err = crSDPErrno( );
			crError( "Couldn't bind to socket (port=%d): %s", port, crSDPErrorString( err ) );
		}
		last_port = port;
		if ( listen( cr_sdp.server_sock, 100 /* max pending connections */ ) )
		{
			err = crSDPErrno( );
			crError( "Couldn't listen on socket: %s", crSDPErrorString( err ) );
		}
	}
	
	if (conn->broker)
	{
		CRConnection *mother;
		char response[8096];
		char my_hostname[256];
		char *temp;
		mother = __copy_of_crMothershipConnect( );
    
		if (!hostname)
		{
			if ( crGetHostname( my_hostname, sizeof( my_hostname ) ) )
			{
				crError( "Couldn't determine my own hostname in crSDPAccept!" );
			}
		}
		else
			crStrcpy(my_hostname, hostname);
    
		/* Hack hostname, YUCK!!! */
		temp = strtok(my_hostname, ".");
		crStrcat(temp, crGetSDPHostnameSuffix());
		(void) temp;
		if (!__copy_of_crMothershipSendString( mother, response, "acceptrequest sdp %s %d %d", temp, conn->port, conn->endianness ) )
		{
			crError( "Mothership didn't like my accept request" );
		}
    
		__copy_of_crMothershipDisconnect( mother );
    
		sscanf( response, "%u", &(conn->id) );
	}
	
	addr_length =	sizeof( addr );
	conn->sdp_socket = accept( cr_sdp.server_sock, (struct sockaddr *) &addr, &addr_length );
	if (conn->sdp_socket == -1)
	{
		err = crSDPErrno( );
		crError( "Couldn't accept client: %s", crSDPErrorString( err ) );
	}
	
	sin_addr = ((struct sockaddr_in *) &addr)->sin_addr;
	host = gethostbyaddr( (char *) &sin_addr, sizeof( sin_addr), AF_INET_SDP );
	if (host == NULL )
	{
		char *temp = inet_ntoa( sin_addr );
		conn->hostname = crStrdup( temp );
	}
	else
	{
		char *temp;
		conn->hostname = crStrdup( host->h_name );
    
		temp = conn->hostname;
		while (*temp && *temp != '.' )
			temp++;
		*temp = '\0';
	}
	
#ifdef RECV_BAIL_OUT 
	err = sizeof(unsigned int);
	if ( getsockopt( conn->sdp_socket, SOL_SOCKET, SO_RCVBUF,
									 (char *) &conn->krecv_buf_size, &err ) )
	{
		conn->krecv_buf_size = 0;	
	}
#endif
	crDebug( "Accepted connection from \"%s\".", conn->hostname );
}
Example #10
0
GLint RENDER_APIENTRY
renderspuWindowCreate( const char *dpyName, GLint visBits )
{
	WindowInfo *window;
	VisualInfo *visual;
	GLboolean showIt;

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

	visual = renderspuFindVisual( dpyName, visBits );
	if (!visual)
	{
		crWarning( "Render SPU: Couldn't create a window, renderspuFindVisual returned NULL" );
		return -1;
	}

	/* Allocate WindowInfo */
	window = (WindowInfo *) crCalloc(sizeof(WindowInfo));
	if (!window)
	{
		crWarning( "Render SPU: Couldn't create a window" );
		return -1;
	}

	crHashtableAdd(render_spu.windowTable, render_spu.window_id, window);
	window->id = render_spu.window_id;
	render_spu.window_id++;

	window->x = render_spu.defaultX;
	window->y = render_spu.defaultY;
	window->width  = render_spu.defaultWidth;
	window->height = render_spu.defaultHeight;

	if ((render_spu.render_to_app_window || render_spu.render_to_crut_window) && !crGetenv("CRNEWSERVER"))
		showIt = 0;
	else
		showIt = window->id > 0;

	/* Set window->title, replacing %i with the window ID number */
	{
		const char *s = crStrstr(render_spu.window_title, "%i");
		if (s) {
			int i, j, k;
			window->title = crAlloc(crStrlen(render_spu.window_title) + 10);
			for (i = 0; render_spu.window_title[i] != '%'; i++)
				window->title[i] = render_spu.window_title[i];
			k = sprintf(window->title + i, "%d", window->id);
			CRASSERT(k < 10);
			i++; /* skip the 'i' after the '%' */
			j = i + k;
			for (; (window->title[j] = s[i]) != 0; i++, j++)
				;
		}
		else {
			window->title = crStrdup(render_spu.window_title);
		}
	}

	/*
	crDebug("Render SPU: Creating window (visBits=0x%x, id=%d)", visBits, window->id);
	*/
	/* Have GLX/WGL/AGL create the window */
	if (!renderspu_SystemCreateWindow( visual, showIt, window ))
	{
		crFree(window);
		crWarning( "Render SPU: Couldn't create a window, renderspu_SystemCreateWindow failed" );
		return -1;
	}

	CRASSERT(window->visual == visual);

	return window->id;
}
GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID)
{
    GLint retVal = -1;
    CRContext *newCtx;
    CRContextInfo *pContextInfo;
    GLboolean fFirst = GL_FALSE;

    dpyName = "";

    if (shareCtx > 0) {
        crWarning("CRServer: context sharing not implemented.");
        shareCtx = 0;
    }

    pContextInfo = (CRContextInfo *) crAlloc(sizeof (CRContextInfo));
    if (!pContextInfo)
    {
        crWarning("failed to alloc context info!");
        return -1;
    }

    pContextInfo->currentMural = NULL;

    pContextInfo->CreateInfo.requestedVisualBits = visualBits;

    if (cr_server.fVisualBitsDefault)
        visualBits = cr_server.fVisualBitsDefault;

    pContextInfo->CreateInfo.realVisualBits = visualBits;

    /* Since the Cr server serialized all incoming clients/contexts into
     * one outgoing GL stream, we only need to create one context for the
     * head SPU.  We'll only have to make it current once too, below.
     */
    if (cr_server.firstCallCreateContext) {
        cr_server.MainContextInfo.CreateInfo.realVisualBits = visualBits;
        cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
            CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, shareCtx);
        if (cr_server.MainContextInfo.SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crFree(pContextInfo);
            return -1;
        }
        cr_server.MainContextInfo.pContext = crStateCreateContext(&cr_server.limits, visualBits, NULL);
        CRASSERT(cr_server.MainContextInfo.pContext);
        cr_server.firstCallCreateContext = GL_FALSE;
        fFirst = GL_TRUE;

        cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext);
    }
    else {
        /* second or third or ... context */
        if (!cr_server.bUseMultipleContexts && ((visualBits & cr_server.MainContextInfo.CreateInfo.realVisualBits) != visualBits)) {
            int oldSpuContext;
            /* should never be here */
            CRASSERT(0);
            /* the new context needs new visual attributes */
            cr_server.MainContextInfo.CreateInfo.realVisualBits |= visualBits;
            crWarning("crServerDispatchCreateContext requires new visual (0x%x).",
                    cr_server.MainContextInfo.CreateInfo.realVisualBits);

            /* Here, we used to just destroy the old rendering context.
             * Unfortunately, this had the side effect of destroying
             * all display lists and textures that had been loaded on
             * the old context as well.
             *
             * Now, first try to create a new context, with a suitable
             * visual, sharing display lists and textures with the
             * old context.  Then destroy the old context.
             */

            /* create new rendering context with suitable visual */
            oldSpuContext = cr_server.MainContextInfo.SpuContext;
            cr_server.MainContextInfo.SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext);
            /* destroy old rendering context */
            cr_server.head_spu->dispatch_table.DestroyContext(oldSpuContext);
            if (cr_server.MainContextInfo.SpuContext < 0) {
                crWarning("crServerDispatchCreateContext() failed.");
                crFree(pContextInfo);
                return -1;
            }

            /* we do not need to clean up the old default context explicitly, since the above cr_server.head_spu->dispatch_table.DestroyContext call
             * will do that for us */
            cr_server.head_spu->dispatch_table.ChromiumParameteriCR(GL_HH_SET_DEFAULT_SHARED_CTX, cr_server.MainContextInfo.SpuContext);
        }
    }

    if (cr_server.bUseMultipleContexts) {
        pContextInfo->SpuContext = cr_server.head_spu->dispatch_table.
                CreateContext(dpyName, cr_server.MainContextInfo.CreateInfo.realVisualBits, cr_server.MainContextInfo.SpuContext);
        if (pContextInfo->SpuContext < 0) {
            crWarning("crServerDispatchCreateContext() failed.");
            crStateEnableDiffOnMakeCurrent(GL_TRUE);
            cr_server.bUseMultipleContexts = GL_FALSE;
            if (!fFirst)
                crError("creating shared context failed, while it is expected to work!");
        }
        else if (fFirst)
        {
            crStateEnableDiffOnMakeCurrent(GL_FALSE);
        }
    }
    else
    {
        pContextInfo->SpuContext = -1;
    }

    /* Now create a new state-tracker context and initialize the
     * dispatch function pointers.
     */
    newCtx = crStateCreateContextEx(&cr_server.limits, visualBits, NULL, internalID);
    if (newCtx) {
        crStateSetCurrentPointers( newCtx, &(cr_server.current) );
        crStateResetCurrentPointers(&(cr_server.current));
        retVal = preloadCtxID<0 ? (GLint)crHashtableAllocKeys( cr_server.contextTable, 1 ) : preloadCtxID;

        pContextInfo->pContext = newCtx;
        Assert(pContextInfo->CreateInfo.realVisualBits == visualBits);
        pContextInfo->CreateInfo.externalID = retVal;
        pContextInfo->CreateInfo.pszDpyName = dpyName ? crStrdup(dpyName) : NULL;
        crHashtableAdd(cr_server.contextTable, retVal, pContextInfo);
    }

    if (retVal != -1 && !cr_server.bIsInLoadingState) {
        int pos;
        for (pos = 0; pos < CR_MAX_CONTEXTS; pos++) {
            if (cr_server.curClient->contextList[pos] == 0) {
                cr_server.curClient->contextList[pos] = retVal;
                break;
            }
        }
    }

    crServerReturnValue( &retVal, sizeof(retVal) );

    return retVal;
}
Example #12
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);
}
Example #13
0
/*
 * Allocate a new ThreadInfo structure, setup a connection to the
 * server, allocate/init a packer context, bind this ThreadInfo to
 * the calling thread with crSetTSD().
 * We'll always call this function at least once even if we're not
 * using threads.
 */
ThreadInfo *packspuNewThread( unsigned long id )
{
    ThreadInfo *thread=NULL;
    int i;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&_PackMutex);
#else
    CRASSERT(pack_spu.numThreads == 0);
#endif

    CRASSERT(pack_spu.numThreads < MAX_THREADS);
    for (i=0; i<MAX_THREADS; ++i)
    {
        if (!pack_spu.thread[i].inUse)
        {
            thread = &pack_spu.thread[i];
            break;
        }
    }
    CRASSERT(thread);

    thread->inUse = GL_TRUE;
    thread->id = id;
    thread->currentContext = NULL;
    thread->bInjectThread = GL_FALSE;

    /* connect to the server */
    thread->netServer.name = crStrdup( pack_spu.name );
    thread->netServer.buffer_size = pack_spu.buffer_size;
    if (pack_spu.numThreads == 0) {
        packspuConnectToServer( &(thread->netServer) );
        if (!thread->netServer.conn) {
            return NULL;
        }
        pack_spu.swap = thread->netServer.conn->swap;
    }
    else {
        /* a new pthread */
        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
        CRASSERT(thread->netServer.conn);
    }

    /* packer setup */
    CRASSERT(thread->packer == NULL);
    thread->packer = crPackNewContext( pack_spu.swap );
    CRASSERT(thread->packer);
    crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
                thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
    thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
    crPackSetBuffer( thread->packer, &thread->buffer );
    crPackFlushFunc( thread->packer, packspuFlush );
    crPackFlushArg( thread->packer, (void *) thread );
    crPackSendHugeFunc( thread->packer, packspuHuge );
    crPackSetContext( thread->packer );

#ifdef CHROMIUM_THREADSAFE
    crSetTSD(&_PackTSD, thread);
#endif

    pack_spu.numThreads++;

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&_PackMutex);
#endif
    return thread;
}
Example #14
0
/**
 * 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;
#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
    HMODULE hVBoxD3D = NULL;
#endif

    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;
    }
#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.");
# ifdef VBOXOGL_FAKEDRI
            return false;
# else
            exit(1);
# endif
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }
    }
#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();

#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
    hVBoxD3D = NULL;
    if (!GetModuleHandleEx(0, VBOX_MODNAME_DISPD3D, &hVBoxD3D))
    {
        crDebug("GetModuleHandleEx failed err %d", GetLastError());
        hVBoxD3D = NULL;
    }

    if (hVBoxD3D)
    {
        disable_sync = 1;
        crDebug("running with %s", VBOX_MODNAME_DISPD3D);
        stub.trackWindowVisibleRgn = 0;
        /* @todo: should we enable that? */
        stub.trackWindowSize = 0;
        stub.trackWindowPos = 0;
        stub.trackWindowVisibility = 0;
        stub.bRunningUnderWDDM = true;
    }
#endif

    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 #15
0
/**
 * Establish a connection with a server.
 * \param server  the server to connect to, in the form
 *                "protocol://servername:port" where the port specifier
 *                is optional and if the protocol is missing it is assumed
 *                to be "tcpip".
 * \param default_port  the port to connect to, if port not specified in the
 *                      server URL string.
 * \param mtu  desired maximum transmission unit size (in bytes)
 * \param broker  either 1 or 0 to indicate if connection is brokered through
 *                the mothership
 */
CRConnection *
crNetConnectToServer( const char *server, unsigned short default_port,
											int mtu, int broker )
{
	char hostname[4096], protocol[4096];
	unsigned short port;
	CRConnection *conn;

	crDebug( "In crNetConnectToServer( \"%s\", port=%d, mtu=%d, broker=%d )",
					 server, default_port, mtu, broker );

	CRASSERT( cr_net.initialized );

	if (mtu < CR_MINIMUM_MTU)
	{
		crError( "You tried to connect to server \"%s\" with an mtu of %d, "
						 "but the minimum MTU is %d", server, mtu, CR_MINIMUM_MTU );
	}

	/* Tear the URL apart into relevant portions. */
	if ( !crParseURL( server, protocol, hostname, &port, default_port ) ) {
		 crError( "Malformed URL: \"%s\"", server );
	}

	/* If the host name is "localhost" replace it with the _real_ name
	 * of the localhost.  If we don't do this, there seems to be
	 * confusion in the mothership as to whether or not "localhost" and
	 * "foo.bar.com" are the same machine.
	 */
	if (crStrcmp(hostname, "localhost") == 0) {
		int rv = crGetHostname(hostname, 4096);
		CRASSERT(rv == 0);
		(void) rv;
	}

	/* XXX why is this here???  I think it could be moved into the
	 * crTeacConnection() function with no problem. I.e. change the
	 * connection's port, teac_rank and tcscomm_rank there.  (BrianP)
	 */
	if ( !crStrcmp( protocol, "quadrics" ) ||
	     !crStrcmp( protocol, "quadrics-tcscomm" ) ) {
	  /* For Quadrics protocols, treat "port" as "rank" */
	  if ( port > CR_QUADRICS_HIGHEST_RANK ) {
	    crWarning( "Invalid crserver rank, %d, defaulting to %d\n",
		       port, CR_QUADRICS_LOWEST_RANK );
	    port = CR_QUADRICS_LOWEST_RANK;
	  }
	}
	crDebug( "Connecting to %s on port %d, with protocol %s",
					 hostname, port, protocol );

#ifdef SDP_SUPPORT
	/* This makes me ill, but we need to "fix" the hostname for sdp. MCH */
	if (!crStrcmp(protocol, "sdp")) {
		char* temp;
		temp = strtok(hostname, ".");
		crStrcat(temp, crGetSDPHostnameSuffix());
		crStrcpy(hostname, temp);
		crDebug("SDP rename hostname: %s", hostname);    
	}
#endif

	conn = (CRConnection *) crCalloc( sizeof(*conn) );
	if (!conn)
		return NULL;

	/* init the non-zero fields */
	conn->type               = CR_NO_CONNECTION; /* we don't know yet */
	conn->recv_credits       = CR_INITIAL_RECV_CREDITS;
	conn->hostname           = crStrdup( hostname );
	conn->port               = port;
	conn->mtu                = mtu;
	conn->buffer_size        = mtu;
	conn->broker             = broker;
	conn->endianness         = crDetermineEndianness();
	/* XXX why are these here??? Move them into the crTeacConnection()
	 * and crTcscommConnection() functions.
	 */
	conn->teac_id            = -1;
	conn->teac_rank          = port;
	conn->tcscomm_id         = -1;
	conn->tcscomm_rank       = port;

#ifdef CHROMIUM_THREADSAFE
	crInitMutex(&conn->messageList.lock);
	crInitCondition(&conn->messageList.nonEmpty);
#endif

	/* now, just dispatch to the appropriate protocol's initialization functions. */
	InitConnection(conn, protocol, mtu);

	if (!crNetConnect( conn ))
	{
		crDebug("crNetConnectToServer() failed, freeing the connection");
		crFree( conn );
		return NULL;
	}

	crDebug( "Done connecting to %s (swapping=%d)", server, conn->swap );
	return conn;
}
Example #16
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 );
}
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;
}
Example #18
0
/**
 * This is the main routine responsible for replicating our GL state
 * for a new VNC viewer.  Called when we detect that a new VNC viewer
 * has been started.
 * \param ipaddress  the IP address where the new viewer is running.
 */
void
replicatespuReplicate(int ipaddress) 
{
	GET_THREAD(thread);
	struct in_addr addr;
	char *hosturl;
	char *ipstring;
	int i, r_slot;
	int serverPort;

	crDebug("Replicate SPU: Enter replicatespuReplicate(ipaddress=0x%x)", ipaddress);

	replicatespuFlushAll( (void *)thread );

#ifdef CHROMIUM_THREADSAFE_notyet
	crLockMutex(&_ReplicateMutex);
#endif

	/*
	 * Find empty slot.
	 * Slot 0 is the dummy slot (a non-existant server on devnull connection)
	 */
	for (r_slot = 1; r_slot < CR_MAX_REPLICANTS; r_slot++) {
		if (!IS_CONNECTED(replicate_spu.rserver[r_slot].conn))
			break;
	}
	if (r_slot == CR_MAX_REPLICANTS) {
		crWarning("Replicate SPU: no more replicant slots available");
		return;
	}

	/**
	 ** OK, now rserver[r_slot] is free for use.
	 **/

	/*
	 * At this time, we can only support one VNC viewer per host.
	 * Check for that here.
	 */
	for (i = 1; i < CR_MAX_REPLICANTS; i++) {
		if (replicate_spu.ipnumbers[i] == ipaddress) {
			CRConnection *conn = replicate_spu.rserver[i].conn;
			/* If the connection appears to be active, it may actually be a dangling
			 * connection.  Try flushing it now.  If flushing fails, the connection
			 * type will definitely be CR_NO_CONNECTION (which we test below).
			 */
			if (conn) {
				if (conn->type != CR_NO_CONNECTION) {
					FlushConnection(i);
				}
				if (conn->type != CR_NO_CONNECTION) {
					crWarning("Replicate SPU: Can't connect to multiple VNC viewers on one host.");
#if 0
					/* The above test isn't 100% reliable and can prevent successful
					 * restart of a viewer on a host.  For now, just print warning and
					 * continue.
					 */
					return;
#endif
				}
			}
		}
	}

	replicate_spu.ipnumbers[r_slot] = ipaddress;

	serverPort = replicate_spu.chromium_start_port + r_slot;

	if (replicate_spu.vncAvailable) {
		/* Send a ChromiumStart message to the VNC Server.  The VNC Server will
		 * in turn send a ChromiumStart message to all the attached VNC viewers.
		 * The VNC Viewer/Chromium module will tell its crserver that there's
		 * a new OpenGL client.
		 * We pass the mothership port and crserver port in this message.
		 */
		char protocol[100], hostname[1000];
		const char *mothershipURL;
		unsigned short mothershipPort;
		mothershipURL = crGetenv("CRMOTHERSHIP");
		crDebug("Replicate SPU: CRMOTHERSHIP env var = %s", mothershipURL);
		if (mothershipURL)
			crParseURL(mothershipURL, protocol, hostname, &mothershipPort,
								 DEFAULT_MOTHERSHIP_PORT);
		else
			mothershipPort = DEFAULT_MOTHERSHIP_PORT;
		crDebug("Replicate SPU: Sending ChromiumStart msg to VNC server, port=%d",
						serverPort);

		if (!XVncChromiumStart(replicate_spu.glx_display, ipaddress,
													 serverPort, mothershipPort)) {
			 crWarning("Replicate SPU: XVncChromiumStart() call failed");
		}
	}

	addr.s_addr = ipaddress;
	ipstring = inet_ntoa(addr);
	hosturl = crAlloc(crStrlen(ipstring) + 9);
	sprintf(hosturl, "tcpip://%s", ipstring);

	crDebug("Replicate SPU attaching to %s on port %d", hosturl, serverPort);

	/* connect to the remote VNC server */
	replicate_spu.rserver[r_slot].name = crStrdup( replicate_spu.name );
	replicate_spu.rserver[r_slot].buffer_size = replicate_spu.buffer_size;
	replicate_spu.rserver[r_slot].conn
		= crNetConnectToServer( hosturl, serverPort,
														replicate_spu.rserver[r_slot].buffer_size, 1);

	if (!replicate_spu.rserver[r_slot].conn) {
		crWarning("Replicate SPU: failed to connect to %s", hosturl);
		return;
	}

	CRASSERT(replicate_spu.rserver[r_slot].conn);

	/*
	 * Setup the the packer flush function.  While replicating state to
	 * a particular server we definitely don't want to do any broadcast
	 * flushing!
	 */
	crPackFlushFunc( thread->packer, replicatespuFlushOnePacker );
	crPackSendHugeFunc( thread->packer, replicatespuHugeOnePacker );

	NewServerIndex = r_slot;

	/*
	 * Create server-side windows and contexts by walking tables of app windows
	 * and contexts.  Note that windows can be created in random order,
	 * but contexts must be created in the order they were originally
	 * created, or shared contexts will break.
	 */
	crHashtableWalk(replicate_spu.windowTable, replicatespuReplicateWindow, thread);
	crListApply(replicate_spu.contextList, replicatespuReplicateContext, thread);

	/* MakeCurrent, the current context */
	if (thread->currentContext) {
		int serverWindow = thread->currentContext->currentWindow->id[r_slot];
		int serverContext = thread->currentContext->rserverCtx[r_slot];
		if (replicate_spu.swap)
			crPackMakeCurrentSWAP(serverWindow, 0, serverContext);
	 	else
			crPackMakeCurrent(serverWindow, 0, serverContext);

		crStateMakeCurrent( thread->currentContext->State );
	}

	/*
	 * Set window sizes
	 */
	crHashtableWalk(replicate_spu.windowTable, replicatespuResizeWindows, thread);
	replicatespuFlushOne(thread, NewServerIndex);

	/*
	 * restore normal, broadcasting packer flush function now.
	 */
	crPackFlushFunc( thread->packer, replicatespuFlush );
	crPackSendHugeFunc( thread->packer, replicatespuHuge );

	NewServerIndex = -1;

	crDebug("Replicate SPU: leaving replicatespuReplicate");

#ifdef CHROMIUM_THREADSAFE_notyet
	crUnlockMutex(&_ReplicateMutex);
#endif
}