From 15f848e8d8516d7026e20e1e2984dc9373128390 Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Sun, 20 Nov 2016 04:59:55 -0800 Subject: [PATCH] Only skip updating computed flex basis within the same generation Reviewed By: dshahidehpour Differential Revision: D4207106 fbshipit-source-id: fc1063ca79ecf75f6101aadded53bca96cb0585d --- React/CSSLayout/CSSLayout.c | 16 ++++++++++------ React/CSSLayout/CSSLayout.h | 5 +++-- .../jni/first-party/csslayoutjni/jni/CSSJNI.cpp | 15 ++++++++++----- ReactCommon/CSSLayout/CSSLayout/CSSLayout.c | 16 ++++++++++------ ReactCommon/CSSLayout/CSSLayout/CSSLayout.h | 5 +++-- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/React/CSSLayout/CSSLayout.c b/React/CSSLayout/CSSLayout.c index 81795b721..9fa990b41 100644 --- a/React/CSSLayout/CSSLayout.c +++ b/React/CSSLayout/CSSLayout.c @@ -49,6 +49,7 @@ typedef struct CSSLayout { float dimensions[2]; CSSDirection direction; + uint32_t computedFlexBasisGeneration; float computedFlexBasis; // Instead of recomputing the entire layout every single time, we @@ -967,7 +968,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, if (!CSSValueIsUndefined(CSSNodeStyleGetFlexBasis(child)) && !CSSValueIsUndefined(isMainAxisRow ? width : height)) { - if (CSSValueIsUndefined(child->layout.computedFlexBasis)) { + if (CSSValueIsUndefined(child->layout.computedFlexBasis) || + child->layout.computedFlexBasisGeneration != gCurrentGenerationCount) { child->layout.computedFlexBasis = fmaxf(CSSNodeStyleGetFlexBasis(child), getPaddingAndBorderAxis(child, mainAxis)); } @@ -1052,6 +1054,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, : child->layout.measuredDimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, mainAxis)); } + + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; } static void absoluteLayoutChild(const CSSNodeRef node, @@ -1477,6 +1481,7 @@ static void layoutNodeImpl(const CSSNodeRef node, child->nextChild = NULL; } else { if (child == singleFlexChild) { + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; child->layout.computedFlexBasis = 0; } else { computeChildFlexBasis(node, @@ -1813,8 +1818,8 @@ static void layoutNodeImpl(const CSSNodeRef node, if (!CSSValueIsUndefined(node->style.minDimensions[dim[mainAxis]]) && node->style.minDimensions[dim[mainAxis]] >= 0) { remainingFreeSpace = fmaxf(0, - node->style.minDimensions[dim[mainAxis]] - - (availableInnerMainDim - remainingFreeSpace)); + node->style.minDimensions[dim[mainAxis]] - + (availableInnerMainDim - remainingFreeSpace)); } else { remainingFreeSpace = 0; } @@ -2542,10 +2547,9 @@ void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc, CSSCalloc cssCalloc, CSSRealloc cssRealloc, CSSFree cssFree) { - CSS_ASSERT(gNodeInstanceCount == 0, - "Cannot set memory functions: all node must be freed first"); + CSS_ASSERT(gNodeInstanceCount == 0, "Cannot set memory functions: all node must be freed first"); CSS_ASSERT((cssMalloc == NULL && cssCalloc == NULL && cssRealloc == NULL && cssFree == NULL) || - (cssMalloc != NULL && cssCalloc != NULL && cssRealloc != NULL && cssFree != NULL), + (cssMalloc != NULL && cssCalloc != NULL && cssRealloc != NULL && cssFree != NULL), "Cannot set memory functions: functions must be all NULL or Non-NULL"); if (cssMalloc == NULL || cssCalloc == NULL || cssRealloc == NULL || cssFree == NULL) { diff --git a/React/CSSLayout/CSSLayout.h b/React/CSSLayout/CSSLayout.h index 8e28e4f7c..e052b07e8 100644 --- a/React/CSSLayout/CSSLayout.h +++ b/React/CSSLayout/CSSLayout.h @@ -28,8 +28,8 @@ static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define CSSUndefined NAN -#include "CSSMacros.h" #include "CSSEnums.h" +#include "CSSMacros.h" CSS_EXTERN_C_BEGIN @@ -160,7 +160,8 @@ CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction); WIN_EXPORT void CSSLayoutSetLogger(CSSLogger logger); WIN_EXPORT void CSSLog(CSSLogLevel level, const char *message, ...); -WIN_EXPORT void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, bool enabled); +WIN_EXPORT void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, + bool enabled); WIN_EXPORT bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature); WIN_EXPORT void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc, diff --git a/ReactAndroid/src/main/jni/first-party/csslayoutjni/jni/CSSJNI.cpp b/ReactAndroid/src/main/jni/first-party/csslayoutjni/jni/CSSJNI.cpp index 9c3e39590..2c6ef3af9 100644 --- a/ReactAndroid/src/main/jni/first-party/csslayoutjni/jni/CSSJNI.cpp +++ b/ReactAndroid/src/main/jni/first-party/csslayoutjni/jni/CSSJNI.cpp @@ -77,12 +77,15 @@ static int _jniLog(CSSLogLevel level, const char *format, va_list args) { char buffer[256]; int result = vsnprintf(buffer, sizeof(buffer), format, args); - static auto logFunc = - findClassLocal("com/facebook/csslayout/CSSLogger")->getMethod, jstring)>("log"); + static auto logFunc = findClassLocal("com/facebook/csslayout/CSSLogger") + ->getMethod, jstring)>("log"); - static auto logLevelFromInt = JCSSLogLevel::javaClassStatic()->getStaticMethod("fromInt"); + static auto logLevelFromInt = + JCSSLogLevel::javaClassStatic()->getStaticMethod("fromInt"); - logFunc(jLogger->get(), logLevelFromInt(JCSSLogLevel::javaClassStatic(), static_cast(level)), Environment::current()->NewStringUTF(buffer)); + logFunc(jLogger->get(), + logLevelFromInt(JCSSLogLevel::javaClassStatic(), static_cast(level)), + Environment::current()->NewStringUTF(buffer)); return result; } @@ -112,7 +115,9 @@ void jni_CSSLog(alias_ref clazz, jint level, jstring message) { Environment::current()->ReleaseStringUTFChars(message, nMessage); } -void jni_CSSLayoutSetExperimentalFeatureEnabled(alias_ref clazz, jint feature, jboolean enabled) { +void jni_CSSLayoutSetExperimentalFeatureEnabled(alias_ref clazz, + jint feature, + jboolean enabled) { CSSLayoutSetExperimentalFeatureEnabled(static_cast(feature), enabled); } diff --git a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c index 81795b721..9fa990b41 100644 --- a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c +++ b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.c @@ -49,6 +49,7 @@ typedef struct CSSLayout { float dimensions[2]; CSSDirection direction; + uint32_t computedFlexBasisGeneration; float computedFlexBasis; // Instead of recomputing the entire layout every single time, we @@ -967,7 +968,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, if (!CSSValueIsUndefined(CSSNodeStyleGetFlexBasis(child)) && !CSSValueIsUndefined(isMainAxisRow ? width : height)) { - if (CSSValueIsUndefined(child->layout.computedFlexBasis)) { + if (CSSValueIsUndefined(child->layout.computedFlexBasis) || + child->layout.computedFlexBasisGeneration != gCurrentGenerationCount) { child->layout.computedFlexBasis = fmaxf(CSSNodeStyleGetFlexBasis(child), getPaddingAndBorderAxis(child, mainAxis)); } @@ -1052,6 +1054,8 @@ static void computeChildFlexBasis(const CSSNodeRef node, : child->layout.measuredDimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, mainAxis)); } + + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; } static void absoluteLayoutChild(const CSSNodeRef node, @@ -1477,6 +1481,7 @@ static void layoutNodeImpl(const CSSNodeRef node, child->nextChild = NULL; } else { if (child == singleFlexChild) { + child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; child->layout.computedFlexBasis = 0; } else { computeChildFlexBasis(node, @@ -1813,8 +1818,8 @@ static void layoutNodeImpl(const CSSNodeRef node, if (!CSSValueIsUndefined(node->style.minDimensions[dim[mainAxis]]) && node->style.minDimensions[dim[mainAxis]] >= 0) { remainingFreeSpace = fmaxf(0, - node->style.minDimensions[dim[mainAxis]] - - (availableInnerMainDim - remainingFreeSpace)); + node->style.minDimensions[dim[mainAxis]] - + (availableInnerMainDim - remainingFreeSpace)); } else { remainingFreeSpace = 0; } @@ -2542,10 +2547,9 @@ void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc, CSSCalloc cssCalloc, CSSRealloc cssRealloc, CSSFree cssFree) { - CSS_ASSERT(gNodeInstanceCount == 0, - "Cannot set memory functions: all node must be freed first"); + CSS_ASSERT(gNodeInstanceCount == 0, "Cannot set memory functions: all node must be freed first"); CSS_ASSERT((cssMalloc == NULL && cssCalloc == NULL && cssRealloc == NULL && cssFree == NULL) || - (cssMalloc != NULL && cssCalloc != NULL && cssRealloc != NULL && cssFree != NULL), + (cssMalloc != NULL && cssCalloc != NULL && cssRealloc != NULL && cssFree != NULL), "Cannot set memory functions: functions must be all NULL or Non-NULL"); if (cssMalloc == NULL || cssCalloc == NULL || cssRealloc == NULL || cssFree == NULL) { diff --git a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.h b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.h index 8e28e4f7c..e052b07e8 100644 --- a/ReactCommon/CSSLayout/CSSLayout/CSSLayout.h +++ b/ReactCommon/CSSLayout/CSSLayout/CSSLayout.h @@ -28,8 +28,8 @@ static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; #define CSSUndefined NAN -#include "CSSMacros.h" #include "CSSEnums.h" +#include "CSSMacros.h" CSS_EXTERN_C_BEGIN @@ -160,7 +160,8 @@ CSS_NODE_LAYOUT_PROPERTY(CSSDirection, Direction); WIN_EXPORT void CSSLayoutSetLogger(CSSLogger logger); WIN_EXPORT void CSSLog(CSSLogLevel level, const char *message, ...); -WIN_EXPORT void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, bool enabled); +WIN_EXPORT void CSSLayoutSetExperimentalFeatureEnabled(CSSExperimentalFeature feature, + bool enabled); WIN_EXPORT bool CSSLayoutIsExperimentalFeatureEnabled(CSSExperimentalFeature feature); WIN_EXPORT void CSSLayoutSetMemoryFuncs(CSSMalloc cssMalloc,