Esempio n. 1
0
int32_t DLM_APIENTRY crDLMSaveState(CRDLM *dlm, PSSMHANDLE pSSM)
{
    uint32_t ui32;
    int32_t  rc;

    CRDLMSaveListsCbArg arg;

    arg.pSSM = pSSM;
    arg.err = 0;

    /* Save number of Display Lists assigned to current DLM context. */
    ui32 = (uint32_t)crHashtableNumElements(dlm->displayLists);
    rc = SSMR3PutU32(pSSM, ui32); AssertRCReturn(rc, rc);

    crHashtableWalk(dlm->displayLists, crDLMSaveListsCb, (void *)&arg);

    return arg.err == 0;
}
Esempio n. 2
0
DECLEXPORT(int32_t) crVBoxServerSaveState(PSSMHANDLE pSSM)
{
    int32_t  rc, i;
    uint32_t ui32;
    GLboolean b;
    unsigned long key;
#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    unsigned long ctxID=-1, winID=-1;
#endif

    /* We shouldn't be called if there's no clients at all*/
    CRASSERT(cr_server.numClients>0);

    /* @todo it's hack atm */
    /* We want to be called only once to save server state but atm we're being called from svcSaveState
     * for every connected client (e.g. guest opengl application)
     */
    if (!cr_server.bIsInSavingState) /* It's first call */
    {
        cr_server.bIsInSavingState = GL_TRUE;

        /* Store number of clients */
        rc = SSMR3PutU32(pSSM, (uint32_t) cr_server.numClients);
        AssertRCReturn(rc, rc);

        g_hackVBoxServerSaveLoadCallsLeft = cr_server.numClients;
    }

    g_hackVBoxServerSaveLoadCallsLeft--;

    /* Do nothing until we're being called last time */
    if (g_hackVBoxServerSaveLoadCallsLeft>0)
    {
        return VINF_SUCCESS;
    }

    /* Save rendering contexts creation info */
    ui32 = crHashtableNumElements(cr_server.pContextCreateInfoTable);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.pContextCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM);

#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    /* Save current win and ctx IDs, as we'd rebind contexts when saving textures */
    if (cr_server.curClient)
    {
        ctxID = cr_server.curClient->currentContextNumber;
        winID = cr_server.curClient->currentWindow;
    }
#endif

    /* Save contexts state tracker data */
    /* @todo For now just some blind data dumps,
     * but I've a feeling those should be saved/restored in a very strict sequence to
     * allow diff_api to work correctly.
     * Should be tested more with multiply guest opengl apps working when saving VM snapshot.
     */
    crHashtableWalk(cr_server.contextTable, crVBoxServerSaveContextStateCB, pSSM);

#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
    /* Restore original win and ctx IDs*/
    if (cr_server.curClient)
    {
        crServerDispatchMakeCurrent(winID, 0, ctxID);
    }
#endif

    /* Save windows creation info */
    ui32 = crHashtableNumElements(cr_server.pWindowCreateInfoTable);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.pWindowCreateInfoTable, crVBoxServerSaveCreateInfoCB, pSSM);

    /* Save cr_server.muralTable
     * @todo we don't need it all, just geometry info actually
     */
    ui32 = crHashtableNumElements(cr_server.muralTable);
    /* There should be default mural always */
    CRASSERT(ui32>=1);
    rc = SSMR3PutU32(pSSM, (uint32_t) ui32-1);
    AssertRCReturn(rc, rc);
    crHashtableWalk(cr_server.muralTable, crVBoxServerSaveMuralCB, pSSM);

    /* Save starting free context and window IDs */
    rc = SSMR3PutMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    AssertRCReturn(rc, rc);

    /* Save clients info */
    for (i = 0; i < cr_server.numClients; i++)
    {
        if (cr_server.clients[i] && cr_server.clients[i]->conn)
        {
            CRClient *pClient = cr_server.clients[i];

            rc = SSMR3PutU32(pSSM, pClient->conn->u32ClientID);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutU32(pSSM, pClient->conn->vMajor);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutU32(pSSM, pClient->conn->vMinor);
            AssertRCReturn(rc, rc);

            rc = SSMR3PutMem(pSSM, pClient, sizeof(*pClient));
            AssertRCReturn(rc, rc);

            if (pClient->currentCtx && pClient->currentContextNumber>=0)
            {
                b = crHashtableGetDataKey(cr_server.contextTable, pClient->currentCtx, &key);
                CRASSERT(b);
                rc = SSMR3PutMem(pSSM, &key, sizeof(key));
                AssertRCReturn(rc, rc);
            }

            if (pClient->currentMural && pClient->currentWindow>=0)
            {
                b = crHashtableGetDataKey(cr_server.muralTable, pClient->currentMural, &key);
                CRASSERT(b);
                rc = SSMR3PutMem(pSSM, &key, sizeof(key));
                AssertRCReturn(rc, rc);
            }
        }
    }

    cr_server.bIsInSavingState = GL_FALSE;

    return VINF_SUCCESS;
}