1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:27:35 +00:00

Move WindowServer to userspace.

This is a monster patch that required changing a whole bunch of things.
There are performance and stability issues all over the place, but it works.
Pretty cool, I have to admit :^)
This commit is contained in:
Andreas Kling 2019-02-17 00:13:47 +01:00
parent 0b1b21d622
commit 640360e958
41 changed files with 325 additions and 463 deletions

View file

@ -3,20 +3,11 @@
#include <AK/BufferStream.h>
#include <AK/StdLibExtras.h>
#ifdef KERNEL
#include <Kernel/Process.h>
#include <Kernel/MemoryManager.h>
#include <Kernel/FileDescriptor.h>
#include <Kernel/VirtualFileSystem.h>
#endif
#ifdef USERLAND
#include <LibC/unistd.h>
#include <LibC/stdio.h>
#include <LibC/fcntl.h>
#include <LibC/errno.h>
#include <LibC/mman.h>
#endif
static const byte error_glyph_width = 8;
static const byte error_glyph_height = 10;
@ -54,19 +45,7 @@ Font& Font::default_font()
{
static const char* default_font_path = "/res/fonts/LizaRegular8x10.font";
if (!s_default_font) {
#ifdef USERLAND
s_default_font = Font::load_from_file(default_font_path).leak_ref();
#else
int error;
auto descriptor = VFS::the().open(default_font_path, error, 0, 0, *VFS::the().root_inode());
if (!descriptor) {
kprintf("Failed to open default font (%s)\n", default_font_path);
ASSERT_NOT_REACHED();
}
auto* region = current->allocate_file_backed_region(LinearAddress(), font_file_size(10), descriptor->inode(), "default_font", /*readable*/true, /*writable*/false);
ASSERT(region);
s_default_font = Font::load_from_memory(region->laddr().as_ptr()).leak_ref();
#endif
ASSERT(s_default_font);
}
return *s_default_font;
@ -76,19 +55,7 @@ Font& Font::default_bold_font()
{
static const char* default_bold_font_path = "/res/fonts/LizaBold8x10.font";
if (!s_default_bold_font) {
#ifdef USERLAND
s_default_bold_font = Font::load_from_file(default_bold_font_path).leak_ref();
#else
int error;
auto descriptor = VFS::the().open(default_bold_font_path, error, 0, 0, *VFS::the().root_inode());
if (!descriptor) {
kprintf("Failed to open default bold font (%s)\n", default_bold_font_path);
ASSERT_NOT_REACHED();
}
auto* region = current->allocate_file_backed_region(LinearAddress(), font_file_size(10), descriptor->inode(), "default_bold_font", /*readable*/true, /*writable*/false);
ASSERT(region);
s_default_bold_font = Font::load_from_memory(region->laddr().as_ptr()).leak_ref();
#endif
ASSERT(s_default_bold_font);
}
return *s_default_bold_font;
@ -116,6 +83,10 @@ Font::Font(const String& name, unsigned* rows, byte glyph_width, byte glyph_heig
Font::~Font()
{
if (m_mmap_ptr) {
int rc = munmap(m_mmap_ptr, 4096 * 3);
ASSERT(rc == 0);
}
}
RetainPtr<Font> Font::load_from_memory(const byte* data)
@ -134,7 +105,6 @@ RetainPtr<Font> Font::load_from_memory(const byte* data)
return adopt(*new Font(String(header.name), rows, header.glyph_width, header.glyph_height));
}
#ifdef USERLAND
RetainPtr<Font> Font::load_from_file(const String& path)
{
int fd = open(path.characters(), O_RDONLY, 0644);
@ -152,6 +122,7 @@ RetainPtr<Font> Font::load_from_file(const String& path)
}
auto font = load_from_memory(mapped_file);
font->m_mmap_ptr = mapped_file;
int rc = close(fd);
ASSERT(rc == 0);
@ -189,4 +160,3 @@ bool Font::write_to_file(const String& path)
ASSERT(rc == 0);
return true;
}
#endif

View file

@ -47,10 +47,8 @@ public:
static RetainPtr<Font> load_from_memory(const byte*);
#ifdef USERLAND
static RetainPtr<Font> load_from_file(const String& path);
bool write_to_file(const String& path);
#endif
~Font();
@ -69,6 +67,7 @@ private:
String m_name;
unsigned* m_rows { nullptr };
void* m_mmap_ptr { nullptr };
RetainPtr<CharacterBitmap> m_error_bitmap;

View file

@ -1,18 +1,9 @@
#include "GraphicsBitmap.h"
#ifdef KERNEL
#include <Kernel/Process.h>
#include <Kernel/MemoryManager.h>
#include <WindowServer/WSMessageLoop.h>
#endif
#ifdef USERLAND
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#endif
RetainPtr<GraphicsBitmap> GraphicsBitmap::create(const Size& size)
{
@ -23,18 +14,9 @@ GraphicsBitmap::GraphicsBitmap(const Size& size)
: m_size(size)
, m_pitch(size.width() * sizeof(RGBA32))
{
#ifdef KERNEL
Syscall::SC_mmap_params params;
memset(&params, 0, sizeof(params));
params.fd = 0;
params.prot = PROT_READ | PROT_WRITE;
params.flags = MAP_ANONYMOUS | MAP_PRIVATE;
params.size = size.area() * sizeof(RGBA32);
params.offset = 0;
m_data = (RGBA32*)current->sys$mmap(&params);
m_data = (RGBA32*)mmap(nullptr, size.area() * sizeof(RGBA32), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
ASSERT(m_data && m_data != (void*)-1);
m_mmaped = true;
#endif
}
RetainPtr<GraphicsBitmap> GraphicsBitmap::create_wrapper(const Size& size, RGBA32* data)
@ -44,8 +26,6 @@ RetainPtr<GraphicsBitmap> GraphicsBitmap::create_wrapper(const Size& size, RGBA3
RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(const String& path, const Size& size)
{
RGBA32* mapped_data = nullptr;
#ifdef USERLAND
int fd = open(path.characters(), O_RDONLY, 0644);
if (fd < 0) {
dbgprintf("open(%s) got fd=%d, failed: %s\n", path.characters(), fd, strerror(errno));
@ -53,35 +33,17 @@ RetainPtr<GraphicsBitmap> GraphicsBitmap::load_from_file(const String& path, con
return nullptr;
}
mapped_data = (RGBA32*)mmap(nullptr, size.area() * 4, PROT_READ, MAP_SHARED, fd, 0);
auto* mapped_data = (RGBA32*)mmap(nullptr, size.area() * 4, PROT_READ, MAP_SHARED, fd, 0);
if (mapped_data == MAP_FAILED) {
int rc = close(fd);
ASSERT(rc == 0);
return nullptr;
}
#else
int error;
auto descriptor = VFS::the().open(path, error, 0, 0, *VFS::the().root_inode());
if (!descriptor) {
kprintf("Failed to load GraphicsBitmap from file (%s)\n", path.characters());
return nullptr;
}
auto* region = WSMessageLoop::the().server_process().allocate_file_backed_region(LinearAddress(), size.area() * 4, descriptor->inode(), ".rgb file", /*readable*/true, /*writable*/false);
mapped_data = (RGBA32*)region->laddr().get();
#endif
#ifdef USERLAND
int rc = close(fd);
ASSERT(rc == 0);
#endif
auto bitmap = create_wrapper(size, mapped_data);
#ifdef KERNEL
bitmap->m_server_region = region;
#else
bitmap->m_mmaped = true;
#endif
return bitmap;
}
@ -95,11 +57,7 @@ GraphicsBitmap::GraphicsBitmap(const Size& size, RGBA32* data)
RetainPtr<GraphicsBitmap> GraphicsBitmap::create_with_shared_buffer(int shared_buffer_id, const Size& size, RGBA32* data)
{
if (!data) {
#ifdef KERNEL
void* shared_buffer = current->sys$get_shared_buffer(shared_buffer_id);
#else
void* shared_buffer = get_shared_buffer(shared_buffer_id);
#endif
if (!shared_buffer || shared_buffer == (void*)-1)
return nullptr;
data = (RGBA32*)shared_buffer;
@ -118,20 +76,11 @@ GraphicsBitmap::GraphicsBitmap(int shared_buffer_id, const Size& size, RGBA32* d
GraphicsBitmap::~GraphicsBitmap()
{
if (m_mmaped) {
#ifdef KERNEL
int rc = current->sys$munmap(m_data, m_size.area() * 4);
#else
int rc = munmap(m_data, m_size.area() * 4);
#endif
ASSERT(rc == 0);
}
if (m_shared_buffer_id != -1) {
int rc;
#ifdef KERNEL
rc = current->sys$release_shared_buffer(m_shared_buffer_id);
#else
rc = release_shared_buffer(m_shared_buffer_id);
#endif
int rc = release_shared_buffer(m_shared_buffer_id);
ASSERT(rc == 0);
}
m_data = nullptr;

View file

@ -7,8 +7,6 @@
#include <AK/RetainPtr.h>
#include <AK/AKString.h>
class Region;
class GraphicsBitmap : public Retainable<GraphicsBitmap> {
public:
static RetainPtr<GraphicsBitmap> create(const Size&);
@ -25,17 +23,10 @@ public:
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
size_t pitch() const { return m_pitch; }
#ifdef KERNEL
Region* server_region() { return m_server_region; }
#endif
int shared_buffer_id() const { return m_shared_buffer_id; }
private:
#ifdef KERNEL
GraphicsBitmap(const Size&);
#endif
GraphicsBitmap(const Size&, RGBA32*);
GraphicsBitmap(int shared_buffer_id, const Size&, RGBA32*);
@ -44,10 +35,6 @@ private:
size_t m_pitch { 0 };
bool m_mmaped { false };
int m_shared_buffer_id { -1 };
#ifdef KERNEL
Region* m_server_region { nullptr };
#endif
};
inline RGBA32* GraphicsBitmap::scanline(int y)

View file

@ -4,7 +4,7 @@
#include <AK/Assertions.h>
#include <AK/StdLibExtras.h>
#ifdef USERLAND
#ifdef LIBGUI
#include <LibGUI/GWidget.h>
#include <LibGUI/GWindow.h>
#include <LibGUI/GEventLoop.h>
@ -22,7 +22,7 @@ Painter::Painter(GraphicsBitmap& bitmap)
m_clip_rect = { { 0, 0 }, bitmap.size() };
}
#ifdef USERLAND
#ifdef LIBGUI
Painter::Painter(GWidget& widget)
: m_font(&widget.font())
{
@ -30,7 +30,6 @@ Painter::Painter(GWidget& widget)
request.type = WSAPI_ClientMessage::Type::GetWindowBackingStore;
request.window_id = widget.window()->window_id();
auto response = GEventLoop::main().sync_request(request, WSAPI_ServerMessage::DidGetWindowBackingStore);
m_backing_store_id = response.backing.backing_store_id;
m_target = GraphicsBitmap::create_with_shared_buffer(response.backing.shared_buffer_id, response.backing.size);
ASSERT(m_target);
@ -50,15 +49,7 @@ Painter::Painter(GWidget& widget)
Painter::~Painter()
{
#ifdef USERLAND
m_target = nullptr;
if (m_backing_store_id) {
WSAPI_ClientMessage request;
request.type = WSAPI_ClientMessage::Type::ReleaseWindowBackingStore;
request.backing.backing_store_id = m_backing_store_id;
GEventLoop::main().post_message_to_server(request);
}
#endif
}
void Painter::fill_rect_with_draw_op(const Rect& a_rect, Color color)

View file

@ -11,7 +11,7 @@ class GlyphBitmap;
class GraphicsBitmap;
class Font;
#ifndef KERNEL
#ifdef USERLAND
class GWidget;
class GWindow;
#endif
@ -20,7 +20,7 @@ enum class TextAlignment { TopLeft, CenterLeft, Center, CenterRight };
class Painter {
public:
#ifndef KERNEL
#ifdef USERLAND
explicit Painter(GWidget&);
#endif
explicit Painter(GraphicsBitmap&);
@ -63,9 +63,8 @@ private:
Point m_translation;
Rect m_clip_rect;
RetainPtr<GraphicsBitmap> m_target;
#ifndef KERNEL
#ifdef LIBGUI
GWindow* m_window { nullptr };
void* m_backing_store_id { nullptr };
#endif
DrawOp m_draw_op { DrawOp::Copy };
};