Renderscript

RenderScript چارچوبی برای اجرای وظایف محاسباتی فشرده با عملکرد بالا در اندروید است. این برای استفاده با محاسبات موازی داده طراحی شده است، اگرچه بارهای کاری سریال نیز می توانند مفید باشند. زمان اجرا RenderScript کار را در بین پردازنده‌های موجود در یک دستگاه، مانند پردازنده‌های چند هسته‌ای و پردازنده‌های گرافیکی موازی می‌کند و به توسعه‌دهندگان این امکان را می‌دهد تا به جای زمان‌بندی کار، بر بیان الگوریتم‌ها تمرکز کنند. RenderScript به ویژه برای برنامه هایی که پردازش تصویر، عکاسی محاسباتی یا بینایی کامپیوتر را انجام می دهند مفید است.

دستگاه‌های دارای Android نسخه ۸.۰ و بالاتر از چارچوب RenderScript و HAL‌های فروشنده زیر استفاده می‌کنند:

شکل 1. کد فروشنده که به لیب های داخلی پیوند می دهد

تفاوت‌های RenderScript در اندروید 7.x و پایین‌تر عبارتند از:

  • دو نمونه از Libهای داخلی 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، و bcc plugin ) با لینک‌های داخلی RenderScript واقع در /system/lib/vndk-sp پیوند داده شده‌اند. آنها نمی توانند در برابر libs در /system/lib پیوند دهند، زیرا libهای موجود در آن دایرکتوری برای پلتفرم ساخته شده اند و بنابراین ممکن است با کد فروشنده سازگار نباشند (یعنی نمادها ممکن است حذف شوند). انجام این کار یک OTA فقط برای چارچوب را غیرممکن می کند.

طرح

بخش‌های زیر به جزئیات طراحی RenderScript در اندروید 8.0 و بالاتر می‌پردازند.

لیب های RenderScript در دسترس فروشندگان است

این بخش لیب های RenderScript (معروف به Vendor NDK برای HAL های فرآیندی مشابه یا VNDK-SP) که در دسترس کد فروشنده هستند و می توانند با آنها پیوند شوند را فهرست می کند. همچنین کتابخانه‌های دیگری را که به RenderScript مرتبط نیستند، اما به کد فروشنده نیز ارائه شده‌اند، شرح می‌دهد.

در حالی که فهرست کتابخانه‌های زیر ممکن است بین نسخه‌های اندروید متفاوت باشد، اما برای یک نسخه خاص اندرویدی تغییر ناپذیر است. برای لیست به روز کتابخانه های موجود، به /system/etc/ld.config.txt مراجعه کنید.

RenderScript Libs Libs غیر RenderScript
  • 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

پیکربندی فضای نام لینکر

محدودیت پیوندی که از استفاده از Libهای غیر در VNDK-SP توسط کد فروشنده جلوگیری می کند، در زمان اجرا با استفاده از فضای نام پیوند دهنده اعمال می شود. (برای جزئیات، به ارائه VNDK Design مراجعه کنید.)

