Title: [283392] trunk/Source/WebCore
Revision
283392
Author
[email protected]
Date
2021-10-01 13:20:58 -0700 (Fri, 01 Oct 2021)

Log Message

REGRESSION(r283047): PerformanceTests/Layout/line-layout-simple.html regressed by ~10%
https://bugs.webkit.org/show_bug.cgi?id=231089

Reviewed by Antti Koivisto.

Let's just hold on to the applicable RenderStyle instead of constructing a dedicated Style structure.
Note that the expected style for line breaking is not necessarily the style of the inline item (e.g. in case of an atomic inline box, it's the parent inline box's style).

* layout/formattingContexts/inline/InlineContentBreaker.cpp:
(WebCore::Layout::InlineContentBreaker::isWrappingAllowed):
(WebCore::Layout::InlineContentBreaker::shouldKeepEndOfLineWhitespace const):
(WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
(WebCore::Layout::InlineContentBreaker::wordBreakBehavior const):
(WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):
* layout/formattingContexts/inline/InlineContentBreaker.h:
(WebCore::Layout::InlineContentBreaker::ContinuousContent::Run::Run):
(WebCore::Layout::logicalWidth): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (283391 => 283392)


--- trunk/Source/WebCore/ChangeLog	2021-10-01 19:46:03 UTC (rev 283391)
+++ trunk/Source/WebCore/ChangeLog	2021-10-01 20:20:58 UTC (rev 283392)
@@ -1,5 +1,25 @@
 2021-10-01  Alan Bujtas  <[email protected]>
 
+        REGRESSION(r283047): PerformanceTests/Layout/line-layout-simple.html regressed by ~10%
+        https://bugs.webkit.org/show_bug.cgi?id=231089
+
+        Reviewed by Antti Koivisto.
+
+        Let's just hold on to the applicable RenderStyle instead of constructing a dedicated Style structure.
+        Note that the expected style for line breaking is not necessarily the style of the inline item (e.g. in case of an atomic inline box, it's the parent inline box's style).
+
+        * layout/formattingContexts/inline/InlineContentBreaker.cpp:
+        (WebCore::Layout::InlineContentBreaker::isWrappingAllowed):
+        (WebCore::Layout::InlineContentBreaker::shouldKeepEndOfLineWhitespace const):
+        (WebCore::Layout::InlineContentBreaker::processOverflowingContent const):
+        (WebCore::Layout::InlineContentBreaker::wordBreakBehavior const):
+        (WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const):
+        * layout/formattingContexts/inline/InlineContentBreaker.h:
+        (WebCore::Layout::InlineContentBreaker::ContinuousContent::Run::Run):
+        (WebCore::Layout::logicalWidth): Deleted.
+
+2021-10-01  Alan Bujtas  <[email protected]>
+
         [LFC][IFC] Add a dedicated function to set the line break box's vertical geometry
         https://bugs.webkit.org/show_bug.cgi?id=231080
 

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp (283391 => 283392)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-10-01 19:46:03 UTC (rev 283391)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp	2021-10-01 20:20:58 UTC (rev 283392)
@@ -115,7 +115,7 @@
 bool InlineContentBreaker::isWrappingAllowed(const ContinuousContent::Run& run)
 {
     // Do not try to wrap overflown 'pre' and 'no-wrap' content to next line.
-    return run.style.whiteSpace != WhiteSpace::Pre && run.style.whiteSpace != WhiteSpace::NoWrap;
+    return run.style.whiteSpace() != WhiteSpace::Pre && run.style.whiteSpace() != WhiteSpace::NoWrap;
 }
 
 bool InlineContentBreaker::shouldKeepEndOfLineWhitespace(const ContinuousContent& continuousContent) const
@@ -124,7 +124,7 @@
     // Note that the "keep" in this context means we let the whitespace content sit on the current line.
     // It might very well get collapsed when we close the line (normal/nowrap/pre-line).
     // See https://www.w3.org/TR/css-text-3/#white-space-property
-    auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace;
+    auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace();
     return whitespace == WhiteSpace::Normal || whitespace == WhiteSpace::NoWrap || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::PreLine;
 }
 
@@ -233,7 +233,7 @@
                 if (inlineTextItem.length() <= firstCodePointLength)
                     return Result { Result::Action::Keep, IsEndOfLine::Yes };
 
