RenderScript

RenderScript, Android'de yoğun hesaplama gerektiren görevleri yüksek performansla çalıştırmak için kullanılan bir çerçevedir. Seri iş yükleri de yararlanabilse de bu API, veri paralel hesaplama ile kullanılmak üzere tasarlanmıştır. RenderScript çalışma zamanı, bir cihazda bulunan işlemciler (ör. çok çekirdekli CPU'lar ve GPU'lar) arasında işi paralel hale getirir. Böylece geliştiriciler, iş planlamak yerine algoritmaları ifade etmeye odaklanabilir. RenderScript, özellikle görüntü işleme, hesaplamalı fotoğrafçılık veya bilgisayarla görme işlemleri yapan uygulamalar için yararlıdır.

Android 8.0 ve sonraki sürümlerin yüklü olduğu cihazlarda aşağıdaki RenderScript çerçevesi ve satıcı HAL'leri kullanılır:

Şekil 1. Dahili kitaplıklara bağlanan tedarikçi kodu.

Android 7.x ve önceki sürümlerdeki RenderScript'ten farklılıklar:

  • Bir süreçte iki RenderScript dahili kitaplığı örneği. Bir grup, CPU yedek yolu içindir ve doğrudan /system/lib konumundadır. Diğer grup ise GPU yolu içindir ve /system/lib/vndk-sp konumundadır.
  • /system/lib içindeki RS dahili kitaplıkları, platformun bir parçası olarak oluşturulur ve system.img yükseltildikçe güncellenir. Ancak /system/lib/vndk-sp içindeki kitaplıklar satıcı için oluşturulur ve system.img yükseltildiğinde güncellenmez (güvenlik düzeltmesi için güncellenebilir ancak ABI'leri aynı kalır).
  • Tedarikçi kodu (RS HAL, RS sürücüsü ve bcc plugin), /system/lib/vndk-sp konumundaki RenderScript dahili kitaplıklarına bağlanır. Bu dizindeki kitaplıklar /system/lib platformu için oluşturulduğundan ve bu nedenle satıcı koduyla uyumlu olmayabileceğinden (ör. semboller kaldırılabilir) bu dizindeki kitaplıklarla bağlantı oluşturulamaz. Aksi takdirde, yalnızca çerçeve içeren OTA mümkün olmaz.

Tasarım

Aşağıdaki bölümlerde, Android 8.0 ve sonraki sürümlerdeki RenderScript tasarımı ayrıntılı olarak açıklanmaktadır.

RenderScript kitaplıkları satıcılar tarafından kullanılabilir

Bu bölümde, satıcı kodunda kullanılabilen ve bağlantı oluşturulabilen RenderScript kitaplıkları (Vendor NDK for Same-Process HALs veya VNDK-SP olarak bilinir) listelenmektedir. Ayrıca, RenderScript ile ilgili olmayan ancak satıcı koduna da sağlanan ek kitaplıklar hakkında ayrıntılı bilgi verir.

Aşağıdaki kitaplık listesi Android sürümleri arasında farklılık gösterebilir ancak belirli bir Android sürümü için değişmezdir. Kullanılabilir kitaplıkların güncel listesi için /system/etc/ld.config.txt bölümüne bakın.

RenderScript Libs Non-RenderScript Libs
  • android.hardware.graphics.renderscript@1.0.so
  • libRS_internal.so
  • libRSCpuRef.so
  • libblas.so
  • libbcinfo.so
  • libcompiler_rt.so
  • libRSDriver.so
  • libc.so
  • libm.so
  • libdl.so
  • libstdc++.so
  • liblog.so
  • libnativewindow.so
  • libsync.so
  • libvndksupport.so
  • libbase.so
  • libc++.so
  • libcutils.so
  • libutils.so
  • libhardware.so
  • libhidlbase.so
  • libhidltransport.so
  • libhwbinder.so
  • liblzma.so
  • libz.so
  • libEGL.so
  • libGLESv1_CM.so
  • libGLESv2.so

Bağlayıcı ad alanı yapılandırması

VNDK-SP'de bulunmayan kitaplıkların satıcı kodu tarafından kullanılmasını engelleyen bağlantı kısıtlaması, bağlayıcı ad alanı kullanılarak çalışma zamanında uygulanır. (Ayrıntılar için VNDK Tasarımı sunumuna bakın.)

Android 8.0 ve sonraki sürümleri çalıştıran bir cihazda, RenderScript hariç tüm Aynı İşlem HAL'leri (SP-HAL'ler) bağlayıcı ad alanına sphal yüklenir. RenderScript, RenderScript'e özel ad alanına rs yüklenir. Bu konum, RenderScript kitaplıkları için biraz daha esnek bir zorunluluk sağlar. RS uygulamasının derlenmiş bit kodunu yüklemesi gerektiğinden /data/*/*.so, rs ad alanının yoluna eklenir (diğer SP-HAL'lerin veri bölümünden kitaplık yüklemesine izin verilmez).

