Compilando el código render-script en tiempo de ejecución
Me preguntaba si es posible escribir / modificar el código de los renderscript cuando la aplicación androide se está ejecutando. Mi objetivo principal es hacer una aplicación donde los usuarios pueden aprender a trabajar con renderscript sin ningún conocimiento de java. El diseño básico de la aplicación consistiría en una imagen de entrada y salida, con la posibilidad de introducir código. La funcionalidad básica de esta aplicación ya está funcionando y esta es una imagen de la interfaz.
Sería útil para probar el código de renderscript con comentarios directos de la aplicación.
- Allocation.copyTo (Bitmap) que daña valores de píxeles
- Script de procesamiento de Android
- Cómo utilizar ScriptIntrinsic3DLUT con un archivo .cube?
- ¿Cómo obtener estadísticas de uso de la CPU en Android?
- No se puede ejecutar Renderscript HelloCompute ejemplo en Android GB 2.3.5
Ya he hecho la investigación sobre el proceso de construcción y se me ocurrió la siguiente idea:
Un fichero render-script básico de "plantilla", con las variables globales necesarias como las asignaciones de entrada y salida.
Mi código java crearía un objeto script de la clase java generada y haría la inicialización básica de estas variables globales de script. La función raíz de este archivo .rs de la plantilla estaría vacía, y debería ser posible implementarla por el usuario en tiempo de ejecución.
Cuando el usuario escribe su código en la vista principal de la aplicación, el código se escribe en mi propio archivo .rs que luego es compilado por el compilador llvm-rs-cc, invocado por la aplicación. El .bc generado se copiará entonces a la ubicación del archivo .bc original de la plantilla. Como el único cambio de código ocurre dentro de la función raíz, no sería necesario realizar cambios en el código java que lo rodea.
El problema que estoy teniendo en este momento es el hecho de que los archivos .bc están incluidos en el apk final dentro de la carpeta res / raw, que no es accesible por la aplicación. Por lo tanto, no es posible sobrescribir archivos .bc antiguos con los archivos recién generados.
¿Hay una (otra manera) para compilar el código de renderscript en tiempo de ejecución?
Editar: Solución se puede encontrar en este enlace github . Para más detalles, marque esta respuesta, lea el último comentario
- ¿Puede renderizarse Android en GPU?
- ¿Cómo detectar el dispositivo Android es de 64 bits o procesador de 32 bits?
- ¿Cómo intercambiar datos entre renderscript y android framework?
- RenderScript: El uso de ScriptGroup para el proceso de imagen causa rayas horizontales
- La biblioteca de soporte de RenderScript se bloquea en dispositivos x86
- Cómo pasar valores de matriz desde y hacia RenderScript de Android mediante Asignaciones
- 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
- Confiabilidad del contador del procesador
Tendrá que alterar la clase de pegamento generada ( ScriptC_mono
) y su base ( ScriptC
) como mínimo.
<ExtremeHax>
El archivo .bc
se lee y pasa a los internos de RenderScript. Por lo que puedo decir, que se hace dentro de ScriptC.internalCreate()
, que está cableado para leer un recurso sin ScriptC.internalCreate()
. Lo necesita para leer su archivo desde una ubicación que usted controla. Posiblemente solo necesitará modificar internalCreate()
pero probablemente habrá complicaciones que requieran una edición más amplia.
Una vez que implemente RuntimeScriptC
, debe modificar ScriptC_mono
para heredar de esa clase base en lugar de ScriptC
.
Como notaste, estarás muy limitado en los cambios que puedas hacer al código rs
ya que no puedes modificar la clase de pegamento en tiempo de ejecución. Por ejemplo, no se puede cambiar la firma de un kernel. Sin embargo, podría tomar este hack un poco más: si renuncia a la clase de pegamento, es posible hacer los cambios que desee.
Los kernels se invocan en la clase de pegamento por índice en lugar de por nombre, y los controles de tipo / elemento se realizan dentro de la clase de pegamento. Por lo tanto, incluso si cambiaste la firma del kernel, siempre y cuando supieras su índice y los tipos de sus asignaciones de entrada y salida, aún podrías invocarlo usando forEach()
directamente.
public class ScriptC_mono extends ScriptC { //... public void forEach_root(Allocation ain, Allocation aout) { // check ain if (!ain.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); } // check aout if (!aout.getType().getElement().isCompatible(__U8_4)) { throw new RSRuntimeException("Type mismatch with U8_4!"); // Verify dimensions Type tIn = ain.getType(); Type tOut = aout.getType(); if ((tIn.getCount() != tOut.getCount()) || (tIn.getX() != tOut.getX()) || (tIn.getY() != tOut.getY()) || (tIn.getZ() != tOut.getZ()) || (tIn.hasFaces() != tOut.hasFaces()) || (tIn.hasMipmaps() != tOut.hasMipmaps())) { throw new RSRuntimeException("Dimension mismatch between input and output parameters!"); } forEach(mExportForEachIdx_root, ain, aout, null); } }
</ExtremeHax>
- Cómo obtener la ruta del archivo utilizando el descriptor de archivo en Android?
- El brillo de una imagen sigue aumentando incluso al mover la barra de desplazamiento de Seekbar a la izquierda