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 bu özellikten yararlanabilir ancak 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ğlantı veren tedarikçi kodu.
Android 7.x ve önceki sürümlerdeki RenderScript'ten farklılıklar şunlardır:
- Bir işlemdeki 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 oluşturulur vesystem.img
yükseltilirken güncellenir. Ancak/system/lib/vndk-sp
'teki libs, tedarikçi firma için derlenir vesystem.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 ile bağlantı kuramaz. 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 |
---|---|
|
|
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ı sunusuna 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ı tarafından 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ı oluşturucu için ad alanı yapılandırması.
Sürücüleri yükleme
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
uygulanır.
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) dlopen
uygulanmıştır ve sürücü kitaplığı default
ad alanından (libRS_internal.so
) de default
ad alanına yüklendiğinden yüklenir.
Şekil 3. CPU yedek 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
öğesini (RS HAL'nin tedarikçi firma uygulaması) sphal
adlı farklı bir bağlayıcı ad alanına yüklemek için android.hardware.renderscript@1.0.so
(ve temel libhidltransport.so
) kullanır. RS HAL, daha sonra rs
adlı başka bir bağlayıcı ad alanında dlopen
s 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 kullanmak üzere 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ş yaparken yükleme, /system/etc/ld.config.txt
içindeki aşağıdaki satır aracılığıyla dolaylı olarak gerçekleştirilir:
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ırmada, ad alanı geçişini gerçekleştirmek için libRS_internal.so
için yapılan basit bir dlopen()
çağrısı 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 satıcını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 kitaplık 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
veyaOVERRIDE_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ütürken RS çerçevesinin /system/lib
veya /system/lib/vndk-sp
üzerinden yüklenmesine 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.- Tedarikçi firma SEPolicy aracılığıyla
vendor
bölmesine eklenen tüm yeniexec_types
,vendor_file_type
özelliğine sahip olmalıdır. Bu,neverallows
aracılığıyla zorunlu kılınmıştır. - Gelecekteki platform/çerçeve güncellemeleriyle çakışmaları önlemek için
vendor
bölümündeexec_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 (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 kodunun kullanımı üç aşamada gerçekleşir:
Sahne | Ayrıntılar |
---|---|
Derleme |
|
Bağlantı |
|
Yükle |
|
HAL'nin yanı sıra ç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 olmayan 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:
/vendor/bin/
içinde tedarikçi firmaya özgü RenderScript derleyiciyi ç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.- Satıcı tarafından sağlanan
/system/bin/bcc
ile sistem bcc:bcc plugin
çağrısı; bu eklenti, satıcılara sunulan RenderScript kitaplıkları listesinde bulunmayan hiçbir sistem kitaplığına bağlı olamaz.
bcc plugin
tedarikçisinin CPU derlemesine müdahale etmesi gerekiyorsa ve libLLVM.so
tedarikçisine olan bağımlılığı kolayca kaldırılamıyorsa tedarikçi firma bcc
'ı (ve libLLVM.so
ve 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.
libclcore.bc
dosyasını/vendor
bölümüne kopyalayın. Bu,libclcore.bc
,libLLVM.so
velibbcc.so
'nin senkronize olmasını sağlar.- RS HAL uygulamasından
RsdCpuScriptImpl::BCC_EXE_PATH
ayarlayarakbcc
yürütülebilir 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. Ö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:
- PRODUCT_SHIPPING_API_LEVEL 26'dan düşük.
- PRODUCT_FULL_TREBLE_OVERRIDE tanımlı değil.
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'daki Android GPU Compute Going Forward (Android GPU'da Gelecekte Kullanılacak Hesaplama) başlıklı makaleyi inceleyin. Desteğin sonlandırılmasıyla ilgili kaynak bilgileri şunları içerir:
- Renderscript'ten taşıma
- RenderScriptMigration Örneği
- Intrinsics Replacement Toolkit README
- İçsel DeğişimToolkit.kt