Esegui la migrazione da RenderScript

Le API RenderScript saranno deprecate a partire da Android 12. Dispositivo e componente i produttori hanno già smesso di fornire supporto per l'accelerazione hardware, e il supporto di RenderScript sarà rimosso completamente in una versione futura.

le prestazioni C/C++ possono essere adeguate per molti casi d'uso e se solo fare affidamento su RenderScript per elementi intrinseci, puoi sostituirli con il RenderScript Intrinsics Sostituzione Toolkit, che è più semplice da usare e offre un potenziale miglioramento delle prestazioni di 2 volte.

Se hai bisogno di sfruttare appieno l'accelerazione GPU, ti consigliamo eseguire la migrazione degli script a Vulkan, Altre opzioni accelerate puoi eseguire la migrazione degli script a OpenGL, utilizzando le impostazioni basate su Canvas operazioni sulle immagini o l'utilizzo di Android Graphics Shading Lingua (AGSL).

A seguito del ritiro di RenderScript nella piattaforma Android, È in corso la rimozione di RenderScript dal plug-in Android Gradle. A partire da Plug-in Android per Gradle 7.2; API RenderScript deprecate. Loro continuano a funzionare, ma richiamano gli avvisi. Le versioni future di AGP non saranno più includono il supporto di Renderscript. Questa guida spiega come eseguire la migrazione da in RenderScript.

Esegui la migrazione dai componenti intrinseci

Sebbene le funzioni intrinseche di RenderScript continuino a funzionare dopo il il ritiro di RenderScript, possono essere eseguiti solo sulla CPU anziché GPU.

Per alcune di queste operazioni, ci sono opzioni più efficienti ora integrate nella piattaforma o nelle librerie Jetpack.

Operazioni sulle immagini accelerate integrate

La piattaforma Android supporta operazioni di elaborazione delle immagini accelerata, possono essere applicate alle immagini, indipendentemente dalle caratteristiche intrinseche di RenderScript. Ecco alcuni esempi:

  • Mix
  • Sfocatura
  • Matrice colore
  • Ridimensiona

Sfocatura immagine su Android 12 e versioni successive in una visualizzazione

In Android 12 è stato aggiunto RenderEffect con supporto per la sfocatura, Livello API 31, che consente di sfocare un elemento RenderNode. RenderNode è una struttura dell'elenco visualizzato che Android utilizza per accelerare la grafica della piattaforma.

Android fornisce una scorciatoia per applicare un effetto all'elemento RenderNode associato con un View. Per sfocare un View, chiama View.setRenderEffect():

val blurRenderEffect = RenderEffect.createBlurEffect(radius, radius,
        Shader.TileMode.MIRROR
    )
view.setRenderEffect(blurRenderEffect)

Sfocatura immagine su Android 12 e versioni successive visualizzata in una bitmap

Se hai bisogno di visualizzare l'immagine sfocata in un Bitmap, il framework supporta il rendering accelerato con HardwareRenderer supportata da HardwareBuffer. Il seguente codice crea HardwareRenderer, RenderNode e RenderEffect per la sfocatura:

val imageReader = ImageReader.newInstance(
    bitmap.width, bitmap.height,
    PixelFormat.RGBA_8888, numberOfOutputImages,
    HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT
)
val renderNode = RenderNode("BlurEffect")
val hardwareRenderer = HardwareRenderer()

hardwareRenderer.setSurface(imageReader.surface)
hardwareRenderer.setContentRoot(renderNode)
renderNode.setPosition(0, 0, imageReader.width, imageReader.height)
val blurRenderEffect = RenderEffect.createBlurEffect(
    radius, radius,
    Shader.TileMode.MIRROR
)
renderNode.setRenderEffect(blurRenderEffect)

L'applicazione dell'effetto comporta l'utilizzo della RecordingCanvas per RenderNode. Il seguente codice registra il disegno, crea la richiesta di rendering e attende il per completare la richiesta:

val renderCanvas = it.renderNode.beginRecording()
renderCanvas.drawBitmap(it.bitmap, 0f, 0f, null)
renderNode.endRecording()
hardwareRenderer.createRenderRequest()
    .setWaitForPresent(true)
    .syncAndDraw()

