diff --git a/Kernel/API/FB.h b/Kernel/API/FB.h index f3a52f7c01..94b6c07677 100644 --- a/Kernel/API/FB.h +++ b/Kernel/API/FB.h @@ -38,4 +38,9 @@ ALWAYS_INLINE int fb_set_buffer(int fd, int index) return ioctl(fd, FB_IOCTL_SET_BUFFER, index); } +ALWAYS_INLINE int fb_flush_buffer(int fd, FBRect* rect) +{ + return ioctl(fd, FB_IOCTL_FLUSH_BUFFER, rect); +} + __END_DECLS diff --git a/Userland/Libraries/LibC/sys/ioctl_numbers.h b/Userland/Libraries/LibC/sys/ioctl_numbers.h index 6123e9496d..87d5e2cf1d 100644 --- a/Userland/Libraries/LibC/sys/ioctl_numbers.h +++ b/Userland/Libraries/LibC/sys/ioctl_numbers.h @@ -23,6 +23,13 @@ struct FBResolution { unsigned height; }; +struct FBRect { + unsigned x; + unsigned y; + unsigned width; + unsigned height; +}; + __END_DECLS enum IOCtlNumber { @@ -43,6 +50,7 @@ enum IOCtlNumber { FB_IOCTL_SET_RESOLUTION, FB_IOCTL_GET_BUFFER, FB_IOCTL_SET_BUFFER, + FB_IOCTL_FLUSH_BUFFER, SIOCSIFADDR, SIOCGIFADDR, SIOCGIFHWADDR, @@ -75,6 +83,7 @@ enum IOCtlNumber { #define FB_IOCTL_SET_RESOLUTION FB_IOCTL_SET_RESOLUTION #define FB_IOCTL_GET_BUFFER FB_IOCTL_GET_BUFFER #define FB_IOCTL_SET_BUFFER FB_IOCTL_SET_BUFFER +#define FB_IOCTL_FLUSH_BUFFER FB_IOCTL_FLUSH_BUFFER #define SIOCSIFADDR SIOCSIFADDR #define SIOCGIFADDR SIOCGIFADDR #define SIOCGIFHWADDR SIOCGIFHWADDR diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index 962b0c3b49..54141bc686 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -662,6 +662,7 @@ void Compositor::flush(Screen& screen) from_ptr = (const Gfx::RGBA32*)((const u8*)from_ptr + pitch); to_ptr = (Gfx::RGBA32*)((u8*)to_ptr + pitch); } + screen.flush_display(a_rect.intersected(screen.rect())); }; for (auto& rect : screen_data.m_flush_rects.rects()) do_flush(rect); diff --git a/Userland/Services/WindowServer/Screen.cpp b/Userland/Services/WindowServer/Screen.cpp index 83bdd5a9ab..fc7497db0d 100644 --- a/Userland/Services/WindowServer/Screen.cpp +++ b/Userland/Services/WindowServer/Screen.cpp @@ -316,4 +316,14 @@ void ScreenInput::on_receive_keyboard_data(::KeyEvent kernel_event) Core::EventLoop::current().post_event(WindowManager::the(), move(message)); } +void Screen::flush_display(const Gfx::IntRect& flush_region) +{ + FBRect rect { + .x = static_cast(flush_region.x()) * scale_factor(), + .y = static_cast(flush_region.y()) * scale_factor(), + .width = static_cast(flush_region.width()) * scale_factor(), + .height = static_cast(flush_region.height() * scale_factor()) + }; + fb_flush_buffer(m_framebuffer_fd, &rect); +} } diff --git a/Userland/Services/WindowServer/Screen.h b/Userland/Services/WindowServer/Screen.h index 353f7231a8..3e653174d1 100644 --- a/Userland/Services/WindowServer/Screen.h +++ b/Userland/Services/WindowServer/Screen.h @@ -160,6 +160,8 @@ public: Gfx::IntSize size() const { return { m_virtual_rect.width(), m_virtual_rect.height() }; } Gfx::IntRect rect() const { return m_virtual_rect; } + void flush_display(const Gfx::IntRect& rect); + private: Screen(ScreenLayout::Screen&); bool open_device();