Add YogaNodeProperties implementation based on ByteBuffer

Summary:
@public
Adds an implementation of `YogaNodeProperties` that accesses style and layout properties using a `ByteBuffer` rather than JNI calls.
We hope for a speed improvement.

This needs further cleanup after experimenting, e.g. to codegen the offsets.

Reviewed By: pasqualeanatriello

Differential Revision: D8911723

fbshipit-source-id: 3c24b57eb545155878896ebb5d64d4553eb6bedc
This commit is contained in:
David Aurelio
2018-07-30 09:30:51 -07:00
committed by Facebook Github Bot
parent b1821ab4cd
commit 3499e2e0ef
29 changed files with 2034 additions and 979 deletions

View File

@@ -6,6 +6,7 @@
*
*/
#include <fb/fbjni.h>
#include <fb/fbjni/ByteBuffer.h>
#include <yoga/YGNode.h>
#include <yoga/Yoga.h>
#include <iostream>
@@ -26,6 +27,12 @@ struct JYogaNodePropertiesJNI : public JavaClass<JYogaNodePropertiesJNI> {
"Lcom/facebook/yoga/YogaNodePropertiesJNI;";
};
struct JYogaNodePropertiesByteBuffer
: public JavaClass<JYogaNodePropertiesByteBuffer, JYogaNodePropertiesJNI> {
static constexpr auto kJavaDescriptor =
"Lcom/facebook/yoga/YogaNodePropertiesByteBuffer";
};
struct YGConfigContext {
global_ref<jobject>* logger;
global_ref<jobject>* config;
@@ -331,6 +338,19 @@ jlong jni_YGNodeNewWithConfig(
return reinterpret_cast<jlong>(node);
}
jlong jni_YGNodeNewByteBuffer(
alias_ref<jclass>,
alias_ref<JYogaNode> javaNode) {
return jni_YGNodeNew(nullptr, javaNode);
}
jlong jni_YGNodeNewByteBufferWithConfig(
alias_ref<jclass>,
alias_ref<JYogaNode> javaNode,
jlong configPointer) {
return jni_YGNodeNewWithConfig(nullptr, javaNode, configPointer);
}
void jni_YGNodeSetOwner(
alias_ref<jobject> thiz,
jlong nativePointer,
@@ -351,6 +371,13 @@ jlong jni_YGNodeClone(
return reinterpret_cast<jlong>(clonedYogaNode);
}
jlong jni_YGNodeCloneNoProps(
alias_ref<jclass> cls,
jlong nativePointer,
alias_ref<JYogaNode> clonedJavaObject) {
return jni_YGNodeClone(cls, nativePointer, clonedJavaObject, nullptr);
}
void jni_YGNodeFree(alias_ref<jobject> thiz, jlong nativePointer) {
const YGNodeRef node = _jlong2YGNodeRef(nativePointer);
delete reinterpret_cast<JNINodeContext*>(node->getContext());
@@ -404,7 +431,7 @@ void jni_YGNodeRemoveChild(
_jlong2YGNodeRef(nativePointer), _jlong2YGNodeRef(childPointer));
}
void jni_YGNodeCalculateLayout(
jboolean jni_YGNodeCalculateLayout(
alias_ref<jobject>,
jlong nativePointer,
jfloat width,
@@ -415,6 +442,7 @@ void jni_YGNodeCalculateLayout(
static_cast<float>(width),
static_cast<float>(height),
YGNodeStyleGetDirection(_jlong2YGNodeRef(nativePointer)));
return root->getHasNewLayout();
}
static void jni_YGTransferLayoutOutputsRecursive(
@@ -694,6 +722,21 @@ void jni_YGConfigSetLogger(
jint jni_YGNodeGetInstanceCount(alias_ref<jclass> clazz) {
return YGNodeGetInstanceCount();
}
local_ref<JByteBuffer> jni_getStyleBuffer(
alias_ref<jclass>,
jlong nativePointer) {
YGStyle* style = &_jlong2YGNodeRef(nativePointer)->getStyle();
return JByteBuffer::wrapBytes(
reinterpret_cast<uint8_t*>(style), sizeof(YGStyle));
}
local_ref<JByteBuffer> jni_getLayoutBuffer(
alias_ref<jclass>,
jlong nativePointer) {
YGLayout* layout = &_jlong2YGNodeRef(nativePointer)->getLayout();
return JByteBuffer::wrapBytes(
reinterpret_cast<uint8_t*>(layout), sizeof(YGLayout));
}
#define YGMakeNativeMethod(name) makeNativeMethod(#name, name)
@@ -803,5 +846,17 @@ jint JNI_OnLoad(JavaVM* vm, void*) {
YGMakeNativeMethod(
jni_YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour),
});
registerNatives(
"com/facebook/yoga/YogaNodePropertiesByteBuffer",
{
YGMakeNativeMethod(jni_YGNodeCloneNoProps),
YGMakeNativeMethod(jni_YGNodeFree),
YGMakeNativeMethod(jni_YGNodeNewByteBuffer),
YGMakeNativeMethod(jni_YGNodeNewByteBufferWithConfig),
YGMakeNativeMethod(jni_YGNodeReset),
YGMakeNativeMethod(jni_YGNodeIsDirty),
YGMakeNativeMethod(jni_getStyleBuffer),
YGMakeNativeMethod(jni_getLayoutBuffer),
});
});
}