RenderScript چارچوبی برای اجرای وظایف محاسباتی فشرده با کارایی بالا در اندروید است. این چارچوب برای استفاده با محاسبات موازی داده طراحی شده است، اگرچه بارهای کاری سریالی نیز میتوانند از آن بهرهمند شوند. زمان اجرای RenderScript، کار را در پردازندههای موجود در یک دستگاه، مانند CPUهای چند هستهای و GPUها، موازی میکند و به توسعهدهندگان این امکان را میدهد که به جای برنامهریزی کار، بر بیان الگوریتمها تمرکز کنند. RenderScript به ویژه برای برنامههایی که پردازش تصویر، عکاسی محاسباتی یا بینایی کامپیوتر انجام میدهند، مفید است.
دستگاههایی که اندروید ۸.۰ و بالاتر را اجرا میکنند از چارچوب RenderScript و HALهای فروشندگان زیر استفاده میکنند:

شکل ۱. کد فروشنده که به کتابخانههای داخلی لینک میشود.
تفاوتهای RenderScript در اندروید ۷.x و پایینتر شامل موارد زیر است:
- دو نمونه از کتابخانههای داخلی RenderScript در یک فرآیند. یک مجموعه برای مسیر جایگزین CPU است و مستقیماً از
/system/libمیآید؛ مجموعه دیگر برای مسیر GPU است و از/system/lib/vndk-spمیآید. - کتابخانههای داخلی RS در
/system/libبه عنوان بخشی از پلتفرم ساخته شدهاند و با ارتقاءsystem.imgبهروزرسانی میشوند. با این حال، کتابخانههای موجود در/system/lib/vndk-spبرای فروشنده ساخته شدهاند و با ارتقاءsystem.imgبهروزرسانی نمیشوند (در حالی که میتوانند برای رفع مشکل امنیتی بهروزرسانی شوند، ABI آنها ثابت میماند). - کد فروشنده (RS HAL، درایور RS و
bcc plugin) به کتابخانههای داخلی RenderScript واقع در/system/lib/vndk-spمتصل هستند. آنها نمیتوانند به کتابخانههای موجود در/system/libمتصل شوند زیرا کتابخانههای موجود در آن دایرکتوری برای پلتفرم ساخته شدهاند و بنابراین ممکن است با کد فروشنده سازگار نباشند (یعنی ممکن است نمادها حذف شوند). انجام این کار، OTA فقط برای چارچوب را غیرممکن میکند.
طراحی
بخشهای بعدی جزئیات طراحی RenderScript را در اندروید ۸.۰ و بالاتر شرح میدهند.
کتابخانههای RenderScript در دسترس فروشندگان
این بخش، کتابخانههای RenderScript (که به عنوان Vendor NDK برای HALهای Same-Process یا VNDK-SP شناخته میشوند) را که برای کد فروشنده در دسترس هستند و میتوانند به آنها لینک شوند، فهرست میکند. همچنین جزئیات کتابخانههای اضافی که به RenderScript مرتبط نیستند اما برای کد فروشنده نیز ارائه شدهاند را شرح میدهد.
اگرچه لیست کتابخانههای زیر ممکن است بین نسخههای اندروید متفاوت باشد، اما برای یک نسخه خاص اندروید تغییرناپذیر است؛ برای مشاهده لیست بهروز کتابخانههای موجود، به /system/etc/ld.config.txt مراجعه کنید.
| کتابخانههای رندراسکریپت | کتابخانههای غیر RenderScript |
|---|---|
|
|
پیکربندی فضای نام لینکر
محدودیت پیوند که مانع از استفاده کتابخانههایی که در VNDK-SP نیستند توسط کد فروشنده میشود، در زمان اجرا با استفاده از فضای نام پیونددهنده اعمال میشود. (برای جزئیات بیشتر، به ارائه طراحی VNDK مراجعه کنید.)
در دستگاهی که اندروید ۸.۰ و بالاتر را اجرا میکند، همه HALهای Same-Process (SP-HAL) به جز RenderScript در فضای نام linker sphal بارگذاری میشوند. RenderScript در فضای نام مختص RenderScript به نام rs بارگذاری میشود، مکانی که اجرای کمی آسانتر کتابخانههای RenderScript را امکانپذیر میکند. از آنجا که پیادهسازی RS نیاز به بارگذاری کد بیتی کامپایل شده دارد، /data/*/*.so به مسیر فضای نام rs اضافه میشود (سایر SP-HALها مجاز به بارگذاری کتابخانهها از پارتیشن داده نیستند).
علاوه بر این، فضای نام rs نسبت به سایر فضاهای نام، کتابخانههای بیشتری را در خود جای میدهد. libmediandk.so و libft2.so در معرض فضای نام rs قرار دارند زیرا libRS_internal.so به این کتابخانهها وابستگی داخلی دارد.

شکل ۲. پیکربندی فضای نام برای لینکر.
درایورهای بار
مسیر جایگزین CPU
بسته به وجود بیت RS_CONTEXT_LOW_LATENCY هنگام ایجاد یک زمینه RS، مسیر CPU یا GPU انتخاب میشود. وقتی مسیر CPU انتخاب میشود، libRS_internal.so (پیادهسازی اصلی چارچوب RS) مستقیماً از فضای نام پیشفرض لینکر که نسخه پلتفرم کتابخانههای RS در آن ارائه شده است، dlopen میشود.
پیادهسازی RS HAL از فروشنده، هنگام انتخاب مسیر جایگزین CPU، به هیچ وجه مورد استفاده قرار نمیگیرد و یک شیء RsContext با مقدار null mVendorDriverName ایجاد میشود. libRSDriver.so (به طور پیشفرض) dlopen و lib درایور از فضای نام default بارگذاری میشود، زیرا فراخوانیکننده ( libRS_internal.so ) نیز در فضای نام default بارگذاری شده است.

شکل ۳. مسیر جایگزین CPU.
مسیر پردازنده گرافیکی
برای مسیر 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، libRS_internal.so را در یک فضای نام پیوند دهنده دیگر به نام rs dlopen .
فروشندگان میتوانند با تنظیم پرچم زمان ساخت OVERRIDE_RS_DRIVER که در پیادهسازی RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp ) تعبیه شده است، درایور RS خود را ارائه دهند. سپس نام این درایور برای RS context مربوط به مسیر 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 بارگذاری کند، زمانی که lib از فضای نام sphal پیدا/بارگذاری نشود (که همیشه همینطور است زیرا فضای نام sphal مسیر /system/lib/vndk-sp را که libRS_internal.so در آن قرار دارد، جستجو نمیکند). با این پیکربندی، یک فراخوانی ساده dlopen() به libRS_internal.so برای انجام انتقال فضای نام کافی است.
بارگذاری افزونه bcc
bcc plugin یک کتابخانه ارائه شده توسط فروشنده است که در کامپایلر bcc بارگذاری میشود. از آنجا که bcc یک فرآیند سیستمی در دایرکتوری /system/bin است، کتابخانه bcc plugin را میتوان یک SP-HAL در نظر گرفت (یعنی، یک HAL فروشنده که میتواند مستقیماً بدون اتصال به فرآیند سیستم بارگذاری شود). به عنوان یک SP-HAL، کتابخانه bcc-plugin :
- نمیتوان به کتابخانههای صرفاً چارچوبی مانند
libLLVM.soپیوند داد. - فقط میتواند به کتابخانههای VNDK-SP موجود برای فروشنده پیوند برقرار کند.
این محدودیت با بارگذاری bcc plugin در فضای نام sphal با استفاده از تابع android_sphal_load_library() اعمال میشود. در نسخههای قبلی اندروید، نام افزونه با استفاده از گزینه -load مشخص میشد و کتابخانه با استفاده از dlopen() ساده توسط libLLVM.so بارگذاری میشد. در اندروید ۸.۰ و بالاتر، این مورد در گزینه -plugin مشخص شده و کتابخانه مستقیماً توسط خود bcc بارگذاری میشود. این گزینه یک مسیر غیر مختص اندروید را به پروژه متنباز LLVM فعال میکند.

شکل ۵. بارگذاری افزونهی bcc، اندروید ۷.x و پایینتر.

شکل ۶. بارگذاری افزونهی bcc، اندروید ۸.۰ و بالاتر.
مسیرهای جستجو برای ld.mc
هنگام اجرای ld.mc ، برخی از کتابخانههای زمان اجرا RS به عنوان ورودی به لینکر داده میشوند. بیتکد RS از برنامه به کتابخانههای زمان اجرا لینک میشود و هنگامی که بیتکد تبدیلشده در یک فرآیند برنامه بارگذاری میشود، کتابخانههای زمان اجرا دوباره به صورت پویا از بیتکد تبدیلشده لینک میشوند.
کتابخانههای زمان اجرا شامل موارد زیر هستند:
-
libcompiler_rt.so -
libm.so -
libc.so - درایور RS (یا
libRSDriver.soیاOVERRIDE_RS_DRIVER)
هنگام بارگذاری کد بیتی کامپایل شده در فرآیند برنامه، دقیقاً همان کتابخانهای را که توسط ld.mc استفاده شده است، ارائه دهید. در غیر این صورت، کد بیتی کامپایل شده ممکن است نمادی را که هنگام پیوند در دسترس بوده است، پیدا نکند.
برای انجام این کار، چارچوب RS هنگام اجرای ld.mc از مسیرهای جستجوی متفاوتی برای کتابخانههای زمان اجرا استفاده میکند، بسته به اینکه آیا خود چارچوب RS از /system/lib یا از /system/lib/vndk-sp بارگذاری شده است. این را میتوان با خواندن آدرس یک نماد دلخواه از یک کتابخانه چارچوب RS و استفاده از dladdr() برای دریافت مسیر فایل نگاشت شده به آن آدرس تعیین کرد.
سیاست SELinux
در نتیجه تغییرات سیاست SELinux در اندروید ۸.۰ و بالاتر، هنگام برچسبگذاری فایلهای اضافی در پارتیشن vendor ، باید قوانین خاصی را رعایت کنید (که از طریق neverallows اعمال میشوند):
-
vendor_fileباید برچسب پیشفرض برای همه فایلهای موجود در پارتیشنvendorباشد. سیاست پلتفرم برای دسترسی به پیادهسازیهای HAL عبوری، این را الزامی میکند. - تمام
exec_typesجدید اضافه شده در پارتیشنvendorاز طریق vendor SEPolicy باید دارای ویژگیvendor_file_typeباشند. این امر از طریقneverallowsاعمال میشود. - برای جلوگیری از تداخل با بهروزرسانیهای آتی پلتفرم/فریمورک، از برچسبگذاری فایلهایی غیر از
exec_typesدر پارتیشنvendorخودداری کنید. - تمام وابستگیهای کتابخانهای برای HALهای فرآیند یکسان شناساییشده توسط AOSP باید با برچسب
same_process_hal_fileمشخص شوند.
برای جزئیات بیشتر در مورد سیاست SELinux، به بخش «لینوکس با امنیت بهبود یافته در اندروید» مراجعه کنید.
سازگاری ABI برای بیتکد
اگر هیچ API جدیدی اضافه نشود، که به معنای عدم تغییر نسخه HAL است، فریمورکهای RS به استفاده از درایور GPU موجود (HAL 1.0) ادامه خواهند داد.
برای تغییرات جزئی HAL (HAL 1.1) که روی بیتکد تأثیری ندارند، چارچوبها باید برای این APIهای تازه اضافه شده به CPU رجوع کنند و در جای دیگر از درایور GPU (HAL 1.0) استفاده کنند.
برای تغییرات عمده HAL (HAL 2.0) که بر کامپایل/لینک کردن بیتکد تأثیر میگذارند، چارچوبهای RS باید درایورهای GPU ارائه شده توسط فروشنده را بارگیری نکنند و در عوض از مسیر CPU یا Vulkan برای شتابدهی استفاده کنند.
مصرف بیتکد RenderScript در سه مرحله رخ میدهد:
| صحنه | جزئیات |
|---|---|
| کامپایل |
|
| پیوند |
|
| بار |
|
علاوه بر HAL، APIهای زمان اجرا و نمادهای صادر شده نیز رابط هستند. هیچ یک از رابطها از اندروید ۷.۰ (API 24) تغییر نکردهاند و هیچ برنامه فوری برای تغییر آن در اندروید ۸.۰ و بالاتر وجود ندارد. با این حال، اگر رابط تغییر کند، نسخه HAL نیز افزایش مییابد.
پیادهسازیهای فروشنده
اندروید ۸.۰ و بالاتر برای عملکرد صحیح درایور GPU نیاز به تغییراتی در درایور GPU دارد.
ماژولهای درایور
- ماژولهای درایور نباید به هیچ کتابخانه سیستمی که در لیست نیستند، وابسته باشند.
- درایور باید
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 تعریف نشده است.
برای دستگاههای قدیمی، این محدودیتها هنگام ارتقا به اندروید ۸.۰ و بالاتر اعمال نمیشوند، به این معنی که درایورها میتوانند به کتابخانههای موجود در /system/lib[64] لینک شوند. با این حال، به دلیل تغییر معماری مربوط به OVERRIDE_RS_DRIVER ، android.hardware.renderscript@1.0-impl باید در پارتیشن /vendor نصب شود. عدم انجام این کار، باعث میشود که زمان اجرای RenderScript به مسیر CPU بازگردد.
برای اطلاعات بیشتر در مورد انگیزهی منسوخ شدن Renderscript، به وبلاگ توسعهدهندگان اندروید با عنوان « محاسبات پردازندهی گرافیکی اندروید در مسیر پیشرفت» مراجعه کنید. اطلاعات منبع برای این منسوخ شدن شامل موارد زیر است:
- مهاجرت از رندراسکریپت
- نمونه مهاجرت RenderScript
- راهنمای ابزار جایگزینی ذاتی
- ابزار جایگزینی ذاتی.kt