Example #1
0
/**
 * 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]);
            }
        }
    }
}
Example #2
0
/* 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;
}