mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-13 06:32:54 +00:00
Kernel/Memory: Introduce the SharedFramebufferVMObject class
This new type of VMObject will be used to coordinate switching safely from graphical mode to text mode and vice-versa, by supplying a way to remap all Regions that were created with this object, so mappings can be changed according to the given state of system mode. This makes it quite easy to give applications like WindowServer the feeling of having full access to the framebuffer device from a DisplayConnector, but still keep the Kernel in control to be able to safely switch to text console.
This commit is contained in:
parent
ec925cbb89
commit
3d22917548
Notes:
sideshowbarker
2024-07-17 10:25:41 +09:00
Author: https://github.com/supercomputer7
Commit: 3d22917548
Pull-request: https://github.com/SerenityOS/serenity/pull/14029
Reviewed-by: https://github.com/FireFox317
Reviewed-by: https://github.com/linusg
5 changed files with 219 additions and 2 deletions
94
Kernel/Memory/SharedFramebufferVMObject.h
Normal file
94
Kernel/Memory/SharedFramebufferVMObject.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Kernel/Forward.h>
|
||||
#include <Kernel/Memory/AllocationStrategy.h>
|
||||
#include <Kernel/Memory/AnonymousVMObject.h>
|
||||
#include <Kernel/Memory/MemoryManager.h>
|
||||
#include <Kernel/Memory/PageFaultResponse.h>
|
||||
#include <Kernel/PhysicalAddress.h>
|
||||
|
||||
namespace Kernel::Memory {
|
||||
|
||||
class SharedFramebufferVMObject final : public VMObject {
|
||||
public:
|
||||
class FakeWritesFramebufferVMObject final : public VMObject {
|
||||
public:
|
||||
static ErrorOr<NonnullRefPtr<FakeWritesFramebufferVMObject>> try_create(Badge<SharedFramebufferVMObject>, SharedFramebufferVMObject const& parent_object);
|
||||
|
||||
private:
|
||||
FakeWritesFramebufferVMObject(SharedFramebufferVMObject const& parent_object, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||
: VMObject(move(new_physical_pages))
|
||||
, m_parent_object(parent_object)
|
||||
{
|
||||
}
|
||||
virtual StringView class_name() const override { return "FakeWritesFramebufferVMObject"sv; }
|
||||
virtual ErrorOr<NonnullRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
|
||||
virtual Span<RefPtr<PhysicalPage> const> physical_pages() const override { return m_parent_object->fake_sink_framebuffer_physical_pages(); }
|
||||
virtual Span<RefPtr<PhysicalPage>> physical_pages() override { return m_parent_object->fake_sink_framebuffer_physical_pages(); }
|
||||
NonnullRefPtr<SharedFramebufferVMObject> m_parent_object;
|
||||
};
|
||||
|
||||
class RealWritesFramebufferVMObject final : public VMObject {
|
||||
public:
|
||||
static ErrorOr<NonnullRefPtr<RealWritesFramebufferVMObject>> try_create(Badge<SharedFramebufferVMObject>, SharedFramebufferVMObject const& parent_object);
|
||||
|
||||
private:
|
||||
RealWritesFramebufferVMObject(SharedFramebufferVMObject const& parent_object, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
|
||||
: VMObject(move(new_physical_pages))
|
||||
, m_parent_object(parent_object)
|
||||
{
|
||||
}
|
||||
virtual StringView class_name() const override { return "RealWritesFramebufferVMObject"sv; }
|
||||
virtual ErrorOr<NonnullRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
|
||||
virtual Span<RefPtr<PhysicalPage> const> physical_pages() const override { return m_parent_object->real_framebuffer_physical_pages(); }
|
||||
virtual Span<RefPtr<PhysicalPage>> physical_pages() override { return m_parent_object->real_framebuffer_physical_pages(); }
|
||||
NonnullRefPtr<SharedFramebufferVMObject> m_parent_object;
|
||||
};
|
||||
|
||||
virtual ~SharedFramebufferVMObject() override = default;
|
||||
|
||||
static ErrorOr<NonnullRefPtr<SharedFramebufferVMObject>> try_create_for_physical_range(PhysicalAddress paddr, size_t size);
|
||||
static ErrorOr<NonnullRefPtr<SharedFramebufferVMObject>> try_create_at_arbitrary_physical_range(size_t size);
|
||||
virtual ErrorOr<NonnullRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
|
||||
|
||||
void switch_to_fake_sink_framebuffer_writes(Badge<Kernel::DisplayConnector>);
|
||||
void switch_to_real_framebuffer_writes(Badge<Kernel::DisplayConnector>);
|
||||
|
||||
virtual Span<RefPtr<PhysicalPage> const> physical_pages() const override;
|
||||
virtual Span<RefPtr<PhysicalPage>> physical_pages() override;
|
||||
|
||||
Span<RefPtr<PhysicalPage>> fake_sink_framebuffer_physical_pages();
|
||||
Span<RefPtr<PhysicalPage> const> fake_sink_framebuffer_physical_pages() const;
|
||||
|
||||
Span<RefPtr<PhysicalPage>> real_framebuffer_physical_pages();
|
||||
Span<RefPtr<PhysicalPage> const> real_framebuffer_physical_pages() const;
|
||||
|
||||
FakeWritesFramebufferVMObject const& fake_writes_framebuffer_vmobject() const { return *m_fake_writes_framebuffer_vmobject; }
|
||||
FakeWritesFramebufferVMObject& fake_writes_framebuffer_vmobject() { return *m_fake_writes_framebuffer_vmobject; }
|
||||
|
||||
RealWritesFramebufferVMObject const& real_writes_framebuffer_vmobject() const { return *m_real_writes_framebuffer_vmobject; }
|
||||
RealWritesFramebufferVMObject& real_writes_framebuffer_vmobject() { return *m_real_writes_framebuffer_vmobject; }
|
||||
|
||||
private:
|
||||
SharedFramebufferVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, CommittedPhysicalPageSet, AnonymousVMObject& real_framebuffer_vmobject);
|
||||
|
||||
virtual StringView class_name() const override { return "SharedFramebufferVMObject"sv; }
|
||||
|
||||
ErrorOr<void> create_fake_writes_framebuffer_vm_object();
|
||||
ErrorOr<void> create_real_writes_framebuffer_vm_object();
|
||||
|
||||
NonnullRefPtr<AnonymousVMObject> m_real_framebuffer_vmobject;
|
||||
RefPtr<FakeWritesFramebufferVMObject> m_fake_writes_framebuffer_vmobject;
|
||||
RefPtr<RealWritesFramebufferVMObject> m_real_writes_framebuffer_vmobject;
|
||||
bool m_writes_are_faked { false };
|
||||
mutable RecursiveSpinlock m_writes_state_lock;
|
||||
CommittedPhysicalPageSet m_committed_pages;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue