RenderScript'ten veri taşıma

RenderScript API'leri Android 12'den itibaren kullanımdan kaldırılmıştır. Cihaz ve bileşen üreticileri, donanım hızlandırma desteği sunmayı zaten durdurmuştur ve RenderScript desteğinin gelecekteki bir sürümde tamamen kaldırılması beklenmektedir.

C/C++ performansı birçok kullanım durumu için yeterli olabilir ve yalnızca yerleşik öğeler için RenderScript'i kullandıysanız bu kullanımları, kullanımı daha kolay olan ve potansiyel 2 kat performans artışı sağlayabilecek RenderScript Intrinsics Replacement Toolkit ile değiştirebilirsiniz.

GPU hızlandırmadan tam olarak yararlanmanız gerekiyorsa komut dosyalarınızı Vulkan'a taşımanızı öneririz. Diğer hızlandırılmış seçenekler arasında komut dosyalarınızı OpenGL'ye taşımayı, Tuval tabanlı görüntü işlemlerini veya Android Grafik Gölgeleme Dili'ni (AGSL) kullanmayı içerir.

Android platformunda RenderScript'in kullanımdan kaldırılmasının ardından, Android Gradle eklentisinden de RenderScript desteği kaldırılıyor. RenderScript API'leri Android Gradle eklentisi 7.2'den itibaren kullanımdan kaldırılmıştır. Bunlar çalışmaya devam eder ancak uyarı çağırır. AGP'nin gelecekteki sürümlerinde artık Renderscript desteği olmayacaktır. Bu kılavuzda, RenderScript'ten nasıl geçiş yapılacağı açıklanmaktadır.

Yerleşik öğelerden geçiş yapın

RenderScript yerleşik işlevleri, RenderScript'in kullanımdan kaldırılmasından sonra da çalışmaya devam etse de GPU yerine yalnızca CPU'da yürütülebilir.

Bu işlemlerin bazıları için artık platforma veya Jetpack kitaplıklarına entegre edilen daha etkili seçenekler bulunmaktadır.

Yerleşik hızlandırılmış görüntü işlemleri

Android platformu, RenderScript yerleşik özelliklerinden bağımsız olarak resimlere uygulanabilen hızlandırılmış resim işleme işlemlerini destekler. Örnekler:

  • Karışık
  • Bulanıklaştırma
  • Renk Matrisi
  • Yeniden boyutlandır

Android 12 ve sonraki sürümlerde bir görünüme uygulanan resim bulanıklaştırma

Android 12 API düzeyi 31'e bulanıklaştırma destekli RenderEffect eklendi. Bu sayede RenderNode bulanıklaştırılabilir. RenderNode, Android'in platform grafiklerini hızlandırmak için kullandığı görüntüleme listesinin yapısıdır.

Android, View ile ilişkilendirilmiş RenderNode öğesine efekt uygulamak için kısayol sunar. View öğesini bulanıklaştırmak için View.setRenderEffect() numaralı telefonu arayın:

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

Android 12 ve sonraki sürümlerde bit eşlem olarak oluşturulan resim bulanıklaştırma

Bulanıklaştırılmış resmin Bitmap içinde oluşturulması gerekiyorsa çerçeve, HardwareBuffer destekli bir HardwareRenderer ile hızlandırılmış oluşturmayı destekler. Aşağıdaki kod bulanıklaştırma için HardwareRenderer, RenderNode ve RenderEffect oluşturur:

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)

Efektin uygulanması, RenderNode için dahili RecordingCanvas kullanımını içerir. Aşağıdaki kod çizimi kaydeder, oluşturma isteğini oluşturur ve ardından isteğin tamamlanmasını bekler:

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

Oluşturulan görüntü, ImageReader ile ilişkili HardwareBuffer içindedir. Aşağıdaki kod Image öğesini alır ve HardwareBuffer öğesini saran bir Bitmap döndürür.

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

Resim oluşturulduktan sonra aşağıdaki kod temizlenir. ImageReader, RenderNode, RenderEffect ve HardwareRenderer öğelerinin birden fazla resmi işlemek için kullanılabileceğini unutmayın.

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

Resim işleme için AGSL

Android Grafik Gölgeleme Dili (AGSL), Android 13 ve sonraki sürümler tarafından programlanabilir RuntimeShader nesnelerinin davranışını tanımlamak için kullanılır. AGSL, söz diziminin büyük bir kısmını GLSL parça gölgelendiricileriyle paylaşır ancak Android grafik oluşturma sistemi içinde hem Canvas içinde boyamayı özelleştirmek hem de View içeriğini filtrelemek için çalışır. Bu, çizim işlemleri sırasında özel resim işleme eklemek için veya bir resmi Bitmap tuvalinde oluşturmak için doğrudan RenderNode kullanılarak kullanılabilir. Aşağıdaki örnekte, resim bulanıklaştırma efektinin yerine özel bir gölgelendiricinin nasıl uygulanacağı gösterilmektedir.

AGSL gölgelendirici koduyla örneklendirmek için bir RuntimeShader oluşturarak başlayın. Bu gölgelendirici, ton rotasyonu için bir renk matrisi uygulamak üzere kullanılır:

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

