浏览代码

WindowServer: Don't re-render the window frame when not needed

Merely moving a window shouldn't require re-rendering the window
frame anymore now that we cache the rendered frame in bitmaps. This
reduces CPU usage significantly when moving windows.
Tom 4 年之前
父节点
当前提交
f8d65e57ba

+ 1 - 1
Userland/Services/WindowServer/ClientConnection.cpp

@@ -466,7 +466,7 @@ OwnPtr<Messages::WindowServer::CreateWindowResponse> ClientConnection::handle(co
     window->set_size_increment(message.size_increment());
     window->set_base_size(message.base_size());
     window->set_resize_aspect_ratio(message.resize_aspect_ratio());
-    window->invalidate();
+    window->invalidate(true, true);
     if (window->type() == WindowType::MenuApplet)
         AppletManager::the().add_applet(*window);
     m_windows.set(window_id, move(window));

+ 9 - 12
Userland/Services/WindowServer/Window.cpp

@@ -152,7 +152,7 @@ void Window::set_rect(const Gfx::IntRect& rect)
         m_backing_store = Gfx::Bitmap::create(Gfx::BitmapFormat::RGB32, m_rect.size());
     }
 
-    invalidate(true);
+    invalidate(true, old_rect.size() != rect.size());
     m_frame.notify_window_rect_changed(old_rect, rect); // recomputes occlusions
 }
 
@@ -172,7 +172,7 @@ void Window::set_rect_without_repaint(const Gfx::IntRect& rect)
         }
     }
 
-    invalidate(true);
+    invalidate(true, old_rect.size() != rect.size());
     m_frame.notify_window_rect_changed(old_rect, rect); // recomputes occlusions
 }
 
@@ -466,14 +466,15 @@ void Window::set_visible(bool b)
         Compositor::the().invalidate_screen(frame().render_rect());
 }
 
-void Window::invalidate(bool invalidate_frame)
+void Window::invalidate(bool invalidate_frame, bool re_render_frame)
 {
     m_invalidated = true;
     m_invalidated_all = true;
     if (invalidate_frame && !m_invalidated_frame) {
         m_invalidated_frame = true;
-        frame().set_dirty();
     }
+    if (re_render_frame)
+        frame().set_dirty();
     m_dirty_rects.clear();
     Compositor::the().invalidate_window();
 }
@@ -494,10 +495,8 @@ bool Window::invalidate_no_notify(const Gfx::IntRect& rect, bool with_frame)
     if (rect.is_empty())
         return false;
     if (m_invalidated_all) {
-        if (with_frame && !m_invalidated_frame) {
-            m_invalidated_frame = true;
-            frame().set_dirty();
-        }
+        if (with_frame)
+            m_invalidated_frame |= true;
         return false;
     }
 
@@ -510,10 +509,8 @@ bool Window::invalidate_no_notify(const Gfx::IntRect& rect, bool with_frame)
         return false;
 
     m_invalidated = true;
-    if (with_frame && !m_invalidated_frame) {
-        m_invalidated_frame = true;
-        frame().set_dirty();
-    }
+    if (with_frame)
+        m_invalidated_frame |= true;
     m_dirty_rects.add(inner_rect.translated(-outer_rect.location()));
     return true;
 }

+ 1 - 1
Userland/Services/WindowServer/Window.h

@@ -179,7 +179,7 @@ public:
 
     Gfx::IntSize size() const { return m_rect.size(); }
 
-    void invalidate(bool with_frame = true);
+    void invalidate(bool with_frame = true, bool re_render_frame = false);
     void invalidate(const Gfx::IntRect&, bool with_frame = false);
     bool invalidate_no_notify(const Gfx::IntRect& rect, bool with_frame = false);
 

+ 1 - 0
Userland/Services/WindowServer/WindowFrame.cpp

@@ -465,6 +465,7 @@ Gfx::IntRect WindowFrame::render_rect() const
 
 void WindowFrame::invalidate_title_bar()
 {
+    m_dirty = true;
     invalidate(title_bar_rect());
 }
 

+ 10 - 9
Userland/Services/WindowServer/WindowManager.cpp

@@ -440,7 +440,7 @@ void WindowManager::start_window_move(Window& window, const MouseEvent& event)
     m_move_window->set_default_positioned(false);
     m_move_origin = event.position();
     m_move_window_origin = window.position();
-    window.invalidate();
+    window.invalidate(true, true);
 }
 
 void WindowManager::start_window_resize(Window& window, const Gfx::IntPoint& position, MouseButton button)
@@ -475,7 +475,7 @@ void WindowManager::start_window_resize(Window& window, const Gfx::IntPoint& pos
 
     m_active_input_tracking_window = nullptr;
 
-    window.invalidate();
+    window.invalidate(true, true);
 
     if (hot_area_row == 0 || hot_area_column == 0) {
         m_resize_window->set_default_positioned(false);
@@ -495,7 +495,7 @@ bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hove
 
         dbgln_if(MOVE_DEBUG, "[WM] Finish moving Window({})", m_move_window);
 
-        m_move_window->invalidate();
+        m_move_window->invalidate(true, true);
         if (m_move_window->rect().contains(event.position()))
             hovered_window = m_move_window;
         if (m_move_window->is_resizable()) {
@@ -591,7 +591,7 @@ bool WindowManager::process_ongoing_window_resize(const MouseEvent& event, Windo
         }
 
         Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect()));
-        m_resize_window->invalidate();
+        m_resize_window->invalidate(true, true);
         if (m_resize_window->rect().contains(event.position()))
             hovered_window = m_resize_window;
         m_resize_window = nullptr;
@@ -1181,11 +1181,12 @@ void WindowManager::set_highlight_window(Window* window)
 {
     if (window == m_highlight_window)
         return;
-    if (auto* previous_highlight_window = m_highlight_window.ptr())
-        previous_highlight_window->invalidate();
+    auto* previous_highlight_window = m_highlight_window.ptr();
     m_highlight_window = window;
+    if (previous_highlight_window)
+        previous_highlight_window->invalidate(true, true);
     if (m_highlight_window)
-        m_highlight_window->invalidate();
+        m_highlight_window->invalidate(true, true);
 }
 
 bool WindowManager::is_active_window_or_accessory(Window& window) const
@@ -1267,7 +1268,7 @@ void WindowManager::set_active_window(Window* window, bool make_input)
 
     if (previously_active_window) {
         Core::EventLoop::current().post_event(*previously_active_window, make<Event>(Event::WindowDeactivated));
-        previously_active_window->invalidate();
+        previously_active_window->invalidate(true, true);
         m_active_window = nullptr;
         m_active_input_tracking_window = nullptr;
         tell_wm_listeners_window_state_changed(*previously_active_window);
@@ -1276,7 +1277,7 @@ void WindowManager::set_active_window(Window* window, bool make_input)
     if (window) {
         m_active_window = *window;
         Core::EventLoop::current().post_event(*m_active_window, make<Event>(Event::WindowActivated));
-        m_active_window->invalidate();
+        m_active_window->invalidate(true, true);
         if (auto* client = window->client()) {
             MenuManager::the().set_current_menubar(client->app_menubar());
         } else {