Serenity Operating System
at master 174 lines 6.3 kB view raw
1/* 2 * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Types.h> 10#include <Kernel/API/Ioctl.h> 11#include <Kernel/Devices/CharacterDevice.h> 12#include <Kernel/Memory/SharedFramebufferVMObject.h> 13#include <LibEDID/EDID.h> 14 15namespace Kernel { 16 17class GraphicsManagement; 18class DisplayConnector : public CharacterDevice { 19 friend class GraphicsManagement; 20 friend class DeviceManagement; 21 22public: 23 struct ModeSetting { 24 size_t horizontal_blanking_start() const 25 { 26 return horizontal_active; 27 } 28 size_t horizontal_sync_start() const 29 { 30 return horizontal_active + horizontal_front_porch_pixels; 31 } 32 size_t horizontal_sync_end() const 33 { 34 return horizontal_active + horizontal_front_porch_pixels + horizontal_sync_time_pixels; 35 } 36 size_t horizontal_total() const 37 { 38 return horizontal_active + horizontal_blank_pixels; 39 } 40 41 size_t vertical_blanking_start() const 42 { 43 return vertical_active; 44 } 45 size_t vertical_sync_start() const 46 { 47 return vertical_active + vertical_front_porch_lines; 48 } 49 size_t vertical_sync_end() const 50 { 51 return vertical_active + vertical_front_porch_lines + vertical_sync_time_lines; 52 } 53 size_t vertical_total() const 54 { 55 return vertical_active + vertical_blank_lines; 56 } 57 58 size_t horizontal_stride; // Note: This is commonly known as "pitch" 59 size_t pixel_clock_in_khz; 60 61 size_t horizontal_active; 62 size_t horizontal_front_porch_pixels; 63 size_t horizontal_sync_time_pixels; 64 size_t horizontal_blank_pixels; 65 66 size_t vertical_active; 67 size_t vertical_front_porch_lines; 68 size_t vertical_sync_time_lines; 69 size_t vertical_blank_lines; 70 71 size_t horizontal_offset; // Note: This is commonly known as "x offset" 72 size_t vertical_offset; // Note: This is commonly known as "y offset" 73 }; 74 75public: 76 enum class DisplayMode { 77 Graphical, 78 Console, 79 }; 80 81public: 82 virtual ~DisplayConnector() = default; 83 84 virtual bool mutable_mode_setting_capable() const = 0; 85 virtual bool double_framebuffering_capable() const = 0; 86 virtual bool flush_support() const = 0; 87 virtual bool partial_flush_support() const = 0; 88 // Note: This can indicate to userland if the underlying hardware requires 89 // a defined refresh rate being supplied when modesetting the screen resolution. 90 // Paravirtualized hardware don't need such setting and can safely ignore this. 91 virtual bool refresh_rate_support() const = 0; 92 93 bool console_mode() const; 94 ErrorOr<ByteBuffer> get_edid() const; 95 virtual ErrorOr<void> set_mode_setting(ModeSetting const&) = 0; 96 virtual ErrorOr<void> set_safe_mode_setting() = 0; 97 ModeSetting current_mode_setting() const; 98 virtual ErrorOr<void> set_y_offset(size_t y) = 0; 99 virtual ErrorOr<void> unblank() = 0; 100 101 void set_display_mode(Badge<GraphicsManagement>, DisplayMode); 102 103 Memory::Region const& framebuffer_region() const { return *m_framebuffer_region; } 104 105protected: 106 void set_edid_bytes(Array<u8, 128> const& edid_bytes, bool might_be_invalid = false); 107 108 DisplayConnector(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size, bool enable_write_combine_optimization); 109 DisplayConnector(size_t framebuffer_resource_size, bool enable_write_combine_optimization); 110 virtual void enable_console() = 0; 111 virtual void disable_console() = 0; 112 virtual ErrorOr<void> flush_first_surface() = 0; 113 virtual ErrorOr<void> flush_rectangle(size_t buffer_index, FBRect const& rect); 114 115 ErrorOr<void> initialize_edid_for_generic_monitor(Optional<Array<u8, 3>> manufacturer_id_string); 116 117 mutable Spinlock<LockRank::None> m_control_lock {}; 118 mutable Mutex m_flushing_lock; 119 120 bool m_console_mode { false }; 121 122 bool m_vertical_offsetted { false }; 123 124 mutable Spinlock<LockRank::None> m_modeset_lock {}; 125 ModeSetting m_current_mode_setting {}; 126 127 Optional<EDID::Parser> m_edid_parser; 128 EDID::Parser::RawBytes m_edid_bytes {}; 129 bool m_edid_valid { false }; 130 131 u8* framebuffer_data() { return m_framebuffer_data; } 132 133private: 134 // ^File 135 virtual bool is_seekable() const override { return true; } 136 virtual bool can_read(OpenFileDescription const&, u64) const final override { return true; } 137 virtual bool can_write(OpenFileDescription const&, u64) const final override { return true; } 138 virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override final; 139 virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override final; 140 virtual ErrorOr<NonnullLockRefPtr<Memory::VMObject>> vmobject_for_mmap(Process&, Memory::VirtualRange const&, u64&, bool) override final; 141 virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final; 142 virtual StringView class_name() const override final { return "DisplayConnector"sv; } 143 144 DisplayConnector& operator=(DisplayConnector const&) = delete; 145 DisplayConnector& operator=(DisplayConnector&&) = delete; 146 DisplayConnector(DisplayConnector&&) = delete; 147 148 virtual void will_be_destroyed() override; 149 virtual ErrorOr<void> after_inserting() override; 150 151 ErrorOr<void> allocate_framebuffer_resources(size_t rounded_size); 152 153 ErrorOr<bool> ioctl_requires_ownership(unsigned request) const; 154 155 OwnPtr<Memory::Region> m_framebuffer_region; 156 OwnPtr<Memory::Region> m_fake_writes_framebuffer_region; 157 u8* m_framebuffer_data {}; 158 159 bool const m_enable_write_combine_optimization { false }; 160 bool const m_framebuffer_at_arbitrary_physical_range { false }; 161 162protected: 163 Optional<PhysicalAddress> const m_framebuffer_address; 164 size_t m_framebuffer_resource_size; 165 166private: 167 LockRefPtr<Memory::SharedFramebufferVMObject> m_shared_framebuffer_vmobject; 168 169 LockWeakPtr<Process> m_responsible_process; 170 Spinlock<LockRank::None> m_responsible_process_lock {}; 171 172 IntrusiveListNode<DisplayConnector, LockRefPtr<DisplayConnector>> m_list_node; 173}; 174}