Selaa lähdekoodia

Make GraphicsBitmaps be Region-backed when running in the kernel.

This is a lot better than having them in kmalloc memory. I'm gonna need
a way to keep track of which process owns which bitmap eventually,
maybe through some sort of resource keying system. We'll see.
Andreas Kling 6 vuotta sitten
vanhempi
commit
becc2c7fa5

+ 2 - 0
Kernel/MemoryManager.h

@@ -11,6 +11,8 @@
 #include <AK/AKString.h>
 #include <VirtualFileSystem/VirtualFileSystem.h>
 
+#define PAGE_ROUND_UP(x) ((((dword)(x)) + PAGE_SIZE-1) & (~(PAGE_SIZE-1)))
+
 class Process;
 extern Process* current;
 

+ 3 - 1
Kernel/Process.cpp

@@ -68,6 +68,7 @@ Vector<Process*> Process::allProcesses()
 
 Region* Process::allocate_region(LinearAddress laddr, size_t size, String&& name, bool is_readable, bool is_writable, bool commit)
 {
+    size = PAGE_ROUND_UP(size);
     // FIXME: This needs sanity checks. What if this overlaps existing regions?
     if (laddr.is_null()) {
         laddr = m_nextRegion;
@@ -84,7 +85,7 @@ Region* Process::allocate_region(LinearAddress laddr, size_t size, String&& name
 Region* Process::allocate_file_backed_region(LinearAddress laddr, size_t size, RetainPtr<Vnode>&& vnode, String&& name, bool is_readable, bool is_writable)
 {
     ASSERT(!vnode->isCharacterDevice());
-
+    size = PAGE_ROUND_UP(size);
     // FIXME: This needs sanity checks. What if this overlaps existing regions?
     if (laddr.is_null()) {
         laddr = m_nextRegion;
@@ -99,6 +100,7 @@ Region* Process::allocate_file_backed_region(LinearAddress laddr, size_t size, R
 Region* Process::allocate_region_with_vmo(LinearAddress laddr, size_t size, RetainPtr<VMObject>&& vmo, size_t offset_in_vmo, String&& name, bool is_readable, bool is_writable)
 {
     ASSERT(vmo);
+    size = PAGE_ROUND_UP(size);
     // FIXME: This needs sanity checks. What if this overlaps existing regions?
     if (laddr.is_null()) {
         laddr = m_nextRegion;

+ 1 - 0
Kernel/Process.h

@@ -43,6 +43,7 @@ struct DisplayInfo {
 class Process : public InlineLinkedListNode<Process> {
     friend class InlineLinkedListNode<Process>;
     friend class WindowManager; // FIXME: Make a better API for allocate_region().
+    friend class GraphicsBitmap; // FIXME: Make a better API for allocate_region().
 public:
     static Process* create_kernel_process(String&& name, void (*entry)());
     static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);

+ 3 - 1
Kernel/i386.cpp

@@ -231,8 +231,10 @@ void exception_14_handler(RegisterDumpWithExceptionCode& regs)
     );
 #endif
 
-    if (current->isRing0())
+    if (current->isRing0()) {
+        current->dumpRegions();
         HANG;
+    }
 
     auto response = MM.handle_page_fault(PageFault(regs.exception_code, LinearAddress(faultAddress)));
 

+ 15 - 0
Widgets/GraphicsBitmap.cpp

@@ -1,6 +1,11 @@
 #include "GraphicsBitmap.h"
 #include <AK/kmalloc.h>
 
+#ifdef SERENITY
+#include "Process.h"
+#include "MemoryManager.h"
+#endif
+
 RetainPtr<GraphicsBitmap> GraphicsBitmap::create(const Size& size)
 {
     return adopt(*new GraphicsBitmap(size));
@@ -15,9 +20,15 @@ GraphicsBitmap::GraphicsBitmap(const Size& size)
     : m_size(size)
     , m_pitch(size.width() * sizeof(RGBA32))
 {
+#ifdef SERENITY
+    m_region = current->allocate_region(LinearAddress(), size.width() * size.height() * sizeof(RGBA32), "GraphicsBitmap", true, true, true);
+    m_data = (RGBA32*)m_region->linearAddress.asPtr();
+    m_owned = false;
+#else
     m_data = static_cast<RGBA32*>(kmalloc(size.width() * size.height() * sizeof(RGBA32)));
     memset(m_data, 0, size.width() * size.height() * sizeof(RGBA32));
     m_owned = true;
+#endif
 }
 
 GraphicsBitmap::GraphicsBitmap(const Size& size, RGBA32* data)
@@ -30,6 +41,10 @@ GraphicsBitmap::GraphicsBitmap(const Size& size, RGBA32* data)
 
 GraphicsBitmap::~GraphicsBitmap()
 {
+#ifdef SERENITY
+    if (m_region)
+        current->deallocate_region(*m_region);
+#endif
     if (m_owned)
         kfree(m_data);
     m_data = nullptr;

+ 5 - 0
Widgets/GraphicsBitmap.h

@@ -5,6 +5,8 @@
 #include <AK/Retainable.h>
 #include <AK/RetainPtr.h>
 
+class Region;
+
 class GraphicsBitmap : public Retainable<GraphicsBitmap> {
 public:
     static RetainPtr<GraphicsBitmap> create(const Size&);
@@ -26,5 +28,8 @@ private:
     Size m_size;
     RGBA32* m_data { nullptr };
     size_t m_pitch { 0 };
+#ifdef SERENITY
+    Region* m_region { nullptr };
+#endif
     bool m_owned { false };
 };

+ 1 - 1
Widgets/WindowManager.cpp

@@ -70,7 +70,7 @@ WindowManager::WindowManager()
 {
     auto size = m_screen_rect.size();
     m_front_bitmap = GraphicsBitmap::create_wrapper(size, m_framebuffer.scanline(0));
-    auto* region = current->allocate_region(LinearAddress(), size.width() * size.height() * 4, "back buffer", true, true, true);
+    auto* region = current->allocate_region(LinearAddress(), size.width() * size.height() * sizeof(RGBA32), "BackBitmap", true, true, true);
     m_back_bitmap = GraphicsBitmap::create_wrapper(m_screen_rect.size(), (RGBA32*)region->linearAddress.get());
 
     m_activeWindowBorderColor = Color(0, 64, 192);