summaryrefslogtreecommitdiff
path: root/Widgets
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-13 00:04:23 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-13 00:04:23 +0100
commite4cb9b298579cbb8274dd9f32dd730b7249d025b (patch)
tree5894a1fbd583227f255683e7198bf7693fff77da /Widgets
parentc43903eebd23496083ec18a3b03cb1768aa1fbd0 (diff)
downloadserenity-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.cpp10
-rw-r--r--Widgets/Rect.h6
-rw-r--r--Widgets/WindowManager.cpp13
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);