am 1269ff96: Merge "Adds invocable functions to ScriptGroup"

* commit '1269ff961000c726247d510762e42b21562b8c2b':
  Adds invocable functions to ScriptGroup
This commit is contained in:
Yang Ni
2015-02-05 02:24:35 +00:00
committed by Android Git Automerger
5 changed files with 439 additions and 3 deletions

View File

@@ -241,8 +241,7 @@ public class FieldPacker {
addI64(0);
addI64(0);
addI64(0);
}
else {
} else {
addI32((int)obj.getID(null));
}
} else {
@@ -619,6 +618,289 @@ public class FieldPacker {
return mPos;
}
private static void addToPack(FieldPacker fp, Object obj) {
if (obj instanceof Boolean) {
fp.addBoolean(((Boolean)obj).booleanValue());
return;
}
if (obj instanceof Byte) {
fp.addI8(((Byte)obj).byteValue());
return;
}
if (obj instanceof Short) {
fp.addI16(((Short)obj).shortValue());
return;
}
if (obj instanceof Integer) {
fp.addI32(((Integer)obj).intValue());
return;
}
if (obj instanceof Long) {
fp.addI64(((Long)obj).longValue());
return;
}
if (obj instanceof Float) {
fp.addF32(((Float)obj).floatValue());
return;
}
if (obj instanceof Double) {
fp.addF64(((Double)obj).doubleValue());
return;
}
if (obj instanceof Byte2) {
fp.addI8((Byte2)obj);
return;
}
if (obj instanceof Byte3) {
fp.addI8((Byte3)obj);
return;
}
if (obj instanceof Byte4) {
fp.addI8((Byte4)obj);
return;
}
if (obj instanceof Short2) {
fp.addI16((Short2)obj);
return;
}
if (obj instanceof Short3) {
fp.addI16((Short3)obj);
return;
}
if (obj instanceof Short4) {
fp.addI16((Short4)obj);
return;
}
if (obj instanceof Int2) {
fp.addI32((Int2)obj);
return;
}
if (obj instanceof Int3) {
fp.addI32((Int3)obj);
return;
}
if (obj instanceof Int4) {
fp.addI32((Int4)obj);
return;
}
if (obj instanceof Long2) {
fp.addI64((Long2)obj);
return;
}
if (obj instanceof Long3) {
fp.addI64((Long3)obj);
return;
}
if (obj instanceof Long4) {
fp.addI64((Long4)obj);
return;
}
if (obj instanceof Float2) {
fp.addF32((Float2)obj);
return;
}
if (obj instanceof Float3) {
fp.addF32((Float3)obj);
return;
}
if (obj instanceof Float4) {
fp.addF32((Float4)obj);
return;
}
if (obj instanceof Double2) {
fp.addF64((Double2)obj);
return;
}
if (obj instanceof Double3) {
fp.addF64((Double3)obj);
return;
}
if (obj instanceof Double4) {
fp.addF64((Double4)obj);
return;
}
if (obj instanceof Matrix2f) {
fp.addMatrix((Matrix2f)obj);
return;
}
if (obj instanceof Matrix3f) {
fp.addMatrix((Matrix3f)obj);
return;
}
if (obj instanceof Matrix4f) {
fp.addMatrix((Matrix4f)obj);
return;
}
if (obj instanceof BaseObj) {
fp.addObj((BaseObj)obj);
return;
}
}
private static int getPackedSize(Object obj) {
if (obj instanceof Boolean) {
return 1;
}
if (obj instanceof Byte) {
return 1;
}
if (obj instanceof Short) {
return 2;
}
if (obj instanceof Integer) {
return 4;
}
if (obj instanceof Long) {
return 8;
}
if (obj instanceof Float) {
return 4;
}
if (obj instanceof Double) {
return 8;
}
if (obj instanceof Byte2) {
return 2;
}
if (obj instanceof Byte3) {
return 3;
}
if (obj instanceof Byte4) {
return 4;
}
if (obj instanceof Short2) {
return 4;
}
if (obj instanceof Short3) {
return 6;
}
if (obj instanceof Short4) {
return 8;
}
if (obj instanceof Int2) {
return 8;
}
if (obj instanceof Int3) {
return 12;
}
if (obj instanceof Int4) {
return 16;
}
if (obj instanceof Long2) {
return 16;
}
if (obj instanceof Long3) {
return 24;
}
if (obj instanceof Long4) {
return 32;
}
if (obj instanceof Float2) {
return 8;
}
if (obj instanceof Float3) {
return 12;
}
if (obj instanceof Float4) {
return 16;
}
if (obj instanceof Double2) {
return 16;
}
if (obj instanceof Double3) {
return 24;
}
if (obj instanceof Double4) {
return 32;
}
if (obj instanceof Matrix2f) {
return 16;
}
if (obj instanceof Matrix3f) {
return 36;
}
if (obj instanceof Matrix4f) {
return 64;
}
if (obj instanceof BaseObj) {
if (RenderScript.sPointerSize == 8) {
return 32;
} else {
return 4;
}
}
return 0;
}
static FieldPacker createFieldPack(Object[] args) {
int len = 0;
for (Object arg : args) {
len += getPackedSize(arg);
}
FieldPacker fp = new FieldPacker(len);
for (Object arg : args) {
addToPack(fp, arg);
}
return fp;
}
private final byte mData[];
private int mPos;
private int mLen;

View File

@@ -313,6 +313,15 @@ public class RenderScript {
sizes, depClosures, depFieldIDs);
}
native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
long[] fieldIDs, long[] values, int[] sizes);
synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
long[] fieldIDs, long[] values, int[] sizes) {
validate();
return rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
values, sizes);
}
native void rsnClosureSetArg(long con, long closureID, int index,
long value, int size);
synchronized void nClosureSetArg(long closureID, int index, long value,
@@ -745,6 +754,12 @@ public class RenderScript {
return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
}
native long rsnScriptInvokeIDCreate(long con, long sid, int slot);
synchronized long nScriptInvokeIDCreate(long sid, int slot) {
validate();
return rsnScriptInvokeIDCreate(mContext, sid, slot);
}
native long rsnScriptFieldIDCreate(long con, long sid, int slot);
synchronized long nScriptFieldIDCreate(long sid, int slot) {
validate();

View File

@@ -65,6 +65,46 @@ public class Script extends BaseObj {
return k;
}
/**
* @hide Pending API review
* InvokeID is an identifier for an invoke function. It is used
* as an identifier for ScriptGroup creation.
*
* This class should not be directly created. Instead use the method in the
* reflected or intrinsic code "getInvokeID_funcname()".
*
*/
public static final class InvokeID extends BaseObj {
Script mScript;
int mSlot;
InvokeID(long id, RenderScript rs, Script s, int slot) {
super(id, rs);
mScript = s;
mSlot = slot;
}
}
private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
/**
* @hide Pending API review
* Only to be used by generated reflected classes.
*/
protected InvokeID createInvokeID(int slot) {
InvokeID i = mIIDs.get(slot);
if (i != null) {
return i;
}
long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
if (id == 0) {
throw new RSDriverException("Failed to create KernelID");
}
i = new InvokeID(id, mRS, this, slot);
mIIDs.put(slot, i);
return i;
}
/**
* FieldID is an identifier for a Script + exported field pair. It is used
* as an identifier for ScriptGroup creation.

View File

@@ -34,6 +34,8 @@ public class ScriptGroup2 extends BaseObj {
private Future mReturnFuture;
private Map<Script.FieldID, Future> mGlobalFuture;
private FieldPacker mFP;
private static final String TAG = "Closure";
public Closure(long id, RenderScript rs) {
@@ -89,6 +91,44 @@ public class ScriptGroup2 extends BaseObj {
setID(id);
}
public Closure(RenderScript rs, Script.InvokeID invokeID,
Object[] args, Map<Script.FieldID, Object> globals) {
super(0, rs);
mFP = FieldPacker.createFieldPack(args);
mBindings = new HashMap<Script.FieldID, Object>();
mGlobalFuture = new HashMap<Script.FieldID, Future>();
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<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 {
// 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) {
@@ -99,6 +139,12 @@ public class ScriptGroup2 extends BaseObj {
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;
@@ -121,6 +167,10 @@ public class ScriptGroup2 extends BaseObj {
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);
}
@@ -160,7 +210,6 @@ public class ScriptGroup2 extends BaseObj {
size = 8;
}
}
public long value;
public int size;
}
@@ -297,6 +346,13 @@ public class ScriptGroup2 extends BaseObj {
return c;
}
public Closure addInvoke(Script.InvokeID invoke, Object[] args,
Map<Script.FieldID, Object> globalBindings) {
Closure c = new Closure(mRS, invoke, args, globalBindings);
mClosures.add(c);
return c;
}
public UnboundValue addInput() {
UnboundValue unbound = new UnboundValue();
mInputs.add(unbound);

View File

@@ -242,6 +242,37 @@ nClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong kernelID,
depFieldIDs, (size_t)depFieldIDs_length);
}
static jlong
nInvokeClosureCreate(JNIEnv *_env, jobject _this, jlong con, jlong invokeID,
jbyteArray paramArray, jlongArray fieldIDArray, jlongArray valueArray,
jintArray sizeArray) {
jbyte* jParams = _env->GetByteArrayElements(paramArray, nullptr);
jsize jParamLength = _env->GetArrayLength(paramArray);
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);
return (jlong)(uintptr_t)rsInvokeClosureCreate(
(RsContext)con, (RsScriptInvokeID)invokeID, jParams, jParamLength,
fieldIDs, (size_t)fieldIDs_length, values, (size_t)values_length,
(size_t*)sizes, (size_t)sizes_length);
}
static void
nClosureSetArg(JNIEnv *_env, jobject _this, jlong con, jlong closureID,
jint index, jlong value, jint size) {
@@ -1487,6 +1518,16 @@ nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint sl
return (jlong)(uintptr_t)rsScriptKernelIDCreate((RsContext)con, (RsScript)sid, slot, sig);
}
static jlong
nScriptInvokeIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
{
if (kLogApi) {
ALOGD("nScriptInvokeIDCreate, con(%p) script(%p), slot(%i), sig(%i)", (RsContext)con,
(void *)sid, slot);
}
return (jlong)(uintptr_t)rsScriptInvokeIDCreate((RsContext)con, (RsScript)sid, slot);
}
static jlong
nScriptFieldIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint slot)
{
@@ -1935,6 +1976,7 @@ static JNINativeMethod methods[] = {
{"rsnContextResume", "(J)V", (void*)nContextResume },
{"rsnContextSendMessage", "(JI[I)V", (void*)nContextSendMessage },
{"rsnClosureCreate", "(JJJ[J[J[I[J[J)J", (void*)nClosureCreate },
{"rsnInvokeClosureCreate", "(JJ[B[J[J[I)J", (void*)nInvokeClosureCreate },
{"rsnClosureSetArg", "(JJIJI)V", (void*)nClosureSetArg },
{"rsnClosureSetGlobal", "(JJJJI)V", (void*)nClosureSetGlobal },
{"rsnAssignName", "(JJ[B)V", (void*)nAssignName },
@@ -2009,6 +2051,7 @@ static JNINativeMethod methods[] = {
{"rsnScriptCCreate", "(JLjava/lang/String;Ljava/lang/String;[BI)J", (void*)nScriptCCreate },
{"rsnScriptIntrinsicCreate", "(JIJ)J", (void*)nScriptIntrinsicCreate },
{"rsnScriptKernelIDCreate", "(JJII)J", (void*)nScriptKernelIDCreate },
{"rsnScriptInvokeIDCreate", "(JJI)J", (void*)nScriptInvokeIDCreate },
{"rsnScriptFieldIDCreate", "(JJI)J", (void*)nScriptFieldIDCreate },
{"rsnScriptGroupCreate", "(J[J[J[J[J[J)J", (void*)nScriptGroupCreate },
{"rsnScriptGroup2Create", "(JLjava/lang/String;[J)J", (void*)nScriptGroup2Create },