L'immagine visualizzata è in un elemento HardwareBuffer associato a ImageReader. Il seguente codice acquisisce i valori Image e restituisce un Bitmap che aggrega il relativo HardwareBuffer.

val image = imageReader.acquireNextImage() ?: throw RuntimeException("No Image")
val hardwareBuffer = image.hardwareBuffer ?: throw RuntimeException("No HardwareBuffer")
val bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, null)
    ?: throw RuntimeException("Create Bitmap Failed")

Il seguente codice viene pulito dopo il rendering dell'immagine. Tieni presente che È possibile utilizzare ImageReader, RenderNode, RenderEffect e HardwareRenderer per elaborare più immagini.

hardwareBuffer.close()
image.close()
imageReader.close()
renderNode.discardDisplayList()
hardwareRenderer.destroy()

AGSL per l'elaborazione delle immagini

Android Graphics Shading Language (AGSL) viene utilizzato da Android 13 e versioni successive per per definire il comportamento degli annunci RuntimeShader. AGSL condivide gran parte della sua sintassi con gli Shaper di frammenti GLSL, ma funziona all'interno Sistema di rendering grafico Android per personalizzare la pittura all'interno di Canvas e filtra i contenuti di View. Consente di aggiungere un'elaborazione delle immagini personalizzata durante le operazioni di disegno o utilizzando direttamente un RenderNode per eseguire il rendering in un canvas Bitmap. L'esempio seguente mostra come applicare shaker personalizzato per sostituire l'effetto di sfocatura dell'immagine.

Inizia creando un RuntimeShader, creando un'istanza con lo shaker AGSL le API nel tuo codice. Questo Shar viene utilizzato per applicare una matrice di colori per la rotazione delle tonalità:

val hueShader = RuntimeShader("""
    uniform float2 iResolution;       // Viewport resolution (pixels)
    uniform float2 iImageResolution;  // iImage1 resolution (pixels)
    uniform float iRadian;            // radian to rotate things around
    uniform shader iImage1;           // An input image
    half4 main(float2 fragCoord) {
    float cosR = cos(iRadian);
    float sinR = sin(iRadian);
        mat4 hueRotation =
        mat4 (
                0.299 + 0.701 * cosR + 0.168 * sinR, //0
                0.587 - 0.587 * cosR + 0.330 * sinR, //1
                0.114 - 0.114 * cosR - 0.497 * sinR, //2
                0.0,                                 //3
                0.299 - 0.299 * cosR - 0.328 * sinR, //4
                0.587 + 0.413 * cosR + 0.035 * sinR, //5
                0.114 - 0.114 * cosR + 0.292 * sinR, //6
                0.0,                                 //7
                0.299 - 0.300 * cosR + 1.25 * sinR,  //8
                0.587 - 0.588 * cosR - 1.05 * sinR,  //9
                0.114 + 0.886 * cosR - 0.203 * sinR, //10
                0.0,                                 //11
                0.0, 0.0, 0.0, 1.0 );                //12,13,14,15
        float2 scale = iImageResolution.xy / iResolution.xy;
        return iImage1.eval(fragCoord * scale)*hueRotation;
    }
""")

Lo Shar può essere applicato a un RenderNode, proprio come qualsiasi altro RenderEffect. L'esempio seguente mostra come impostare le uniformi in hueShader:

hueShader.setFloatUniform("iImageResolution", bitmap.width.toFloat(),
    bitmap.height.toFloat())
hueShader.setFloatUniform("iResolution", bitmap.width.toFloat(),
    bitmap.height.toFloat())
hueShader.setFloatUniform("iRadian", radian)
hueShader.setInputShader( "iImage1", BitmapShader(bitmap, Shader.TileMode.MIRROR,
    Shader.TileMode.MIRROR))
val colorFilterEffect = RenderEffect.createShaderEffect(it.hueShader)
renderNode.setRenderEffect(colorFilterEffect)

