Esempio n. 1
0
int32_t crVBoxServerClientWrite(uint32_t u32ClientID, uint8_t *pBuffer, uint32_t cbBuffer)
{
    CRClient *pClient = NULL;
    int32_t i;
#ifdef VBOXCR_LOGFPS
    uint64_t tstart, tend;
#endif

    /*crDebug("=>crServer: ClientWrite u32ClientID=%d", u32ClientID);*/

    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn
            && cr_server.clients[i]->conn->u32ClientID==u32ClientID)
        {
            pClient = cr_server.clients[i];
            break;
        }
    }
    if (!pClient) return VERR_INVALID_PARAMETER;

    if (!pClient->conn->vMajor) return VERR_NOT_SUPPORTED;

#ifdef VBOXCR_LOGFPS
    tstart = RTTimeNanoTS();
#endif

    CRASSERT(pBuffer);

    /* This should never fire unless we start to multithread */
    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);

    /* Check if there's a blocker in queue and it's not this client */
    if (cr_server.run_queue->client != pClient
        && crServerClientInBeginEnd(cr_server.run_queue->client))
    {
        crDebug("crServer: client %d blocked, allow_redir_ptr = 0", u32ClientID);
        pClient->conn->allow_redir_ptr = 0;
    }
    else
    {
        pClient->conn->allow_redir_ptr = 1;
    }

    pClient->conn->pBuffer = pBuffer;
    pClient->conn->cbBuffer = cbBuffer;

    crNetRecv();
    CRASSERT(pClient->conn->pBuffer==NULL && pClient->conn->cbBuffer==0);

    crServerServiceClients();

#if 0
        if (pClient->currentMural) {
            crStateViewport( 0, 0, 500, 500 );
            pClient->currentMural->viewportValidated = GL_FALSE;
            cr_server.head_spu->dispatch_table.Viewport( 0, 0, 500, 500 );
            crStateViewport( 0, 0, 600, 600 );
            pClient->currentMural->viewportValidated = GL_FALSE;
            cr_server.head_spu->dispatch_table.Viewport( 0, 0, 600, 600 );

            crStateMatrixMode(GL_PROJECTION);
            cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.6, 0.6, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.6, 0.6, -0.5, 0.5, 1.5, 150.0);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);

            crStateMatrixMode(GL_MODELVIEW);
            cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
            crServerDispatchLoadIdentity();
            crStateFrustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            cr_server.head_spu->dispatch_table.Frustum(-0.5, 0.5, -0.5, 0.5, 1.5, 150.0);
            crServerDispatchLoadIdentity();
        }
#endif

    crStateResetCurrentPointers(&cr_server.current);

    CRASSERT(!pClient->conn->allow_redir_ptr || crNetNumMessages(pClient->conn)==0);

#ifdef VBOXCR_LOGFPS
    tend = RTTimeNanoTS();
    pClient->timeUsed += tend-tstart;
#endif
    /*crDebug("<=crServer: ClientWrite u32ClientID=%d", u32ClientID);*/

    return VINF_SUCCESS;
}
Esempio n. 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;
}
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;
}