int VBoxDispVHWADisable(PVBOXDISPDEV pDev) { int rc = VERR_GENERAL_FAILURE; VBOXVHWACMD* pCmd; if (!pDev->hgsmi.bSupported) return VERR_NOT_SUPPORTED; pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_DISABLE, 0); if (!pCmd) { WARN(("VBoxDispVHWACommandCreate failed")); return rc; } if(VBoxDispVHWACommandSubmit (pDev, pCmd)) { if(RT_SUCCESS(pCmd->rc)) { rc = VINF_SUCCESS; } } VBoxDispVHWACommandRelease(pDev, pCmd); VBoxDispVHWACommandCheckHostCmds(pDev); return rc; }
DWORD APIENTRY VBoxDispDDGetBltStatus(PDD_GETBLTSTATUSDATA lpGetBltStatus) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpGetBltStatus->lpDD->dhpdev; PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpGetBltStatus->lpDDSurface->lpGbl->dwReserved1; LOGF_ENTER(); if(lpGetBltStatus->dwFlags == DDGBS_CANBLT) { lpGetBltStatus->ddRVal = DD_OK; } else /* DDGBS_ISBLTDONE */ { if (pDesc) { if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst)) { lpGetBltStatus->ddRVal = DDERR_WASSTILLDRAWING; } else { lpGetBltStatus->ddRVal = DD_OK; } } else { lpGetBltStatus->ddRVal = DD_OK; } } else { WARN(("!pDesc")); lpGetBltStatus->ddRVal = DDERR_GENERIC; } } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
DWORD APIENTRY VBoxDispDDGetFlipStatus(PDD_GETFLIPSTATUSDATA lpGetFlipStatus) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpGetFlipStatus->lpDD->dhpdev; PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpGetFlipStatus->lpDDSurface->lpGbl->dwReserved1; LOGF_ENTER(); /*can't flip is there's a flip pending, so result is same for DDGFS_CANFLIP/DDGFS_ISFLIPDONE */ if (pDesc) { if(ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr)) { lpGetFlipStatus->ddRVal = DDERR_WASSTILLDRAWING; } else { lpGetFlipStatus->ddRVal = DD_OK; } } else { lpGetFlipStatus->ddRVal = DD_OK; } } else { WARN(("!pDesc")); lpGetFlipStatus->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
VBOXVHWACMD* VBoxDispVHWACommandCreate(PVBOXDISPDEV pDev, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd) { VBOXVHWACMD* pHdr = (VBOXVHWACMD*)VBoxHGSMIBufferAlloc(&pDev->hgsmi.ctx, cbCmd + VBOXVHWACMD_HEADSIZE(), HGSMI_CH_VBVA, VBVA_VHWA_CMD); if (!pHdr) { WARN(("HGSMIHeapAlloc failed")); } else { memset(pHdr, 0, sizeof(VBOXVHWACMD)); pHdr->iDisplay = pDev->iDevice; pHdr->rc = VERR_GENERAL_FAILURE; pHdr->enmCmd = enmCmd; pHdr->cRefs = 1; } /* @todo: temporary hack */ VBoxDispVHWACommandCheckHostCmds(pDev); return pHdr; }
/* Lock specified area of surface */ DWORD APIENTRY VBoxDispDDLock(PDD_LOCKDATA lpLock) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpLock->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL* pSurf = lpLock->lpDDSurface; lpLock->ddRVal = DD_OK; #if 0 #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC) pSurf->lpGbl->dwReserved1; RECTL tmpRect, *pRect; if (!pDesc) { WARN(("!pDesc, memory overwrite somewhere?")); lpLock->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } /* Check if host is still processing drawing commands */ if (ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)) { lpLock->ddRVal = DDERR_WASSTILLDRAWING; return DDHAL_DRIVER_HANDLED; } } if (lpLock->bHasRect) { pRect = &lpLock->rArea; } else { tmpRect.left = 0; tmpRect.top = 0; tmpRect.right = pSurf->lpGbl->wWidth-1; tmpRect.bottom = pSurf->lpGbl->wHeight-1; pRect = &tmpRect; } if (lpLock->dwFlags & DDLOCK_DISCARDCONTENTS) { VBoxDispVHWARegionTrySubstitute(&pDesc->NonupdatedMemRegion, pRect); VBoxDispVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect); } else if (!VBoxDispVHWARegionIntersects(&pDesc->NonupdatedMemRegion, pRect)) { VBoxDispVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect); } else { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK)); if (pCmd) { VBOXVHWACMD_SURF_LOCK *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK)); pBody->u.in.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSurf->lpGbl->fpVidMem); VBoxDispVHWAFromRECTL(&pBody->u.in.rect, &pDesc->NonupdatedMemRegion.Rect); pBody->u.in.rectValid = 1; pBody->u.in.hSurf = pDesc->hHostHandle; /* wait for the surface to be locked and memory buffer updated */ VBoxDispVHWACommandSubmit(pDev, pCmd); VBOX_WARNRC(pCmd->rc); VBoxDispVHWACommandRelease(pDev, pCmd); VBoxDispVHWARegionClear(&pDesc->NonupdatedMemRegion); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpLock->ddRVal = DDERR_GENERIC; } } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ #endif /* We only care about primary surface as we'd have to report dirty rectangles to the host in the DDUnlock*/ if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pDev->ddpsLock.bLocked = TRUE; if (lpLock->bHasRect) { pDev->ddpsLock.rect = lpLock->rArea; } else { pDev->ddpsLock.rect.left = 0; pDev->ddpsLock.rect.top = 0; pDev->ddpsLock.rect.right = pDev->mode.ulWidth; pDev->ddpsLock.rect.bottom = pDev->mode.ulHeight; } } LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
DWORD APIENTRY VBoxDispDDFlip(PDD_FLIPDATA lpFlip) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpFlip->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pCurrSurf = lpFlip->lpSurfCurr; DD_SURFACE_LOCAL *pTargSurf = lpFlip->lpSurfTarg; PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC) pCurrSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC) pTargSurf->lpGbl->dwReserved1; if (pCurrDesc && pTargDesc) { if(ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr)) { lpFlip->ddRVal = DDERR_WASSTILLDRAWING; return DDHAL_DRIVER_HANDLED; } } VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP)); if (pCmd) { VBOXVHWACMD_SURF_FLIP *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP)); pBody->u.in.offCurrSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pCurrSurf->lpGbl->fpVidMem); pBody->u.in.offTargSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pTargSurf->lpGbl->fpVidMem); pBody->u.in.hTargSurf = pTargDesc->hHostHandle; pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle; pBody->TargGuestSurfInfo = (uint64_t)pTargDesc; pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc; pTargDesc->bVisible = pCurrDesc->bVisible; pCurrDesc->bVisible = false; ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr); ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg); #ifdef DEBUG ASMAtomicIncU32(&pCurrDesc->cFlipsCurr); ASMAtomicIncU32(&pTargDesc->cFlipsTarg); #endif if(pTargDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedTargMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pTargDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynch(pDev, pCmd, VBoxDispVHWASurfFlipCompletion, NULL); lpFlip->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpFlip->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pCurrDesc && pTargDesc)")); lpFlip->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }