Cómo pasar valores de matriz desde y hacia RenderScript de Android mediante Asignaciones

He estado trabajando con RenderScript recientemente con la intención de crear una API que un programador puede usar con facilidad, similar a la forma en que funciona Microsoft Accelerator.

El problema que estoy atrapado en el momento en que quiero pasar valores a y desde la capa RenderScript y tener todo ejecutado de la manera más eficiente posible, este es un extracto de mi código fuente hasta el momento:

int[] A = new int[10]; int[] B = new int[10]; for (int i = 0; i < 10; i++) { A[i] = 2; B[i] = i; } intAdd(A, B); 

Esto sólo crea dos arrays básicos y los llena de valores y llama a las funciones que los enviarán a RenderScript.

  private void intAdd(int[] A, int[] B) { RenderScript rs = RenderScript.create(this); ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); mScript = intaddscript; for(int i = 0; i < A.length; i++) { setNewValues(mScript, A[i], B[i]); intaddscript.invoke_intAdd(); int C = getResult(mScript); notifyUser.append(" " + C); } } public void setNewValues(Script script, int A, int B) { mScript.set_numberA(A); mScript.set_numberB(B); } public int getResult(Script script) { int C = mScript.get_numberC(); return C; } 

Esto enviará un par de valores al siguiente código RenderScript:

 int numberA; int numberB; int numberC; void intAdd() { /*Add the two together*/ numberC = numberA + numberB; /*Send their values to the logcat*/ rsDebug("Current Value", numberC); } 

Pero hay dos problemas con esto, el primero es la naturaleza asíncrona de RenderScript significa que cuando la capa Java solicita el valor, el script no ha hecho la operación todavía, o ya lo ha hecho, destruido el valor de la salida Y comenzó en el siguiente. Y gracias a la baja visibilidad de depuración de RenderScript no hay forma de decirlo.

El otro problema es que no es muy eficiente, el código está constantemente llamando a la función RenderScript para agregar dos números juntos. Idealmente, me gustaría pasar la matriz a RenderScript y almacenar en una estructura y tener toda la operación realizada en una llamada de script en lugar de muchos. Pero para recuperarlo, creo que necesitaré usar la función rsSendtoClient, pero no he encontrado ningún material sobre cómo usarlo. Y preferiblemente me gustaría usar la estrategia rsForEach, pero de nuevo la información es un susto.

Si alguien tiene alguna idea, estaría muy agradecido. Gracias.

¿Scott-Jackson

No estoy seguro de si esto será de ayuda para usted en este momento, pero ya sé cuánto de un dolor puede ser trabajar a través de RenderScript, aquí está la ayuda que puedo ofrecer. Para utilizar la función rsSendToClient, debe instruir la instancia de RenderScript que creó a dónde enviar mensajes. Esto se logra por algo como:

 private void intAdd(int[] A, int[] B) { RenderScript rs = RenderScript.create(this); MySubclassedRSMessageHandler handler = new MySubclassedRSMessageHandler(); rs.setMessageHandler(handler); ScriptC_rsintadd intaddscript = new ScriptC_rsintadd(rs, getResources(), R.raw.rsintadd); mScript = intaddscript; for(int i = 0; i < A.length; i++) { setNewValues(mScript, A[i], B[i]); intaddscript.invoke_intAdd(); int C = getResult(mScript); notifyUser.append(" " + C); } } 

Será necesario subclasificar RenderScript.RSMessageHandler y anular el método run (). Vea http://developer.android.com/reference/android/renderscript/RenderScript.RSMessageHandler.html si usted havn't ya. Básicamente, no hay forma de evitar la naturaleza asincrónica que considero una espada de doble filo.

En cuanto a la ineficiencia, consideraría la creación de una instancia de RenderScript, lo dejaría en ejecución (se puede pausar cuando no es necesario, se quedará en la memoria, pero detener los hilos, por lo tanto no incurrir en el costo de construcción cada vez que llame a una función). Desde aquí puedes tener tus estructuras y luego usar invoke_myFunction (algunos argumentos aquí) de la capa Java reflejada.

Espero que esto ayude al menos un poco.

Yo tuve el mismo problema. El problema con su programa es que no sabe cuándo debe funcionar la función add en rs, pruebe esto debería funcionar

 public void setNewValues(Script script, int A, int B) { mScript.set_numberA(A); mScript.set_numberB(B); mscript.invoke_intAdd(); } 

Tuve el mismo problema contigo. Creo que la función rsSendtoClient no es útil y crea muchos errores. En su lugar, utilizando un puntero y asignar una memoria para traer resultados a usted es mucho más fácil.

Recomiendo la solución de su problema como este:

En rsintadd.rs utiliza este fragmento:

 int32_t *a; int32_t *b; int32_t *c; void intAdd() { for(int i = 0; i<10;i++){ c[i] = a[i] + b[i]; } 

En su código JAVA use este fragmento:

  int[] B = new int[10]; int[] A = new int[10]; for (int i = 0; i < 10; i++) { A[i] = 2; B[i] = 1; } // provide memory for b using data in B Allocation b = Allocation.createSized(rs, Element.I32(rs), B.length); b.copyFrom(B); inv.bind_b(b); // provide memory for a using data in A Allocation a = Allocation.createSized(rs, Element.I32(rs), A.length); a.copyFrom(A); inv.bind_a(a); // create blank memory for c inv.bind_c(Allocation.createSized(rs, Element.I32(rs), 10)); // call intAdd function inv.invoke_intAdd(); // get result int[] C = new int[10]; inv.get_c().copyTo(C); for (int i = 0; i < C.length; i++) { System.out.println(C[i]); } 

Y este es su resultado en Logcat:

Resultado de C

Su primera pregunta es sobre Asíncrono, puede utilizar el hilo para esperar resultado. En este ejemplo, la función es lo suficientemente rápida y da instantáneamente la salida a la matriz C para que el resultado pueda mostrarse en logcat.

Su segunda pregunta es acerca de implementar la función intAdd () sin recordarla. El código de arriba es la respuesta. Puede acceder a cualquier parte de int array en Java hasta que se complete el método (diferente de la función root ()).

Espero que esto pueda ayudar a alguien 🙂

  • ¿Por qué no funciona rsDebug?
  • ¿Cómo obtener estadísticas de uso de la CPU en Android?
  • Encuentra la velocidad del procesador de un dispositivo Android en MHz
  • Cómo utilizar ScriptIntrinsicYuvToRGB (convertir byte yuv a byte rgba)
  • Uso de OpenGL para reemplazar Canvas - Android
  • La adición de Renderscript en el estudio de Android 1.0.1 con API @ 21 y SDKTools @ 21.1.2 causa errores de compilación
  • ¿Cómo detectar el dispositivo Android es de 64 bits o procesador de 32 bits?
  • ¿Cómo intercambiar datos entre renderscript y android framework?
  • Rotar un mapa de bits utilizando script android
  • ApplicationStatus clase E / SysUtils: ApplicationContext es null en ApplicationStatus
  • RenderScript Bound Pointers vs. Asignaciones
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.