From 4191a211aaf50f4b491e1f574a759810a4e1f779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 12 Oct 2007 16:50:24 +0000 Subject: [PATCH] * 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 --- headers/os/add-ons/graphics/Accelerant.h | 4 + src/servers/app/ServerScreen.cpp | 18 +++- src/servers/app/ServerScreen.h | 3 +- src/servers/app/VirtualScreen.cpp | 3 +- .../app/drawing/AccelerantHWInterface.cpp | 99 +++++++++++++++++++ .../app/drawing/AccelerantHWInterface.h | 4 + src/servers/app/drawing/HWInterface.cpp | 14 +++ src/servers/app/drawing/HWInterface.h | 2 + src/servers/app/drawing/Jamfile | 1 + 9 files changed, 143 insertions(+), 5 deletions(-) diff --git a/headers/os/add-ons/graphics/Accelerant.h b/headers/os/add-ons/graphics/Accelerant.h index 68f6386846..519496514e 100644 --- a/headers/os/add-ons/graphics/Accelerant.h +++ b/headers/os/add-ons/graphics/Accelerant.h @@ -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); diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index 14e5ecc675..f29cc31de1 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -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; diff --git a/src/servers/app/ServerScreen.h b/src/servers/app/ServerScreen.h index 44656ad463..2dfc916019 100644 --- a/src/servers/app/ServerScreen.h +++ b/src/servers/app/ServerScreen.h @@ -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, diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index ba667a0e1c..eb39ce516a 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -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 diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index dcf4a1d89b..9dcb90acab 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -22,6 +22,7 @@ #include "ServerProtocol.h" #include "SystemPalette.h" +#include #include #include @@ -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() { diff --git a/src/servers/app/drawing/AccelerantHWInterface.h b/src/servers/app/drawing/AccelerantHWInterface.h index 7fe65380ac..82296afd6e 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.h +++ b/src/servers/app/drawing/AccelerantHWInterface.h @@ -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; diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 6133670c73..927c1561b2 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -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 - diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index 928c4f32e6..8f61be0230 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -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; diff --git a/src/servers/app/drawing/Jamfile b/src/servers/app/drawing/Jamfile index 3693519e4d..2c814633c0 100644 --- a/src/servers/app/drawing/Jamfile +++ b/src/servers/app/drawing/Jamfile @@ -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 ] ;