ladybird/Libraries/LibWeb/Painting/ClipFrame.cpp
Aliaksandr Kalenik 66e1d599f8
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
LibWeb: Use scroll state from snapshot while applying clip rectangles
Fixes race condition introduced in eed47acb when rendering thread
accesses ScrollFrame that could be mutated in the middle of
rasterization by the main thread, resulting in broken rendering.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/5553
2025-07-24 13:03:23 -04:00

42 lines
1.4 KiB
C++

/*
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Painting/ClipFrame.h>
namespace Web::Painting {
void ClipFrame::add_clip_rect(CSSPixelRect rect, BorderRadiiData radii, RefPtr<ScrollFrame const> enclosing_scroll_frame)
{
for (auto& existing_clip : m_clip_rects) {
if (rect == existing_clip.rect && enclosing_scroll_frame == existing_clip.enclosing_scroll_frame) {
existing_clip.corner_radii.union_max_radii(radii);
return;
}
}
Optional<size_t> enclosing_scroll_frame_id;
if (enclosing_scroll_frame)
enclosing_scroll_frame_id = enclosing_scroll_frame->id();
m_clip_rects.append({ rect, radii, move(enclosing_scroll_frame), enclosing_scroll_frame_id });
}
CSSPixelRect ClipFrame::clip_rect_for_hit_testing() const
{
VERIFY(!m_clip_rects.is_empty());
auto rect = m_clip_rects[0].rect;
if (m_clip_rects[0].enclosing_scroll_frame) {
rect.translate_by(m_clip_rects[0].enclosing_scroll_frame->cumulative_offset());
}
for (size_t i = 1; i < m_clip_rects.size(); ++i) {
auto clip_rect = m_clip_rects[i].rect;
if (m_clip_rects[i].enclosing_scroll_frame) {
clip_rect.translate_by(m_clip_rects[i].enclosing_scroll_frame->cumulative_offset());
}
rect.intersect(clip_rect);
}
return rect;
}
}