BOOL vboxVbvaBufferBeginUpdate (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva) { BOOL bRc = FALSE; // DISPDBG((1, "VBoxDisp::vboxHwBufferBeginUpdate called flags = 0x%08X\n", // ppdev->pVBVA? ppdev->pVBVA->u32HostEvents: -1)); if ( pVbva->pVBVA && (pVbva->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED)) { uint32_t indexRecordNext; Assert (!pVbva->fHwBufferOverflow); Assert (pVbva->pRecord == NULL); indexRecordNext = (pVbva->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS; if (indexRecordNext == pVbva->pVBVA->indexRecordFirst) { /* All slots in the records queue are used. */ vboxHwBufferFlush (pDevExt, pVbva); } if (indexRecordNext == pVbva->pVBVA->indexRecordFirst) { // /* Even after flush there is no place. Fail the request. */ // LOG(("no space in the queue of records!!! first %d, last %d", // ppdev->pVBVA->indexRecordFirst, ppdev->pVBVA->indexRecordFree)); } else { /* Initialize the record. */ VBVARECORD *pRecord = &pVbva->pVBVA->aRecords[pVbva->pVBVA->indexRecordFree]; pRecord->cbRecord = VBVA_F_RECORD_PARTIAL; pVbva->pVBVA->indexRecordFree = indexRecordNext; // LOG(("indexRecordNext = %d\n", indexRecordNext)); /* Remember which record we are using. */ pVbva->pRecord = pRecord; bRc = TRUE; } } return bRc; }
RTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx) { bool bRc = false; // LogFunc(("flags = 0x%08X\n", pCtx->pVBVA? pCtx->pVBVA->u32HostEvents: -1)); if ( pCtx->pVBVA && (pCtx->pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED)) { uint32_t indexRecordNext; Assert(!pCtx->fHwBufferOverflow); Assert(pCtx->pRecord == NULL); indexRecordNext = (pCtx->pVBVA->indexRecordFree + 1) % VBVA_MAX_RECORDS; if (indexRecordNext == pCtx->pVBVA->indexRecordFirst) { /* All slots in the records queue are used. */ vboxHwBufferFlush (pHGSMICtx); } if (indexRecordNext == pCtx->pVBVA->indexRecordFirst) { /* Even after flush there is no place. Fail the request. */ LogFunc(("no space in the queue of records!!! first %d, last %d\n", pCtx->pVBVA->indexRecordFirst, pCtx->pVBVA->indexRecordFree)); } else { /* Initialize the record. */ VBVARECORD *pRecord = &pCtx->pVBVA->aRecords[pCtx->pVBVA->indexRecordFree]; pRecord->cbRecord = VBVA_F_RECORD_PARTIAL; pCtx->pVBVA->indexRecordFree = indexRecordNext; // LogFunc(("indexRecordNext = %d\n", indexRecordNext)); /* Remember which record we are using. */ pCtx->pRecord = pRecord; bRc = true; } } return bRc; }
static int vboxHwBufferWrite (PVBOXMP_DEVEXT pDevExt, VBOXVBVAINFO *pVbva, const void *p, uint32_t cb) { VBVARECORD *pRecord; uint32_t cbHwBufferAvail; uint32_t cbWritten = 0; VBVABUFFER *pVBVA = pVbva->pVBVA; Assert(pVBVA); if (!pVBVA || pVbva->fHwBufferOverflow) { return VERR_INVALID_STATE; } Assert (pVBVA->indexRecordFirst != pVBVA->indexRecordFree); pRecord = pVbva->pRecord; Assert (pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)); // LOGF(("VW %d", cb)); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); while (cb > 0) { uint32_t cbChunk = cb; // LOG(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n", // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten)); if (cbChunk >= cbHwBufferAvail) { LOG(("1) avail %d, chunk %d", cbHwBufferAvail, cbChunk)); vboxHwBufferFlush (pDevExt, pVbva); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); if (cbChunk >= cbHwBufferAvail) { LOG(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.", cb, cbHwBufferAvail)); if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold) { LOGREL(("Buffer overflow!!!")); pVbva->fHwBufferOverflow = TRUE; Assert(FALSE); return VERR_NO_MEMORY; } cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold; } } Assert(cbChunk <= cb); Assert(cbChunk <= vboxHwBufferAvail (pVBVA)); vboxHwBufferPlaceDataAt (pVbva->pVBVA, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free); pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData; pRecord->cbRecord += cbChunk; cbHwBufferAvail -= cbChunk; cb -= cbChunk; cbWritten += cbChunk; } return VINF_SUCCESS; }
static bool vboxHwBufferWrite(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, const void *p, uint32_t cb) { VBVARECORD *pRecord; uint32_t cbHwBufferAvail; uint32_t cbWritten = 0; VBVABUFFER *pVBVA = pCtx->pVBVA; Assert(pVBVA); if (!pVBVA || pCtx->fHwBufferOverflow) { return false; } Assert(pVBVA->indexRecordFirst != pVBVA->indexRecordFree); pRecord = pCtx->pRecord; Assert(pRecord && (pRecord->cbRecord & VBVA_F_RECORD_PARTIAL)); // LogFunc(("%d\n", cb)); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); while (cb > 0) { uint32_t cbChunk = cb; // LogFunc(("pVBVA->off32Free %d, pRecord->cbRecord 0x%08X, cbHwBufferAvail %d, cb %d, cbWritten %d\n", // pVBVA->off32Free, pRecord->cbRecord, cbHwBufferAvail, cb, cbWritten)); if (cbChunk >= cbHwBufferAvail) { LogFunc(("1) avail %d, chunk %d\n", cbHwBufferAvail, cbChunk)); vboxHwBufferFlush (pHGSMICtx); cbHwBufferAvail = vboxHwBufferAvail (pVBVA); if (cbChunk >= cbHwBufferAvail) { LogFunc(("no place for %d bytes. Only %d bytes available after flush. Going to partial writes.\n", cb, cbHwBufferAvail)); if (cbHwBufferAvail <= pVBVA->cbPartialWriteThreshold) { LogFunc(("Buffer overflow!!!\n")); pCtx->fHwBufferOverflow = true; Assert(false); return false; } cbChunk = cbHwBufferAvail - pVBVA->cbPartialWriteThreshold; } } Assert(cbChunk <= cb); Assert(cbChunk <= vboxHwBufferAvail (pVBVA)); vboxHwBufferPlaceDataAt (pCtx, (uint8_t *)p + cbWritten, cbChunk, pVBVA->off32Free); pVBVA->off32Free = (pVBVA->off32Free + cbChunk) % pVBVA->cbData; pRecord->cbRecord += cbChunk; cbHwBufferAvail -= cbChunk; cb -= cbChunk; cbWritten += cbChunk; } return true; }