[LFC][IFC] Optimize LineLayoutContext::tryAddingInlineItems for the most common inline content
https://bugs.webkit.org/show_bug.cgi?id=206372
<rdar://problem/58657525>
Reviewed by Simon Fraser.
~4% progression on PerformanceTests/Layout/line-layout-simple.html.
* layout/inlineformatting/LineLayoutContext.cpp:
(WebCore::Layout::endsWithSoftWrapOpportunity):
(WebCore::Layout::isAtSoftWrapOpportunity):
(WebCore::Layout::nextWrapOpportunity):
(WebCore::Layout::LineCandidateContent::appendInlineContent):
(WebCore::Layout::LineCandidateContent::reset):
(WebCore::Layout::LineLayoutContext::tryAddingInlineItems):
(WebCore::Layout::LineLayoutContext::commitPartialContent):
(WebCore::Layout::LineLayoutContext::commitContent): Deleted.
* layout/inlineformatting/LineLayoutContext.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6ee2a31..c3f7c6f 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,24 @@
+2020-01-16 Zalan Bujtas <zalan@apple.com>
+
+ [LFC][IFC] Optimize LineLayoutContext::tryAddingInlineItems for the most common inline content
+ https://bugs.webkit.org/show_bug.cgi?id=206372
+ <rdar://problem/58657525>
+
+ Reviewed by Simon Fraser.
+
+ ~4% progression on PerformanceTests/Layout/line-layout-simple.html.
+
+ * layout/inlineformatting/LineLayoutContext.cpp:
+ (WebCore::Layout::endsWithSoftWrapOpportunity):
+ (WebCore::Layout::isAtSoftWrapOpportunity):
+ (WebCore::Layout::nextWrapOpportunity):
+ (WebCore::Layout::LineCandidateContent::appendInlineContent):
+ (WebCore::Layout::LineCandidateContent::reset):
+ (WebCore::Layout::LineLayoutContext::tryAddingInlineItems):
+ (WebCore::Layout::LineLayoutContext::commitPartialContent):
+ (WebCore::Layout::LineLayoutContext::commitContent): Deleted.
+ * layout/inlineformatting/LineLayoutContext.h:
+
2020-01-16 Fujii Hironori <Hironori.Fujii@sony.com>
Unreviewed removing a stale FIXME comment
diff --git a/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp b/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp
index 65d636b..dfbf9ca 100644
--- a/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp
+++ b/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp
@@ -35,7 +35,7 @@
namespace WebCore {
namespace Layout {
-static bool endsWithSoftWrapOpportunity(const InlineTextItem& currentTextItem, const InlineTextItem& nextInlineTextItem)
+static inline bool endsWithSoftWrapOpportunity(const InlineTextItem& currentTextItem, const InlineTextItem& nextInlineTextItem)
{
ASSERT(!nextInlineTextItem.isWhitespace());
// We are at the position after a whitespace.
@@ -61,7 +61,7 @@
return !TextUtil::findNextBreakablePosition(lineBreakIterator, 0, nextInlineTextItem.style());
}
-static bool isAtSoftWrapOpportunity(const InlineItem& current, const InlineItem& next)
+static inline bool isAtSoftWrapOpportunity(const InlineItem& current, const InlineItem& next)
{
// "is at" simple means that there's a soft wrap opportunity right after the [current].
// [text][ ][text][container start]... (<div>text content<span>..</div>)
@@ -101,7 +101,7 @@
return endsWithSoftWrapOpportunity(currentInlineTextItem, nextInlineTextItem);
}
-static size_t nextWrapOpportunity(const InlineItems& inlineContent, unsigned startIndex)
+static inline size_t nextWrapOpportunity(const InlineItems& inlineContent, unsigned startIndex)
{
// 1. Find the start candidate by skipping leading non-content items e.g <span><span>start : skip "<span><span>"
// 2. Find the end candidate by skipping non-content items inbetween e.g. <span><span>start</span>end: skip "</span>"
@@ -200,13 +200,13 @@
const InlineItem* m_trailingLineBreak { nullptr };
};
-void LineCandidateContent::appendInlineContent(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)
+inline void LineCandidateContent::appendInlineContent(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)
{
m_inlineContentLogicalWidth += logicalWidth;
m_inlineRuns.append({ inlineItem, logicalWidth });
}
-void LineCandidateContent::reset()
+inline void LineCandidateContent::reset()
{
m_inlineContentLogicalWidth = 0;
m_inlineRuns.clear();
@@ -423,7 +423,8 @@
auto result = lineBreaker.shouldWrapInlineContent(candidateRuns, candidateContent.inlineContentLogicalWidth(), lineStatus);
if (result.action == LineBreaker::Result::Action::Keep) {
// This continuous content can be fully placed on the current line.
- commitContent(line, candidateRuns, { });
+ for (auto& run : candidateRuns)
+ line.append(run.inlineItem, run.logicalWidth);
// Consume trailing line break as well.
if (auto* lineBreakItem = candidateContent.trailingLineBreak()) {
line.append(*lineBreakItem, 0);
@@ -442,7 +443,7 @@
if (result.action == LineBreaker::Result::Action::Split) {
// Commit the combination of full and partial content on the current line.
ASSERT(result.partialTrailingContent);
- commitContent(line, candidateRuns, result.partialTrailingContent);
+ commitPartialContent(line, candidateRuns, *result.partialTrailingContent);
// When splitting multiple runs <span style="word-break: break-all">text</span><span>content</span>, we might end up splitting them at run boundary.
// It simply means we don't really have a partial run. Partial content yes, but not partial run.
auto trailingRunIndex = result.partialTrailingContent->trailingRunIndex;
@@ -459,15 +460,15 @@
return { LineBreaker::IsEndOfLine::No };
}
-void LineLayoutContext::commitContent(LineBuilder& line, const LineBreaker::RunList& runs, Optional<LineBreaker::Result::PartialTrailingContent> partialTrailingContent)
+void LineLayoutContext::commitPartialContent(LineBuilder& line, const LineBreaker::RunList& runs, const LineBreaker::Result::PartialTrailingContent& partialTrailingContent)
{
for (size_t index = 0; index < runs.size(); ++index) {
auto& run = runs[index];
- if (partialTrailingContent && partialTrailingContent->trailingRunIndex == index) {
+ if (partialTrailingContent.trailingRunIndex == index) {
ASSERT(run.inlineItem.isText());
// Create and commit partial trailing item.
- if (auto partialRun = partialTrailingContent->partialRun) {
- auto& trailingInlineTextItem = downcast<InlineTextItem>(runs[partialTrailingContent->trailingRunIndex].inlineItem);
+ if (auto partialRun = partialTrailingContent.partialRun) {
+ auto& trailingInlineTextItem = downcast<InlineTextItem>(runs[partialTrailingContent.trailingRunIndex].inlineItem);
// FIXME: LineBuilder should not hold on to the InlineItem.
ASSERT(!m_partialTrailingTextItem);
m_partialTrailingTextItem = trailingInlineTextItem.left(partialRun->length);
diff --git a/Source/WebCore/layout/inlineformatting/LineLayoutContext.h b/Source/WebCore/layout/inlineformatting/LineLayoutContext.h
index d0df8e6..9cc65a3 100644
--- a/Source/WebCore/layout/inlineformatting/LineLayoutContext.h
+++ b/Source/WebCore/layout/inlineformatting/LineLayoutContext.h
@@ -63,7 +63,7 @@
};
Result tryAddingFloatItems(LineBuilder&, const FloatList&);
Result tryAddingInlineItems(LineBreaker&, LineBuilder&, const LineCandidateContent&);
- void commitContent(LineBuilder&, const LineBreaker::RunList&, Optional<LineBreaker::Result::PartialTrailingContent>);
+ void commitPartialContent(LineBuilder&, const LineBreaker::RunList&, const LineBreaker::Result::PartialTrailingContent&);
LineContent close(LineBuilder&, unsigned leadingInlineItemIndex, unsigned committedInlineItemCount, Optional<LineContent::PartialContent>);
InlineLayoutUnit inlineItemWidth(const InlineItem&, InlineLayoutUnit contentLogicalLeft) const;