betimleme

RenderScript , Android'de yüksek performansta hesaplama açısından yoğun görevleri çalıştırmak için bir çerçevedir. Seri iş yükleri de fayda sağlasa da, veri paralel hesaplama ile kullanım için tasarlanmıştır. RenderScript çalışma zamanı, çok çekirdekli CPU'lar ve GPU'lar gibi bir cihazda bulunan işlemciler arasında çalışmayı paralel hale getirerek geliştiricilerin işi planlamak yerine algoritmaları ifade etmeye odaklanmasını sağlar. RenderScript, özellikle görüntü işleme, hesaplamalı fotoğrafçılık veya bilgisayarla görme gerçekleştiren uygulamalar için kullanışlıdır.

Android 8.0 ve sonraki sürümleri çalıştıran cihazlar, aşağıdaki RenderScript çerçevesini ve satıcı HAL'lerini kullanır:

Şekil 1. Dahili kütüphanelere bağlanan satıcı kodu

Android 7.x ve önceki sürümlerde RenderScript'ten farklılıklar şunları içerir:

  • Bir işlemde RenderScript dahili kitaplıklarının iki örneği. Bir küme CPU geri dönüş yolu içindir ve doğrudan /system/lib adresinden alınır; diğer küme GPU yolu içindir ve /system/lib/vndk-sp .
  • /system/lib içindeki RS dahili kütüphaneleri, platformun bir parçası olarak oluşturulur ve system.img yükseltildikçe güncellenir. Ancak, /system/lib/vndk-sp içindeki lib'ler satıcı için oluşturulmuştur ve system.img yükseltildiğinde güncellenmezler (bir güvenlik düzeltmesi için güncellenebilseler de ABI'ları aynı kalır).
  • Satıcı kodu (RS HAL, RS sürücüsü ve bcc plugin ), /system/lib/vndk-sp bulunan RenderScript dahili kitaplıklarına bağlıdır. /system/lib içindeki lib'lere bağlanamazlar çünkü bu dizindeki lib'ler platform için oluşturulmuştur ve bu nedenle satıcı koduyla uyumlu olmayabilirler (yani semboller kaldırılabilir). Bunu yapmak, yalnızca çerçeveye yönelik bir OTA'yı imkansız hale getirir.

Tasarım

Aşağıdaki bölümler, Android 8.0 ve sonraki sürümlerde RenderScript tasarımını detaylandırmaktadır.

Satıcıların kullanımına sunulan RenderScript kitaplıkları

Bu bölüm, satıcı kodu için kullanılabilen ve ilişkilendirilebilen RenderScript kitaplıklarını (Aynı İşlem HAL'leri için Satıcı NDK veya VNDK-SP olarak bilinir) listeler. Ayrıca, RenderScript ile ilgisi olmayan ancak aynı zamanda satıcı koduna sağlanan ek kitaplıkları da detaylandırı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şmezdir; kullanılabilir kitaplıkların güncel bir listesi için /system/etc/ld.config.txt adresine bakın.

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 olmayan 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ümlerini çalıştıran bir cihazda, RenderScript dışındaki tüm Aynı İşlem HAL'leri (SP- HAL'ler ) linker ad alanı sphal içine yüklenir. RenderScript, RenderScript kitaplıkları için biraz daha gevşek bir zorlama sağlayan bir konum olan RenderScript'e özgü ad alanına rs yüklenir. 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ıkları yüklemesine izin verilmez).

Ek olarak, rs ad alanı, diğer ad alanları tarafından sağlanandan daha fazla kitaplığa izin verir. libmediandk.so ve libft2.so rs ad alanına maruz kalır çünkü libRS_internal.so bu kitaplıklara dahili bir bağımlılığa sahiptir.

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

Sürücüler yükleniyor

CPU geri dönüş yolu

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

Satıcının RS HAL uygulaması, CPU geri dönüş yolu alındığında hiç kullanılmaz ve boş mVendorDriverName ile bir RsContext nesnesi oluşturulur. libRSDriver.so (varsayılan olarak) silinir ve çağıran ( dlopen ) default ad alanına da yüklendiğinden libRS_internal.so default ad alanından yüklenir.

Şekil 4. CPU geri dönüş yolu

GPU yolu

