1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 04:48:14 +00:00

LibGUI+WindowServer: Coalesce paints and resizes on the client side.

Only process paint and resize events on the GUI client side if those events
have the latest up-to-date window size. This drastically reduces async
overdraw during interactive resize.
This commit is contained in:
Andreas Kling 2019-04-10 15:39:28 +02:00
parent 0ac55f2c38
commit 55811f233f
5 changed files with 50 additions and 13 deletions

View file

@ -20,6 +20,7 @@
#include <LibC/stdlib.h>
//#define GEVENTLOOP_DEBUG
//#define COALESCING_DEBUG
static HashMap<GShortcut, GAction*>* g_actions;
static GEventLoop* s_main_event_loop;
@ -352,7 +353,32 @@ void GEventLoop::wait_for_event()
void GEventLoop::process_unprocessed_messages()
{
int coalesced_paints = 0;
int coalesced_resizes = 0;
auto unprocessed_events = move(m_unprocessed_messages);
HashMap<int, Size> latest_size_for_window_id;
for (auto& event : unprocessed_events) {
if (event.type == WSAPI_ServerMessage::Type::WindowResized) {
latest_size_for_window_id.set(event.window_id, event.window.rect.size);
}
}
int paint_count = 0;
HashMap<int, Size> latest_paint_size_for_window_id;
for (auto& event : unprocessed_events) {
if (event.type == WSAPI_ServerMessage::Type::Paint) {
++paint_count;
#ifdef COALESCING_DEBUG
dbgprintf(" %s (window: %s)\n", Rect(event.paint.rect).to_string().characters(), Size(event.paint.window_size).to_string().characters());
#endif
latest_paint_size_for_window_id.set(event.window_id, event.paint.window_size);
}
}
#ifdef COALESCING_DEBUG
dbgprintf("paint_count: %d\n", paint_count);
#endif
for (auto& event : unprocessed_events) {
if (event.type == WSAPI_ServerMessage::Type::Greeting) {
s_server_pid = event.greeting.server_pid;
@ -387,6 +413,10 @@ void GEventLoop::process_unprocessed_messages()
}
switch (event.type) {
case WSAPI_ServerMessage::Type::Paint:
if (Size(event.paint.window_size) != latest_paint_size_for_window_id.get(event.window_id)) {
++coalesced_paints;
break;
}
handle_paint_event(event, *window);
break;
case WSAPI_ServerMessage::Type::MouseDown:
@ -410,6 +440,10 @@ void GEventLoop::process_unprocessed_messages()
handle_window_entered_or_left_event(event, *window);
break;
case WSAPI_ServerMessage::Type::WindowResized:
if (Size(event.window.rect.size) != latest_size_for_window_id.get(event.window_id)) {
++coalesced_resizes;
break;
}
handle_resize_event(event, *window);
break;
case WSAPI_ServerMessage::Type::WM_WindowRemoved:
@ -421,6 +455,13 @@ void GEventLoop::process_unprocessed_messages()
}
}
#ifdef COALESCING_DEBUG
if (coalesced_paints)
dbgprintf("Coalesced %d paints\n", coalesced_paints);
if (coalesced_resizes)
dbgprintf("Coalesced %d resizes\n", coalesced_resizes);
#endif
if (!m_unprocessed_messages.is_empty())
process_unprocessed_messages();
}