/** * Callback function called by the X server to tell us about dirty * rectangles in the video buffer. * * @param pScreen pointer to the information structure for the current * screen * @param iRects Number of dirty rectangles to update * @param aRects Array of structures containing the coordinates of the * rectangles */ static void vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects) { VBVACMDHDR cmdHdr; VBOXPtr pVBox; int i; unsigned j; pVBox = pScrn->driverPrivate; if (pVBox->fHaveHGSMI == FALSE || !pScrn->vtSema) return; for (j = 0; j < pVBox->cScreens; ++j) { /* Just continue quietly if VBVA is not currently active. */ struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA; if ( !pVBVA || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED)) continue; for (i = 0; i < iRects; ++i) { if ( aRects[i].x1 > pVBox->aScreenLocation[j].x + pVBox->aScreenLocation[j].cx || aRects[i].y1 > pVBox->aScreenLocation[j].y + pVBox->aScreenLocation[j].cy || aRects[i].x2 < pVBox->aScreenLocation[j].x || aRects[i].y2 < pVBox->aScreenLocation[j].y) continue; cmdHdr.x = (int16_t)aRects[i].x1; cmdHdr.y = (int16_t)aRects[i].y1; cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1); cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1); #if 0 TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n", j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h); #endif if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j], &pVBox->guestCtx)) { VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr, sizeof(cmdHdr)); VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]); } } } }
/* Unlock previously locked surface */ DWORD APIENTRY VBoxDispDDUnlock(PDD_UNLOCKDATA lpUnlock) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpUnlock->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSurf = lpUnlock->lpDDSurface; lpUnlock->ddRVal = DD_OK; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC) pSurf->lpGbl->dwReserved1; if (!pDesc) { WARN(("!pDesc, memory overwrite somewhere?")); lpUnlock->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } if((pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && pDesc->UpdatedMemRegion.bValid && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->hgsmi.ctx)) { vbvaReportDirtyRect(pDev, &pDesc->UpdatedMemRegion.Rect); if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET) { vrdpReset(pDev); pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &= ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; } if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_VRDP) { vrdpReportDirtyRect(pDev, &pDesc->UpdatedMemRegion.Rect); } VBoxVBVABufferEndUpdate(&pDev->vbvaCtx); } else if ((pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE) || ((pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && pDesc->bVisible)) { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK)); if(pCmd) { VBOXVHWACMD_SURF_UNLOCK *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK)); pBody->u.in.hSurf = pDesc->hHostHandle; if(pDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedMemRect, &pDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpUnlock->ddRVal = DDERR_GENERIC; } } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ if (pDev->ddpsLock.bLocked) { pDev->ddpsLock.bLocked = FALSE; if (pDev->hgsmi.bSupported && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->hgsmi.ctx)) { vbvaReportDirtyRect(pDev, &pDev->ddpsLock.rect); if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET) { vrdpReset(pDev); pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &= ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; } if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_VRDP) { vrdpReportDirtyRect(pDev, &pDev->ddpsLock.rect); } VBoxVBVABufferEndUpdate(&pDev->vbvaCtx); } } LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }