Loading rs/java/android/renderscript/RenderScript.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -302,8 +302,12 @@ public class RenderScript { long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { long[] depFieldIDs) { validate(); validate(); return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, sizes, depClosures, depFieldIDs); sizes, depClosures, depFieldIDs); if (c == 0) { throw new RSRuntimeException("Failed creating closure."); } return c; } } native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, Loading @@ -311,8 +315,12 @@ public class RenderScript { synchronized long nInvokeClosureCreate(long invokeID, byte[] params, synchronized long nInvokeClosureCreate(long invokeID, byte[] params, long[] fieldIDs, long[] values, int[] sizes) { long[] fieldIDs, long[] values, int[] sizes) { validate(); validate(); return rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs, long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs, values, sizes); values, sizes); if (c == 0) { throw new RSRuntimeException("Failed creating closure."); } return c; } } native void rsnClosureSetArg(long con, long closureID, int index, native void rsnClosureSetArg(long con, long closureID, int index, Loading @@ -337,7 +345,11 @@ public class RenderScript { synchronized long nScriptGroup2Create(String name, String cachePath, synchronized long nScriptGroup2Create(String name, String cachePath, long[] closures) { long[] closures) { validate(); validate(); return rsnScriptGroup2Create(mContext, name, cachePath, closures); long g = rsnScriptGroup2Create(mContext, name, cachePath, closures); if (g == 0) { throw new RSRuntimeException("Failed creating script group."); } return g; } } native void rsnScriptGroup2Execute(long con, long groupID); native void rsnScriptGroup2Execute(long con, long groupID); Loading rs/jni/android_renderscript_RenderScript.cpp +165 −43 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,9 @@ //#define LOG_API ALOGE //#define LOG_API ALOGE static constexpr bool kLogApi = false; static constexpr bool kLogApi = false; static constexpr size_t kMaxNumberArgsAndBindings = 1000; static constexpr size_t kMaxNumberClosuresInScriptGroup = 1000000; static constexpr size_t kMaxNumberKernelArguments = 256; using namespace android; using namespace android; Loading Loading @@ -333,79 +336,167 @@ nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID, jlong returnValue, jlongArray fieldIDArray, jlong returnValue, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray, jlongArray valueArray, jintArray sizeArray, jlongArray depClosureArray, jlongArray depFieldIDArray) { jlongArray depClosureArray, jlongArray depFieldIDArray) { jlong ret = 0; jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); jsize values_length = _env->GetArrayLength(valueArray); for (int i = 0; i< fieldIDs_length; i++) { jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); jlong* jDepClosures = _env->GetLongArrayElements(depClosureArray, nullptr); jsize depClosures_length = _env->GetArrayLength(depClosureArray); jlong* jDepFieldIDs = _env->GetLongArrayElements(depFieldIDArray, nullptr); jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); size_t numValues, numDependencies; RsScriptFieldID* fieldIDs; uintptr_t* values; RsClosure* depClosures; RsScriptFieldID* depFieldIDs; if (fieldIDs_length != values_length || values_length != sizes_length) { ALOGE("Unmatched field IDs, values, and sizes in closure creation."); goto exit; } numValues = (size_t)fieldIDs_length; if (depClosures_length != depFieldIDs_length) { ALOGE("Unmatched closures and field IDs for dependencies in closure creation."); goto exit; } numDependencies = (size_t)depClosures_length; if (numDependencies > numValues) { ALOGE("Unexpected number of dependencies in closure creation"); goto exit; } if (numValues > kMaxNumberArgsAndBindings) { ALOGE("Too many arguments or globals in closure creation"); goto exit; } fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); if (fieldIDs == nullptr) { goto exit; } for (size_t i = 0; i < numValues; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues); jsize values_length = _env->GetArrayLength(valueArray); if (values == nullptr) { uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); goto exit; for (int i = 0; i < values_length; i++) { } for (size_t i = 0; i < numValues; i++) { values[i] = (uintptr_t)jValues[i]; values[i] = (uintptr_t)jValues[i]; } } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies); jsize sizes_length = _env->GetArrayLength(sizeArray); if (depClosures == nullptr) { goto exit; } jlong* jDepClosures = for (size_t i = 0; i < numDependencies; i++) { _env->GetLongArrayElements(depClosureArray, nullptr); jsize depClosures_length = _env->GetArrayLength(depClosureArray); RsClosure* depClosures = (RsClosure*)alloca(sizeof(RsClosure) * depClosures_length); for (int i = 0; i < depClosures_length; i++) { depClosures[i] = (RsClosure)jDepClosures[i]; depClosures[i] = (RsClosure)jDepClosures[i]; } } jlong* jDepFieldIDs = depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies); _env->GetLongArrayElements(depFieldIDArray, nullptr); if (depFieldIDs == nullptr) { jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); goto exit; RsScriptFieldID* depFieldIDs = } (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length); for (int i = 0; i < depClosures_length; i++) { for (size_t i = 0; i < numDependencies; i++) { depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; } } return (jlong)(uintptr_t)rsClosureCreate( ret = (jlong)(uintptr_t)rsClosureCreate( (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, fieldIDs, numValues, values, numValues, (int*)sizes, (size_t)sizes_length, (int*)jSizes, numValues, depClosures, (size_t)depClosures_length, depClosures, numDependencies, depFieldIDs, (size_t)depFieldIDs_length); depFieldIDs, numDependencies); exit: _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT); _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT); _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); return ret; } } static jlong static jlong nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID, nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID, jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray, jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray) { jintArray sizeArray) { jlong ret = 0; jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr); jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr); jsize jParamLength = _env->GetArrayLength(paramArray); jsize jParamLength = _env->GetArrayLength(paramArray); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); jsize values_length = _env->GetArrayLength(valueArray); for (int i = 0; i< fieldIDs_length; i++) { jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); size_t numValues; RsScriptFieldID* fieldIDs; uintptr_t* values; if (fieldIDs_length != values_length || values_length != sizes_length) { ALOGE("Unmatched field IDs, values, and sizes in closure creation."); goto exit; } numValues = (size_t) fieldIDs_length; if (numValues > kMaxNumberArgsAndBindings) { ALOGE("Too many arguments or globals in closure creation"); goto exit; } fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); if (fieldIDs == nullptr) { goto exit; } for (size_t i = 0; i< numValues; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues); jsize values_length = _env->GetArrayLength(valueArray); if (values == nullptr) { uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); goto exit; for (int i = 0; i < values_length; i++) { values[i] = (uintptr_t)jValues[i]; } } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); for (size_t i = 0; i < numValues; i++) { jsize sizes_length = _env->GetArrayLength(sizeArray); values[i] = (uintptr_t)jValues[i]; } return (jlong)(uintptr_t)rsInvokeClosureCreate( ret = (jlong)(uintptr_t)rsInvokeClosureCreate( (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength, (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, fieldIDs, numValues, values, numValues, (int*)sizes, (size_t)sizes_length); (int*)jSizes, numValues); exit: _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); _env->ReleaseByteArrayElements(paramArray, jParams, JNI_ABORT); return ret; } } static void static void Loading @@ -425,20 +516,40 @@ nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID, static long static long nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name, nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name, jstring cacheDir, jlongArray closureArray) { jstring cacheDir, jlongArray closureArray) { jlong ret = 0; AutoJavaStringToUTF8 nameUTF(_env, name); AutoJavaStringToUTF8 nameUTF(_env, name); AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jsize numClosures = _env->GetArrayLength(closureArray); jsize numClosures = _env->GetArrayLength(closureArray); RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); RsClosure* closures; if (numClosures > (jsize) kMaxNumberClosuresInScriptGroup) { ALOGE("Too many closures in script group"); goto exit; } closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); if (closures == nullptr) { goto exit; } for (int i = 0; i < numClosures; i++) { for (int i = 0; i < numClosures; i++) { closures[i] = (RsClosure)jClosures[i]; closures[i] = (RsClosure)jClosures[i]; } } return (jlong)(uintptr_t)rsScriptGroup2Create( ret = (jlong)(uintptr_t)rsScriptGroup2Create( (RsContext)con, nameUTF.c_str(), nameUTF.length(), (RsContext)con, nameUTF.c_str(), nameUTF.length(), cacheDirUTF.c_str(), cacheDirUTF.length(), cacheDirUTF.c_str(), cacheDirUTF.length(), closures, numClosures); closures, numClosures); exit: _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT); return ret; } } static void static void Loading Loading @@ -1766,8 +1877,14 @@ nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, if (ains != nullptr) { if (ains != nullptr) { in_len = _env->GetArrayLength(ains); in_len = _env->GetArrayLength(ains); in_ptr = _env->GetLongArrayElements(ains, nullptr); if (in_len > (jint)kMaxNumberKernelArguments) { ALOGE("Too many arguments in kernel launch."); // TODO (b/20758983): Report back to Java and throw an exception return; } // TODO (b/20760800): Check in_ptr is not null in_ptr = _env->GetLongArrayElements(ains, nullptr); if (sizeof(RsAllocation) == sizeof(jlong)) { if (sizeof(RsAllocation) == sizeof(jlong)) { in_allocs = (RsAllocation*)in_ptr; in_allocs = (RsAllocation*)in_ptr; Loading @@ -1775,6 +1892,11 @@ nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, // Convert from 64-bit jlong types to the native pointer type. // Convert from 64-bit jlong types to the native pointer type. in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); if (in_allocs == nullptr) { ALOGE("Failed launching kernel for lack of memory."); _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); return; } for (int index = in_len; --index >= 0;) { for (int index = in_len; --index >= 0;) { in_allocs[index] = (RsAllocation)in_ptr[index]; in_allocs[index] = (RsAllocation)in_ptr[index]; Loading Loading
rs/java/android/renderscript/RenderScript.java +15 −3 Original line number Original line Diff line number Diff line Loading @@ -302,8 +302,12 @@ public class RenderScript { long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { long[] depFieldIDs) { validate(); validate(); return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, sizes, depClosures, depFieldIDs); sizes, depClosures, depFieldIDs); if (c == 0) { throw new RSRuntimeException("Failed creating closure."); } return c; } } native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params, Loading @@ -311,8 +315,12 @@ public class RenderScript { synchronized long nInvokeClosureCreate(long invokeID, byte[] params, synchronized long nInvokeClosureCreate(long invokeID, byte[] params, long[] fieldIDs, long[] values, int[] sizes) { long[] fieldIDs, long[] values, int[] sizes) { validate(); validate(); return rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs, long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs, values, sizes); values, sizes); if (c == 0) { throw new RSRuntimeException("Failed creating closure."); } return c; } } native void rsnClosureSetArg(long con, long closureID, int index, native void rsnClosureSetArg(long con, long closureID, int index, Loading @@ -337,7 +345,11 @@ public class RenderScript { synchronized long nScriptGroup2Create(String name, String cachePath, synchronized long nScriptGroup2Create(String name, String cachePath, long[] closures) { long[] closures) { validate(); validate(); return rsnScriptGroup2Create(mContext, name, cachePath, closures); long g = rsnScriptGroup2Create(mContext, name, cachePath, closures); if (g == 0) { throw new RSRuntimeException("Failed creating script group."); } return g; } } native void rsnScriptGroup2Execute(long con, long groupID); native void rsnScriptGroup2Execute(long con, long groupID); Loading
rs/jni/android_renderscript_RenderScript.cpp +165 −43 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,9 @@ //#define LOG_API ALOGE //#define LOG_API ALOGE static constexpr bool kLogApi = false; static constexpr bool kLogApi = false; static constexpr size_t kMaxNumberArgsAndBindings = 1000; static constexpr size_t kMaxNumberClosuresInScriptGroup = 1000000; static constexpr size_t kMaxNumberKernelArguments = 256; using namespace android; using namespace android; Loading Loading @@ -333,79 +336,167 @@ nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID, jlong returnValue, jlongArray fieldIDArray, jlong returnValue, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray, jlongArray valueArray, jintArray sizeArray, jlongArray depClosureArray, jlongArray depFieldIDArray) { jlongArray depClosureArray, jlongArray depFieldIDArray) { jlong ret = 0; jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); jsize values_length = _env->GetArrayLength(valueArray); for (int i = 0; i< fieldIDs_length; i++) { jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); jlong* jDepClosures = _env->GetLongArrayElements(depClosureArray, nullptr); jsize depClosures_length = _env->GetArrayLength(depClosureArray); jlong* jDepFieldIDs = _env->GetLongArrayElements(depFieldIDArray, nullptr); jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); size_t numValues, numDependencies; RsScriptFieldID* fieldIDs; uintptr_t* values; RsClosure* depClosures; RsScriptFieldID* depFieldIDs; if (fieldIDs_length != values_length || values_length != sizes_length) { ALOGE("Unmatched field IDs, values, and sizes in closure creation."); goto exit; } numValues = (size_t)fieldIDs_length; if (depClosures_length != depFieldIDs_length) { ALOGE("Unmatched closures and field IDs for dependencies in closure creation."); goto exit; } numDependencies = (size_t)depClosures_length; if (numDependencies > numValues) { ALOGE("Unexpected number of dependencies in closure creation"); goto exit; } if (numValues > kMaxNumberArgsAndBindings) { ALOGE("Too many arguments or globals in closure creation"); goto exit; } fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); if (fieldIDs == nullptr) { goto exit; } for (size_t i = 0; i < numValues; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues); jsize values_length = _env->GetArrayLength(valueArray); if (values == nullptr) { uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); goto exit; for (int i = 0; i < values_length; i++) { } for (size_t i = 0; i < numValues; i++) { values[i] = (uintptr_t)jValues[i]; values[i] = (uintptr_t)jValues[i]; } } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); depClosures = (RsClosure*)alloca(sizeof(RsClosure) * numDependencies); jsize sizes_length = _env->GetArrayLength(sizeArray); if (depClosures == nullptr) { goto exit; } jlong* jDepClosures = for (size_t i = 0; i < numDependencies; i++) { _env->GetLongArrayElements(depClosureArray, nullptr); jsize depClosures_length = _env->GetArrayLength(depClosureArray); RsClosure* depClosures = (RsClosure*)alloca(sizeof(RsClosure) * depClosures_length); for (int i = 0; i < depClosures_length; i++) { depClosures[i] = (RsClosure)jDepClosures[i]; depClosures[i] = (RsClosure)jDepClosures[i]; } } jlong* jDepFieldIDs = depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numDependencies); _env->GetLongArrayElements(depFieldIDArray, nullptr); if (depFieldIDs == nullptr) { jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); goto exit; RsScriptFieldID* depFieldIDs = } (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length); for (int i = 0; i < depClosures_length; i++) { for (size_t i = 0; i < numDependencies; i++) { depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; } } return (jlong)(uintptr_t)rsClosureCreate( ret = (jlong)(uintptr_t)rsClosureCreate( (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, fieldIDs, numValues, values, numValues, (int*)sizes, (size_t)sizes_length, (int*)jSizes, numValues, depClosures, (size_t)depClosures_length, depClosures, numDependencies, depFieldIDs, (size_t)depFieldIDs_length); depFieldIDs, numDependencies); exit: _env->ReleaseLongArrayElements(depFieldIDArray, jDepFieldIDs, JNI_ABORT); _env->ReleaseLongArrayElements(depClosureArray, jDepClosures, JNI_ABORT); _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); return ret; } } static jlong static jlong nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID, nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID, jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray, jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray) { jintArray sizeArray) { jlong ret = 0; jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr); jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr); jsize jParamLength = _env->GetArrayLength(paramArray); jsize jParamLength = _env->GetArrayLength(paramArray); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); jsize values_length = _env->GetArrayLength(valueArray); for (int i = 0; i< fieldIDs_length; i++) { jint* jSizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); size_t numValues; RsScriptFieldID* fieldIDs; uintptr_t* values; if (fieldIDs_length != values_length || values_length != sizes_length) { ALOGE("Unmatched field IDs, values, and sizes in closure creation."); goto exit; } numValues = (size_t) fieldIDs_length; if (numValues > kMaxNumberArgsAndBindings) { ALOGE("Too many arguments or globals in closure creation"); goto exit; } fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * numValues); if (fieldIDs == nullptr) { goto exit; } for (size_t i = 0; i< numValues; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); values = (uintptr_t*)alloca(sizeof(uintptr_t) * numValues); jsize values_length = _env->GetArrayLength(valueArray); if (values == nullptr) { uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); goto exit; for (int i = 0; i < values_length; i++) { values[i] = (uintptr_t)jValues[i]; } } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); for (size_t i = 0; i < numValues; i++) { jsize sizes_length = _env->GetArrayLength(sizeArray); values[i] = (uintptr_t)jValues[i]; } return (jlong)(uintptr_t)rsInvokeClosureCreate( ret = (jlong)(uintptr_t)rsInvokeClosureCreate( (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength, (RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, fieldIDs, numValues, values, numValues, (int*)sizes, (size_t)sizes_length); (int*)jSizes, numValues); exit: _env->ReleaseIntArrayElements (sizeArray, jSizes, JNI_ABORT); _env->ReleaseLongArrayElements(valueArray, jValues, JNI_ABORT); _env->ReleaseLongArrayElements(fieldIDArray, jFieldIDs, JNI_ABORT); _env->ReleaseByteArrayElements(paramArray, jParams, JNI_ABORT); return ret; } } static void static void Loading @@ -425,20 +516,40 @@ nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID, static long static long nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name, nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jstring name, jstring cacheDir, jlongArray closureArray) { jstring cacheDir, jlongArray closureArray) { jlong ret = 0; AutoJavaStringToUTF8 nameUTF(_env, name); AutoJavaStringToUTF8 nameUTF(_env, name); AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); AutoJavaStringToUTF8 cacheDirUTF(_env, cacheDir); jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jsize numClosures = _env->GetArrayLength(closureArray); jsize numClosures = _env->GetArrayLength(closureArray); RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); RsClosure* closures; if (numClosures > (jsize) kMaxNumberClosuresInScriptGroup) { ALOGE("Too many closures in script group"); goto exit; } closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); if (closures == nullptr) { goto exit; } for (int i = 0; i < numClosures; i++) { for (int i = 0; i < numClosures; i++) { closures[i] = (RsClosure)jClosures[i]; closures[i] = (RsClosure)jClosures[i]; } } return (jlong)(uintptr_t)rsScriptGroup2Create( ret = (jlong)(uintptr_t)rsScriptGroup2Create( (RsContext)con, nameUTF.c_str(), nameUTF.length(), (RsContext)con, nameUTF.c_str(), nameUTF.length(), cacheDirUTF.c_str(), cacheDirUTF.length(), cacheDirUTF.c_str(), cacheDirUTF.length(), closures, numClosures); closures, numClosures); exit: _env->ReleaseLongArrayElements(closureArray, jClosures, JNI_ABORT); return ret; } } static void static void Loading Loading @@ -1766,8 +1877,14 @@ nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, if (ains != nullptr) { if (ains != nullptr) { in_len = _env->GetArrayLength(ains); in_len = _env->GetArrayLength(ains); in_ptr = _env->GetLongArrayElements(ains, nullptr); if (in_len > (jint)kMaxNumberKernelArguments) { ALOGE("Too many arguments in kernel launch."); // TODO (b/20758983): Report back to Java and throw an exception return; } // TODO (b/20760800): Check in_ptr is not null in_ptr = _env->GetLongArrayElements(ains, nullptr); if (sizeof(RsAllocation) == sizeof(jlong)) { if (sizeof(RsAllocation) == sizeof(jlong)) { in_allocs = (RsAllocation*)in_ptr; in_allocs = (RsAllocation*)in_ptr; Loading @@ -1775,6 +1892,11 @@ nScriptForEach(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot, // Convert from 64-bit jlong types to the native pointer type. // Convert from 64-bit jlong types to the native pointer type. in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation)); if (in_allocs == nullptr) { ALOGE("Failed launching kernel for lack of memory."); _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT); return; } for (int index = in_len; --index >= 0;) { for (int index = in_len; --index >= 0;) { in_allocs[index] = (RsAllocation)in_ptr[index]; in_allocs[index] = (RsAllocation)in_ptr[index]; Loading