Changed the way a valid display mode is chosen:
* instead a fitting display mode from the list, and having a fallback "ignore frequency" mode, the closest available screen mode is now chosen. * The display_mode's frequency of the mode found is now adapted to the requested frequency, as it's done in the screen preferences panel. * Removed the fallback 8 bit mode for now; instead, we should have _FindMode() deviate from the color space as well, if needed. * This all fixes the problem that you suddenly had an (still badly supported) 8 bit mode after reboot, instead of the one originally chosen in the screen mode preferences. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16558 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,6 +22,22 @@
|
|||||||
#include "ServerScreen.h"
|
#include "ServerScreen.h"
|
||||||
|
|
||||||
|
|
||||||
|
static float
|
||||||
|
get_mode_frequency(const display_mode& mode)
|
||||||
|
{
|
||||||
|
// Taken from Screen preferences
|
||||||
|
float timing = float(mode.timing.h_total * mode.timing.v_total);
|
||||||
|
if (timing == 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
return rint(10 * float(mode.timing.pixel_clock * 1000)
|
||||||
|
/ timing) / 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
Screen::Screen(::HWInterface *interface, int32 id)
|
Screen::Screen(::HWInterface *interface, int32 id)
|
||||||
: fID(id),
|
: fID(id),
|
||||||
fDriver(interface ? new DrawingEngine(interface) : NULL),
|
fDriver(interface ? new DrawingEngine(interface) : NULL),
|
||||||
@@ -97,8 +113,25 @@ Screen::SetMode(uint16 width, uint16 height, uint32 colorspace,
|
|||||||
status = _FindMode(640, 480, B_CMAP8, 60.0, &mode);
|
status = _FindMode(640, 480, B_CMAP8, 60.0, &mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status >= B_OK)
|
if (status >= B_OK) {
|
||||||
|
float modeFrequency = get_mode_frequency(mode);
|
||||||
|
display_mode originalMode = mode;
|
||||||
|
bool adjusted = false;
|
||||||
|
|
||||||
|
if (modeFrequency != frequency) {
|
||||||
|
// adjust timing to fit the requested frequency if needed
|
||||||
|
// (taken from Screen preferences application)
|
||||||
|
mode.timing.pixel_clock = ((uint32)mode.timing.h_total
|
||||||
|
* mode.timing.v_total / 10 * int32(frequency * 10)) / 1000;
|
||||||
|
adjusted = true;
|
||||||
|
}
|
||||||
|
|
||||||
status = SetMode(mode, makeDefault);
|
status = SetMode(mode, makeDefault);
|
||||||
|
if (status < B_OK) {
|
||||||
|
// try again with the unchanged mode
|
||||||
|
status = SetMode(originalMode, makeDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -121,8 +154,7 @@ Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace,
|
|||||||
width = mode.virtual_width;
|
width = mode.virtual_width;
|
||||||
height = mode.virtual_height;
|
height = mode.virtual_height;
|
||||||
colorspace = mode.space;
|
colorspace = mode.space;
|
||||||
frequency = mode.timing.pixel_clock * 1000.f
|
frequency = get_mode_frequency(mode);
|
||||||
/ (mode.timing.h_total * mode.timing.v_total);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -150,10 +182,10 @@ status_t
|
|||||||
Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace,
|
Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace,
|
||||||
float frequency, display_mode* mode) const
|
float frequency, display_mode* mode) const
|
||||||
{
|
{
|
||||||
display_mode* dm = NULL;
|
display_mode* modes = NULL;
|
||||||
uint32 count;
|
uint32 count;
|
||||||
|
|
||||||
status_t status = fHWInterface->GetModeList(&dm, &count);
|
status_t status = fHWInterface->GetModeList(&modes, &count);
|
||||||
if (status < B_OK || count <= 0) {
|
if (status < B_OK || count <= 0) {
|
||||||
// We've run into quite a problem here! This is a function which is a requirement
|
// We've run into quite a problem here! This is a function which is a requirement
|
||||||
// for a graphics module. The best thing that we can hope for is 640x480x8 without
|
// for a graphics module. The best thing that we can hope for is 640x480x8 without
|
||||||
@@ -166,61 +198,55 @@ Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST
|
int32 index = _FindMode(modes, count, width, height, colorspace, frequency);
|
||||||
int32 index = _FindMode(dm, count, width, height, colorspace, frequency);
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
fprintf(stderr, "mode not found (%d, %d, %f) -> ignoring frequency and using B_CMAP8!\n", width, height, frequency);
|
fprintf(stderr, "mode not found (%d, %d, %f) -> using first mode from list!\n",
|
||||||
index = _FindMode(dm, count, width, height, B_CMAP8, frequency, true);
|
width, height, frequency);
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Ignore frequency in test mode
|
|
||||||
int32 index = _FindMode(dm, count, width, height, colorspace, frequency, true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
fprintf(stderr, "mode not found (%d, %d, %f) -> using first mode from list!\n", width, height, frequency);
|
|
||||||
// fallback to first mode from list - TODO: ?!?
|
// fallback to first mode from list - TODO: ?!?
|
||||||
// NOTE: count > 0 is checked above
|
// NOTE: count > 0 is checked above
|
||||||
*mode = dm[0];
|
*mode = modes[0];
|
||||||
} else {
|
} else {
|
||||||
*mode = dm[index];
|
*mode = modes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] dm;
|
delete[] modes;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Returns the mode that matches the given criteria. The frequency
|
||||||
|
doesn't have to match, though - the closest one found is used.
|
||||||
|
*/
|
||||||
int32
|
int32
|
||||||
Screen::_FindMode(const display_mode* dm, uint32 count,
|
Screen::_FindMode(const display_mode* modes, uint32 count,
|
||||||
uint16 width, uint16 height, uint32 colorspace,
|
uint16 width, uint16 height, uint32 colorspace,
|
||||||
float frequency, bool ignoreFrequency) const
|
float frequency) const
|
||||||
{
|
{
|
||||||
|
// we always try to choose the mode with the closest frequency
|
||||||
|
float bestFrequencyDiff = 0.0f;
|
||||||
int32 index = -1;
|
int32 index = -1;
|
||||||
|
|
||||||
for (uint32 i = 0; i < count; i++) {
|
for (uint32 i = 0; i < count; i++) {
|
||||||
if (dm[i].virtual_width == width
|
if (modes[i].virtual_width == width
|
||||||
&& dm[i].virtual_height == height
|
&& modes[i].virtual_height == height
|
||||||
&& dm[i].space == colorspace) {
|
&& modes[i].space == colorspace) {
|
||||||
if (!ignoreFrequency) {
|
// we have found a mode with the correct width, height and format
|
||||||
// we have found a mode with the correct width, height and format
|
// now see if the frequency matches
|
||||||
// now see if the frequency matches (don't be too picky)
|
float modeFrequency = get_mode_frequency(modes[i]);
|
||||||
float modeFrequency = 0.0;
|
float frequencyDiff = fabs(modeFrequency - frequency);
|
||||||
float t = dm[i].timing.h_total * dm[i].timing.v_total;
|
|
||||||
if (t != 0.0)
|
if (index == -1 || bestFrequencyDiff > frequencyDiff) {
|
||||||
modeFrequency = dm[i].timing.pixel_clock * 1000.f / t;
|
|
||||||
|
|
||||||
if (int(modeFrequency/* * 10.0*/ + 0.5) == int(frequency/* * 10.0*/ + 0.5)) {
|
|
||||||
index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ignore frequency
|
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
if (frequencyDiff == 0.0f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bestFrequencyDiff = frequencyDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,8 @@ class Screen {
|
|||||||
display_mode* mode) const;
|
display_mode* mode) const;
|
||||||
|
|
||||||
int32 _FindMode(const display_mode* modeList,
|
int32 _FindMode(const display_mode* modeList,
|
||||||
uint32 count, uint16 width, uint16 height, uint32 colorspace,
|
uint32 count, uint16 width, uint16 height,
|
||||||
float frequency,
|
uint32 colorspace, float frequency) const;
|
||||||
bool ignoreFrequency = false) const;
|
|
||||||
|
|
||||||
int32 fID;
|
int32 fID;
|
||||||
DrawingEngine* fDriver;
|
DrawingEngine* fDriver;
|
||||||
|
|||||||
Reference in New Issue
Block a user