VirtualBox

Changeset 31195 in vbox


Ignore:
Timestamp:
Jul 29, 2010 8:40:17 AM (15 years ago)
Author:
vboxsync
Message:

Attempt to fix crashes in DevVGA::vgaPortTakeScreenshot (xTracker 5146).

Location:
trunk/src/VBox
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r30886 r31195  
    17631763static void vga_draw_text(VGAState *s, int full_update)
    17641764#else
    1765 static int vga_draw_text(VGAState *s, int full_update)
     1765static int vga_draw_text(VGAState *s, int full_update, bool fFailOnResize)
    17661766#endif /* !VBOX */
    17671767{
     
    18511851    if (width != (int)s->last_width || height != (int)s->last_height ||
    18521852        cw != s->last_cw || cheight != s->last_ch) {
     1853#ifdef VBOX
     1854        if (fFailOnResize)
     1855        {
     1856            /* The caller does not want to call the pfnResize. */
     1857            return VERR_TRY_AGAIN;
     1858        }
     1859#endif /* VBOX */
    18531860        s->last_scr_width = width * cw;
    18541861        s->last_scr_height = height * cheight;
     
    21752182static void vga_draw_graphic(VGAState *s, int full_update)
    21762183#else
    2177 static int vga_draw_graphic(VGAState *s, int full_update)
     2184static int vga_draw_graphic(VGAState *s, int full_update, bool fFailOnResize)
    21782185#endif /* !VBOX */
    21792186{
     
    22622269        ||  offsets_changed)
    22632270    {
     2271        if (fFailOnResize)
     2272        {
     2273            /* The caller does not want to call the pfnResize. */
     2274            return VERR_TRY_AGAIN;
     2275        }
    22642276        int rc = vga_resize_graphic(s, disp_width, height, v);
    22652277        if (rc != VINF_SUCCESS)  /* Return any rc, particularly VINF_VGA_RESIZE_IN_PROGRESS, to the caller. */
     
    24682480    VGAState *s = vga_state;
    24692481#else /* VBOX */
    2470 static int vga_update_display(PVGASTATE s, bool fUpdateAll)
     2482static int vga_update_display(PVGASTATE s, bool fUpdateAll, bool fFailOnResize)
    24712483{
    24722484    int rc = VINF_SUCCESS;
     
    25032515#ifdef VBOX
    25042516        if (fUpdateAll) {
    2505             /* A full update is requested. Special processing for a "blank" mode is required. */
     2517            /* A full update is requested. Special processing for a "blank" mode is required, because
     2518             * the request must process all pending resolution changes.
     2519             *
     2520             * Appropriate vga_draw_graphic or vga_draw_text function, which checks the resolution change,
     2521             * must be called even if the screen has been blanked, but then the function should do no actual
     2522             * screen update. To do this, pfnUpdateRect is replaced with a nop.
     2523             */
    25062524            typedef DECLCALLBACK(void) FNUPDATERECT(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
    25072525            typedef FNUPDATERECT *PFNUPDATERECT;
     
    25242542
    25252543            /* Do a complete redraw, which will pick up a new screen resolution. */
    2526             if (fBlank) {
    2527                 s->graphic_mode = GMODE_BLANK;
    2528                 vga_draw_blank(s, 1);
    2529             } else if (s->gr[6] & 1) {
     2544            if (s->gr[6] & 1) {
    25302545                s->graphic_mode = GMODE_GRAPH;
    2531                 rc = vga_draw_graphic(s, 1);
     2546                rc = vga_draw_graphic(s, 1, false);
    25322547            } else {
    25332548                s->graphic_mode = GMODE_TEXT;
    2534                 rc = vga_draw_text(s, 1);
     2549                rc = vga_draw_text(s, 1, false);
    25352550            }
    25362551
     
    25612576            rc =
    25622577#endif /* VBOX */
    2563             vga_draw_text(s, full_update);
     2578            vga_draw_text(s, full_update, fFailOnResize);
    25642579            break;
    25652580        case GMODE_GRAPH:
     
    25672582            rc =
    25682583#endif /* VBOX */
    2569             vga_draw_graphic(s, full_update);
     2584            vga_draw_graphic(s, full_update, fFailOnResize);
    25702585            break;
    25712586        case GMODE_BLANK:
     
    34803495    {
    34813496#ifdef DEBUG_sunlover
    3482         AssertMsgFailed(("vgaR3IOPortHGSMIRead: Port=%#x cb=%d\n", Port, cb));
     3497        Log(("vgaR3IOPortHGSMIRead: Port=%#x cb=%d\n", Port, cb));
    34833498#endif
    34843499        rc = VERR_IOM_IOPORT_UNUSED;
     
    48614876    }
    48624877
    4863     rc = vga_update_display(pThis, false);
     4878    rc = vga_update_display(pThis, false, false);
    48644879    if (rc != VINF_SUCCESS)
    48654880    {
     
    48894904    pThis->graphic_mode = -1; /* force full update */
    48904905
    4891     return vga_update_display(pThis, true);
     4906    return vga_update_display(pThis, true, false);
    48924907}
    48934908
     
    49784993
    49794994    /*
    4980      * Do a complete screen update first to resolve any pending resize issues.
     4995     * Get screenshot. This function will fail if a resize is required.
     4996     * So there is not need to do a 'updateDisplayAll' before taking screenshot.
    49814997     */
    4982     updateDisplayAll(pThis);
    49834998
    49844999    /*
     
    50285043            /* Make the screenshot.
    50295044             *
    5030              * The second parameter is 'false' because the current display state, already updated by the
    5031              * pfnUpdateDisplayAll call above, is being rendered to an external buffer using a fake connector.
    5032              * That is if display is blanked, we expect a black screen in the external buffer.
     5045             * The second parameter is 'false' because the current display state is being rendered to an
     5046             * external buffer using a fake connector. That is if display is blanked, we expect a black
     5047             * screen in the external buffer.
     5048             * If there is a pending resize, the function will fail.
    50335049             */
    5034             rc = vga_update_display(pThis, false);
     5050            rc = vga_update_display(pThis, false, true);
    50355051
    50365052            /* Restore. */
  • trunk/src/VBox/Main/DisplayImpl.cpp

    r30871 r31195  
    24332433    uint32_t cx = 0;
    24342434    uint32_t cy = 0;
     2435    int vrc = VINF_SUCCESS;
    24352436
    24362437#ifdef VBOX_WITH_OLD_VBVA_LOCK
    2437     int vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)Display::displayTakeScreenshotEMT, 6,
     2438    int cRetries = 5;
     2439
     2440    while (cRetries-- > 0)
     2441    {
     2442        vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)Display::displayTakeScreenshotEMT, 6,
    24382443                              pDisplay, aScreenId, &pu8Data, &cbData, &cx, &cy);
     2444        if (vrc != VERR_TRY_AGAIN)
     2445        {
     2446            break;
     2447        }
     2448
     2449        RTThreadSleep(10);
     2450    }
    24392451#else
    24402452    /* @todo pfnTakeScreenshot is probably callable from any thread, because it uses the VGA device lock. */
    2441     int vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)pDrv->pUpPort->pfnTakeScreenshot, 5,
     2453    vrc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)pDrv->pUpPort->pfnTakeScreenshot, 5,
    24422454                              pDrv->pUpPort, &pu8Data, &cbData, &cx, &cy);
    24432455#endif /* !VBOX_WITH_OLD_VBVA_LOCK */
     
    25252537        rc = setError(E_NOTIMPL,
    25262538                      tr("This feature is not implemented"));
     2539    else if (vrc == VERR_TRY_AGAIN)
     2540        rc = setError(E_UNEXPECTED,
     2541                      tr("This feature is not available at this time"));
    25272542    else if (RT_FAILURE(vrc))
    25282543        rc = setError(VBOX_E_IPRT_ERROR,
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