diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index c1ae95202d..83c7116318 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -591,15 +591,28 @@ void Compositor::flush(Screen& screen) } screen_data.m_have_flush_rects = false; + auto screen_rect = screen.rect(); if (m_flash_flush) { - for (auto& rect : screen_data.m_flush_rects.rects()) + Gfx::IntRect bounding_flash; + for (auto& rect : screen_data.m_flush_rects.rects()) { screen_data.m_front_painter->fill_rect(rect, Color::Yellow); - for (auto& rect : screen_data.m_flush_transparent_rects.rects()) + bounding_flash = bounding_flash.united(rect); + } + for (auto& rect : screen_data.m_flush_transparent_rects.rects()) { screen_data.m_front_painter->fill_rect(rect, Color::Green); - usleep(10000); + bounding_flash = bounding_flash.united(rect); + } + if (!bounding_flash.is_empty()) { + if (device_can_flush_buffers) { + // If the device needs a flush we need to let it know that we + // modified the front buffer! + bounding_flash.translate_by(-screen_rect.location()); + screen.flush_display_front_buffer((!screen_data.m_screen_can_set_buffer || !screen_data.m_buffers_are_flipped) ? 0 : 1, bounding_flash); + } + usleep(10000); + } } - auto screen_rect = screen.rect(); if (device_can_flush_buffers && screen_data.m_screen_can_set_buffer) { if (!screen_data.m_has_flipped) { // If we have not flipped any buffers before, we should be flushing @@ -680,7 +693,7 @@ void Compositor::flush(Screen& screen) // Instead, we skip this step and just keep track of them until shortly before the next flip. // If we however don't support flipping buffers then we need to flush the changed areas right // now so that they can be sent to the device. - screen.flush_display(screen_data.m_buffers_are_flipped ? 0 : 1); + screen.flush_display(screen_data.m_buffers_are_flipped ? 1 : 0); } } diff --git a/Userland/Services/WindowServer/Screen.cpp b/Userland/Services/WindowServer/Screen.cpp index 12703f8889..d108156578 100644 --- a/Userland/Services/WindowServer/Screen.cpp +++ b/Userland/Services/WindowServer/Screen.cpp @@ -413,4 +413,25 @@ void Screen::flush_display(int buffer_index) fb_data.too_many_pending_flush_rects = false; fb_data.pending_flush_rects.clear_with_capacity(); } + +void Screen::flush_display_front_buffer(int front_buffer_index, Gfx::IntRect& rect) +{ + VERIFY(m_can_device_flush_buffers); + auto scale_factor = this->scale_factor(); + FBRect flush_rect { + x : (unsigned)(rect.x() * scale_factor), + y : (unsigned)(rect.y() * scale_factor), + width : (unsigned)(rect.width() * scale_factor), + height : (unsigned)(rect.height() * scale_factor) + }; + + if (fb_flush_buffers(m_framebuffer_fd, front_buffer_index, &flush_rect, 1) < 0) { + int err = errno; + if (err == ENOTSUP) + m_can_device_flush_buffers = false; + else + dbgln("Screen #{}: Error ({}) flushing display front buffer: {}", index(), err, strerror(err)); + } +} + } diff --git a/Userland/Services/WindowServer/Screen.h b/Userland/Services/WindowServer/Screen.h index 159e830584..2182c9c139 100644 --- a/Userland/Services/WindowServer/Screen.h +++ b/Userland/Services/WindowServer/Screen.h @@ -167,6 +167,7 @@ public: bool can_device_flush_buffers() const { return m_can_device_flush_buffers; } void queue_flush_display_rect(Gfx::IntRect const& rect); void flush_display(int buffer_index); + void flush_display_front_buffer(int front_buffer_index, Gfx::IntRect&); private: Screen(ScreenLayout::Screen&);