summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
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; }