We are able to read the EDID from SysFS, therefore there's no need to
provide this ioctl on a DisplayConnector anymore.
Also, now we can simply require the video pledge to be set before doing
any ioctl on a DisplayConnector.
It is starting to get a little messy with how each device can try to add
or remove itself to either /sys/dev/block or /sys/dev/char directories.
To better do this, we introduce 4 virtual methods to take care of that,
so until we ensure all nodes in /sys/dev/block and /sys/dev/char are
actual symlinks, we allow the Device base class to call virtual methods
upon insertion or before being destroying, so it add itself elegantly to
either of these directories or remove itself when needed.
For special cases where we need to create symlinks, we have two virtual
methods to be called otherwise to do almost the same thing mentioned
before, but to use symlinks instead.
Under normal conditions (when mounting SysFS in /sys), there will be a
new directory in the /sys/devices directory called "graphics".
For now, under that directory there will be only a sub-directory called
"connectors" which will contain all DisplayConnectors' details, each in
its own sub-directory too, distinguished in naming with its minor
number.
Therefore, /sys/devices/graphics/connectors/MINOR_NUMBER/ will contain:
- General device attributes such as mutable_mode_setting_capable,
double_buffering_capable, flush_support, partial_flush_support and
refresh_rate_support. These values are exposed in the ioctl interface
of the DisplayConnector class too, but these can be useful later on
for command line utilities that want/need to expose these basic
settings.
- The EDID blob, simply named "edid". This will help userspace to fetch
the edid without the need of using the ioctl interface later on.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
The WindowServer doesn't use this interface anymore and therefore it's
not used by any userspace application, so let's remove this stale method
to ensure we don't have to bother with it anymore.
The mmap interface was removed when we introduced the DisplayConnector
class, as it was quite unsafe to use and didn't handle switching between
graphical and text modes safely. By using the SharedFramebufferVMObject,
we are able to elegantly coordinate the switch by remapping the attached
mmap'ed-Memory::Region(s) with different mappings, therefore, keeping
WindowServer to think that the mappings it has are still valid, while
they are going to a different physical range until we are back to the
graphical mode (after a switch from text mode).
Most drivers take advantage of the fact that we know where is the actual
framebuffer in physical memory space, the SharedFramebufferVMObject is
created with that information. However, the VirtIO driver is different
in that aspect, because it relies on DMA transactions to show graphics
on the framebuffer, so the SharedFramebufferVMObject is created with
that mindset to support the arbitrary framebuffer location in physical
memory space.
This fixes a weird bug that when sometimes a user tried to switch to
console mode, the screen was frozen on graphics mode. After a hour of
debugging this, it became apparent that the problem was that we left the
y offset of the bochs graphics device in an invalid state, so it was not
zero because the WindowServer changed it, and the framebuffer console
code is not aware of horizontal and vertical offsets of the framebuffer
screen, leading to the problem that the framebuffer console updates the
first framebuffer (y offset = 0), but hardware was indicated to show the
second framebuffer (y offset = first framebuffer height).
Therefore, when doing a switch between these modes, always set the y
offset to be zero.
The DisplayConnector class is meant to replace the FramebufferDevice
class. The advantage of this class over the FramebufferDevice class is:
1. It removes the mmap interface entirely. This interface is unsafe, as
multiple processes could try to use it, and when switching to and from
text console mode, there's no "good" way to revoke a memory mapping from
this interface, let alone when there are multiple processes that call
this interface. Therefore, in the DisplayConnector class there's no
implementation for this method at all.
2. The class uses a new real-world structure called ModeSetting, which
takes into account the fact that real hardware requires more than width,
height and pitch settings to mode-set the display resolution.
3. The class assumes all instances should supply some sort of EDID,
so it facilitates such mechanism to do so. Even if a given driver does
not know what is the actual EDID, it will ask to create default-generic
EDID blob.
3. This class shifts the responsibilies of switching between console
mode and graphical mode from a GraphicsAdapter to the DisplayConnector
class, so when doing the switch, the GraphicsManagement code actually
asks each DisplayConnector object to do the switch and doesn't rely on
the GraphicsAdapter objects at all.