RenderScript

RenderScript, yoğun bilgi işlem gerektiren görevleri Android'de yüksek performansla çalıştırmak için kullanılan bir çerçevedir. Seri iş yükleri de fayda sağlayabilse de veri paralel hesaplama ile kullanılmak üzere tasarlanmıştır. RenderScript çalışma zamanı, çok çekirdekli CPU'lar ve GPU'lar gibi bir cihazda bulunan işlemciler arasında paralel olarak çalışır. Böylece geliştiriciler, işleri 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ümleri çalıştıran cihazlar aşağıdaki RenderScript çerçevesini ve tedarikçi HAL'lerini kullanır:

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

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

  • Bir işlemde iki RenderScript dahili kitaplığı örneği. Bir grup, CPU yedek yolu içindir ve doğrudan /system/lib adresinden alınır; diğer grup ise GPU yolu içindir ve /system/lib/vndk-sp adresinden alınır.
  • /system/lib'teki RS dahili kitaplıkları, platformun bir parçası olarak derlenir ve system.img yükseltilirken güncellenir. Ancak /system/lib/vndk-sp'teki libs, tedarikçi firma için derlenir ve system.img yükseltildiğinde güncellenmez (güvenlik düzeltmesi için güncellenebilir olsalar da ABI'leri aynı kalır).
  • Tedarikçi kodu (RS HAL, RS sürücüsü ve bcc plugin), /system/lib/vndk-sp adresindeki RenderScript dahili kitaplıklarına bağlanır. Bu dizindeki libs, platform için derlendiğinden ve dolayısıyla tedarikçi koduyla uyumlu olmayabileceğinden (ör. semboller kaldırılabilir) /system/lib içindeki libs'lere bağlanamaz. Aksi takdirde, yalnızca çerçeve için OTA işlemi imkansız olur.

Tasarım

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

Tedarikçi firmaların kullanabileceği RenderScript kitaplıkları

Bu bölümde, tedarikçi kodu tarafından kullanılabilen ve bağlanılabilen RenderScript kitaplıkları (aynı işlem HAL'leri için tedarikçi NDK veya VNDK-SP olarak bilinir) listelenmektedir. Ayrıca, RenderScript ile alakalı olmayan ancak tedarikçi koduna da sağlanan ek kitaplıklar ayrıntılı olarak açıklanır.

Aşağıdaki kitaplık listesi Android sürümleri arasında farklılık gösterse de belirli bir Android sürümü için değişmez. Mevcut kitaplıkların güncel listesini /system/etc/ld.config.txt adresinde bulabilirsiniz.

RenderScript Kitaplıkları 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 tedarikçi 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 sunağına bakın.)

Android 8.0 ve sonraki sürümleri çalıştıran bir cihazda, RenderScript hariç tüm aynı işlem HAL'leri (SP-HAL'ler) sphal bağlayıcı ad alanının içine yüklenir. RenderScript, RenderScript'e özel rs ad alanına yüklenir. Bu alan, RenderScript kitaplıkları için biraz daha gevşek bir yaptırım 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ında sağlananlardan daha fazla kitaplığa izin verir. libRS_internal.so bu kitaplıklara dahili olarak bağımlı olduğundan libmediandk.so ve libft2.so, rs ad alanına açıktır.

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

Sürücüleri yükleme

CPU yedek yolu

RS bağlamı oluştururken 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 ve mVendorDriverName null ile bir RsContext nesnesi oluşturulduğunda tedarikçi firmanın RS HAL uygulaması hiç kullanılmaz. libRSDriver.so (varsayılan olarak) dlopened olur ve çağıran (libRS_internal.so) da default ad alanına yüklendiğinde sürücü kitaplığı default ad alanından yüklenir.

Şekil 3. CPU yedek yolu.

GPU yolu

GPU yolu için libRS_internal.so farklı şekilde yüklenir. Öncelikle libRS.so, android.hardware.renderscript@1.0-impl.so'ı (RS HAL'ın satıcı uygulaması) sphal adlı farklı bir bağlayıcı ad alanına yüklemek için android.hardware.renderscript@1.0.so'ü (ve temelindeki libhidltransport.so'yi) kullanır. RS HAL, daha sonra rs adlı başka bir bağlayıcı ad alanında dlopens libRS_internal.so.

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

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

Şekil 4. GPU yedek yolu.

default ad alanından sphal ad alanına geçiş yaparken libhidltransport.so, android_load_sphal_library() işlevini kullanarak dinamik bağlayıcıya -impl.so kitaplığını sphal ad alanından yüklemesini açıkça emreder.

sphal ad alanından rs ad alanına geçiş yapılırken yükleme, /system/etc/ld.config.txt içindeki aşağıdaki satır tarafından 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 kitaplığı sphal ad alanında bulunamadığında/yüklenemediğinde rs ad alanından yüklemesi gerektiğini belirtir (sphal ad alanı, libRS_internal.so'nin bulunduğu /system/lib/vndk-sp alanında arama yapmadığı için bu durum her zaman geçerlidir). Bu yapılandırmayla, ad alanı geçişini yapmak için dlopen()'ten libRS_internal.so'a basit bir çağrı yeterlidir.

Bcc eklentisini yükleme

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

  • libLLVM.so gibi yalnızca çerçeve kitaplıklarına bağlanamaz.
  • Yalnızca tedarikçi firmanın kullanabileceği 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üklenmesi ile uygulanır. Android'in önceki sürümlerinde, eklenti adı -load seçeneği kullanılarak belirtiliyordu ve lib, 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 lib doğrudan bcc tarafından yüklenir. Bu seçenek, açık kaynak LLVM projesine Android'e özgü olmayan bir yol açar.

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



Şekil 6. Android 8.0 ve sonraki sürümlerde bcc eklentisi yükleniyor.

ld.mc için arama yolları

ld.mc yürütüldüğünde, 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 sürecine 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ş bit kodunu uygulama işlemine yüklerken ld.mc tarafından kullanılan kitaplığın bire bir aynısını sağlayın. Aksi takdirde, derlenmiş bit kodu, bağlandığında mevcut olan bir simgeyi bulamayabilir.

Bunu yapmak için RS çerçevesi, ld.mc'ü yürüttüğünde RS çerçevesinin /system/lib'ten mi yoksa /system/lib/vndk-sp'den mi yükleneceğine bağlı olarak çalışma zamanı kitaplıkları için farklı arama yolları kullanır. Bu, bir RS çerçeve kitaplığının rastgele bir sembolünün adresi okunarak ve dladdr() kullanılarak adresle eşlenen dosya yolu elde edilerek belirlenebilir.

SELinux politikası

Android 8.0 ve sonraki sürümlerde SELinux politikasındaki değişiklikler nedeniyle, vendor bölümünde ek dosyaları etiketlerken belirli kurallara (neverallows üzerinden uygulanır) uymanız gerekir:

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

SELinux politikası hakkında ayrıntılı bilgi için Android'de Güvenlik Gelişmiş 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'yu (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, bu yeni eklenen API'ler için CPU'ya geri dönmeli ve GPU (HAL 1.0) sürücüsünü başka yerlerde kullanmaya devam etmelidir.

Bit kodu derlemeyi/bağlamayı etkileyen önemli HAL değişiklikleri (HAL 2.0) için RS çerçeveleri, tedarikçi firma tarafından sağlanan GPU sürücülerini yüklememeyi seçmeli ve bunun yerine hızlandırma için CPU veya Vulkan yolunu kullanmalıdır.

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

Sahne Ayrıntılar
Derleme
  • bcc için giriş bit kodu (.bc), LLVM 3.2 bit kodu biçiminde olmalıdır 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ında işlevler olabilir). Ayırma ayarlayıcıları ve alıcıları, matematik işlevleri vb.). Çalışma zamanındaki işlevlerin bir kısmı libclcore.bc içinde, bir kısmı ise LibRSDriver veya tedarikçi firmanın eşdeğeri içinde bulunur.
  • Yeni çalışma zamanı işlevleri veya önemli meta veri değişiklikleri, bit kodu API düzeyinin artırılması Tedarikçi sürücüleri bu sürümleri kullanamayacağından HAL sürümü de artırılmalıdır.
  • Tedarikçi firmaların kendi derleyicileri olabilir ancak bcc ile ilgili sonuçlar/şartlar bu derleyiciler için de geçerlidir.
