DWORD APIENTRY VBoxDispDDSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpSetOverlayPosition->lpDD->dhpdev; DD_SURFACE_LOCAL *pSrcSurf = lpSetOverlayPosition->lpDDSrcSurface; DD_SURFACE_LOCAL *pDstSurf = lpSetOverlayPosition->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; LOGF_ENTER(); if (pSrcDesc && pDstDesc) { if (!pSrcDesc->bVisible) { WARN(("!pSrcDesc->bVisible")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); if (pCmd) { VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; pBody->u.in.hDstSurf = pDstDesc->hHostHandle; pBody->u.in.xPos = lpSetOverlayPosition->lXPos; pBody->u.in.yPos = lpSetOverlayPosition->lYPos; VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); lpSetOverlayPosition->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pSrcDesc && pDstDesc)")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
DWORD APIENTRY VBoxDispDDSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpSetColorKey->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSurf = lpSetColorKey->lpDDSurface; PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)pSurf->lpGbl->dwReserved1; VBOXVHWACMD* pCmd; lpSetColorKey->ddRVal = DD_OK; if (pDesc) { pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET)); if (pCmd) { VBOXVHWACMD_SURF_COLORKEY_SET *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET)); pBody->u.in.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSurf->lpGbl->fpVidMem); pBody->u.in.hSurf = pDesc->hHostHandle; pBody->u.in.flags = VBoxDispVHWAFromDDCKEYs(lpSetColorKey->dwFlags); VBoxDispVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew); VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpSetColorKey->ddRVal = DDERR_GENERIC; } } else { WARN(("!pDesc")); lpSetColorKey->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
/* 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; }
/* Called to create DirectDraw surface. * Note: we always return DDHAL_DRIVER_NOTHANDLED, which asks DirectDraw memory manager * to perform actual memory allocation in our DDraw heap. */ DWORD APIENTRY VBoxDispDDCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpCreateSurface->lpDD->dhpdev; LOGF_ENTER(); PDD_SURFACE_LOCAL pSurf = lpCreateSurface->lplpSList[0]; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { LOG(("primary surface")); pSurf->lpGbl->fpVidMem = 0; } else { LOG(("non primary surface")); pSurf->lpGbl->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE; } pSurf->lpGbl->dwReserved1 = 0; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE)); if (pCmd) { VBOXVHWACMD_SURF_CREATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE); PVBOXVHWASURFDESC pDesc; int rc; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE)); rc = VBoxDispVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpCreateSurface->lpDDSurfaceDesc); VBOX_WARNRC(rc); pBody->SurfInfo.surfCaps = VBoxDispVHWAFromDDSCAPS(pSurf->ddsCaps.dwCaps); pBody->SurfInfo.flags |= DDSD_CAPS; pBody->SurfInfo.height = pSurf->lpGbl->wHeight; pBody->SurfInfo.width = pSurf->lpGbl->wWidth; pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH; VBoxDispVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, &pSurf->lpGbl->ddpfSurface); pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pBody->SurfInfo.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, 0); } else { pBody->SurfInfo.offSurface = VBOXVHWA_OFFSET64_VOID; } pDesc = VBoxDispVHWASurfDescAlloc(); if (pDesc) { VBoxDispVHWACommandSubmit(pDev, pCmd); if (RT_SUCCESS(pCmd->rc)) { uint32_t surfSizeX = pBody->SurfInfo.sizeX; uint32_t surfSizeY = pBody->SurfInfo.sizeY; pDesc->hHostHandle = pBody->SurfInfo.hSurf; if(!!(pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && !!(pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE)) { pDesc->bVisible = true; } pSurf->lpGbl->dwBlockSizeX = pBody->SurfInfo.sizeX; pSurf->lpGbl->dwBlockSizeY = pBody->SurfInfo.sizeY; pSurf->lpGbl->lPitch = pBody->SurfInfo.pitch; lpCreateSurface->lpDDSurfaceDesc->lPitch = pSurf->lpGbl->lPitch; lpCreateSurface->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; /*@todo: it's probably a memory leak, because DDDestroySurface wouldn't be called for * primary surfaces. */ pSurf->lpGbl->dwReserved1 = (ULONG_PTR)pDesc; } else { WARN(("VBoxDispVHWACommandSubmit failed with rc=%#x", rc)); VBoxDispVHWASurfDescFree(pDesc); } } else { WARN(("VBoxDispVHWASurfDescAlloc failed")); } VBoxDispVHWACommandRelease(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed")); } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ LPDDSURFACEDESC pDesc = lpCreateSurface->lpDDSurfaceDesc; if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth/2, 32, LONG); } else if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth, 32, LONG); } else { pSurf->lpGbl->lPitch = pSurf->lpGbl->wWidth*(pDesc->ddpfPixelFormat.dwRGBBitCount/8); } pSurf->lpGbl->dwBlockSizeX = pSurf->lpGbl->lPitch; pSurf->lpGbl->dwBlockSizeY = pSurf->lpGbl->wHeight; pDesc->lPitch = pSurf->lpGbl->lPitch; pDesc->dwFlags |= DDSD_PITCH; LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
DWORD APIENTRY VBoxDispDDUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpUpdateOverlay->lpDD->dhpdev; DD_SURFACE_LOCAL* pSrcSurf = lpUpdateOverlay->lpDDSrcSurface; DD_SURFACE_LOCAL* pDstSurf = lpUpdateOverlay->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; LOGF_ENTER(); if (pSrcDesc) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE)); if (pCmd) { VBOXVHWACMD_SURF_OVERLAY_UPDATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest); VBoxDispVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc); pBody->u.in.flags = VBoxDispVHWAFromDDOVERs(lpUpdateOverlay->dwFlags); VBoxDispVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX); if (lpUpdateOverlay->dwFlags & DDOVER_HIDE) { pSrcDesc->bVisible = false; } else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW) { pSrcDesc->bVisible = true; if(pSrcDesc->UpdatedMemRegion.bValid) { pBody->u.in.xFlags = VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pSrcDesc->UpdatedMemRegion); } } if(pDstSurf) { PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; if (!pDstDesc) { WARN(("!pDstDesc")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } pBody->u.in.hDstSurf = pDstDesc->hHostHandle; pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); } VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); lpUpdateOverlay->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; } } else { WARN(("!pSrcDesc")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
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; }
DWORD APIENTRY VBoxDispDDBlt(PDD_BLTDATA lpBlt) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpBlt->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSrcSurf = lpBlt->lpDDSrcSurface; DD_SURFACE_LOCAL *pDstSurf = lpBlt->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; if (pSrcDesc && pDstDesc) { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT)); if (pCmd) { VBOXVHWACMD_SURF_BLT *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); pBody->u.in.hDstSurf = pDstDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc); pBody->DstGuestSurfInfo = (uint64_t)pDstDesc; pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc; pBody->u.in.flags = VBoxDispVHWAFromDDBLTs(lpBlt->dwFlags); VBoxDispVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX); ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc); ASMAtomicIncU32(&pDstDesc->cPendingBltsDst); VBoxDispVHWARegionAdd(&pDstDesc->NonupdatedMemRegion, &lpBlt->rDest); VBoxDispVHWARegionTrySubstitute(&pDstDesc->UpdatedMemRegion, &lpBlt->rDest); if(pSrcDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedSrcMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pSrcDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynch(pDev, pCmd, VBoxDispVHWASurfBltCompletion, NULL); lpBlt->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpBlt->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pSrcDesc && pDstDesc)")); lpBlt->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }