From 6526548b508b2ef1dd925a935520bc0469d12797 Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Mon, 21 Nov 2016 11:03:57 -0800 Subject: [PATCH] Move measure code for known dimensions out of main layout function Reviewed By: gkassabli Differential Revision: D4213339 fbshipit-source-id: 5ca35ca307594f3419fd0dee81321d3c2e06710f --- React/CSSLayout/CSSLayout.c | 92 ++++++++++----------- ReactCommon/CSSLayout/CSSLayout/CSSLayout.c | 92 ++++++++++----------- 2 files changed, 84 insertions(+), 100 deletions(-) diff --git a/React/CSSLayout/CSSLayout.c b/React/CSSLayout/CSSLayout.c index 2b8e2d610..8c0733370 100644 --- a/React/CSSLayout/CSSLayout.c +++ b/React/CSSLayout/CSSLayout.c @@ -1275,6 +1275,37 @@ static void setMeasuredDimensionsForEmptyContainer(const CSSNodeRef node, : availableHeight - marginAxisColumn); } +static bool setMeasuredDimensionsIfEmptyOrFixedSize(const CSSNodeRef node, + const float availableWidth, + const float availableHeight, + const CSSMeasureMode widthMeasureMode, + const CSSMeasureMode heightMeasureMode) { + if ((widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) || + (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) || + (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly)) { + const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); + const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + + node->layout.measuredDimensions[CSSDimensionWidth] = + boundAxis(node, + CSSFlexDirectionRow, + CSSValueIsUndefined(availableWidth) || availableWidth < 0 + ? 0 + : availableWidth - marginAxisRow); + + node->layout.measuredDimensions[CSSDimensionHeight] = + boundAxis(node, + CSSFlexDirectionColumn, + CSSValueIsUndefined(availableHeight) || availableHeight < 0 + ? 0 + : availableHeight - marginAxisColumn); + + return true; + } + + return false; +} + // // This is the main routine that implements a subset of the flexbox layout // algorithm @@ -1420,56 +1451,12 @@ static void layoutNodeImpl(const CSSNodeRef node, return; } - const float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); - const float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); - const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); - const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); - - // If we're not being asked to perform a full layout, we can handle a number - // of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but - // there is no available - // width, - // the measurement will always be zero. - if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0 && - heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, 0); - return; - } - - if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, - CSSFlexDirectionColumn, - CSSValueIsUndefined(availableHeight) ? 0 - : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = - boundAxis(node, - CSSFlexDirectionRow, - CSSValueIsUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to - // measure the children. - if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) { - node->layout.measuredDimensions[CSSDimensionWidth] = - boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn); - return; - } + // If we're not being asked to perform a full layout we can skip the algorithm if we already know + // the size + if (!performLayout && + setMeasuredDimensionsIfEmptyOrFixedSize( + node, availableWidth, availableHeight, widthMeasureMode, heightMeasureMode)) { + return; } // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM @@ -1491,6 +1478,11 @@ static void layoutNodeImpl(const CSSNodeRef node, const CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; + const float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); + const float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); + const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float availableInnerHeight = diff --git a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c index 2b8e2d610..8c0733370 100644 --- a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c +++ b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c @@ -1275,6 +1275,37 @@ static void setMeasuredDimensionsForEmptyContainer(const CSSNodeRef node, : availableHeight - marginAxisColumn); } +static bool setMeasuredDimensionsIfEmptyOrFixedSize(const CSSNodeRef node, + const float availableWidth, + const float availableHeight, + const CSSMeasureMode widthMeasureMode, + const CSSMeasureMode heightMeasureMode) { + if ((widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) || + (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) || + (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly)) { + const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); + const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + + node->layout.measuredDimensions[CSSDimensionWidth] = + boundAxis(node, + CSSFlexDirectionRow, + CSSValueIsUndefined(availableWidth) || availableWidth < 0 + ? 0 + : availableWidth - marginAxisRow); + + node->layout.measuredDimensions[CSSDimensionHeight] = + boundAxis(node, + CSSFlexDirectionColumn, + CSSValueIsUndefined(availableHeight) || availableHeight < 0 + ? 0 + : availableHeight - marginAxisColumn); + + return true; + } + + return false; +} + // // This is the main routine that implements a subset of the flexbox layout // algorithm @@ -1420,56 +1451,12 @@ static void layoutNodeImpl(const CSSNodeRef node, return; } - const float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); - const float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); - const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); - const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); - - // If we're not being asked to perform a full layout, we can handle a number - // of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but - // there is no available - // width, - // the measurement will always be zero. - if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0 && - heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, 0); - return; - } - - if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, - CSSFlexDirectionColumn, - CSSValueIsUndefined(availableHeight) ? 0 - : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { - node->layout.measuredDimensions[CSSDimensionWidth] = - boundAxis(node, - CSSFlexDirectionRow, - CSSValueIsUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to - // measure the children. - if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) { - node->layout.measuredDimensions[CSSDimensionWidth] = - boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow); - node->layout.measuredDimensions[CSSDimensionHeight] = - boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn); - return; - } + // If we're not being asked to perform a full layout we can skip the algorithm if we already know + // the size + if (!performLayout && + setMeasuredDimensionsIfEmptyOrFixedSize( + node, availableWidth, availableHeight, widthMeasureMode, heightMeasureMode)) { + return; } // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM @@ -1491,6 +1478,11 @@ static void layoutNodeImpl(const CSSNodeRef node, const CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; + const float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); + const float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); + const float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + const float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float availableInnerHeight =