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; /** ****************************** 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 mBindings; private Future mReturnFuture; private Map mGlobalFuture; private FieldPacker mFP; 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 globals) { super(0, rs); mReturnValue = Allocation.createTyped(rs, returnType); mBindings = new HashMap(); mGlobalFuture = new HashMap(); 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 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); } public Closure(RenderScript rs, Script.InvokeID invokeID, Object[] args, Map globals) { super(0, rs); mFP = FieldPacker.createFieldPack(args); mBindings = new HashMap(); mGlobalFuture = new HashMap(); int numValues = 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 = 0; for (Map.Entry 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 { // TODO(yangni): Verify obj not a future. retrieveValueAndDependenceInfo(rs, i, obj, values, sizes, depClosures, depFieldIDs); } i++; } long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs, values, sizes); 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; if (obj == null) { // Value is originally created by the owner closure values[index] = 0; sizes[index] = 0; return; } } 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) { // If the field is not bound to this closure, this will return a future // without an associated value (reference). So this is not working for // cross-module (cross-script) linking in this case where a field not // explicitly bound. 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> mFieldID; // -1 means unset. Legal values are 0 .. n-1, where n is the number of // arguments for the referencing closure. List> mArgIndex; UnboundValue() { mFieldID = new ArrayList>(); mArgIndex = new ArrayList>(); } 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 p : mArgIndex) { Closure closure = p.first; int index = p.second.intValue(); closure.setArg(index, value); } for (Pair p : mFieldID) { Closure closure = p.first; Script.FieldID fieldID = p.second; closure.setGlobal(fieldID, value); } } } List mClosures; List mInputs; Future[] mOutputs; private static final String TAG = "ScriptGroup2"; public ScriptGroup2(long id, RenderScript rs) { super(id, rs); } ScriptGroup2(RenderScript rs, List closures, List 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(ScriptC.mCachePath, closureIDs); setID(id); } 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 mClosures; List mInputs; private static final String TAG = "ScriptGroup2.Builder"; public Builder(RenderScript rs) { mRS = rs; mClosures = new ArrayList(); mInputs = new ArrayList(); } public Closure addKernel(Script.KernelID k, Type returnType, Object[] args, Map globalBindings) { Closure c = new Closure(mRS, k, returnType, args, globalBindings); mClosures.add(c); return c; } public Closure addInvoke(Script.InvokeID invoke, Object[] args, Map globalBindings) { Closure c = new Closure(mRS, invoke, args, globalBindings); mClosures.add(c); return c; } public UnboundValue addInput() { UnboundValue unbound = new UnboundValue(); mInputs.add(unbound); return unbound; } public ScriptGroup2 create(Future... outputs) { ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs); return ret; } } }