VirtualBox

儲存庫 vbox 的更動 34849


忽略:
時間撮記:
2010-12-9 上午12:05:15 (14 年 以前)
作者:
vboxsync
訊息:

Devices/Graphics: clean up VBE register setting and do not overwrite virtual widths

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r34404 r34849  
    6767 * Only works when VBE_NEW_DYN_LIST is defined! */
    6868#define VRAM_SIZE_FIX
    69 
    70 /** Some fixes to ensure that logical scan-line lengths are not overwritten. */
    71 #define KEEP_SCAN_LINE_LENGTH
    7269
    7370/** Check buffer if an VRAM offset is within the right range or not. */
     
    948945
    949946    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
     947        bool fRecalculate = false;
    950948        Log(("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val));
    951949        switch(s->vbe_index) {
     
    970968            break;
    971969        case VBE_DISPI_INDEX_XRES:
    972             if (val <= VBE_DISPI_MAX_XRES) {
     970            if (val <= VBE_DISPI_MAX_XRES)
     971            {
    973972                s->vbe_regs[s->vbe_index] = val;
    974 #ifdef KEEP_SCAN_LINE_LENGTH
    975                 s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], val);
    976                 /* XXX: support weird bochs semantics ? */
    977                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(s->vbe_regs[VBE_DISPI_INDEX_BPP], s->vbe_line_offset);
    978                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    979                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
    980                 s->vbe_start_addr = 0;
    981 #endif  /* KEEP_SCAN_LINE_LENGTH defined */
     973                fRecalculate = true;
    982974            }
    983975            break;
    984976        case VBE_DISPI_INDEX_YRES:
    985             if (val <= VBE_DISPI_MAX_YRES) {
     977            if (val <= VBE_DISPI_MAX_YRES)
    986978                s->vbe_regs[s->vbe_index] = val;
    987 #ifdef KEEP_SCAN_LINE_LENGTH
    988                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = val;
    989                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    990                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
    991                 s->vbe_start_addr = 0;
    992 #endif  /* KEEP_SCAN_LINE_LENGTH defined */
    993             }
    994979            break;
    995980        case VBE_DISPI_INDEX_BPP:
     
    999984                val == 16 || val == 24 || val == 32) {
    1000985                s->vbe_regs[s->vbe_index] = val;
    1001 #ifdef KEEP_SCAN_LINE_LENGTH
    1002                 s->vbe_line_offset = calc_line_pitch(val, s->vbe_regs[VBE_DISPI_INDEX_XRES]);
    1003                 /* XXX: support weird bochs semantics ? */
    1004                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = calc_line_width(val, s->vbe_line_offset);
    1005                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    1006                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
    1007                 s->vbe_start_addr = 0;
    1008 #endif  /* KEEP_SCAN_LINE_LENGTH defined */
     986                fRecalculate = true;
    1009987            }
    1010988            break;
     
    10481026                    cb = s->vbe_regs[VBE_DISPI_INDEX_XRES] * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
    10491027                cb *= s->vbe_regs[VBE_DISPI_INDEX_YRES];
    1050 #ifndef KEEP_SCAN_LINE_LENGTH
    1051                 if (    !s->vbe_regs[VBE_DISPI_INDEX_XRES]
    1052                     ||  !s->vbe_regs[VBE_DISPI_INDEX_YRES]
    1053                     ||  cb > s->vram_size)
    1054                 {
    1055                     AssertMsgFailed(("XRES=%d YRES=%d cb=%d vram_size=%d\n",
    1056                                      s->vbe_regs[VBE_DISPI_INDEX_XRES], s->vbe_regs[VBE_DISPI_INDEX_YRES], cb, s->vram_size));
    1057                     return VINF_SUCCESS; /* Note: silent failure like before */
    1058                 }
    1059 #else  /* KEEP_SCAN_LINE_LENGTH defined */
    1060                 if (    !s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH]
     1028                uint16_t cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
     1029                if (!cVirtWidth)
     1030                    cVirtWidth = s->vbe_regs[VBE_DISPI_INDEX_XRES];
     1031                if (    !cVirtWidth
    10611032                    ||  !s->vbe_regs[VBE_DISPI_INDEX_YRES]
    10621033                    ||  cb > s->vram_size)
     
    10661037                    return VINF_SUCCESS; /* Note: silent failure like before */
    10671038                }
    1068 #endif  /* KEEP_SCAN_LINE_LENGTH defined */
    1069 
    1070 #ifndef KEEP_SCAN_LINE_LENGTH
    1071                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
    1072                     s->vbe_regs[VBE_DISPI_INDEX_XRES];
    1073                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
    1074                     s->vbe_regs[VBE_DISPI_INDEX_YRES];
    1075                 s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
    1076                 s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
    1077 
    1078                 s->vbe_line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP],
    1079                                                       s->vbe_regs[VBE_DISPI_INDEX_XRES]);
    1080                 s->vbe_start_addr = 0;
    1081 #endif  /* KEEP_SCAN_LINE_LENGTH not defined */
    10821039
    10831040                /* clear the screen (should be done in BIOS) */
    10841041                if (!(val & VBE_DISPI_NOCLEARMEM)) {
     1042                    uint16_t cY = RT_MIN(s->vbe_regs[VBE_DISPI_INDEX_YRES],
     1043                                         s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT]);
     1044                    uint16_t cbLinePitch = s->vbe_line_offset;
    10851045                    memset(s->CTX_SUFF(vram_ptr), 0,
    1086                            s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
     1046                           cY * cbLinePitch);
    10871047                }
    10881048
     
    10931053                s->cr[0x13] = s->vbe_line_offset >> 3;
    10941054                /* width */
    1095                 s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
     1055                s->cr[0x01] = (cVirtWidth >> 3) - 1;
    10961056                /* height (only meaningful if < 1024) */
    10971057                h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
     
    11501110#endif /* IN_RING3 */
    11511111        case VBE_DISPI_INDEX_VIRT_WIDTH:
    1152             {
    1153                 int w, h, line_offset;
    1154 
    1155                 if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
    1156                     return VINF_SUCCESS;
    1157                 w = val;
    1158                 line_offset = calc_line_pitch(s->vbe_regs[VBE_DISPI_INDEX_BPP], w);
    1159                 h = s->vram_size / line_offset;
    1160                 /* XXX: support weird bochs semantics ? */
    1161                 if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
    1162                     return VINF_SUCCESS;
    1163                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
    1164                 s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
    1165                 s->vbe_line_offset = line_offset;
    1166             }
    1167             break;
    11681112        case VBE_DISPI_INDEX_X_OFFSET:
    11691113        case VBE_DISPI_INDEX_Y_OFFSET:
    11701114            {
    1171                 int x;
    11721115                s->vbe_regs[s->vbe_index] = val;
    1173                 s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
    1174                 x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
    1175                 if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
    1176                     s->vbe_start_addr += x >> 1;
    1177                 else
    1178                     s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
    1179                 s->vbe_start_addr >>= 2;
     1116                fRecalculate = true;
    11801117            }
    11811118            break;
     
    12011138        default:
    12021139            break;
     1140        }
     1141        if (fRecalculate)
     1142        {
     1143            uint16_t cBPP        = s->vbe_regs[VBE_DISPI_INDEX_BPP];
     1144            uint16_t cVirtWidth  = s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH];
     1145            uint16_t cX          = s->vbe_regs[VBE_DISPI_INDEX_XRES];
     1146            uint16_t offX        = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
     1147            uint16_t offY        = s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
     1148            if (!cBPP || !cX)
     1149                return VINF_SUCCESS;  /* Not enough data has been set yet. */
     1150            uint32_t cbLinePitch = calc_line_pitch(cBPP, cVirtWidth);
     1151            if (!cbLinePitch)
     1152                cbLinePitch      = calc_line_pitch(cBPP, cX);
     1153            Assert(cbLinePitch != 0);
     1154            uint16_t cVirtHeight = s->vram_size / cbLinePitch;
     1155            uint32_t offStart    = cbLinePitch * offY;
     1156            if (cBPP == 4)
     1157                offStart += offX >> 1;
     1158            else
     1159                offStart += offX * ((cBPP + 7) >> 3);
     1160            offStart >>= 2;
     1161            s->vbe_line_offset = RT_MIN(cbLinePitch, s->vram_size);
     1162            s->vbe_start_addr  = RT_MIN(offStart, s->vram_size);
     1163            s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = cVirtHeight;
    12031164        }
    12041165    }
     
    20472008
    20482009    int rc;
     2010    AssertReturn(cx, VERR_INVALID_PARAMETER);
     2011    AssertReturn(cy, VERR_INVALID_PARAMETER);
     2012    AssertPtrReturn(s, VERR_INVALID_POINTER);
     2013    AssertReturn(s->line_offset, VERR_INTERNAL_ERROR);
    20492014#if 0 //def VBOX_WITH_VDMA
    20502015    /* @todo: we get a second resize here when VBVA is on, while we actually should not */
     
    20612026#endif
    20622027    {
     2028        /* Silently skip the resize and if the values are not valid, and
     2029         * forceably disable VBE and blank the screen. */
     2030        if (s->start_addr * 4 + s->line_offset * cy < s->vram_size)
    20632031        /* Take into account the programmed start address (in DWORDs) of the visible screen. */
    2064         rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy);
     2032            rc = s->pDrv->pfnResize(s->pDrv, cBits, s->CTX_SUFF(vram_ptr) + s->start_addr * 4, s->line_offset, cx, cy);
     2033        else
     2034        {
     2035            s->vbe_regs[VBE_DISPI_INDEX_ENABLE] &= ~VBE_DISPI_ENABLED;
     2036            s->ar_index &= ~0x20;
     2037            s->pDrv->pfnLFBModeChange(s->pDrv, false);
     2038            /* Try again with the changes we have just made, but still set
     2039             * s->last_* to avoid a loop. */
     2040            rc = VERR_TRY_AGAIN;
     2041        }
    20652042    }
    20662043
     
    20722049    s->last_height = cy;
    20732050
    2074     if (rc == VINF_VGA_RESIZE_IN_PROGRESS)
     2051    if (rc == VINF_VGA_RESIZE_IN_PROGRESS || rc == VERR_TRY_AGAIN)
    20752052        return rc;
    20762053    AssertRC(rc);
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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