VirtualBox

Changeset 32897 in vbox for trunk/src/VBox/Devices/Graphics


Ignore:
Timestamp:
Oct 5, 2010 9:37:12 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66380
Message:

VGA: Removed mode width restriction, broke out pitch calculation.

File:
1 edited

Legend:

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

    r32877 r32897  
    828828}
    829829
     830#define VBE_PITCH_ALIGN     8       /* Align pitch to 64 bits. */
     831
     832/* Calculate scanline pitch based on bit depth and width in pixels. */
     833static uint32_t calc_line_pitch(uint16_t bpp, uint16_t width)
     834{
     835    uint32_t    pitch, aligned_pitch;
     836
     837    if (bpp <= 4)
     838        pitch = width >> 1;
     839    else
     840        pitch = width * ((bpp + 7) >> 3);
     841
     842    /* Align the pitch to some sensible value. */
     843    aligned_pitch = (pitch + (VBE_PITCH_ALIGN - 1)) & ~(VBE_PITCH_ALIGN - 1);
     844    if (aligned_pitch != pitch)
     845        Log(("VBE: Line pitch %d aligned to %d bytes\n", pitch, aligned_pitch));
     846
     847    return aligned_pitch;
     848}
     849
     850/* Calculate line width in pixels based on bit depth and pitch. */
     851static uint32_t calc_line_width(uint16_t bpp, uint32_t pitch)
     852{
     853    uint32_t    width;
     854
     855    if (bpp <= 4)
     856        width = pitch << 1;
     857    else
     858        width = pitch / ((bpp + 7) >> 3);
     859
     860    return width;
     861}
     862
    830863static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
    831864{
     
    864897            break;
    865898        case VBE_DISPI_INDEX_XRES:
    866             if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
     899            if (val <= VBE_DISPI_MAX_XRES) {
    867900                s->vbe_regs[s->vbe_index] = val;
    868901#ifdef KEEP_SCAN_LINE_LENGTH
    869                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
    870                     s->vbe_line_offset = val >> 1;
    871                 else
    872                     s->vbe_line_offset = val * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
     902                s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], val);
    873903                /* XXX: support weird bochs semantics ? */
    874                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = val;
     904                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(s->vbe_regs[VBE_DISPI_INDEX_BPP], s->vbe_line_offset);
    875905                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    876906                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
     
    897927                s->vbe_regs[s->vbe_index] = val;
    898928#ifdef KEEP_SCAN_LINE_LENGTH
    899                 if (val == 4)
    900                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
    901                 else
    902                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((val + 7) >> 3);
     929                s->vbe_line_offset = calc_line_pitch(val, s->vbe_regs[VBE_DISPI_INDEX_XRES]);
    903930                /* XXX: support weird bochs semantics ? */
    904                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = val;
     931                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(val, s->vbe_line_offset);
    905932                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    906933                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
     
    9731000                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
    9741001
    975                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
    976                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
    977                 else
    978                     s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
    979                         ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
     1002                s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP],
     1003                                                      s->vbe_regs[VBE_DISPI_INDEX_XRES]);
    9801004                s->vbe_start_addr = 0;
    9811005#endif  /* KEEP_SCAN_LINE_LENGTH not defined */
     
    10651089                    return VINF_SUCCESS;
    10661090                w = val;
    1067                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
    1068                     line_offset = w >> 1;
    1069                 else
    1070                     line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
     1091                line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], w);
    10711092                h = s->vram_size / line_offset;
    10721093                /* XXX: support weird bochs semantics ? */
     
    61216142    uint32_t    cCustomModes;
    61226143    uint32_t    cyReduction;
     6144    uint32_t    cbPitch;
     6145    int         nPages;
    61236146    PVBEHEADER  pVBEDataHdr;
    61246147    ModeInfoListItem *pCurMode;
     
    65896612                    return VERR_VGA_INVALID_CUSTOM_MODE;
    65906613                }
    6591                 /* Round up the X resolution to a multiple of eight. */
    6592                 cx = (cx + 7) & ~7;
     6614                cbPitch = calc_line_pitch(cBits, cx);
    65936615# ifdef VRAM_SIZE_FIX
    6594                 if (cx * cy * cBits / 8 >= pThis->vram_size)
     6616                if (cy * cbPitch >= pThis->vram_size)
    65956617                {
    65966618                    AssertMsgFailed(("Configuration error: custom video mode %dx%dx%dbits is too large for the virtual video memory of %dMb.  Please increase the video memory size.\n",
     
    66306652
    66316653                /* adjust defaults */
     6654                /* The "number of image pages" is really the max page index... */
     6655                nPages = pThis->vram_size / (cy * cbPitch) - 1;
     6656                Assert(nPages);
     6657                if (nPages > 255)
     6658                    nPages = 255;   /* 8-bit value. */
    66326659                pCurMode->info.XResolution = cx;
    66336660                pCurMode->info.YResolution = cy;
    6634 
    6635                 switch (cBits)
    6636                 {
    6637                     case 16:
    6638                         pCurMode->info.BytesPerScanLine = cx * 2;
    6639                         pCurMode->info.LinBytesPerScanLine = cx * 2;
    6640                         break;
    6641 
    6642                     case 24:
    6643                         pCurMode->info.BytesPerScanLine = cx * 3;
    6644                         pCurMode->info.LinBytesPerScanLine = cx * 3;
    6645                         break;
    6646 
    6647                     case 32:
    6648                         pCurMode->info.BytesPerScanLine = cx * 4;
    6649                         pCurMode->info.LinBytesPerScanLine = cx * 4;
    6650                         break;
    6651                 }
     6661                pCurMode->info.BytesPerScanLine    = cbPitch;
     6662                pCurMode->info.LinBytesPerScanLine = cbPitch;
     6663                pCurMode->info.NumberOfImagePages  = nPages;
     6664                pCurMode->info.LinNumberOfPages    = nPages;
    66526665
    66536666                /* commit it */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette