1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 19:38:12 +00:00

WindowServer+LibGUI: Mark window bitmaps volatile in occluded windows

WindowServer now tracks whether windows are occluded (meaning that
they are completely covered by one or more opaque windows sitting above
them.) This state is communicated to the windows via WindowStateChanged
messages, which then allow GWindow to mark its backing store volatile.

This reduces the effective memory impact of windows that are not at all
visible to the user. Very cool. :^)
This commit is contained in:
Andreas Kling 2019-12-27 11:34:40 +01:00
parent 5d1acdda82
commit c7847d7c81
9 changed files with 72 additions and 10 deletions

View file

@ -298,6 +298,11 @@ bool GWindow::is_visible() const
return m_window_id != 0;
}
void GWindow::update()
{
update({ 0, 0, width(), height() });
}
void GWindow::update(const Rect& a_rect)
{
if (!m_window_id)
@ -583,17 +588,19 @@ void GWindow::update_all_windows(Badge<GWindowServerConnection>)
}
}
void GWindow::notify_state_changed(Badge<GWindowServerConnection>, bool minimized)
void GWindow::notify_state_changed(Badge<GWindowServerConnection>, bool minimized, bool occluded)
{
// When double buffering is enabled, minimization means we can mark the front bitmap volatile (in addition to the back bitmap.)
// When double buffering is enabled, minimization/occlusion means we can mark the front bitmap volatile (in addition to the back bitmap.)
// When double buffering is disabled, there is only the back bitmap (which we can now mark volatile!)
RefPtr<GraphicsBitmap>& bitmap = m_double_buffering_enabled ? m_front_bitmap : m_back_bitmap;
if (!bitmap)
return;
if (minimized) {
if (minimized || occluded) {
bitmap->shared_buffer()->set_volatile();
} else {
if (!bitmap->shared_buffer()->set_nonvolatile())
if (!bitmap->shared_buffer()->set_nonvolatile()) {
bitmap = nullptr;
update();
}
}
}

View file

@ -101,7 +101,8 @@ public:
const GWidget* focused_widget() const { return m_focused_widget; }
void set_focused_widget(GWidget*);
void update(const Rect& = Rect());
void update();
void update(const Rect&);
void set_global_cursor_tracking_widget(GWidget*);
GWidget* global_cursor_tracking_widget() { return m_global_cursor_tracking_widget.ptr(); }
@ -136,7 +137,7 @@ public:
void schedule_relayout();
static void update_all_windows(Badge<GWindowServerConnection>);
void notify_state_changed(Badge<GWindowServerConnection>, bool minimized);
void notify_state_changed(Badge<GWindowServerConnection>, bool minimized, bool occluded);
protected:
GWindow(CObject* parent = nullptr);

View file

@ -299,5 +299,5 @@ void GWindowServerConnection::handle(const WindowClient::DragCancelled&)
void GWindowServerConnection::handle(const WindowClient::WindowStateChanged& message)
{
if (auto* window = GWindow::from_window_id(message.window_id()))
window->notify_state_changed({}, message.minimized());
window->notify_state_changed({}, message.minimized(), message.occluded());
}