1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 08:38:10 +00:00

WindowServer: Fix compositor overdraw issues related to transparency

We were re-rendering areas that were considered transparency areas even
though they weren't transparency areas or were occluded by opaque
areas.

In order to fix this, we need to be a bit smarter about what is above
and below any given window. Even though a window may have transparent
areas, if those are occluded by opaque window areas on top they are
not actually any areas that should be rendered at all. And the opposite
also applies, opaque window areas for windows below that are occluded
by transparent areas, do need to be rendered as transparency. This
solves the problem of unnecessary transparency areas.

The other problem is that we need to know what areas of a window's
dirty rectangles affect other windows, and where. Basically any
opaque area that is somehow below a transparent area that isn't
otherwise occluded, and any transparent area above any other window
area (transparent or opaque) needs to be marked dirty prior to
composing. This makes sure that all affected windows render these
areas in the correct order. To track these, we now have a map of
affected windows and the rectangles that are affected (because not all
of that window's transparency areas may be affected).
This commit is contained in:
Tom 2021-07-17 21:15:17 -06:00 committed by Andreas Kling
parent 6bb1825366
commit 220886db4c
3 changed files with 129 additions and 82 deletions

View file

@ -333,6 +333,10 @@ public:
Gfx::DisjointRectSet& opaque_rects() { return m_opaque_rects; }
Gfx::DisjointRectSet& transparency_rects() { return m_transparency_rects; }
Gfx::DisjointRectSet& transparency_wallpaper_rects() { return m_transparency_wallpaper_rects; }
// The affected transparency rects are the rectangles of other windows (above or below)
// that also need to be marked dirty whenever a window's dirty rect in a transparency
// area needs to be rendered
auto& affected_transparency_rects() { return m_affected_transparency_rects; }
Menubar* menubar() { return m_menubar; }
const Menubar* menubar() const { return m_menubar; }
@ -402,6 +406,7 @@ private:
Gfx::DisjointRectSet m_opaque_rects;
Gfx::DisjointRectSet m_transparency_rects;
Gfx::DisjointRectSet m_transparency_wallpaper_rects;
HashMap<Window*, Gfx::DisjointRectSet> m_affected_transparency_rects;
WindowType m_type { WindowType::Normal };
bool m_global_cursor_tracking_enabled { false };
bool m_automatic_cursor_tracking_enabled { false };