diff options
Diffstat (limited to 'src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp')
-rw-r--r-- | src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp | 106 |
1 files changed, 93 insertions, 13 deletions
diff --git a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp index 84fe7b2c..c0d2c0b8 100644 --- a/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp +++ b/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp @@ -8,7 +8,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -1039,19 +1039,12 @@ int HGSMIHostCommandProcessAndFreeAsynch (PHGSMIINSTANCE pIns, { LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem)); - VM_ASSERT_OTHER_THREAD(pIns->pVM); - #if 0 void *pvContext = NULL; #endif HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem); -// /* Have to forward to EMT because FIFO processing is there. */ -// int rc = VMR3ReqCallVoid (pIns->pVM, &pReq, RT_INDEFINITE_WAIT, -// (PFNRT) hgsmiHostCommandProcess, -// 3, pIns, offBuffer, &pvContext); - int rc = hgsmiHostCommandProcess (pIns, offBuffer, #if 0 hgsmiHostCommandFreeCallback, &pvContext, @@ -1192,6 +1185,32 @@ static int hgsmiHostSaveFifoLocked (HGSMILIST * pFifo, PSSMHANDLE pSSM) return rc; } +static int hgsmiHostSaveGuestCmdCompletedFifoEntryLocked (HGSMIGUESTCOMPLENTRY *pEntry, PSSMHANDLE pSSM) +{ + return SSMR3PutU32 (pSSM, pEntry->offBuffer); +} + +static int hgsmiHostSaveGuestCmdCompletedFifoLocked (HGSMILIST * pFifo, PSSMHANDLE pSSM) +{ + VBOXHGSMI_SAVE_FIFOSTART(pSSM); + uint32_t size = 0; + for(HGSMILISTENTRY * pEntry = pFifo->pHead; pEntry; pEntry = pEntry->pNext) + { + ++size; + } + int rc = SSMR3PutU32 (pSSM, size); + + for(HGSMILISTENTRY * pEntry = pFifo->pHead; pEntry && RT_SUCCESS(rc); pEntry = pEntry->pNext) + { + HGSMIGUESTCOMPLENTRY *pFifoEntry = HGSMILISTENTRY_2_HGSMIGUESTCOMPLENTRY(pEntry); + rc = hgsmiHostSaveGuestCmdCompletedFifoEntryLocked (pFifoEntry, pSSM); + } + + VBOXHGSMI_SAVE_FIFOSTOP(pSSM); + + return rc; +} + static int hgsmiHostLoadFifoEntryLocked (PHGSMIINSTANCE pIns, HGSMIHOSTFIFOENTRY **ppEntry, PSSMHANDLE pSSM) { HGSMIHOSTFIFOENTRY *pEntry; @@ -1234,13 +1253,65 @@ static int hgsmiHostLoadFifoLocked (PHGSMIINSTANCE pIns, HGSMILIST * pFifo, PSSM return rc; } +static int hgsmiHostLoadGuestCmdCompletedFifoEntryLocked (PHGSMIINSTANCE pIns, HGSMIGUESTCOMPLENTRY **ppEntry, PSSMHANDLE pSSM) +{ + HGSMIGUESTCOMPLENTRY *pEntry; + int rc = hgsmiGuestCompletionFIFOAlloc (pIns, &pEntry); AssertRC(rc); + if (RT_SUCCESS (rc)) + { + rc = SSMR3GetU32 (pSSM, &pEntry->offBuffer); AssertRC(rc); + if (RT_SUCCESS (rc)) + *ppEntry = pEntry; + else + hgsmiGuestCompletionFIFOFree (pIns, pEntry); + } + return rc; +} + +static int hgsmiHostLoadGuestCmdCompletedFifoLocked (PHGSMIINSTANCE pIns, HGSMILIST * pFifo, PSSMHANDLE pSSM, uint32_t u32Version) +{ + VBOXHGSMI_LOAD_FIFOSTART(pSSM); + + uint32_t size; + int rc = SSMR3GetU32 (pSSM, &size); AssertRC(rc); + if(RT_SUCCESS(rc) && size) + { + if (u32Version > VGA_SAVEDSTATE_VERSION_INV_GCMDFIFO) + { + for(uint32_t i = 0; i < size; ++i) + { + HGSMIGUESTCOMPLENTRY *pFifoEntry = NULL; /* initialized to shut up gcc */ + rc = hgsmiHostLoadGuestCmdCompletedFifoEntryLocked (pIns, &pFifoEntry, pSSM); + AssertRCBreak(rc); + hgsmiListAppend (pFifo, &pFifoEntry->entry); + } + } + else + { + LogRel(("WARNING: the current saved state version has some 3D support data missing, " + "which may lead to some guest applications function improperly")); + /* just read out all invalid data and discard it */ + for(uint32_t i = 0; i < size; ++i) + { + HGSMIHOSTFIFOENTRY *pFifoEntry = NULL; /* initialized to shut up gcc */ + rc = hgsmiHostLoadFifoEntryLocked (pIns, &pFifoEntry, pSSM); + AssertRCBreak(rc); + hgsmiHostFIFOFree (pIns, pFifoEntry); + } + } + } + + VBOXHGSMI_LOAD_FIFOSTOP(pSSM); + + return rc; +} + int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM) { VBOXHGSMI_SAVE_START(pSSM); int rc; - HGSMIOFFSET off = pIns->pHGFlags ? HGSMIPointerToOffset(&pIns->area, (const HGSMIBUFFERHEADER *)pIns->pHGFlags) : HGSMIOFFSET_VOID; SSMR3PutU32 (pSSM, off); @@ -1251,7 +1322,7 @@ int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM) SSMR3PutU32 (pSSM, HGSMIHeapOffset(&pIns->hostHeap)); SSMR3PutU32 (pSSM, HGSMIHeapSize(&pIns->hostHeap)); /* need save mem pointer to calculate offset on restore */ - SSMR3PutU64 (pSSM, (uint64_t)pIns->area.pu8Base); + SSMR3PutU64 (pSSM, (uint64_t)(uintptr_t)pIns->area.pu8Base); rc = hgsmiFIFOLock (pIns); if(RT_SUCCESS(rc)) { @@ -1259,7 +1330,7 @@ int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM) rc = hgsmiHostSaveFifoLocked (&pIns->hostFIFORead, pSSM); AssertRC(rc); rc = hgsmiHostSaveFifoLocked (&pIns->hostFIFOProcessed, pSSM); AssertRC(rc); #ifdef VBOX_WITH_WDDM - rc = hgsmiHostSaveFifoLocked (&pIns->guestCmdCompleted, pSSM); AssertRC(rc); + rc = hgsmiHostSaveGuestCmdCompletedFifoLocked (&pIns->guestCmdCompleted, pSSM); AssertRC(rc); #endif hgsmiFIFOUnlock (pIns); @@ -1326,7 +1397,7 @@ int HGSMIHostLoadStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM, uint32_t u32Ve rc = hgsmiHostLoadFifoLocked (pIns, &pIns->hostFIFOProcessed, pSSM); #ifdef VBOX_WITH_WDDM if (RT_SUCCESS(rc) && u32Version > VGA_SAVEDSTATE_VERSION_PRE_WDDM) - rc = hgsmiHostLoadFifoLocked (pIns, &pIns->hostFIFOProcessed, pSSM); + rc = hgsmiHostLoadGuestCmdCompletedFifoLocked (pIns, &pIns->guestCmdCompleted, pSSM, u32Version); #endif hgsmiFIFOUnlock (pIns); @@ -1729,6 +1800,12 @@ int hgsmiCompleteGuestCommand(PHGSMIINSTANCE pIns, /* Now guest can read the FIFO, the notification is informational. */ hgsmiNotifyGuest (pIns); } +#ifdef DEBUG_misha + else + { + Assert(0); + } +#endif } return rc; } @@ -1740,7 +1817,10 @@ int HGSMICompleteGuestCommand(PHGSMIINSTANCE pIns, LogFlowFunc(("pIns = %p, pvMem = %p\n", pIns, pvMem)); int rc = VINF_SUCCESS; - HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (&pIns->hostHeap, pvMem); + + HGSMIBUFFERHEADER *pHeader = HGSMIBufferHeaderFromData(pvMem); + HGSMIOFFSET offBuffer = HGSMIPointerToOffset(&pIns->area, pHeader); + Assert(offBuffer != HGSMIOFFSET_VOID); if (offBuffer != HGSMIOFFSET_VOID) { |