VirtualBox

Changeset 67474 in vbox for trunk/src


Ignore:
Timestamp:
Jun 19, 2017 1:12:33 PM (8 years ago)
Author:
vboxsync
Message:

Devices/DevVGA: Unify the drawing logic (full update is handled by the other case, too). Introduce proper VGA blanking.
Main/Display: Handle VGA blanking

Location:
trunk/src/VBox
Files:
2 edited

Legend:

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

    r67355 r67474  
    17861786 */
    17871787static int vga_draw_text(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty,
    1788         PDMIDISPLAYCONNECTOR *pDrv)
     1788                         PDMIDISPLAYCONNECTOR *pDrv)
    17891789{
    17901790    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
     
    23122312        uint32_t offPage0   = offSrcLine & ~PAGE_OFFSET_MASK;
    23132313        uint32_t offPage1   = (offSrcLine + cbScanline - 1) & ~PAGE_OFFSET_MASK;
     2314        /** @todo r=klaus this assumes that a line is fully covered by 2 pages,
     2315         * irrespective of alignment. Not guaranteed for high res modes, i.e.
     2316         * anything wider than 1026 pixels @32bpp. Need to check the pages
     2317         * between the first and last one, too. */
    23142318        bool     fUpdate    = fFullUpdate | vga_is_dirty(pThis, offPage0) | vga_is_dirty(pThis, offPage1);
    23152319        if (offPage1 - offPage0 > PAGE_SIZE)
     
    23612365 */
    23622366static int vga_draw_graphic(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty,
    2363                 PDMIDISPLAYCONNECTOR *pDrv)
     2367                            PDMIDISPLAYCONNECTOR *pDrv)
    23642368{
    23652369    int y1, y2, y, page_min, page_max, linesize, y_start, double_scan;
     
    25012505        page0 = addr & ~PAGE_OFFSET_MASK;
    25022506        page1 = (addr + bwidth - 1) & ~PAGE_OFFSET_MASK;
     2507        /** @todo r=klaus this assumes that a line is fully covered by 2 pages,
     2508         * irrespective of alignment. Not guaranteed for high res modes, i.e.
     2509         * anything wider than 1026 pixels @32bpp. Need to check the pages
     2510         * between the first and last one, too. */
    25032511        bool update = full_update | vga_is_dirty(pThis, page0) | vga_is_dirty(pThis, page1);
    25042512        if (page1 - page0 > PAGE_SIZE) {
     
    25562564}
    25572565
    2558 static void vga_draw_blank(PVGASTATE pThis, int full_update, PDMIDISPLAYCONNECTOR *pDrv)
     2566/*
     2567 * blanked modes
     2568 */
     2569static int vga_draw_blank(PVGASTATE pThis, bool full_update, bool fFailOnResize, bool reset_dirty,
     2570                          PDMIDISPLAYCONNECTOR *pDrv)
    25592571{
    25602572    int i, w, val;
    25612573    uint8_t *d;
    25622574    uint32_t cbScanline = pDrv->cbScanline;
    2563 
     2575    uint32_t page_min, page_max;
     2576
     2577    if (pThis->last_width != 0)
     2578    {
     2579        if (fFailOnResize)
     2580        {
     2581            /* The caller does not want to call the pfnResize. */
     2582            return VERR_TRY_AGAIN;
     2583        }
     2584        pThis->last_width = 0;
     2585        pThis->last_height = 0;
     2586        /* For blanking signal width=0, height=0, bpp=0 and cbLine=0 here.
     2587         * There is no screen content, which distinguishes it from text mode. */
     2588        pDrv->pfnResize(pDrv, 0, NULL, 0, 0, 0);
     2589    }
     2590    /* reset modified pages, i.e. everything */
     2591    if (reset_dirty && pThis->last_scr_height > 0)
     2592    {
     2593        page_min = (pThis->start_addr * 4) & ~PAGE_OFFSET_MASK;
     2594        /* round up page_max by one page, as otherwise this can be -PAGE_SIZE,
     2595         * which causes assertion trouble in vga_reset_dirty. */
     2596        page_max = (  pThis->start_addr * 4 + pThis->line_offset * pThis->last_scr_height
     2597                    - 1 + PAGE_SIZE) & ~PAGE_OFFSET_MASK;
     2598        vga_reset_dirty(pThis, page_min, page_max + PAGE_SIZE);
     2599    }
    25642600    if (pDrv->pbData == pThis->vram_ptrR3) /* Do not clear the VRAM itself. */
    2565         return;
     2601        return VINF_SUCCESS;
    25662602    if (!full_update)
    2567         return;
     2603        return VINF_SUCCESS;
    25682604    if (pThis->last_scr_width <= 0 || pThis->last_scr_height <= 0)
    2569         return;
     2605        return VINF_SUCCESS;
    25702606    if (pDrv->cBits == 8)
    25712607        val = pThis->rgb_to_pixel(0, 0, 0);
     
    25822618    }
    25832619    pDrv->pfnUpdateRect(pDrv, 0, 0, pThis->last_scr_width, pThis->last_scr_height);
     2620    return VINF_SUCCESS;
    25842621}
    25852622
     
    25902627
    25912628
    2592 #define GMODE_TEXT     0
    2593 #define GMODE_GRAPH    1
    2594 #define GMODE_BLANK 2
     2629#define GMODE_TEXT      0
     2630#define GMODE_GRAPH     1
     2631#define GMODE_BLANK     2
    25952632#ifdef VBOX_WITH_VMSVGA
    25962633#define GMODE_SVGA      3
     
    26222659        }
    26232660
    2624         if (fUpdateAll) {
    2625             /* A full update is requested. Special processing for a "blank" mode is required, because
    2626              * the request must process all pending resolution changes.
    2627              *
    2628              * Appropriate vga_draw_graphic or vga_draw_text function, which checks the resolution change,
    2629              * must be called even if the screen has been blanked, but then the function should do no actual
    2630              * screen update. To do this, pfnUpdateRect is replaced with a nop.
    2631              */
    2632             typedef DECLCALLBACK(void) FNUPDATERECT(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy);
    2633             typedef FNUPDATERECT *PFNUPDATERECT;
    2634 
    2635             PFNUPDATERECT pfnUpdateRect = NULL;
    2636 
    2637             /* Detect the "screen blank" conditions. */
    2638             int fBlank = 0;
    2639             if (!(pThis->ar_index & 0x20) || (pThis->sr[0x01] & 0x20)) {
    2640                 fBlank = 1;
    2641             }
    2642 
    2643             if (fBlank) {
    2644                 /* Provide a void pfnUpdateRect callback. */
    2645                 if (pDrv) {
    2646                     pfnUpdateRect = pDrv->pfnUpdateRect;
    2647                     pDrv->pfnUpdateRect = voidUpdateRect;
    2648                 }
    2649             }
    2650 
    2651             /* Do a complete redraw, which will pick up a new screen resolution. */
    2652 #ifdef VBOX_WITH_VMSVGA
    2653             if (pThis->svga.fEnabled) {
    2654                 *pcur_graphic_mode = GMODE_SVGA;
    2655                 rc = vmsvga_draw_graphic(pThis, 1, fFailOnResize, reset_dirty, pDrv);
    2656             }
    2657             else
    2658 #endif
    2659             if (pThis->gr[6] & 1) {
    2660                 *pcur_graphic_mode = GMODE_GRAPH;
    2661                 rc = vga_draw_graphic(pThis, 1, fFailOnResize, reset_dirty, pDrv);
    2662             } else {
    2663                 *pcur_graphic_mode = GMODE_TEXT;
    2664                 rc = vga_draw_text(pThis, 1, fFailOnResize, reset_dirty, pDrv);
    2665             }
    2666 
    2667             if (fBlank) {
    2668                 /* Set the current mode and restore the callback. */
    2669                 *pcur_graphic_mode = GMODE_BLANK;
    2670                 if (pDrv) {
    2671                     pDrv->pfnUpdateRect = pfnUpdateRect;
    2672                 }
    2673             }
    2674             return rc;
    2675         }
    2676 
    26772661#ifdef VBOX_WITH_VMSVGA
    26782662        if (pThis->svga.fEnabled) {
     
    26842668            graphic_mode = GMODE_BLANK;
    26852669        } else {
    2686             graphic_mode = pThis->gr[6] & 1;
    2687         }
    2688         bool full_update = graphic_mode != *pcur_graphic_mode;
     2670            graphic_mode = pThis->gr[6] & 1 ? GMODE_GRAPH : GMODE_TEXT;
     2671        }
     2672        bool full_update = fUpdateAll || graphic_mode != *pcur_graphic_mode;
    26892673        if (full_update) {
    26902674            *pcur_graphic_mode = graphic_mode;
     
    27042688        case GMODE_BLANK:
    27052689        default:
    2706             vga_draw_blank(pThis, full_update, pDrv);
     2690            rc = vga_draw_blank(pThis, full_update, fFailOnResize, reset_dirty, pDrv);
    27072691            break;
    27082692        }
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r66400 r67474  
    10781078    pFBInfo->pSourceBitmap.setNull();
    10791079
     1080    /* VGA blanking is signaled as w=0, h=0, bpp=0 and cbLine=0, and it's
     1081     * best to keep the old resolution, as otherwise the window size would
     1082     * change before the new resolution is known. */
     1083    const bool fVGABlank = fVGAResize && uScreenId == VBOX_VIDEO_PRIMARY_SCREEN
     1084                        && w == 0 && h == 0 && bpp == 0 && cbLine == 0;
     1085    if (fVGABlank)
     1086    {
     1087        w = pFBInfo->w;
     1088        h = pFBInfo->h;
     1089    }
     1090
    10801091    /* Update the video mode information. */
    10811092    pFBInfo->w = w;
     
    10921103        pFBInfo->fDisabled = RT_BOOL(flags & VBVA_SCREEN_F_DISABLED);
    10931104        pFBInfo->fVBVAForceResize = false;
     1105    }
     1106    else
     1107    {
     1108        pFBInfo->flags = 0;
     1109        if (fVGABlank)
     1110            pFBInfo->flags |= VBVA_SCREEN_F_BLANK;
     1111        pFBInfo->fDisabled = false;
    10941112    }
    10951113
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