summaryrefslogtreecommitdiff
path: root/Terminal
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-26 05:20:32 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-26 05:20:32 +0100
commit7cf3c7461c54ea6bdcfdbd47f1e2644ca5d0f35a (patch)
tree686fd26a6bdef3da271d773fac53d24608fbc47e /Terminal
parent3a401d5249a453f952086e7096499853961bb2f3 (diff)
downloadserenity-7cf3c7461c54ea6bdcfdbd47f1e2644ca5d0f35a.zip
Refactor GUI rendering model to be two-phased.
Instead of clients painting whenever they feel like it, we now ask that they paint in response to a paint message. After finishing painting, clients notify the WindowServer about the rect(s) they painted into and then flush eventually happens, etc. This stuff leaves us with a lot of badly named things. Need to fix that.
Diffstat (limited to 'Terminal')
-rw-r--r--Terminal/Terminal.cpp39
-rw-r--r--Terminal/Terminal.h4
-rw-r--r--Terminal/main.cpp4
3 files changed, 32 insertions, 15 deletions
diff --git a/Terminal/Terminal.cpp b/Terminal/Terminal.cpp
index a4a00df443..b4decc8ef1 100644
--- a/Terminal/Terminal.cpp
+++ b/Terminal/Terminal.cpp
@@ -88,7 +88,7 @@ Terminal::Line::Line(word columns)
{
characters = new byte[length];
attributes = new Attribute[length];
- needs_invalidation = false;
+ did_paint = false;
memset(characters, ' ', length);
}
@@ -603,7 +603,7 @@ void Terminal::paint()
Painter painter(*m_backing);
for (size_t i = 0; i < rows(); ++i)
- line(i).needs_invalidation = false;
+ line(i).did_paint = false;
if (m_rows_to_scroll_backing_store && m_rows_to_scroll_backing_store < m_rows) {
int first_scanline = m_inset;
@@ -630,7 +630,7 @@ void Terminal::paint()
painter.fill_rect(row_rect(row), line.attributes[0].background_color);
for (word column = 0; column < m_columns; ++column) {
auto& attribute = line.attributes[column];
- line.needs_invalidation = true;
+ line.did_paint = true;
char ch = line.characters[column];
auto character_rect = glyph_rect(row, column);
if (!has_only_one_background_color) {
@@ -649,7 +649,7 @@ void Terminal::paint()
else
painter.draw_rect(cursor_rect, Color::MidGray);
- line(m_cursor_row).needs_invalidation = true;
+ line(m_cursor_row).did_paint = true;
if (m_belling) {
m_need_full_invalidation = true;
@@ -657,23 +657,38 @@ void Terminal::paint()
}
if (m_need_full_invalidation) {
- invalidate_window();
+ did_paint();
m_need_full_invalidation = false;
return;
}
- Rect invalidation_rect;
+ Rect painted_rect;
for (int i = 0; i < m_rows; ++i) {
- if (line(i).needs_invalidation)
- invalidation_rect = invalidation_rect.united(row_rect(i));
+ if (line(i).did_paint)
+ painted_rect = painted_rect.united(row_rect(i));
}
- invalidate_window(invalidation_rect);
+ did_paint(painted_rect);
}
-void Terminal::invalidate_window(const Rect& a_rect)
+void Terminal::did_paint(const Rect& a_rect)
{
GUI_Rect rect = a_rect;
- int rc = gui_invalidate_window(m_window_id, a_rect.is_null() ? nullptr : &rect);
+ int rc = gui_notify_paint_finished(m_window_id, a_rect.is_null() ? nullptr : &rect);
+ if (rc < 0) {
+ perror("gui_notify_paint_finished");
+ exit(1);
+ }
+}
+
+void Terminal::update()
+{
+ Rect rect;
+ for (int i = 0; i < m_rows; ++i) {
+ if (line(i).did_paint)
+ rect = rect.united(row_rect(i));
+ }
+ GUI_Rect gui_rect = rect;
+ int rc = gui_invalidate_window(m_window_id, rect.is_null() ? nullptr : &gui_rect);
if (rc < 0) {
perror("gui_invalidate_window");
exit(1);
@@ -695,7 +710,7 @@ void Terminal::set_in_active_window(bool b)
return;
m_in_active_window = b;
invalidate_cursor();
- paint();
+ update();
}
void Terminal::invalidate_cursor()
diff --git a/Terminal/Terminal.h b/Terminal/Terminal.h
index 3c8f6a2a1f..ed43ac5e8b 100644
--- a/Terminal/Terminal.h
+++ b/Terminal/Terminal.h
@@ -18,6 +18,7 @@ public:
void on_char(byte);
void set_in_active_window(bool);
+ void update();
private:
Font& font() { return *m_font; }
@@ -25,6 +26,7 @@ private:
void set_cursor(unsigned row, unsigned column);
void put_character_at(unsigned row, unsigned column, byte ch);
void invalidate_cursor();
+ void did_paint(const Rect& = Rect());
void invalidate_window(const Rect& = Rect());
void set_window_title(const String&);
@@ -67,7 +69,7 @@ private:
bool has_only_one_background_color() const;
byte* characters { nullptr };
Attribute* attributes { nullptr };
- bool needs_invalidation { false };
+ bool did_paint { false };
bool dirty { false };
word length { 0 };
};
diff --git a/Terminal/main.cpp b/Terminal/main.cpp
index 6242246cf2..34a3b7cd5a 100644
--- a/Terminal/main.cpp
+++ b/Terminal/main.cpp
@@ -77,7 +77,7 @@ int main(int, char**)
Terminal terminal;
terminal.create_window();
- terminal.paint();
+ terminal.update();
for (;;) {
fd_set rfds;
@@ -100,7 +100,7 @@ int main(int, char**)
assert(nread != 0);
for (ssize_t i = 0; i < nread; ++i)
terminal.on_char(buffer[i]);
- terminal.paint();
+ terminal.update();
}
if (FD_ISSET(event_fd, &rfds)) {