Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1269ff96 authored by Yang Ni's avatar Yang Ni Committed by Gerrit Code Review
Browse files

Merge "Adds invocable functions to ScriptGroup"

parents 21702263 be392ad3
Loading
Loading
Loading
Loading
+284 −2
Original line number Diff line number Diff line
@@ -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;
+15 −0
Original line number Diff line number Diff line
@@ -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();
+40 −0
Original line number Diff line number Diff line
@@ -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.
+57 −1
Original line number Diff line number Diff line
@@ -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);
+43 −0
Original line number Diff line number Diff line
@@ -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 },