GPU yolu için libRS_internal.so farklı şekilde yüklenir. İlk olarak, libRS.so , android.hardware.renderscript@1.0-impl.so (RS HAL'in bir satıcı uygulaması) adı verilen farklı bir bağlayıcı ad alanına yüklemek için android.hardware.renderscript@1.0.so (ve onun altında yatan libhidltransport.so ) kullanır. sphal . RS HAL daha sonra s libRS_internal.so rs adlı başka bir bağlayıcı ad alanında dlopen .

Satıcılar, RS HAL uygulamasına katıştırılmış olan OVERRIDE_RS_DRIVER oluşturma zamanı bayrağını ayarlayarak kendi RS sürücülerini sağlayabilirler ( hardware/interfaces/renderscript/1.0/default/Context.cpp ). Bu sürücü adı daha sonra dlopen yolu için RS bağlamı için silinir.

RsContext nesnesinin oluşturulması, RS HAL uygulamasına devredilmiştir. 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 daha sonra RsContext başlatıldığında belirtilen sürücüyü yükler. Bu durumda, sürücü kitaplığı rs ad alanına yüklenir, çünkü RsContext nesnesi rs ad alanı içinde oluşturulur ve /vendor/lib ad alanının arama yolundadır.

Şekil 5. GPU yedek yolu

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

sphal ad alanından rs ad alanına geçiş yapılırken, yükleme, /system/etc/ld.config.txt dosyasında 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 lib sphal ad alanından bulunamadığı/yüklenemediği zaman libRS_internal.so rs ad alanından yüklemesi gerektiğini belirtir (bu, sphal ad alanı /system/lib/vndk-sp aramadığı için her zaman böyledir). libRS_internal.so bulunur). Bu yapılandırmayla, ad alanı geçişini yapmak için libRS_internal.so basit bir dlopen() çağrısı yeterlidir.

bcc eklentisi yükleniyor

bcc plugin , bcc derleyicisine yüklenen, satıcı 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ı hale getirilmeden sistem işlemine doğrudan yüklenebilen bir satıcı HAL'ı) olarak kabul edilebilir. Bir SP-HAL olarak, bcc-plugin kitaplığı:

  • libLLVM.so gibi yalnızca çerçeve kitaplıklarına bağlanamaz.
  • Yalnızca satıcının kullanabileceği VNDK-SP kitaplıklarına bağlanabilir.

Bu kısıtlama, android_sphal_load_library() işlevini kullanarak bcc plugin sphal ad alanına yükleyerek uygulanır. Android'in önceki sürümlerinde, eklenti adı -load seçeneği kullanılarak belirtildi ve lib, libLLVM.so tarafından basit dlopen() kullanılarak yüklendi. 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 kaynaklı LLVM projesine Android'e özgü olmayan bir yol sağlar.

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


Şekil 7. bcc eklentisi yükleniyor, Android 8.0 ve üstü

ld.mc için arama yolları

ld.mc yürütülürken, bağlayıcıya girdi olarak bazı RS çalışma zamanı kitaplıkları verilir. Uygulamadan gelen RS bit kodu, çalışma zamanı kitaplıklarına bağlanır ve dönüştürülen bit kodu bir uygulama sürecine yüklendiğinde, çalıştırma zamanı kitaplıkları, dönüştürülen bit kodundan yeniden 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 kodunu uygulama sürecine yüklerken, ld.mc tarafından kullanılan kitaplığın aynısını sağlayın. Aksi takdirde, derlenmiş bit kodu, bağlandığında mevcut olan bir sembolü bulamayabilir.

Bunu yapmak için RS çerçevesi, ld.mc yürütülürken, RS çerçevesinin kendisinin /system/lib /lib'den mi yoksa /system/lib/vndk-sp mi yüklendiğine bağlı olarak, çalışma zamanı ld.mc için farklı arama yolları kullanır. Bu, bir RS çerçeve kütüphanesinin 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ümlerde SELinux politikası değişikliklerinin bir sonucu olarak, vendor bölümünde ek dosyaları etiketlerken belirli kurallara (asla izin neverallows yoluyla uygulanan) uymanız gerekir:

  • vendor_file , vendor bölümündeki tüm dosyalar için varsayılan etiket olmalıdır. Platform ilkesi, bunun doğrudan HAL uygulamalarına erişmesini gerektirir.
  • Satıcı SEPolicy aracılığıyla vendor bölümüne eklenen tüm yeni exec_types , vendor_file_type özniteliğine sahip olmalıdır. Bu, neverallows aracılığıyla uygulanır.
  • Gelecekteki platform/çerçeve güncellemeleriyle çakışmaları ö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 ilkesiyle ilgili ayrıntılar için bkz . Android'de Güvenliği Geliştirilmiş Linux .

bit kodu için ABI uyumluluğu

Yeni API'ler eklenmezse, yani HAL sürümü çarpması olmazsa, RS çerçeveleri mevcut GPU (HAL 1.0) sürücüsünü kullanmaya devam edecektir.

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 başka bir yerde GPU (HAL 1.0) sürücüsünü kullanmaya devam etmelidir.

Bit kodu derlemesini/bağlanması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 seçmeli ve bunun yerine hızlandırma için CPU veya Vulkan yolunu kullanmalıdır.

