Don't transfer layout outputs to java for nodes which don't have a new layout

Summary:
As suggested in facebook/yoga#484. This is the PR which only adds the part of using a local bool field for storing the hasLayoutFlag, to be able to pass the layout only if it has really changed.
Closes https://github.com/facebook/yoga/pull/492

Reviewed By: astreet

Differential Revision: D4786961

Pulled By: emilsjolander

fbshipit-source-id: cf3d354b93f6dcc3ef817ef73a47bd29e37d1848
This commit is contained in:
Lukas Wöhrl
2017-03-29 16:39:24 -07:00
committed by Facebook Github Bot
parent 60db018ce4
commit 5884ab7b76
2 changed files with 52 additions and 56 deletions

View File

@@ -81,6 +81,8 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
private float mBorderBottom = 0; private float mBorderBottom = 0;
@DoNotStrip @DoNotStrip
private int mLayoutDirection = 0; private int mLayoutDirection = 0;
@DoNotStrip
private boolean mHasNewLayout = true;
private native long jni_YGNodeNew(); private native long jni_YGNodeNew();
public YogaNode() { public YogaNode() {
@@ -115,6 +117,7 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
mHasSetMargin = false; mHasSetMargin = false;
mHasSetBorder = false; mHasSetBorder = false;
mHasSetPosition = false; mHasSetPosition = false;
mHasNewLayout = true;
mWidth = YogaConstants.UNDEFINED; mWidth = YogaConstants.UNDEFINED;
mHeight = YogaConstants.UNDEFINED; mHeight = YogaConstants.UNDEFINED;
@@ -180,10 +183,9 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
jni_YGNodeCalculateLayout(mNativePointer, width, height); jni_YGNodeCalculateLayout(mNativePointer, width, height);
} }
private native boolean jni_YGNodeHasNewLayout(long nativePointer);
@Override @Override
public boolean hasNewLayout() { public boolean hasNewLayout() {
return jni_YGNodeHasNewLayout(mNativePointer); return mHasNewLayout;
} }
private native void jni_YGNodeMarkDirty(long nativePointer); private native void jni_YGNodeMarkDirty(long nativePointer);
@@ -198,18 +200,17 @@ public class YogaNode implements YogaNodeAPI<YogaNode> {
return jni_YGNodeIsDirty(mNativePointer); return jni_YGNodeIsDirty(mNativePointer);
} }
private native void jni_YGNodeMarkLayoutSeen(long nativePointer);
@Override
public void markLayoutSeen() {
jni_YGNodeMarkLayoutSeen(mNativePointer);
}
private native void jni_YGNodeCopyStyle(long dstNativePointer, long srcNativePointer); private native void jni_YGNodeCopyStyle(long dstNativePointer, long srcNativePointer);
@Override @Override
public void copyStyle(YogaNode srcNode) { public void copyStyle(YogaNode srcNode) {
jni_YGNodeCopyStyle(mNativePointer, srcNode.mNativePointer); jni_YGNodeCopyStyle(mNativePointer, srcNode.mNativePointer);
} }
@Override
public void markLayoutSeen() {
mHasNewLayout = false;
}
private native int jni_YGNodeStyleGetDirection(long nativePointer); private native int jni_YGNodeStyleGetDirection(long nativePointer);
@Override @Override
public YogaDirection getStyleDirection() { public YogaDirection getStyleDirection() {

View File

@@ -24,54 +24,59 @@ static void YGTransferLayoutDirection(YGNodeRef node, alias_ref<jobject> javaNod
} }
static void YGTransferLayoutOutputsRecursive(YGNodeRef root) { static void YGTransferLayoutOutputsRecursive(YGNodeRef root) {
if (auto obj = YGNodeJobject(root)->lockLocal()) { if(YGNodeGetHasNewLayout(root)){
static auto widthField = obj->getClass()->getField<jfloat>("mWidth"); if (auto obj = YGNodeJobject(root)->lockLocal()) {
static auto heightField = obj->getClass()->getField<jfloat>("mHeight"); static auto widthField = obj->getClass()->getField<jfloat>("mWidth");
static auto leftField = obj->getClass()->getField<jfloat>("mLeft"); static auto heightField = obj->getClass()->getField<jfloat>("mHeight");
static auto topField = obj->getClass()->getField<jfloat>("mTop"); static auto leftField = obj->getClass()->getField<jfloat>("mLeft");
static auto topField = obj->getClass()->getField<jfloat>("mTop");
static auto marginLeftField = obj->getClass()->getField<jfloat>("mMarginLeft"); static auto marginLeftField = obj->getClass()->getField<jfloat>("mMarginLeft");
static auto marginTopField = obj->getClass()->getField<jfloat>("mMarginTop"); static auto marginTopField = obj->getClass()->getField<jfloat>("mMarginTop");
static auto marginRightField = obj->getClass()->getField<jfloat>("mMarginRight"); static auto marginRightField = obj->getClass()->getField<jfloat>("mMarginRight");
static auto marginBottomField = obj->getClass()->getField<jfloat>("mMarginBottom"); static auto marginBottomField = obj->getClass()->getField<jfloat>("mMarginBottom");
static auto paddingLeftField = obj->getClass()->getField<jfloat>("mPaddingLeft"); static auto paddingLeftField = obj->getClass()->getField<jfloat>("mPaddingLeft");
static auto paddingTopField = obj->getClass()->getField<jfloat>("mPaddingTop"); static auto paddingTopField = obj->getClass()->getField<jfloat>("mPaddingTop");
static auto paddingRightField = obj->getClass()->getField<jfloat>("mPaddingRight"); static auto paddingRightField = obj->getClass()->getField<jfloat>("mPaddingRight");
static auto paddingBottomField = obj->getClass()->getField<jfloat>("mPaddingBottom"); static auto paddingBottomField = obj->getClass()->getField<jfloat>("mPaddingBottom");
static auto borderLeftField = obj->getClass()->getField<jfloat>("mBorderLeft"); static auto borderLeftField = obj->getClass()->getField<jfloat>("mBorderLeft");
static auto borderTopField = obj->getClass()->getField<jfloat>("mBorderTop"); static auto borderTopField = obj->getClass()->getField<jfloat>("mBorderTop");
static auto borderRightField = obj->getClass()->getField<jfloat>("mBorderRight"); static auto borderRightField = obj->getClass()->getField<jfloat>("mBorderRight");
static auto borderBottomField = obj->getClass()->getField<jfloat>("mBorderBottom"); static auto borderBottomField = obj->getClass()->getField<jfloat>("mBorderBottom");
obj->setFieldValue(widthField, YGNodeLayoutGetWidth(root)); static auto hasNewLayoutField = obj->getClass()->getField<jboolean>("mHasNewLayout");
obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root));
obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root));
obj->setFieldValue(topField, YGNodeLayoutGetTop(root));
obj->setFieldValue(marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft)); obj->setFieldValue(widthField, YGNodeLayoutGetWidth(root));
obj->setFieldValue(marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop)); obj->setFieldValue(heightField, YGNodeLayoutGetHeight(root));
obj->setFieldValue(marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight)); obj->setFieldValue(leftField, YGNodeLayoutGetLeft(root));
obj->setFieldValue(marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom)); obj->setFieldValue(topField, YGNodeLayoutGetTop(root));
obj->setFieldValue(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft)); obj->setFieldValue(marginLeftField, YGNodeLayoutGetMargin(root, YGEdgeLeft));
obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop)); obj->setFieldValue(marginTopField, YGNodeLayoutGetMargin(root, YGEdgeTop));
obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight)); obj->setFieldValue(marginRightField, YGNodeLayoutGetMargin(root, YGEdgeRight));
obj->setFieldValue(paddingBottomField, YGNodeLayoutGetPadding(root, YGEdgeBottom)); obj->setFieldValue(marginBottomField, YGNodeLayoutGetMargin(root, YGEdgeBottom));
obj->setFieldValue(borderLeftField, YGNodeLayoutGetBorder(root, YGEdgeLeft)); obj->setFieldValue(paddingLeftField, YGNodeLayoutGetPadding(root, YGEdgeLeft));
obj->setFieldValue(borderTopField, YGNodeLayoutGetBorder(root, YGEdgeTop)); obj->setFieldValue(paddingTopField, YGNodeLayoutGetPadding(root, YGEdgeTop));
obj->setFieldValue(borderRightField, YGNodeLayoutGetBorder(root, YGEdgeRight)); obj->setFieldValue(paddingRightField, YGNodeLayoutGetPadding(root, YGEdgeRight));
obj->setFieldValue(borderBottomField, YGNodeLayoutGetBorder(root, YGEdgeBottom)); obj->setFieldValue(paddingBottomField, YGNodeLayoutGetPadding(root, YGEdgeBottom));
YGTransferLayoutDirection(root, obj); obj->setFieldValue(borderLeftField, YGNodeLayoutGetBorder(root, YGEdgeLeft));
obj->setFieldValue(borderTopField, YGNodeLayoutGetBorder(root, YGEdgeTop));
obj->setFieldValue(borderRightField, YGNodeLayoutGetBorder(root, YGEdgeRight));
obj->setFieldValue(borderBottomField, YGNodeLayoutGetBorder(root, YGEdgeBottom));
for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) { obj->setFieldValue<jboolean>(hasNewLayoutField, true);
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i)); YGTransferLayoutDirection(root, obj);
YGNodeSetHasNewLayout(root, false);
for (uint32_t i = 0; i < YGNodeGetChildCount(root); i++) {
YGTransferLayoutOutputsRecursive(YGNodeGetChild(root, i));
}
} else {
YGLog(YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
} }
} else {
YGLog(YGLogLevelError, "Java YGNode was GCed during layout calculation\n");
} }
} }
@@ -242,14 +247,6 @@ void jni_YGNodeSetHasBaselineFunc(alias_ref<jobject>,
hasBaselineFunc ? YGJNIBaselineFunc : NULL); hasBaselineFunc ? YGJNIBaselineFunc : NULL);
} }
jboolean jni_YGNodeHasNewLayout(alias_ref<jobject>, jlong nativePointer) {
return (jboolean) YGNodeGetHasNewLayout(_jlong2YGNodeRef(nativePointer));
}
void jni_YGNodeMarkLayoutSeen(alias_ref<jobject>, jlong nativePointer) {
YGNodeSetHasNewLayout(_jlong2YGNodeRef(nativePointer), false);
}
void jni_YGNodeCopyStyle(alias_ref<jobject>, jlong dstNativePointer, jlong srcNativePointer) { void jni_YGNodeCopyStyle(alias_ref<jobject>, jlong dstNativePointer, jlong srcNativePointer) {
YGNodeCopyStyle(_jlong2YGNodeRef(dstNativePointer), _jlong2YGNodeRef(srcNativePointer)); YGNodeCopyStyle(_jlong2YGNodeRef(dstNativePointer), _jlong2YGNodeRef(srcNativePointer));
} }
@@ -403,10 +400,8 @@ jint JNI_OnLoad(JavaVM *vm, void *) {
YGMakeNativeMethod(jni_YGNodeInsertChild), YGMakeNativeMethod(jni_YGNodeInsertChild),
YGMakeNativeMethod(jni_YGNodeRemoveChild), YGMakeNativeMethod(jni_YGNodeRemoveChild),
YGMakeNativeMethod(jni_YGNodeCalculateLayout), YGMakeNativeMethod(jni_YGNodeCalculateLayout),
YGMakeNativeMethod(jni_YGNodeHasNewLayout),
YGMakeNativeMethod(jni_YGNodeMarkDirty), YGMakeNativeMethod(jni_YGNodeMarkDirty),
YGMakeNativeMethod(jni_YGNodeIsDirty), YGMakeNativeMethod(jni_YGNodeIsDirty),
YGMakeNativeMethod(jni_YGNodeMarkLayoutSeen),
YGMakeNativeMethod(jni_YGNodeSetHasMeasureFunc), YGMakeNativeMethod(jni_YGNodeSetHasMeasureFunc),
YGMakeNativeMethod(jni_YGNodeSetHasBaselineFunc), YGMakeNativeMethod(jni_YGNodeSetHasBaselineFunc),
YGMakeNativeMethod(jni_YGNodeCopyStyle), YGMakeNativeMethod(jni_YGNodeCopyStyle),