Bağlantı
  • Derlenmiş .o dosyası, tedarikçi sürücüyle (ör. libRSDriver_foo.so ve libcompiler_rt.so. CPU yolu, libRSDriver.so ile bağlantı kurar.
  • .o, libRSDriver_foo'ten yeni bir çalışma zamanı API'si gerektiriyorsa tedarikçi sürücüsünün bunu desteklemek için güncellenmesi gerekir.
  • Belirli satıcıların kendi bağlayıcıları olabilir ancak ld.mc için geçerli olan argüman bu satıcılar için de geçerlidir.
Yükleme
  • libRSCpuRef, paylaşılan nesneyi yükler. Bu arayüzde değişiklik varsa HAL sürümünün yükseltilmesi gerekir.
  • Tedarikçi firmalar, paylaşılan nesneyi yüklemek için libRSCpuRef'ten yararlanır veya kendilerini uygular.

HAL'e ek olarak çalışma zamanı API'leri ve dışa aktarılan semboller de arayüzdür. Bu iki arayüz Android 7.0 (API 24) sürümünden beri değişmedi ve Android 8.0 ile sonraki sürümlerde de değiştirilme planı bulunmuyor. Ancak arayüz değişirse HAL sürümü de artar.

Tedarikçi firma 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 bulunmayan sistem kitaplıklarına bağlı olmamalıdır.
  • Sürücü kendi android.hardware.renderscript@1.0-impl_{NAME}'ünü sağlamalıdır veya varsayılan uygulamayı android.hardware.renderscript@1.0-impl bağımlılığı olarak belirtmelidir.
  • VNDK-SP dışındaki bağımlılıkların nasıl kaldırılacağına dair iyi bir örnek olan CPU uygulaması libRSDriver.so.

Bit kodu derleyicisi

Tedarikçi sürücüsü için RenderScript bit kodunu iki şekilde derleyebilirsiniz:

  1. /vendor/bin/ bölümünde tedarikçiye özgü RenderScript derleyicisini çağırın (GPU derlemesi için tercih edilen yöntem). Diğer sürücü modüllerine benzer şekilde, tedarikçi derleyici ikili dosyası, tedarikçi firmaların kullanabileceği RenderScript kitaplıkları listesinde bulunmayan hiçbir sistem kitaplığına bağlı olamaz.
  2. Satıcı tarafından sağlanan /system/bin/bcc ile sistem gizli kopya alanını çağırın: bcc plugin; bu eklenti, satıcılara sunulan RenderScript kitaplıkları listesinde bulunmayan hiçbir sistem kitaplığına bağlı olamaz.

bcc plugin tedarikçisinin CPU derlemesini etkilemesi gerekiyorsa ve libLLVM.so'a olan bağımlılığı kolayca kaldırılamıyorsa tedarikçi, bcc'yi (ve libLLVM.so, libbcc.so dahil olmak üzere LL-NDK olmayan tüm bağımlılıkları) /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 dosyası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 RsdCpuScriptImpl::BCC_EXE_PATH ayarlayarak bcc yürütülebilir dosyasının yolunu değiştirin.

SELinux politikası

SELinux politikası hem sürücüyü hem de derleyici çalıştırılabilir dosyalarını etkiler. Tüm sürücü modülleri, cihazın file_contexts bölümünde same_process_hal_file olarak etiketlenmelidir. Örnek:

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

Derleyici yürütülebilir dosyası, bcc'nin (/vendor/bin/bcc) tedarikçi firma kopyasında olduğu gibi bir uygulama işlemi 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ğlantı vermeye 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 kurulmalıdır. Aksi takdirde RenderScript çalışma zamanı, CPU yoluna geri dönmeye zorlanır.

Renderscript'in desteğinin sonlandırılmasının nedeni hakkında bilgi edinmek için Android Developers Blog'undaki Android GPU Compute Going Forward (Android GPU'da Gelecekte Kullanılacak Hesaplama) başlıklı makaleyi inceleyin. Bu desteğin sonlandırılmasıyla ilgili kaynak bilgileri şunları içerir: