From b9eacd390dbdf776561062b324dab4c6f5a0dc80 Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Mon, 12 Jun 2017 04:51:23 +1200 Subject: [PATCH] vesa: fold framebuffer driver into vesa driver. * The app_server isn't designed to support two fallback drivers, so on systems using UEFI to boot, the framebuffer driver will often win when other drivers would likely work on those systems. --- build/jam/images/definitions/minimum | 4 +- src/add-ons/accelerants/vesa/accelerant.cpp | 16 ++++--- src/add-ons/accelerants/vesa/mode.cpp | 45 +++++++++++++++++-- .../kernel/drivers/graphics/vesa/driver.cpp | 7 +-- .../kernel/drivers/graphics/vesa/vesa.cpp | 16 +++++-- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/build/jam/images/definitions/minimum b/build/jam/images/definitions/minimum index 437219da9e..0fcc5b5a66 100644 --- a/build/jam/images/definitions/minimum +++ b/build/jam/images/definitions/minimum @@ -144,7 +144,7 @@ SYSTEM_NETWORK_PROTOCOLS = SYSTEM_ADD_ONS_ACCELERANTS = [ FFilterByBuildFeatures x86,x86_64 @{ - framebuffer.accelerant vesa.accelerant + vesa.accelerant }@ # x86,x86_64 ] ; @@ -172,7 +172,7 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = [ FFilterByBuildFeatures x86,x86_64 @{ - framebuffer vesa + vesa }@ # x86,x86_64 ] ; diff --git a/src/add-ons/accelerants/vesa/accelerant.cpp b/src/add-ons/accelerants/vesa/accelerant.cpp index 886d249657..5790ba761f 100644 --- a/src/add-ons/accelerants/vesa/accelerant.cpp +++ b/src/add-ons/accelerants/vesa/accelerant.cpp @@ -1,5 +1,6 @@ /* * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2016-207, Jessica Hamilton, jessica.l.hamilton@gmail.com. * Distributed under the terms of the MIT License. */ @@ -55,7 +56,7 @@ AreaCloner::~AreaCloner() } -area_id +area_id AreaCloner::Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea) { @@ -64,7 +65,7 @@ AreaCloner::Clone(const char *name, void **_address, uint32 spec, } -void +void AreaCloner::Keep() { fArea = -1; @@ -111,8 +112,11 @@ init_common(int device, bool isClone) return status; } - gInfo->vesa_modes = (vesa_mode *)((uint8 *)gInfo->shared_info - + gInfo->shared_info->vesa_mode_offset); + if (gInfo->shared_info->vesa_mode_count == 0) + gInfo->vesa_modes = NULL; + else + gInfo->vesa_modes = (vesa_mode *)((uint8 *)gInfo->shared_info + + gInfo->shared_info->vesa_mode_offset); sharedCloner.Keep(); return B_OK; @@ -146,7 +150,7 @@ vesa_init_accelerant(int device) TRACE(("vesa_init_accelerant()\n")); status_t status = init_common(device, false); - if (status != B_OK) + if (status != B_OK) return status; status = create_mode_list(); @@ -198,7 +202,7 @@ vesa_clone_accelerant(void *info) status = gInfo->mode_list_area = clone_area( "vesa cloned modes", (void **)&gInfo->mode_list, B_ANY_ADDRESS, B_READ_AREA, gInfo->shared_info->mode_list_area); - if (status < B_OK) + if (status < B_OK) goto err2; return B_OK; diff --git a/src/add-ons/accelerants/vesa/mode.cpp b/src/add-ons/accelerants/vesa/mode.cpp index 8dedbcd6fa..1cc2837211 100644 --- a/src/add-ons/accelerants/vesa/mode.cpp +++ b/src/add-ons/accelerants/vesa/mode.cpp @@ -53,6 +53,16 @@ is_mode_supported(display_mode* mode) { vesa_mode* modes = gInfo->vesa_modes; + if (modes == NULL) { + // we're a UEFI framebuffer, just confirm it's our current mode + const display_mode ¤t = gInfo->shared_info->current_mode; + return mode->virtual_width == current.virtual_width + && mode->virtual_height == current.virtual_height + && mode->h_display_start == current.h_display_start + && mode->v_display_start == current.v_display_start + && mode->space == current.space; + } + for (uint32 i = gInfo->shared_info->vesa_mode_count; i-- > 0;) { // search mode in VESA mode list // TODO: list is ordered, we could use binary search @@ -75,12 +85,20 @@ create_mode_list(void) { const color_space kVesaSpaces[] = {B_RGB32_LITTLE, B_RGB24_LITTLE, B_RGB16_LITTLE, B_RGB15_LITTLE, B_CMAP8}; + const color_space kUefiSpaces[] = { + (color_space)gInfo->shared_info->current_mode.space + }; uint32 initialModesCount = 0; + bool vesaAvailable = gInfo->vesa_modes != NULL; // Add initial VESA modes. - display_mode* initialModes = (display_mode*)malloc( - sizeof(display_mode) * gInfo->shared_info->vesa_mode_count); + display_mode* initialModes = NULL; + if (vesaAvailable) { + initialModes = (display_mode*)malloc( + sizeof(display_mode) * gInfo->shared_info->vesa_mode_count); + } + if (initialModes != NULL) { initialModesCount = gInfo->shared_info->vesa_mode_count; vesa_mode* vesaModes = gInfo->vesa_modes; @@ -91,12 +109,27 @@ create_mode_list(void) fill_display_mode(vesaModes[i].width, vesaModes[i].height, &initialModes[i]); } + } else { + // UEFI doesn't give us any VESA modes + initialModes = (display_mode*)malloc(sizeof(display_mode)); + if (initialModes != NULL) { + initialModesCount = 1; + + compute_display_timing(initialModes[0].virtual_width, + initialModes[0].virtual_height, 60, false, + &initialModes[0].timing); + fill_display_mode(initialModes[0].virtual_width, + initialModes[0].virtual_height, &initialModes[0]); + } } + const color_space *colorSpaces = vesaAvailable ? kVesaSpaces : kUefiSpaces; + size_t colorSpaceCount = vesaAvailable ? + sizeof(kVesaSpaces) / sizeof(kVesaSpaces[0]) : 1; + gInfo->mode_list_area = create_display_modes("vesa modes", gInfo->shared_info->has_edid ? &gInfo->shared_info->edid_info : NULL, - initialModes, initialModesCount, - kVesaSpaces, sizeof(kVesaSpaces) / sizeof(kVesaSpaces[0]), + initialModes, initialModesCount, colorSpaces, colorSpaceCount, is_mode_supported, &gInfo->mode_list, &gInfo->shared_info->mode_count); free(initialModes); @@ -163,6 +196,10 @@ vesa_set_display_mode(display_mode* _mode) return B_BAD_VALUE; vesa_mode* modes = gInfo->vesa_modes; + if (modes == NULL) + return B_BAD_VALUE; + // UEFI has no VESA modes + for (uint32 i = gInfo->shared_info->vesa_mode_count; i-- > 0;) { // search mode in VESA mode list // TODO: list is ordered, we could use binary search diff --git a/src/add-ons/kernel/drivers/graphics/vesa/driver.cpp b/src/add-ons/kernel/drivers/graphics/vesa/driver.cpp index edf8ac2ba4..28cb549589 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/driver.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/driver.cpp @@ -53,12 +53,7 @@ init_hardware(void) { TRACE((DEVICE_NAME ": init_hardware()\n")); - // If we don't have the VESA mode info, then we have a - // dumb framebuffer, in which case we bail, and leave it - // up to the framebuffer driver to handle. - return (get_boot_item(VESA_MODES_BOOT_INFO, NULL) != NULL - && get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL) != NULL) - ? B_OK : B_ERROR; + return get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL) != NULL ? B_OK : B_ERROR; } diff --git a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp index 0a3dd14455..eca4ea537b 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp @@ -402,10 +402,12 @@ vesa_init(vesa_info& info) memcpy(&sharedInfo.edid_info, edidInfo, sizeof(edid1_info)); } - vbe_get_dpms_capabilities(info.vbe_dpms_capabilities, - sharedInfo.dpms_capabilities); - if (bufferInfo->depth <= 8) - vbe_set_bits_per_gun(info, 8); + if (modes != NULL) { + vbe_get_dpms_capabilities(info.vbe_dpms_capabilities, + sharedInfo.dpms_capabilities); + if (bufferInfo->depth <= 8) + vbe_set_bits_per_gun(info, 8); + } dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n"); return B_OK; @@ -477,6 +479,9 @@ vesa_get_dpms_mode(vesa_info& info, uint32& mode) mode = B_DPMS_ON; // we always return a valid mode + if (info.modes == NULL) + return B_ERROR; + // Prepare BIOS environment bios_state* state; status_t status = vbe_call_prepare(&state); @@ -514,6 +519,9 @@ out: status_t vesa_set_dpms_mode(vesa_info& info, uint32 mode) { + if (info.modes == NULL) + return B_ERROR; + // Only let supported modes through mode &= info.shared_info->dpms_capabilities;