summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2023-02-17 20:57:08 -0700
committerLinus Groh <mail@linusgroh.de>2023-02-19 01:15:26 +0100
commit15d4903efb5f9ce875e996dfa85082ebd97c36da (patch)
tree64b5fbd50eb1d4f9898d9d874a4c6485fa1ad6cf /Userland/Services
parent5b77346f53774fac4c9cebb73e820dafd63aaf0d (diff)
downloadserenity-15d4903efb5f9ce875e996dfa85082ebd97c36da.zip
WindowServer: Fix caching stretched wallpaper for multiple screens
This creates a cached bitmap for each unique screen resolution, which allows us to share it between displays with the same resolution. If the resolution is the same as the wallpaper, we can just use the wallpaper as-is.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/WindowServer/Compositor.cpp45
-rw-r--r--Userland/Services/WindowServer/Compositor.h2
-rw-r--r--Userland/Services/WindowServer/Screen.h1
3 files changed, 33 insertions, 15 deletions
diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp
index 6acc5300ee..26e4e74834 100644
--- a/Userland/Services/WindowServer/Compositor.cpp
+++ b/Userland/Services/WindowServer/Compositor.cpp
@@ -840,28 +840,47 @@ void Compositor::update_wallpaper_bitmap()
screen_data.clear_wallpaper_bitmap();
return IterationDecision::Continue;
}
- if (!screen_data.m_wallpaper_bitmap)
- screen_data.init_wallpaper_bitmap(screen);
- auto rect = screen_data.m_wallpaper_bitmap->rect();
- auto& painter = *screen_data.m_wallpaper_painter;
+ // See if there is another screen with the same resolution and scale.
+ // If so, we can use the same bitmap.
+ bool share_bitmap_with_other_screen = false;
+ Screen::for_each([&](Screen& screen2) {
+ if (&screen == &screen2) {
+ // Stop iterating here, we haven't updated wallpaper bitmaps for
+ // this screen and the following screens.
+ return IterationDecision::Break;
+ }
+
+ if (screen.size() == screen2.size() && screen.scale_factor() == screen2.scale_factor()) {
+ auto& screen2_data = screen2.compositor_screen_data();
- painter.draw_scaled_bitmap(rect, *m_wallpaper, m_wallpaper->rect());
+ // Use the same bitmap as the other screen
+ screen_data.m_wallpaper_bitmap = screen2_data.m_wallpaper_bitmap;
+ share_bitmap_with_other_screen = true;
+ return IterationDecision::Break;
+ }
+ return IterationDecision::Continue;
+ });
+
+ if (share_bitmap_with_other_screen)
+ return IterationDecision::Continue;
+ if (screen.size() == m_wallpaper->size() && screen.scale_factor() == m_wallpaper->scale()) {
+ // If the screen size is equal to the wallpaper size, we don't actually need to scale it
+ screen_data.m_wallpaper_bitmap = m_wallpaper;
+ } else {
+ if (!screen_data.m_wallpaper_bitmap)
+ screen_data.m_wallpaper_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, screen.size(), screen.scale_factor()).release_value_but_fixme_should_propagate_errors();
+
+ Gfx::Painter painter(*screen_data.m_wallpaper_bitmap);
+ painter.draw_scaled_bitmap(screen_data.m_wallpaper_bitmap->rect(), *m_wallpaper, m_wallpaper->rect());
+ }
return IterationDecision::Continue;
});
}
-void CompositorScreenData::init_wallpaper_bitmap(Screen& screen)
-{
- m_wallpaper_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, screen.size(), screen.scale_factor()).release_value_but_fixme_should_propagate_errors();
- m_wallpaper_painter = make<Gfx::Painter>(*m_wallpaper_bitmap);
- m_wallpaper_painter->translate(-screen.rect().location());
-}
-
void CompositorScreenData::clear_wallpaper_bitmap()
{
- m_wallpaper_painter = nullptr;
m_wallpaper_bitmap = nullptr;
}
diff --git a/Userland/Services/WindowServer/Compositor.h b/Userland/Services/WindowServer/Compositor.h
index 6862f1270e..cbbc5a4485 100644
--- a/Userland/Services/WindowServer/Compositor.h
+++ b/Userland/Services/WindowServer/Compositor.h
@@ -40,7 +40,6 @@ struct CompositorScreenData {
OwnPtr<Gfx::Painter> m_back_painter;
OwnPtr<Gfx::Painter> m_front_painter;
OwnPtr<Gfx::Painter> m_temp_painter;
- OwnPtr<Gfx::Painter> m_wallpaper_painter;
RefPtr<Gfx::Bitmap> m_cursor_back_bitmap;
OwnPtr<Gfx::Painter> m_cursor_back_painter;
Gfx::IntRect m_last_cursor_rect;
@@ -62,7 +61,6 @@ struct CompositorScreenData {
void flip_buffers(Screen&);
void draw_cursor(Screen&, Gfx::IntRect const&);
bool restore_cursor_back(Screen&, Gfx::IntRect&);
- void init_wallpaper_bitmap(Screen&);
void clear_wallpaper_bitmap();
template<typename F>
diff --git a/Userland/Services/WindowServer/Screen.h b/Userland/Services/WindowServer/Screen.h
index ef8b367ecf..64cce345bf 100644
--- a/Userland/Services/WindowServer/Screen.h
+++ b/Userland/Services/WindowServer/Screen.h
@@ -164,6 +164,7 @@ public:
Gfx::IntSize physical_size() const { return { physical_width(), physical_height() }; }
+ Gfx::IntPoint location() const { return m_virtual_rect.location(); }
Gfx::IntSize size() const { return { m_virtual_rect.width(), m_virtual_rect.height() }; }
Gfx::IntRect rect() const { return m_virtual_rect; }