Ejemplo n.º 1
0
/**
 * KVM state-load operation, final pass.
 *
 * @returns VBox status code.
 * @param   pVM             Pointer to the VM.
 * @param   pSSM            Pointer to the SSM handle.
 * @param   uSSMVersion     The GIM saved-state version.
 */
VMMR3_INT_DECL(int) gimR3KvmLoad(PVM pVM, PSSMHANDLE pSSM, uint32_t uSSMVersion)
{
    /*
     * Load the KVM SSM version first.
     */
    uint32_t uKvmSavedStatVersion;
    int rc = SSMR3GetU32(pSSM, &uKvmSavedStatVersion);
    AssertRCReturn(rc, rc);
    if (uKvmSavedStatVersion != GIM_KVM_SAVED_STATE_VERSION)
        return SSMR3SetLoadError(pSSM, VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION, RT_SRC_POS,
                                 N_("Unsupported KVM saved-state version %u (expected %u)."), uKvmSavedStatVersion,
                                 GIM_KVM_SAVED_STATE_VERSION);

    /*
     * Update the TSC frequency from TM.
     */
    PGIMKVM pKvm = &pVM->gim.s.u.Kvm;
    pKvm->cTscTicksPerSecond = TMCpuTicksPerSecond(pVM);

    /*
     * Load per-VCPU data.
     */
    for (uint32_t i = 0; i < pVM->cCpus; i++)
    {
        PVMCPU     pVCpu   = &pVM->aCpus[i];
        PGIMKVMCPU pKvmCpu = &pVCpu->gim.s.u.KvmCpu;

        uint8_t fSystemTimeFlags = 0;
        SSMR3GetU64(pSSM, &pKvmCpu->u64SystemTimeMsr);
        SSMR3GetU64(pSSM, &pKvmCpu->uTsc);
        SSMR3GetU64(pSSM, &pKvmCpu->uVirtNanoTS);
        SSMR3GetGCPhys(pSSM, &pKvmCpu->GCPhysSystemTime);
        SSMR3GetU32(pSSM, &pKvmCpu->u32SystemTimeVersion);
        rc = SSMR3GetU8(pSSM, &pKvmCpu->fSystemTimeFlags);
        AssertRCReturn(rc, rc);

        /* Enable the system-time struct. if necessary. */
        /** @todo update guest struct only if cTscTicksPerSecond doesn't match host
         *        anymore. */
        if (MSR_GIM_KVM_SYSTEM_TIME_IS_ENABLED(pKvmCpu->u64SystemTimeMsr))
        {
            Assert(!TMVirtualIsTicking(pVM));       /* paranoia. */
            Assert(!TMCpuTickIsTicking(pVCpu));
            rc = gimR3KvmEnableSystemTime(pVM, pVCpu);
            AssertRCReturn(rc, rc);
        }
    }

    /*
     * Load per-VM data.
     */
    SSMR3GetU64(pSSM, &pKvm->u64WallClockMsr);
    rc = SSMR3GetU32(pSSM, &pKvm->uBaseFeat);
    AssertRCReturn(rc, rc);

    return VINF_SUCCESS;
}
Ejemplo n.º 2
0
int readSavedGuestSize(const Utf8Str &strStateFilePath, uint32_t u32ScreenId, uint32_t *pu32Width, uint32_t *pu32Height)
{
    LogFlowFunc(("u32ScreenId = %d [%s]\n", u32ScreenId, strStateFilePath.c_str()));

    /* @todo cache read data */
    if (strStateFilePath.isEmpty())
    {
        /* No saved state data. */
        return VERR_NOT_SUPPORTED;
    }

    uint32_t u32Width = 0;
    uint32_t u32Height = 0;

    PSSMHANDLE pSSM;
    int vrc = SSMR3Open(strStateFilePath.c_str(), 0 /*fFlags*/, &pSSM);
    if (RT_SUCCESS(vrc))
    {
        uint32_t uVersion;
        vrc = SSMR3Seek(pSSM, "DisplayData", 0 /*iInstance*/, &uVersion);
        if (RT_SUCCESS(vrc))
        {
            /* Only the second version is supported. */
            if (   uVersion == sSSMDisplayVer2
                || uVersion == sSSMDisplayVer3)
            {
                uint32_t cMonitors;
                SSMR3GetU32(pSSM, &cMonitors);
                if (u32ScreenId > cMonitors)
                    vrc = -2;
                else
                {
                    /* Skip all previous monitors and the first 3 entries. */
                    SSMR3Skip(pSSM, u32ScreenId * 5 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
                    SSMR3GetU32(pSSM, &u32Width);
                    SSMR3GetU32(pSSM, &u32Height);
                }
            }
        }

        SSMR3Close(pSSM);
    }

    if (RT_SUCCESS(vrc))
    {
        *pu32Width = u32Width;
        *pu32Height = u32Height;
    }

    LogFlowFunc(("vrc %Rrc\n", vrc));
    return vrc;
}
Ejemplo n.º 3
0
bool DLM_APIENTRY
crDLMLoadState(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
{
    uint32_t cLists = 0;
    uint32_t i;
    int32_t  rc;
    bool     fSuccess = true;

    /* Get number of Display Lists assigned to current DLM context. */
    rc = SSMR3GetU32(pSSM, &cLists);
    if (RT_SUCCESS(rc))
    {
        crDebug("Restoring Display Lists: %u lists to restore.", cLists);

        for (i = 0; i < cLists; i++)
        {
            fSuccess = crDLMLoadList(dlm, pSSM, dispatchTable);
            if (!fSuccess)
                break;
        }
    }
    else
        crError("Restoring Display Lists: can't get number of lists.");

    return fSuccess;
}
Ejemplo n.º 4
0
static bool
crDLMLoadListInstance(PSSMHANDLE pSSM, DLMListInfo *pListInfo, SPUDispatchTable *dispatchTable)
{
    uint32_t         cbInstance = 0;
    DLMInstanceList *pInstance;
    int32_t          rc;

    /* Get Display List item size. */
    rc = SSMR3GetU32(pSSM, &cbInstance);
    if (RT_SUCCESS(rc))
    {
        /* Allocate memory for the item, initialize it and put into the list. */
        pInstance = crCalloc(cbInstance);
        if (pInstance)
        {
            crMemset(pInstance, 0, cbInstance);

            rc = SSMR3GetMem(pSSM, pInstance, cbInstance); AssertRCReturn(rc, rc);
            if (RT_SUCCESS(rc))
            {
                pInstance->execute = crDLMGetExecuteRoutine(pInstance->iVBoxOpCode);
                if (pInstance->execute)
                {
                    pInstance->execute(pInstance, dispatchTable);

                    pInstance->next         = NULL;
                    pInstance->stateNext    = NULL;
                    pInstance->cbInstance   = cbInstance;

                    pListInfo->numInstances++;

                    if (!pListInfo->first)
                        pListInfo->first = pInstance;

                    if (pListInfo->last)
                        pListInfo->last->next = pInstance;

                    pListInfo->last = pInstance;

                    return true;
                }
                else
                    crError("Restoring Display Lists: unknown list item (opcode=%u).", pInstance->iVBoxOpCode);
            }
            else
                crError("Restoring Display Lists: can't read list element size.");
        }
        else
            crError("Restoring Display Lists: not enough memory, aborting.");
    }
    else
        crError("Restoring Display Lists: saved state file might be corrupted.");

    return false;
}
Ejemplo n.º 5
0
/**
 * Load a queue state.
 *
 * @param   pSSM                SSM handle to read the state from.
 * @param   pQ                  Pointer to the queue.
 *
 * @return  int                 VBox status/error code.
 */
static int ps2kLoadQueue(PSSMHANDLE pSSM, GeneriQ *pQ)
{
    int         rc;

    /* On load, always put the read pointer at zero. */
    SSMR3GetU32(pSSM, &pQ->cUsed);

    LogFlow(("Loading %d items to queue %p\n", pQ->cUsed, pQ));

    if (pQ->cUsed > pQ->cSize)
    {
        AssertMsgFailed(("Saved size=%u, actual=%u\n", pQ->cUsed, pQ->cSize));
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Recalculate queue positions and load data in one go. */
    pQ->rpos = 0;
    pQ->wpos = pQ->cUsed;
    rc = SSMR3GetMem(pSSM, pQ->abQueue, pQ->cUsed);

    return rc;
}
int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
    RT_NOREF(uPass);
    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    AssertReturn(pState, VERR_NO_MEMORY);
    int            rc;
    uint32_t       cContexts, cSurfaces;
    LogFlow(("vmsvga3dLoadExec:\n"));

#ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
    /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
    vmsvga3dPowerOn(pThis);
#endif

    /* Get the generic 3d state first. */
    rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    AssertRCReturn(rc, rc);

    cContexts                           = pState->cContexts;
    cSurfaces                           = pState->cSurfaces;
    pState->cContexts                   = 0;
    pState->cSurfaces                   = 0;

    /* Fetch all active contexts. */
    for (uint32_t i = 0; i < cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext;
        uint32_t         cid;

        /* Get the context id */
        rc = SSMR3GetU32(pSSM, &cid);
        AssertRCReturn(rc, rc);

        if (cid != SVGA3D_INVALID_ID)
        {
            uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
            LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));

#ifdef VMSVGA3D_OPENGL
            if (cid == VMSVGA3D_SHARED_CTX_ID)
            {
                i--; /* Not included in cContexts. */
                pContext = &pState->SharedCtx;
                if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
                {
                    rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
                    AssertRCReturn(rc, rc);
                }
            }
            else
#endif
            {
                rc = vmsvga3dContextDefine(pThis, cid);
                AssertRCReturn(rc, rc);

                pContext = pState->papContexts[i];
            }
            AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);

            rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
            AssertRCReturn(rc, rc);

            cPixelShaders                       = pContext->cPixelShaders;
            cVertexShaders                      = pContext->cVertexShaders;
            cPixelShaderConst                   = pContext->state.cPixelShaderConst;
            cVertexShaderConst                  = pContext->state.cVertexShaderConst;
            pContext->cPixelShaders             = 0;
            pContext->cVertexShaders            = 0;
            pContext->state.cPixelShaderConst   = 0;
            pContext->state.cVertexShaderConst  = 0;

            /* Fetch all pixel shaders. */
            for (uint32_t j = 0; j < cPixelShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch all vertex shaders. */
            for (uint32_t j = 0; j < cVertexShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch pixel shader constants. */
            for (uint32_t j = 0; j < cPixelShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            /* Fetch vertex shader constants. */
            for (uint32_t j = 0; j < cVertexShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_TEX_STAGES)
            {
                /* Load texture stage and samplers state. */

                /* Number of stages/samplers. */
                uint32_t cStages;
                rc = SSMR3GetU32(pSSM, &cStages);
                AssertRCReturn(rc, rc);

                /* Number of states. */
                uint32_t cTextureStates;
                rc = SSMR3GetU32(pSSM, &cTextureStates);
                AssertRCReturn(rc, rc);

                for (uint32_t iStage = 0; iStage < cStages; ++iStage)
                {
                    for (uint32_t j = 0; j < cTextureStates; ++j)
                    {
                        SVGA3dTextureState textureState;
                        SSMR3GetU32(pSSM, &textureState.stage);
                        uint32_t u32Name;
                        SSMR3GetU32(pSSM, &u32Name);
                        textureState.name = (SVGA3dTextureStateName)u32Name;
                        rc = SSMR3GetU32(pSSM, &textureState.value);
                        AssertRCReturn(rc, rc);

                        if (   iStage < RT_ELEMENTS(pContext->state.aTextureStates)
                            && j < RT_ELEMENTS(pContext->state.aTextureStates[0]))
                        {
                            pContext->state.aTextureStates[iStage][j] = textureState;
                        }
                    }
                }
            }

            if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA)
            {
                VMSVGA3DQUERY query;
                RT_ZERO(query);

                rc = SSMR3GetStructEx(pSSM, &query, sizeof(query), 0, g_aVMSVGA3DQUERYFields, NULL);
                AssertRCReturn(rc, rc);

                switch (query.enmQueryState)
                {
                    case VMSVGA3DQUERYSTATE_BUILDING:
                        /* Start collecting data. */
                        vmsvga3dQueryBegin(pThis, cid, SVGA3D_QUERYTYPE_OCCLUSION);
                        /* Partial result. */
                        pContext->occlusion.u32QueryResult = query.u32QueryResult;
                        break;

                    case VMSVGA3DQUERYSTATE_ISSUED:
                        /* Guest ended the query but did not read result. Result is restored. */
                        query.enmQueryState = VMSVGA3DQUERYSTATE_SIGNALED;
                        RT_FALL_THRU();
                    case VMSVGA3DQUERYSTATE_SIGNALED:
                        /* Create the query object. */
                        vmsvga3dOcclusionQueryCreate(pState, pContext);

                        /* Update result and state. */
                        pContext->occlusion.enmQueryState = query.enmQueryState;
                        pContext->occlusion.u32QueryResult = query.u32QueryResult;
                        break;

                    default:
                        AssertFailed();
                        RT_FALL_THRU();
                    case VMSVGA3DQUERYSTATE_NULL:
                        RT_ZERO(pContext->occlusion);
                        break;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Make the shared context the current one. */
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
        VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
#endif

    /* Fetch all surfaces. */
    for (uint32_t i = 0; i < cSurfaces; i++)
    {
        uint32_t sid;

        /* Fetch the id first. */
        rc = SSMR3GetU32(pSSM, &sid);
        AssertRCReturn(rc, rc);

        if (sid != SVGA3D_INVALID_ID)
        {
            VMSVGA3DSURFACE  surface;
            LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));

            /* Fetch the surface structure first. */
            rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
            AssertRCReturn(rc, rc);

            {
                uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
                AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
                SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
                AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);

                /* Load the mip map level info. */
                for (uint32_t face=0; face < surface.cFaces; face++)
                {
                    for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
                    {
                        uint32_t idx = j + face * surface.faces[0].numMipLevels;
                        /* Load the mip map level struct. */
                        rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
                        AssertRCReturn(rc, rc);

                        pMipmapLevelSize[idx] = pMipmapLevel[idx].mipmapSize;
                    }
                }

                rc = vmsvga3dSurfaceDefine(pThis, sid, surface.surfaceFlags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
                AssertRCReturn(rc, rc);

                RTMemFree(pMipmapLevelSize);
                RTMemFree(pMipmapLevel);
            }

            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
            Assert(pSurface->id == sid);

            pSurface->fDirty = false;

            /* Load the mip map level data. */
            for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
            {
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
                bool fDataPresent = false;

                /* vmsvga3dSurfaceDefine already allocated the surface data buffer. */
                Assert(pMipmapLevel->cbSurface);
                AssertReturn(pMipmapLevel->pSurfaceData, VERR_INTERNAL_ERROR);

                /* Fetch the data present boolean first. */
                rc = SSMR3GetBool(pSSM, &fDataPresent);
                AssertRCReturn(rc, rc);

                Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));

                if (fDataPresent)
                {
                    rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
                    AssertRCReturn(rc, rc);
                    pMipmapLevel->fDirty = true;
                    pSurface->fDirty     = true;
                }
                else
                {
                    pMipmapLevel->fDirty = false;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Reinitialize the shared context. */
    LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    {
        rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
        AssertRCReturn(rc, rc);
    }
#endif

    /* Reinitialize all active contexts. */
    for (uint32_t i = 0; i < pState->cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
        if (pContext->id != SVGA3D_INVALID_ID)
        {
            rc = vmsvga3dLoadReinitContext(pThis, pContext);
            AssertRCReturn(rc, rc);
        }
    }

    LogFlow(("vmsvga3dLoadExec: return success\n"));
    return VINF_SUCCESS;
}
Ejemplo n.º 7
0
static bool
crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable)
{
    uint32_t cElements = 0;
    uint32_t idList    = 0;
    uint32_t i;
    int32_t  rc;

    /* Restore Display List length. */
    rc = SSMR3GetU32(pSSM, &cElements);
    if (RT_SUCCESS(rc))
    {
        /* Restore Display List ID. */
        rc = SSMR3GetU32(pSSM, &idList);
        if (RT_SUCCESS(rc))
        {
            /* Initialize new list data and start recording it. */
            DLMListInfo *pListInfo;

            pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
            if (pListInfo)
            {
                GLuint hwid;

                crMemset(pListInfo, 0, sizeof(DLMListInfo));

                hwid = dispatchTable->GenLists(1);
                if (hwid > 0)
                {
                    bool               fSuccess = true;
                    CRDLMContextState *pDLMContextState;

                    pListInfo->numInstances = 0;
                    pListInfo->stateFirst   = pListInfo->stateLast = NULL;
                    pListInfo->hwid         = hwid;

                    dispatchTable->NewList(hwid, GL_COMPILE);

                    /* Fake list state in order to prevent expando SPU from double caching. */
                    pDLMContextState = crDLMGetCurrentState();
                    pDLMContextState->currentListMode = GL_FALSE;

                    crDebug("Restoring Display Lists:\t%u elements to restore.", cElements);

                    /* Iterate over list instances. */
                    for (i = 0; i < cElements; i++)
                    {
                        fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable);
                        if (!fSuccess)
                            break;
                    }

                    dispatchTable->EndList();

                    if (fSuccess)
                    {
                        /* Add list to cache. */
                        crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL);
                        return true;
                    }
                    else
                        crError("Restoring Display Lists: some elements could not be restored.");
                }
                else
                    crError("Restoring Display Lists: can't allocate hwid for list %u.", idList);

                crFree(pListInfo);
            }
            else
                crError("Restoring Display Lists: can't allocate memory.");
        }
        else
            crError("Restoring Display Lists: can't get list ID.");
    }
    else
        crError("Restoring Display Lists: can't get number of elements in list.");

    return false;
}
/**
 * Hyper-V state-load operation, final pass.
 *
 * @returns VBox status code.
 * @param   pVM             Pointer to the VM.
 * @param   pSSM            Pointer to the SSM handle.
 * @param   uSSMVersion     The GIM saved-state version.
 */
VMMR3_INT_DECL(int) gimR3HvLoad(PVM pVM, PSSMHANDLE pSSM, uint32_t uSSMVersion)
{
    PGIMHV pHv = &pVM->gim.s.u.Hv;

    /*
     * Load the Hyper-V SSM version first.
     */
    uint32_t uHvSavedStatVersion;
    int rc = SSMR3GetU32(pSSM, &uHvSavedStatVersion);
    AssertRCReturn(rc, rc);
    if (uHvSavedStatVersion != GIM_HV_SAVED_STATE_VERSION)
        return SSMR3SetLoadError(pSSM, VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION, RT_SRC_POS,
                                 N_("Unsupported Hyper-V saved-state version %u (expected %u)."), uHvSavedStatVersion,
                                 GIM_HV_SAVED_STATE_VERSION);

    /*
     * Load per-VM MSRs.
     */
    SSMR3GetU64(pSSM, &pHv->u64GuestOsIdMsr);
    SSMR3GetU64(pSSM, &pHv->u64HypercallMsr);
    SSMR3GetU64(pSSM, &pHv->u64TscPageMsr);

    /*
     * Load Hyper-V features / capabilities.
     */
    SSMR3GetU32(pSSM, &pHv->uBaseFeat);
    SSMR3GetU32(pSSM, &pHv->uPartFlags);
    SSMR3GetU32(pSSM, &pHv->uPowMgmtFeat);
    SSMR3GetU32(pSSM, &pHv->uMiscFeat);
    SSMR3GetU32(pSSM, &pHv->uHyperHints);
    SSMR3GetU32(pSSM, &pHv->uHyperCaps);

    /*
     * Load and enable the Hypercall region.
     */
    PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX];
    SSMR3GetU8(pSSM,     &pRegion->iRegion);
    SSMR3GetBool(pSSM,   &pRegion->fRCMapping);
    SSMR3GetU32(pSSM,    &pRegion->cbRegion);
    SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage);
    rc = SSMR3GetStrZ(pSSM, pRegion->szDescription, sizeof(pRegion->szDescription));
    AssertRCReturn(rc, rc);
    if (MSR_GIM_HV_HYPERCALL_IS_ENABLED(pHv->u64HypercallMsr))
    {
        Assert(pRegion->GCPhysPage != NIL_RTGCPHYS);
        if (RT_LIKELY(pRegion->fRegistered))
        {
            rc = gimR3HvEnableHypercallPage(pVM, pRegion->GCPhysPage);
            if (RT_FAILURE(rc))
                return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to enable the hypercall page. GCPhys=%#RGp rc=%Rrc"),
                                        pRegion->GCPhysPage, rc);
        }
        else
            return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Hypercall MMIO2 region not registered. Missing GIM device?!"));
    }

    /*
     * Load and enable the reference TSC region.
     */
    uint32_t uTscSequence;
    pRegion = &pHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
    SSMR3GetU8(pSSM,     &pRegion->iRegion);
    SSMR3GetBool(pSSM,   &pRegion->fRCMapping);
    SSMR3GetU32(pSSM,    &pRegion->cbRegion);
    SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage);
    SSMR3GetStrZ(pSSM,    pRegion->szDescription, sizeof(pRegion->szDescription));
    rc = SSMR3GetU32(pSSM, &uTscSequence);
    AssertRCReturn(rc, rc);
    if (MSR_GIM_HV_REF_TSC_IS_ENABLED(pHv->u64TscPageMsr))
    {
        Assert(pRegion->GCPhysPage != NIL_RTGCPHYS);
        if (pRegion->fRegistered)
        {
            rc = gimR3HvEnableTscPage(pVM, pRegion->GCPhysPage, true /* fUseThisTscSeq */, uTscSequence);
            if (RT_FAILURE(rc))
                return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to enable the TSC page. GCPhys=%#RGp rc=%Rrc"),
                                        pRegion->GCPhysPage, rc);
        }
        else
            return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("TSC-page MMIO2 region not registered. Missing GIM device?!"));
    }

    return rc;
}
Ejemplo n.º 9
0
static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
{
#ifndef UNIT_TEST
    LogRel2 (("svcLoadState: u32ClientID = %d\n", u32ClientID));

    VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient;

    /* Existing client can not be in async state yet. */
    Assert (!pClient->fAsync);

    /* Save the client ID for data validation. */
    /** @todo isn't this the same as u32ClientID? Playing safe for now... */
    uint32_t const u32ClientIDOld = pClient->u32ClientID;

    /* Restore the client data. */
    uint32_t lenOrVer;
    int rc = SSMR3GetU32 (pSSM, &lenOrVer);
    AssertRCReturn (rc, rc);
    if (lenOrVer == UINT32_C (0x80000002))
    {
        rc = SSMR3GetStructEx (pSSM, pClient, sizeof(*pClient), 0 /*fFlags*/, &g_aClipboardClientDataFields[0], NULL);
        AssertRCReturn (rc, rc);
    }
    else if (lenOrVer == (SSMR3HandleHostBits (pSSM) == 64 ? 72 : 48))
    {
        /**
         * SSM descriptor table for the CLIPSAVEDSTATEDATA structure.
         */
        static SSMFIELD const s_aClipSavedStateDataFields30[] =
        {
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pNext),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pPrev),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, pCtx),
            SSMFIELD_ENTRY(                 CLIPSAVEDSTATEDATA, u32ClientID),
            SSMFIELD_ENTRY_CUSTOM(fMsgQuit+fMsgReadData+fMsgFormats, RT_OFFSETOF(CLIPSAVEDSTATEDATA, u32ClientID) + 4, 4),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, async.callHandle),
            SSMFIELD_ENTRY_IGN_HCPTR(       CLIPSAVEDSTATEDATA, async.paParms),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.pv),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.cb),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, data.u32Format),
            SSMFIELD_ENTRY_IGNORE(          CLIPSAVEDSTATEDATA, u32AvailableFormats),
            SSMFIELD_ENTRY(                 CLIPSAVEDSTATEDATA, u32RequestedFormat),
            SSMFIELD_ENTRY_TERM()
        };

        CLIPSAVEDSTATEDATA savedState;
        RT_ZERO (savedState);
        rc = SSMR3GetStructEx (pSSM, &savedState, sizeof(savedState), SSMSTRUCT_FLAGS_MEM_BAND_AID,
                               &s_aClipSavedStateDataFields30[0], NULL);
        AssertRCReturn (rc, rc);

        pClient->fMsgQuit           = savedState.fMsgQuit;
        pClient->fMsgReadData       = savedState.fMsgReadData;
        pClient->fMsgFormats        = savedState.fMsgFormats;
        pClient->u32RequestedFormat = savedState.u32RequestedFormat;
    }
    else
    {
        LogRel (("Client data size mismatch: got %#x\n", lenOrVer));
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Verify the client ID. */
    if (pClient->u32ClientID != u32ClientIDOld)
    {
        LogRel (("Client ID mismatch: expected %d, got %d\n", u32ClientIDOld, pClient->u32ClientID));
        pClient->u32ClientID = u32ClientIDOld;
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Actual host data are to be reported to guest (SYNC). */
    vboxClipboardSync (pClient);

#endif /* !UNIT_TEST */
    return VINF_SUCCESS;
}
Ejemplo n.º 10
0
int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
    PVMSVGA3DSTATE pState = pThis->svga.p3dState;
    AssertReturn(pState, VERR_NO_MEMORY);
    int            rc;
    uint32_t       cContexts, cSurfaces;
    LogFlow(("vmsvga3dLoadExec:\n"));

#ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
    /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
    vmsvga3dPowerOn(pThis);
#endif

    /* Get the generic 3d state first. */
    rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
    AssertRCReturn(rc, rc);

    cContexts                           = pState->cContexts;
    cSurfaces                           = pState->cSurfaces;
    pState->cContexts                   = 0;
    pState->cSurfaces                   = 0;

    /* Fetch all active contexts. */
    for (uint32_t i = 0; i < cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext;
        uint32_t         cid;

        /* Get the context id */
        rc = SSMR3GetU32(pSSM, &cid);
        AssertRCReturn(rc, rc);

        if (cid != SVGA3D_INVALID_ID)
        {
            uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
            LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));

#ifdef VMSVGA3D_OPENGL
            if (cid == VMSVGA3D_SHARED_CTX_ID)
            {
                i--; /* Not included in cContexts. */
                pContext = &pState->SharedCtx;
                if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
                {
                    rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
                    AssertRCReturn(rc, rc);
                }
            }
            else
#endif
            {
                rc = vmsvga3dContextDefine(pThis, cid);
                AssertRCReturn(rc, rc);

                pContext = pState->papContexts[i];
            }
            AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);

            rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
            AssertRCReturn(rc, rc);

            cPixelShaders                       = pContext->cPixelShaders;
            cVertexShaders                      = pContext->cVertexShaders;
            cPixelShaderConst                   = pContext->state.cPixelShaderConst;
            cVertexShaderConst                  = pContext->state.cVertexShaderConst;
            pContext->cPixelShaders             = 0;
            pContext->cVertexShaders            = 0;
            pContext->state.cPixelShaderConst   = 0;
            pContext->state.cVertexShaderConst  = 0;

            /* Fetch all pixel shaders. */
            for (uint32_t j = 0; j < cPixelShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch all vertex shaders. */
            for (uint32_t j = 0; j < cVertexShaders; j++)
            {
                VMSVGA3DSHADER  shader;
                uint32_t        shid;

                /* Fetch the id first. */
                rc = SSMR3GetU32(pSSM, &shid);
                AssertRCReturn(rc, rc);

                if (shid != SVGA3D_INVALID_ID)
                {
                    uint32_t *pData;

                    /* Fetch a copy of the shader struct. */
                    rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
                    AssertRCReturn(rc, rc);

                    pData = (uint32_t *)RTMemAlloc(shader.cbData);
                    AssertReturn(pData, VERR_NO_MEMORY);

                    rc = SSMR3GetMem(pSSM, pData, shader.cbData);
                    AssertRCReturn(rc, rc);

                    rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
                    AssertRCReturn(rc, rc);

                    RTMemFree(pData);
                }
            }

            /* Fetch pixel shader constants. */
            for (uint32_t j = 0; j < cPixelShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }

            /* Fetch vertex shader constants. */
            for (uint32_t j = 0; j < cVertexShaderConst; j++)
            {
                VMSVGASHADERCONST ShaderConst;

                rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
                AssertRCReturn(rc, rc);

                if (ShaderConst.fValid)
                {
                    rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
                    AssertRCReturn(rc, rc);
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Make the shared context the current one. */
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
        VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
#endif

    /* Fetch all surfaces. */
    for (uint32_t i = 0; i < cSurfaces; i++)
    {
        uint32_t sid;

        /* Fetch the id first. */
        rc = SSMR3GetU32(pSSM, &sid);
        AssertRCReturn(rc, rc);

        if (sid != SVGA3D_INVALID_ID)
        {
            VMSVGA3DSURFACE  surface;
            LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));

            /* Fetch the surface structure first. */
            rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
            AssertRCReturn(rc, rc);

            {
                uint32_t             cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
                AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
                SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
                AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);

                /* Load the mip map level info. */
                for (uint32_t face=0; face < surface.cFaces; face++)
                {
                    for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
                    {
                        uint32_t idx = j + face * surface.faces[0].numMipLevels;
                        /* Load the mip map level struct. */
                        rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
                        AssertRCReturn(rc, rc);

                        pMipmapLevelSize[idx] = pMipmapLevel[idx].size;
                    }
                }

                rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
                AssertRCReturn(rc, rc);

                RTMemFree(pMipmapLevelSize);
                RTMemFree(pMipmapLevel);
            }

            PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
            Assert(pSurface->id == sid);

            pSurface->fDirty = false;

            /* Load the mip map level data. */
            for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
            {
                PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
                bool fDataPresent = false;

                Assert(pMipmapLevel->cbSurface);
                pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
                AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);

                /* Fetch the data present boolean first. */
                rc = SSMR3GetBool(pSSM, &fDataPresent);
                AssertRCReturn(rc, rc);

                Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));

                if (fDataPresent)
                {
                    rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
                    AssertRCReturn(rc, rc);
                    pMipmapLevel->fDirty = true;
                    pSurface->fDirty     = true;
                }
                else
                {
                    pMipmapLevel->fDirty = false;
                }
            }
        }
    }

