mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 15:43:20 +00:00
LibWeb: Don't emit Push{Pop}StackingContext without visible effect
Before this change we would emit PushStackingContext/PopStackingContext display list items regardless of whether the stacking context had any transform/opacity/clip effects. Display list size on https://x.com/ladybirdbrowser is reduced from ~2700 to ~800 items.
This commit is contained in:
parent
2cf10981af
commit
719a50c9bf
Notes:
github-actions[bot]
2025-09-23 17:06:10 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 719a50c9bf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6283
7 changed files with 54 additions and 45 deletions
|
@ -233,6 +233,18 @@ public:
|
||||||
return determinant() != static_cast<T>(0.0);
|
return determinant() != static_cast<T>(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_identity() const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < N; ++i) {
|
||||||
|
for (size_t j = 0; j < N; ++j) {
|
||||||
|
float expected = (i == j) ? 1.0f : 0.0f;
|
||||||
|
if ((*this)[i, j] != expected)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T m_elements[N][N];
|
T m_elements[N][N];
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct StackingContextTransform {
|
||||||
Gfx::FloatMatrix4x4 matrix;
|
Gfx::FloatMatrix4x4 matrix;
|
||||||
|
|
||||||
StackingContextTransform(Gfx::FloatPoint origin, Gfx::FloatMatrix4x4 matrix, float scale);
|
StackingContextTransform(Gfx::FloatPoint origin, Gfx::FloatMatrix4x4 matrix, float scale);
|
||||||
|
|
||||||
|
[[nodiscard]] bool is_identity() const { return matrix.is_identity(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WEB_API DisplayListRecorder {
|
class WEB_API DisplayListRecorder {
|
||||||
|
@ -109,6 +111,8 @@ public:
|
||||||
bool isolate;
|
bool isolate;
|
||||||
StackingContextTransform transform;
|
StackingContextTransform transform;
|
||||||
Optional<Gfx::Path> clip_path = {};
|
Optional<Gfx::Path> clip_path = {};
|
||||||
|
|
||||||
|
bool has_effect() const { return opacity != 1.0f || compositing_and_blending_operator != Gfx::CompositingAndBlendingOperator::Normal || isolate || clip_path.has_value() || !transform.is_identity(); }
|
||||||
};
|
};
|
||||||
void push_stacking_context(PushStackingContextParams params);
|
void push_stacking_context(PushStackingContextParams params);
|
||||||
void pop_stacking_context();
|
void pop_stacking_context();
|
||||||
|
|
|
@ -331,18 +331,24 @@ void StackingContext::paint(DisplayListRecordingContext& context) const
|
||||||
paintable_box().apply_clip_overflow_rect(context, PaintPhase::Foreground);
|
paintable_box().apply_clip_overflow_rect(context, PaintPhase::Foreground);
|
||||||
}
|
}
|
||||||
paintable_box().apply_scroll_offset(context);
|
paintable_box().apply_scroll_offset(context);
|
||||||
context.display_list_recorder().push_stacking_context(push_stacking_context_params);
|
|
||||||
|
|
||||||
auto const& filter = computed_values.filter();
|
auto mask_image = computed_values.mask_image();
|
||||||
auto filter_applied = false;
|
Optional<Gfx::Filter> resolved_filter;
|
||||||
if (filter.has_filters()) {
|
if (computed_values.filter().has_filters())
|
||||||
if (auto resolved_filter = paintable_box().resolve_filter(filter); resolved_filter.has_value()) {
|
resolved_filter = paintable_box().resolve_filter(computed_values.filter());
|
||||||
context.display_list_recorder().apply_filter(*resolved_filter);
|
|
||||||
filter_applied = true;
|
bool needs_to_save_state = mask_image || paintable_box().get_masking_area().has_value();
|
||||||
}
|
|
||||||
|
if (push_stacking_context_params.has_effect()) {
|
||||||
|
context.display_list_recorder().push_stacking_context(push_stacking_context_params);
|
||||||
|
} else if (needs_to_save_state) {
|
||||||
|
context.display_list_recorder().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto mask_image = computed_values.mask_image()) {
|
if (resolved_filter.has_value())
|
||||||
|
context.display_list_recorder().apply_filter(*resolved_filter);
|
||||||
|
|
||||||
|
if (mask_image) {
|
||||||
auto mask_display_list = DisplayList::create(context.device_pixels_per_css_pixel());
|
auto mask_display_list = DisplayList::create(context.device_pixels_per_css_pixel());
|
||||||
DisplayListRecorder display_list_recorder(*mask_display_list);
|
DisplayListRecorder display_list_recorder(*mask_display_list);
|
||||||
auto mask_painting_context = context.clone(display_list_recorder);
|
auto mask_painting_context = context.clone(display_list_recorder);
|
||||||
|
@ -361,11 +367,14 @@ void StackingContext::paint(DisplayListRecordingContext& context) const
|
||||||
|
|
||||||
paint_internal(context);
|
paint_internal(context);
|
||||||
|
|
||||||
if (filter_applied) {
|
if (resolved_filter.has_value())
|
||||||
|
context.display_list_recorder().restore();
|
||||||
|
|
||||||
|
if (push_stacking_context_params.has_effect()) {
|
||||||
|
context.display_list_recorder().pop_stacking_context();
|
||||||
|
} else if (needs_to_save_state) {
|
||||||
context.display_list_recorder().restore();
|
context.display_list_recorder().restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.display_list_recorder().pop_stacking_context();
|
|
||||||
paintable_box().reset_scroll_offset(context);
|
paintable_box().reset_scroll_offset(context);
|
||||||
if (has_css_transform)
|
if (has_css_transform)
|
||||||
paintable_box().clear_clip_overflow_rect(context, PaintPhase::Foreground);
|
paintable_box().clear_clip_overflow_rect(context, PaintPhase::Foreground);
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
SaveLayer
|
SaveLayer
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
DrawGlyphRun rect=[35,8 8x18] translation=[35.15625,21.796875] color=rgb(0, 0, 0) scale=1
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
DrawGlyphRun rect=[8,8 28x18] translation=[8,21.796875] color=rgb(0, 0, 0) scale=1
|
||||||
DrawGlyphRun rect=[35,8 8x18] translation=[35.15625,21.796875] color=rgb(0, 0, 0) scale=1
|
DrawLine from=[8,24] to=[35,24] color=rgb(0, 0, 0) thickness=2
|
||||||
DrawGlyphRun rect=[8,8 28x18] translation=[8,21.796875] color=rgb(0, 0, 0) scale=1
|
DrawGlyphRun rect=[43,8 28x18] translation=[43.15625,21.796875] color=rgb(0, 0, 0) scale=1
|
||||||
DrawLine from=[8,24] to=[35,24] color=rgb(0, 0, 0) thickness=2
|
DrawLine from=[43,27] to=[71,27] color=rgb(0, 0, 0) thickness=2
|
||||||
DrawGlyphRun rect=[43,8 28x18] translation=[43.15625,21.796875] color=rgb(0, 0, 0) scale=1
|
|
||||||
DrawLine from=[43,27] to=[71,27] color=rgb(0, 0, 0) thickness=2
|
|
||||||
PopStackingContext
|
|
||||||
PopStackingContext
|
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
SaveLayer
|
SaveLayer
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillRect rect=[8,8 106x22] color=rgb(212, 208, 200)
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillPath
|
||||||
FillRect rect=[8,8 106x22] color=rgb(212, 208, 200)
|
DrawGlyphRun rect=[13,10 96x18] translation=[13,23.796875] color=rgb(0, 0, 0) scale=1
|
||||||
FillPath
|
DrawLine from=[13,26] to=[109,26] color=rgb(0, 0, 0) thickness=2
|
||||||
DrawGlyphRun rect=[13,10 96x18] translation=[13,23.796875] color=rgb(0, 0, 0) scale=1
|
|
||||||
DrawLine from=[13,26] to=[109,26] color=rgb(0, 0, 0) thickness=2
|
|
||||||
PopStackingContext
|
|
||||||
PopStackingContext
|
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
SaveLayer
|
SaveLayer
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillRect rect=[8,8 29x30] color=rgb(0, 0, 0)
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillRect rect=[38,8 28x30] color=rgb(0, 0, 0)
|
||||||
FillRect rect=[8,8 29x30] color=rgb(0, 0, 0)
|
FillRect rect=[67,8 29x30] color=rgb(0, 0, 0)
|
||||||
FillRect rect=[38,8 28x30] color=rgb(0, 0, 0)
|
FillRect rect=[97,8 28x30] color=rgb(0, 0, 0)
|
||||||
FillRect rect=[67,8 29x30] color=rgb(0, 0, 0)
|
FillRect rect=[126,8 29x30] color=rgb(0, 0, 0)
|
||||||
FillRect rect=[97,8 28x30] color=rgb(0, 0, 0)
|
|
||||||
FillRect rect=[126,8 29x30] color=rgb(0, 0, 0)
|
|
||||||
PopStackingContext
|
|
||||||
PopStackingContext
|
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
SaveLayer
|
SaveLayer
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillPath
|
||||||
PushStackingContext opacity=1 isolate=false has_clip_path=false transform=[1 0 0 1 0 0]
|
FillRect rect=[10,10 300x150] color=rgb(240, 128, 128)
|
||||||
FillPath
|
DrawGlyphRun rect=[10,10 38x18] translation=[10,23.796875] color=rgb(0, 0, 0) scale=1
|
||||||
FillRect rect=[10,10 300x150] color=rgb(240, 128, 128)
|
|
||||||
DrawGlyphRun rect=[10,10 38x18] translation=[10,23.796875] color=rgb(0, 0, 0) scale=1
|
|
||||||
PopStackingContext
|
|
||||||
PopStackingContext
|
|
||||||
Restore
|
Restore
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue