Browse Source

Userland: Add FB_FLUSH ioctl for fbdev

Sahan Fernando 4 years ago
parent
commit
974e996d33

+ 5 - 0
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

+ 9 - 0
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

+ 1 - 0
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);

+ 10 - 0
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<unsigned>(flush_region.x()) * scale_factor(),
+        .y = static_cast<unsigned>(flush_region.y()) * scale_factor(),
+        .width = static_cast<unsigned>(flush_region.width()) * scale_factor(),
+        .height = static_cast<unsigned>(flush_region.height() * scale_factor())
+    };
+    fb_flush_buffer(m_framebuffer_fd, &rect);
+}
 }

+ 2 - 0
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();