浏览代码

Kernel/Graphics: Choose VMObject considering enabled state when mmaping

When mmaping a Framebuffer from userspace, we need to check whether the
framebuffer device is actually enabled (e.g. graphical mode is being
used) or a textual VirtualConsole is active.

Considering the above state, we mmap the right VMObject to ensure we
don't have graphical artifacts if we change the resolution from
DisplaySettings, changed to textual mode and after the resolution change
was reverted, we will see the Desktop reappearing even though we are
still in textual mode.
Liav A 4 年之前
父节点
当前提交
db268efa69
共有 2 个文件被更改,包括 12 次插入1 次删除
  1. 10 1
      Kernel/Graphics/FramebufferDevice.cpp
  2. 2 0
      Kernel/Graphics/FramebufferDevice.h

+ 10 - 1
Kernel/Graphics/FramebufferDevice.cpp

@@ -22,6 +22,7 @@ namespace Kernel {
 
 
 KResultOr<Region*> FramebufferDevice::mmap(Process& process, FileDescription&, const Range& range, u64 offset, int prot, bool shared)
 KResultOr<Region*> FramebufferDevice::mmap(Process& process, FileDescription&, const Range& range, u64 offset, int prot, bool shared)
 {
 {
+    ScopedSpinLock lock(m_activation_lock);
     REQUIRE_PROMISE(video);
     REQUIRE_PROMISE(video);
     if (!shared)
     if (!shared)
         return ENODEV;
         return ENODEV;
@@ -40,9 +41,15 @@ KResultOr<Region*> FramebufferDevice::mmap(Process& process, FileDescription&, c
     m_real_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, page_round_up(framebuffer_size_in_bytes()), "Framebuffer", Region::Access::Read | Region::Access::Write);
     m_real_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_real_framebuffer_vmobject, page_round_up(framebuffer_size_in_bytes()), "Framebuffer", Region::Access::Read | Region::Access::Write);
     m_swapped_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, page_round_up(framebuffer_size_in_bytes()), "Framebuffer Swap (Blank)", Region::Access::Read | Region::Access::Write);
     m_swapped_framebuffer_region = MM.allocate_kernel_region_with_vmobject(*m_swapped_framebuffer_vmobject, page_round_up(framebuffer_size_in_bytes()), "Framebuffer Swap (Blank)", Region::Access::Read | Region::Access::Write);
 
 
+    RefPtr<VMObject> chosen_vmobject;
+    if (m_graphical_writes_enabled) {
+        chosen_vmobject = m_real_framebuffer_vmobject;
+    } else {
+        chosen_vmobject = m_swapped_framebuffer_vmobject;
+    }
     auto result = process.space().allocate_region_with_vmobject(
     auto result = process.space().allocate_region_with_vmobject(
         range,
         range,
-        vmobject.release_nonnull(),
+        chosen_vmobject.release_nonnull(),
         0,
         0,
         "Framebuffer",
         "Framebuffer",
         prot,
         prot,
@@ -62,6 +69,7 @@ void FramebufferDevice::dectivate_writes()
     auto vmobject = m_swapped_framebuffer_vmobject;
     auto vmobject = m_swapped_framebuffer_vmobject;
     m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
     m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
     m_userspace_framebuffer_region->remap();
     m_userspace_framebuffer_region->remap();
+    m_graphical_writes_enabled = false;
 }
 }
 void FramebufferDevice::activate_writes()
 void FramebufferDevice::activate_writes()
 {
 {
@@ -75,6 +83,7 @@ void FramebufferDevice::activate_writes()
     auto vmobject = m_userspace_real_framebuffer_vmobject;
     auto vmobject = m_userspace_real_framebuffer_vmobject;
     m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
     m_userspace_framebuffer_region->set_vmobject(vmobject.release_nonnull());
     m_userspace_framebuffer_region->remap();
     m_userspace_framebuffer_region->remap();
+    m_graphical_writes_enabled = true;
 }
 }
 
 
 String FramebufferDevice::device_name() const
 String FramebufferDevice::device_name() const

+ 2 - 0
Kernel/Graphics/FramebufferDevice.h

@@ -59,6 +59,8 @@ private:
     OwnPtr<Region> m_real_framebuffer_region;
     OwnPtr<Region> m_real_framebuffer_region;
     OwnPtr<Region> m_swapped_framebuffer_region;
     OwnPtr<Region> m_swapped_framebuffer_region;
 
 
+    bool m_graphical_writes_enabled { true };
+
     RefPtr<AnonymousVMObject> m_userspace_real_framebuffer_vmobject;
     RefPtr<AnonymousVMObject> m_userspace_real_framebuffer_vmobject;
     Region* m_userspace_framebuffer_region { nullptr };
     Region* m_userspace_framebuffer_region { nullptr };
 };
 };