diff options
author | Yang Ni <yangni@google.com> | 2015-02-05 01:05:08 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-02-05 01:05:08 +0000 |
commit | 1269ff961000c726247d510762e42b21562b8c2b (patch) | |
tree | a23dc006bc3d3e7b098ae46115a8041922762a63 /rs | |
parent | 21702263d96341bc13420e2c74af9a4bec6c7907 (diff) | |
parent | be392ad35e29b17ed54fdbbbb8dd3e80fc1022b9 (diff) | |
download | frameworks_base-1269ff961000c726247d510762e42b21562b8c2b.zip frameworks_base-1269ff961000c726247d510762e42b21562b8c2b.tar.gz frameworks_base-1269ff961000c726247d510762e42b21562b8c2b.tar.bz2 |
Merge "Adds invocable functions to ScriptGroup"
Diffstat (limited to 'rs')
-rw-r--r-- | rs/java/android/renderscript/FieldPacker.java | 286 | ||||
-rw-r--r-- | rs/java/android/renderscript/RenderScript.java | 15 | ||||
-rw-r--r-- | rs/java/android/renderscript/Script.java | 40 | ||||
-rw-r--r-- | rs/java/android/renderscript/ScriptGroup2.java | 58 | ||||
-rw-r--r-- | rs/jni/android_renderscript_RenderScript.cpp | 43 |
5 files changed, 439 insertions, 3 deletions
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java index 20b07e7..0f967fc 100644 --- a/rs/java/android/renderscript/FieldPacker.java +++ b/rs/java/android/renderscript/FieldPacker.java @@ -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; diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index f37519e..94aa857 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -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(); diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java index eb1687a..d352130 100644 --- a/rs/java/android/renderscript/Script.java +++ b/rs/java/android/renderscript/Script.java @@ -66,6 +66,46 @@ public class Script extends BaseObj { } /** + * @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. * diff --git a/rs/java/android/renderscript/ScriptGroup2.java b/rs/java/android/renderscript/ScriptGroup2.java index 366039e..113b896 100644 --- a/rs/java/android/renderscript/ScriptGroup2.java +++ b/rs/java/android/renderscript/ScriptGroup2.java @@ -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); diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp index cbcba39..7387af0 100644 --- a/rs/jni/android_renderscript_RenderScript.cpp +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -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) { @@ -1488,6 +1519,16 @@ nScriptKernelIDCreate(JNIEnv *_env, jobject _this, jlong con, jlong sid, jint sl } 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) { if (kLogApi) { @@ -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 }, |