#ifdef VMSVGA3D_OPENGL
    /* Reinitialize the shared context. */
    LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
    if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
    {
        rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
        AssertRCReturn(rc, rc);
    }
#endif

    /* Reinitialize all active contexts. */
    for (uint32_t i = 0; i < pState->cContexts; i++)
    {
        PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
        if (pContext->id != SVGA3D_INVALID_ID)
        {
            rc = vmsvga3dLoadReinitContext(pThis, pContext);
            AssertRCReturn(rc, rc);
        }
    }

    LogFlow(("vmsvga3dLoadExec: return success\n"));
    return VINF_SUCCESS;
}
Ejemplo n.º 11
0
int readSavedDisplayScreenshot(const Utf8Str &strStateFilePath, uint32_t u32Type, uint8_t **ppu8Data, uint32_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
{
    LogFlowFunc(("u32Type = %d [%s]\n", u32Type, strStateFilePath.c_str()));

    /* @todo cache read data */
    if (strStateFilePath.isEmpty())
    {
        /* No saved state data. */
        return VERR_NOT_SUPPORTED;
    }

    uint8_t *pu8Data = NULL;
    uint32_t cbData = 0;
    uint32_t u32Width = 0;
    uint32_t u32Height = 0;

    PSSMHANDLE pSSM;
    int vrc = SSMR3Open(strStateFilePath.c_str(), 0 /*fFlags*/, &pSSM);
    if (RT_SUCCESS(vrc))
    {
        uint32_t uVersion;
        vrc = SSMR3Seek(pSSM, "DisplayScreenshot", 1100 /*iInstance*/, &uVersion);
        if (RT_SUCCESS(vrc))
        {
            if (uVersion == sSSMDisplayScreenshotVer)
            {
                uint32_t cBlocks;
                vrc = SSMR3GetU32(pSSM, &cBlocks);
                AssertRCReturn(vrc, vrc);

                for (uint32_t i = 0; i < cBlocks; i++)
                {
                    uint32_t cbBlock;
                    vrc = SSMR3GetU32(pSSM, &cbBlock);
                    AssertRCBreak(vrc);

                    uint32_t typeOfBlock;
                    vrc = SSMR3GetU32(pSSM, &typeOfBlock);
                    AssertRCBreak(vrc);

                    LogFlowFunc(("[%d] type %d, size %d bytes\n", i, typeOfBlock, cbBlock));

                    if (typeOfBlock == u32Type)
                    {
                        if (cbBlock > 2 * sizeof(uint32_t))
                        {
                            cbData = cbBlock - 2 * sizeof(uint32_t);
                            pu8Data = (uint8_t *)RTMemAlloc(cbData);
                            if (pu8Data == NULL)
                            {
                                vrc = VERR_NO_MEMORY;
                                break;
                            }

                            vrc = SSMR3GetU32(pSSM, &u32Width);
                            AssertRCBreak(vrc);
                            vrc = SSMR3GetU32(pSSM, &u32Height);
                            AssertRCBreak(vrc);
                            vrc = SSMR3GetMem(pSSM, pu8Data, cbData);
                            AssertRCBreak(vrc);
                        }
                        else
                        {
                            /* No saved state data. */
                            vrc = VERR_NOT_SUPPORTED;
                        }

                        break;
                    }
                    else
                    {
                        /* displaySSMSaveScreenshot did not write any data, if
                         * cbBlock was == 2 * sizeof (uint32_t).
                         */
                        if (cbBlock > 2 * sizeof (uint32_t))
                        {
                            vrc = SSMR3Skip(pSSM, cbBlock);
                            AssertRCBreak(vrc);
                        }
                    }
                }
            }
            else
            {
                vrc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
            }
        }

        SSMR3Close(pSSM);
    }

    if (RT_SUCCESS(vrc))
    {
        if (u32Type == 0 && cbData % 4 != 0)
        {
            /* Bitmap is 32bpp, so data is invalid. */
            vrc = VERR_SSM_UNEXPECTED_DATA;
        }
    }

    if (RT_SUCCESS(vrc))
    {
        *ppu8Data = pu8Data;
        *pcbData = cbData;
        *pu32Width = u32Width;
        *pu32Height = u32Height;
        LogFlowFunc(("cbData %d, u32Width %d, u32Height %d\n", cbData, u32Width, u32Height));
    }

    LogFlowFunc(("vrc %Rrc\n", vrc));
    return vrc;
}
Ejemplo n.º 12
0
int readSavedGuestScreenInfo(const Utf8Str &strStateFilePath, uint32_t u32ScreenId,
                             uint32_t *pu32OriginX, uint32_t *pu32OriginY,
                             uint32_t *pu32Width, uint32_t *pu32Height, uint16_t *pu16Flags)
{
    LogFlowFunc(("u32ScreenId = %d [%s]\n", u32ScreenId, strStateFilePath.c_str()));

    /* @todo cache read data */
    if (strStateFilePath.isEmpty())
    {
        /* No saved state data. */
        return VERR_NOT_SUPPORTED;
    }

    PSSMHANDLE pSSM;
    int vrc = SSMR3Open(strStateFilePath.c_str(), 0 /*fFlags*/, &pSSM);
    if (RT_SUCCESS(vrc))
    {
        uint32_t uVersion;
        vrc = SSMR3Seek(pSSM, "DisplayData", 0 /*iInstance*/, &uVersion);
        if (RT_SUCCESS(vrc))
        {
            if (   uVersion == sSSMDisplayVer2
                || uVersion == sSSMDisplayVer3)
            {
                uint32_t cMonitors;
                SSMR3GetU32(pSSM, &cMonitors);
                if (u32ScreenId > cMonitors)
                {
                    vrc = VERR_INVALID_PARAMETER;
                }
                else
                {
                    if (uVersion == sSSMDisplayVer2)
                    {
                        /* Skip all previous monitors, each 5 uint32_t, and the first 3 uint32_t entries. */
                        SSMR3Skip(pSSM, u32ScreenId * 5 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
                        SSMR3GetU32(pSSM, pu32Width);
                        SSMR3GetU32(pSSM, pu32Height);
                        *pu32OriginX = 0;
                        *pu32OriginY = 0;
                        *pu16Flags = VBVA_SCREEN_F_ACTIVE;
                    }
                    else
                    {
                        Assert(uVersion == sSSMDisplayVer3);
                        /* Skip all previous monitors, each 8 uint32_t, and the first 3 uint32_t entries. */
                        SSMR3Skip(pSSM, u32ScreenId * 8 * sizeof(uint32_t) + 3 * sizeof(uint32_t));
                        SSMR3GetU32(pSSM, pu32Width);
                        SSMR3GetU32(pSSM, pu32Height);
                        SSMR3GetU32(pSSM, pu32OriginX);
                        SSMR3GetU32(pSSM, pu32OriginY);
                        uint32_t u32Flags = 0;
                        SSMR3GetU32(pSSM, &u32Flags);
                        *pu16Flags = (uint16_t)u32Flags;
                    }
                }
            }
            else
            {
                vrc = VERR_NOT_SUPPORTED;
            }
        }

        SSMR3Close(pSSM);
    }

    LogFlowFunc(("vrc %Rrc\n", vrc));
    return vrc;
}
Ejemplo n.º 13
0
DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
{
    int32_t  rc, i;
    uint32_t ui, uiNumElems;
    unsigned long key;

    if (!cr_server.bIsInLoadingState)
    {
        /* AssertRCReturn(...) will leave us in loading state, but it doesn't matter as we'd be failing anyway */
        cr_server.bIsInLoadingState = GL_TRUE;

        /* Read number of clients */
        rc = SSMR3GetU32(pSSM, &g_hackVBoxServerSaveLoadCallsLeft);
        AssertRCReturn(rc, rc);
    }

    g_hackVBoxServerSaveLoadCallsLeft--;

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

    if (version!=SHCROGL_SSM_VERSION)
    {
        return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
    }

    /* Load and recreate rendering contexts */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint ctxID;
        CRContext* pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        ctxID = crServerDispatchCreateContextEx(createInfo.pszDpyName, createInfo.visualBits, 0, key, createInfo.internalID);
        CRASSERT((int64_t)ctxID == (int64_t)key);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);
        pContext->shared->id=-1;
    }

    /* Restore context state data */
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRContext *pContext;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);

        pContext = (CRContext*) crHashtableSearch(cr_server.contextTable, key);
        CRASSERT(pContext);

        rc = crStateLoadContext(pContext, cr_server.contextTable, pSSM);
        AssertRCReturn(rc, rc);
    }

    /* Load windows */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRCreateInfo_t createInfo;
        char psz[200];
        GLint winID;
        unsigned long key;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &createInfo, sizeof(createInfo));
        AssertRCReturn(rc, rc);

        if (createInfo.pszDpyName)
        {
            rc = SSMR3GetStrZEx(pSSM, psz, 200, NULL);
            AssertRCReturn(rc, rc);
            createInfo.pszDpyName = psz;
        }

        winID = crServerDispatchWindowCreateEx(createInfo.pszDpyName, createInfo.visualBits, key);
        CRASSERT((int64_t)winID == (int64_t)key);
    }

    /* Load cr_server.muralTable */
    rc = SSMR3GetU32(pSSM, &uiNumElems);
    AssertRCReturn(rc, rc);
    for (ui=0; ui<uiNumElems; ++ui)
    {
        CRMuralInfo muralInfo;

        rc = SSMR3GetMem(pSSM, &key, sizeof(key));
        AssertRCReturn(rc, rc);
        rc = SSMR3GetMem(pSSM, &muralInfo, sizeof(muralInfo));
        AssertRCReturn(rc, rc);

        if (muralInfo.pVisibleRects)
        {
            muralInfo.pVisibleRects = crAlloc(4*sizeof(GLint)*muralInfo.cVisibleRects);
            if (!muralInfo.pVisibleRects)
            {
                return VERR_NO_MEMORY;
            }

            rc = SSMR3GetMem(pSSM, muralInfo.pVisibleRects, 4*sizeof(GLint)*muralInfo.cVisibleRects);
            AssertRCReturn(rc, rc);
        }

        /* Restore windows geometry info */
        crServerDispatchWindowSize(key, muralInfo.width, muralInfo.height);
        crServerDispatchWindowPosition(key, muralInfo.gX, muralInfo.gY);
        /* Same workaround as described in stub.c:stubUpdateWindowVisibileRegions for compiz on a freshly booted VM*/
        if (muralInfo.bReceivedRects)
        {
            crServerDispatchWindowVisibleRegion(key, muralInfo.cVisibleRects, muralInfo.pVisibleRects);
        }
        crServerDispatchWindowShow(key, muralInfo.bVisible);

        if (muralInfo.pVisibleRects)
        {
            crFree(muralInfo.pVisibleRects);
        }
    }

    /* Load starting free context and window IDs */
    rc = SSMR3GetMem(pSSM, &cr_server.idsPool, sizeof(cr_server.idsPool));
    CRASSERT(rc == VINF_SUCCESS);

    /* Load 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];
            CRClient client;
            unsigned long ctxID=-1, winID=-1;

            rc = SSMR3GetU32(pSSM, &ui);
            AssertRCReturn(rc, rc);
            /* If this assert fires, then we should search correct client in the list first*/
            CRASSERT(ui == pClient->conn->u32ClientID);

            if (version>=4)
            {
                rc = SSMR3GetU32(pSSM, &pClient->conn->vMajor);
                AssertRCReturn(rc, rc);

                rc = SSMR3GetU32(pSSM, &pClient->conn->vMinor);
                AssertRCReturn(rc, rc);
            }

            rc = SSMR3GetMem(pSSM, &client, sizeof(client));
            CRASSERT(rc == VINF_SUCCESS);

            client.conn = pClient->conn;
            /* We can't reassign client number, as we'd get wrong results in TranslateTextureID
             * and fail to bind old textures.
             */
            /*client.number = pClient->number;*/
            *pClient = client;

            pClient->currentContextNumber = -1;
            pClient->currentCtx = cr_server.DummyContext;
            pClient->currentMural = NULL;
            pClient->currentWindow = -1;

            cr_server.curClient = pClient;

            if (client.currentCtx && client.currentContextNumber>=0)
            {
                rc = SSMR3GetMem(pSSM, &ctxID, sizeof(ctxID));
                AssertRCReturn(rc, rc);
                client.currentCtx = (CRContext*) crHashtableSearch(cr_server.contextTable, ctxID);
                CRASSERT(client.currentCtx);
                //pClient->currentCtx = client.currentCtx;
                //pClient->currentContextNumber = ctxID;
            }

            if (client.currentMural && client.currentWindow>=0)
            {
                rc = SSMR3GetMem(pSSM, &winID, sizeof(winID));
                AssertRCReturn(rc, rc);
                client.currentMural = (CRMuralInfo*) crHashtableSearch(cr_server.muralTable, winID);
                CRASSERT(client.currentMural);
                //pClient->currentMural = client.currentMural;
                //pClient->currentWindow = winID;
            }

            /* Restore client active context and window */
            crServerDispatchMakeCurrent(winID, 0, ctxID);

            if (0)
            {
            CRContext *tmpCtx;
            CRCreateInfo_t *createInfo;
            GLfloat one[4] = { 1, 1, 1, 1 };
            GLfloat amb[4] = { 0.4f, 0.4f, 0.4f, 1.0f };

            crServerDispatchMakeCurrent(winID, 0, ctxID);

            crHashtableWalk(client.currentCtx->shared->textureTable, crVBoxServerSyncTextureCB, client.currentCtx);

            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base1D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base2D, GL_TRUE);
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.base3D, GL_TRUE);
#ifdef CR_ARB_texture_cube_map
            crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseCubeMap, GL_TRUE);
