* Started accelerant extension to be able to get the preferred mode from

the accelerant, as well as its EDID info. B_GET_PREFERRED_DISPLAY_MODE and
  B_GET_EDID_INFO are both optional. The preferred mode will be taken from the
  EDID info if only the latter hook is implemented, or the former returned an
  error.
* Currently, the app_server should correctly set the preferred mode on start,
  but no accelerant supports that yet, so it's not really tested.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22520 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-12 16:50:24 +00:00
parent e8cae7424e
commit 4191a211aa
9 changed files with 143 additions and 5 deletions
+4
View File
@@ -41,6 +41,8 @@ enum {
B_DPMS_CAPABILITIES, /* required if driver supports DPMS */
B_DPMS_MODE, /* required if driver supports DPMS */
B_SET_DPMS_MODE, /* required if driver supports DPMS */
B_GET_PREFERRED_DISPLAY_MODE, /* optional */
B_GET_EDID_INFO, /* optional */
/* cursor managment */
B_MOVE_CURSOR = 0x200, /* optional */
@@ -213,6 +215,8 @@ typedef void (*set_indexed_colors)(uint count, uint8 first, uint8 *color_data, u
typedef uint32 (*dpms_capabilities)(void);
typedef uint32 (*dpms_mode)(void);
typedef status_t (*set_dpms_mode)(uint32 dpms_flags);
typedef status_t (*get_preferred_display_mode)(display_mode *preferredMode);
typedef status_t (*get_edid_info)(void *info, uint32 size, uint32 *_version);
typedef sem_id (*accelerant_retrace_semaphore)(void);
typedef status_t (*set_cursor_shape)(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
+15 -3
View File
@@ -86,7 +86,7 @@ Screen::Shutdown()
status_t
Screen::SetMode(display_mode mode, bool makeDefault)
Screen::SetMode(const display_mode& mode, bool makeDefault)
{
gBitmapManager->SuspendOverlays();
@@ -140,6 +140,18 @@ Screen::SetMode(uint16 width, uint16 height, uint32 colorspace,
}
status_t
Screen::SetPreferredMode()
{
display_mode mode;
status_t status = fHWInterface->GetPreferredMode(&mode);
if (status < B_OK)
return status;
return SetMode(mode, false);
}
void
Screen::GetMode(display_mode* mode) const
{
@@ -149,7 +161,7 @@ Screen::GetMode(display_mode* mode) const
void
Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace,
float &frequency) const
float &frequency) const
{
display_mode mode;
fHWInterface->GetMode(&mode);
@@ -183,7 +195,7 @@ Screen::ColorSpace() const
status_t
Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace,
float frequency, display_mode* mode) const
float frequency, display_mode* mode) const
{
display_mode* modes = NULL;
uint32 count;
+2 -1
View File
@@ -30,10 +30,11 @@ class Screen {
int32 ID() const { return fID; }
status_t SetMode(display_mode mode, bool makeDefault);
status_t SetMode(const display_mode& mode, bool makeDefault);
status_t SetMode(uint16 width, uint16 height,
uint32 colorspace, float frequency,
bool makeDefault);
status_t SetPreferredMode();
void GetMode(display_mode* mode) const;
void GetMode(uint16 &width,
+2 -1
View File
@@ -133,7 +133,8 @@ VirtualScreen::AddScreen(Screen* screen)
}
if (status < B_OK) {
// TODO: more intelligent standard mode (monitor preference, desktop default, ...)
screen->SetMode(800, 600, B_RGB32, 60.f, false);
if (screen->SetPreferredMode() != B_OK)
screen->SetMode(800, 600, B_RGB32, 60.f, false);
}
// TODO: this works only for single screen configurations
@@ -22,6 +22,7 @@
#include "ServerProtocol.h"
#include "SystemPalette.h"
#include <edid.h>
#include <safemode.h>
#include <Accelerant.h>
@@ -349,6 +350,8 @@ AccelerantHWInterface::_SetupDefaultHooks()
// optional
fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
fAccGetPreferredDisplayMode = (get_preferred_display_mode)fAccelerantHook(B_GET_PREFERRED_DISPLAY_MODE, NULL);
fAccGetEDIDInfo = (get_edid_info)fAccelerantHook(B_GET_EDID_INFO, NULL);
// cursor
fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
@@ -716,6 +719,102 @@ AccelerantHWInterface::ProposeMode(display_mode *candidate, const display_mode *
}
status_t
AccelerantHWInterface::GetPreferredMode(display_mode* mode)
{
status_t status = B_NOT_SUPPORTED;
if (fAccGetPreferredDisplayMode != NULL) {
status = fAccGetPreferredDisplayMode(mode);
if (status == B_OK)
return B_OK;
}
if (fAccGetEDIDInfo != NULL) {
edid1_info info;
uint32 version;
status_t status = fAccGetEDIDInfo(&info, sizeof(info), &version);
if (status < B_OK)
return status;
if (version != EDID_VERSION_1)
return B_NOT_SUPPORTED;
status = B_ERROR;
// 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 most list
// TODO: handle sync and flags correctly!
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;
}
}
return status;
}
status_t
AccelerantHWInterface::GetMonitorInfo(BString& name, BString& serial)
{
if (fAccGetEDIDInfo == NULL)
return B_NOT_SUPPORTED;
edid1_info info;
uint32 version;
status_t status = fAccGetEDIDInfo(&info, sizeof(info), &version);
if (status < B_OK)
return status;
if (version != EDID_VERSION_1)
return B_NOT_SUPPORTED;
uint32 found = 0;
for (uint32 i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
edid1_detailed_monitor *monitor = &info.detailed_monitor[i];
switch (monitor->monitor_desc_type) {
case EDID1_SERIAL_NUMBER:
serial.SetTo(monitor->data.serial_number);
found++;
break;
case EDID1_MONITOR_NAME:
name.SetTo(monitor->data.monitor_name);
found++;
break;
default:
break;
}
}
return found > 0 ? B_OK : B_NAME_NOT_FOUND;
}
sem_id
AccelerantHWInterface::RetraceSemaphore()
{
@@ -41,6 +41,8 @@ public:
virtual status_t ProposeMode(display_mode *candidate,
const display_mode *low,
const display_mode *high);
virtual status_t GetPreferredMode(display_mode* mode);
virtual status_t GetMonitorInfo(BString& name, BString& serial);
virtual sem_id RetraceSemaphore();
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT);
@@ -128,6 +130,8 @@ private:
// optional accelerant hooks
get_timing_constraints fAccGetTimingConstraints;
propose_display_mode fAccProposeDisplayMode;
get_preferred_display_mode fAccGetPreferredDisplayMode;
get_edid_info fAccGetEDIDInfo;
fill_rectangle fAccFillRect;
invert_rectangle fAccInvertRect;
screen_to_screen_blit fAccScreenBlit;
+14
View File
@@ -89,6 +89,20 @@ HWInterface::GetDriverPath(BString &path)
}
status_t
HWInterface::GetPreferredMode(display_mode* mode)
{
return B_NOT_SUPPORTED;
}
status_t
HWInterface::GetMonitorInfo(BString& name, BString& serial)
{
return B_NOT_SUPPORTED;
}
// #pragma mark -
+2
View File
@@ -77,6 +77,8 @@ class HWInterface : protected MultiLocker {
virtual status_t ProposeMode(display_mode *candidate,
const display_mode *low,
const display_mode *high) = 0;
virtual status_t GetPreferredMode(display_mode* mode);
virtual status_t GetMonitorInfo(BString& name, BString& serial);
virtual sem_id RetraceSemaphore() = 0;
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT) = 0;
+1
View File
@@ -2,6 +2,7 @@ SubDir HAIKU_TOP src servers app drawing ;
UseLibraryHeaders agg ;
UsePrivateHeaders app graphics kernel interface shared ;
UsePrivateHeaders [ FDirName graphics common ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;