summaryrefslogtreecommitdiffstats
path: root/rs/java/android/renderscript/ScriptGroup2.java
diff options
context:
space:
mode:
Diffstat (limited to 'rs/java/android/renderscript/ScriptGroup2.java')
-rw-r--r--rs/java/android/renderscript/ScriptGroup2.java189
1 files changed, 165 insertions, 24 deletions
diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java
index 13e22aa..9d73ac4 100644
--- a/rs/java/android/renderscript/ScriptGroup2.java
+++ b/rs/java/android/renderscript/ScriptGroup2.java
@@ -24,25 +24,39 @@ import java.util.List;
import java.util.Map;
/**
+ * ScriptGroup2 is a new, enhanced API for script groups.
+ * A script group is a collection of kernels or invocable functions, with
+ * data dependencies defined among them. A script group is launched for
+ * execution as a whole, rather than launching each kernel or invocable function
+ * separately. Once created, a script group can be repeatedly used with
+ * different inputs.
+ * <p>
+ * In the new ScriptGroup2 API, a script group is modeled using closures.
+ * A closure, in this context, is defined as a function call to a kernel or
+ * invocable function. Each function argument or global variable accessed inside
+ * the function is bound to 1) a known value, 2) a script group input, or 3) a
+ * future. A future is the output of a closure, i.e., the return value of the
+ * function or a global variable written by that function.
+ * <p>
+ * A script group is a directed acyclic graph (DAG), in which closures are the
+ * vertices and the dependencies among them are the edges.
+ * The way the ScriptGroup2 API is designed makes cycles impossible in a script
+ * group. For example, it is impossible to make forward references to futures,
+ * i.e., it is impossible to set as input to a closure the future from itself or
+ * a future from another closure that directly or indirectly depends on it.
+ * <p>
+ * Grouping kernels and invocable functions together allows to execute them more
+ * efficiently. Runtime and compiler optimizations are applied to script
+ * groups, to reduce computation or communication overhead, and to make more
+ * efficient use of the CPU and the GPU.
+ */
-******************************
-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 {
+ /**
+ * An opaque class for closures
+ */
+
public static class Closure extends BaseObj {
private Object[] mArgs;
private Allocation mReturnValue;
@@ -135,7 +149,6 @@ public class ScriptGroup2 extends BaseObj {
UnboundValue unbound = (UnboundValue)obj;
unbound.addReference(this, fieldID);
} else {
- // TODO(yangni): Verify obj not a future.
retrieveValueAndDependenceInfo(rs, i, obj, values,
sizes, depClosures, depFieldIDs);
}
@@ -177,6 +190,12 @@ public class ScriptGroup2 extends BaseObj {
sizes[index] = vs.size;
}
+ /**
+ * Returns the future for the return value
+ *
+ * @return a future
+ */
+
public Future getReturn() {
if (mReturnFuture == null) {
mReturnFuture = new Future(this, null, mReturnValue);
@@ -185,6 +204,13 @@ public class ScriptGroup2 extends BaseObj {
return mReturnFuture;
}
+ /**
+ * Returns the future for a global variable
+ *
+ * @param field the field ID for the global variable
+ * @return a future
+ */
+
public Future getGlobal(Script.FieldID field) {
Future f = mGlobalFuture.get(field);
@@ -239,6 +265,10 @@ public class ScriptGroup2 extends BaseObj {
}
}
+ /**
+ * An opaque class for futures
+ */
+
public static class Future {
Closure mClosure;
Script.FieldID mFieldID;
@@ -255,6 +285,10 @@ public class ScriptGroup2 extends BaseObj {
Object getValue() { return mValue; }
}
+ /**
+ * An opaque class for unbound values (a.k.a. script group inputs)
+ */
+
public static class UnboundValue {
// Either mFieldID or mArgIndex should be set but not both.
List<Pair<Closure, Script.FieldID>> mFieldID;
@@ -314,6 +348,13 @@ public class ScriptGroup2 extends BaseObj {
setID(id);
}
+ /**
+ * Executes a script group
+ *
+ * @param inputs inputs to the script group
+ * @return outputs of the script group as an array of objects
+ */
+
public Object[] execute(Object... inputs) {
if (inputs.length < mInputs.size()) {
Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
@@ -348,32 +389,95 @@ public class ScriptGroup2 extends BaseObj {
}
/**
- @hide Pending Android public API approval.
- */
+ * A class representing a binding of a value to a global variable in a
+ * kernel or invocable function. Such a binding can be used to create a
+ * closure.
+ */
+
public static final class Binding {
- public Script.FieldID mField;
- public Object mValue;
+ private Script.FieldID mField;
+ private Object mValue;
+
+ /**
+ * Returns a Binding object that binds value to field
+ *
+ * @param field the Script.FieldID of the global variable
+ * @param value the value
+ */
+
public Binding(Script.FieldID field, Object value) {
mField = field;
mValue = value;
}
+
+ /**
+ * Returns the field ID
+ */
+
+ public Script.FieldID getField() { return mField; }
+
+ /**
+ * Returns the value
+ */
+
+ public Object getValue() { return mValue; }
}
/**
- @hide Pending Android public API approval.
- */
+ * The builder class to create a script group.
+ * <p>
+ * Closures are created using the {@link #addKernel} or {@link #addInvoke}
+ * methods.
+ * When a closure is created, futures from previously created closures
+ * can be used as inputs.
+ * Unbound values can be used as inputs to create closures as well.
+ * An unbound value is created using the {@link #addInput} method.
+ * Unbound values become inputs to the script group to be created,
+ * in the order that they are added.
+ * A script group is created by a call to the {@link #create} method, which
+ * accepts an array of futures as the outputs for the script group.
+ * <p>
+ * Closures in a script group can be evaluated in any order as long as the
+ * following conditions are met.
+ * First, a closure must be evaluated before any other closures that take its
+ * futures as inputs.
+ * Second, all closures added before an invoke closure must be evaluated
+ * before it.
+ * Third, all closures added after an invoke closure must be evaluated after
+ * it.
+ * <p>
+ * As a special case, the order that the closures are added is a legal
+ * evaluation order. However, other evaluation orders are allowed, including
+ * concurrently evaluating independent closures.
+ */
+
public static final class Builder {
RenderScript mRS;
List<Closure> mClosures;
List<UnboundValue> mInputs;
private static final String TAG = "ScriptGroup2.Builder";
+ /**
+ * Returns a Builder object
+ *
+ * @param rs the RenderScript context
+ */
public Builder(RenderScript rs) {
mRS = rs;
mClosures = new ArrayList<Closure>();
mInputs = new ArrayList<UnboundValue>();
}
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param returnType Allocation type for the return value
+ * @param args arguments to the kernel function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+
public Closure addKernel(Script.KernelID k, Type returnType, Object[] args,
Map<Script.FieldID, Object> globalBindings) {
Closure c = new Closure(mRS, k, returnType, args, globalBindings);
@@ -381,6 +485,15 @@ public class ScriptGroup2 extends BaseObj {
return c;
}
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param args arguments to the invocable function
+ * @param globalBindings bindings for global variables
+ * @return a closure
+ */
+
public Closure addInvoke(Script.InvokeID invoke, Object[] args,
Map<Script.FieldID, Object> globalBindings) {
Closure c = new Closure(mRS, invoke, args, globalBindings);
@@ -388,12 +501,25 @@ public class ScriptGroup2 extends BaseObj {
return c;
}
+ /**
+ * Adds a script group input
+ *
+ * @return a unbound value that can be used to create a closure
+ */
public UnboundValue addInput() {
UnboundValue unbound = new UnboundValue();
mInputs.add(unbound);
return unbound;
}
+ /**
+ * Adds a closure for a kernel
+ *
+ * @param k Kernel ID for the kernel function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
ArrayList<Object> args = new ArrayList<Object>();
Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
@@ -403,6 +529,14 @@ public class ScriptGroup2 extends BaseObj {
return addKernel(k, returnType, args.toArray(), bindingMap);
}
+ /**
+ * Adds a closure for an invocable function
+ *
+ * @param invoke Invoke ID for the invocable function
+ * @param argsAndBindings arguments followed by bindings for global variables
+ * @return a closure
+ */
+
public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
ArrayList<Object> args = new ArrayList<Object>();
Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
@@ -412,6 +546,13 @@ public class ScriptGroup2 extends BaseObj {
return addInvoke(invoke, args.toArray(), bindingMap);
}
+ /**
+ * Creates a script group
+ *
+ * @param outputs futures intended as outputs of the script group
+ * @return a script group
+ */
+
public ScriptGroup2 create(Future... outputs) {
ScriptGroup2 ret = new ScriptGroup2(mRS, mClosures, mInputs, outputs);
return ret;
@@ -433,7 +574,7 @@ public class ScriptGroup2 extends BaseObj {
return false;
}
Binding b = (Binding)argsAndBindings[i];
- bindingMap.put(b.mField, b.mValue);
+ bindingMap.put(b.getField(), b.getValue());
}
return true;