コード例 #1
0
ファイル: DisplayImplLegacy.cpp プロジェクト: miguelinux/vbox
int Display::i_videoAccelFlush(PPDMIDISPLAYPORT pUpPort)
{
    VIDEOACCEL *pVideoAccel = &mVideoAccelLegacy;
    VBVAMEMORY *pVbvaMemory = pVideoAccel->pVbvaMemory;

#ifdef DEBUG_sunlover_2
    LogFlowFunc(("fVideoAccelEnabled = %d\n", pVideoAccel->fVideoAccelEnabled));
#endif /* DEBUG_sunlover_2 */

    if (!pVideoAccel->fVideoAccelEnabled)
    {
        Log(("Display::VideoAccelFlush: called with disabled VBVA!!! Ignoring.\n"));
        return VINF_SUCCESS;
    }

    /* Here VBVA is enabled and we have the accelerator memory pointer. */
    Assert(pVbvaMemory);

#ifdef DEBUG_sunlover_2
    LogFlowFunc(("indexRecordFirst = %d, indexRecordFree = %d, off32Data = %d, off32Free = %d\n",
                  pVbvaMemory->indexRecordFirst, pVbvaMemory->indexRecordFree,
                  pVbvaMemory->off32Data, pVbvaMemory->off32Free));
#endif /* DEBUG_sunlover_2 */

    /* Quick check for "nothing to update" case. */
    if (pVbvaMemory->indexRecordFirst == pVbvaMemory->indexRecordFree)
    {
        return VINF_SUCCESS;
    }

    /* Process the ring buffer */
    unsigned uScreenId;

    /* Initialize dirty rectangles accumulator. */
    VBVADIRTYREGION rgn;
    vbvaRgnInit(&rgn, maFramebuffers, mcMonitors, this, pUpPort);

    for (;;)
    {
        VBVACMDHDR *phdr = NULL;
        uint32_t cbCmd = ~0;

        /* Fetch the command data. */
        if (!i_vbvaFetchCmd(pVideoAccel, &phdr, &cbCmd))
        {
            Log(("Display::VideoAccelFlush: unable to fetch command. off32Data = %d, off32Free = %d. Disabling VBVA!!!\n",
                  pVbvaMemory->off32Data, pVbvaMemory->off32Free));
            return VERR_INVALID_STATE;
        }

        if (cbCmd == uint32_t(~0))
        {
            /* No more commands yet in the queue. */
#ifdef DEBUG_sunlover
            LogFlowFunc(("no command\n"));
#endif /* DEBUG_sunlover */
            break;
        }

        if (cbCmd != 0)
        {
#ifdef DEBUG_sunlover
            LogFlowFunc(("hdr: cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n",
                         cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
#endif /* DEBUG_sunlover */

            VBVACMDHDR hdrSaved = *phdr;

            int x = phdr->x;
            int y = phdr->y;
            int w = phdr->w;
            int h = phdr->h;

            uScreenId = mapCoordsToScreen(maFramebuffers, mcMonitors, &x, &y, &w, &h);

            phdr->x = (int16_t)x;
            phdr->y = (int16_t)y;
            phdr->w = (uint16_t)w;
            phdr->h = (uint16_t)h;

            /* Handle the command.
             *
             * Guest is responsible for updating the guest video memory.
             * The Windows guest does all drawing using Eng*.
             *
             * For local output, only dirty rectangle information is used
             * to update changed areas.
             *
             * Dirty rectangles are accumulated to exclude overlapping updates and
             * group small updates to a larger one.
             */

            /* Accumulate the update. */
            vbvaRgnDirtyRect(&rgn, uScreenId, phdr);

            /* Forward the command to VRDP server. */
            mParent->i_consoleVRDPServer()->SendUpdate(uScreenId, phdr, cbCmd);

            *phdr = hdrSaved;
        }

        i_vbvaReleaseCmd(pVideoAccel, phdr, cbCmd);
    }

    for (uScreenId = 0; uScreenId < mcMonitors; uScreenId++)
    {
        /* Draw the framebuffer. */
        vbvaRgnUpdateFramebuffer(&rgn, uScreenId);
    }
    return VINF_SUCCESS;
}
コード例 #2
0
/**
 * Called regularly on the DisplayRefresh timer.
 * Also on behalf of guest, when the ring buffer is full.
 *
 * @thread EMT
 */
void Display::VideoAccelFlush (void)
{
#ifdef DEBUG_sunlover
    LogFlow(("Display::VideoAccelFlush: mfVideoAccelEnabled = %d\n", mfVideoAccelEnabled));
#endif /* DEBUG_sunlover */

    if (!mfVideoAccelEnabled)
    {
        Log(("Display::VideoAccelFlush: called with disabled VBVA!!! Ignoring.\n"));
        return;
    }

    /* Here VBVA is enabled and we have the accelerator memory pointer. */
    Assert(mpVbvaMemory);

#ifdef DEBUG_sunlover
    LogFlow(("Display::VideoAccelFlush: indexRecordFirst = %d, indexRecordFree = %d, off32Data = %d, off32Free = %d\n",
              mpVbvaMemory->indexRecordFirst, mpVbvaMemory->indexRecordFree, mpVbvaMemory->off32Data, mpVbvaMemory->off32Free));
#endif /* DEBUG_sunlover */

    /* Quick check for "nothing to update" case. */
    if (mpVbvaMemory->indexRecordFirst == mpVbvaMemory->indexRecordFree)
        return;

    /* Process the ring buffer */

    bool fFramebufferIsNull = (mFramebuffer == NULL);

    if (!fFramebufferIsNull)
        mFramebuffer->Lock();

    /* Initialize dirty rectangles accumulator. */
    VBVADIRTYREGION rgn;
    vbvaRgnInit (&rgn, mFramebuffer, this, mpDrv->pUpPort);

    for (;;)
    {
        VBVACMDHDR *phdr = NULL;
        uint32_t cbCmd = 0;

        /* Fetch the command data. */
        if (!vbvaFetchCmd (&phdr, &cbCmd))
        {
            Log(("Display::VideoAccelFlush: unable to fetch command. off32Data = %d, off32Free = %d. Disabling VBVA!!!\n",
                  mpVbvaMemory->off32Data, mpVbvaMemory->off32Free));

            /* Disable VBVA on those processing errors. */
            VideoAccelEnable (false, NULL);

            break;
        }

        if (!cbCmd)
        {
            /* No more commands yet in the queue. */
            break;
        }

        if (!fFramebufferIsNull)
        {
#ifdef DEBUG_sunlover
            LogFlow(("MAIN::DisplayImpl::VideoAccelFlush: hdr: cbCmd = %d, x=%d, y=%d, w=%d, h=%d\n", cbCmd, phdr->x, phdr->y, phdr->w, phdr->h));
#endif /* DEBUG_sunlover */

            /* Handle the command.
             *
             * Guest is responsible for updating the guest video memory.
             * The Windows guest does all drawing using Eng*.
             *
             * For local output, only dirty rectangle information is used
             * to update changed areas.
             *
             * Dirty rectangles are accumulated to exclude overlapping updates and
             * group small updates to a larger one.
             */

            /* Accumulate the update. */
            vbvaRgnDirtyRect (&rgn, phdr);

//            /* Forward the command to VRDP server. */
//            mParent->consoleVRDPServer()->SendUpdate (phdr, cbCmd);
        }

        vbvaReleaseCmd (phdr, cbCmd);
    }

    if (!fFramebufferIsNull)
        mFramebuffer->Unlock ();

    /* Draw the framebuffer. */
    vbvaRgnUpdateFramebuffer (&rgn);
}