Ticket #3850: vesa_edi_wip.patch

File vesa_edi_wip.patch, 12.5 KB (added by tqh, 11 years ago)
  • src/add-ons/accelerants/common/create_display_modes.cpp

     
    1212
    1313#include <video_overlay.h>
    1414
     15#if !defined(_KERNEL_MODE) && !defined(_BOOT_MODE)
     16#define dprintf _sPrintf
     17extern "C" void _sPrintf(const char *format, ...);
     18#endif
    1519
    1620#define POSITIVE_SYNC \
    1721    (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
     
    8387    ModeList();
    8488    ~ModeList();
    8589
    86     bool AddModes(edid1_info* info);
     90    bool AddModes(const edid1_info* info);
    8791    bool AddModes(const display_mode* modes, uint32 count);
    8892
    8993    bool CreateColorSpaces(const color_space* spaces, uint32 count);
     
    97101    bool _MakeSpace(uint32 count);
    98102    bool _AddMode(const display_mode* mode);
    99103    void _RemoveModeAt(uint32 index);
    100     void _AddBaseMode(uint16 width, uint16 height, uint32 refresh);
     104    bool _IsEstablishedMode(const display_mode& mode, const edid1_established_timing timings);
     105    bool _IsStandardMode(const display_mode& mode, const edid1_info* info);
     106    bool _IsModeInRange(const display_mode& mode, const edid1_info* info);
    101107
     108    bool _ModeMatches(const display_mode& mode, uint16 width, uint16 height, uint32 refresh);
     109
    102110    display_mode*   fModes;
    103111    uint32          fCount;
    104112    uint32          fCapacity;
     
    108116
    109117using namespace BPrivate;
    110118
    111 
    112119static float
    113120get_refresh_rate(const display_mode& mode)
    114121{
     
    159166    free(fModes);
    160167}
    161168
    162 
    163169bool
    164 ModeList::AddModes(edid1_info* info)
     170ModeList::AddModes(const edid1_info* info)
    165171{
    166     if (info->established_timing.res_720x400x70)
    167         _AddBaseMode(720, 400, 70);
    168     if (info->established_timing.res_720x400x88)
    169         _AddBaseMode(720, 400, 88);
     172    for (uint32 mIndex = 0; mIndex < kNumBaseModes; mIndex++) {
     173        const display_mode& mode = kBaseModeList[mIndex];
    170174
    171     if (info->established_timing.res_640x480x60)
    172         _AddBaseMode(640, 480, 60);
    173     if (info->established_timing.res_640x480x67)
    174         _AddBaseMode(640, 480, 67);
    175     if (info->established_timing.res_640x480x72)
    176         _AddBaseMode(640, 480, 72);
    177     if (info->established_timing.res_640x480x75)
    178         _AddBaseMode(640, 480, 75);
    179 
    180     if (info->established_timing.res_800x600x56)
    181         _AddBaseMode(800, 600, 56);
    182     if (info->established_timing.res_800x600x60)
    183         _AddBaseMode(800, 600, 60);
    184     if (info->established_timing.res_800x600x72)
    185         _AddBaseMode(800, 600, 72);
    186     if (info->established_timing.res_800x600x75)
    187         _AddBaseMode(800, 600, 75);
    188 
    189 #if 0
    190     if (info->established_timing.res_832x624x75)
    191         _AddBaseMode(832, 624, 75);
    192 
    193     if (info->established_timing.res_1024x768x87i)
    194         _AddBaseMode(1024, 768, 87);
    195 #endif
    196     if (info->established_timing.res_1024x768x60)
    197         _AddBaseMode(1024, 768, 60);
    198     if (info->established_timing.res_1024x768x70)
    199         _AddBaseMode(1024, 768, 70);
    200     if (info->established_timing.res_1024x768x75)
    201         _AddBaseMode(1024, 768, 75);
    202 
    203     if (info->established_timing.res_1152x870x75)
    204         _AddBaseMode(1152, 870, 75);
    205     if (info->established_timing.res_1280x1024x75)
    206         _AddBaseMode(1280, 1024, 75);
    207 
    208     for (uint32 i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
    209         if (info->std_timing[i].h_size <= 256)
    210             continue;
    211 
    212         _AddBaseMode(info->std_timing[i].h_size, info->std_timing[i].v_size,
    213             info->std_timing[i].refresh);
    214     }
    215 
     175        if (_IsEstablishedMode(mode, info->established_timing) ||
     176                _IsStandardMode(mode, info) ||
     177                _IsModeInRange(mode, info))
     178            _AddMode(&mode);
     179        else
     180            dprintf("Mode not EDI compatible %dx%d@%fHz\n",
     181                    mode.timing.h_display, mode.timing.v_display,
     182                    get_refresh_rate(mode));
     183    }   
     184           
    216185    for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
    217186        if (info->detailed_monitor[i].monitor_desc_type
    218187                != EDID1_IS_DETAILED_TIMING)
     
    253222
    254223        _AddMode(&mode);
    255224    }
    256 
    257     // TODO: add other modes from the base list that satisfy the display's
    258     //  requirements!
    259 
     225   
    260226    return true;
    261227}
    262228
     
    319285    }
    320286}
    321287
     288bool
     289ModeList::_IsEstablishedMode(const display_mode& mode, edid1_established_timing timings)
     290{
     291    return (timings.res_720x400x70 && _ModeMatches(mode, 720, 400, 70)) ||
     292            (timings.res_720x400x88 && _ModeMatches(mode, 720, 400, 88)) ||
     293            (timings.res_640x480x60 && _ModeMatches(mode, 640, 480, 60)) ||
     294            (timings.res_640x480x67 && _ModeMatches(mode, 640, 480, 67)) ||
     295            (timings.res_640x480x72 && _ModeMatches(mode, 640, 480, 72)) ||
     296            (timings.res_640x480x75 && _ModeMatches(mode, 640, 480, 75)) ||
     297            (timings.res_800x600x56 && _ModeMatches(mode, 800, 600, 56)) ||
     298            (timings.res_800x600x60 && _ModeMatches(mode, 800, 600, 60)) ||
     299            (timings.res_800x600x72 && _ModeMatches(mode, 800, 600, 72)) ||
     300            (timings.res_800x600x75 && _ModeMatches(mode, 800, 600, 75)) ||
     301#if 0
     302            (timings.res_832x624x75 && _ModeMatches(mode, 832, 624, 75)) ||
     303            (timings.res_1024x768x87i && _ModeMatches(mode, 1024, 768, 87)) ||
     304#endif
     305            (timings.res_1024x768x60 && _ModeMatches(mode, 1024, 768, 60)) ||
     306            (timings.res_1024x768x70 && _ModeMatches(mode, 1024, 768, 70)) ||
     307            (timings.res_1024x768x75 && _ModeMatches(mode, 1024, 768, 75)) ||
     308            (timings.res_1152x870x75 && _ModeMatches(mode, 1152, 870, 75)) ||
     309            (timings.res_1280x1024x75 && _ModeMatches(mode, 1280, 1024, 75));   
     310}
    322311
    323 void
    324 ModeList::_AddBaseMode(uint16 width, uint16 height, uint32 refresh)
     312bool
     313ModeList::_ModeMatches(const display_mode& mode, uint16 width,
     314        uint16 height, uint32 refresh)
    325315{
    326     for (uint32 i = 0; i < kNumBaseModes; i++) {
    327         const display_mode& mode = kBaseModeList[i];
     316    // Add mode if width and height match, and the computed refresh rate of
     317    // the mode is within 1.2 percent of the refresh rate specified by the
     318    // caller.  Note that refresh rates computed from mode parameters is
     319    // not exact;  thus, the tolerance of 1.2% was obtained by testing the
     320    // various established modes that can be selected by the EDID info.
    328321
    329         // Add mode if width and height match, and the computed refresh rate of
    330         // the mode is within 1.2 percent of the refresh rate specified by the
    331         // caller.  Note that refresh rates computed from mode parameters is
    332         // not exact;  thus, the tolerance of 1.2% was obtained by testing the
    333         // various established modes that can be selected by the EDID info.
     322    return mode.timing.h_display == width && mode.timing.v_display == height
     323        && fabs(get_refresh_rate(mode) - refresh) < refresh * 0.012;
     324}
    334325
    335         if (mode.timing.h_display == width && mode.timing.v_display == height
    336             && fabs(get_refresh_rate(mode) - refresh) < refresh * 0.012) {
    337             _AddMode(&mode);
    338         }
     326bool
     327ModeList::_IsStandardMode(const display_mode& mode, const edid1_info* info)
     328{
     329    for (uint32 i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
     330        const edid1_std_timing std_timing = info->std_timing[i];
     331        if (std_timing.h_size <= 256)
     332            continue;
     333        if (_ModeMatches(mode, std_timing.h_size, std_timing.v_size,
     334                std_timing.refresh))
     335            return true;
    339336    }
     337    return false;
    340338}
    341339
     340bool
     341ModeList::_IsModeInRange(const display_mode& mode, const edid1_info* info)
     342{
     343    // As far as I understand:
     344    // vertical_freq = pixelclk / (htot * vtot)
     345    // hfreq = pixelclk / htot
     346    // => hfreq = vertical_freq * vtot
    342347
     348    float vertical_freq = get_refresh_rate(mode);
     349    //Since EDI uses kHz we do too.
     350    float horizontal_freq_kHz = vertical_freq * mode.timing.v_total / 1000;
     351    dprintf("Vertical freq: %fHz, Horizontal freq: %fkHz, Pixel clock %dkHz\n",
     352            vertical_freq, horizontal_freq_kHz, mode.timing.pixel_clock);
     353    for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
     354        if (info->detailed_monitor[i].monitor_desc_type != EDID1_MONITOR_RANGES)
     355            continue;
     356        const edid1_monitor_range& monitor_range
     357            = info->detailed_monitor[i].data.monitor_range;
     358       
     359        if (mode.timing.pixel_clock <= monitor_range.max_clock * 10000 &&
     360                vertical_freq >= monitor_range.min_v &&
     361                vertical_freq <= monitor_range.max_v &&
     362                horizontal_freq_kHz >= monitor_range.min_h &&
     363                horizontal_freq_kHz <= monitor_range.max_h )
     364            return true;
     365    }
     366    return false;
     367}
     368
     369
    343370bool
    344371ModeList::_MakeSpace(uint32 count)
    345372{
     
    361388bool
    362389ModeList::_AddMode(const display_mode* mode)
    363390{
    364     if (!_MakeSpace(1))
     391    if (!_MakeSpace(1)) {
     392        dprintf("Failed to add mode, no space: %dx%d@%fHz\n", mode->timing.h_display,
     393            mode->timing.v_display, get_refresh_rate(*mode));
    365394        return false;
     395    }
     396    dprintf("Mode added: %dx%d@%fHz\n", mode->timing.h_display,
     397        mode->timing.v_display, get_refresh_rate(*mode));
    366398
    367399    fModes[fCount++] = *mode;
    368400    return true;
     
    372404void
    373405ModeList::_RemoveModeAt(uint32 index)
    374406{
     407    dprintf("Removing mode: %dx%d@%fHz\n", fModes[index].timing.h_display,
     408        fModes[index].timing.v_display, get_refresh_rate(fModes[index]));
    375409    if (index < fCount - 1) {
    376410        memmove(&fModes[index], &fModes[index + 1],
    377411            (fCount - 1 - index) * sizeof(display_mode));
  • src/add-ons/accelerants/common/dump_edid.c

     
    5050
    5151    dprintf("Supported VESA Video Modes:\n");
    5252    if (edid->established_timing.res_720x400x70)
    53         dprintf("720x400@70\n");
     53        dprintf("720x400@70Hz\n");
    5454    if (edid->established_timing.res_720x400x88)
    55         dprintf("720x400@88\n");
     55        dprintf("720x400@88Hz\n");
    5656    if (edid->established_timing.res_640x480x60)
    57         dprintf("640x480@60\n");
     57        dprintf("640x480@60Hz\n");
    5858    if (edid->established_timing.res_640x480x67)
    59         dprintf("640x480x67\n");
     59        dprintf("640x480x67Hz\n");
    6060    if (edid->established_timing.res_640x480x72)
    61         dprintf("640x480x72\n");
     61        dprintf("640x480x72Hz\n");
    6262    if (edid->established_timing.res_640x480x75)
    63         dprintf("640x480x75\n");
     63        dprintf("640x480x75Hz\n");
    6464    if (edid->established_timing.res_800x600x56)
    65         dprintf("800x600@56\n");
     65        dprintf("800x600@56Hz\n");
    6666    if (edid->established_timing.res_800x600x60)
    67         dprintf("800x600@60\n");
     67        dprintf("800x600@60Hz\n");
    6868
    6969    if (edid->established_timing.res_800x600x72)
    70         dprintf("800x600@72\n");
     70        dprintf("800x600@72Hz\n");
    7171    if (edid->established_timing.res_800x600x75)
    72         dprintf("800x600@75\n");
     72        dprintf("800x600@75Hz\n");
    7373    if (edid->established_timing.res_832x624x75)
    74         dprintf("832x624@75\n");
     74        dprintf("832x624@75Hz\n");
    7575    if (edid->established_timing.res_1024x768x87i)
    76         dprintf("1024x768@87 interlaced\n");
     76        dprintf("1024x768@87Hz interlaced\n");
    7777    if (edid->established_timing.res_1024x768x60)
    78         dprintf("1024x768@60\n");
     78        dprintf("1024x768@60Hz\n");
    7979    if (edid->established_timing.res_1024x768x70)
    80         dprintf("1024x768@70\n");
     80        dprintf("1024x768@70Hz\n");
    8181    if (edid->established_timing.res_1024x768x75)
    82         dprintf("1024x768@75\n");
     82        dprintf("1024x768@75Hz\n");
    8383    if (edid->established_timing.res_1280x1024x75)
    84         dprintf("1280x1024@75\n");
     84        dprintf("1280x1024@75Hz\n");
    8585
    8686    if (edid->established_timing.res_1152x870x75)
    87         dprintf("1152x870@75\n");
     87        dprintf("1152x870@75Hz\n");
    8888
    8989    for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
    9090        edid1_detailed_monitor *monitor = &edid->detailed_monitor[i];
     
    149149            case EDID1_IS_DETAILED_TIMING:
    150150            {
    151151                edid1_detailed_timing *timing = &monitor->data.detailed_timing;
     152                dprintf("Additional Video Mode (%dx%d@%dHz):\n",
     153                    timing->h_active, timing->v_active,
     154                    (timing->pixel_clock * 10000
     155                    / (timing->h_active + timing->h_blank)
     156                    / (timing->v_active + timing->v_blank)));
     157                //Refreshrate = pixel clock in Hz / Htotal / Vtotal
    152158
    153                 dprintf("Additional Video Mode:\n");
    154159                dprintf("clock=%f MHz\n", timing->pixel_clock / 100.0);
    155160                dprintf("h: (%d, %d, %d, %d)\n",
    156161                    timing->h_active, timing->h_active + timing->h_sync_off,
  • src/add-ons/accelerants/vesa/mode.cpp

     
    7373    const color_space kVesaSpaces[] = {B_RGB32_LITTLE, B_RGB24_LITTLE,
    7474        B_RGB16_LITTLE, B_RGB15_LITTLE, B_CMAP8};
    7575
    76     gInfo->mode_list_area = create_display_modes("vesa modes", NULL, NULL, 0,
     76//  gInfo->mode_list_area = create_display_modes("vesa modes", NULL, NULL, 0,   
     77    gInfo->mode_list_area = create_display_modes("vesa modes", &(gInfo->shared_info->edid_info), NULL, 0,
    7778        kVesaSpaces, sizeof(kVesaSpaces) / sizeof(kVesaSpaces[0]),
    7879        is_mode_supported, &gInfo->mode_list, &gInfo->shared_info->mode_count);
    7980    if (gInfo->mode_list_area < B_OK)
     
    164165status_t
    165166vesa_get_edid_info(void *info, size_t size, uint32 *_version)
    166167{
    167     TRACE(("intel_get_edid_info()\n"));
     168    TRACE(("vesa_get_edid_info()\n"));
    168169
    169170    if (!gInfo->shared_info->has_edid)
    170171        return B_ERROR;