Skip to content

Commit

Permalink
Add YogaNodeProperties implementation with ByteBuffer based setters
Browse files Browse the repository at this point in the history
Summary:
@public
Adds an implementation of `YogaNodeProperties` that sets style properties using a `ByteBuffer` rather than JNI calls.
We hope for a speed improvement.

Reviewed By: pasqualeanatriello

Differential Revision: D9042225

fbshipit-source-id: c7f2b24eaeddd1190755bec85a5034079bd2f492
  • Loading branch information
davidaurelio authored and facebook-github-bot committed Jul 30, 2018
1 parent 0c97e75 commit 23657cc
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 9 deletions.
29 changes: 25 additions & 4 deletions ReactAndroid/src/main/java/com/facebook/yoga/YogaNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public class YogaNode implements Cloneable {
SoLoader.loadLibrary("yoga");
}

public static final int BYTE_BUFFER = 1;
public static final int HYBRID = 2;

/** Get native instance count. Useful for testing only. */
static native int jni_YGNodeGetInstanceCount();

Expand All @@ -39,12 +42,30 @@ public YogaNode(YogaConfig config) {
mDelegate = new YogaNodePropertiesJNI(this, config);
}

public YogaNode(boolean unsafeClownyUseByteBufferValueDoesNotMatter) {
mDelegate = new YogaNodePropertiesByteBuffer(this);
public YogaNode(int storageType) {
switch (storageType) {
case BYTE_BUFFER:
mDelegate = new YogaNodePropertiesByteBuffer(this);
break;
case HYBRID:
mDelegate = new YogaNodePropertiesHybrid(this);
break;
default:
mDelegate = new YogaNodePropertiesJNI(this);
}
}

public YogaNode(boolean unsafeClownyUseByteBufferValueDoesNotMatter, YogaConfig config) {
mDelegate = new YogaNodePropertiesByteBuffer(this, config);
public YogaNode(int storageType, YogaConfig config) {
switch (storageType) {
case BYTE_BUFFER:
mDelegate = new YogaNodePropertiesByteBuffer(this, config);
break;
case HYBRID:
mDelegate = new YogaNodePropertiesHybrid(this, config);
break;
default:
mDelegate = new YogaNodePropertiesJNI(this, config);
}
}

public long getNativePointer() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
/*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*
*/
package com.facebook.yoga;

import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.soloader.SoLoader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@DoNotStrip
public class YogaNodePropertiesHybrid extends YogaNodePropertiesJNI {

static {
SoLoader.loadLibrary("yoga");
}

private ByteBuffer mStyleBuffer;

private static native ByteBuffer jni_getStyleBuffer(long nativePointer);

public YogaNodePropertiesHybrid(YogaNode node) {
super(node);
mStyleBuffer = jni_getStyleBuffer(getNativePointer()).order(ByteOrder.LITTLE_ENDIAN);
}

public YogaNodePropertiesHybrid(YogaNode node, YogaConfig config) {
super(node, config);
mStyleBuffer = jni_getStyleBuffer(getNativePointer()).order(ByteOrder.LITTLE_ENDIAN);
}

@Override
public void setDirection(YogaDirection direction) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleDirection, direction.intValue());
}

@Override
public void setFlexDirection(YogaFlexDirection flexDirection) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleFlexDirection, flexDirection.intValue());
}

@Override
public void setJustifyContent(YogaJustify justifyContent) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleJustifyContent, justifyContent.intValue());
}

@Override
public void setAlignItems(YogaAlign alignItems) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleAlignItems, alignItems.intValue());
}

@Override
public void setAlignSelf(YogaAlign alignSelf) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleAlignSelf, alignSelf.intValue());
}

@Override
public void setAlignContent(YogaAlign alignContent) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleAlignContent, alignContent.intValue());
}

@Override
public void setPositionType(YogaPositionType positionType) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.stylePositionType, positionType.intValue());
}

@Override
public void setWrap(YogaWrap flexWrap) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleFlexWrap, flexWrap.intValue());
}

@Override
public void setOverflow(YogaOverflow overflow) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleOverflow, overflow.intValue());
}

@Override
public void setDisplay(YogaDisplay display) {
mStyleBuffer.putInt(YogaNodeMemoryLayout.styleDisplay, display.intValue());
}

@Override
public void setFlex(float flex) {
YogaNodeMemoryLayout.putOptional(mStyleBuffer, YogaNodeMemoryLayout.styleFlex, flex);
}

@Override
public void setFlexGrow(float flexGrow) {
YogaNodeMemoryLayout.putOptional(mStyleBuffer, YogaNodeMemoryLayout.styleFlexGrow, flexGrow);
}

@Override
public void setFlexShrink(float flexShrink) {
YogaNodeMemoryLayout.putOptional(
mStyleBuffer, YogaNodeMemoryLayout.styleFlexShrink, flexShrink);
}

@Override
public void setFlexBasis(float flexBasis) {
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.styleFlexBasis, flexBasis);
}

@Override
public void setFlexBasisPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.styleFlexBasis, percent);
}

@Override
public void setFlexBasisAuto() {
YogaNodeMemoryLayout.putAutoValue(mStyleBuffer, YogaNodeMemoryLayout.styleFlexBasis);
}

@Override
public void setMargin(YogaEdge edge, float margin) {
mEdgeSetFlag |= MARGIN;
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMarginOffset(edge), margin);
}

@Override
public void setMarginPercent(YogaEdge edge, float percent) {
mEdgeSetFlag |= MARGIN;
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMarginOffset(edge), percent);
}