Ayrıca, rs ad alanı, diğer ad alanlarının sağladığından daha fazla kitaplığa izin verir. libmediandk.so ve libft2.so, libRS_internal.so bu kitaplıklara dahili olarak bağımlı olduğu için rs ad alanına sunulur.

Şekil 2. Bağlayıcı için ad alanı yapılandırması.

Yük sürücüleri

CPU yedek yolu

Bir RS bağlamı oluşturulurken RS_CONTEXT_LOW_LATENCY bitinin varlığına bağlı olarak CPU veya GPU yolu seçilir. CPU yolu seçildiğinde, libRS_internal.so (RS çerçevesinin ana uygulaması) doğrudan dlopened from the default linker namespace where the platform version of RS libs are provided.

CPU yedek yolu kullanıldığında satıcının RS HAL uygulaması hiç kullanılmaz ve boş mVendorDriverName ile bir RsContext nesnesi oluşturulur. Arayan (libRS_internal.so) da default ad alanına yüklendiğinden libRSDriver.so, (varsayılan olarak) dlopen olarak ayarlanır ve sürücü kitaplığı default ad alanından yüklenir.

Şekil 3. CPU yedek yolu.

GPU yolu

GPU yolunda libRS_internal.so farklı şekilde yüklenir. İlk olarak, libRS.so, android.hardware.renderscript@1.0.so (ve temelindeki libhidltransport.so) kullanarak android.hardware.renderscript@1.0-impl.so'ü (RS HAL'nin bir satıcı uygulaması) sphal adlı farklı bir bağlayıcı ad alanına yükler. RS HAL, daha sonra dlopen, libRS_internal.so adlı başka bir bağlayıcı ad alanında rs.

Tedarikçiler, RS HAL uygulamasında yerleşik olan derleme süresi işaretini OVERRIDE_RS_DRIVER ayarlayarak kendi RS sürücülerini sağlayabilir (hardware/interfaces/renderscript/1.0/default/Context.cpp). Bu sürücü adı daha sonra GPU yolu için RS bağlamında dlopen edilir.

RsContext nesnesinin oluşturulması, RS HAL uygulamasına devredilir. HAL, bağımsız değişken olarak kullanılacak sürücünün adıyla rsContextCreateVendor() işlevini kullanarak RS çerçevesini geri çağırır. Ardından RS çerçevesi, RsContext başlatıldığında belirtilen sürücüyü yükler. Bu durumda, rs nesnesi rs ad alanı içinde oluşturulduğu ve /vendor/lib ad alanının arama yolunda olduğu için sürücü kitaplığı rs ad alanına yüklenir.RsContext

Şekil 4. GPU yedek yolu.

default ad alanından sphal ad alanına geçiş yapılırken libhidltransport.so, dinamik bağlayıcıya -impl.so kitaplığını sphal ad alanından yüklemesi için açıkça talimat vermek üzere android_load_sphal_library() işlevini kullanır.

sphal ad alanından rs ad alanına geçiş yaparken yükleme, /system/etc/ld.config.txt içindeki aşağıdaki satırla dolaylı olarak yapılır:

namespace.sphal.link.rs.shared_libs = libRS_internal.so

Bu satır, dinamik bağlayıcının libRS_internal.so öğesini rs ad alanından yüklemesi gerektiğini belirtir. Bunun nedeni, lib öğesinin sphal ad alanında bulunamaması/yüklenememesidir (sphal ad alanı, libRS_internal.so öğesinin bulunduğu /system/lib/vndk-sp konumunda arama yapmadığı için bu durum her zaman geçerlidir). Bu yapılandırmayla, ad alanı geçişini yapmak için libRS_internal.so'ye basit bir dlopen() çağrısı yeterlidir.

BCC eklentisini yükleme

bcc plugin, bcc derleyicisine yüklenen, tedarikçi tarafından sağlanan bir kitaplıktır. bcc, /system/bin dizinindeki bir sistem işlemi olduğundan bcc plugin kitaplığı, SP-HAL (yani binderize edilmeden doğrudan sistem işlemine yüklenebilen bir satıcı HAL'ı) olarak kabul edilebilir. Bir SP-HAL olarak bcc-plugin kitaplığı:

  • libLLVM.so gibi yalnızca çerçeve içeren kitaplıklara karşı bağlantı oluşturulamaz.
  • Yalnızca satıcıya sunulan VNDK-SP kitaplıklarına bağlanabilir.

Bu kısıtlama, bcc plugin öğesinin android_sphal_load_library() işlevi kullanılarak sphal ad alanına yüklenmesiyle uygulanır. Android'in önceki sürümlerinde eklenti adı -load seçeneği kullanılarak belirtiliyordu ve kitaplık, libLLVM.so tarafından basit dlopen() kullanılarak yükleniyordu. Android 8.0 ve sonraki sürümlerde bu, -plugin seçeneğinde belirtilir ve kitaplık doğrudan bcc tarafından yüklenir. Bu seçenek, açık kaynaklı LLVM projesine Android'e özgü olmayan bir yol sağlar.

Şekil 5. Android 7.x ve önceki sürümlerde bcc eklentisi yükleniyor.



Şekil 6. BCC eklentisi yükleniyor, Android 8.0 ve sonraki sürümler.

ld.mc için arama yolları

ld.mc yürütülürken bazı RS çalışma zamanı kitaplıkları bağlayıcıya giriş olarak verilir. Uygulamadaki RS bit kodu, çalışma zamanı kitaplıklarına bağlanır ve dönüştürülmüş bit kodu bir uygulama işlemine yüklendiğinde çalışma zamanı kitaplıkları, dönüştürülmüş bit kodundan tekrar dinamik olarak bağlanır.

Çalışma zamanı kitaplıkları şunları içerir:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • RS sürücüsü (libRSDriver.so veya OVERRIDE_RS_DRIVER)

Derlenmiş bit kodu uygulama işlemine yüklerken ld.mc tarafından kullanılan kitaplığın aynısını sağlayın. Aksi takdirde, derlenmiş bitcode, bağlandığı sırada mevcut olan bir sembolü bulamayabilir.

Bunu yapmak için RS çerçevesi, ld.mc yürütülürken çalışma zamanı kitaplıkları için farklı arama yolları kullanır. Bu, RS çerçevesinin kendisinin /system/lib veya /system/lib/vndk-sp konumundan yüklenmesine bağlıdır. Bu, bir RS çerçeve kitaplığının rastgele bir sembolünün adresi okunarak ve adrese eşlenen dosya yolunu almak için dladdr() kullanılarak belirlenebilir.

SELinux politikası

Android 8.0 ve sonraki sürümlerdeki SELinux politikası değişiklikleri nedeniyle, vendor bölümünde ek dosyaları etiketlerken neverallows aracılığıyla uygulanan belirli kurallara uymanız gerekir:

  • vendor_file, vendor bölümündeki tüm dosyalar için varsayılan etiket olmalıdır. Platform politikası, geçiş HAL uygulamalarına erişmek için bunu gerektirir.
  • Satıcı SEPolicy'si aracılığıyla vendor bölümüne eklenen tüm yeni exec_types öğelerinde vendor_file_type özelliği bulunmalıdır. Bu, neverallows aracılığıyla zorunlu kılınır.
  • Gelecekteki platform/çerçeve güncellemeleriyle çakışmaları önlemek için vendor bölümünde exec_types dışındaki dosyaları etiketlemeyin.
  • AOSP tarafından aynı işlem HAL'leri olarak tanımlanan tüm kitaplık bağımlılıkları same_process_hal_file olarak etiketlenmelidir.

SELinux politikasıyla ilgili ayrıntılar için Android'de Güvenliği Artırılmış Linux başlıklı makaleyi inceleyin.

Bit kodu için ABI uyumluluğu

Yeni API eklenmezse (yani HAL sürümü yükseltilmezse) RS çerçeveleri mevcut GPU (HAL 1.0) sürücüsünü kullanmaya devam eder.

Bit kodunu etkilemeyen küçük HAL değişiklikleri (HAL 1.1) için çerçeveler, yeni eklenen bu API'lerde CPU'ya geri dönmeli ve başka yerlerde GPU (HAL 1.0) sürücüsünü kullanmaya devam etmelidir.

Bit kodu derleme/bağlama işlemlerini etkileyen büyük HAL değişiklikleri (HAL 2.0) için RS çerçeveleri, satıcı tarafından sağlanan GPU sürücülerini yüklememeyi ve bunun yerine hızlandırma için CPU veya Vulkan yolunu kullanmayı tercih etmelidir.

RenderScript bit kodu üç aşamada tüketilir:

Aşama Ayrıntılar
Derle
  • bcc için giriş bit kodu (.bc) LLVM 3.2 bit kodu biçiminde olmalı ve bcc mevcut (eski) uygulamalarla geriye dönük uyumlu olmalıdır.
  • Ancak .bc dosyasındaki meta veriler değişebilir (ör. Allocation ayarlayıcıları ve alıcıları, matematik işlevleri gibi yeni çalışma zamanı işlevleri olabilir). Çalışma zamanı işlevlerinin bir kısmı libclcore.bc içinde, bir kısmı ise LibRSDriver veya tedarikçiye ait eşdeğer bir kitaplıkta bulunur.
  • Yeni çalışma zamanı işlevleri veya meta verilerde yapılan ve uyumluluğu bozan değişiklikler, bitcode API düzeyinin artırılmasını gerektirir. Tedarikçi sürücüleri bunu kullanamayacağından, HAL sürümü de artırılmalıdır.
  • Satıcıların kendi derleyicileri olabilir ancak bcc ile ilgili sonuçlar/gereksinimler bu derleyiciler için de geçerlidir.
Bağlantı
  • Derlenen .o, satıcı sürücüsüyle bağlanır (ör. libRSDriver_foo.so ve libcompiler_rt.so). CPU yolu, libRSDriver.so ile bağlantı oluşturur.
  • .o, libRSDriver_foo tarafından yeni bir çalışma zamanı API'si gerektiriyorsa satıcı sürücüsünün bunu destekleyecek şekilde güncellenmesi gerekir.
  • Belirli satıcıların kendi bağlayıcıları olabilir ancak ld.mc için geçerli olan argümanlar onlar için de geçerlidir.
Yükleme
  • libRSCpuRef, paylaşılan nesneyi yükler. Bu arayüzde değişiklik olursa HAL sürümünün yükseltilmesi gerekir.
  • Tedarikçiler, paylaşılan nesneyi yüklemek için libRSCpuRef kullanır veya kendi nesnelerini uygular.

HAL'ye ek olarak, çalışma zamanı API'leri ve dışa aktarılan semboller de arayüzlerdir. Android 7.0'dan (API 24) beri iki arayüzde de değişiklik yapılmadı ve Android 8.0 ile sonraki sürümlerde bu arayüzleri değiştirmek için acil bir plan bulunmuyor. Ancak arayüz değişirse HAL sürümü de artar.

Tedarikçi uygulamaları

Android 8.0 ve sonraki sürümlerde GPU sürücüsünün düzgün çalışması için bazı GPU sürücüsü değişiklikleri gerekir.

Sürücü modülleri

  • Sürücü modülleri, listede olmayan sistem kitaplıklarına bağlı olmamalıdır.
  • Sürücü kendi android.hardware.renderscript@1.0-impl_{NAME} öğesini sağlamalı veya varsayılan uygulamayı android.hardware.renderscript@1.0-impl bağımlılığı olarak bildirmelidir.
  • CPU uygulaması libRSDriver.so, VNDK-SP olmayan bağımlılıkların nasıl kaldırılacağına dair iyi bir örnektir.

Bitcode derleyicisi

Tedarikçi sürücüsü için RenderScript bitcode'u iki şekilde derleyebilirsiniz:

  1. /vendor/bin/ içinde tedarikçiye özel RenderScript derleyicisini çağırın (tercih edilen GPU derleme yöntemi). Diğer sürücü modüllerine benzer şekilde, katılımcı derleyici ikili programı, katılımcıların kullanımına sunulan RenderScript kitaplıkları listesinde yer almayan hiçbir sistem kitaplığına bağlı olamaz.
  2. Satıcı tarafından sağlanan /system/bin/bcc ile sistem bcc'sini çağırın: bcc plugin; bu eklenti, satıcılara sunulan RenderScript kitaplıkları listesinde olmayan hiçbir sistem kitaplığına bağlı olamaz.

Tedarikçinin bcc plugin CPU derlemesine müdahale etmesi gerekiyorsa ve libLLVM.so bağımlılığı kolayca kaldırılamıyorsa tedarikçi bcc (libLLVM.so, libbcc.so dahil olmak üzere tüm LL-NDK dışı bağımlılıklarla birlikte) öğesini /vendor bölümüne kopyalamalıdır.

Ayrıca, tedarikçilerin aşağıdaki değişiklikleri yapması gerekir:

Şekil 7. Tedarikçi sürücüsünde yapılan değişiklikler.

  1. libclcore.bc bölümünü /vendor bölümüne kopyalayın. Bu, libclcore.bc, libLLVM.so ve libbcc.so'nin senkronize olmasını sağlar.
  2. RS HAL uygulamasından bcc ayarını yaparak yürütülebilir dosyanın yolunu değiştirin.RsdCpuScriptImpl::BCC_EXE_PATH

SELinux politikası

SELinux politikası hem sürücüyü hem de derleyici yürütülebilir dosyalarını etkiler. Tüm sürücü modülleri, cihazın file_contexts bölümünde same_process_hal_file olarak etiketlenmelidir. Örneğin:

/vendor/lib(64)?/libRSDriver_EXAMPLE\.so     u:object_r:same_process_hal_file:s0

Derleyici yürütülebilir dosyası, bcc'nin satıcı kopyası (/vendor/bin/bcc) gibi bir uygulama süreci tarafından çağrılabilmelidir. Örneğin:

device/vendor_foo/device_bar/sepolicy/file_contexts:
/vendor/bin/bcc                    u:object_r:same_process_hal_file:s0

Eski cihazlar

Eski cihazlar aşağıdaki koşulları karşılayan cihazlardır:

  1. PRODUCT_SHIPPING_API_LEVEL 26'dan düşük.
  2. PRODUCT_FULL_TREBLE_OVERRIDE tanımlanmamış.

Eski cihazlarda, Android 8.0 ve sonraki sürümlere yükseltme yapılırken kısıtlamalar uygulanmaz. Bu nedenle, sürücüler /system/lib[64] içindeki kitaplıklara bağlanmaya devam edebilir. Ancak OVERRIDE_RS_DRIVER ile ilgili mimari değişikliği nedeniyle android.hardware.renderscript@1.0-impl, /vendor bölümüne yüklenmelidir. Aksi takdirde RenderScript çalışma zamanı CPU yoluna geri döner.

RenderScript desteğinin sonlandırılmasının nedeni hakkında bilgi edinmek için Android Developers Blog: Android GPU Compute Going Forward başlıklı makaleyi inceleyin. Bu kullanımdan kaldırma işlemiyle ilgili kaynak bilgileri şunları içerir: