VirtualBox

Changeset 2106 in vbox for trunk/src/VBox/Frontends/VBoxBFE


Ignore:
Timestamp:
Apr 16, 2007 3:25:48 PM (18 years ago)
Author:
vboxsync
Message:

Do not block EMT while resizing the framebuffer.

Location:
trunk/src/VBox/Frontends/VBoxBFE
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp

    r1550 r2106  
    9393    mcbVbvaPartial = 0;
    9494
    95     RTSemEventMultiCreate(&mResizeSem);
    9695    RTSemEventMultiCreate(&mUpdateSem);
    9796
    9897    // reset the event sems
    99     RTSemEventMultiReset(mResizeSem);
    10098    RTSemEventMultiReset(mUpdateSem);
    10199
     
    105103    mInternalFramebuffer = true;
    106104    mFramebufferOpened = false;
     105
     106    mu32ResizeStatus = ResizeStatus_Void;
    107107}
    108108
     
    110110{
    111111    mFramebuffer = 0;
    112     RTSemEventMultiDestroy(mResizeSem);
    113112    RTSemEventMultiDestroy(mUpdateSem);
    114113}
     
    124123 * @param h New display height
    125124 */
    126 void VMDisplay::handleDisplayResize (int w, int h)
     125int VMDisplay::handleDisplayResize (int w, int h)
    127126{
    128127    LogFlow(("VMDisplay::handleDisplayResize(): w=%d, h=%d\n", w, h));
     
    130129    // if there is no Framebuffer, this call is not interesting
    131130    if (mFramebuffer == NULL)
    132         return;
    133 
    134      // callback into the Framebuffer to notify it
     131        return VINF_SUCCESS;
     132
     133    /* Atomically set the resize status before calling the framebuffer. The new InProgress status will
     134     * disable access to the VGA device by the EMT thread.
     135     */
     136    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_InProgress, ResizeStatus_Void);
     137    AssertRelease(f);NOREF(f);
     138
     139    // callback into the Framebuffer to notify it
    135140    BOOL finished;
    136141
    137142    mFramebuffer->Lock();
    138 
    139     /* Reset the event here. It could be signalled before it gets to after 'if (!finished)' */
    140     RTSemEventMultiReset(mResizeSem);
    141143
    142144    mFramebuffer->RequestResize(w, h, &finished);
     
    150152         */
    151153
    152         /// @todo is this compatible with VBOX_NEXT_STEP?
    153         // the framebuffer needs more time to process
    154         // the event so we have to halt the VM until it's done
    155         RTSemEventMultiWait(mResizeSem, RT_INDEFINITE_WAIT);
    156     }
    157 
    158     updateDisplayData();
    159 
    160     mFramebuffer->Unlock();
    161     return;
     154        return VINF_VGA_RESIZE_IN_PROGRESS;
     155    }
     156
     157    /* Set the status so the 'handleResizeCompleted' would work.  */
     158    f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);
     159    AssertRelease(f);NOREF(f);
     160
     161    /* The method also unlocks the framebuffer. */
     162    handleResizeCompletedEMT();
     163
     164    return VINF_SUCCESS;
     165}
     166
     167/**
     168 *  Framebuffer has been resized.
     169 *  Read the new display data and unlock the framebuffer.
     170 *
     171 *  @thread EMT
     172 */
     173void VMDisplay::handleResizeCompletedEMT (void)
     174{
     175    LogFlowFunc(("\n"));
     176    if (mFramebuffer)
     177    {
     178        /* Framebuffer has completed the resize. Update the connector data. */
     179        updateDisplayData();
     180   
     181        mpDrv->pUpPort->pfnSetRenderVRAM (mpDrv->pUpPort, true);
     182
     183        /* Unlock framebuffer. */
     184        mFramebuffer->Unlock();
     185    }
     186
     187    /* Go into non resizing state. */
     188    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_Void, ResizeStatus_UpdateDisplayData);
     189    AssertRelease(f);NOREF(f);
    162190}
    163191
     
    176204        return E_FAIL;
    177205
    178     /* The framebuffer can already be locked by the thread waiting for completion; due to recent
    179      * changes when calling the VGA device. We don't really need to lock it here, so just don't
    180      * bother.
    181      */
    182     //mFramebuffer->Lock();
    183     // signal our semaphore
    184     RTSemEventMultiSignal(mResizeSem);
    185     //mFramebuffer->Unlock();
     206    /* Set the flag indicating that the resize has completed and display data need to be updated. */
     207    bool f = ASMAtomicCmpXchgU32 (&mu32ResizeStatus, ResizeStatus_UpdateDisplayData, ResizeStatus_InProgress);
     208    AssertRelease(f);NOREF(f);
    186209
    187210    return S_OK;
     
    423446 * @param  cy         New height in pixels.
    424447 */
    425 DECLCALLBACK(void) VMDisplay::displayResizeCallback(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy)
     448DECLCALLBACK(int) VMDisplay::displayResizeCallback(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy)
    426449{
    427450    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
    428451
    429452    // forward call to instance handler
    430     pDrv->pDisplay->handleDisplayResize(cx, cy);
     453    return pDrv->pDisplay->handleDisplayResize(cx, cy);
    431454}
    432455
     
    465488
    466489    VMDisplay *pDisplay = pDrv->pDisplay;
     490
     491    uint32_t u32ResizeStatus = pDisplay->mu32ResizeStatus;
     492   
     493    if (u32ResizeStatus == ResizeStatus_UpdateDisplayData)
     494    {
     495#ifdef DEBUG_sunlover
     496        LogFlowFunc (("ResizeStatus_UpdateDisplayData\n"));
     497#endif /* DEBUG_sunlover */
     498        /* The framebuffer was resized and display data need to be updated. */
     499        pDisplay->handleResizeCompletedEMT ();
     500        /* Continue with normal processing because the status here is ResizeStatus_Void. */
     501        Assert (pDisplay->mu32ResizeStatus == ResizeStatus_Void);
     502    }
     503    else if (u32ResizeStatus == ResizeStatus_InProgress)
     504    {
     505#ifdef DEBUG_sunlover
     506        LogFlowFunc (("ResizeStatus_InProcess\n"));
     507#endif /* DEBUG_sunlover */
     508        /* The framebuffer is being resized. Do not call the VGA device back. Immediately return. */
     509        return;
     510    }
    467511
    468512    if (pDisplay->mfPendingVideoAccelEnable)
  • trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.h

    r1550 r2106  
    3939
    4040    // public methods only for internal purposes
    41     void handleDisplayResize (int w, int h);
     41    int handleDisplayResize (int w, int h);
    4242    void handleDisplayUpdate (int x, int y, int cx, int cy);
    4343
     
    6767    static DECLCALLBACK(void*) drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface);
    6868    static DECLCALLBACK(int)   drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle);
    69     static DECLCALLBACK(void)  displayResizeCallback(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy);
     69    static DECLCALLBACK(int)   displayResizeCallback(PPDMIDISPLAYCONNECTOR pInterface, uint32_t bpp, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy);
    7070    static DECLCALLBACK(void)  displayUpdateCallback(PPDMIDISPLAYCONNECTOR pInterface,
    7171                                                     uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
     
    8282
    8383    ULONG mSupportedAccelOps;
    84     RTSEMEVENTMULTI mResizeSem;
    8584    RTSEMEVENTMULTI mUpdateSem;
    8685
     
    9796    bool vbvaFetchCmd (struct _VBVACMDHDR **ppHdr, uint32_t *pcbCmd);
    9897    void vbvaReleaseCmd (struct _VBVACMDHDR *pHdr, int32_t cbCmd);
     98
     99    void VMDisplay::handleResizeCompletedEMT (void);
     100    volatile uint32_t mu32ResizeStatus;
     101   
     102    enum {
     103        ResizeStatus_Void,
     104        ResizeStatus_InProgress,
     105        ResizeStatus_UpdateDisplayData
     106    };
    99107};
    100108
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