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:
parent
0ac55f2c38
commit
55811f233f
5 changed files with 50 additions and 13 deletions
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue