am 1269ff96: Merge "Adds invocable functions to ScriptGroup"
* commit '1269ff961000c726247d510762e42b21562b8c2b': Adds invocable functions to ScriptGroup
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user