VirtualBox

Ignore:
Timestamp:
Apr 13, 2010 12:25:12 PM (15 years ago)
Author:
vboxsync
Message:

IDisplay::TakeScreenshot for multimonitor. (xTracker 4655)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/DisplayImpl.cpp

    r28240 r28245  
    440440        /* SSM code is executed on EMT(0), therefore no need to use VMR3ReqCallWait. */
    441441#ifdef VBOX_WITH_OLD_VBVA_LOCK
    442         int rc = Display::displayTakeScreenshotEMT(that, &pu8Data, &cbData, &cx, &cy);
     442        int rc = Display::displayTakeScreenshotEMT(that, VBOX_VIDEO_PRIMARY_SCREEN, &pu8Data, &cbData, &cx, &cy);
    443443#else
    444444        int rc = that->mpDrv->pUpPort->pfnTakeScreenshot (that->mpDrv->pUpPort, &pu8Data, &cbData, &cx, &cy);
     
    21822182
    21832183#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2184 int Display::displayTakeScreenshotEMT(Display *pDisplay, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
    2185 {
    2186    int rc;
    2187    pDisplay->vbvaLock();
    2188    rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort, ppu8Data, pcbData, pu32Width, pu32Height);
    2189    pDisplay->vbvaUnlock();
    2190    return rc;
     2184int Display::displayTakeScreenshotEMT(Display *pDisplay, ULONG aScreenId, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pu32Width, uint32_t *pu32Height)
     2185{
     2186    int rc;
     2187    pDisplay->vbvaLock();
     2188    if (aScreenId == VBOX_VIDEO_PRIMARY_SCREEN)
     2189    {
     2190        rc = pDisplay->mpDrv->pUpPort->pfnTakeScreenshot(pDisplay->mpDrv->pUpPort, ppu8Data, pcbData, pu32Width, pu32Height);
     2191    }
     2192    else if (aScreenId < pDisplay->mcMonitors)
     2193    {
     2194        DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[aScreenId];
     2195
     2196        uint32_t width = pFBInfo->w;
     2197        uint32_t height = pFBInfo->h;
     2198
     2199        /* Allocate 32 bit per pixel bitmap. */
     2200        size_t cbRequired = width * 4 * height;
     2201
     2202        if (cbRequired)
     2203        {
     2204            uint8_t *pu8Data = (uint8_t *)RTMemAlloc(cbRequired);
     2205
     2206            if (pu8Data == NULL)
     2207            {
     2208                rc = VERR_NO_MEMORY;
     2209            }
     2210            else
     2211            {
     2212                /* Copy guest VRAM to the allocated 32bpp buffer. */
     2213                const uint8_t *pu8Src       = pFBInfo->pu8FramebufferVRAM;
     2214                int32_t xSrc                = 0;
     2215                int32_t ySrc                = 0;
     2216                uint32_t u32SrcWidth        = width;
     2217                uint32_t u32SrcHeight       = height;
     2218                uint32_t u32SrcLineSize     = pFBInfo->u32LineSize;
     2219                uint32_t u32SrcBitsPerPixel = pFBInfo->u16BitsPerPixel;
     2220
     2221                uint8_t *pu8Dst             = pu8Data;
     2222                int32_t xDst                = 0;
     2223                int32_t yDst                = 0;
     2224                uint32_t u32DstWidth        = u32SrcWidth;
     2225                uint32_t u32DstHeight       = u32SrcHeight;
     2226                uint32_t u32DstLineSize     = u32DstWidth * 4;
     2227                uint32_t u32DstBitsPerPixel = 32;
     2228
     2229                rc = pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
     2230                                                      width, height,
     2231                                                      pu8Src,
     2232                                                      xSrc, ySrc,
     2233                                                      u32SrcWidth, u32SrcHeight,
     2234                                                      u32SrcLineSize, u32SrcBitsPerPixel,
     2235                                                      pu8Dst,
     2236                                                      xDst, yDst,
     2237                                                      u32DstWidth, u32DstHeight,
     2238                                                      u32DstLineSize, u32DstBitsPerPixel);
     2239                if (RT_SUCCESS(rc))
     2240                {
     2241                    *ppu8Data = pu8Data;
     2242                    *pcbData = cbRequired;
     2243                    *pu32Width = width;
     2244                    *pu32Height = height;
     2245                }
     2246            }
     2247        }
     2248        else
     2249        {
     2250            /* No image. */
     2251            *ppu8Data = NULL;
     2252            *pcbData = 0;
     2253            *pu32Width = 0;
     2254            *pu32Height = 0;
     2255        }
     2256    }
     2257    else
     2258    {
     2259        rc = VERR_INVALID_PARAMETER;
     2260    }
     2261    pDisplay->vbvaUnlock();
     2262    return rc;
    21912263}
    21922264#endif /* VBOX_WITH_OLD_VBVA_LOCK */
    21932265
    21942266#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2195 static int displayTakeScreenshot(PVM pVM, Display *pDisplay, struct DRVMAINDISPLAY *pDrv, BYTE *address, ULONG width, ULONG height)
     2267static int displayTakeScreenshot(PVM pVM, Display *pDisplay, struct DRVMAINDISPLAY *pDrv, ULONG aScreenId, BYTE *address, ULONG width, ULONG height)
    21962268#else
    21972269static int displayTakeScreenshot(PVM pVM, struct DRVMAINDISPLAY *pDrv, BYTE *address, ULONG width, ULONG height)
     
    22042276
    22052277#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2206     int vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)Display::displayTakeScreenshotEMT, 5,
    2207                               pDisplay, &pu8Data, &cbData, &cx, &cy);
     2278    int vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)Display::displayTakeScreenshotEMT, 6,
     2279                              pDisplay, aScreenId, &pu8Data, &cbData, &cx, &cy);
    22082280#else
    22092281    /* @todo pfnTakeScreenshot is probably callable from any thread, because it uses the VGA device lock. */
     
    22862358
    22872359#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2288     int vrc = displayTakeScreenshot(pVM, this, mpDrv, address, width, height);
     2360    int vrc = displayTakeScreenshot(pVM, this, mpDrv, aScreenId, address, width, height);
    22892361#else
    22902362    int vrc = displayTakeScreenshot(pVM, mpDrv, address, width, height);
     
    23042376
    23052377STDMETHODIMP Display::TakeScreenShotToArray (ULONG aScreenId, ULONG width, ULONG height,
    2306                                           ComSafeArrayOut(BYTE, aScreenData))
     2378                                             ComSafeArrayOut(BYTE, aScreenData))
    23072379{
    23082380    LogFlowFuncEnter();
     
    23422414
    23432415#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2344     int vrc = displayTakeScreenshot(pVM, this, mpDrv, pu8Data, width, height);
     2416    int vrc = displayTakeScreenshot(pVM, this, mpDrv, aScreenId, pu8Data, width, height);
    23452417#else
    23462418    int vrc = displayTakeScreenshot(pVM, mpDrv, pu8Data, width, height);
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