-                auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
+                auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade(), inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);
                 return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, PartialRun { firstCodePointLength, firstCodePointWidth } } };
             }
             if (trailingContent->overflows && lineStatus.hasContent) {
@@ -405,16 +405,16 @@
     return { overflowingRunIndex };
 }
 
-OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const ContinuousContent::Run::Style& style, bool hasWrapOpportunityAtPreviousPosition) const
+OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const RenderStyle& style, bool hasWrapOpportunityAtPreviousPosition) const
 {
     // Disregard any prohibition against line breaks mandated by the word-break property.
     // The different wrapping opportunities must not be prioritized.
     // Note hyphenation is not applied.
-    if (style.lineBreak == LineBreak::Anywhere)
+    if (style.lineBreak() == LineBreak::Anywhere)
         return { WordBreakRule::AtArbitraryPosition };
 
     auto includeHyphenationIfAllowed = [&](std::optional<InlineContentBreaker::WordBreakRule> wordBreakRule) -> OptionSet<InlineContentBreaker::WordBreakRule> {
-        auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens == Hyphens::Auto && canHyphenate(style.locale);
+        auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens() == Hyphens::Auto && canHyphenate(style.computedLocale());
         if (hyphenationIsAllowed) {
             if (wordBreakRule)
                 return { *wordBreakRule, WordBreakRule::AtHyphenationOpportunities };
@@ -425,18 +425,18 @@
         return { };
     };
     // Breaking is allowed within “words”.
-    if (style.wordBreak == WordBreak::BreakAll)
+    if (style.wordBreak() == WordBreak::BreakAll)
         return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
     // For compatibility with legacy content, the word-break property also supports a deprecated break-word keyword.
     // When specified, this has the same effect as word-break: normal and overflow-wrap: anywhere, regardless of the actual value of the overflow-wrap property.
-    if (style.wordBreak == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition)
+    if (style.wordBreak() == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition)
         return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
     // OverflowWrap::BreakWord/Anywhere An otherwise unbreakable sequence of characters may be broken at an arbitrary point if there are no otherwise-acceptable break points in the line.
     // Note that this applies to content where CSS properties (e.g. WordBreak::KeepAll) make it unbreakable. 
-    if ((style.overflowWrap == OverflowWrap::BreakWord || style.overflowWrap == OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition)
+    if ((style.overflowWrap() == OverflowWrap::BreakWord || style.overflowWrap() == OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition)
         return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition);
     // Breaking is forbidden within “words”.
-    if (style.wordBreak == WordBreak::KeepAll)
+    if (style.wordBreak() == WordBreak::KeepAll)
         return { };
     return includeHyphenationIfAllowed({ });
 }
@@ -452,6 +452,7 @@
     if (breakRules.isEmpty())
         return { };
 
+    auto& fontCascade = style.fontCascade();
     if (breakRules.contains(WordBreakRule::AtHyphenationOpportunities)) {
         auto tryBreakingAtHyphenationOpportunity = [&]() -> std::optional<PartialRun> {
             // Find the hyphen position as follows:
@@ -462,30 +463,30 @@
                 return { };
             }
             auto runLength = inlineTextItem.length();
-            auto limitBefore = style.hyphenationLimitBefore.value_or(0);
-            auto limitAfter = style.hyphenationLimitAfter.value_or(0);
+            unsigned limitBefore = style.hyphenationLimitBefore() == RenderStyle::initialHyphenationLimitBefore() ? 0 : style.hyphenationLimitBefore();
+            unsigned limitAfter = style.hyphenationLimitAfter() == RenderStyle::initialHyphenationLimitAfter() ? 0 : style.hyphenationLimitAfter();
             // Check if this run can accommodate the before/after limits at all before start measuring text.
             if (limitBefore >= runLength || limitAfter >= runLength || limitBefore + limitAfter > runLength)
                 return { };
 
             unsigned leftSideLength = runLength;
-            auto hyphenWidth = InlineLayoutUnit { style.fontCascade.width(TextRun { StringView { style.hyphenString } }) };
+            auto hyphenWidth = InlineLayoutUnit { fontCascade.width(TextRun { StringView { style.hyphenString() } }) };
             if (!availableSpaceIsInfinite) {
                 auto availableWidthExcludingHyphen = *availableWidth - hyphenWidth;
-                if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, style.fontCascade.pixelSize()))
+                if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, fontCascade.pixelSize()))
                     return { };