#endif
#ifdef CR_NV_texture_rectangle
            //@todo this doesn't work as expected
            //crStateTextureObjectDiff(client.currentCtx, NULL, NULL, &client.currentCtx->texture.baseRect, GL_TRUE);
#endif
            /*cr_server.head_spu->dispatch_table.Materialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.LightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);
            cr_server.head_spu->dispatch_table.Lightfv(GL_LIGHT1, GL_DIFFUSE, one);

            cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT0);
            cr_server.head_spu->dispatch_table.Enable(GL_LIGHT1);

            cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
            cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);*/

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

            //crStateLoadIdentity();
            //cr_server.head_spu->dispatch_table.LoadIdentity();

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

                /*createInfo = (CRCreateInfo_t *) crHashtableSearch(cr_server.pContextCreateInfoTable, ctxID);
                CRASSERT(createInfo);
                tmpCtx = crStateCreateContext(NULL, createInfo->visualBits, NULL);
                CRASSERT(tmpCtx);
                crStateDiffContext(tmpCtx, client.currentCtx);
                crStateDestroyContext(tmpCtx);*/
            }
        }
    }

    //crServerDispatchMakeCurrent(-1, 0, -1);

    cr_server.curClient = NULL;

    {
        GLenum err = crServerDispatchGetError();

        if (err != GL_NO_ERROR)
        {
            crWarning("crServer: glGetError %d after loading snapshot", err);
        }
    }

    cr_server.bIsInLoadingState = GL_FALSE;

    return VINF_SUCCESS;
}