Gölgelendirici, diğer RenderEffect öğeleri gibi bir RenderNode öğesine de uygulanabilir. Aşağıdaki örnekte, üniformaların hueShader'da nasıl ayarlanacağı gösterilmektedir:

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)

Bitmap elde etmek için önceki resim bulanıklaştırma örneğindeki teknikle aynı teknik kullanılır.

  • RenderNode için dahili RecordingCanvas gölgelendiriciyi uygular.
  • Image edinilir ve HardwareBuffer öğesini sarmalayan bir Bitmap döndürülür.

CameraX'i kullanarak düzlemsel YUV'den RGB'ye dönüştürme

Resim işlemede kullanım için düzlem YUV'den RGB'ye dönüştürme, Jetpack'in CameraX ürünündeki ImageAnalysis kullanım alanı kapsamında desteklenir.

ImageAnalysis KameraX'i Kullanmaya Başlama codelab'inin parçası olarak ve Android kamera samples deposunda ImageAnalysis kullanılmasıyla ilgili kaynaklar bulunmaktadır.

Renderscript yerleşik değiştirme araç seti

Uygulamanız iç yapıyı kullanıyorsa bağımsız değişim kitaplığını kullanabilirsiniz. Testlerimiz, mevcut RenderScript CPU uygulamasını kullanmaktan daha hızlı olduğunu göstermektedir.

Araç seti aşağıdaki işlevleri içerir:

  • Karışık
  • Bulanıklaştırma
  • Renk matrisi
  • Dönüştür
  • Histogram ve histogramNokta
  • Arama tablosu (LUT) ve LUT 3D
  • Yeniden boyutlandır
  • YUV - RGB

Tüm ayrıntılar ve sınırlamalar için araç setindeki README.md ve Toolkit.kt dokümanlarına bakın. dosyaları.

Kitaplığı indirmek, eklemek ve kullanmak için aşağıdaki adımları uygulayın:

  1. GitHub'dan projeyi indirin.

  2. renderscript-toolkit module öğesini bulun ve oluşturun.

  3. Uygulamanın build.gradle dosyasını değiştirerek kitaplığı Android Studio projenize ekleyin.

  4. Araç setinde uygun yöntemi çağırmak.

Örnek: ScriptIntrinsicBlur işlevinden taşıma

ScriptIntrinsicBlur işlevini değiştirmek için:

  • Bit eşlemi bulanıklaştırmak için Toolkit.blur çağrısı yapın.

    var blurredBitmap = Toolkit.blur(myBitmap, radius)
    
  • Bayt dizisiyle temsil edilen bir resmi bulanıklaştırmak istiyorsanız genişliği, yüksekliği ve piksel başına bayt sayısını belirtin.

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

Komut dosyalarından taşı

Kullanım alanınız aşağıdakilerle çözülemiyorsa:

Kullanım alanınız GPU hızlandırmasından yararlanabilir. Android, platformlar arası Vulkan ve OpenGL ES (GLES) API'lerinde GPU bilgi işlemesini destekler. Çoğu cihazda komut dosyalarınız zaten GPU yerine CPU'da çalıştığı için bunu gerekli olmayabilir: C/C++, bazı kullanım alanlarında RenderScript, GLES veya Vulkan bilgi işlemden daha hızlı olabilir. (veya en azından kullanım alanınıza uygun hızda)

Taşıma işleminin nasıl yapılacağını daha iyi anlamak için örnek uygulamayı inceleyin. Örnekte, RenderScript'te hem bit eşlemin nasıl bulanıklaştırılacağı hem de renk matrisi dönüşümünün nasıl yapılacağı gösterilmektedir. Vulkan ve OpenGL'de eşdeğer kod bulunmaktadır.

Uygulamanızın bir dizi sürümü desteklemesi gerekiyorsa Android 6 (API düzeyi 23) ve önceki sürümleri çalıştıran cihazlar için RenderScript'i, Android 7 (API düzeyi 24) ve sonraki sürümleri çalıştıran desteklenen cihazlarda Vulkan veya GLES'yi kullanın. minSdkVersion sürümünüz 24 veya üzeriyse RenderScript'i kullanmanız gerekmeyebilir. Vulkan veya GLES 3.1, GPU bilgi işlem desteğine ihtiyacınız olan her yerde kullanılabilir.

Android, GLES API'leri için SDK bağlamaları sağlar, bu nedenle OpenGL ES'de çalışırken NDK'nın kullanılması gerekmez.

Vulkan, SDK bağlamaları sağlamaz. Bu nedenle RenderScript'ten Vulkan'a doğrudan eşleme yapılmaz. Vulkan kodunu NDK'yı kullanarak yazar ve bu koda Kotlin veya Java'dan erişmek için JNI işlevleri oluşturursunuz.

Aşağıdaki sayfalarda RenderScript'ten taşıma işlemi konuları ele alınmaktadır. Örnek uygulama, bu noktaların neredeyse tümünü uygular. Bunları daha iyi anlamak için RenderScript ve Vulkan'daki eşdeğer kodları karşılaştırın.