در دستگاهی که Android نسخه 8.0 و بالاتر دارد، همه HAL های Same-Process (SP-HAL) به جز RenderScript در فضای نام پیوند دهنده sphal بارگیری می شوند. RenderScript در فضای نام خاص RenderScript rs بارگیری می شود، مکانی که اجرای کمی آزادتر را برای لبه های RenderScript فعال می کند. از آنجا که پیاده سازی RS نیاز به بارگذاری بیت کد کامپایل شده دارد، /data/*/*.so به مسیر فضای نام rs اضافه می شود (سایر SP-HAL ها مجاز به بارگذاری لیب ها از پارتیشن داده نیستند).

علاوه بر این، فضای نام rs امکان lib های بیشتری را نسبت به فضای نام های دیگر فراهم می کند. libmediandk.so و libft2.so در معرض فضای نام rs هستند زیرا libRS_internal.so وابستگی داخلی به این کتابخانه ها دارد.

شکل 2. پیکربندی فضای نام برای پیوند دهنده

در حال بارگیری درایورها

مسیر بازگشتی CPU

بسته به وجود بیت RS_CONTEXT_LOW_LATENCY هنگام ایجاد زمینه RS، مسیر CPU یا GPU انتخاب می شود. هنگامی که مسیر CPU انتخاب می شود، libRS_internal.so (اجرای اصلی چارچوب RS) مستقیماً از فضای نام پیوند دهنده پیش فرض که در آن نسخه پلتفرم RS libs ارائه می شود، dlopen می شود.

پیاده سازی RS HAL از فروشنده به هیچ وجه زمانی که مسیر بازگشتی CPU گرفته می شود، استفاده نمی شود و یک شی RsContext با mVendorDriverName null ایجاد می شود. libRSDriver.so (به طور پیش‌فرض) dlopen ed است و lib درایور از فضای نام default بارگیری می‌شود، زیرا تماس‌گیرنده ( libRS_internal.so ) نیز در فضای نام default بارگیری می‌شود.

شکل 4. مسیر بازگشتی CPU

مسیر پردازنده گرافیکی

برای مسیر GPU، libRS_internal.so متفاوت بارگذاری می شود. ابتدا، libRS.so از android.hardware.renderscript@1.0.solibhidltransport.so زیربنایی آن) برای بارگیری android.hardware.renderscript@1.0-impl.so (پیاده سازی فروشنده RS HAL) در فضای نام پیوند دهنده متفاوتی به نام استفاده می کند. sphal . سپس RS HAL libRS_internal.so را در فضای نام پیوند دهنده دیگری به نام rs dlopen .

فروشندگان می توانند درایور RS خود را با تنظیم پرچم زمان ساخت OVERRIDE_RS_DRIVER ، که در اجرای RS HAL تعبیه شده است ( hardware/interfaces/renderscript/1.0/default/Context.cpp ) ارائه دهند. این نام درایور سپس برای زمینه RS برای مسیر GPU dlopen شود.

ایجاد شی RsContext به پیاده سازی RS HAL واگذار می شود. HAL با استفاده از تابع rsContextCreateVendor() با نام درایور برای استفاده به عنوان آرگومان به چارچوب RS فراخوانی می کند. چارچوب RS سپس درایور مشخص شده را هنگامی که RsContext مقدار دهی اولیه می شود بارگیری می کند. در این حالت، کتابخانه درایور در فضای نام rs بارگذاری می شود زیرا شی RsContext در فضای rs ایجاد می شود و /vendor/lib در مسیر جستجوی فضای نام قرار دارد.

شکل 5. مسیر برگشتی 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 مشخص می‌شد و lib با استفاده از dlopen() ساده توسط libLLVM.so بارگذاری می‌شد. در اندروید 8.0 و بالاتر، این مورد در گزینه -plugin مشخص شده است و lib مستقیماً توسط خود bcc بارگذاری می شود. این گزینه یک مسیر غیر اختصاصی اندروید را به پروژه منبع باز LLVM فعال می کند.

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


شکل 7. بارگیری افزونه bcc، اندروید 8.0 و بالاتر

مسیرهای جستجو برای ld.mc

هنگام اجرای ld.mc ، برخی از لبه های زمان اجرا RS به عنوان ورودی به پیوند دهنده داده می شود. بیت‌کد RS از برنامه با لیب‌های زمان اجرا مرتبط می‌شود و زمانی که بیت‌کد تبدیل‌شده در یک فرآیند برنامه بارگذاری می‌شود، لیب‌های زمان اجرا دوباره به‌صورت پویا از بیت‌کد تبدیل‌شده پیوند داده می‌شوند.

فایل های زمان اجرا شامل:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • درایور RS (یا libRSDriver.so یا OVERRIDE_RS_DRIVER )

هنگام بارگیری بیت کد کامپایل شده در فرآیند برنامه، دقیقاً همان کتابخانه ای را ارائه کنید که توسط ld.mc استفاده شده است. در غیر این صورت، بیت کد کامپایل شده ممکن است نمادی را پیدا نکند که در هنگام پیوند در دسترس بوده است.

برای انجام این کار، چارچوب RS از مسیرهای جستجوی مختلفی برای lib‌های زمان اجرا هنگام اجرای 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، به Linux Enhanced Security در Android مراجعه کنید.

سازگاری ABI برای بیت کد

اگر هیچ API جدیدی اضافه نشود، به این معنی که نسخه HAL برآمده نیست، چارچوب‌های RS همچنان از درایور GPU موجود (HAL 1.0) استفاده می‌کنند.

برای تغییرات جزئی HAL (HAL 1.1) که روی بیت‌کد تأثیر نمی‌گذارد، فریم‌ورک‌ها باید به CPU برای این APIهای جدید اضافه شده برگردند و همچنان از درایور GPU (HAL 1.0) در جاهای دیگر استفاده کنند.

برای تغییرات عمده HAL (HAL 2.0) که بر کامپایل/پیوند کردن بیت‌کد تأثیر می‌گذارد، چارچوب‌های RS باید درایورهای GPU ارائه‌شده توسط فروشنده را بارگیری نکنند و در عوض از مسیر CPU یا Vulkan برای شتاب استفاده کنند.

مصرف بیت کد RenderScript در سه مرحله انجام می شود:

صحنه جزئیات
گردآوری
  • بیت‌کد ورودی (bc.) برای bcc باید در قالب بیت‌کد LLVM 3.2 باشد و bcc باید با برنامه‌های موجود (قدیمی) سازگار باشد.
  • با این حال، متا داده در .bc می تواند تغییر کند (می تواند توابع جدید زمان اجرا وجود داشته باشد، به عنوان مثال، تنظیم کننده های تخصیص ∓ گیرنده ها، توابع ریاضی، و غیره). بخشی از توابع زمان اجرا در libclcore.bc زندگی می کنند، بخشی از آنها در LibRSDriver یا معادل فروشنده زندگی می کنند.
  • توابع جدید زمان اجرا یا شکستن تغییرات متا داده نیازمند افزایش سطح API بیت کد است. از آنجا که درایورهای فروشنده قادر به مصرف آن نیستند، نسخه HAL نیز باید افزایش یابد.
  • فروشندگان ممکن است کامپایلرهای خود را داشته باشند، اما نتیجه گیری/الزامات برای bcc در مورد آن کامپایلرها نیز صدق می کند.
ارتباط دادن
  • .o کامپایل شده با درایور فروشنده، به عنوان مثال، libRSDriver_foo.so و libcompiler_rt.so مرتبط خواهد شد. مسیر CPU با libRSDriver.so مرتبط می شود.
  • اگر .o به یک API زمان اجرا جدید از libRSDriver_foo نیاز دارد، درایور فروشنده باید برای پشتیبانی از آن به روز شود.
  • برخی از فروشندگان ممکن است پیوند دهنده های خاص خود را داشته باشند، اما استدلال ld.mc در مورد آنها نیز صدق می کند.
بار
  • libRSCpuRef شی مشترک را بارگذاری می کند. اگر تغییراتی در این رابط ایجاد شود، به نسخه HAL نیاز است.
  • فروشندگان برای بارگذاری شی مشترک یا به libRSCpuRef تکیه می کنند یا شیء خود را پیاده سازی می کنند.

علاوه بر HAL، APIهای زمان اجرا و نمادهای صادر شده نیز رابط هستند. هیچ یک از این رابط ها از اندروید 7.0 (API 24) تغییر نکرده است و هیچ برنامه فوری برای تغییر آن در اندروید 8.0 و بالاتر وجود ندارد. با این حال، اگر رابط تغییر کند، نسخه HAL نیز افزایش می یابد.

پیاده سازی های فروشنده

اندروید 8.0 و بالاتر به برخی تغییرات در درایور GPU نیاز دارد تا درایور GPU به درستی کار کند.

ماژول های درایور

  • ماژول های درایور نباید به کتابخانه های سیستمی که در لیست نیستند وابسته باشند.
  • درایور باید android.hardware.renderscript@1.0-impl_{NAME} خود را ارائه دهد یا اجرای پیش‌فرض android.hardware.renderscript@1.0-impl به عنوان وابستگی خود اعلام کند.
  • پیاده سازی CPU libRSDriver.so مثال خوبی از نحوه حذف وابستگی های غیر VNDK-SP است.

کامپایلر بیت کد

شما می توانید بیت کد RenderScript را برای درایور فروشنده به دو روش کامپایل کنید:

  1. کامپایلر RenderScript خاص فروشنده را در /vendor/bin/ فراخوانی کنید (روش ترجیحی کامپایل GPU). مشابه سایر ماژول‌های درایور، باینری کامپایلر فروشنده نمی‌تواند به کتابخانه‌های سیستمی که در لیست لیب‌های RenderScript در دسترس فروشندگان نیست، وابسته باشد.
  2. سیستم bcc را فراخوانی کنید: /system/bin/bcc با bcc plugin ارائه‌شده توسط فروشنده. این افزونه نمی تواند به هیچ کتابخانه سیستمی وابسته باشد که در لیست لیب های RenderScript در دسترس فروشندگان نیست.

اگر bcc plugin فروشنده نیاز به تداخل با کامپایل CPU داشته باشد و وابستگی آن به libLLVM.so به راحتی قابل حذف نباشد، فروشنده باید bcc (و همه وابستگی های غیر LL-NDK، از جمله libLLVM.so ، libbcc.so ) را در آن کپی کند. /vendor .

علاوه بر این، فروشندگان باید تغییرات زیر را اعمال کنند:

شکل 8. تغییرات در راننده فروشنده
  1. libclcore.bc در پارتیشن /vendor کپی کنید. این تضمین می‌کند که libclcore.bc ، libLLVM.so ، و libbcc.so همگام هستند.
  2. با تنظیم RsdCpuScriptImpl::BCC_EXE_PATH از اجرای RS HAL، مسیر فایل اجرایی bcc را تغییر دهید.

خط مشی SELinux

خط مشی SELinux هم بر درایور و هم بر فایل های اجرایی کامپایلر تأثیر می گذارد. همه ماژول‌های درایور باید دارای برچسب same_process_hal_file در file_contexts دستگاه باشند. مثلا:

/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

دستگاه های قدیمی

دستگاه های قدیمی آنهایی هستند که شرایط زیر را برآورده می کنند:

  1. PRODUCT_SHIPPING_API_LEVEL کمتر از 26 است.
  2. 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 GPU Compute Going Forward . اطلاعات منابع برای این منسوخ شدن شامل موارد زیر است: