* Factored out a _FindBestMethod() from _SetFallbackMode() - it now also takes
the timing of the original mode into account (I haven't tested if the computed score makes that much sense, though). * GetPreferredMode() now also works correctly for EDID data): it now returns the correct status, and also constructs the mode correctly. Furthermore, it will now search for the mode in the mode list, instead of using that mode directly (so that it can take hardware limits into account). * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22778 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9121620d41
commit
b289dec88c
@ -398,6 +398,40 @@ AccelerantHWInterface::Shutdown()
|
||||
}
|
||||
|
||||
|
||||
/*! Finds the mode in the mode list that is closest to the mode specified.
|
||||
As long as the mode list is not empty, this method will always succeed.
|
||||
*/
|
||||
status_t
|
||||
AccelerantHWInterface::_FindBestMode(const display_mode& compareMode,
|
||||
display_mode& modeFound) const
|
||||
{
|
||||
int32 bestDiff = 0;
|
||||
int32 bestIndex = -1;
|
||||
for (int32 i = 0; i < fModeCount; i++) {
|
||||
display_mode& mode = fModeList[i];
|
||||
|
||||
// compute some random equality score
|
||||
int32 diff = 1000 * abs(mode.timing.h_display - compareMode.timing.h_display)
|
||||
+ 1000 * abs(mode.timing.v_display - compareMode.timing.v_display)
|
||||
+ abs(mode.timing.h_total * mode.timing.v_total
|
||||
- compareMode.timing.h_total * compareMode.timing.v_total) / 100
|
||||
+ abs(mode.timing.pixel_clock - compareMode.timing.pixel_clock) / 100
|
||||
+ 100000 * abs(mode.space - compareMode.space);
|
||||
|
||||
if (bestIndex == -1 || diff < bestDiff) {
|
||||
bestDiff = diff;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestIndex < 0)
|
||||
return B_ERROR;
|
||||
|
||||
modeFound = fModeList[bestIndex];
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
This method is used for the initial mode set only - because that one
|
||||
should really not fail.
|
||||
@ -412,38 +446,17 @@ AccelerantHWInterface::_SetFallbackMode(display_mode& newMode) const
|
||||
// At first, we search the closest display mode from the list of
|
||||
// supported modes - if that fails, we just take one
|
||||
|
||||
int32 bestDiff = 0;
|
||||
int32 bestIndex = -1;
|
||||
for (int32 i = 0; i < fModeCount; i++) {
|
||||
display_mode& mode = fModeList[i];
|
||||
|
||||
// compute some random equality score
|
||||
int32 diff = abs(mode.virtual_width - newMode.virtual_width)
|
||||
+ abs(mode.virtual_height - newMode.virtual_height)
|
||||
+ 10 * abs(mode.space - newMode.space);
|
||||
|
||||
if (bestIndex == -1 || diff < bestDiff) {
|
||||
bestDiff = diff;
|
||||
bestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestIndex < 0)
|
||||
return B_ERROR;
|
||||
|
||||
newMode = fModeList[bestIndex];
|
||||
status_t status = fAccSetDisplayMode(&newMode);
|
||||
if (status == B_OK)
|
||||
if (_FindBestMode(newMode, newMode) == B_OK
|
||||
&& fAccSetDisplayMode(&newMode) == B_OK)
|
||||
return B_OK;
|
||||
|
||||
// That failed as well, this looks like a bug in the graphics
|
||||
// driver, but we have to try to be as forgiving as possible
|
||||
// here - just take the first mode that fits!
|
||||
// here - just take the first mode that works!
|
||||
|
||||
for (int32 i = 0; i < fModeCount; i++) {
|
||||
newMode = fModeList[i];
|
||||
status = fAccSetDisplayMode(&newMode);
|
||||
if (status == B_OK)
|
||||
if (fAccSetDisplayMode(&newMode) == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -709,32 +722,32 @@ AccelerantHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
|
||||
|
||||
|
||||
status_t
|
||||
AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
|
||||
AccelerantHWInterface::ProposeMode(display_mode *candidate,
|
||||
const display_mode *_low, const display_mode *_high)
|
||||
{
|
||||
AutoReadLocker _(this);
|
||||
|
||||
if (!candidate || !low || !high)
|
||||
if (candidate == NULL || _low == NULL || _high == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!fAccProposeDisplayMode)
|
||||
if (fAccProposeDisplayMode == NULL)
|
||||
return B_UNSUPPORTED;
|
||||
|
||||
|
||||
// avoid const issues
|
||||
display_mode this_high, this_low;
|
||||
this_high = *high;
|
||||
this_low = *low;
|
||||
|
||||
return fAccProposeDisplayMode(candidate, &this_low, &this_high);
|
||||
display_mode high, low;
|
||||
high = *_high;
|
||||
low = *_low;
|
||||
|
||||
return fAccProposeDisplayMode(candidate, &low, &high);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AccelerantHWInterface::GetPreferredMode(display_mode* mode)
|
||||
AccelerantHWInterface::GetPreferredMode(display_mode* preferredMode)
|
||||
{
|
||||
status_t status = B_NOT_SUPPORTED;
|
||||
|
||||
if (fAccGetPreferredDisplayMode != NULL) {
|
||||
status = fAccGetPreferredDisplayMode(mode);
|
||||
status = fAccGetPreferredDisplayMode(preferredMode);
|
||||
if (status == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
@ -742,7 +755,7 @@ AccelerantHWInterface::GetPreferredMode(display_mode* mode)
|
||||
if (fAccGetEDIDInfo != NULL) {
|
||||
edid1_info info;
|
||||
uint32 version;
|
||||
status_t status = fAccGetEDIDInfo(&info, sizeof(info), &version);
|
||||
status = fAccGetEDIDInfo(&info, sizeof(info), &version);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
if (version != EDID_VERSION_1)
|
||||
@ -751,34 +764,30 @@ AccelerantHWInterface::GetPreferredMode(display_mode* mode)
|
||||
if (fModeList == NULL)
|
||||
_UpdateModeList();
|
||||
|
||||
status = B_NOT_SUPPORTED;
|
||||
|
||||
// find preferred mode from EDID info
|
||||
for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
|
||||
if (info.detailed_monitor[i].monitor_desc_type != EDID1_IS_DETAILED_TIMING)
|
||||
continue;
|
||||
|
||||
// TODO: we could also just look for this mode in the mode list
|
||||
// TODO: handle sync and flags correctly!
|
||||
// construct basic mode and find it in the mode list
|
||||
const edid1_detailed_timing& timing = info.detailed_monitor[i].data.detailed_timing;
|
||||
mode->timing.pixel_clock = timing.pixel_clock * 10;
|
||||
mode->timing.h_display = timing.h_active;
|
||||
mode->timing.h_sync_start = timing.h_blank;
|
||||
mode->timing.h_sync_end = timing.h_sync_off;
|
||||
mode->timing.h_total = timing.h_sync_width;
|
||||
mode->timing.v_display = timing.v_active;
|
||||
mode->timing.v_sync_start = timing.v_blank;
|
||||
mode->timing.v_sync_end = timing.v_sync_off;
|
||||
mode->timing.v_total = timing.v_sync_width;
|
||||
mode->timing.flags = B_POSITIVE_HSYNC | B_POSITIVE_VSYNC;
|
||||
mode->space = B_RGB32;
|
||||
mode->virtual_width = timing.h_active;
|
||||
mode->virtual_height = timing.v_active;
|
||||
mode->h_display_start = 0;
|
||||
mode->v_display_start = 0;
|
||||
if (fModeCount > 0)
|
||||
mode->flags = fModeList[0].flags;
|
||||
else
|
||||
mode->flags = B_8_BIT_DAC | B_PARALLEL_ACCESS;
|
||||
status = B_OK;
|
||||
display_mode mode;
|
||||
mode.timing.pixel_clock = timing.pixel_clock * 10;
|
||||
mode.timing.h_display = timing.h_active;
|
||||
mode.timing.h_sync_start = timing.h_active + timing.h_sync_off;
|
||||
mode.timing.h_sync_end = mode.timing.h_sync_start + timing.h_sync_width;
|
||||
mode.timing.h_total = timing.h_active + timing.h_blank;
|
||||
mode.timing.v_display = timing.v_active;
|
||||
mode.timing.v_sync_start = timing.v_active + timing.v_sync_off;
|
||||
mode.timing.v_sync_end = mode.timing.v_sync_start + timing.v_sync_width;
|
||||
mode.timing.v_total = timing.v_active + timing.v_blank;
|
||||
mode.space = B_RGB32;
|
||||
mode.virtual_width = timing.h_active;
|
||||
mode.virtual_height = timing.v_active;
|
||||
|
||||
status = _FindBestMode(mode, *preferredMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,8 @@ private:
|
||||
void _RegionToRectParams(/*const*/ BRegion* region,
|
||||
uint32* count) const;
|
||||
uint32 _NativeColor(const rgb_color& color) const;
|
||||
status_t _FindBestMode(const display_mode& compareMode,
|
||||
display_mode& modeFound) const;
|
||||
status_t _SetFallbackMode(display_mode& mode) const;
|
||||
void _SetSystemPalette();
|
||||
void _SetGrayscalePalette();
|
||||
|
Loading…
Reference in New Issue
Block a user