VirtualBox

Changeset 44382 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jan 25, 2013 2:14:51 PM (12 years ago)
Author:
vboxsync
Message:

Main/DisplayImpl: Fix for access violation in case of multimonitor.

Display requests a resize of 4 framebuffers simultaneously. When one of framebuffers is resized, Display calls InvalidateAndUpdateEMT which is updating _all_ framebuffers but some of them are not yet finished with the resize. As a result, InvalidateAndUpdateEMT is assuming that all the framebuffers have right size, which is not true. Thus, crash while copying from source to destination recatangle .

File:
1 edited

Legend:

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

    r44347 r44382  
    27742774}
    27752775
    2776 void Display::InvalidateAndUpdateEMT(Display *pDisplay)
     2776void Display::InvalidateAndUpdateEMT(Display *pDisplay, unsigned uId, bool fUpdateAll)
    27772777{
    27782778    pDisplay->vbvaLock();
    27792779    unsigned uScreenId;
    2780     for (uScreenId = 0; uScreenId < pDisplay->mcMonitors; uScreenId++)
     2780    for (uScreenId = (fUpdateAll ? 0 : uId); uScreenId < pDisplay->mcMonitors; uScreenId++)
    27812781    {
    27822782        DISPLAYFBINFO *pFBInfo = &pDisplay->maFramebuffers[uScreenId];
     
    27892789        {
    27902790            if (   !pFBInfo->pFramebuffer.isNull()
    2791                 && !(pFBInfo->fDisabled))
     2791                && !(pFBInfo->fDisabled)
     2792                && pFBInfo->u32ResizeStatus == ResizeStatus_Void)
    27922793            {
    27932794                /* Render complete VRAM screen to the framebuffer.
     
    27972798                {
    27982799                    BYTE *address = NULL;
     2800                    ULONG uWidth = 0;
     2801                    ULONG uHeight = 0;
     2802                    pFBInfo->pFramebuffer->COMGETTER(Width) (&uWidth);
     2803                    pFBInfo->pFramebuffer->COMGETTER(Height) (&uHeight);
    27992804                    HRESULT hrc = pFBInfo->pFramebuffer->COMGETTER(Address) (&address);
    28002805                    if (SUCCEEDED(hrc) && address != NULL)
     
    28202825                        uint32_t u32DstBitsPerPixel = 32;
    28212826
    2822                         pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
    2823                                                               width, height,
    2824                                                               pu8Src,
    2825                                                               xSrc, ySrc,
    2826                                                               u32SrcWidth, u32SrcHeight,
    2827                                                               u32SrcLineSize, u32SrcBitsPerPixel,
    2828                                                               pu8Dst,
    2829                                                               xDst, yDst,
    2830                                                               u32DstWidth, u32DstHeight,
    2831                                                               u32DstLineSize, u32DstBitsPerPixel);
     2827                        /* if uWidth != pFBInfo->w and uHeight != pFBInfo->h
     2828                         * implies resize of Framebuffer is in progress and
     2829                         * copyrect should not be called.
     2830                         */
     2831                        if (uWidth == pFBInfo->w && uHeight == pFBInfo->h)
     2832                        {
     2833
     2834                            pDisplay->mpDrv->pUpPort->pfnCopyRect(pDisplay->mpDrv->pUpPort,
     2835                                                                  width, height,
     2836                                                                  pu8Src,
     2837                                                                  xSrc, ySrc,
     2838                                                                  u32SrcWidth, u32SrcHeight,
     2839                                                                  u32SrcLineSize, u32SrcBitsPerPixel,
     2840                                                                  pu8Dst,
     2841                                                                  xDst, yDst,
     2842                                                                  u32DstWidth, u32DstHeight,
     2843                                                                  u32DstLineSize, u32DstBitsPerPixel);
     2844                        }
    28322845                    }
    28332846                }
     
    28362849            }
    28372850        }
     2851        if (!fUpdateAll)
     2852            break;
    28382853    }
    28392854    pDisplay->vbvaUnlock();
     
    28702885    /* pdm.h says that this has to be called from the EMT thread */
    28712886    int rcVBox = VMR3ReqCallVoidWaitU(ptrVM.rawUVM(), VMCPUID_ANY, (PFNRT)Display::InvalidateAndUpdateEMT,
    2872                                       1, this);
     2887                                      3, this, 0, true);
    28732888    alock.acquire();
    28742889
     
    32283243             * Repaint all displays because VM continued to run during the framebuffer resize.
    32293244             */
    3230             pDisplay->InvalidateAndUpdateEMT(pDisplay);
     3245            pDisplay->InvalidateAndUpdateEMT(pDisplay, uScreenId, false);
    32313246        }
    32323247        else if (u32ResizeStatus == ResizeStatus_InProgress)
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