diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index eedeaba2e50b..37c0ba2a9a84 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -294,8 +294,12 @@ class YG_EXPORT Style { Dimension axis, float referenceLength, float ownerWidth) const { - FloatOptional value = minDimension(axis).resolve(referenceLength); - if (boxSizing() == BoxSizing::BorderBox) { + const auto handle = minDimensions_[yoga::to_underlying(axis)]; + if (handle.isUndefined()) { + return FloatOptional{}; + } + FloatOptional value = resolve(handle, referenceLength); + if (boxSizing() == BoxSizing::BorderBox || !value.isDefined()) { return value; } @@ -319,8 +323,12 @@ class YG_EXPORT Style { Dimension axis, float referenceLength, float ownerWidth) const { - FloatOptional value = maxDimension(axis).resolve(referenceLength); - if (boxSizing() == BoxSizing::BorderBox) { + const auto handle = maxDimensions_[yoga::to_underlying(axis)]; + if (handle.isUndefined()) { + return FloatOptional{}; + } + FloatOptional value = resolve(handle, referenceLength); + if (boxSizing() == BoxSizing::BorderBox || !value.isDefined()) { return value; } @@ -409,8 +417,7 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float axisSize) const { - return computePosition(flexStartEdge(axis), direction) - .resolve(axisSize) + return resolve(computePosition(flexStartEdge(axis), direction), axisSize) .unwrapOrDefault(0.0f); } @@ -418,8 +425,9 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float axisSize) const { - return computePosition(inlineStartEdge(axis, direction), direction) - .resolve(axisSize) + return resolve( + computePosition(inlineStartEdge(axis, direction), direction), + axisSize) .unwrapOrDefault(0.0f); } @@ -427,8 +435,7 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float axisSize) const { - return computePosition(flexEndEdge(axis), direction) - .resolve(axisSize) + return resolve(computePosition(flexEndEdge(axis), direction), axisSize) .unwrapOrDefault(0.0f); } @@ -436,8 +443,9 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float axisSize) const { - return computePosition(inlineEndEdge(axis, direction), direction) - .resolve(axisSize) + return resolve( + computePosition(inlineEndEdge(axis, direction), direction), + axisSize) .unwrapOrDefault(0.0f); } @@ -445,8 +453,7 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float widthSize) const { - return computeMargin(flexStartEdge(axis), direction) - .resolve(widthSize) + return resolve(computeMargin(flexStartEdge(axis), direction), widthSize) .unwrapOrDefault(0.0f); } @@ -454,8 +461,9 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float widthSize) const { - return computeMargin(inlineStartEdge(axis, direction), direction) - .resolve(widthSize) + return resolve( + computeMargin(inlineStartEdge(axis, direction), direction), + widthSize) .unwrapOrDefault(0.0f); } @@ -463,8 +471,7 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float widthSize) const { - return computeMargin(flexEndEdge(axis), direction) - .resolve(widthSize) + return resolve(computeMargin(flexEndEdge(axis), direction), widthSize) .unwrapOrDefault(0.0f); } @@ -472,36 +479,36 @@ class YG_EXPORT Style { FlexDirection axis, Direction direction, float widthSize) const { - return computeMargin(inlineEndEdge(axis, direction), direction) - .resolve(widthSize) + return resolve( + computeMargin(inlineEndEdge(axis, direction), direction), + widthSize) .unwrapOrDefault(0.0f); } float computeFlexStartBorder(FlexDirection axis, Direction direction) const { return maxOrDefined( - computeBorder(flexStartEdge(axis), direction).resolve(0.0f).unwrap(), + resolve(computeBorder(flexStartEdge(axis), direction), 0.0f).unwrap(), 0.0f); } float computeInlineStartBorder(FlexDirection axis, Direction direction) const { return maxOrDefined( - computeBorder(inlineStartEdge(axis, direction), direction) - .resolve(0.0f) + resolve( + computeBorder(inlineStartEdge(axis, direction), direction), 0.0f) .unwrap(), 0.0f); } float computeFlexEndBorder(FlexDirection axis, Direction direction) const { return maxOrDefined( - computeBorder(flexEndEdge(axis), direction).resolve(0.0f).unwrap(), + resolve(computeBorder(flexEndEdge(axis), direction), 0.0f).unwrap(), 0.0f); } float computeInlineEndBorder(FlexDirection axis, Direction direction) const { return maxOrDefined( - computeBorder(inlineEndEdge(axis, direction), direction) - .resolve(0.0f) + resolve(computeBorder(inlineEndEdge(axis, direction), direction), 0.0f) .unwrap(), 0.0f); } @@ -511,8 +518,7 @@ class YG_EXPORT Style { Direction direction, float widthSize) const { return maxOrDefined( - computePadding(flexStartEdge(axis), direction) - .resolve(widthSize) + resolve(computePadding(flexStartEdge(axis), direction), widthSize) .unwrap(), 0.0f); } @@ -522,8 +528,9 @@ class YG_EXPORT Style { Direction direction, float widthSize) const { return maxOrDefined( - computePadding(inlineStartEdge(axis, direction), direction) - .resolve(widthSize) + resolve( + computePadding(inlineStartEdge(axis, direction), direction), + widthSize) .unwrap(), 0.0f); } @@ -533,8 +540,7 @@ class YG_EXPORT Style { Direction direction, float widthSize) const { return maxOrDefined( - computePadding(flexEndEdge(axis), direction) - .resolve(widthSize) + resolve(computePadding(flexEndEdge(axis), direction), widthSize) .unwrap(), 0.0f); } @@ -544,8 +550,9 @@ class YG_EXPORT Style { Direction direction, float widthSize) const { return maxOrDefined( - computePadding(inlineEndEdge(axis, direction), direction) - .resolve(widthSize) + resolve( + computePadding(inlineEndEdge(axis, direction), direction), + widthSize) .unwrap(), 0.0f); } @@ -610,13 +617,13 @@ class YG_EXPORT Style { float computeGapForAxis(FlexDirection axis, float ownerSize) const { auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); - return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f); + return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); } float computeGapForDimension(Dimension dimension, float ownerSize) const { auto gap = dimension == Dimension::Width ? computeColumnGap() : computeRowGap(); - return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f); + return maxOrDefined(resolve(gap, ownerSize).unwrap(), 0.0f); } bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { @@ -709,79 +716,82 @@ class YG_EXPORT Style { }); } - Style::Length computeColumnGap() const { + StyleValueHandle computeColumnGap() const { if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { - return pool_.getLength(gap_[yoga::to_underlying(Gutter::Column)]); + return gap_[yoga::to_underlying(Gutter::Column)]; } else { - return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); + return gap_[yoga::to_underlying(Gutter::All)]; } } - Style::Length computeRowGap() const { + StyleValueHandle computeRowGap() const { if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { - return pool_.getLength(gap_[yoga::to_underlying(Gutter::Row)]); + return gap_[yoga::to_underlying(Gutter::Row)]; } else { - return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]); + return gap_[yoga::to_underlying(Gutter::All)]; } } - Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection) - const { + StyleValueHandle computeLeftEdge( + const Edges& edges, + Direction layoutDirection) const { if (layoutDirection == Direction::LTR && edges[yoga::to_underlying(Edge::Start)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); + return edges[yoga::to_underlying(Edge::Start)]; } else if ( layoutDirection == Direction::RTL && edges[yoga::to_underlying(Edge::End)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); + return edges[yoga::to_underlying(Edge::End)]; } else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Left)]); + return edges[yoga::to_underlying(Edge::Left)]; } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); + return edges[yoga::to_underlying(Edge::Horizontal)]; } else { - return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + return edges[yoga::to_underlying(Edge::All)]; } } - Style::Length computeTopEdge(const Edges& edges) const { + StyleValueHandle computeTopEdge(const Edges& edges) const { if (edges[yoga::to_underlying(Edge::Top)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Top)]); + return edges[yoga::to_underlying(Edge::Top)]; } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); + return edges[yoga::to_underlying(Edge::Vertical)]; } else { - return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + return edges[yoga::to_underlying(Edge::All)]; } } - Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection) - const { + StyleValueHandle computeRightEdge( + const Edges& edges, + Direction layoutDirection) const { if (layoutDirection == Direction::LTR && edges[yoga::to_underlying(Edge::End)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::End)]); + return edges[yoga::to_underlying(Edge::End)]; } else if ( layoutDirection == Direction::RTL && edges[yoga::to_underlying(Edge::Start)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]); + return edges[yoga::to_underlying(Edge::Start)]; } else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Right)]); + return edges[yoga::to_underlying(Edge::Right)]; } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]); + return edges[yoga::to_underlying(Edge::Horizontal)]; } else { - return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + return edges[yoga::to_underlying(Edge::All)]; } } - Style::Length computeBottomEdge(const Edges& edges) const { + StyleValueHandle computeBottomEdge(const Edges& edges) const { if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Bottom)]); + return edges[yoga::to_underlying(Edge::Bottom)]; } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { - return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]); + return edges[yoga::to_underlying(Edge::Vertical)]; } else { - return pool_.getLength(edges[yoga::to_underlying(Edge::All)]); + return edges[yoga::to_underlying(Edge::All)]; } } - Style::Length computePosition(PhysicalEdge edge, Direction direction) const { + StyleValueHandle computePosition(PhysicalEdge edge, Direction direction) + const { switch (edge) { case PhysicalEdge::Left: return computeLeftEdge(position_, direction); @@ -796,7 +806,7 @@ class YG_EXPORT Style { } } - Style::Length computeMargin(PhysicalEdge edge, Direction direction) const { + StyleValueHandle computeMargin(PhysicalEdge edge, Direction direction) const { switch (edge) { case PhysicalEdge::Left: return computeLeftEdge(margin_, direction); @@ -811,7 +821,8 @@ class YG_EXPORT Style { } } - Style::Length computePadding(PhysicalEdge edge, Direction direction) const { + StyleValueHandle computePadding(PhysicalEdge edge, Direction direction) + const { switch (edge) { case PhysicalEdge::Left: return computeLeftEdge(padding_, direction); @@ -826,7 +837,7 @@ class YG_EXPORT Style { } } - Style::Length computeBorder(PhysicalEdge edge, Direction direction) const { + StyleValueHandle computeBorder(PhysicalEdge edge, Direction direction) const { switch (edge) { case PhysicalEdge::Left: return computeLeftEdge(border_, direction); @@ -841,6 +852,26 @@ class YG_EXPORT Style { } } + /** + * Internal resolution of a StyleValueHandle. + * + * Part of the handle-based optimization, this function allows the layout + * engine to resolve stored values (Points, Percents) directly from the pool + * via handles. This avoids the overhead of materializing an intermediate + * StyleLength/StyleSizeLength object on the stack during hot-path overhead + * calculations. + */ + FloatOptional resolve(StyleValueHandle handle, float referenceLength) const { + if (handle.isPoint()) { + return FloatOptional{pool_.getStoredValue(handle)}; + } + if (handle.isPercent()) { + return FloatOptional{ + pool_.getStoredValue(handle) * referenceLength * 0.01f}; + } + return FloatOptional{}; + } + Direction direction_ : bitCount() = Direction::Inherit; FlexDirection flexDirection_ : bitCount() = FlexDirection::Column; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h index d9c6ae05791e..6a2b58902339 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h @@ -49,6 +49,14 @@ class StyleValueHandle { return type() == Type::Auto; } + constexpr bool isPercent() const { + return type() == Type::Percent; + } + + constexpr bool isPoint() const { + return type() == Type::Point; + } + private: friend class StyleValuePool; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h index dfee30ade9f1..fb31193b9789 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h @@ -121,6 +121,16 @@ class StyleValuePool { } } + float getStoredValue(StyleValueHandle handle) const { + assert( + handle.type() == StyleValueHandle::Type::Point || + handle.type() == StyleValueHandle::Type::Percent || + handle.type() == StyleValueHandle::Type::Number); + return handle.isValueIndexed() + ? std::bit_cast(buffer_.get32(handle.value())) + : unpackInlineInteger(handle.value()); + } + private: void storeValue( StyleValueHandle& handle,