From 0c645ba86750be07e717d11c7f36ced92fe0cf13 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 27 Jun 2024 00:39:59 +0300 Subject: [PATCH] LibGUI: Window now uses double buffering This allows data in shared memory object be always up to date. With this change window server can update lazily, and not necessarily on all invalidate calls --- userspace/libraries/LibGUI/Window.cpp | 32 +++++++++---------- .../libraries/LibGUI/include/LibGUI/Window.h | 7 ++-- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index 4fdef8bd16..39e2e40815 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -1,5 +1,7 @@ #include "LibGUI/Window.h" +#include + #include #include @@ -16,7 +18,7 @@ namespace LibGUI Window::~Window() { - munmap(m_framebuffer, m_width * m_height * 4); + munmap(m_framebuffer_smo, m_width * m_height * 4); close(m_server_fd); } @@ -25,9 +27,13 @@ namespace LibGUI if (title.size() >= sizeof(WindowCreatePacket::title)) return BAN::Error::from_errno(EINVAL); + BAN::Vector framebuffer; + TRY(framebuffer.resize(width * height)); + int server_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (server_fd == -1) return BAN::Error::from_errno(errno); + BAN::ScopeGuard server_closer([server_fd] { close(server_fd); }); if (fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_CLOEXEC) == -1) return BAN::Error::from_errno(errno); @@ -46,11 +52,8 @@ namespace LibGUI timespec current_time; clock_gettime(CLOCK_MONOTONIC, ¤t_time); time_t duration_s = (current_time.tv_sec - start_time.tv_sec) + (current_time.tv_nsec >= start_time.tv_nsec); - if (duration_s > 10) - { - close(server_fd); + if (duration_s > 1) return BAN::Error::from_errno(ETIMEDOUT); - } timespec sleep_time; sleep_time.tv_sec = 0; @@ -64,28 +67,22 @@ namespace LibGUI strncpy(packet.title, title.data(), title.size()); packet.title[title.size()] = '\0'; if (send(server_fd, &packet, sizeof(packet), 0) != sizeof(packet)) - { - close(server_fd); return BAN::Error::from_errno(errno); - } WindowCreateResponse response; if (recv(server_fd, &response, sizeof(response), 0) != sizeof(response)) - { - close(server_fd); return BAN::Error::from_errno(errno); - } void* framebuffer_addr = smo_map(response.framebuffer_smo_key); if (framebuffer_addr == nullptr) - { - close(server_fd); return BAN::Error::from_errno(errno); - } + + server_closer.disable(); return TRY(BAN::UniqPtr::create( server_fd, static_cast(framebuffer_addr), + BAN::move(framebuffer), width, height )); @@ -143,8 +140,8 @@ namespace LibGUI uint32_t amount_abs = BAN::Math::abs(amount); if (amount_abs == 0 || amount_abs >= height()) return; - uint32_t* dst = (amount > 0) ? m_framebuffer + width() * amount_abs : m_framebuffer; - uint32_t* src = (amount < 0) ? m_framebuffer + width() * amount_abs : m_framebuffer; + uint32_t* dst = (amount > 0) ? m_framebuffer.data() + width() * amount_abs : m_framebuffer.data(); + uint32_t* src = (amount < 0) ? m_framebuffer.data() + width() * amount_abs : m_framebuffer.data(); memmove(dst, src, width() * (height() - amount_abs) * 4); } @@ -172,6 +169,9 @@ namespace LibGUI if (!clamp_to_framebuffer(x, y, width, height)) return true; + for (uint32_t i = 0; i < height; i++) + memcpy(&m_framebuffer_smo[(y + i) * m_width + x], &m_framebuffer[(y + i) * m_width + x], width * sizeof(uint32_t)); + WindowInvalidatePacket packet; packet.x = x; packet.y = y; diff --git a/userspace/libraries/LibGUI/include/LibGUI/Window.h b/userspace/libraries/LibGUI/include/LibGUI/Window.h index 1a21f39b30..970538a552 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -136,9 +136,10 @@ namespace LibGUI int server_fd() const { return m_server_fd; } private: - Window(int server_fd, uint32_t* framebuffer, uint32_t width, uint32_t height) + Window(int server_fd, uint32_t* framebuffer_smo, BAN::Vector&& framebuffer, uint32_t width, uint32_t height) : m_server_fd(server_fd) , m_framebuffer(framebuffer) + , m_framebuffer_smo(framebuffer_smo) , m_width(width) , m_height(height) { } @@ -147,7 +148,9 @@ namespace LibGUI private: int m_server_fd; - uint32_t* m_framebuffer; + + BAN::Vector m_framebuffer; + uint32_t* m_framebuffer_smo; uint32_t m_width; uint32_t m_height;