Per ottenere l'elemento Bitmap, viene utilizzata la stessa tecnica della sfocatura dell'immagine precedente campione.

  • L'interfaccia RecordingCanvas per RenderNode applica lo shaker.
  • L'entità Image viene acquisita, restituendo un Bitmap che aggrega il suo HardwareBuffer.

Convertire da YUV planare a RGB utilizzando CameraX

Conversione da YUV planare in corso... a RGB per l'utilizzo nell'elaborazione delle immagini è supportato Caso d'uso di ImageAnalysis all'interno di Jetpack FotocameraX.

Sono disponibili risorse sull'utilizzo di ImageAnalysis nell'ambito Codelab su Introduzione a CameraX la fotocamera Android nel repository samples.

Il toolkit di sostituzione di Renderscript Intrinsics

Se la tua applicazione utilizza componenti intrinseci, puoi usare la versione autonoma biblioteca; i nostri test indicano che è più veloce rispetto all'utilizzo della CPU RenderScript esistente implementazione.

Il toolkit include le seguenti funzioni:

  • Mix
  • Sfocatura
  • Matrice colore
  • Convolve
  • Istogramma e istogrammaDot
  • Tabella di ricerca (LUT) e LUT 3D
  • Ridimensiona
  • Da YUV a RGB

Per tutti i dettagli e le limitazioni, consulta le sezioni README.md e Toolkit.kt del toolkit. di copertina.

Per scaricare, aggiungere e utilizzare la libreria, procedi nel seguente modo:

  1. Scarica il progetto. da GitHub.

  2. Individua e crea renderscript-toolkit module.

  3. Aggiungi la libreria al progetto Android Studio modificando lo spazio dei nomi dell'app build.gradle.

  4. Richiama il metodo appropriato del toolkit.

Esempio: eseguire la migrazione dalla funzione ScriptIntrinsicBlur

Per sostituire la funzione ScriptIntrinsicBlur:

  • Per sfocare una bitmap, chiama Toolkit.blur.

    var blurredBitmap = Toolkit.blur(myBitmap, radius)
    
  • Se vuoi sfocare un'immagine rappresentata da un array di byte, specifica la la larghezza, l'altezza e il numero di byte per pixel.

    val outArray = Toolkit.blur(inputArray, bytesPerPixel, width, height, radius)
    
di Gemini Advanced.

Esegui la migrazione dagli script

Se il tuo caso d'uso non può essere risolto con:

Inoltre, per il tuo caso d'uso può trarre vantaggio dall'accelerazione GPU, Android supporta GPU di computing su API multipiattaforma Vulkan e OpenGL ES (GLES). Potresti trovare questo inutili perché sulla maggior parte dei dispositivi i tuoi script sono già in esecuzione sulla CPU anziché la GPU: C/C++ potrebbe essere più veloce di RenderScript, GLES o Vulkan il computing per alcuni casi d'uso. (o almeno abbastanza velocemente per il tuo caso d'uso)

Per comprendere meglio come eseguire la migrazione, esamina il app di esempio. La esempio mostra come sfocare una bitmap ed eseguire una conversione della matrice colori in RenderScript e ha un codice equivalente in Vulkan e OpenGL.

Se la tua applicazione deve supportare una serie di release, utilizza RenderScript per dispositivi con Android 6 (livello API 23) e versioni precedenti e Vulkan o GLES su dispositivi supportati con Android 7 (livello API 24) e versioni successive. Se le tue minSdkVersion è 24 o superiore, potrebbe non essere necessario utilizzare RenderScript. Vulkan o GLES 3.1 può essere utilizzato ovunque sia necessario il supporto di calcolo GPU.

Android fornisce associazioni di SDK per le API GLES, quindi non è necessario utilizzare NDK quando si lavora in OpenGL ES.

Vulkan non fornisce associazioni di SDK, quindi non esiste una mappatura diretta da RenderScript in Vulkan; scrivi il codice Vulkan utilizzando NDK e crei JNI per accedere a questo codice da Kotlin o Java.

Le pagine seguenti trattano alcuni aspetti della migrazione da RenderScript. L'esempio nell'app implementa quasi tutte queste considerazioni. Per comprenderli meglio, con il codice equivalente di RenderScript e Vulkan.