VirtualBox

Changeset 52652 in vbox


Ignore:
Timestamp:
Sep 9, 2014 8:12:31 AM (10 years ago)
Author:
vboxsync
Message:

DisplayImpl: fixes for legacy VBVA locking and restoring saved state.

Location:
trunk/src/VBox/Main
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r52574 r52652  
    164164    bool i_VideoAccelAllowed(void);
    165165    void i_VideoAccelVRDP(bool fEnable);
     166
     167    /* Legacy video acceleration requests coming from the VGA refresh timer. */
     168    int  VideoAccelEnableVGA(bool fEnable, VBVAMEMORY *pVbvaMemory);
     169
     170    /* Legacy video acceleration requests coming from VMMDev. */
     171    int  VideoAccelEnableVMMDev(bool fEnable, VBVAMEMORY *pVbvaMemory);
     172    void VideoAccelFlushVMMDev(void);
    166173
    167174    int  i_VideoCaptureStart();
     
    375382    void i_handleResizeCompletedEMT(unsigned uScreenId, BOOL fResizeContext);
    376383
    377     /* Old guest additions (3.x?) use VMMDev for VBVA and the host VBVA code (VideoAccel*)
    378      * can be executed concurrently by VGA refresh timer and the guest VMMDev request
    379      * in SMP VMs. The lock serialized this.
     384    /* Old guest additions (3.x and older) use both VMMDev and DevVGA refresh timer
     385     * to process the VBVABUFFER memory. Therefore the legacy VBVA (VideoAccel) host
     386     * code can be executed concurrently by VGA refresh timer and the guest VMMDev
     387     * request in SMP VMs. The semaphore serialized this.
    380388     */
    381     RTCRITSECT mVBVALock;
    382     volatile uint32_t mfu32PendingVideoAccelDisable;
    383 
    384     int  i_vbvaLock(void);
    385     void i_vbvaUnlock(void);
     389    RTSEMXROADS mhXRoadsVideoAccel;
     390    int videoAccelEnterVGA(void);
     391    void videoAccelLeaveVGA(void);
     392    int videoAccelEnterVMMDev(void);
     393    void videoAccelLeaveVMMDev(void);
     394
     395    /* Serializes access to mpVbvaMemory, etc between VRDP and Display. */
     396    RTCRITSECT mVideoAccelLock;
    386397
    387398public:
    388 
    389     bool i_vbvaLockIsOwner(void);
    390399
    391400    static int i_displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppu8Data, size_t *pcbData,
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r52574 r52652  
    123123    mfVMMDevInited = false;
    124124
    125     int rc = RTCritSectInit(&mVBVALock);
     125    int rc = RTCritSectInit(&mVideoAccelLock);
    126126    AssertRC(rc);
    127127
    128     mfu32PendingVideoAccelDisable = false;
     128    mhXRoadsVideoAccel = NIL_RTSEMXROADS;
     129    rc = RTSemXRoadsCreate(&mhXRoadsVideoAccel);
     130    AssertRC(rc);
    129131
    130132#ifdef VBOX_WITH_HGSMI
     
    160162    uninit();
    161163
    162     if (RTCritSectIsInitialized (&mVBVALock))
    163     {
    164         RTCritSectDelete (&mVBVALock);
    165         RT_ZERO(mVBVALock);
     164    RTSemXRoadsDestroy(mhXRoadsVideoAccel);
     165
     166    if (RTCritSectIsInitialized(&mVideoAccelLock))
     167    {
     168        RTCritSectDelete(&mVideoAccelLock);
     169        RT_ZERO(mVideoAccelLock);
    166170    }
    167171
     
    398402
    399403                /* This can be called from any thread. */
    400                 Assert(!that->i_vbvaLockIsOwner());
    401404                that->mpDrv->pUpPort->pfnFreeScreenshot(that->mpDrv->pUpPort, pu8Data);
    402405            }
     
    876879    if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    877880    {
    878         Assert(!i_vbvaLockIsOwner());
    879881        mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, false);
    880882
     
    15211523}
    15221524
    1523 int Display::i_vbvaLock(void)
    1524 {
    1525     return RTCritSectEnter(&mVBVALock);
    1526 }
    1527 
    1528 void Display::i_vbvaUnlock(void)
    1529 {
    1530     RTCritSectLeave(&mVBVALock);
    1531 }
    1532 
    1533 bool Display::i_vbvaLockIsOwner(void)
    1534 {
    1535     return RTCritSectIsOwner(&mVBVALock);
     1525int Display::videoAccelEnterVGA(void)
     1526{
     1527    return RTSemXRoadsNSEnter(mhXRoadsVideoAccel);
     1528}
     1529
     1530void Display::videoAccelLeaveVGA(void)
     1531{
     1532    RTSemXRoadsNSLeave(mhXRoadsVideoAccel);
     1533}
     1534
     1535int Display::videoAccelEnterVMMDev(void)
     1536{
     1537    return RTSemXRoadsEWEnter(mhXRoadsVideoAccel);
     1538}
     1539
     1540void Display::videoAccelLeaveVMMDev(void)
     1541{
     1542    RTSemXRoadsEWLeave(mhXRoadsVideoAccel);
     1543}
     1544
     1545int Display::VideoAccelEnableVMMDev(bool fEnable, VBVAMEMORY *pVbvaMemory)
     1546{
     1547    LogFlowFunc(("%d %p\n", fEnable, pVbvaMemory));
     1548    int rc = videoAccelEnterVMMDev();
     1549    if (RT_SUCCESS(rc))
     1550    {
     1551        rc = i_VideoAccelEnable(fEnable, pVbvaMemory);
     1552        videoAccelLeaveVMMDev();
     1553    }
     1554    LogFlowFunc(("leave %Rrc\n", rc));
     1555    return rc;
     1556}
     1557
     1558int Display::VideoAccelEnableVGA(bool fEnable, VBVAMEMORY *pVbvaMemory)
     1559{
     1560    LogFlowFunc(("%d %p\n", fEnable, pVbvaMemory));
     1561    int rc = videoAccelEnterVGA();
     1562    if (RT_SUCCESS(rc))
     1563    {
     1564        rc = i_VideoAccelEnable(fEnable, pVbvaMemory);
     1565        videoAccelLeaveVGA();
     1566    }
     1567    LogFlowFunc(("leave %Rrc\n", rc));
     1568    return rc;
     1569}
     1570
     1571void Display::VideoAccelFlushVMMDev(void)
     1572{
     1573    LogFlowFunc(("enter\n"));
     1574    int rc = videoAccelEnterVMMDev();
     1575    if (RT_SUCCESS(rc))
     1576    {
     1577        i_VideoAccelFlush();
     1578        videoAccelLeaveVMMDev();
     1579    }
     1580    LogFlowFunc(("leave\n"));
    15361581}
    15371582
     
    15421587{
    15431588    int rc;
    1544     if (fEnable)
    1545     {
    1546         /* Process any pending VGA device changes, resize. */
    1547         Assert(!i_vbvaLockIsOwner());
    1548         mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false);
    1549     }
    1550 
    1551     i_vbvaLock();
     1589    LogRelFlowFunc(("fEnable = %d\n", fEnable));
     1590
    15521591    rc = i_videoAccelEnable(fEnable, pVbvaMemory);
    1553     i_vbvaUnlock();
    1554 
    1555     if (!fEnable)
    1556     {
    1557         Assert(!i_vbvaLockIsOwner());
    1558         mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false);
    1559     }
    1560 
     1592
     1593    LogRelFlowFunc(("%Rrc.\n", rc));
    15611594    return rc;
    15621595}
     
    15641597int Display::i_videoAccelEnable(bool fEnable, VBVAMEMORY *pVbvaMemory)
    15651598{
    1566     Assert(i_vbvaLockIsOwner());
    1567 
    15681599    int rc = VINF_SUCCESS;
    15691600    /* Called each time the guest wants to use acceleration,
     
    16181649        mpVbvaMemory->fu32ModeFlags &= ~VBVA_F_MODE_ENABLED;
    16191650
    1620     /* Safety precaution. There is no more VBVA until everything is setup! */
    1621     mpVbvaMemory = NULL;
    1622     mfVideoAccelEnabled = false;
    1623 
    1624     /* Everything OK. VBVA status can be changed. */
     1651    if (fEnable)
     1652    {
     1653        /* Process any pending VGA device changes, resize. */
     1654        mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false);
     1655    }
     1656
     1657    /* Protect the videoaccel state transition. */
     1658    RTCritSectEnter(&mVideoAccelLock);
     1659
     1660    if (fEnable)
     1661    {
     1662        mpVbvaMemory = pVbvaMemory;
     1663        mfVideoAccelEnabled = true;
     1664
     1665        /* Initialize the hardware memory. */
     1666        i_vbvaSetMemoryFlags(mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP,
     1667                             mfu32SupportedOrders, maFramebuffers, mcMonitors);
     1668        mpVbvaMemory->off32Data = 0;
     1669        mpVbvaMemory->off32Free = 0;
     1670
     1671        memset(mpVbvaMemory->aRecords, 0, sizeof(mpVbvaMemory->aRecords));
     1672        mpVbvaMemory->indexRecordFirst = 0;
     1673        mpVbvaMemory->indexRecordFree = 0;
     1674
     1675        LogRel(("VBVA: Enabled.\n"));
     1676    }
     1677    else
     1678    {
     1679        mpVbvaMemory = NULL;
     1680        mfVideoAccelEnabled = false;
     1681
     1682        LogRel(("VBVA: Disabled.\n"));
     1683    }
     1684
     1685    RTCritSectLeave(&mVideoAccelLock);
     1686
     1687    if (!fEnable)
     1688    {
     1689        mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false);
     1690    }
    16251691
    16261692    /* Notify the VMMDev, which saves VBVA status in the saved state,
     
    16351701    }
    16361702
    1637     if (fEnable)
    1638     {
    1639         mpVbvaMemory = pVbvaMemory;
    1640         mfVideoAccelEnabled = true;
    1641 
    1642         /* Initialize the hardware memory. */
    1643         i_vbvaSetMemoryFlags(mpVbvaMemory, mfVideoAccelEnabled, mfVideoAccelVRDP,
    1644                              mfu32SupportedOrders, maFramebuffers, mcMonitors);
    1645         mpVbvaMemory->off32Data = 0;
    1646         mpVbvaMemory->off32Free = 0;
    1647 
    1648         memset(mpVbvaMemory->aRecords, 0, sizeof(mpVbvaMemory->aRecords));
    1649         mpVbvaMemory->indexRecordFirst = 0;
    1650         mpVbvaMemory->indexRecordFree = 0;
    1651 
    1652         mfu32PendingVideoAccelDisable = false;
    1653 
    1654         LogRel(("VBVA: Enabled.\n"));
    1655     }
    1656     else
    1657     {
    1658         LogRel(("VBVA: Disabled.\n"));
    1659     }
    1660 
    1661     LogRelFlowFunc(("VideoAccelEnable: rc = %Rrc.\n", rc));
    1662 
     1703    LogRelFlowFunc(("%Rrc.\n", rc));
    16631704    return rc;
    16641705}
     
    16701711    LogRelFlowFunc(("fEnable = %d\n", fEnable));
    16711712
    1672     i_vbvaLock();
    1673 
    16741713    int c = fEnable?
    16751714                ASMAtomicIncS32(&mcVideoAccelVRDPRefs):
     
    16771716
    16781717    Assert (c >= 0);
     1718
     1719    /* This can run concurrently with Display videoaccel state change. */
     1720    RTCritSectEnter(&mVideoAccelLock);
    16791721
    16801722    if (c == 0)
     
    17241766        Assert(mfVideoAccelVRDP == true);
    17251767    }
    1726     i_vbvaUnlock();
     1768
     1769    RTCritSectLeave(&mVideoAccelLock);
    17271770}
    17281771
     
    20002043void Display::i_VideoAccelFlush(void)
    20012044{
    2002     i_vbvaLock();
    20032045    int rc = i_videoAccelFlush();
    20042046    if (RT_FAILURE(rc))
     
    20072049        i_videoAccelEnable(false, NULL);
    20082050    }
    2009     i_vbvaUnlock();
    20102051
    20112052    if (RT_FAILURE(rc))
    20122053    {
    20132054        /* VideoAccel was disabled because of a failure, switching back to VGA updates. Redraw the screen. */
    2014         Assert(!i_vbvaLockIsOwner());
    20152055        mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false);
    20162056    }
     
    20192059int Display::i_videoAccelFlush(void)
    20202060{
    2021     Assert(i_vbvaLockIsOwner());
    2022 
    20232061#ifdef DEBUG_sunlover_2
    20242062    LogFlowFunc(("mfVideoAccelEnabled = %d\n", mfVideoAccelEnabled));
     
    21312169    int rc = VWRN_INVALID_STATE; /* Default is to do a display update in VGA device. */
    21322170
    2133     i_vbvaLock();
    2134 
    2135     if (ASMAtomicCmpXchgU32(&mfu32PendingVideoAccelDisable, false, true))
    2136     {
    2137         i_videoAccelEnable(false, NULL);
    2138     }
    2139     else if (mfPendingVideoAccelEnable)
     2171    videoAccelEnterVGA();
     2172
     2173    if (mfPendingVideoAccelEnable)
    21402174    {
    21412175        /* Acceleration was enabled while machine was not yet running
     
    21812215    }
    21822216
    2183     i_vbvaUnlock();
     2217    videoAccelLeaveVGA();
    21842218
    21852219    return rc;
     
    22382272            alock.release();
    22392273
    2240             Assert(!i_vbvaLockIsOwner());
    22412274            int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &u32BitsPerPixel);
    22422275            AssertRC(rc);
     
    24242457
    24252458        uint32_t cBits = 0;
    2426         Assert(!i_vbvaLockIsOwner());
    24272459        int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &cBits);
    24282460        AssertRC(rc);
     
    25692601        && pDisplay->maFramebuffers[aScreenId].fVBVAEnabled == false) /* A non-VBVA mode. */
    25702602    {
    2571         Assert(!pDisplay->i_vbvaLockIsOwner());
    25722603        rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort, ppu8Data, pcbData, pu32Width, pu32Height);
    25732604    }
     
    26092640                uint32_t u32DstBitsPerPixel = 32;
    26102641
    2611                 Assert(!pDisplay->i_vbvaLockIsOwner());
    26122642                rc = pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
    26132643                                                           width, height,
     
    26352665                        && aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    26362666                    {
    2637                         Assert(!pDisplay->i_vbvaLockIsOwner());
    26382667                        rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort,
    26392668                                                                         ppu8Data, pcbData, pu32Width, pu32Height);
     
    27212750        {
    27222751            /* This can be called from any thread. */
    2723             Assert(!pDisplay->i_vbvaLockIsOwner());
    27242752            pDrv->pUpPort->pfnFreeScreenshot(pDrv->pUpPort, pu8Data);
    27252753        }
     
    30343062    if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    30353063    {
    3036         Assert(!pDisplay->i_vbvaLockIsOwner());
    30373064        rc = pDisplay->mpDrv->pUpPort->pfnDisplayBlt(pDisplay->mpDrv->pUpPort, address, x, y, width, height);
    30383065    }
     
    30563083        uint32_t u32DstBitsPerPixel = pFBInfo->u16BitsPerPixel;
    30573084
    3058         Assert(!pDisplay->i_vbvaLockIsOwner());
    30593085        rc = pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
    30603086                                                   width, height,
     
    31093135                        u32DstBitsPerPixel = 32;
    31103136
    3111                         Assert(!pDisplay->i_vbvaLockIsOwner());
    31123137                        pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
    31133138                                                              width, height,
     
    32063231            && uScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
    32073232        {
    3208             Assert(!pDisplay->i_vbvaLockIsOwner());
    32093233            pDisplay->mpDrv->pUpPort->pfnUpdateDisplayAll(pDisplay->mpDrv->pUpPort, /* fFailOnResize = */ true);
    32103234        }
     
    32593283                        if (ulWidth == pFBInfo->w && ulHeight == pFBInfo->h)
    32603284                        {
    3261                             Assert(!pDisplay->i_vbvaLockIsOwner());
    32623285                            pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
    32633286                                                                  width, height,
     
    34673490        if (fSetRenderVRAM)
    34683491        {
    3469             Assert(!i_vbvaLockIsOwner());
    34703492            mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, true);
    34713493        }
     
    36963718            /* No VBVA do a display update. */
    36973719            DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN];
    3698             Assert(!pDisplay->i_vbvaLockIsOwner());
    36993720            pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort);
    37003721        }
     
    38173838
    38183839   /* Disable VBVA mode. */
    3819     pDrv->pDisplay->i_VideoAccelEnable(false, NULL);
     3840    pDrv->pDisplay->VideoAccelEnableVGA(false, NULL);
    38203841}
    38213842
     
    38343855
    38353856    /* Disable VBVA mode in any case. The guest driver reenables VBVA mode if necessary. */
    3836     /* The LFBModeChange function is called under DevVGA lock. Postpone disabling VBVA, do it in the refresh timer. */
    3837     ASMAtomicWriteU32(&pDrv->pDisplay->mfu32PendingVideoAccelDisable, true);
     3857    pDrv->pDisplay->VideoAccelEnableVGA(false, NULL);
    38383858}
    38393859
     
    44934513    {
    44944514        /* Force full screen update, because VGA device must take control, do resize, etc. */
    4495         Assert(!pThis->i_vbvaLockIsOwner());
    44964515        pThis->mpDrv->pUpPort->pfnUpdateDisplayAll(pThis->mpDrv->pUpPort, /* fFailOnResize = */ false);
    44974516    }
     
    45294548            && !pFBInfo->fDisabled)
    45304549        {
    4531             Assert(!pThis->i_vbvaLockIsOwner());
    45324550            pDrv->pUpPort->pfnUpdateDisplayRect(pDrv->pUpPort, pCmd->x, pCmd->y, pCmd->w, pCmd->h);
    45334551        }
     
    45704588                uint32_t u32DstBitsPerPixel = 32;
    45714589
    4572                 Assert(!pThis->i_vbvaLockIsOwner());
    45734590                pDrv->pUpPort->pfnCopyRect(pDrv->pUpPort,
    45744591                                           width, height,
     
    48554872    LogRelFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
    48564873
    4857     if (pThis->pDisplay)
    4858         Assert(!pThis->pDisplay->i_vbvaLockIsOwner());
    4859 
    48604874    pThis->pUpPort->pfnSetRenderVRAM(pThis->pUpPort, false);
    48614875
     
    49654979
    49664980    /* Disable VRAM to a buffer copy initially. */
    4967     Assert(!pDisplay->i_vbvaLockIsOwner());
    49684981    pThis->pUpPort->pfnSetRenderVRAM(pThis->pUpPort, false);
    49694982    pThis->IConnector.cBits = 32; /* DevVGA does nothing otherwise. */
     
    49724985     * Start periodic screen refreshes
    49734986     */
    4974     Assert(!pDisplay->i_vbvaLockIsOwner());
    49754987    pThis->pUpPort->pfnSetRefreshRate(pThis->pUpPort, 20);
    49764988
  • trunk/src/VBox/Main/src-client/VMMDevInterface.cpp

    r52082 r52652  
    369369    {
    370370        LogSunlover(("MAIN::VMMDevInterface::iface_VideoAccelEnable: %d, %p\n", fEnable, pVbvaMemory));
    371         return display->i_VideoAccelEnable(fEnable, pVbvaMemory);
     371        return display->VideoAccelEnableVMMDev(fEnable, pVbvaMemory);
    372372    }
    373373
     
    384384    {
    385385        LogSunlover(("MAIN::VMMDevInterface::iface_VideoAccelFlush\n"));
    386         display->i_VideoAccelFlush();
     386        display->VideoAccelFlushVMMDev();
    387387    }
    388388}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette