Changeset 52652 in vbox
- Timestamp:
- Sep 9, 2014 8:12:31 AM (10 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
-
include/DisplayImpl.h (modified) (2 diffs)
-
src-client/DisplayImpl.cpp (modified) (38 diffs)
-
src-client/VMMDevInterface.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/DisplayImpl.h
r52574 r52652 164 164 bool i_VideoAccelAllowed(void); 165 165 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); 166 173 167 174 int i_VideoCaptureStart(); … … 375 382 void i_handleResizeCompletedEMT(unsigned uScreenId, BOOL fResizeContext); 376 383 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. 380 388 */ 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; 386 397 387 398 public: 388 389 bool i_vbvaLockIsOwner(void);390 399 391 400 static int i_displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppu8Data, size_t *pcbData, -
trunk/src/VBox/Main/src-client/DisplayImpl.cpp
r52574 r52652 123 123 mfVMMDevInited = false; 124 124 125 int rc = RTCritSectInit(&mV BVALock);125 int rc = RTCritSectInit(&mVideoAccelLock); 126 126 AssertRC(rc); 127 127 128 mfu32PendingVideoAccelDisable = false; 128 mhXRoadsVideoAccel = NIL_RTSEMXROADS; 129 rc = RTSemXRoadsCreate(&mhXRoadsVideoAccel); 130 AssertRC(rc); 129 131 130 132 #ifdef VBOX_WITH_HGSMI … … 160 162 uninit(); 161 163 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); 166 170 } 167 171 … … 398 402 399 403 /* This can be called from any thread. */ 400 Assert(!that->i_vbvaLockIsOwner());401 404 that->mpDrv->pUpPort->pfnFreeScreenshot(that->mpDrv->pUpPort, pu8Data); 402 405 } … … 876 879 if (uScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 877 880 { 878 Assert(!i_vbvaLockIsOwner());879 881 mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, false); 880 882 … … 1521 1523 } 1522 1524 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); 1525 int Display::videoAccelEnterVGA(void) 1526 { 1527 return RTSemXRoadsNSEnter(mhXRoadsVideoAccel); 1528 } 1529 1530 void Display::videoAccelLeaveVGA(void) 1531 { 1532 RTSemXRoadsNSLeave(mhXRoadsVideoAccel); 1533 } 1534 1535 int Display::videoAccelEnterVMMDev(void) 1536 { 1537 return RTSemXRoadsEWEnter(mhXRoadsVideoAccel); 1538 } 1539 1540 void Display::videoAccelLeaveVMMDev(void) 1541 { 1542 RTSemXRoadsEWLeave(mhXRoadsVideoAccel); 1543 } 1544 1545 int 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 1558 int 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 1571 void 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")); 1536 1581 } 1537 1582 … … 1542 1587 { 1543 1588 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 1552 1591 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)); 1561 1594 return rc; 1562 1595 } … … 1564 1597 int Display::i_videoAccelEnable(bool fEnable, VBVAMEMORY *pVbvaMemory) 1565 1598 { 1566 Assert(i_vbvaLockIsOwner());1567 1568 1599 int rc = VINF_SUCCESS; 1569 1600 /* Called each time the guest wants to use acceleration, … … 1618 1649 mpVbvaMemory->fu32ModeFlags &= ~VBVA_F_MODE_ENABLED; 1619 1650 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 } 1625 1691 1626 1692 /* Notify the VMMDev, which saves VBVA status in the saved state, … … 1635 1701 } 1636 1702 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)); 1663 1704 return rc; 1664 1705 } … … 1670 1711 LogRelFlowFunc(("fEnable = %d\n", fEnable)); 1671 1712 1672 i_vbvaLock();1673 1674 1713 int c = fEnable? 1675 1714 ASMAtomicIncS32(&mcVideoAccelVRDPRefs): … … 1677 1716 1678 1717 Assert (c >= 0); 1718 1719 /* This can run concurrently with Display videoaccel state change. */ 1720 RTCritSectEnter(&mVideoAccelLock); 1679 1721 1680 1722 if (c == 0) … … 1724 1766 Assert(mfVideoAccelVRDP == true); 1725 1767 } 1726 i_vbvaUnlock(); 1768 1769 RTCritSectLeave(&mVideoAccelLock); 1727 1770 } 1728 1771 … … 2000 2043 void Display::i_VideoAccelFlush(void) 2001 2044 { 2002 i_vbvaLock();2003 2045 int rc = i_videoAccelFlush(); 2004 2046 if (RT_FAILURE(rc)) … … 2007 2049 i_videoAccelEnable(false, NULL); 2008 2050 } 2009 i_vbvaUnlock();2010 2051 2011 2052 if (RT_FAILURE(rc)) 2012 2053 { 2013 2054 /* VideoAccel was disabled because of a failure, switching back to VGA updates. Redraw the screen. */ 2014 Assert(!i_vbvaLockIsOwner());2015 2055 mpDrv->pUpPort->pfnUpdateDisplayAll(mpDrv->pUpPort, /* fFailOnResize = */ false); 2016 2056 } … … 2019 2059 int Display::i_videoAccelFlush(void) 2020 2060 { 2021 Assert(i_vbvaLockIsOwner());2022 2023 2061 #ifdef DEBUG_sunlover_2 2024 2062 LogFlowFunc(("mfVideoAccelEnabled = %d\n", mfVideoAccelEnabled)); … … 2131 2169 int rc = VWRN_INVALID_STATE; /* Default is to do a display update in VGA device. */ 2132 2170 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) 2140 2174 { 2141 2175 /* Acceleration was enabled while machine was not yet running … … 2181 2215 } 2182 2216 2183 i_vbvaUnlock();2217 videoAccelLeaveVGA(); 2184 2218 2185 2219 return rc; … … 2238 2272 alock.release(); 2239 2273 2240 Assert(!i_vbvaLockIsOwner());2241 2274 int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &u32BitsPerPixel); 2242 2275 AssertRC(rc); … … 2424 2457 2425 2458 uint32_t cBits = 0; 2426 Assert(!i_vbvaLockIsOwner());2427 2459 int rc = mpDrv->pUpPort->pfnQueryColorDepth(mpDrv->pUpPort, &cBits); 2428 2460 AssertRC(rc); … … 2569 2601 && pDisplay->maFramebuffers[aScreenId].fVBVAEnabled == false) /* A non-VBVA mode. */ 2570 2602 { 2571 Assert(!pDisplay->i_vbvaLockIsOwner());2572 2603 rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort, ppu8Data, pcbData, pu32Width, pu32Height); 2573 2604 } … … 2609 2640 uint32_t u32DstBitsPerPixel = 32; 2610 2641 2611 Assert(!pDisplay->i_vbvaLockIsOwner());2612 2642 rc = pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort, 2613 2643 width, height, … … 2635 2665 && aScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 2636 2666 { 2637 Assert(!pDisplay->i_vbvaLockIsOwner());2638 2667 rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort, 2639 2668 ppu8Data, pcbData, pu32Width, pu32Height); … … 2721 2750 { 2722 2751 /* This can be called from any thread. */ 2723 Assert(!pDisplay->i_vbvaLockIsOwner());2724 2752 pDrv->pUpPort->pfnFreeScreenshot(pDrv->pUpPort, pu8Data); 2725 2753 } … … 3034 3062 if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 3035 3063 { 3036 Assert(!pDisplay->i_vbvaLockIsOwner());3037 3064 rc = pDisplay->mpDrv->pUpPort->pfnDisplayBlt(pDisplay->mpDrv->pUpPort, address, x, y, width, height); 3038 3065 } … … 3056 3083 uint32_t u32DstBitsPerPixel = pFBInfo->u16BitsPerPixel; 3057 3084 3058 Assert(!pDisplay->i_vbvaLockIsOwner());3059 3085 rc = pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort, 3060 3086 width, height, … … 3109 3135 u32DstBitsPerPixel = 32; 3110 3136 3111 Assert(!pDisplay->i_vbvaLockIsOwner());3112 3137 pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort, 3113 3138 width, height, … … 3206 3231 && uScreenId == VBOX_VIDEO_PRIMARY_SCREEN) 3207 3232 { 3208 Assert(!pDisplay->i_vbvaLockIsOwner());3209 3233 pDisplay->mpDrv->pUpPort->pfnUpdateDisplayAll(pDisplay->mpDrv->pUpPort, /* fFailOnResize = */ true); 3210 3234 } … … 3259 3283 if (ulWidth == pFBInfo->w && ulHeight == pFBInfo->h) 3260 3284 { 3261 Assert(!pDisplay->i_vbvaLockIsOwner());3262 3285 pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort, 3263 3286 width, height, … … 3467 3490 if (fSetRenderVRAM) 3468 3491 { 3469 Assert(!i_vbvaLockIsOwner());3470 3492 mpDrv->pUpPort->pfnSetRenderVRAM(mpDrv->pUpPort, true); 3471 3493 } … … 3696 3718 /* No VBVA do a display update. */ 3697 3719 DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[VBOX_VIDEO_PRIMARY_SCREEN]; 3698 Assert(!pDisplay->i_vbvaLockIsOwner());3699 3720 pDrv->pUpPort->pfnUpdateDisplay(pDrv->pUpPort); 3700 3721 } … … 3817 3838 3818 3839 /* Disable VBVA mode. */ 3819 pDrv->pDisplay-> i_VideoAccelEnable(false, NULL);3840 pDrv->pDisplay->VideoAccelEnableVGA(false, NULL); 3820 3841 } 3821 3842 … … 3834 3855 3835 3856 /* 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); 3838 3858 } 3839 3859 … … 4493 4513 { 4494 4514 /* Force full screen update, because VGA device must take control, do resize, etc. */ 4495 Assert(!pThis->i_vbvaLockIsOwner());4496 4515 pThis->mpDrv->pUpPort->pfnUpdateDisplayAll(pThis->mpDrv->pUpPort, /* fFailOnResize = */ false); 4497 4516 } … … 4529 4548 && !pFBInfo->fDisabled) 4530 4549 { 4531 Assert(!pThis->i_vbvaLockIsOwner());4532 4550 pDrv->pUpPort->pfnUpdateDisplayRect(pDrv->pUpPort, pCmd->x, pCmd->y, pCmd->w, pCmd->h); 4533 4551 } … … 4570 4588 uint32_t u32DstBitsPerPixel = 32; 4571 4589 4572 Assert(!pThis->i_vbvaLockIsOwner());4573 4590 pDrv->pUpPort->pfnCopyRect(pDrv->pUpPort, 4574 4591 width, height, … … 4855 4872 LogRelFlowFunc(("iInstance=%d\n", pDrvIns->iInstance)); 4856 4873 4857 if (pThis->pDisplay)4858 Assert(!pThis->pDisplay->i_vbvaLockIsOwner());4859 4860 4874 pThis->pUpPort->pfnSetRenderVRAM(pThis->pUpPort, false); 4861 4875 … … 4965 4979 4966 4980 /* Disable VRAM to a buffer copy initially. */ 4967 Assert(!pDisplay->i_vbvaLockIsOwner());4968 4981 pThis->pUpPort->pfnSetRenderVRAM(pThis->pUpPort, false); 4969 4982 pThis->IConnector.cBits = 32; /* DevVGA does nothing otherwise. */ … … 4972 4985 * Start periodic screen refreshes 4973 4986 */ 4974 Assert(!pDisplay->i_vbvaLockIsOwner());4975 4987 pThis->pUpPort->pfnSetRefreshRate(pThis->pUpPort, 20); 4976 4988 -
trunk/src/VBox/Main/src-client/VMMDevInterface.cpp
r52082 r52652 369 369 { 370 370 LogSunlover(("MAIN::VMMDevInterface::iface_VideoAccelEnable: %d, %p\n", fEnable, pVbvaMemory)); 371 return display-> i_VideoAccelEnable(fEnable, pVbvaMemory);371 return display->VideoAccelEnableVMMDev(fEnable, pVbvaMemory); 372 372 } 373 373 … … 384 384 { 385 385 LogSunlover(("MAIN::VMMDevInterface::iface_VideoAccelFlush\n")); 386 display-> i_VideoAccelFlush();386 display->VideoAccelFlushVMMDev(); 387 387 } 388 388 }
Note:
See TracChangeset
for help on using the changeset viewer.

