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