diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-13 00:04:23 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-13 00:04:23 +0100 |
commit | e4cb9b298579cbb8274dd9f32dd730b7249d025b (patch) | |
tree | 5894a1fbd583227f255683e7198bf7693fff77da /Widgets | |
parent | c43903eebd23496083ec18a3b03cb1768aa1fbd0 (diff) | |
download | serenity-e4cb9b298579cbb8274dd9f32dd730b7249d025b.zip |
Have WindowManager::invalidate() unite dirty rects that intersect each other.
This is kinda primitive but it avoids double-draw when slowly dragging stuff.
Diffstat (limited to 'Widgets')
-rw-r--r-- | Widgets/Rect.cpp | 10 | ||||
-rw-r--r-- | Widgets/Rect.h | 6 | ||||
-rw-r--r-- | Widgets/WindowManager.cpp | 13 |
3 files changed, 27 insertions, 2 deletions
diff --git a/Widgets/Rect.cpp b/Widgets/Rect.cpp index 4656a82f0f..95704357dc 100644 --- a/Widgets/Rect.cpp +++ b/Widgets/Rect.cpp @@ -20,3 +20,13 @@ void Rect::intersect(const Rect& other) m_size.setWidth((r - l) + 1); m_size.setHeight((b - t) + 1); } + +Rect Rect::united(const Rect& other) const +{ + Rect rect; + rect.set_left(min(left(), other.left())); + rect.set_top(min(top(), other.top())); + rect.set_right(max(right(), other.right())); + rect.set_bottom(max(bottom(), other.bottom())); + return rect; +} diff --git a/Widgets/Rect.h b/Widgets/Rect.h index 6e6ef85c76..95f98dd1c7 100644 --- a/Widgets/Rect.h +++ b/Widgets/Rect.h @@ -88,12 +88,12 @@ public: void set_right(int right) { - setWidth(right - x()); + setWidth(right - x() + 1); } void set_bottom(int bottom) { - setHeight(bottom - y()); + setHeight(bottom - y() + 1); } bool intersects(const Rect& other) const @@ -132,6 +132,8 @@ public: return r; } + Rect united(const Rect&) const; + private: Point m_location; Size m_size; diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp index 3f6ec1ef5a..7ac80bf269 100644 --- a/Widgets/WindowManager.cpp +++ b/Widgets/WindowManager.cpp @@ -8,6 +8,8 @@ #include "Process.h" #include "MemoryManager.h" +//#define DEBUG_FLUSH_YELLOW + static const int windowTitleBarHeight = 16; static inline Rect titleBarRectForWindow(const Rect& window) @@ -327,6 +329,12 @@ void WindowManager::invalidate(const Rect& a_rect) for (auto& r : m_invalidated_rects) { if (r.contains(rect)) return; + if (r.intersects(rect)) { + // Unite with the existing dirty rect. + // FIXME: It would be much nicer to compute the exact rects needing repaint. + r = r.united(rect); + return; + } } m_invalidated_rects.append(rect); @@ -350,6 +358,11 @@ void WindowManager::flush(const Rect& a_rect) const RGBA32* back_ptr = m_back_bitmap->scanline(rect.y()) + rect.x(); size_t pitch = m_back_bitmap->pitch(); +#ifdef DEBUG_FLUSH_YELLOW + Painter p(*m_front_bitmap); + p.fill_rect(rect, Color::Yellow); +#endif + for (int y = 0; y < rect.height(); ++y) { fast_dword_copy(front_ptr, back_ptr, rect.width()); front_ptr = (RGBA32*)((byte*)front_ptr + pitch); |