Skip to content

Commit

Permalink
[IFC][Cleanup] InlineDamage::type is redundant
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=271533

Reviewed by Antti Koivisto.

1. Content and/or style change always initiates InlineDamage (with a reason)
2. Partial layout happens when
  - there's an InlineDamage and
  - we manage to figure out a start layout position for all the damages (in many cases there's only one change)

There may be cases with multiple changes when
- we manage to find the layout position (partial layout candidate) for the first damage
- but fail at a subsequent change
In such cases we reset the "layout start position" indicating full layout, but we keep the reason.
(in other words, decouple reason(s) the partial layout)

This setups renders InlineDamage::Type::Invalid redundant. However we can't just
destroy m_inlineDamage as we have to keep it around for "detached" content.

* Source/WebCore/layout/formattingContexts/inline/invalidation/InlineDamage.h:
(WebCore::Layout::InlineDamage::setDamageReason):
(WebCore::Layout::InlineDamage::resetLayoutPosition):
(WebCore::Layout::InlineDamage::type const): Deleted.
(WebCore::Layout::InlineDamage::setDamageType): Deleted.
(WebCore::Layout::InlineDamage::reset): Deleted.
* Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp:
(WebCore::Layout::InlineInvalidation::updateInlineDamage):
(WebCore::Layout::InlineInvalidation::setFullLayoutIfNeeded):
(WebCore::Layout::InlineInvalidation::textInserted):
(WebCore::Layout::InlineInvalidation::textWillBeRemoved):
(WebCore::Layout::InlineInvalidation::inlineLevelBoxInserted):
(WebCore::Layout::InlineInvalidation::inlineLevelBoxWillBeRemoved):
(WebCore::Layout::InlineInvalidation::restartForPagination):
(WebCore::Layout::InlineInvalidation::applyFullDamageIfNeeded): Deleted.
* Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.h:

Canonical link: https://commits.webkit.org/276617@main
  • Loading branch information
alanbaradlay committed Mar 25, 2024
1 parent 8763b25 commit cc88128
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ class InlineDamage {
InlineDamage() = default;
~InlineDamage();

enum class Type : uint8_t {
// Can't decide the type of damage. Let's nuke all the things.
Invalid,
NeedsContentUpdateAndLineLayout,
};
Type type() const { return m_damageType; }

enum class Reason : uint8_t {
Append = 1 << 0,
Insert = 1 << 1,
Expand All @@ -58,13 +51,15 @@ class InlineDamage {
Pagination = 1 << 5
};
OptionSet<Reason> reasons() const { return m_damageReasons; }

// FIXME: Add support for damage range with multiple, different damage types.
struct LayoutPosition {
size_t lineIndex { 0 };
InlineItemPosition inlineItemPosition { };
LayoutUnit partialContentTop;
};
std::optional<LayoutPosition> layoutStartPosition() const { return m_layoutStartPosition; }

using TrailingDisplayBoxList = Vector<InlineDisplay::Box>;
std::optional<InlineDisplay::Box> trailingContentForLine(size_t lineIndex) const;

Expand All @@ -78,12 +73,10 @@ class InlineDamage {
friend class InlineInvalidation;

void setDamageReason(Reason reason) { m_damageReasons.add(reason); }
void setDamageType(Type type) { m_damageType = type; }
void setLayoutStartPosition(LayoutPosition position) { m_layoutStartPosition = position; }
void reset();
void resetLayoutPosition();
void setTrailingDisplayBoxes(TrailingDisplayBoxList&& trailingDisplayBoxes) { m_trailingDisplayBoxes = WTFMove(trailingDisplayBoxes); }

Type m_damageType { Type::Invalid };
OptionSet<Reason> m_damageReasons;
std::optional<LayoutPosition> m_layoutStartPosition;
TrailingDisplayBoxList m_trailingDisplayBoxes;
Expand Down Expand Up @@ -114,10 +107,8 @@ inline InlineDamage::~InlineDamage()
m_detachedLayoutBoxes.clear();
}

inline void InlineDamage::reset()
inline void InlineDamage::resetLayoutPosition()
{
m_damageType = { };
m_damageReasons = { };
m_layoutStartPosition = { };
m_trailingDisplayBoxes.clear();
// Never reset m_detachedLayoutBoxes. We need to keep those layout boxes around until after layout.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,62 +334,60 @@ static InlineDamage::TrailingDisplayBoxList trailingDisplayBoxesAfterDamagedLine
return trailingDisplayBoxes;
}

void InlineInvalidation::updateInlineDamage(InlineDamage::Type type, std::optional<InlineDamage::Reason> reason, std::optional<InvalidatedLine> invalidatedLine, ShouldApplyRangeLayout shouldApplyRangeLayout, LayoutUnit pageTopAdjustment)
bool InlineInvalidation::updateInlineDamage(const InvalidatedLine& invalidatedLine, InlineDamage::Reason reason, ShouldApplyRangeLayout shouldApplyRangeLayout, LayoutUnit pageTopAdjustment)
{
if (type == InlineDamage::Type::Invalid || !invalidatedLine)
return m_inlineDamage.reset();
auto isValidDamage = [&] {
// Check for consistency.
if (!invalidatedLine->leadingInlineItemPosition) {
if (!invalidatedLine.leadingInlineItemPosition) {
// We have to start at the first line if damage points to the leading inline item.
return !invalidatedLine->index;
return !invalidatedLine.index;
}
return true;
};
if (!isValidDamage()) {
ASSERT_NOT_REACHED();
m_inlineDamage.reset();
return;
m_inlineDamage.resetLayoutPosition();
return false;
}

auto partialContentTop = LayoutUnit { invalidatedLine->index ? m_displayContent.lines[invalidatedLine->index - 1].lineBoxLogicalRect().maxY() : 0 } + pageTopAdjustment;
auto partialContentTop = LayoutUnit { invalidatedLine.index ? m_displayContent.lines[invalidatedLine.index - 1].lineBoxLogicalRect().maxY() : 0 } + pageTopAdjustment;

auto layoutStartPosition = InlineDamage::LayoutPosition {
invalidatedLine->index,
invalidatedLine->leadingInlineItemPosition,
invalidatedLine.index,
invalidatedLine.leadingInlineItemPosition,
partialContentTop
};

m_inlineDamage.setDamageType(type);
m_inlineDamage.setDamageReason(*reason);
m_inlineDamage.setDamageReason(reason);
m_inlineDamage.setLayoutStartPosition(WTFMove(layoutStartPosition));

if (shouldApplyRangeLayout == ShouldApplyRangeLayout::Yes)
m_inlineDamage.setTrailingDisplayBoxes(trailingDisplayBoxesAfterDamagedLine(invalidatedLine->index, m_displayContent));
m_inlineDamage.setTrailingDisplayBoxes(trailingDisplayBoxesAfterDamagedLine(invalidatedLine.index, m_displayContent));
return true;
}

static bool isSupportedContent(const Box& layoutBox)
{
return is<InlineTextBox>(layoutBox) || layoutBox.isLineBreakBox() || layoutBox.isReplacedBox() || layoutBox.isInlineBox();
}

bool InlineInvalidation::applyFullDamageIfNeeded(const Box& layoutBox)
bool InlineInvalidation::setFullLayoutIfNeeded(const Box& layoutBox)
{
if (!isSupportedContent(layoutBox)) {
ASSERT_NOT_REACHED();
updateInlineDamage(InlineDamage::Type::Invalid, { }, { });
m_inlineDamage.resetLayoutPosition();
return true;
}

if (displayBoxes().isEmpty()) {
ASSERT_NOT_REACHED();
updateInlineDamage(InlineDamage::Type::Invalid, { }, { });
m_inlineDamage.resetLayoutPosition();
return true;
}

if (m_inlineItemList.isEmpty()) {
// We must be under memory pressure.
updateInlineDamage(InlineDamage::Type::Invalid, { }, { });
m_inlineDamage.resetLayoutPosition();
return true;
}

Expand All @@ -398,7 +396,7 @@ bool InlineInvalidation::applyFullDamageIfNeeded(const Box& layoutBox)

bool InlineInvalidation::textInserted(const InlineTextBox& newOrDamagedInlineTextBox, std::optional<size_t> offset)
{
if (applyFullDamageIfNeeded(newOrDamagedInlineTextBox))
if (setFullLayoutIfNeeded(newOrDamagedInlineTextBox))
return false;

auto& displayBoxes = this->displayBoxes();
Expand Down Expand Up @@ -428,23 +426,28 @@ bool InlineInvalidation::textInserted(const InlineTextBox& newOrDamagedInlineTex
break;
}

updateInlineDamage(!invalidatedLine ? InlineDamage::Type::Invalid : InlineDamage::Type::NeedsContentUpdateAndLineLayout, damageReason, invalidatedLine, offset ? ShouldApplyRangeLayout::No : ShouldApplyRangeLayout::Yes);
return invalidatedLine.has_value();
if (invalidatedLine)
return updateInlineDamage(*invalidatedLine, damageReason, offset ? ShouldApplyRangeLayout::No : ShouldApplyRangeLayout::Yes);

m_inlineDamage.resetLayoutPosition();
return false;
}

bool InlineInvalidation::textWillBeRemoved(const InlineTextBox& damagedInlineTextBox, std::optional<size_t> offset)
{
if (applyFullDamageIfNeeded(damagedInlineTextBox))
if (setFullLayoutIfNeeded(damagedInlineTextBox))
return false;

auto invalidatedLine = invalidatedLineByDamagedBox({ damagedInlineTextBox, offset.value_or(0), DamagedContent::Type::Removal }, m_inlineItemList, displayBoxes());
updateInlineDamage(!invalidatedLine ? InlineDamage::Type::Invalid : InlineDamage::Type::NeedsContentUpdateAndLineLayout, InlineDamage::Reason::Remove, invalidatedLine, ShouldApplyRangeLayout::No);
return invalidatedLine.has_value();
if (auto invalidatedLine = invalidatedLineByDamagedBox({ damagedInlineTextBox, offset.value_or(0), DamagedContent::Type::Removal }, m_inlineItemList, displayBoxes()))
return updateInlineDamage(*invalidatedLine, InlineDamage::Reason::Remove, ShouldApplyRangeLayout::No);

m_inlineDamage.resetLayoutPosition();
return false;
}

bool InlineInvalidation::inlineLevelBoxInserted(const Box& layoutBox)
{
if (applyFullDamageIfNeeded(layoutBox))
if (setFullLayoutIfNeeded(layoutBox))
return false;

auto& displayBoxes = this->displayBoxes();
Expand All @@ -453,7 +456,7 @@ bool InlineInvalidation::inlineLevelBoxInserted(const Box& layoutBox)
// New box got appended. Let's dirty the last line.
if (m_inlineDamage.reasons() == InlineDamage::Reason::Append) {
// Series of append operations always produces the same damage position.
return m_inlineDamage.type() != InlineDamage::Type::Invalid;
return m_inlineDamage.layoutStartPosition().has_value();
}
ASSERT(!m_inlineDamage.reasons());
if (auto leadingInlineItemPosition = leadingInlineItemPositionOnLastLine(m_inlineItemList, displayBoxes)) {
Expand All @@ -466,18 +469,23 @@ bool InlineInvalidation::inlineLevelBoxInserted(const Box& layoutBox)
if (auto* previousSibling = layoutBox.previousInFlowSibling())
invalidatedLine = invalidatedLineByDamagedBox({ *previousSibling }, m_inlineItemList, displayBoxes);
}
updateInlineDamage(!invalidatedLine ? InlineDamage::Type::Invalid : InlineDamage::Type::NeedsContentUpdateAndLineLayout, !layoutBox.nextInFlowSibling() ? InlineDamage::Reason::Append : InlineDamage::Reason::Insert, invalidatedLine, ShouldApplyRangeLayout::Yes);
return invalidatedLine.has_value();
if (invalidatedLine)
return updateInlineDamage(*invalidatedLine, !layoutBox.nextInFlowSibling() ? InlineDamage::Reason::Append : InlineDamage::Reason::Insert, ShouldApplyRangeLayout::Yes);

m_inlineDamage.resetLayoutPosition();
return false;
}

bool InlineInvalidation::inlineLevelBoxWillBeRemoved(const Box& layoutBox)
{
if (applyFullDamageIfNeeded(layoutBox))
if (setFullLayoutIfNeeded(layoutBox))
return false;

auto invalidatedLine = invalidatedLineByDamagedBox({ layoutBox, { }, DamagedContent::Type::Removal }, m_inlineItemList, displayBoxes());
updateInlineDamage(!invalidatedLine ? InlineDamage::Type::Invalid : InlineDamage::Type::NeedsContentUpdateAndLineLayout, InlineDamage::Reason::Remove, invalidatedLine, ShouldApplyRangeLayout::Yes);
return invalidatedLine.has_value();
if (auto invalidatedLine = invalidatedLineByDamagedBox({ layoutBox, { }, DamagedContent::Type::Removal }, m_inlineItemList, displayBoxes()))
return updateInlineDamage(*invalidatedLine, InlineDamage::Reason::Remove, ShouldApplyRangeLayout::Yes);

m_inlineDamage.resetLayoutPosition();
return false;
}

void InlineInvalidation::restartForPagination(size_t lineIndex, LayoutUnit pageTopAdjustment)
Expand All @@ -489,9 +497,7 @@ void InlineInvalidation::restartForPagination(size_t lineIndex, LayoutUnit pageT
if (!leadingContentDisplayBoxOnDamagedLine)
return;

auto invalidatedLine = InvalidatedLine { lineIndex, *inlineItemPositionForLeadingDisplayBox };

updateInlineDamage(InlineDamage::Type::NeedsContentUpdateAndLineLayout, InlineDamage::Reason::Pagination, invalidatedLine, ShouldApplyRangeLayout::Yes, pageTopAdjustment);
updateInlineDamage({ lineIndex, *inlineItemPositionForLeadingDisplayBox }, InlineDamage::Reason::Pagination, ShouldApplyRangeLayout::Yes, pageTopAdjustment);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class InlineInvalidation {

private:
enum class ShouldApplyRangeLayout : bool { No, Yes };
void updateInlineDamage(InlineDamage::Type, std::optional<InlineDamage::Reason>, std::optional<InvalidatedLine>, ShouldApplyRangeLayout = ShouldApplyRangeLayout::No, LayoutUnit restartPaginationAdjustment = 0_lu);
bool applyFullDamageIfNeeded(const Box&);
bool updateInlineDamage(const InvalidatedLine&, InlineDamage::Reason, ShouldApplyRangeLayout = ShouldApplyRangeLayout::No, LayoutUnit restartPaginationAdjustment = 0_lu);
bool setFullLayoutIfNeeded(const Box&);
const InlineDisplay::Boxes& displayBoxes() const { return m_displayContent.boxes; }
const InlineDisplay::Lines& displayLines() const { return m_displayContent.lines; }

Expand Down

0 comments on commit cc88128

Please sign in to comment.