RenderScript bit kodunu tüketmek üç aşamada gerçekleşir:

Sahne Detaylar
derlemek
  • 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'deki meta veriler değişebilir (örneğin, Tahsis ayarlayıcıları ∓ alıcılar, matematik işlevleri vb. gibi yeni çalışma zamanı işlevleri olabilir). Çalışma zamanı işlevlerinin bir kısmı libclcore.bc içinde, bir kısmı LibRSDriver veya satıcı eşdeğerinde yaşar.
  • Yeni çalışma zamanı işlevleri veya meta veri değişikliklerini bozma, bit kodu API düzeyini artırmayı gerektirir. Satıcı sürücüleri onu tüketemeyeceğinden, HAL sürümü de artırılmalıdır.
  • Satıcıların kendi derleyicileri olabilir, ancak bcc için sonuçlar/gereksinimler bu derleyiciler için de geçerlidir.
Bağlantı
  • Derlenmiş .o, satıcı sürücüsü ile bağlantılı olacaktır, örneğin, libRSDriver_foo.so ve libcompiler_rt.so . CPU yolu libRSDriver.so ile bağlantı kuracaktır.
  • .o, libRSDriver_foo yeni bir çalışma zamanı API'si gerektiriyorsa, satıcı sürücüsünün bunu destekleyecek şekilde güncellenmesi gerekir.
  • Bazı satıcıların kendi bağlayıcıları olabilir, ancak ld.mc argümanı onlar için de geçerlidir.
Yük
  • libRSCpuRef , paylaşılan nesneyi yükler. Bu arabirimde değişiklikler varsa, bir HAL sürümü tümseği gerekir.
  • Satıcılar, paylaşılan nesneyi yüklemek için libRSCpuRef güvenir veya kendilerininkini uygular.

HAL'a ek olarak, çalışma zamanı API'leri ve dışa aktarılan semboller de arayüzlerdir. Android 7.0'dan (API 24) beri hiçbir arayüz değişmedi ve onu Android 8.0 ve sonrasında değiştirmek için acil bir plan yok. Ancak arabirim değişirse HAL sürümü de artar.

Satıcı uygulamaları

Android 8.0 ve üstü, GPU sürücüsünün doğru çalışması için bazı GPU sürücüsü değişiklikleri gerektirir.

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} 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 iyi bir örnektir.

bit kodu derleyici

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

  1. /vendor/bin/ içinde satıcıya özel RenderScript derleyicisini çağırın (tercih edilen GPU derleme yöntemi). Diğer sürücü modüllerine benzer şekilde, satıcı derleyici ikili dosyası, satıcıların kullanabileceği RenderScript kitaplıkları listesinde olmayan herhangi bir sistem kitaplığına bağlı olamaz.
  2. Sistem bcc'yi çağırın: /system/bin/bcc , satıcı tarafından sağlanan bir bcc plugin ; bu eklenti, satıcıların kullanabileceği RenderScript kitaplıkları listesinde olmayan herhangi bir sistem kitaplığına bağlı olamaz.

Satıcı bcc plugin CPU derlemesine müdahale etmesi gerekiyorsa ve libLLVM.so olan bağımlılığı kolayca kaldırılamıyorsa, satıcı bcc (ve libLLVM.so , libbcc.so dahil olmak üzere tüm LL-NDK olmayan bağımlılıkları) içine kopyalamalıdır. /vendor bölümü.

Ayrıca, satıcıların aşağıdaki değişiklikleri yapması gerekir:

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

SELinux politikası

SELinux ilkesi hem sürücüyü hem de derleyici yürütülebilir dosyalarını etkiler. Tüm sürücü modülleri, aygıtın same_process_hal_file içinde file_contexts olarak etiketlenmelidir. Örneğin:

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

Yürütülebilir derleyici, bcc'nin ( /vendor/bin/bcc ) satıcı kopyasında olduğu 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şılayanlardır:

  1. PRODUCT_SHIPPING_API_LEVEL , 26'dan düşük.
  2. PRODUCT_FULL_TREBLE_OVERRIDE tanımlı değil.

Eski aygıtlar için, Android 8.0 ve sonraki sürümlere yükseltme yapılırken kısıtlamalar uygulanmaz; bu, sürücülerin /system/lib[64] içindeki kitaplıklara bağlanmaya devam edebileceği anlamına gelir. 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; bunu yapmamak, RenderScript çalışma zamanı geri dönüşünü CPU yoluna zorlar.

Renderscript'in kullanımdan kaldırılmasına yönelik motivasyon hakkında bilgi için Android Developers Blog: Android GPU Compute Going Forward'a bakın. Bu kullanımdan kaldırma için kaynak bilgileri şunları içerir: