Von RenderScript migrieren

RenderScript APIs werden ab Android 12 eingestellt. Gerät und Komponente bieten Hersteller Unterstützung für die Hardwarebeschleunigung, und RenderScript wird in einer zukünftigen Version voraussichtlich vollständig entfernt.

Die C/C++-Leistung kann für viele Anwendungsfälle geeignet sein. Wenn Sie nur RenderScript für intrinsische Elemente ist, können Sie diese Verwendungszwecke RenderScript Intrinsics Replacement Toolkit. und kann die Leistung verdoppeln.

Wenn Sie die GPU-Beschleunigung optimal nutzen möchten, empfehlen wir Migration deiner Skripts zu Vulkan, andere beschleunigte Optionen beinhalten die Migration Ihrer Skripts zu OpenGL mithilfe von Canvas-basierten Bildoperationen oder die Grafik-Shading-Funktion von Android Sprache (AGSL).

Nach der Einstellung von RenderScript auf der Android-Plattform wird die Unterstützung für RenderScript wird aus dem Android-Gradle-Plug-in entfernt. Beginnend mit Android-Gradle-Plug-in 7.2, die RenderScript APIs wurden eingestellt. Sie funktionieren weiterhin, aber rufen Warnungen auf. Künftige Versionen von AGP werden nicht mehr Renderscript-Unterstützung. In diesem Leitfaden wird erläutert, wie Sie von RenderScript sein.

Von intrinsischen Daten migrieren

Obwohl die intrinsischen RenderScript-Funktionen auch nach der RenderScript wird eingestellt. Sie werden möglicherweise nur auf der CPU ausgeführt, nicht auf der GPU

Für einige dieser Vorgänge gibt es effizientere Optionen oder in Jetpack-Bibliotheken.

Integrierte beschleunigte Image-Vorgänge

Die Android-Plattform unterstützt beschleunigte Bildverarbeitung, wird unabhängig von den RenderScript-Intrinsiken auf Bilder angewendet. Hier einige Beispiele:

  • Mischen
  • Unkenntlich machen
  • Farbmatrix
  • Größe ändern

Weichzeichnen von Bildern unter Android 12 und höher in einer Ansicht

RenderEffect mit Unterstützung für Unkenntlichmachungen wurde in Android 12 eingeführt. API-Level 31, mit dem ein RenderNode unkenntlich gemacht werden kann. RenderNode ist ein Konstrukt der Anzeigeliste, mit der Android Plattformgrafiken.

In Android gibt es eine Tastenkombination, mit der du einen Effekt auf das verknüpfte RenderNode anwenden kannst mit View. Um ein View unkenntlich zu machen, rufen Sie View.setRenderEffect():

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

In eine Bitmap gerenderte Bildverpixelung unter Android 12 und höher

Wenn Sie möchten, dass das unkenntlich gemachte Bild in einem Bitmap gerendert wird, kann das Framework unterstützt beschleunigtes Rendering mit einem HardwareRenderer durch HardwareBuffer gestützt. Der folgende Code erstellt HardwareRenderer, RenderNode und RenderEffect für die Unkenntlichmachung:

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)

Um den Effekt anzuwenden, RecordingCanvas für RenderNode. Der folgende Code zeichnet die Zeichnung auf, erstellt die Rendering-Anfrage und wartet Anfrage zum Abschluss:

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

Das gerenderte Bild befindet sich in einem HardwareBuffer, das zu den ImageReader. Mit dem folgenden Code werden Image und gibt ein Bitmap zurück, das die HardwareBuffer umschließt.

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")

Der folgende Code wird nach dem Rendern des Bildes bereinigt. Das Feld ImageReader, RenderNode, RenderEffect und HardwareRenderer können verwendet werden mehrere Bilder zu verarbeiten.

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

AGSL für die Bildverarbeitung

Die Android Graphics Shading Language (AGSL) wird ab Android 13 verwendet, um definieren Sie das Verhalten programmierbarer RuntimeShader-Objekten Logo: AGSL hat einen Großteil seiner Syntax mit GLSL-Fragment-Shadern, funktioniert aber Grafik-Rendering-System von Android zur Anpassung des Paintings innerhalb von Canvas und filtern Sie View-Inhalte. Damit kann eine benutzerdefinierte Bildverarbeitung hinzugefügt werden. während eines Zeichenvorgangs oder die direkte Verwendung von RenderNode zum Rendern eines in einen Bitmap-Canvas importieren. Das folgende Beispiel zeigt, wie ein benutzerdefinierten Shader als Ersatz für den Weichzeichnereffekt.

Erstellen Sie zuerst einen RuntimeShader und instanziieren Sie ihn mit dem AGSL-Shader Code. Dieser Shader wird verwendet, um eine Farbmatrix für die Farbtonrotation anzuwenden:

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;
    }
""")

Der Shader kann wie jeder andere RenderEffect auf einen RenderNode angewendet werden. Das folgende Beispiel zeigt, wie die Uniformen im Farbton festgelegt werden:

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)

Für das Bitmap wird dieselbe Technik wie beim Weichzeichnen des vorherigen Bildes verwendet Stichprobe.

  • Das interne RecordingCanvas für RenderNode wendet den Shader an.
  • Die Image wird übernommen und gibt ein Bitmap zurück, das ihre HardwareBuffer

Planares YUV in RGB mit CameraX konvertieren

Von planarer YUV konvertieren in RGB für die Bildverarbeitung als Teil des Anwendungsfall ImageAnalysis im Jetpack- CameraX

Es gibt Ressourcen zur Verwendung von ImageAnalysis als Teil des Codelab Getting Started with CameraX und in die Android-Kamera Beispiel-Repository.

Intrinsisches RenderScript-Toolkit

Wenn Ihre Anwendung intrinsische Methoden verwendet, können Sie den eigenständigen Ersatz verwenden. Bibliothek; Unsere Tests zeigen, dass es schneller ist als die vorhandene RenderScript-CPU. Implementierung.

Das Toolkit umfasst die folgenden Funktionen:

  • Mischen
  • Unkenntlich machen
  • Farbmatrix
  • Falten
  • Histogramm und histogramDot
  • Suchtabelle (LUT) und LUT 3D
  • Größe ändern
  • YUV zu RGB

Weitere Informationen und Einschränkungen finden Sie in den README.md und Toolkit.kt des Toolkits. -Dateien.

Führen Sie die folgenden Schritte aus, um die Bibliothek herunterzuladen, hinzuzufügen und zu verwenden:

  1. Laden Sie das Projekt herunter. von GitHub.

  2. Suchen und erstellen Sie die renderscript-toolkit module.

  3. Fügen Sie die Bibliothek Ihrem Android Studio-Projekt hinzu, indem Sie die Änderungen an der build.gradle-Datei.

  4. Rufen Sie die entsprechende Methode des Toolkits auf.

Beispiel: Migration von der Funktion ScriptIntrinsicBlur

So ersetzen Sie die Funktion ScriptIntrinsicBlur:

  • Rufe Toolkit.blur auf, um eine Bitmap unkenntlich zu machen.

    var blurredBitmap = Toolkit.blur(myBitmap, radius)
    
  • Wenn Sie ein Bild unkenntlich machen möchten, das durch ein Array von Byte dargestellt wird, geben Sie Breite, Höhe und die Anzahl der Byte pro Pixel.

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

Von Skripts migrieren

Wenn Ihr Anwendungsfall nicht gelöst werden kann:

Ihr Anwendungsfall kann von der GPU-Beschleunigung profitieren, da Android GPU unterstützt. mit plattformübergreifenden Vulkan- und OpenGL ES-APIs (GLES) berechnen. Hier findest du: unnötig, da die Skripts auf den meisten Geräten bereits auf der CPU ausgeführt werden. anstelle der GPU: C/C++ ist möglicherweise schneller als RenderScript, GLES oder Vulkan für einige Anwendungsfälle. (oder zumindest schnell genug für Ihren Anwendungsfall)

Weitere Informationen zur Migration finden Sie in der Beispiel-App. Die Das Beispiel zeigt, wie eine Bitmap unkenntlich gemacht und eine Farbmatrixkonvertierung durchgeführt wird. in RenderScript und gleichwertiger Code in Vulkan und OpenGL.

Wenn Ihre Anwendung eine Reihe von Versionen unterstützen muss, verwenden Sie RenderScript für Geräte mit Android 6 (API-Level 23) und niedriger sowie Vulkan oder GLES unterstützten Geräten mit Android 7 (API-Level 24) und höher. Wenn Ihr minSdkVersion mindestens 24 ist, musst du RenderScript möglicherweise nicht verwenden. Vulkan oder GLES 3.1 kann überall dort verwendet werden, wo Sie GPU-Computing-Unterstützung benötigen.

Android bietet SDK-Bindungen für GLES APIs, daher ist die Verwendung des NDK bei der Arbeit in OpenGL ES verwenden.

Vulkan bietet keine SDK-Bindungen, sodass keine direkte Zuordnung von RenderScript in Vulkan schreibst du den Vulkan-Code mit dem NDK und erstellst ein JNI um von Kotlin oder Java aus auf diesen Code zuzugreifen.

Auf den folgenden Seiten werden Aspekte der Migration von RenderScript behandelt. Das Beispiel fast alle diese Aspekte berücksichtigt. Um sie besser zu verstehen, den entsprechenden RenderScript- und Vulkan-Code vergleichen.