diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index d245f255258986..b9758d8cfe0ccb 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -540,7 +540,7 @@ static float computeFlexBasisForChildren( const uint32_t generationCount) { float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; - const auto& children = node->getLayoutChildren(); + auto children = node->getLayoutChildren(); SizingMode sizingModeMainDim = isRow(mainAxis) ? widthSizingMode : heightSizingMode; // If there is only one child with flexGrow + flexShrink it means we can set diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp index aac495f47b7ed8..cb5c72891bb7e9 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp @@ -29,8 +29,7 @@ FlexLine calculateFlexLine( float totalFlexGrowFactors = 0.0f; float totalFlexShrinkScaledFactors = 0.0f; size_t numberOfAutoMargins = 0; - size_t endOfLineIndex = iterator.index(); - size_t firstElementInLineIndex = iterator.index(); + yoga::Node* firstElementInLine = nullptr; float sizeConsumedIncludingMinConstraint = 0; const Direction direction = node->resolveDirection(ownerDirection); @@ -40,19 +39,19 @@ FlexLine calculateFlexLine( const float gap = node->style().computeGapForAxis(mainAxis, availableInnerMainDim); + const auto childrenEnd = node->getLayoutChildren().end(); // Add items to the current line until it's full or we run out of items. - for (; iterator != node->getLayoutChildren().end(); - iterator++, endOfLineIndex = iterator.index()) { + for (; iterator != childrenEnd; iterator++) { auto child = *iterator; if (child->style().display() == Display::None || child->style().positionType() == PositionType::Absolute) { - if (firstElementInLineIndex == endOfLineIndex) { - // We haven't found the first contributing element in the line yet. - firstElementInLineIndex++; - } continue; } + if (firstElementInLine == nullptr) { + firstElementInLine = child; + } + if (child->style().flexStartMarginIsAuto(mainAxis, ownerDirection)) { numberOfAutoMargins++; } @@ -60,13 +59,11 @@ FlexLine calculateFlexLine( numberOfAutoMargins++; } - const bool isFirstElementInLine = - (endOfLineIndex - firstElementInLineIndex) == 0; - child->setLineIndex(lineCount); const float childMarginMainAxis = child->style().computeMarginForAxis(mainAxis, availableInnerWidth); - const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap; + const float childLeadingGapMainAxis = + child == firstElementInLine ? 0.0f : gap; const float flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax( child, @@ -117,7 +114,6 @@ FlexLine calculateFlexLine( return FlexLine{ .itemsInFlow = std::move(itemsInFlow), .sizeConsumed = sizeConsumed, - .endOfLineIndex = endOfLineIndex, .numberOfAutoMargins = numberOfAutoMargins, .layout = FlexLineRunningLayout{ totalFlexGrowFactors, diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h index 4dcf7a509d0e24..9ec72ea8315abc 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h @@ -49,9 +49,6 @@ struct FlexLine { // the flexible children. const float sizeConsumed{0.0f}; - // The index of the first item beyond the current line. - const size_t endOfLineIndex{0}; - // Number of edges along the line flow with an auto margin. const size_t numberOfAutoMargins{0}; diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp index 038994d70e2b08..7a694565e9b44e 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.cpp @@ -124,7 +124,7 @@ void roundLayoutResultsToPixelGrid( Dimension::Height); } - for (yoga::Node* child : node->getLayoutChildren()) { + for (yoga::Node* child : node->getChildren()) { roundLayoutResultsToPixelGrid(child, absoluteNodeLeft, absoluteNodeTop); } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h index 7d5598fb04f8c8..b158a6a6379d6c 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h @@ -4,10 +4,12 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ + #pragma once #include -#include +#include +#include #include @@ -18,7 +20,6 @@ class Node; template class LayoutableChildren { public: - using Backtrack = std::vector>; struct Iterator { using iterator_category = std::input_iterator_tag; using difference_type = std::ptrdiff_t; @@ -30,10 +31,6 @@ class LayoutableChildren { Iterator(const T* node, size_t childIndex) : node_(node), childIndex_(childIndex) {} - Iterator(const T* node, size_t childIndex, Backtrack&& backtrack) - : node_(node), - childIndex_(childIndex), - backtrack_(std::move(backtrack)) {} T* operator*() const { return node_->getChild(childIndex_); @@ -41,7 +38,6 @@ class LayoutableChildren { Iterator& operator++() { next(); - currentNodeIndex_++; return *this; } @@ -51,10 +47,6 @@ class LayoutableChildren { return tmp; } - size_t index() const { - return currentNodeIndex_; - } - friend bool operator==(const Iterator& a, const Iterator& b) { return a.node_ == b.node_ && a.childIndex_ == b.childIndex_; } @@ -68,16 +60,16 @@ class LayoutableChildren { if (childIndex_ + 1 >= node_->getChildCount()) { // if the current node has no more children, try to backtrack and // visit its successor - if (backtrack_.empty()) { + if (backtrack_.empty()) [[likely]] { // if there are no nodes to backtrack to, the last node has been // visited *this = Iterator{}; } else { // pop and restore the latest backtrack entry - const auto back = backtrack_.back(); - backtrack_.pop_back(); + const auto& back = backtrack_.front(); node_ = back.first; childIndex_ = back.second; + backtrack_.pop_front(); // go to the next node next(); @@ -87,7 +79,10 @@ class LayoutableChildren { ++childIndex_; // skip all display: contents nodes, possibly going deeper into the // tree - skipContentsNodes(); + if (node_->getChild(childIndex_)->style().display() == + Display::Contents) [[unlikely]] { + skipContentsNodes(); + } } } @@ -99,7 +94,7 @@ class LayoutableChildren { // if it has display: contents set, it shouldn't be returned but its // children should in its place push the current node and child index // so that the current state can be restored when backtracking - backtrack_.push_back({node_, childIndex_}); + backtrack_.push_front({node_, childIndex_}); // traverse the child node_ = currentNode; childIndex_ = 0; @@ -117,8 +112,7 @@ class LayoutableChildren { const T* node_{nullptr}; size_t childIndex_{0}; - size_t currentNodeIndex_{0}; - Backtrack backtrack_; + std::forward_list> backtrack_; friend LayoutableChildren; }; @@ -133,7 +127,10 @@ class LayoutableChildren { Iterator begin() const { if (node_->getChildCount() > 0) { auto result = Iterator(node_, 0); - result.skipContentsNodes(); + if (node_->getChild(0)->style().display() == Display::Contents) + [[unlikely]] { + result.skipContentsNodes(); + } return result; } else { return Iterator{};