From e9ff2157bc8c42d2fe22765e50142af92a7ff03b Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Thu, 1 Jul 2021 14:01:48 -0700 Subject: [PATCH] gltfio: Cache the JNI field ids for MaterialKey. --- .../src/main/cpp/AssetLoader.cpp | 12 +- .../src/main/cpp/MaterialKey.cpp | 186 +++++++++++------- .../gltfio-android/src/main/cpp/MaterialKey.h | 46 ++++- .../src/main/cpp/UbershaderLoader.cpp | 10 +- .../filament/gltfio/MaterialProvider.java | 6 + 5 files changed, 176 insertions(+), 84 deletions(-) diff --git a/android/gltfio-android/src/main/cpp/AssetLoader.cpp b/android/gltfio-android/src/main/cpp/AssetLoader.cpp index 5f1e748993..74863714e8 100644 --- a/android/gltfio-android/src/main/cpp/AssetLoader.cpp +++ b/android/gltfio-android/src/main/cpp/AssetLoader.cpp @@ -91,8 +91,10 @@ public: MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label) override { // Create a Java object for the material key and copy the native fields into it. - jobject key = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor); - nativeToJava(mEnv, *config, key); + jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor); + + auto& helper = MaterialKeyHelper::get(); + helper.copy(mEnv, javaKey, *config); // Convert the optional label into a Java string. jstring stringLabel = label ? mEnv->NewStringUTF(label) : nullptr; @@ -102,7 +104,7 @@ public: // Call the Java-based material provider. jobject materialInstance = mEnv->CallObjectMethod(mJavaProvider, mCreateMaterialInstance, - key, uvMapArray, stringLabel); + javaKey, uvMapArray, stringLabel); // Copy the UvMap results from the JVM array into the native array. if (uvmap) { @@ -114,9 +116,9 @@ public: } // The config parameter is an in-out parameter so we need to copy the results from Java. - nativeFromJava(mEnv, *config, key); + helper.copy(mEnv, *config, javaKey); - mEnv->DeleteLocalRef(key); + mEnv->DeleteLocalRef(javaKey); mEnv->DeleteLocalRef(uvMapArray); if (stringLabel) { diff --git a/android/gltfio-android/src/main/cpp/MaterialKey.cpp b/android/gltfio-android/src/main/cpp/MaterialKey.cpp index ff2dc3750e..dae7c5a43e 100644 --- a/android/gltfio-android/src/main/cpp/MaterialKey.cpp +++ b/android/gltfio-android/src/main/cpp/MaterialKey.cpp @@ -22,82 +22,124 @@ using namespace gltfio; -void nativeFromJava(JNIEnv* env, MaterialKey& dst, jobject src) { - const jclass materialKeyClass = env->FindClass(JAVA_MATERIAL_KEY); - auto field = [materialKeyClass, env](const char* fieldName, const char* signature) { - return env->GetFieldID(materialKeyClass, fieldName, signature); - }; - dst.doubleSided = env->GetBooleanField(src, field("doubleSided", "Z")); - dst.unlit = env->GetBooleanField(src, field("unlit", "Z")); - dst.hasVertexColors = env->GetBooleanField(src, field("hasVertexColors", "Z")); - dst.hasBaseColorTexture = env->GetBooleanField(src, field("hasBaseColorTexture", "Z")); - dst.hasNormalTexture = env->GetBooleanField(src, field("hasNormalTexture", "Z")); - dst.hasOcclusionTexture = env->GetBooleanField(src, field("hasOcclusionTexture", "Z")); - dst.hasEmissiveTexture = env->GetBooleanField(src, field("hasEmissiveTexture", "Z")); - dst.useSpecularGlossiness = env->GetBooleanField(src, field("useSpecularGlossiness", "Z")); - dst.alphaMode = (AlphaMode) env->GetIntField(src, field("alphaMode", "I")); - dst.enableDiagnostics = env->GetBooleanField(src, field("enableDiagnostics", "Z")); - dst.hasMetallicRoughnessTexture = env->GetBooleanField(src, field("hasMetallicRoughnessTexture", "Z")); - dst.metallicRoughnessUV = env->GetIntField(src, field("metallicRoughnessUV", "I")); - dst.baseColorUV = env->GetIntField(src, field("baseColorUV", "I")); - dst.hasClearCoatTexture = env->GetBooleanField(src, field("hasClearCoatTexture", "Z")); - dst.clearCoatUV = env->GetIntField(src, field("clearCoatUV", "I")); - dst.hasClearCoatRoughnessTexture = env->GetBooleanField(src, field("hasClearCoatRoughnessTexture", "Z")); - dst.clearCoatRoughnessUV = env->GetIntField(src, field("clearCoatRoughnessUV", "I")); - dst.hasClearCoatNormalTexture = env->GetBooleanField(src, field("hasClearCoatNormalTexture", "Z")); - dst.clearCoatNormalUV = env->GetIntField(src, field("clearCoatNormalUV", "I")); - dst.hasClearCoat = env->GetBooleanField(src, field("hasClearCoat", "Z")); - dst.hasTransmission = env->GetBooleanField(src, field("hasTransmission", "Z")); - dst.hasTextureTransforms = env->GetBooleanField(src, field("hasTextureTransforms", "Z")); - dst.emissiveUV = env->GetIntField(src, field("emissiveUV", "I")); - dst.aoUV = env->GetIntField(src, field("aoUV", "I")); - dst.normalUV = env->GetIntField(src, field("normalUV", "I")); - dst.hasTransmissionTexture = env->GetBooleanField(src, field("hasTransmissionTexture", "Z")); - dst.transmissionUV = env->GetIntField(src, field("transmissionUV", "I")); - dst.hasSheenColorTexture = env->GetBooleanField(src, field("hasSheenColorTexture", "Z")); - dst.sheenColorUV = env->GetIntField(src, field("sheenColorUV", "I")); - dst.hasSheenRoughnessTexture = env->GetBooleanField(src, field("hasSheenRoughnessTexture", "Z")); - dst.sheenRoughnessUV = env->GetIntField(src, field("sheenRoughnessUV", "I")); - dst.hasSheen = env->GetBooleanField(src, field("hasSheen", "Z")); - dst.hasIOR = env->GetBooleanField(src, field("hasIOR", "Z")); +MaterialKeyHelper& MaterialKeyHelper::get() { + static MaterialKeyHelper helper; + return helper; } -void nativeToJava(JNIEnv* env, MaterialKey& src, jobject dst) { +void MaterialKeyHelper::init(JNIEnv* env) { const jclass materialKeyClass = env->FindClass(JAVA_MATERIAL_KEY); auto field = [materialKeyClass, env](const char* fieldName, const char* signature) { return env->GetFieldID(materialKeyClass, fieldName, signature); }; - env->SetBooleanField(dst, field("doubleSided", "Z"), src.doubleSided); - env->SetBooleanField(dst, field("unlit", "Z"), src.unlit); - env->SetBooleanField(dst, field("hasVertexColors", "Z"), src.hasVertexColors); - env->SetBooleanField(dst, field("hasBaseColorTexture", "Z"), src.hasBaseColorTexture); - env->SetBooleanField(dst, field("hasNormalTexture", "Z"), src.hasNormalTexture); - env->SetBooleanField(dst, field("hasOcclusionTexture", "Z"), src.hasOcclusionTexture); - env->SetBooleanField(dst, field("hasEmissiveTexture", "Z"), src.hasEmissiveTexture); - env->SetBooleanField(dst, field("useSpecularGlossiness", "Z"), src.useSpecularGlossiness); - env->SetIntField(dst, field("alphaMode", "I"), (int) src.alphaMode); - env->SetBooleanField(dst, field("enableDiagnostics", "Z"), src.enableDiagnostics); - env->SetBooleanField(dst, field("hasMetallicRoughnessTexture", "Z"), src.hasMetallicRoughnessTexture); - env->SetIntField(dst, field("metallicRoughnessUV", "I"), src.metallicRoughnessUV); - env->SetIntField(dst, field("baseColorUV", "I"), src.baseColorUV); - env->SetBooleanField(dst, field("hasClearCoatTexture", "Z"), src.hasClearCoatTexture); - env->SetIntField(dst, field("clearCoatUV", "I"), src.clearCoatUV); - env->SetBooleanField(dst, field("hasClearCoatRoughnessTexture", "Z"), src.hasClearCoatRoughnessTexture); - env->SetIntField(dst, field("clearCoatRoughnessUV", "I"), src.clearCoatRoughnessUV); - env->SetBooleanField(dst, field("hasClearCoatNormalTexture", "Z"), src.hasClearCoatNormalTexture); - env->SetIntField(dst, field("clearCoatNormalUV", "I"), src.clearCoatNormalUV); - env->SetBooleanField(dst, field("hasClearCoat", "Z"), src.hasClearCoat); - env->SetBooleanField(dst, field("hasTransmission", "Z"), src.hasTransmission); - env->SetBooleanField(dst, field("hasTextureTransforms", "Z"), src.hasTextureTransforms); - env->SetIntField(dst, field("emissiveUV", "I"), src.emissiveUV); - env->SetIntField(dst, field("aoUV", "I"), src.aoUV); - env->SetIntField(dst, field("normalUV", "I"), src.normalUV); - env->SetBooleanField(dst, field("hasTransmissionTexture", "Z"), src.hasTransmissionTexture); - env->SetIntField(dst, field("transmissionUV", "I"), src.transmissionUV); - env->SetBooleanField(dst, field("hasSheenColorTexture", "Z"), src.hasSheenColorTexture); - env->SetIntField(dst, field("sheenColorUV", "I"), src.sheenColorUV); - env->SetBooleanField(dst, field("hasSheenRoughnessTexture", "Z"), src.hasSheenRoughnessTexture); - env->SetIntField(dst, field("sheenRoughnessUV", "I"), src.sheenRoughnessUV); - env->SetBooleanField(dst, field("hasSheen", "Z"), src.hasSheen); - env->SetBooleanField(dst, field("hasIOR", "Z"), src.hasIOR); + doubleSided = field("doubleSided", "Z"); + unlit = field("unlit", "Z"); + hasVertexColors = field("hasVertexColors", "Z"); + hasBaseColorTexture = field("hasBaseColorTexture", "Z"); + hasNormalTexture = field("hasNormalTexture", "Z"); + hasOcclusionTexture = field("hasOcclusionTexture", "Z"); + hasEmissiveTexture = field("hasEmissiveTexture", "Z"); + useSpecularGlossiness = field("useSpecularGlossiness", "Z"); + alphaMode = field("alphaMode", "I"); + enableDiagnostics = field("enableDiagnostics", "Z"); + hasMetallicRoughnessTexture = field("hasMetallicRoughnessTexture", "Z"); + metallicRoughnessUV = field("metallicRoughnessUV", "I"); + baseColorUV = field("baseColorUV", "I"); + hasClearCoatTexture = field("hasClearCoatTexture", "Z"); + clearCoatUV = field("clearCoatUV", "I"); + hasClearCoatRoughnessTexture = field("hasClearCoatRoughnessTexture", "Z"); + clearCoatRoughnessUV = field("clearCoatRoughnessUV", "I"); + hasClearCoatNormalTexture = field("hasClearCoatNormalTexture", "Z"); + clearCoatNormalUV = field("clearCoatNormalUV", "I"); + hasClearCoat = field("hasClearCoat", "Z"); + hasTransmission = field("hasTransmission", "Z"); + hasTextureTransforms = field("hasTextureTransforms", "Z"); + emissiveUV = field("emissiveUV", "I"); + aoUV = field("aoUV", "I"); + normalUV = field("normalUV", "I"); + hasTransmissionTexture = field("hasTransmissionTexture", "Z"); + transmissionUV = field("transmissionUV", "I"); + hasSheenColorTexture = field("hasSheenColorTexture", "Z"); + sheenColorUV = field("sheenColorUV", "I"); + hasSheenRoughnessTexture = field("hasSheenRoughnessTexture", "Z"); + sheenRoughnessUV = field("sheenRoughnessUV", "I"); + hasSheen = field("hasSheen", "Z"); + hasIOR = field("hasIOR", "Z"); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) { + MaterialKeyHelper::get().init(env); +} + +void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) { + dst.doubleSided = env->GetBooleanField(src, doubleSided); + dst.unlit = env->GetBooleanField(src, unlit); + dst.hasVertexColors = env->GetBooleanField(src, hasVertexColors); + dst.hasBaseColorTexture = env->GetBooleanField(src, hasBaseColorTexture); + dst.hasNormalTexture = env->GetBooleanField(src, hasNormalTexture); + dst.hasOcclusionTexture = env->GetBooleanField(src, hasOcclusionTexture); + dst.hasEmissiveTexture = env->GetBooleanField(src, hasEmissiveTexture); + dst.useSpecularGlossiness = env->GetBooleanField(src, useSpecularGlossiness); + dst.alphaMode = (AlphaMode) env->GetIntField(src, alphaMode); + dst.enableDiagnostics = env->GetBooleanField(src, enableDiagnostics); + dst.hasMetallicRoughnessTexture = env->GetBooleanField(src, hasMetallicRoughnessTexture); + dst.metallicRoughnessUV = env->GetIntField(src, metallicRoughnessUV); + dst.baseColorUV = env->GetIntField(src, baseColorUV); + dst.hasClearCoatTexture = env->GetBooleanField(src, hasClearCoatTexture); + dst.clearCoatUV = env->GetIntField(src, clearCoatUV); + dst.hasClearCoatRoughnessTexture = env->GetBooleanField(src, hasClearCoatRoughnessTexture); + dst.clearCoatRoughnessUV = env->GetIntField(src, clearCoatRoughnessUV); + dst.hasClearCoatNormalTexture = env->GetBooleanField(src, hasClearCoatNormalTexture); + dst.clearCoatNormalUV = env->GetIntField(src, clearCoatNormalUV); + dst.hasClearCoat = env->GetBooleanField(src, hasClearCoat); + dst.hasTransmission = env->GetBooleanField(src, hasTransmission); + dst.hasTextureTransforms = env->GetBooleanField(src, hasTextureTransforms); + dst.emissiveUV = env->GetIntField(src, emissiveUV); + dst.aoUV = env->GetIntField(src, aoUV); + dst.normalUV = env->GetIntField(src, normalUV); + dst.hasTransmissionTexture = env->GetBooleanField(src, hasTransmissionTexture); + dst.transmissionUV = env->GetIntField(src, transmissionUV); + dst.hasSheenColorTexture = env->GetBooleanField(src, hasSheenColorTexture); + dst.sheenColorUV = env->GetIntField(src, sheenColorUV); + dst.hasSheenRoughnessTexture = env->GetBooleanField(src, hasSheenRoughnessTexture); + dst.sheenRoughnessUV = env->GetIntField(src, sheenRoughnessUV); + dst.hasSheen = env->GetBooleanField(src, hasSheen); + dst.hasIOR = env->GetBooleanField(src, hasIOR); +} + +void MaterialKeyHelper::copy(JNIEnv* env, jobject dst, const MaterialKey& src) { + env->SetBooleanField(dst, doubleSided, src.doubleSided); + env->SetBooleanField(dst, unlit, src.unlit); + env->SetBooleanField(dst, hasVertexColors, src.hasVertexColors); + env->SetBooleanField(dst, hasBaseColorTexture, src.hasBaseColorTexture); + env->SetBooleanField(dst, hasNormalTexture, src.hasNormalTexture); + env->SetBooleanField(dst, hasOcclusionTexture, src.hasOcclusionTexture); + env->SetBooleanField(dst, hasEmissiveTexture, src.hasEmissiveTexture); + env->SetBooleanField(dst, useSpecularGlossiness, src.useSpecularGlossiness); + env->SetIntField(dst, alphaMode, (int) src.alphaMode); + env->SetBooleanField(dst, enableDiagnostics, src.enableDiagnostics); + env->SetBooleanField(dst, hasMetallicRoughnessTexture, src.hasMetallicRoughnessTexture); + env->SetIntField(dst, metallicRoughnessUV, src.metallicRoughnessUV); + env->SetIntField(dst, baseColorUV, src.baseColorUV); + env->SetBooleanField(dst, hasClearCoatTexture, src.hasClearCoatTexture); + env->SetIntField(dst, clearCoatUV, src.clearCoatUV); + env->SetBooleanField(dst, hasClearCoatRoughnessTexture, src.hasClearCoatRoughnessTexture); + env->SetIntField(dst, clearCoatRoughnessUV, src.clearCoatRoughnessUV); + env->SetBooleanField(dst, hasClearCoatNormalTexture, src.hasClearCoatNormalTexture); + env->SetIntField(dst, clearCoatNormalUV, src.clearCoatNormalUV); + env->SetBooleanField(dst, hasClearCoat, src.hasClearCoat); + env->SetBooleanField(dst, hasTransmission, src.hasTransmission); + env->SetBooleanField(dst, hasTextureTransforms, src.hasTextureTransforms); + env->SetIntField(dst, emissiveUV, src.emissiveUV); + env->SetIntField(dst, aoUV, src.aoUV); + env->SetIntField(dst, normalUV, src.normalUV); + env->SetBooleanField(dst, hasTransmissionTexture, src.hasTransmissionTexture); + env->SetIntField(dst, transmissionUV, src.transmissionUV); + env->SetBooleanField(dst, hasSheenColorTexture, src.hasSheenColorTexture); + env->SetIntField(dst, sheenColorUV, src.sheenColorUV); + env->SetBooleanField(dst, hasSheenRoughnessTexture, src.hasSheenRoughnessTexture); + env->SetIntField(dst, sheenRoughnessUV, src.sheenRoughnessUV); + env->SetBooleanField(dst, hasSheen, src.hasSheen); + env->SetBooleanField(dst, hasIOR, src.hasIOR); } diff --git a/android/gltfio-android/src/main/cpp/MaterialKey.h b/android/gltfio-android/src/main/cpp/MaterialKey.h index 453c8c57dd..10890605fc 100644 --- a/android/gltfio-android/src/main/cpp/MaterialKey.h +++ b/android/gltfio-android/src/main/cpp/MaterialKey.h @@ -20,5 +20,47 @@ #define JAVA_MATERIAL_KEY "com/google/android/filament/gltfio/MaterialProvider$MaterialKey" -void nativeFromJava(JNIEnv* env, gltfio::MaterialKey& dst, jobject src); -void nativeToJava(JNIEnv* env, gltfio::MaterialKey& src, jobject dst); +class MaterialKeyHelper { +public: + static MaterialKeyHelper& get(); + + void copy(JNIEnv* env, gltfio::MaterialKey& dst, jobject src); + void copy(JNIEnv* env, jobject dst, const gltfio::MaterialKey& src); + + void init(JNIEnv* env); // called only from the Java static class constructor + +private: + jfieldID doubleSided; + jfieldID unlit; + jfieldID hasVertexColors; + jfieldID hasBaseColorTexture; + jfieldID hasNormalTexture; + jfieldID hasOcclusionTexture; + jfieldID hasEmissiveTexture; + jfieldID useSpecularGlossiness; + jfieldID alphaMode; + jfieldID enableDiagnostics; + jfieldID hasMetallicRoughnessTexture; + jfieldID metallicRoughnessUV; + jfieldID baseColorUV; + jfieldID hasClearCoatTexture; + jfieldID clearCoatUV; + jfieldID hasClearCoatRoughnessTexture; + jfieldID clearCoatRoughnessUV; + jfieldID hasClearCoatNormalTexture; + jfieldID clearCoatNormalUV; + jfieldID hasClearCoat; + jfieldID hasTransmission; + jfieldID hasTextureTransforms; + jfieldID emissiveUV; + jfieldID aoUV; + jfieldID normalUV; + jfieldID hasTransmissionTexture; + jfieldID transmissionUV; + jfieldID hasSheenColorTexture; + jfieldID sheenColorUV; + jfieldID hasSheenRoughnessTexture; + jfieldID sheenRoughnessUV; + jfieldID hasSheen; + jfieldID hasIOR; +}; diff --git a/android/gltfio-android/src/main/cpp/UbershaderLoader.cpp b/android/gltfio-android/src/main/cpp/UbershaderLoader.cpp index 62d4059d55..8d984a5de0 100644 --- a/android/gltfio-android/src/main/cpp/UbershaderLoader.cpp +++ b/android/gltfio-android/src/main/cpp/UbershaderLoader.cpp @@ -49,15 +49,15 @@ Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyMaterials(JNIEn extern "C" JNIEXPORT long JNICALL Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance(JNIEnv* env, jclass, jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) { - const jclass materialKeyClass = env->FindClass(JAVA_MATERIAL_KEY); - MaterialKey key = {}; + MaterialKey nativeKey = {}; - nativeFromJava(env, key, materialKey); + auto& helper = MaterialKeyHelper::get(); + helper.copy(env, nativeKey, materialKey); const char* nativeLabel = label ? env->GetStringUTFChars(label, nullptr) : nullptr; UvMap nativeUvMap = {}; auto provider = (MaterialProvider*) nativeProvider; - MaterialInstance* instance = provider->createMaterialInstance(&key, &nativeUvMap, nativeLabel); + MaterialInstance* instance = provider->createMaterialInstance(&nativeKey, &nativeUvMap, nativeLabel); // Copy the UvMap results from the native array into the JVM array. jint* elements = env->GetIntArrayElements(uvmap, nullptr); @@ -70,7 +70,7 @@ Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance } // The config parameter is an in-out parameter so we need to copy the results back to Java. - nativeToJava(env, key, materialKey); + helper.copy(env, materialKey, nativeKey); if (label) { env->ReleaseStringUTFChars(label, nativeLabel); diff --git a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java index 27bb5cac77..5191d983cc 100644 --- a/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java +++ b/android/gltfio-android/src/main/java/com/google/android/filament/gltfio/MaterialProvider.java @@ -64,6 +64,12 @@ public interface MaterialProvider { public int sheenRoughnessUV; public boolean hasSheen; public boolean hasIOR; + + public MaterialKey() {} + static { + nGlobalInit(); + } + private static native void nGlobalInit(); }; /**