diff options
Diffstat (limited to 'Userland/Services')
-rw-r--r-- | Userland/Services/WindowServer/Compositor.cpp | 45 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Compositor.h | 2 | ||||
-rw-r--r-- | Userland/Services/WindowServer/Screen.h | 1 |
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; } |