RenderScript چارچوبی برای اجرای وظایف محاسباتی سنگین با عملکرد بالا در Android است. این زبان برای استفاده با محاسبات داده-موازی طراحی شده است، هرچند که حجمهای کاری ترتیبی نیز میتوانند از آن بهرهمند شوند. زمان اجرای RenderScript کار را در پردازندههای موجود در دستگاه، مانند CPUهای چندهستهای و GPUها، موازی میکند و به توسعهدهندگان امکان میدهد بهجای زمانبندی کار، بر بیان الگوریتمها تمرکز کنند. RenderScript بهویژه برای برنامههایی که پردازش تصویر، عکاسی محاسباتی، یا دید رایانهای انجام میدهند مفید است.
دستگاههای دارای Android 8.0 و بالاتر از چارچوب RenderScript و HALهای فروشنده زیر استفاده میکنند:
شکل ۱. کد فروشنده به کتابخانههای داخلی پیوند میدهد.
تفاوتهای RenderScript در Android 7.x و نسخههای پایینتر شامل موارد زیر است:
- دو نمونه از کتابخانههای داخلی RenderScript در یک فرایند. یک مجموعه برای مسیر بازگشت CPU است و مستقیماً از
/system/libاست؛ مجموعه دیگر برای مسیر GPU است و از/system/lib/vndk-spاست. - کتابخانههای داخلی RS در
/system/libبهعنوان بخشی از پلاتفرم ساخته میشوند و با ارتقا یافتنsystem.imgبهروزرسانی میشوند. بااینحال، libs در/system/lib/vndk-spبرای فروشنده ساخته شده است و وقتیsystem.imgارتقا مییابد بهروز نمیشود (اگرچه میتوان آنها را برای رفع نقص امنیتی بهروز کرد، اما ABI آنها یکسان باقی میماند). - کد فروشنده (RS HAL، RS driver، و
bcc plugin) با کتابخانههای داخلی RenderScript واقع در/system/lib/vndk-spپیوند داده شده است. آنها نمیتوانند به کتابخانههای موجود در/system/libپیوند دهند زیرا کتابخانههای موجود در آن دایرکتوری برای پلاتفرم ساخته شدهاند و بنابراین ممکن است با کد فروشنده سازگار نباشند (یعنی ممکن است نمادها برداشته شوند). انجام این کار باعث میشود OTA فقط چارچوب غیرممکن شود.
طراحی
بخشهای زیر جزئیات طراحی RenderScript را در Android 8.0 و بالاتر شرح میدهند.
کتابخانههای RenderScript دردسترس فروشندگان
این بخش کتابخانههای RenderScript (معروف به Vendor NDK برای Same-Process HALs یا VNDK-SP) را که برای کد فروشنده دردسترس است و میتوان به آن پیوند داد فهرست میکند. همچنین کتابخانههای اضافی را که با RenderScript مرتبط نیستند اما به کد فروشنده ارائه میشوند، شرح میدهد.
اگرچه فهرست زیر از کتابخانهها ممکن است بین نسخههای Android متفاوت باشد،
اما برای یک نسخه خاص Android تغییرناپذیر است؛ برای فهرست بهروز
کتابخانههای دردسترس، به /system/etc/ld.config.txt مراجعه کنید.
| RenderScript Libs | کتابخانههای غیر RenderScript |
|---|---|
|
|
پیکربندی فضای نام پیونددهنده
محدودیت پیونددهی که مانع از استفاده کتابخانههایی میشود که در VNDK-SP نیستند کد فروشنده در زمان اجرا بااستفاده از فضای نام پیونددهنده اعمال میشود. (برای جزئیات، به ارائه طراحی VNDK مراجعه کنید.)
در دستگاههای دارای Android 8.0 و بالاتر، همه «لایههای انتزاع سختافزار همفرایندی» (SP-HALs)
بهجز RenderScript در فضای نام پیونددهنده
sphal بار میشوند. RenderScript در فضای نام مختص RenderScript rs بار میشود، مکانی که اجرای کمی آزادتر را برای کتابخانههای RenderScript ممکن میکند. چون پیادهسازی RS باید بیتکد کامپایلشده را بار کند، /data/*/*.so به مسیر فضای نام rs اضافه میشود (سایر SP-HALها مجاز نیستند کتابخانهها را از پارتیشن داده بار کنند).
علاوهبراین، فضای نام rs امکان استفاده از کتابخانههای بیشتری را نسبت به آنچه
فضاهای نام دیگر ارائه میدهند فراهم میکند. libmediandk.so و libft2.so
به فضای نام rs عرضه میشوند زیرا
libRS_internal.so به این کتابخانهها وابستگی داخلی دارد.
شکل ۲. پیکربندی فضای نام برای پیونددهنده.
بار کردن درایورها
مسیر بازگشت به واحد پردازش مرکزی
بسته به وجود RS_CONTEXT_LOW_LATENCY بیت
هنگام ایجاد بافت RS، مسیر CPU یا GPU انتخاب میشود. وقتی مسیر
واحد پردازش مرکزی انتخاب میشود، libRS_internal.so (پیادهسازی اصلی
چارچوب RS) مستقیماً از فضای نام پیونددهنده پیشفرض که در آن نسخه پلاتفرم کتابخانههای RS ارائه میشود dlopen میشود.
وقتی مسیر بازگشت CPU انتخاب میشود، از پیادهسازی RS HAL فروشنده اصلاً استفاده نمیشود و شیء RsContext با mVendorDriverName تهی ایجاد میشود. libRSDriver.so (بهطور پیشفرض) dlopen شده است و کتابخانه درایور از جاینام default بار میشود زیرا فراخواننده (libRS_internal.so) نیز در جاینام default بار شده است.
شکل ۳. مسیر جایگزین واحد پردازش مرکزی.
مسیر GPU
برای مسیر GPU، libRS_internal.so بهصورت متفاوتی بار میشود.
ابتدا، libRS.so از
android.hardware.renderscript@1.0.so (و libhidltransport.so زیرین آن) برای بار کردن
android.hardware.renderscript@1.0-impl.so (پیادهسازی فروشنده RS HAL) در جاینام پیونددهنده دیگری به نام
sphal استفاده میکند. سپس RS
HAL dlopen libRS_internal.so را در فضای نام پیونددهنده دیگری به نام rs
قرار میدهد.
فروشندگان میتوانند با تنظیم پرچم زمان ساخت
OVERRIDE_RS_DRIVER، که در پیادهسازی RS HAL
(hardware/interfaces/renderscript/1.0/default/Context.cpp) جاسازی شده است،
گرداننده RS خود را ارائه دهند. سپس این
نام گرداننده برای بافت RS برای مسیر GPU dlopen میشود.
ایجاد شیء RsContext به پیادهسازی RS HAL واگذار شده است. HAL بااستفاده از تابع rsContextCreateVendor() با نام درایور برای استفاده بهعنوان آرگومان، به چارچوب RS بازمیگردد. سپس چارچوب RS درایور مشخصشده را هنگام
راهاندازی RsContext بار میکند. در این مورد، کتابخانه درایور در فضای نام rs بار میشود زیرا شیء RsContext
در فضای نام rs ایجاد شده است و /vendor/lib در مسیر جستجوی فضای نام قرار دارد.
شکل ۴. مسیر عقبگرد GPU.
هنگام انتقال از فضای نام default به فضای نام sphal، libhidltransport.so از تابع android_load_sphal_library() برای مرتب کردن صریح پیونددهنده پویا برای بار کردن کتابخانه -impl.so از فضای نام sphal استفاده میکند.
هنگام انتقال از فضای نام sphal به فضای نام rs، بار کردن بهطور غیرمستقیم با خط زیر در /system/etc/ld.config.txt انجام میشود:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
این خط مشخص میکند که پیونددهنده پویا باید
libRS_internal.so را از فضای نام rs بار کند، وقتی که کتابخانه
نمیتواند از فضای نام sphal پیدا/بار شود (که همیشه
اینطور است چون فضای نام sphal در
/system/lib/vndk-sp که libRS_internal.so
در آن قرار دارد جستجو نمیکند). با این پیکربندی، یک فراخوانی ساده dlopen() به
libRS_internal.so برای انتقال فضای نام کافی است.
بار کردن افزایه رونوشت مخفی
bcc plugin کتابخانهای است که فروشنده ارائه کرده است و در کامپایلر
bcc بار شده است. چون bcc فرایند سیستمی در
دایرکتوری /system/bin است، کتابخانه bcc plugin را میتوان
«لایه انتزاع سختافزار SP» (یعنی لایه انتزاع سختافزار فروشنده که میتواند مستقیماً در فرایند سیستم بار شود
بدون اینکه binderized شود) درنظر گرفت. بهعنوان SP-HAL،
کتابخانه bcc-plugin:
- نمیتوان به کتابخانههای فقط چارچوب مثل
libLLVM.soپیوند داد. - فقط میتواند به کتابخانههای VNDK-SP که برای فروشنده دردسترس است پیوند دهد.
این محدودیت با بار کردن bcc plugin در
فضای نام sphal بااستفاده از تابع
android_sphal_load_library() اعمال میشود. در نسخههای قبلی
Android، نام افزایه بااستفاده از گزینه -load مشخص میشد و
کتابخانه بااستفاده از dlopen() ساده توسط
libLLVM.so بار میشد. در Android نسخه ۸.۰ و بالاتر، این مورد در گزینه -plugin مشخص شده است و کتابخانه مستقیماً توسط خود bcc بار میشود. این گزینه مسیر غیرخاص Android را به پروژه متنباز LLVM فعال میکند.
شکل ۵. درحال بار کردن افزایه bcc، Android نسخه ۷.x و پایینتر.
شکل ۶. درحال بار کردن افزایه bcc، Android نسخه ۸.۰ و بالاتر.
مسیرهای جستجو برای ld.mc
هنگام اجرای ld.mc، برخیاز کتابخانههای زمان اجرای RS بهعنوان ورودی به پیونددهنده داده میشوند. کدبیت RS از برنامه دربرابر کتابخانههای زمان اجرا پیوند داده میشود
و وقتی کدبیت تبدیلشده در فرایند برنامه بار میشود، کتابخانههای زمان اجرا
دوباره بهصورت پویا از کدبیت تبدیلشده پیوند داده میشوند.
کتابخانههای زمان اجرا شامل این موارد است:
libcompiler_rt.solibm.solibc.so- درایور RS (
libRSDriver.soیاOVERRIDE_RS_DRIVER)
هنگام بار کردن کدبیت کامپایلشده در فرایند برنامه، دقیقاً همان کتابخانهای را که ld.mc استفاده کرده است ارائه دهید. درغیراینصورت، کدبیت کامپایلشده
ممکن است نمادی را که هنگام پیوند دردسترس بوده است پیدا نکند.
برای انجام این کار، چارچوب RS هنگام اجرای ld.mc از مسیرهای جستجوی مختلفی برای کتابخانههای زمان اجرا استفاده میکند، بسته به اینکه خود چارچوب RS از /system/lib یا از /system/lib/vndk-sp بارگیری شده باشد.
این کار را میتوان با خواندن نشانی نماد دلخواه کتابخانه چارچوب RS
و استفاده از dladdr() برای دریافت مسیر فایل نگاشتشده به
نشانی تعیین کرد.
خطمشی SELinux
در نتیجه تغییرات خطمشی SELinux در Android 8.0 و بالاتر، باید هنگام
برچسبگذاری فایلهای اضافی در پارتیشن vendor، از قوانین خاصی (اجراشده ازطریق neverallows) پیروی کنید:
vendor_fileباید برچسب پیشفرض برای همه فایلها در پارتیشنvendorباشد. خطمشی پلاتفرم برای دسترسی به پیادهسازیهای HAL عبوردهنده به این مورد نیاز دارد.- همه
exec_typesجدید اضافهشده در پارتیشنvendorازطریق SEPolicy فروشنده باید دارای مشخصهvendor_file_typeباشد. این امر ازطریقneverallowsاجرا میشود. - برای جلوگیری از تداخل با بهروزرسانیهای آینده پلاتفرم/چارچوب، از برچسبگذاری
فایلهای غیر
exec_typesدر پارتیشنvendorخودداری کنید. - همه وابستگیهای کتابخانه برای HALهای فرایند یکسان شناساییشده توسط AOSP باید
با
same_process_hal_fileبرچسبگذاری شوند.
برای جزئیات مربوط به خطمشی SELinux، به Security-Enhanced Linux در Android مراجعه کنید.
سازگاری ABI برای بیتکد
اگر میانای برنامهسازی کاربردی جدیدی اضافه نشود، یعنی نسخه HAL ارتقا پیدا نکند، چارچوبهای RS به استفاده از درایور GPU (HAL 1.0) موجود ادامه خواهند داد.
برای تغییرات جزئی HAL (HAL 1.1) که بر بیتکد تأثیر نمیگذارند، چارچوبها باید برای این میاناهای برنامهسازی کاربردی جدیداً اضافهشده به CPU بازگردند و به استفاده از درایور GPU (HAL 1.0) در جاهای دیگر ادامه دهند.
برای تغییرات عمده HAL (HAL 2.0) که بر ترجمه/پیوند کدبیت تأثیر میگذارند، چارچوبهای RS باید انتخاب کنند که درایورهای GPU ارائهشده توسط فروشنده را بارگیری نکنند و درعوض از مسیر CPU یا Vulkan برای شتابدهی استفاده کنند.
مصرف کدبیت RenderScript در سه مرحله انجام میشود:
| صحنه | جزئیات |
|---|---|
| کامپایل کردن |
|
| پیوند |
|
| بار کردن |
|
علاوهبر HAL، میاناهای برنامهسازی کاربردی زمان اجرا و نشانهای صادرشده نیز واسط هستند. هیچیک از این میانها از زمان Android 7.0 (API 24) تغییر نکرده است و هیچ برنامه فوریای برای تغییر آن در Android 8.0 و نسخههای بالاتر وجود ندارد. بااینحال، اگر میانای تغییر کند، نسخه HAL نیز افزایش مییابد.
پیادهسازیهای ارائهدهنده
Android نسخه ۸.۰ و بالاتر برای اینکه درایور «واحد پردازش گرافیکی» بهدرستی کار کند، به تغییراتی در درایور «واحد پردازش گرافیکی» نیاز دارد.
پیمانههای درایور
- واحدهای راهانداز نباید به هیچیک از کتابخانههای سیستمی که در فهرست نیستند وابسته باشند.
- Driver باید
android.hardware.renderscript@1.0-impl_{NAME}خودش را ارائه دهد، یا پیادهسازی پیشفرضandroid.hardware.renderscript@1.0-implرا بهعنوان وابستگیاش اعلام کند. - پیادهسازی CPU
libRSDriver.soنمونه خوبی از نحوه برداشتن وابستگیهای غیر VNDK-SP است.
گردآورنده بیتکد
میتوانید کد شیء RenderScript را برای درایور فروشنده به دو روش کامپایل کنید:
- فراخوانی کامپایلر RenderScript مختص فروشنده در
/vendor/bin/(روش ترجیحی کامپایل GPU). مشابه با دیگر واحدهای درایور، باینری گردآورنده فروشنده نمیتواند به هیچ کتابخانه سیستمی که در فهرست کتابخانههای RenderScript دردسترس فروشندگان نیست وابسته باشد. - bcc سیستم را با
/system/bin/bccکه توسط فروشنده ارائه شده است فراخوانی کنید؛bcc plugin؛ این افزایه نمیتواند به هیچ کتابخانه سیستمی که در فهرست کتابخانههای RenderScript دردسترس فروشندگان نیست وابسته باشد.
اگر فروشنده bcc plugin نیاز دارد در تدوین CPU مداخله کند
و وابستگی آن به libLLVM.so بهراحتی قابلحذف نیست،
فروشنده باید bcc (و همه وابستگیهای غیر LL-NDK،
ازجمله libLLVM.so، libbcc.so) را در
بخش /vendor کپی کند.
علاوهبراین، فروشندگان باید تغییرات زیر را انجام دهند:
شکل ۷. تغییرات در درایور فروشنده.
-
libclcore.bcرا در پارتیشن/vendorکپی کنید. این کار باعث میشودlibclcore.bc،libLLVM.so، وlibbcc.soهمگامسازی شوند. - با تنظیم
RsdCpuScriptImpl::BCC_EXE_PATHاز پیادهسازی RS HAL، مسیر فایل اجراییbccرا تغییر دهید.
خطمشی SELinux
خطمشی SELinux هم بر درایور و هم بر فایلهای اجرایی کامپایلر تأثیر میگذارد. همه
واحدهای راهانداز باید در
file_contexts دستگاه با برچسب same_process_hal_file مشخص شوند. برای مثال:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
برنامه اجرایی کامپایلر باید بتواند توسط فرایند برنامه فراخوانی شود، همانطور که نسخه فروشنده bcc (/vendor/bin/bcc) میتواند. برای مثال:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
دستگاههای قدیمی
دستگاههای قدیمی دستگاههایی هستند که شرایط زیر را برآورده میکنند:
- PRODUCT_SHIPPING_API_LEVEL کمتر از ۲۶ است.
- PRODUCT_FULL_TREBLE_OVERRIDE تعریف نشده است.
برای دستگاههای قدیمی، محدودیتها هنگام ارتقا به
Android 8.0 و بالاتر اعمال نمیشوند، یعنی درایورها میتوانند همچنان به کتابخانهها
در /system/lib[64] پیوند دهند. بااینحال، بهدلیل تغییر معماری
مربوط به OVERRIDE_RS_DRIVER،
android.hardware.renderscript@1.0-impl باید در
بخش /vendor نصب شود؛ درغیراینصورت، زمان اجرای RenderScript
مجبور میشود به مسیر CPU برگردد.
برای اطلاعات درباره انگیزه منسوخ شدن Renderscript، به «وبلاگ توسعهدهندگان Android» مراجعه کنید: محاسبه واحد پردازش گرافیکی Android در آینده. اطلاعات منبع برای این منسوخسازی شامل موارد زیر است:
- انتقال از Renderscript
- نمونه انتقال RenderScript
- README Intrinsics Replacement Toolkit
- جایگزینی ذاتیToolkit.kt