@Override
public void setMarginAuto(YogaEdge edge) {
mEdgeSetFlag |= MARGIN;
YogaNodeMemoryLayout.putAutoValue(mStyleBuffer, YogaNodeMemoryLayout.styleMarginOffset(edge));
}

@Override
public void setPadding(YogaEdge edge, float padding) {
mEdgeSetFlag |= PADDING;
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.stylePaddingOffset(edge), padding);
}

@Override
public void setPaddingPercent(YogaEdge edge, float percent) {
mEdgeSetFlag |= PADDING;
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.stylePaddingOffset(edge), percent);
}

@Override
public void setBorder(YogaEdge edge, float border) {
mEdgeSetFlag |= BORDER;
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.styleBorderOffset(edge), border);
}

@Override
public void setPosition(YogaEdge edge, float position) {
mHasSetPosition = true;
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.stylePositionOffset(edge), position);
}

@Override
public void setPositionPercent(YogaEdge edge, float percent) {
mHasSetPosition = true;
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.stylePositionOffset(edge), percent);
}

@Override
public void setWidth(float width) {
YogaNodeMemoryLayout.putPointValue(mStyleBuffer, YogaNodeMemoryLayout.styleWidth, width);
}

@Override
public void setWidthPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(mStyleBuffer, YogaNodeMemoryLayout.styleWidth, percent);
}

@Override
public void setWidthAuto() {
YogaNodeMemoryLayout.putAutoValue(mStyleBuffer, YogaNodeMemoryLayout.styleWidth);
}

@Override
public void setHeight(float height) {
YogaNodeMemoryLayout.putPointValue(mStyleBuffer, YogaNodeMemoryLayout.styleHeight, height);
}

@Override
public void setHeightPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(mStyleBuffer, YogaNodeMemoryLayout.styleHeight, percent);
}

@Override
public void setHeightAuto() {
YogaNodeMemoryLayout.putAutoValue(mStyleBuffer, YogaNodeMemoryLayout.styleHeight);
}

@Override
public void setMinWidth(float minWidth) {
YogaNodeMemoryLayout.putPointValue(mStyleBuffer, YogaNodeMemoryLayout.styleMinWidth, minWidth);
}

@Override
public void setMinWidthPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(mStyleBuffer, YogaNodeMemoryLayout.styleMinWidth, percent);
}

@Override
public void setMinHeight(float minHeight) {
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMinHeight, minHeight);
}

@Override
public void setMinHeightPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMinHeight, percent);
}

@Override
public void setMaxWidth(float maxWidth) {
YogaNodeMemoryLayout.putPointValue(mStyleBuffer, YogaNodeMemoryLayout.styleMaxWidth, maxWidth);
}

@Override
public void setMaxWidthPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(mStyleBuffer, YogaNodeMemoryLayout.styleMaxWidth, percent);
}

@Override
public void setMaxHeight(float maxHeight) {
YogaNodeMemoryLayout.putPointValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMaxHeight, maxHeight);
}

@Override
public void setMaxHeightPercent(float percent) {
YogaNodeMemoryLayout.putPercentValue(
mStyleBuffer, YogaNodeMemoryLayout.styleMaxHeight, percent);
}

@Override
public void setAspectRatio(float aspectRatio) {
YogaNodeMemoryLayout.putOptional(
mStyleBuffer, YogaNodeMemoryLayout.styleAspectRatio, aspectRatio);
}

@Override
public YogaNodeProperties clone(YogaNode node) {
YogaNodePropertiesHybrid clone = (YogaNodePropertiesHybrid) super.clone(node);
clone.mStyleBuffer =
jni_getStyleBuffer(clone.getNativePointer()).order(ByteOrder.LITTLE_ENDIAN);
return clone;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ public class YogaNodePropertiesJNI implements Cloneable, YogaNodeProperties {
private long mNativePointer;

/* Those flags needs be in sync with YGJNI.cpp */
private static final int MARGIN = 1;
private static final int PADDING = 2;
private static final int BORDER = 4;
protected static final int MARGIN = 1;
protected static final int PADDING = 2;
protected static final int BORDER = 4;

@DoNotStrip private int mEdgeSetFlag = 0;
@DoNotStrip protected int mEdgeSetFlag = 0;

private boolean mHasSetPosition = false;
protected boolean mHasSetPosition = false;

@DoNotStrip private float mWidth = YogaConstants.UNDEFINED;
@DoNotStrip private float mHeight = YogaConstants.UNDEFINED;
Expand Down
11 changes: 11 additions & 0 deletions ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ struct JYogaNodePropertiesByteBuffer
"Lcom/facebook/yoga/YogaNodePropertiesByteBuffer";
};

struct JYogaNodePropertiesHybrid
: public JavaClass<JYogaNodePropertiesHybrid, JYogaNodePropertiesJNI> {
static constexpr auto kJavaDescriptor =
"Lcom/facebook/yoga/YogaNodePropertiesHybrid";
};

struct YGConfigContext {
global_ref<jobject>* logger;
global_ref<jobject>* config;
Expand Down Expand Up @@ -858,5 +864,10 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
YGMakeNativeMethod(jni_getStyleBuffer),
YGMakeNativeMethod(jni_getLayoutBuffer),
});
registerNatives(
"com/facebook/yoga/YogaNodePropertiesHybrid",
{
YGMakeNativeMethod(jni_getStyleBuffer),
});
});
}

0 comments on commit 23657cc

Please sign in to comment.