Optimize edge value resolution
Summary: Noticed in simpleperf this was a very hot method, showing 8ms spent in these methods in our sample application. By splitting the method out in a horizontal and vertical variant we can simplify cases enormously and check for begin/end in one go. Changelog: [Internal] Reviewed By: SidharthGuglani Differential Revision: D27010008 fbshipit-source-id: 22fed58c7476e1d716b0191b55997c7a06e63223
This commit is contained in:
committed by
Facebook GitHub Bot
parent
342aebe1d7
commit
41384fab7b
215
yoga/YGNode.cpp
215
yoga/YGNode.cpp
@@ -50,89 +50,111 @@ void YGNode::print(void* printContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompactValue YGNode::computeEdgeValueForRow(
|
||||||
|
const YGStyle::Edges& edges,
|
||||||
|
YGEdge rowEdge,
|
||||||
|
YGEdge edge,
|
||||||
|
CompactValue defaultValue) {
|
||||||
|
if (!edges[rowEdge].isUndefined()) {
|
||||||
|
return edges[rowEdge];
|
||||||
|
} else if (!edges[edge].isUndefined()) {
|
||||||
|
return edges[edge];
|
||||||
|
} else if (!edges[YGEdgeHorizontal].isUndefined()) {
|
||||||
|
return edges[YGEdgeHorizontal];
|
||||||
|
} else if (!edges[YGEdgeAll].isUndefined()) {
|
||||||
|
return edges[YGEdgeAll];
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactValue YGNode::computeEdgeValueForColumn(
|
||||||
|
const YGStyle::Edges& edges,
|
||||||
|
YGEdge edge,
|
||||||
|
CompactValue defaultValue) {
|
||||||
|
if (!edges[edge].isUndefined()) {
|
||||||
|
return edges[edge];
|
||||||
|
} else if (!edges[YGEdgeVertical].isUndefined()) {
|
||||||
|
return edges[YGEdgeVertical];
|
||||||
|
} else if (!edges[YGEdgeAll].isUndefined()) {
|
||||||
|
return edges[YGEdgeAll];
|
||||||
|
} else {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getLeadingPosition(
|
YGFloatOptional YGNode::getLeadingPosition(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float axisSize) const {
|
const float axisSize) const {
|
||||||
if (YGFlexDirectionIsRow(axis)) {
|
auto leadingPosition = YGFlexDirectionIsRow(axis)
|
||||||
auto leadingPosition = YGComputedEdgeValue(
|
? computeEdgeValueForRow(
|
||||||
style_.position(), YGEdgeStart, CompactValue::ofUndefined());
|
style_.position(),
|
||||||
if (!leadingPosition.isUndefined()) {
|
YGEdgeStart,
|
||||||
|
leading[axis],
|
||||||
|
CompactValue::ofZero())
|
||||||
|
: computeEdgeValueForColumn(
|
||||||
|
style_.position(), leading[axis], CompactValue::ofZero());
|
||||||
return YGResolveValue(leadingPosition, axisSize);
|
return YGResolveValue(leadingPosition, axisSize);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto leadingPosition = YGComputedEdgeValue(
|
|
||||||
style_.position(), leading[axis], CompactValue::ofUndefined());
|
|
||||||
|
|
||||||
return leadingPosition.isUndefined()
|
|
||||||
? YGFloatOptional{0}
|
|
||||||
: YGResolveValue(leadingPosition, axisSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getTrailingPosition(
|
YGFloatOptional YGNode::getTrailingPosition(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float axisSize) const {
|
const float axisSize) const {
|
||||||
if (YGFlexDirectionIsRow(axis)) {
|
auto trailingPosition = YGFlexDirectionIsRow(axis)
|
||||||
auto trailingPosition = YGComputedEdgeValue(
|
? computeEdgeValueForRow(
|
||||||
style_.position(), YGEdgeEnd, CompactValue::ofUndefined());
|
style_.position(),
|
||||||
if (!trailingPosition.isUndefined()) {
|
YGEdgeEnd,
|
||||||
|
trailing[axis],
|
||||||
|
CompactValue::ofZero())
|
||||||
|
: computeEdgeValueForColumn(
|
||||||
|
style_.position(), trailing[axis], CompactValue::ofZero());
|
||||||
return YGResolveValue(trailingPosition, axisSize);
|
return YGResolveValue(trailingPosition, axisSize);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto trailingPosition = YGComputedEdgeValue(
|
|
||||||
style_.position(), trailing[axis], CompactValue::ofUndefined());
|
|
||||||
|
|
||||||
return trailingPosition.isUndefined()
|
|
||||||
? YGFloatOptional{0}
|
|
||||||
: YGResolveValue(trailingPosition, axisSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
||||||
return (YGFlexDirectionIsRow(axis) &&
|
auto leadingPosition = YGFlexDirectionIsRow(axis)
|
||||||
!YGComputedEdgeValue(
|
? computeEdgeValueForRow(
|
||||||
style_.position(), YGEdgeStart, CompactValue::ofUndefined())
|
style_.position(),
|
||||||
.isUndefined()) ||
|
YGEdgeStart,
|
||||||
!YGComputedEdgeValue(
|
leading[axis],
|
||||||
style_.position(), leading[axis], CompactValue::ofUndefined())
|
CompactValue::ofUndefined())
|
||||||
.isUndefined();
|
: computeEdgeValueForColumn(
|
||||||
|
style_.position(), leading[axis], CompactValue::ofUndefined());
|
||||||
|
return !leadingPosition.isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
|
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
|
||||||
return (YGFlexDirectionIsRow(axis) &&
|
auto trailingPosition = YGFlexDirectionIsRow(axis)
|
||||||
!YGComputedEdgeValue(
|
? computeEdgeValueForRow(
|
||||||
style_.position(), YGEdgeEnd, CompactValue::ofUndefined())
|
style_.position(),
|
||||||
.isUndefined()) ||
|
YGEdgeEnd,
|
||||||
!YGComputedEdgeValue(
|
trailing[axis],
|
||||||
style_.position(), trailing[axis], CompactValue::ofUndefined())
|
CompactValue::ofUndefined())
|
||||||
.isUndefined();
|
: computeEdgeValueForColumn(
|
||||||
|
style_.position(), trailing[axis], CompactValue::ofUndefined());
|
||||||
|
return !trailingPosition.isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getLeadingMargin(
|
YGFloatOptional YGNode::getLeadingMargin(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
auto leadingMargin = YGFlexDirectionIsRow(axis)
|
||||||
!style_.margin()[YGEdgeStart].isUndefined()) {
|
? computeEdgeValueForRow(
|
||||||
return YGResolveValueMargin(style_.margin()[YGEdgeStart], widthSize);
|
style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero())
|
||||||
}
|
: computeEdgeValueForColumn(
|
||||||
|
style_.margin(), leading[axis], CompactValue::ofZero());
|
||||||
return YGResolveValueMargin(
|
return YGResolveValueMargin(leadingMargin, widthSize);
|
||||||
YGComputedEdgeValue(
|
|
||||||
style_.margin(), leading[axis], CompactValue::ofZero()),
|
|
||||||
widthSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getTrailingMargin(
|
YGFloatOptional YGNode::getTrailingMargin(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) {
|
auto trailingMargin = YGFlexDirectionIsRow(axis)
|
||||||
return YGResolveValueMargin(style_.margin()[YGEdgeEnd], widthSize);
|
? computeEdgeValueForRow(
|
||||||
}
|
style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
||||||
|
: computeEdgeValueForColumn(
|
||||||
return YGResolveValueMargin(
|
style_.margin(), trailing[axis], CompactValue::ofZero());
|
||||||
YGComputedEdgeValue(
|
return YGResolveValueMargin(trailingMargin, widthSize);
|
||||||
style_.margin(), trailing[axis], CompactValue::ofZero()),
|
|
||||||
widthSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getMarginForAxis(
|
YGFloatOptional YGNode::getMarginForAxis(
|
||||||
@@ -147,7 +169,6 @@ YGSize YGNode::measure(
|
|||||||
float height,
|
float height,
|
||||||
YGMeasureMode heightMode,
|
YGMeasureMode heightMode,
|
||||||
void* layoutContext) {
|
void* layoutContext) {
|
||||||
|
|
||||||
return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_)
|
return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_)
|
||||||
? measure_.withContext(
|
? measure_.withContext(
|
||||||
this, width, widthMode, height, heightMode, layoutContext)
|
this, width, widthMode, height, heightMode, layoutContext)
|
||||||
@@ -448,68 +469,48 @@ bool YGNode::isNodeFlexible() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
|
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
|
||||||
YGValue leadingBorder;
|
YGValue leadingBorder = YGFlexDirectionIsRow(axis)
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
? computeEdgeValueForRow(
|
||||||
!style_.border()[YGEdgeStart].isUndefined()) {
|
style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero())
|
||||||
leadingBorder = style_.border()[YGEdgeStart];
|
: computeEdgeValueForColumn(
|
||||||
if (leadingBorder.value >= 0) {
|
|
||||||
return leadingBorder.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leadingBorder = YGComputedEdgeValue(
|
|
||||||
style_.border(), leading[axis], CompactValue::ofZero());
|
style_.border(), leading[axis], CompactValue::ofZero());
|
||||||
return YGFloatMax(leadingBorder.value, 0.0f);
|
return fmaxf(leadingBorder.value, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
|
float YGNode::getTrailingBorder(const YGFlexDirection axis) const {
|
||||||
YGValue trailingBorder;
|
YGValue trailingBorder = YGFlexDirectionIsRow(axis)
|
||||||
if (YGFlexDirectionIsRow(flexDirection) &&
|
? computeEdgeValueForRow(
|
||||||
!style_.border()[YGEdgeEnd].isUndefined()) {
|
style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
||||||
trailingBorder = style_.border()[YGEdgeEnd];
|
: computeEdgeValueForColumn(
|
||||||
if (trailingBorder.value >= 0.0f) {
|
style_.border(), trailing[axis], CompactValue::ofZero());
|
||||||
return trailingBorder.value;
|
return fmaxf(trailingBorder.value, 0.0f);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trailingBorder = YGComputedEdgeValue(
|
|
||||||
style_.border(), trailing[flexDirection], CompactValue::ofZero());
|
|
||||||
return YGFloatMax(trailingBorder.value, 0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getLeadingPadding(
|
YGFloatOptional YGNode::getLeadingPadding(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
const YGFloatOptional paddingEdgeStart =
|
auto leadingPadding = YGFlexDirectionIsRow(axis)
|
||||||
YGResolveValue(style_.padding()[YGEdgeStart], widthSize);
|
? computeEdgeValueForRow(
|
||||||
if (YGFlexDirectionIsRow(axis) &&
|
style_.padding(),
|
||||||
!style_.padding()[YGEdgeStart].isUndefined() &&
|
YGEdgeStart,
|
||||||
!paddingEdgeStart.isUndefined() && paddingEdgeStart.unwrap() >= 0.0f) {
|
leading[axis],
|
||||||
return paddingEdgeStart;
|
CompactValue::ofZero())
|
||||||
}
|
: computeEdgeValueForColumn(
|
||||||
|
style_.padding(), leading[axis], CompactValue::ofZero());
|
||||||
YGFloatOptional resolvedValue = YGResolveValue(
|
return YGFloatOptionalMax(
|
||||||
YGComputedEdgeValue(
|
YGResolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f));
|
||||||
style_.padding(), leading[axis], CompactValue::ofZero()),
|
|
||||||
widthSize);
|
|
||||||
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getTrailingPadding(
|
YGFloatOptional YGNode::getTrailingPadding(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
const YGFloatOptional paddingEdgeEnd =
|
auto trailingPadding = YGFlexDirectionIsRow(axis)
|
||||||
YGResolveValue(style_.padding()[YGEdgeEnd], widthSize);
|
? computeEdgeValueForRow(
|
||||||
if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) {
|
style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
||||||
return paddingEdgeEnd;
|
: computeEdgeValueForColumn(
|
||||||
}
|
style_.padding(), trailing[axis], CompactValue::ofZero());
|
||||||
|
return YGFloatOptionalMax(
|
||||||
YGFloatOptional resolvedValue = YGResolveValue(
|
YGResolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f));
|
||||||
YGComputedEdgeValue(
|
|
||||||
style_.padding(), trailing[axis], CompactValue::ofZero()),
|
|
||||||
widthSize);
|
|
||||||
|
|
||||||
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
|
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
|
||||||
|
@@ -193,6 +193,17 @@ public:
|
|||||||
return resolvedDimensions_[index];
|
return resolvedDimensions_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CompactValue computeEdgeValueForColumn(
|
||||||
|
const YGStyle::Edges& edges,
|
||||||
|
YGEdge edge,
|
||||||
|
CompactValue defaultValue);
|
||||||
|
|
||||||
|
static CompactValue computeEdgeValueForRow(
|
||||||
|
const YGStyle::Edges& edges,
|
||||||
|
YGEdge rowEdge,
|
||||||
|
YGEdge edge,
|
||||||
|
CompactValue defaultValue);
|
||||||
|
|
||||||
// Methods related to positions, margin, padding and border
|
// Methods related to positions, margin, padding and border
|
||||||
YGFloatOptional getLeadingPosition(
|
YGFloatOptional getLeadingPosition(
|
||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
|
@@ -104,10 +104,13 @@ static void appendEdgeIfNotUndefined(
|
|||||||
const string& str,
|
const string& str,
|
||||||
const YGStyle::Edges& edges,
|
const YGStyle::Edges& edges,
|
||||||
const YGEdge edge) {
|
const YGEdge edge) {
|
||||||
appendNumberIfNotUndefined(
|
// TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account
|
||||||
base,
|
auto value = (edge == YGEdgeLeft || edge == YGEdgeRight)
|
||||||
str,
|
? YGNode::computeEdgeValueForRow(
|
||||||
YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined()));
|
edges, edge, edge, detail::CompactValue::ofUndefined())
|
||||||
|
: YGNode::computeEdgeValueForColumn(
|
||||||
|
edges, edge, detail::CompactValue::ofUndefined());
|
||||||
|
appendNumberIfNotUndefined(base, str, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNodeToString(
|
void YGNodeToString(
|
||||||
|
@@ -144,8 +144,3 @@ static const float kDefaultFlexShrink = 0.0f;
|
|||||||
static const float kWebDefaultFlexShrink = 1.0f;
|
static const float kWebDefaultFlexShrink = 1.0f;
|
||||||
|
|
||||||
extern bool YGFloatsEqual(const float a, const float b);
|
extern bool YGFloatsEqual(const float a, const float b);
|
||||||
extern facebook::yoga::detail::CompactValue YGComputedEdgeValue(
|
|
||||||
const facebook::yoga::detail::Values<
|
|
||||||
facebook::yoga::enums::count<YGEdge>()>& edges,
|
|
||||||
YGEdge edge,
|
|
||||||
facebook::yoga::detail::CompactValue defaultValue);
|
|
||||||
|
@@ -110,36 +110,6 @@ YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
|
|||||||
return facebook::yoga::isUndefined(value);
|
return facebook::yoga::isUndefined(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::CompactValue YGComputedEdgeValue(
|
|
||||||
const YGStyle::Edges& edges,
|
|
||||||
YGEdge edge,
|
|
||||||
detail::CompactValue defaultValue) {
|
|
||||||
if (!edges[edge].isUndefined()) {
|
|
||||||
return edges[edge];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((edge == YGEdgeTop || edge == YGEdgeBottom) &&
|
|
||||||
!edges[YGEdgeVertical].isUndefined()) {
|
|
||||||
return edges[YGEdgeVertical];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart ||
|
|
||||||
edge == YGEdgeEnd) &&
|
|
||||||
!edges[YGEdgeHorizontal].isUndefined()) {
|
|
||||||
return edges[YGEdgeHorizontal];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!edges[YGEdgeAll].isUndefined()) {
|
|
||||||
return edges[YGEdgeAll];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edge == YGEdgeStart || edge == YGEdgeEnd) {
|
|
||||||
return detail::CompactValue::ofUndefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
|
YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
|
||||||
return node->getContext();
|
return node->getContext();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user