📄 proposedisplaymode.c
字号:
SHOW_FLOW0( 4, "out of virtual horizontal limits" ); result = B_BAD_VALUE; } // we may have to use a larger virtual width - // take care of that when calculating memory consumption eff_virtual_width = Radeon_RoundVWidth( target->virtual_height, bpp ); // calculate rowbytes after we've nailed the virtual width row_bytes = eff_virtual_width * bpp; // if we haven't enough memory, reduce virtual height // (some programs create back buffers by asking for a huge // virtual screen; they actually want to know what is possible // to adjust the number of back buffers according to amount // of graphics memory) // careful about additionally required memory: // 1024 bytes are needed for hardware cursor if ((row_bytes * target->virtual_height) > si->memory[mt_local].size - 1024 ) target->virtual_height = (si->memory[mt_local].size - 1024) / row_bytes; // make sure we haven't shrunk virtual height too much if (target->virtual_height < target->timing.v_display) { SHOW_ERROR( 2, "not enough memory for this mode (could show only %d of %d lines)", target->virtual_height, target->timing.v_display ); return B_ERROR; } if (target->virtual_height < low->virtual_height || target->virtual_height > high->virtual_height ) { SHOW_FLOW0( 4, "out of virtual vertical limits" ); result = B_BAD_VALUE; } // we ignore flags - in the sample driver, they did the same, // so why bother? return result;}// public function: return number of display modes returned by get_mode_listuint32 ACCELERANT_MODE_COUNT( void ){ return ai->si->mode_count;}// public function: get list of standard display modes// dm - modes are copied to here (to be allocated by caller)status_t GET_MODE_LIST( display_mode *dm ) { memcpy( dm, ai->mode_list, ai->si->mode_count * sizeof(display_mode) ); return B_OK;}static const color_space spaces[4] = { B_CMAP8, B_RGB15_LITTLE, B_RGB16_LITTLE, B_RGB32_LITTLE};// if given mode is possible on this card, add it to standard mode list// mode - mode to add (colourspace is ignored but replaced // by each officially supported colour space in turn)// ignore_timing - don't care if timing has to be modified to make mode valid // (used for fp modes - we just want their resolution)static void checkAndAddMode( accelerator_info *ai, const display_mode *mode, bool ignore_timing ){ shared_info *si = ai->si; uint i; display_mode low, high; uint32 pix_clk_range; display_mode *dst; if( ignore_timing ) { // for fp modes: don't add mode if its resolution is already in official mode list for( i = 0; i < si->mode_count; ++i ) { if( ai->mode_list[i].timing.h_display == mode->timing.h_display && ai->mode_list[i].timing.v_display == mode->timing.v_display && ai->mode_list[i].virtual_width == mode->virtual_width && ai->mode_list[i].virtual_height == mode->virtual_height ) return; } } // set ranges for acceptable values low = high = *mode; // range is 6.25% of default clock: arbitrarily picked pix_clk_range = low.timing.pixel_clock >> 5; low.timing.pixel_clock -= pix_clk_range; high.timing.pixel_clock += pix_clk_range; if( ignore_timing ) { low.timing.h_total = 0; low.timing.h_sync_start = 0; low.timing.h_sync_end = 0; low.timing.v_total = 0; low.timing.v_sync_start = 0; low.timing.v_sync_end = 0; high.timing.h_total = 0xffff; high.timing.h_sync_start = 0xffff; high.timing.h_sync_end = 0xffff; high.timing.v_total = 0xffff; high.timing.v_sync_start = 0xffff; high.timing.v_sync_end = 0xffff; } dst = &ai->mode_list[si->mode_count]; // iterator through all colour spaces for( i = 0; i < (sizeof(spaces) / sizeof(color_space)); i++ ) { // check whether first port can handle it *dst = *mode; dst->space = low.space = high.space = spaces[i]; if( Radeon_ProposeDisplayMode( si, &si->crtc[0], &si->pll, dst, &low, &high ) == B_OK ) { si->mode_count++; ++dst; } else { // it can't, so try second port *dst = *mode; dst->space = spaces[i]; if( Radeon_ProposeDisplayMode( si, &si->crtc[1], &si->pll, dst, &low, &high ) == B_OK ) { si->mode_count++; ++dst; } else SHOW_FLOW( 4, "%ld, %ld not supported", dst->virtual_width, dst->virtual_height ); } }}// add display mode including span mode variations to offical liststatic void checkAndAddMultiMode( accelerator_info *ai, const display_mode *mode, bool ignore_timing ){ display_mode wide_mode; SHOW_FLOW( 4, "%ld, %ld", mode->virtual_width, mode->virtual_height ); // plain mode checkAndAddMode( ai, mode, ignore_timing ); // double width mode wide_mode = *mode; wide_mode.virtual_width *= 2; wide_mode.flags |= B_SCROLL; checkAndAddMode( ai, &wide_mode, ignore_timing ); // double height mode wide_mode = *mode; wide_mode.virtual_height *= 2; wide_mode.flags |= B_SCROLL; checkAndAddMode( ai, &wide_mode, ignore_timing );}// add display mode of flat panel to official liststatic void addFPMode( accelerator_info *ai ){ shared_info *si = ai->si; fp_info *fp_info = &si->flatpanels[0]; if( (ai->vc->connected_displays & (dd_dvi | dd_lvds)) != 0 ) { display_mode mode; mode.virtual_width = mode.timing.h_display = fp_info->panel_xres; mode.virtual_height = mode.timing.v_display = fp_info->panel_yres; mode.timing.h_total = mode.timing.h_display + fp_info->h_blank; mode.timing.h_sync_start = mode.timing.h_display + fp_info->h_over_plus; mode.timing.h_sync_end = mode.timing.h_sync_start + fp_info->h_sync_width; mode.timing.v_total = mode.timing.v_display + fp_info->v_blank; mode.timing.v_sync_start = mode.timing.v_display + fp_info->v_over_plus; mode.timing.v_sync_end = mode.timing.v_sync_start + fp_info->v_sync_width; mode.timing.pixel_clock = fp_info->dot_clock; // if we have no pixel clock, assume 60 Hz // (as we don't program PLL in this case, it doesn't matter // if it's wrong, we just want this resolution in the mode list) if( mode.timing.pixel_clock == 0 ) { // devide by 1000 as clock is in kHz mode.timing.pixel_clock = ((uint32)mode.timing.h_total * mode.timing.v_total * 60) / 1000; } mode.flags = MODE_FLAGS; mode.h_display_start = 0; mode.v_display_start = 0; SHOW_FLOW( 2, "H: %4d %4d %4d %4d (v=%4d)", mode.timing.h_display, mode.timing.h_sync_start, mode.timing.h_sync_end, mode.timing.h_total, mode.virtual_width ); SHOW_FLOW( 2, "V: %4d %4d %4d %4d (h=%4d)", mode.timing.v_display, mode.timing.v_sync_start, mode.timing.v_sync_end, mode.timing.v_total, mode.virtual_height ); SHOW_FLOW( 2, "clk: %ld", mode.timing.pixel_clock ); // flat panels seem to have strange timings; // as we ignore user-supplied timing for FPs anyway, // the mode can (and usually has to) be modified to be // used for normal CRTs checkAndAddMultiMode( ai, &mode, true ); }}// create list of officially supported modesstatus_t Radeon_CreateModeList( shared_info *si ){ size_t max_size; uint i; uint max_num_modes; // maximum number of official modes: // (predefined-modes + fp-modes) * number-of-colour-spaces * number-of-(non)-span-modes max_num_modes = ((sizeof( base_mode_list ) / sizeof( base_mode_list[0] ) + 1) * 4 * 3); max_size = (max_num_modes * sizeof(display_mode) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1); si->mode_list_area = create_area("Radeon accelerant mode info", (void **)&ai->mode_list, B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); if( si->mode_list_area < B_OK ) return si->mode_list_area; si->mode_count = 0; // check standard modes for( i = 0; i < sizeof( base_mode_list ) / sizeof( base_mode_list[0] ); i++ ) checkAndAddMultiMode( ai, &base_mode_list[i], false ); // plus fp mode addFPMode( ai ); // as we've created the list ourself, we don't clone it ai->mode_list_area = si->mode_list_area; return B_OK;}// cleanup official display mode listvoid Radeon_DisposeModeList( shared_info *si ){ delete_area( si->mode_list_area );}// public function: wraps for internal propose_display_modestatus_t PROPOSE_DISPLAY_MODE( display_mode *target, const display_mode *low, const display_mode *high ){ virtual_card *vc = ai->vc; shared_info *si = ai->si; status_t result1, result2; bool isTunneled; status_t result; display_mode tmp_target; // check whether we got a tunneled settings command result = Radeon_CheckMultiMonTunnel( vc, target, low, high, &isTunneled ); if( isTunneled ) return result; // check how many heads are needed by target mode tmp_target = *target; Radeon_DetectMultiMode( vc, &tmp_target ); // before checking multi-monitor mode, we must define a monitor signal routing // TBD: this may be called a bit too frequently if someone scans available modes // via successive Propose_Display_Mode; though this doesn't do any _real_ harm // it leads to annoying distortions on screen!! Radeon_DetectDisplays( ai); Radeon_SetupDefaultMonitorRouting( ai, Radeon_DifferentPorts( &tmp_target ), vc->use_laptop_panel ); // transform to multi-screen mode first Radeon_DetectMultiMode( vc, target ); Radeon_VerifyMultiMode( vc, si, target ); SHOW_FLOW0( 3, "wished:" ); SHOW_FLOW( 3, "H: %4d %4d %4d %4d (v=%4d)", target->timing.h_display, target->timing.h_sync_start, target->timing.h_sync_end, target->timing.h_total, target->virtual_width ); SHOW_FLOW( 3, "V: %4d %4d %4d %4d (h=%4d)", target->timing.v_display, target->timing.v_sync_start, target->timing.v_sync_end, target->timing.v_total, target->virtual_height ); SHOW_FLOW( 3, "clk: %ld", target->timing.pixel_clock ); // we must assure that each ProposeMode call doesn't tweak the mode in // a way that it cannot be handled by the other port anymore result1 = Radeon_ProposeDisplayMode( si, &si->crtc[0], &si->pll, target, low, high ); if( result1 == B_ERROR ) return B_ERROR; if( Radeon_NeedsSecondPort( target )) { // if both ports are used, make sure both can handle mode result2 = Radeon_ProposeDisplayMode( si, &si->crtc[1], &si->pll, target, low, high ); if( result2 == B_ERROR ) return B_ERROR; } else { result2 = B_OK; } SHOW_INFO0( 4, "got:" ); SHOW_INFO( 4, "H: %4d %4d %4d %4d (v=%4d)", target->timing.h_display, target->timing.h_sync_start, target->timing.h_sync_end, target->timing.h_total, target->virtual_width ); SHOW_INFO( 4, "V: %4d %4d %4d %4d (h=%4d)", target->timing.v_display, target->timing.v_sync_start, target->timing.v_sync_end, target->timing.v_total, target->virtual_height ); SHOW_INFO( 4, "clk: %ld", target->timing.pixel_clock ); Radeon_HideMultiMode( vc, target ); if( result1 == B_OK && result2 == B_OK ) return B_OK; else return B_BAD_VALUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -