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 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 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 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
  • 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ı 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 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 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 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ü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 yeni exec_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ü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 (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
  • bcc için giriş bit kodu (.bc) LLVM 3.2 bit kodu biçiminde, bcc ise mevcut (eski) uygulamalarla geriye dönük uyumlu olmalıdır.
  • Ancak, .bc dosyasındaki meta veriler değişebilir (ör. Ayırma belirleyicileri ve alıcılar, matematik fonksiyonları vb.). Çalışma zamanı işlevlerinin bir kısmı libclcore.bc, bir kısmı da LibRSDriver veya tedarikçi firmanın eşdeğeri sürümünde bulunur.
  • Yeni çalışma zamanı işlevleri veya meta veri değişikliklerinin bozulması, bitcode API düzeyinin artırılmasını gerektirir. 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ükle
  • 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'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:

  1. /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.
  2. 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.

  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 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:

  1. PRODUCT_SHIPPING_API_LEVEL 26'dan düşük.
  2. 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: