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 bilgisayar görüşü gerçekleştiren 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:

1. şekil. 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 RenderScript dahili kitaplıklarının iki ö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ıklara karşı bağlantı oluşturamazlar. Aksi takdirde, yalnızca çerçeve içeren bir 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.

Tedarikçilerin kullanımına sunulan RenderScript kitaplıkları

Bu bölümde, satıcı kodunda kullanılabilen ve bağlantı oluşturulabilen RenderScript kitaplıkları (Same-Process HAL'ler veya VNDK-SP için Vendor NDK 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 RenderScript Olmayan Kitaplıklar
  • 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 Design sunumuna bakın.)

Android 8.0 ve sonraki sürümlerin yüklü olduğu cihazlarda, RenderScript hariç tüm Aynı İşlem HAL'leri (SP-HAL'ler) bağlayıcı ad alanına yüklenir sphal. RenderScript, RenderScript'e özel ad alanına rs yüklenir. Bu konum, RenderScript kitaplıkları için biraz daha esnek bir zorunlu kılma sağlar. RS uygulamasının derlenmiş bitcode'u 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

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ı), RS kitaplıklarının platform sürümünün sağlandığı varsayılan bağlayıcı ad alanından doğrudan dlopen edilir.

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.

3.Şekil 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, dlopens libRS_internal.so başka bir bağlayıcı ad alanında rs olarak adlandırılır.

Tedarikçiler, RS HAL uygulamasında yerleşik olan OVERRIDE_RS_DRIVER derleme zamanı işaretini 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. 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, lib libRS_internal.so ad alanından bulunamadığında/yüklenemediğinde rs ad alanından yüklemesi gerektiğini belirtir (sphal ad alanı, libRS_internal.so'nın bulunduğu /system/lib/vndk-sp'ü aramadığı için bu durum her zaman geçerlidir).sphal Bu yapılandırmayla, ad alanı geçişini yapmak için libRS_internal.so adresine 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 bağlanılamaz.
  • Yalnızca satıcıya sunulan VNDK-SP kitaplıklarına bağlanabilir.

Bu kısıtlama, bcc plugin öğesini android_sphal_load_library() işlevi kullanılarak sphal ad alanına yüklenerek 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 kaynak LLVM projesine Android'e özgü olmayan bir yol sağlar.

5.şekil bcc eklentisi yükleniyor, Android 7.x ve önceki sürümler.



6.şekil 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 göre 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ı şunlardır:

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

Derlenmiş bitcode'u uygulama sürecine 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üklenip yüklenmediğine 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ündeki 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 için 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.

Bitcode'u 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.

Bitcode derlemesini/bağlantısını 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 tüketimi üç aşamada gerçekleşir:

Aşama Ayrıntılar
Derleme
  • 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.yeni çalışma zamanı işlevleri olabilir). Ayırma ayarlayıcıları ve alıcıları, matematik işlevleri vb.). Ç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 yerde 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, tedarikçi sürücüsüyle bağlanır. Örneğin: 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 bunlar 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 arayüzlerden hiçbiri değişmedi ve Android 8.0 ile sonraki sürümlerde arayüzü değiştirmek için acil bir plan yok. 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 yapılması 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 dışı 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 (GPU derlemesi için tercih edilen yöntem). Diğer sürücü modüllerine benzer şekilde, satıcı derleyici ikilisi, satıcılar tarafından kullanılabilen RenderScript kitaplıkları listesinde olmayan hiçbir sistem kitaplığına bağlı olamaz.
  2. Sistemin gizli kopyasını çağırma: /system/bin/bcc, sağlayıcı tarafından sağlanan bcc plugin ile. Bu eklenti, sağlayıcılar tarafından kullanılabilen 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ında bcc ayarını yaparak yürütülebilir RsdCpuScriptImpl::BCC_EXE_PATH dosyasının yolunu değiştirin.

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 tedarikçi 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 /vendor bölümüne android.hardware.renderscript@1.0-impl 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: