Serenity Operating System
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 <Kernel/Forward.h>
10#include <Kernel/Memory/AllocationStrategy.h>
11#include <Kernel/Memory/AnonymousVMObject.h>
12#include <Kernel/Memory/MemoryManager.h>
13#include <Kernel/Memory/PageFaultResponse.h>
14#include <Kernel/PhysicalAddress.h>
15
16namespace Kernel::Memory {
17
18class SharedFramebufferVMObject final : public VMObject {
19public:
20 class FakeWritesFramebufferVMObject final : public VMObject {
21 public:
22 static ErrorOr<NonnullLockRefPtr<FakeWritesFramebufferVMObject>> try_create(Badge<SharedFramebufferVMObject>, SharedFramebufferVMObject const& parent_object);
23
24 private:
25 FakeWritesFramebufferVMObject(SharedFramebufferVMObject const& parent_object, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
26 : VMObject(move(new_physical_pages))
27 , m_parent_object(parent_object)
28 {
29 }
30 virtual StringView class_name() const override { return "FakeWritesFramebufferVMObject"sv; }
31 virtual ErrorOr<NonnullLockRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
32 virtual ReadonlySpan<RefPtr<PhysicalPage>> physical_pages() const override { return m_parent_object->fake_sink_framebuffer_physical_pages(); }
33 virtual Span<RefPtr<PhysicalPage>> physical_pages() override { return m_parent_object->fake_sink_framebuffer_physical_pages(); }
34 NonnullLockRefPtr<SharedFramebufferVMObject> m_parent_object;
35 };
36
37 class RealWritesFramebufferVMObject final : public VMObject {
38 public:
39 static ErrorOr<NonnullLockRefPtr<RealWritesFramebufferVMObject>> try_create(Badge<SharedFramebufferVMObject>, SharedFramebufferVMObject const& parent_object);
40
41 private:
42 RealWritesFramebufferVMObject(SharedFramebufferVMObject const& parent_object, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
43 : VMObject(move(new_physical_pages))
44 , m_parent_object(parent_object)
45 {
46 }
47 virtual StringView class_name() const override { return "RealWritesFramebufferVMObject"sv; }
48 virtual ErrorOr<NonnullLockRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
49 virtual ReadonlySpan<RefPtr<PhysicalPage>> physical_pages() const override { return m_parent_object->real_framebuffer_physical_pages(); }
50 virtual Span<RefPtr<PhysicalPage>> physical_pages() override { return m_parent_object->real_framebuffer_physical_pages(); }
51 NonnullLockRefPtr<SharedFramebufferVMObject> m_parent_object;
52 };
53
54 virtual ~SharedFramebufferVMObject() override = default;
55
56 static ErrorOr<NonnullLockRefPtr<SharedFramebufferVMObject>> try_create_for_physical_range(PhysicalAddress paddr, size_t size);
57 static ErrorOr<NonnullLockRefPtr<SharedFramebufferVMObject>> try_create_at_arbitrary_physical_range(size_t size);
58 virtual ErrorOr<NonnullLockRefPtr<VMObject>> try_clone() override { return Error::from_errno(ENOTIMPL); }
59
60 void switch_to_fake_sink_framebuffer_writes(Badge<Kernel::DisplayConnector>);
61 void switch_to_real_framebuffer_writes(Badge<Kernel::DisplayConnector>);
62
63 virtual ReadonlySpan<RefPtr<PhysicalPage>> physical_pages() const override;
64 virtual Span<RefPtr<PhysicalPage>> physical_pages() override;
65
66 Span<RefPtr<PhysicalPage>> fake_sink_framebuffer_physical_pages();
67 ReadonlySpan<RefPtr<PhysicalPage>> fake_sink_framebuffer_physical_pages() const;
68
69 Span<RefPtr<PhysicalPage>> real_framebuffer_physical_pages();
70 ReadonlySpan<RefPtr<PhysicalPage>> real_framebuffer_physical_pages() const;
71
72 FakeWritesFramebufferVMObject const& fake_writes_framebuffer_vmobject() const { return *m_fake_writes_framebuffer_vmobject; }
73 FakeWritesFramebufferVMObject& fake_writes_framebuffer_vmobject() { return *m_fake_writes_framebuffer_vmobject; }
74
75 RealWritesFramebufferVMObject const& real_writes_framebuffer_vmobject() const { return *m_real_writes_framebuffer_vmobject; }
76 RealWritesFramebufferVMObject& real_writes_framebuffer_vmobject() { return *m_real_writes_framebuffer_vmobject; }
77
78private:
79 SharedFramebufferVMObject(FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages, CommittedPhysicalPageSet, AnonymousVMObject& real_framebuffer_vmobject);
80
81 virtual StringView class_name() const override { return "SharedFramebufferVMObject"sv; }
82
83 ErrorOr<void> create_fake_writes_framebuffer_vm_object();
84 ErrorOr<void> create_real_writes_framebuffer_vm_object();
85
86 NonnullLockRefPtr<AnonymousVMObject> m_real_framebuffer_vmobject;
87 LockRefPtr<FakeWritesFramebufferVMObject> m_fake_writes_framebuffer_vmobject;
88 LockRefPtr<RealWritesFramebufferVMObject> m_real_writes_framebuffer_vmobject;
89 bool m_writes_are_faked { false };
90 mutable RecursiveSpinlock<LockRank::None> m_writes_state_lock {};
91 CommittedPhysicalPageSet m_committed_pages;
92};
93
94}