Loading rs/java/android/renderscript/RenderScript.java +40 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,46 @@ public class RenderScript { rsnContextResume(mContext); } native long rsnClosureCreate(long con, long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs); synchronized long nClosureCreate(long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { validate(); return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, sizes, depClosures, depFieldIDs); } native void rsnClosureSetArg(long con, long closureID, int index, long value, int size); synchronized void nClosureSetArg(long closureID, int index, long value, int size) { validate(); rsnClosureSetArg(mContext, closureID, index, value, size); } native void rsnClosureSetGlobal(long con, long closureID, long fieldID, long value, int size); // Does this have to be synchronized? synchronized void nClosureSetGlobal(long closureID, long fieldID, long value, int size) { validate(); // TODO: is this necessary? rsnClosureSetGlobal(mContext, closureID, fieldID, value, size); } native long rsnScriptGroup2Create(long con, long[] closures); synchronized long nScriptGroup2Create(long[] closures) { validate(); return rsnScriptGroup2Create(mContext, closures); } native void rsnScriptGroup2Execute(long con, long groupID); synchronized void nScriptGroup2Execute(long groupID) { validate(); rsnScriptGroup2Execute(mContext, groupID); } native void rsnAssignName(long con, long obj, byte[] name); synchronized void nAssignName(long obj, byte[] name) { validate(); Loading rs/java/android/renderscript/ScriptGroup2.java 0 → 100644 +319 −0 Original line number Diff line number Diff line package android.renderscript; import android.util.Log; import android.util.Pair; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** @hide Pending Android public API approval. */ /** ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1) You can add "@hide" javadoc comments to the methods, etc. listed in the errors above. 2) You can update current.txt by executing the following command: make update-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** @hide Pending Android public API approval. */ public class ScriptGroup2 extends BaseObj { public static class Closure extends BaseObj { private Allocation mReturnValue; private Map<Script.FieldID, Object> mBindings; private Future mReturnFuture; private Map<Script.FieldID, Future> mGlobalFuture; private static final String TAG = "Closure"; public Closure(long id, RenderScript rs) { super(id, rs); } public Closure(RenderScript rs, Script.KernelID kernelID, Type returnType, Object[] args, Map<Script.FieldID, Object> globals) { super(0, rs); mReturnValue = Allocation.createTyped(rs, returnType); mBindings = new HashMap<Script.FieldID, Object>(); mGlobalFuture = new HashMap<Script.FieldID, Future>(); int numValues = args.length + globals.size(); long[] fieldIDs = new long[numValues]; long[] values = new long[numValues]; int[] sizes = new int[numValues]; long[] depClosures = new long[numValues]; long[] depFieldIDs = new long[numValues]; int i; for (i = 0; i < args.length; i++) { Object obj = args[i]; fieldIDs[i] = 0; if (obj instanceof UnboundValue) { UnboundValue unbound = (UnboundValue)obj; unbound.addReference(this, i); } else { retrieveValueAndDependenceInfo(rs, i, args[i], values, sizes, depClosures, depFieldIDs); } } for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) { Object obj = entry.getValue(); Script.FieldID fieldID = entry.getKey(); fieldIDs[i] = fieldID.getID(rs); if (obj instanceof UnboundValue) { UnboundValue unbound = (UnboundValue)obj; unbound.addReference(this, fieldID); } else { retrieveValueAndDependenceInfo(rs, i, obj, values, sizes, depClosures, depFieldIDs); } i++; } long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs), fieldIDs, values, sizes, depClosures, depFieldIDs); setID(id); } private static void retrieveValueAndDependenceInfo(RenderScript rs, int index, Object obj, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { if (obj instanceof Future) { Future f = (Future)obj; obj = f.getValue(); depClosures[index] = f.getClosure().getID(rs); Script.FieldID fieldID = f.getFieldID(); depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0; } else { depClosures[index] = 0; depFieldIDs[index] = 0; } ValueAndSize vs = new ValueAndSize(rs, obj); values[index] = vs.value; sizes[index] = vs.size; } public Future getReturn() { if (mReturnFuture == null) { mReturnFuture = new Future(this, null, mReturnValue); } return mReturnFuture; } public Future getGlobal(Script.FieldID field) { Future f = mGlobalFuture.get(field); if (f == null) { f = new Future(this, field, mBindings.get(field)); mGlobalFuture.put(field, f); } return f; } void setArg(int index, Object obj) { ValueAndSize vs = new ValueAndSize(mRS, obj); mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size); } void setGlobal(Script.FieldID fieldID, Object obj) { ValueAndSize vs = new ValueAndSize(mRS, obj); mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size); } private static final class ValueAndSize { public ValueAndSize(RenderScript rs, Object obj) { if (obj instanceof Allocation) { value = ((Allocation)obj).getID(rs); size = -1; } else if (obj instanceof Boolean) { value = ((Boolean)obj).booleanValue() ? 1 : 0; size = 4; } else if (obj instanceof Integer) { value = ((Integer)obj).longValue(); size = 4; } else if (obj instanceof Long) { value = ((Long)obj).longValue(); size = 8; } else if (obj instanceof Float) { value = ((Float)obj).longValue(); size = 4; } else if (obj instanceof Double) { value = ((Double)obj).longValue(); size = 8; } } public long value; public int size; } } public static class Future { Closure mClosure; Script.FieldID mFieldID; Object mValue; Future(Closure closure, Script.FieldID fieldID, Object value) { mClosure = closure; mFieldID = fieldID; mValue = value; } Closure getClosure() { return mClosure; } Script.FieldID getFieldID() { return mFieldID; } Object getValue() { return mValue; } } public static class UnboundValue { // Either mFieldID or mArgIndex should be set but not both. List<Pair<Closure, Script.FieldID>> mFieldID; // -1 means unset. Legal values are 0 .. n-1, where n is the number of // arguments for the referencing closure. List<Pair<Closure, Integer>> mArgIndex; UnboundValue() { mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>(); mArgIndex = new ArrayList<Pair<Closure, Integer>>(); } void addReference(Closure closure, int index) { mArgIndex.add(Pair.create(closure, Integer.valueOf(index))); } void addReference(Closure closure, Script.FieldID fieldID) { mFieldID.add(Pair.create(closure, fieldID)); } void set(Object value) { for (Pair<Closure, Integer> p : mArgIndex) { Closure closure = p.first; int index = p.second.intValue(); closure.setArg(index, value); } for (Pair<Closure, Script.FieldID> p : mFieldID) { Closure closure = p.first; Script.FieldID fieldID = p.second; closure.setGlobal(fieldID, value); } } } List<Closure> mClosures; List<UnboundValue> mInputs; Future[] mOutputs; private static final String TAG = "ScriptGroup2"; public ScriptGroup2(long id, RenderScript rs) { super(id, rs); } ScriptGroup2(RenderScript rs, List<Closure> closures, List<UnboundValue> inputs, Future[] outputs) { super(0, rs); mClosures = closures; mInputs = inputs; mOutputs = outputs; long[] closureIDs = new long[closures.size()]; for (int i = 0; i < closureIDs.length; i++) { closureIDs[i] = closures.get(i).getID(rs); } long id = rs.nScriptGroup2Create(closureIDs); setID(id); } // TODO: If this was reflected method, we could enforce the number of // arguments. public Object[] execute(Object... inputs) { if (inputs.length < mInputs.size()) { Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " + "less than expected " + mInputs.size()); return null; } if (inputs.length > mInputs.size()) { Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " + "more than expected " + mInputs.size()); } for (int i = 0; i < mInputs.size(); i++) { Object obj = inputs[i]; if (obj instanceof Future || obj instanceof UnboundValue) { Log.e(TAG, this.toString() + ": input " + i + " is a future or unbound value"); return null; } UnboundValue unbound = mInputs.get(i); unbound.set(obj); } mRS.nScriptGroup2Execute(getID(mRS)); Object[] outputObjs = new Object[mOutputs.length]; int i = 0; for (Future f : mOutputs) { outputObjs[i++] = f.getValue(); } return outputObjs; } /** @hide Pending Android public API approval. */ public static final class Builder { RenderScript mRS; List<Closure> mClosures; List<UnboundValue> mInputs; private static final String TAG = "ScriptGroup2.Builder"; public Builder(RenderScript rs) { mRS = rs; mClosures = new ArrayList<Closure>(); mInputs = new ArrayList<UnboundValue>(); } public Closure addKernel(Script.KernelID k, Type returnType, Object[] args, Map<Script.FieldID, Object> globalBindings) { Closure c = new Closure(mRS, k, returnType, args, globalBindings); mClosures.add(c); return c; } public UnboundValue addInput() { UnboundValue unbound = new UnboundValue(); mInputs.add(unbound); return unbound; } public ScriptGroup2 create(Future... outputs) { // TODO: Save all script groups that have been created and return one that was // saved and matches the outputs. ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs); return ret; } } } rs/jni/android_renderscript_RenderScript.cpp +87 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,88 @@ nContextFinish(JNIEnv *_env, jobject _this, jlong con) rsContextFinish((RsContext)con); } static jlong nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID, jlong returnValue, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray, jlongArray depClosureArray, jlongArray depFieldIDArray) { jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); for (int i = 0; i< fieldIDs_length; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); jsize values_length = _env->GetArrayLength(valueArray); uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); for (int i = 0; i < values_length; i++) { values[i] = (uintptr_t)jValues[i]; } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); jlong* jDepClosures = _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]; } jlong* jDepFieldIDs = _env->GetLongArrayElements(depFieldIDArray, nullptr); jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); RsScriptFieldID* depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length); for (int i = 0; i < depClosures_length; i++) { depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; } return (jlong)(uintptr_t)rsClosureCreate( (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, (size_t*)sizes, (size_t)sizes_length, depClosures, (size_t)depClosures_length, depFieldIDs, (size_t)depFieldIDs_length); } static void nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID, jint index, jlong value, jint size) { rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index, (uintptr_t)value, (size_t)size); } static void nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID, jlong fieldID, jlong value, jint size) { rsClosureSetGlobal((RsContext)con, (RsClosure)closureID, (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size); } static long nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jlongArray closureArray) { jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jsize numClosures = _env->GetArrayLength(closureArray); RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); for (int i = 0; i < numClosures; i++) { closures[i] = (RsClosure)jClosures[i]; } return (jlong)(uintptr_t)rsScriptGroup2Create((RsContext)con, closures, numClosures); } static void nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) { rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID); } static void nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str) { Loading Loading @@ -1841,6 +1923,9 @@ static JNINativeMethod methods[] = { {"rsnContextPause", "(J)V", (void*)nContextPause }, {"rsnContextResume", "(J)V", (void*)nContextResume }, {"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage }, {"rsnClosureCreate", "(JJJ[J[J[I[J[J)J", (void*)nClosureCreate }, {"rsnClosureSetArg", "(JJIJI)V", (void*)nClosureSetArg }, {"rsnClosureSetGlobal", "(JJJJI)V", (void*)nClosureSetGlobal }, {"rsnAssignName", "(JJ[B)V", (void*)nAssignName }, {"rsnGetName", "(JJ)Ljava/lang/String;", (void*)nGetName }, {"rsnObjDestroy", "(JJ)V", (void*)nObjDestroy }, Loading Loading @@ -1915,9 +2000,11 @@ static JNINativeMethod methods[] = { {"rsnScriptKernelIDCreate", "(JJII)J", (void*)nScriptKernelIDCreate }, {"rsnScriptFieldIDCreate", "(JJI)J", (void*)nScriptFieldIDCreate }, {"rsnScriptGroupCreate", "(J[J[J[J[J[J)J", (void*)nScriptGroupCreate }, {"rsnScriptGroup2Create", "(J[J)J", (void*)nScriptGroup2Create }, {"rsnScriptGroupSetInput", "(JJJJ)V", (void*)nScriptGroupSetInput }, {"rsnScriptGroupSetOutput", "(JJJJ)V", (void*)nScriptGroupSetOutput }, {"rsnScriptGroupExecute", "(JJ)V", (void*)nScriptGroupExecute }, {"rsnScriptGroup2Execute", "(JJ)V", (void*)nScriptGroup2Execute }, {"rsnProgramStoreCreate", "(JZZZZZZIII)J", (void*)nProgramStoreCreate }, Loading Loading
rs/java/android/renderscript/RenderScript.java +40 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,46 @@ public class RenderScript { rsnContextResume(mContext); } native long rsnClosureCreate(long con, long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs); synchronized long nClosureCreate(long kernelID, long returnValue, long[] fieldIDs, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { validate(); return rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values, sizes, depClosures, depFieldIDs); } native void rsnClosureSetArg(long con, long closureID, int index, long value, int size); synchronized void nClosureSetArg(long closureID, int index, long value, int size) { validate(); rsnClosureSetArg(mContext, closureID, index, value, size); } native void rsnClosureSetGlobal(long con, long closureID, long fieldID, long value, int size); // Does this have to be synchronized? synchronized void nClosureSetGlobal(long closureID, long fieldID, long value, int size) { validate(); // TODO: is this necessary? rsnClosureSetGlobal(mContext, closureID, fieldID, value, size); } native long rsnScriptGroup2Create(long con, long[] closures); synchronized long nScriptGroup2Create(long[] closures) { validate(); return rsnScriptGroup2Create(mContext, closures); } native void rsnScriptGroup2Execute(long con, long groupID); synchronized void nScriptGroup2Execute(long groupID) { validate(); rsnScriptGroup2Execute(mContext, groupID); } native void rsnAssignName(long con, long obj, byte[] name); synchronized void nAssignName(long obj, byte[] name) { validate(); Loading
rs/java/android/renderscript/ScriptGroup2.java 0 → 100644 +319 −0 Original line number Diff line number Diff line package android.renderscript; import android.util.Log; import android.util.Pair; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** @hide Pending Android public API approval. */ /** ****************************** You have tried to change the API from what has been previously approved. To make these errors go away, you have two choices: 1) You can add "@hide" javadoc comments to the methods, etc. listed in the errors above. 2) You can update current.txt by executing the following command: make update-api To submit the revised current.txt to the main Android repository, you will need approval. ****************************** @hide Pending Android public API approval. */ public class ScriptGroup2 extends BaseObj { public static class Closure extends BaseObj { private Allocation mReturnValue; private Map<Script.FieldID, Object> mBindings; private Future mReturnFuture; private Map<Script.FieldID, Future> mGlobalFuture; private static final String TAG = "Closure"; public Closure(long id, RenderScript rs) { super(id, rs); } public Closure(RenderScript rs, Script.KernelID kernelID, Type returnType, Object[] args, Map<Script.FieldID, Object> globals) { super(0, rs); mReturnValue = Allocation.createTyped(rs, returnType); mBindings = new HashMap<Script.FieldID, Object>(); mGlobalFuture = new HashMap<Script.FieldID, Future>(); int numValues = args.length + globals.size(); long[] fieldIDs = new long[numValues]; long[] values = new long[numValues]; int[] sizes = new int[numValues]; long[] depClosures = new long[numValues]; long[] depFieldIDs = new long[numValues]; int i; for (i = 0; i < args.length; i++) { Object obj = args[i]; fieldIDs[i] = 0; if (obj instanceof UnboundValue) { UnboundValue unbound = (UnboundValue)obj; unbound.addReference(this, i); } else { retrieveValueAndDependenceInfo(rs, i, args[i], values, sizes, depClosures, depFieldIDs); } } for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) { Object obj = entry.getValue(); Script.FieldID fieldID = entry.getKey(); fieldIDs[i] = fieldID.getID(rs); if (obj instanceof UnboundValue) { UnboundValue unbound = (UnboundValue)obj; unbound.addReference(this, fieldID); } else { retrieveValueAndDependenceInfo(rs, i, obj, values, sizes, depClosures, depFieldIDs); } i++; } long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs), fieldIDs, values, sizes, depClosures, depFieldIDs); setID(id); } private static void retrieveValueAndDependenceInfo(RenderScript rs, int index, Object obj, long[] values, int[] sizes, long[] depClosures, long[] depFieldIDs) { if (obj instanceof Future) { Future f = (Future)obj; obj = f.getValue(); depClosures[index] = f.getClosure().getID(rs); Script.FieldID fieldID = f.getFieldID(); depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0; } else { depClosures[index] = 0; depFieldIDs[index] = 0; } ValueAndSize vs = new ValueAndSize(rs, obj); values[index] = vs.value; sizes[index] = vs.size; } public Future getReturn() { if (mReturnFuture == null) { mReturnFuture = new Future(this, null, mReturnValue); } return mReturnFuture; } public Future getGlobal(Script.FieldID field) { Future f = mGlobalFuture.get(field); if (f == null) { f = new Future(this, field, mBindings.get(field)); mGlobalFuture.put(field, f); } return f; } void setArg(int index, Object obj) { ValueAndSize vs = new ValueAndSize(mRS, obj); mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size); } void setGlobal(Script.FieldID fieldID, Object obj) { ValueAndSize vs = new ValueAndSize(mRS, obj); mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size); } private static final class ValueAndSize { public ValueAndSize(RenderScript rs, Object obj) { if (obj instanceof Allocation) { value = ((Allocation)obj).getID(rs); size = -1; } else if (obj instanceof Boolean) { value = ((Boolean)obj).booleanValue() ? 1 : 0; size = 4; } else if (obj instanceof Integer) { value = ((Integer)obj).longValue(); size = 4; } else if (obj instanceof Long) { value = ((Long)obj).longValue(); size = 8; } else if (obj instanceof Float) { value = ((Float)obj).longValue(); size = 4; } else if (obj instanceof Double) { value = ((Double)obj).longValue(); size = 8; } } public long value; public int size; } } public static class Future { Closure mClosure; Script.FieldID mFieldID; Object mValue; Future(Closure closure, Script.FieldID fieldID, Object value) { mClosure = closure; mFieldID = fieldID; mValue = value; } Closure getClosure() { return mClosure; } Script.FieldID getFieldID() { return mFieldID; } Object getValue() { return mValue; } } public static class UnboundValue { // Either mFieldID or mArgIndex should be set but not both. List<Pair<Closure, Script.FieldID>> mFieldID; // -1 means unset. Legal values are 0 .. n-1, where n is the number of // arguments for the referencing closure. List<Pair<Closure, Integer>> mArgIndex; UnboundValue() { mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>(); mArgIndex = new ArrayList<Pair<Closure, Integer>>(); } void addReference(Closure closure, int index) { mArgIndex.add(Pair.create(closure, Integer.valueOf(index))); } void addReference(Closure closure, Script.FieldID fieldID) { mFieldID.add(Pair.create(closure, fieldID)); } void set(Object value) { for (Pair<Closure, Integer> p : mArgIndex) { Closure closure = p.first; int index = p.second.intValue(); closure.setArg(index, value); } for (Pair<Closure, Script.FieldID> p : mFieldID) { Closure closure = p.first; Script.FieldID fieldID = p.second; closure.setGlobal(fieldID, value); } } } List<Closure> mClosures; List<UnboundValue> mInputs; Future[] mOutputs; private static final String TAG = "ScriptGroup2"; public ScriptGroup2(long id, RenderScript rs) { super(id, rs); } ScriptGroup2(RenderScript rs, List<Closure> closures, List<UnboundValue> inputs, Future[] outputs) { super(0, rs); mClosures = closures; mInputs = inputs; mOutputs = outputs; long[] closureIDs = new long[closures.size()]; for (int i = 0; i < closureIDs.length; i++) { closureIDs[i] = closures.get(i).getID(rs); } long id = rs.nScriptGroup2Create(closureIDs); setID(id); } // TODO: If this was reflected method, we could enforce the number of // arguments. public Object[] execute(Object... inputs) { if (inputs.length < mInputs.size()) { Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " + "less than expected " + mInputs.size()); return null; } if (inputs.length > mInputs.size()) { Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " + "more than expected " + mInputs.size()); } for (int i = 0; i < mInputs.size(); i++) { Object obj = inputs[i]; if (obj instanceof Future || obj instanceof UnboundValue) { Log.e(TAG, this.toString() + ": input " + i + " is a future or unbound value"); return null; } UnboundValue unbound = mInputs.get(i); unbound.set(obj); } mRS.nScriptGroup2Execute(getID(mRS)); Object[] outputObjs = new Object[mOutputs.length]; int i = 0; for (Future f : mOutputs) { outputObjs[i++] = f.getValue(); } return outputObjs; } /** @hide Pending Android public API approval. */ public static final class Builder { RenderScript mRS; List<Closure> mClosures; List<UnboundValue> mInputs; private static final String TAG = "ScriptGroup2.Builder"; public Builder(RenderScript rs) { mRS = rs; mClosures = new ArrayList<Closure>(); mInputs = new ArrayList<UnboundValue>(); } public Closure addKernel(Script.KernelID k, Type returnType, Object[] args, Map<Script.FieldID, Object> globalBindings) { Closure c = new Closure(mRS, k, returnType, args, globalBindings); mClosures.add(c); return c; } public UnboundValue addInput() { UnboundValue unbound = new UnboundValue(); mInputs.add(unbound); return unbound; } public ScriptGroup2 create(Future... outputs) { // TODO: Save all script groups that have been created and return one that was // saved and matches the outputs. ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs); return ret; } } }
rs/jni/android_renderscript_RenderScript.cpp +87 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,88 @@ nContextFinish(JNIEnv *_env, jobject _this, jlong con) rsContextFinish((RsContext)con); } static jlong nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID, jlong returnValue, jlongArray fieldIDArray, jlongArray valueArray, jintArray sizeArray, jlongArray depClosureArray, jlongArray depFieldIDArray) { jlong* jFieldIDs = _env->GetLongArrayElements(fieldIDArray, nullptr); jsize fieldIDs_length = _env->GetArrayLength(fieldIDArray); RsScriptFieldID* fieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * fieldIDs_length); for (int i = 0; i< fieldIDs_length; i++) { fieldIDs[i] = (RsScriptFieldID)jFieldIDs[i]; } jlong* jValues = _env->GetLongArrayElements(valueArray, nullptr); jsize values_length = _env->GetArrayLength(valueArray); uintptr_t* values = (uintptr_t*)alloca(sizeof(uintptr_t) * values_length); for (int i = 0; i < values_length; i++) { values[i] = (uintptr_t)jValues[i]; } jint* sizes = _env->GetIntArrayElements(sizeArray, nullptr); jsize sizes_length = _env->GetArrayLength(sizeArray); jlong* jDepClosures = _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]; } jlong* jDepFieldIDs = _env->GetLongArrayElements(depFieldIDArray, nullptr); jsize depFieldIDs_length = _env->GetArrayLength(depFieldIDArray); RsScriptFieldID* depFieldIDs = (RsScriptFieldID*)alloca(sizeof(RsScriptFieldID) * depFieldIDs_length); for (int i = 0; i < depClosures_length; i++) { depFieldIDs[i] = (RsClosure)jDepFieldIDs[i]; } return (jlong)(uintptr_t)rsClosureCreate( (RsContext)con, (RsScriptKernelID)kernelID, (RsAllocation)returnValue, fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length, (size_t*)sizes, (size_t)sizes_length, depClosures, (size_t)depClosures_length, depFieldIDs, (size_t)depFieldIDs_length); } static void nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID, jint index, jlong value, jint size) { rsClosureSetArg((RsContext)con, (RsClosure)closureID, (uint32_t)index, (uintptr_t)value, (size_t)size); } static void nClosureSetGlobal(JNIEnv *_env, jobject _this, jlong con, jlong closureID, jlong fieldID, jlong value, jint size) { rsClosureSetGlobal((RsContext)con, (RsClosure)closureID, (RsScriptFieldID)fieldID, (uintptr_t)value, (size_t)size); } static long nScriptGroup2Create(JNIEnv *_env, jobject _this, jlong con, jlongArray closureArray) { jlong* jClosures = _env->GetLongArrayElements(closureArray, nullptr); jsize numClosures = _env->GetArrayLength(closureArray); RsClosure* closures = (RsClosure*)alloca(sizeof(RsClosure) * numClosures); for (int i = 0; i < numClosures; i++) { closures[i] = (RsClosure)jClosures[i]; } return (jlong)(uintptr_t)rsScriptGroup2Create((RsContext)con, closures, numClosures); } static void nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) { rsScriptGroupExecute((RsContext)con, (RsScriptGroup2)groupID); } static void nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str) { Loading Loading @@ -1841,6 +1923,9 @@ static JNINativeMethod methods[] = { {"rsnContextPause", "(J)V", (void*)nContextPause }, {"rsnContextResume", "(J)V", (void*)nContextResume }, {"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage }, {"rsnClosureCreate", "(JJJ[J[J[I[J[J)J", (void*)nClosureCreate }, {"rsnClosureSetArg", "(JJIJI)V", (void*)nClosureSetArg }, {"rsnClosureSetGlobal", "(JJJJI)V", (void*)nClosureSetGlobal }, {"rsnAssignName", "(JJ[B)V", (void*)nAssignName }, {"rsnGetName", "(JJ)Ljava/lang/String;", (void*)nGetName }, {"rsnObjDestroy", "(JJ)V", (void*)nObjDestroy }, Loading Loading @@ -1915,9 +2000,11 @@ static JNINativeMethod methods[] = { {"rsnScriptKernelIDCreate", "(JJII)J", (void*)nScriptKernelIDCreate }, {"rsnScriptFieldIDCreate", "(JJI)J", (void*)nScriptFieldIDCreate }, {"rsnScriptGroupCreate", "(J[J[J[J[J[J)J", (void*)nScriptGroupCreate }, {"rsnScriptGroup2Create", "(J[J)J", (void*)nScriptGroup2Create }, {"rsnScriptGroupSetInput", "(JJJJ)V", (void*)nScriptGroupSetInput }, {"rsnScriptGroupSetOutput", "(JJJJ)V", (void*)nScriptGroupSetOutput }, {"rsnScriptGroupExecute", "(JJ)V", (void*)nScriptGroupExecute }, {"rsnScriptGroup2Execute", "(JJ)V", (void*)nScriptGroup2Execute }, {"rsnProgramStoreCreate", "(JZZZZZZIII)J", (void*)nProgramStoreCreate }, Loading