Commit graph

20 commits

Author SHA1 Message Date
Aliaksandr Kalenik
36acd1cf3d LibWeb: Rebuild stacking context tree on any z-index value change
The stacking context tree rebuild had an optimization that skipped
rebuilding when a property changed between two values that both create
stacking contexts. This is correct for most properties (e.g. opacity
0.5 -> 0.8 doesn't change tree structure), but incorrect for z-index.

During tree construction, elements with z-index 0/auto are placed in
m_positioned_descendants_and_stacking_contexts_with_stack_level_0,
while elements with other z-index values are painted from m_children
(negative at step 3, positive at step 9 per CSS 2.1 Appendix E).
When z-index changed between non-auto values (e.g. 0 -> 10), the
optimization skipped the rebuild, leaving the element in the wrong
list and causing it to be painted from both step 8 and step 9.

This was visible on pages like shopify.com where elements with
transition-all would transition z-index, producing a flood of
"Painting commands are recorded twice for stacking context" messages.
2026-02-17 20:44:46 +01:00
Psychpsyo
6ea528f0ec LibWeb: Do not create a layer when CSS isolation is set to isolate
This is entirely unnecessary. All that this property does is create a
stacking context.
2026-02-13 11:02:32 +00:00
Aliaksandr Kalenik
24f6e697d9 LibWeb: Optimize stacking context tree rebuilds
Previously, any change to a property that affects stacking context would
trigger a full stacking context tree rebuild. However, an element only
creates or destroys a stacking context when a property crosses from its
"neutral" value to a "creating" value (or vice versa).

For example, animating `transform: translateX(10px)` to
`transform: translateX(20px)` previously triggered stacking context
rebuilds on every frame, but this is unnecessary because the stacking
context already exists.
2026-01-28 18:05:41 +01:00
Aliaksandr Kalenik
96a39aeaa6 LibWeb: Move effects application into AccumulatedVisualContext
Effects (opacity, blend mode, filters) must be applied in the parent's
coordinate space, before the element's transform. Previously this was
handled by manually switching to the parent's visual context when
applying effects at paint time.

By adding EffectsData to AccumulatedVisualContext and positioning it
before TransformData in the chain, effects are now naturally applied in
the correct order during display list replay, eliminating the special
case in StackingContext::paint().

For SVG filters that can generate content from empty elements (feFlood,
feImage, feTurbulence), a transparent FillRect command is emitted to
trigger the filter through the same AVC pipeline.
2026-01-21 16:19:18 +01:00
Aliaksandr Kalenik
c9a8ca3b8c LibWeb: Rebuild AccumulatedVisualContext on clip property changes
AccumulatedVisualContext nodes capture a snapshot of the current clip
rect when the tree is built, so we must invalidate whenever the clip
property changes.
2026-01-19 04:01:37 +01:00
Aliaksandr Kalenik
eb860e2f10 LibWeb: Rebuild AccumulatedVisualContext on clip-path changes
AccumulatedVisualContext nodes capture a snapshot of the current
clip-path when the tree is built, so we must invalidate whenever the
clip-path changes.

Fixes regression introduced in 98afd82
2026-01-19 04:01:37 +01:00
Aliaksandr Kalenik
04c3ad669b LibWeb: Rebuild AccumulatedVisualContext on transform changes
Ensure AccumulatedVisualContext stays synchronized when CSS transform
properties change.

AccumulatedVisualContext copies transform and perspective matrices from
the paintable tree at assignment time. When CSS properties that affect
these matrices change (transform, rotate, scale, translate, perspective,
transform-origin, perspective-origin), we must rebuild the
AccumulatedVisualContext tree to reflect the new values.

This adds a rebuild_accumulated_visual_contexts flag to style
invalidation that triggers a full rebuild during the next paint.

Note: The current invalidation strategy is inefficient - it rebuilds
the entire tree even for single-element transform changes. This could
be improved by patching the AccumulatedVisualContext node in-place with
updated matrices, but only when the transform doesn't transition
from/to none (which would change the tree structure). This optimization
is left for future work.
2026-01-15 19:50:53 +01:00
Callum Law
5381146e85 LibWeb: Include PropertyID.h in fewer header files
This reduces the size of the recompile when PropertyID.h is modified
from ~1500 to ~125
2025-10-27 14:50:54 +00:00
Callum Law
1ba84de4f6 LibWeb: Store opacity in computed form in ComputedProperties 2025-09-08 11:03:32 +01:00
Callum Law
5c2fe12772 LibWeb: Don't consider null -> null as a change for invalidation
This avoids excessive invalidation within `recompute_inherited_style`
where we inherit a value but not an animated value.
2025-08-22 12:17:55 +02:00
Andreas Kling
05d6090fcc Revert "LibWeb: Invalidate layout on opacity change to/from zero"
This partially reverts commit 3aff3327c4
by removing the code change but keeping the added test.

Now that paintables visibility caching has been reverted, this is no
longer doing anything except causing excessive relayouts on pages
like https://linear.app/
2025-08-20 09:14:58 +02:00
Callum Law
3aff3327c4 LibWeb: Invalidate layout on opacity change to/from zero
As of 7dc8062 paintables compute and cache their visibility (which
depends on opacity) at construction - this cached value can fall out of
sync with reality if if the opacity changes to/from zero within the
lifetime of that paintable.

This commit invalidates layout when an opacity changes to/from zero so
that we reconstruct paintables with the correct visibility.
2025-08-18 10:21:44 +01:00
Sam Atkins
4e92ab52e3 LibWeb/CSS: Rename CSSKeywordValue -> KeywordStyleValue
The typed-om CSSKeywordValue will need to be a separate class.
2025-08-08 15:19:03 +01:00
Sam Atkins
c57975c9fd LibWeb: Move and rename CSSStyleValue to StyleValues/StyleValue.{h,cpp}
This reverts 0e3487b9ab.

Back when I made that change, I thought we could make our StyleValue
classes match the typed-om definitions directly. However, they have
different requirements. Typed-om types need to be mutable and GCed,
whereas StyleValues are immutable and ideally wouldn't require a JS VM.

While I was already making such a cataclysmic change, I've moved it into
the StyleValues directory, because it *not* being there has bothered me
for a long time. 😅
2025-08-08 15:19:03 +01:00
Manuel Zahariev
99c6eb0c35 LibWeb/CSS: Invalidate layout tree for changes to counter definitions
A change to a counter "definition" propagates to all subsequent
instances of this counter: descendents, siblings and their descendents
(the "next tree slice"). Rebuilding the layout tree (from the parent
node) covers at least the "next_tree_slice".
2025-06-03 03:51:42 +02:00
Andreas Kling
821d54de7f LibWeb: Invalidate layout tree on CSS position property change
When position changes, we may need to make larger structural updates
to the layout tree. A simple relayout is not sufficient.

This was a source of flakiness in the engine, and gives us at least
+28 new WPT subtest passes.
2025-05-20 13:28:40 +02:00
Andreas Kling
0a300fe59b LibWeb: Update the layout tree when CSS text-transform changes
Because we cache the transformed text string in text nodes affected by
text-transform, we have to actually update the layout tree when this
property value changes.
2025-03-08 20:22:01 +01:00
Andreas Kling
c53c781745 LibWeb: Inline CSSStyleValue::to_keyword()
Shaves 120 ms of loading time off of https://wpt.fyi/
2025-01-28 01:12:45 +01:00
Andreas Kling
c1cad8fa0e LibWeb: Rename CSS::StyleProperties => CSS::ComputedProperties
Now that StyleProperties is only used to hold computed properties, let's
name it ComputedProperties.
2024-12-22 10:12:49 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Renamed from Userland/Libraries/LibWeb/CSS/StyleInvalidation.cpp (Browse further)