-                leftSideLength = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
+                leftSideLength = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;
             }
             if (leftSideLength < limitBefore)
                 return { };
             // Adjust before index to accommodate the limit-after value (it's the last potential hyphen location in this run).
             auto hyphenBefore = std::min(leftSideLength, runLength - limitAfter) + 1;
-            unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style.locale);
+            unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style.computedLocale());
             if (!hyphenLocation || hyphenLocation < limitBefore)
                 return { };
             // hyphenLocation is relative to the start of this InlineItemText.
             ASSERT(inlineTextItem.start() + hyphenLocation < inlineTextItem.end());
-            auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
+            auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);
             return PartialRun { hyphenLocation, trailingPartialRunWidthWithHyphen, hyphenWidth };
         };
         if (auto partialRun = tryBreakingAtHyphenationOpportunity())
@@ -501,7 +502,7 @@
             if (availableSpaceIsInfinite) {
                 // When the run can be split at arbitrary position let's just return the entire run when it is intended to fit on the line.
                 ASSERT(inlineTextItem.length());
-                auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, logicalLeft);
+                auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, fontCascade, logicalLeft);
                 return { inlineTextItem.length(), trailingPartialRunWidth };
             }
             if (!*availableWidth) {
@@ -508,7 +509,7 @@
                 // Fast path for cases when there's no room at all. The content is breakable but we don't have space for it.
                 return { };
             }
-            auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
+            auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);
             return { midWordBreak.length, midWordBreak.logicalWidth };
         };
         // With arbitrary breaking there's always a valid breaking position (even if it is before the first position).

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h (283391 => 283392)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-10-01 19:46:03 UTC (rev 283391)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h	2021-10-01 20:20:58 UTC (rev 283392)
@@ -91,19 +91,7 @@
             Run& operator=(const Run&);
 
             const InlineItem& inlineItem;
-            struct Style {
-                WhiteSpace whiteSpace { WhiteSpace::Normal };
-                LineBreak lineBreak { LineBreak::Auto };
-                WordBreak wordBreak { WordBreak::Normal };
-                OverflowWrap overflowWrap { OverflowWrap::Normal };
-                Hyphens hyphens { Hyphens::None };
-                std::optional<unsigned> hyphenationLimitBefore;
-                std::optional<unsigned> hyphenationLimitAfter;
-                const FontCascade& fontCascade;
-                const AtomString& hyphenString;
-                const AtomString& locale;
-            };
-            Style style;
+            const RenderStyle& style;
             InlineLayoutUnit logicalWidth { 0 };
         };
         using RunList = Vector<Run, 3>;
@@ -138,7 +126,7 @@
         AtArbitraryPosition        = 1 << 0,
         AtHyphenationOpportunities = 1 << 1
     };
-    OptionSet<WordBreakRule> wordBreakBehavior(const ContinuousContent::Run::Style&, bool hasWrapOpportunityAtPreviousPosition) const;
+    OptionSet<WordBreakRule> wordBreakBehavior(const RenderStyle&, bool hasWrapOpportunityAtPreviousPosition) const;
     bool shouldKeepEndOfLineWhitespace(const ContinuousContent&) const;
 
     bool n_hyphenationIsDisabled { false };
@@ -146,16 +134,7 @@
 
 inline InlineContentBreaker::ContinuousContent::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth)
     : inlineItem(inlineItem)
-    , style({ style.whiteSpace()
-        , style.lineBreak()
-        , style.wordBreak()
-        , style.overflowWrap()
-        , style.hyphens()
-        , style.hyphenationLimitBefore() != style.initialHyphenationLimitBefore() ? std::make_optional(style.hyphenationLimitBefore()) : std::nullopt
-        , style.hyphenationLimitAfter() != style.initialHyphenationLimitAfter() ? std::make_optional(style.hyphenationLimitAfter()) : std::nullopt
-        , style.fontCascade()
-        , (style.hyphens() == Hyphens::None ? nullAtom() : style.hyphenString())
-        , style.fontDescription().computedLocale() })
+    , style(style)
     , logicalWidth(logicalWidth)
 {
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to