Changeset 24373 in vbox for trunk/src/VBox/Main/DisplayImpl.cpp
- Timestamp:
- Nov 5, 2009 9:51:34 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/DisplayImpl.cpp
r24301 r24373 41 41 # include <VBox/VBoxVideo.h> 42 42 #endif 43 44 #include <VBox/com/array.h> 45 43 46 /** 44 47 * Display driver instance data. … … 1533 1536 } 1534 1537 1538 static int displayTakeScreenshot(PVM pVM, struct DRVMAINDISPLAY *pDrv, BYTE *address, ULONG width, ULONG height) 1539 { 1540 uint8_t *pu8Data = NULL; 1541 size_t cbData = 0; 1542 uint32_t cx = 0; 1543 uint32_t cy = 0; 1544 1545 /* @todo pfnTakeScreenshot is probably callable from any thread, because it uses the VGA device lock. */ 1546 int vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)pDrv->pUpPort->pfnTakeScreenshot, 5, 1547 pDrv->pUpPort, &pu8Data, &cbData, &cx, &cy); 1548 1549 if (RT_SUCCESS(vrc)) 1550 { 1551 if (cx == width && cy == height) 1552 { 1553 /* No scaling required. */ 1554 memcpy(address, pu8Data, cbData); 1555 } 1556 else 1557 { 1558 /* Scale. */ 1559 LogFlowFunc(("SCALE: %dx%d -> %dx%d\n", cx, cy, width, height)); 1560 1561 uint8_t *dst = address; 1562 uint8_t *src = pu8Data; 1563 int dstX = 0; 1564 int dstY = 0; 1565 int srcX = 0; 1566 int srcY = 0; 1567 int dstW = width; 1568 int dstH = height; 1569 int srcW = cx; 1570 int srcH = cy; 1571 gdImageCopyResampled (dst, 1572 src, 1573 dstX, dstY, 1574 srcX, srcY, 1575 dstW, dstH, srcW, srcH); 1576 } 1577 1578 /* This can be called from any thread. */ 1579 pDrv->pUpPort->pfnFreeScreenshot (pDrv->pUpPort, pu8Data); 1580 } 1581 1582 return vrc; 1583 } 1584 1535 1585 STDMETHODIMP Display::TakeScreenShot (BYTE *address, ULONG width, ULONG height) 1536 1586 { … … 1563 1613 LogFlowFunc (("Sending SCREENSHOT request\n")); 1564 1614 1565 /* 1566 * First try use the graphics device features for making a snapshot. 1567 * This does not support stretching, is an optional feature (returns 1568 * not supported). 1615 /* Leave lock because other thread (EMT) is called and it may initiate a resize 1616 * which also needs lock. 1569 1617 * 1570 * Note: It may cause a display resize. Watch out for deadlocks.1618 * This method does not need the lock anymore. 1571 1619 */ 1572 int rcVBox = VERR_NOT_SUPPORTED; 1573 if ( mpDrv->Connector.cx == width 1574 && mpDrv->Connector.cy == height) 1575 { 1576 size_t cbData = RT_ALIGN_Z(width, 4) * 4 * height; 1577 rcVBox = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)mpDrv->pUpPort->pfnSnapshot, 6, mpDrv->pUpPort, 1578 address, cbData, (uintptr_t)NULL, (uintptr_t)NULL, (uintptr_t)NULL); 1579 } 1580 1581 /* 1582 * If the function returns not supported, or if stretching is requested, 1583 * we'll have to do all the work ourselves using the framebuffer data. 1584 */ 1585 if (rcVBox == VERR_NOT_SUPPORTED || rcVBox == VERR_NOT_IMPLEMENTED) 1586 { 1587 /** @todo implement snapshot stretching & generic snapshot fallback. */ 1588 rc = setError (E_NOTIMPL, tr ("This feature is not implemented")); 1589 } 1590 else if (RT_FAILURE(rcVBox)) 1620 alock.leave(); 1621 1622 int vrc = displayTakeScreenshot(pVM, mpDrv, address, width, height); 1623 1624 if (vrc == VERR_NOT_IMPLEMENTED) 1625 rc = setError (E_NOTIMPL, 1626 tr ("This feature is not implemented")); 1627 else if (RT_FAILURE(vrc)) 1591 1628 rc = setError (VBOX_E_IPRT_ERROR, 1592 tr ("Could not take a screenshot (%Rrc)"), rcVBox);1629 tr ("Could not take a screenshot (%Rrc)"), vrc); 1593 1630 1594 1631 LogFlowFunc (("rc=%08X\n", rc)); … … 1600 1637 ComSafeArrayOut(BYTE, aScreenData)) 1601 1638 { 1602 HRESULT rc = S_OK; 1603 1604 rc = setError (E_NOTIMPL, tr ("This feature is not implemented")); 1605 1606 return rc; 1639 LogFlowFuncEnter(); 1640 LogFlowFunc (("width=%d, height=%d\n", 1641 width, height)); 1642 1643 CheckComArgSafeArrayNotNull(aScreenData); 1644 CheckComArgExpr(width, width != 0); 1645 CheckComArgExpr(height, height != 0); 1646 1647 AutoCaller autoCaller(this); 1648 CheckComRCReturnRC(autoCaller.rc()); 1649 1650 AutoWriteLock alock(this); 1651 1652 CHECK_CONSOLE_DRV (mpDrv); 1653 1654 Console::SafeVMPtr pVM (mParent); 1655 CheckComRCReturnRC(pVM.rc()); 1656 1657 HRESULT rc = S_OK; 1658 1659 LogFlowFunc (("Sending SCREENSHOT request\n")); 1660 1661 /* Leave lock because other thread (EMT) is called and it may initiate a resize 1662 * which also needs lock. 1663 * 1664 * This method does not need the lock anymore. 1665 */ 1666 alock.leave(); 1667 1668 size_t cbData = width * 4 * height; 1669 uint8_t *pu8Data = (uint8_t *)RTMemAlloc(cbData); 1670 1671 if (!pu8Data) 1672 return E_OUTOFMEMORY; 1673 1674 int vrc = displayTakeScreenshot(pVM, mpDrv, pu8Data, width, height); 1675 1676 if (RT_SUCCESS(vrc)) 1677 { 1678 com::SafeArray<BYTE> screenData (cbData); 1679 for (unsigned i = 0; i < cbData; i++) 1680 screenData[i] = pu8Data[i]; 1681 screenData.detachTo(ComSafeArrayOutArg(aScreenData)); 1682 } 1683 else if (vrc == VERR_NOT_IMPLEMENTED) 1684 rc = setError (E_NOTIMPL, 1685 tr ("This feature is not implemented")); 1686 else 1687 rc = setError (VBOX_E_IPRT_ERROR, 1688 tr ("Could not take a screenshot (%Rrc)"), vrc); 1689 1690 LogFlowFunc (("rc=%08X\n", rc)); 1691 LogFlowFuncLeave(); 1692 return rc; 1607 1693 } 1608 1694
Note:
See TracChangeset
for help on using the changeset viewer.