RenderScript هو إطار عمل لتنفيذ المهام التي تتطلّب قدرًا كبيرًا من العمليات الحسابية بأداء عالٍ على نظام التشغيل Android. وهي مصمَّمة للاستخدام مع الحوسبة المتوازية للبيانات، على الرغم من أنّ أحجام العمل التسلسلية يمكن أن تستفيد منها أيضًا. تعمل بيئة تشغيل RenderScript على تقسيم العمل بالتوازي على مستوى المعالِجات المتاحة على الجهاز، مثل وحدات المعالجة المركزية (CPU) ووحدات معالجة الرسومات (GPU) المتعددة النواة، ما يتيح للمطوّرين التركيز على التعبير عن الخوارزميات بدلاً من جدولة العمل. تكون RenderScript مفيدة بشكل خاص للتطبيقات التي تنفّذ عمليات معالجة الصور أو التصوير الحاسوبي أو رؤية الكمبيوتر.
تستخدم الأجهزة التي تعمل بالإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث إطار عمل RenderScript وHALs الخاصة بالمورّد على النحو التالي:
الشكل 1: رمز المورّد الذي يرتبط بالمكتبات الداخلية
تشمل الاختلافات عن RenderScript في الإصدار 7.x من نظام التشغيل Android والإصدارات الأقدم ما يلي:
- مثيلان من مكتبات 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 في نظام التشغيل Android 8.0 والإصدارات الأحدث.
مكتبات RenderScript المتاحة للمورّدين
يسرد هذا القسم مكتبات RenderScript (المعروفة باسم Vendor NDK for Same-Process HALs أو VNDK-SP) المتاحة لرمز المورّد والتي يمكن ربطها. ويوضّح أيضًا المكتبات الإضافية غير المرتبطة بـ RenderScript، ولكن يتم توفيرها أيضًا لرمز المورّد.
على الرغم من أنّ قائمة المكتبات التالية قد تختلف بين إصدارات Android،
إلا أنّها ثابتة لإصدار Android محدّد. وللاطّلاع على قائمة حديثة بالمكتبات
المتاحة، يُرجى الرجوع إلى /system/etc/ld.config.txt.
| RenderScript Libs | Non-RenderScript Libs |
|---|---|
|
|
إعداد مساحة اسم أداة الربط
يتم فرض قيود الربط التي تمنع استخدام المكتبات غير المتوفّرة في VNDK-SP من خلال رمز المورّد في وقت التشغيل باستخدام مساحة اسم الرابط. (لمزيد من التفاصيل، يُرجى الرجوع إلى عرض تصميم VNDK التقديمي).
على جهاز يعمل بالإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، يتم تحميل جميع وحدات HAL التي تعمل في العملية نفسها (SP-HAL)
باستثناء RenderScript داخل مساحة الاسم الخاصة برابط البرنامج
sphal. يتم تحميل RenderScript في مساحة الاسم rs الخاصة بـ RenderScript، وهو موقع جغرافي يتيح تطبيقًا أقل صرامة قليلاً لمكتبات RenderScript. بما أنّ عملية تنفيذ RS تتطلّب تحميل رمز البايت المجمَّع، تتم إضافة /data/*/*.so إلى مسار مساحة الاسم rs (لا يُسمح لطبقات SP-HAL الأخرى بتحميل المكتبات من قسم البيانات).
بالإضافة إلى ذلك، تتيح مساحة الاسم rs استخدام عدد أكبر من المكتبات مقارنةً بمساحات الأسماء الأخرى. يتم عرض libmediandk.so وlibft2.so في مساحة الاسم rs لأنّ libRS_internal.so لديها تبعية داخلية لهاتين المكتبتين.
الشكل 2: إعداد مساحة الاسم الخاصة بأداة الربط
تحميل برامج التشغيل
مسار احتياطي لوحدة المعالجة المركزية
اعتمادًا على وجود وحدة البت RS_CONTEXT_LOW_LATENCY عند إنشاء سياق RS، يتم اختيار مسار وحدة المعالجة المركزية أو وحدة معالجة الرسومات. عند اختيار مسار وحدة المعالجة المركزية، يتم dlopen libRS_internal.so (التنفيذ الرئيسي لإطار عمل RS) مباشرةً من مساحة الاسم التلقائية الخاصة ببرنامج الربط حيث يتم توفير إصدار النظام الأساسي من مكتبات RS.
لا يتم استخدام تنفيذ RS HAL من المورّد على الإطلاق عند اتّخاذ مسار الاحتياطي لوحدة المعالجة المركزية (CPU) < 0x0A، ويتم إنشاء كائن RsContext بقيمة فارغة mVendorDriverName. يتم dlopen libRSDriver.so (تلقائيًا) ويتم تحميل مكتبة برنامج التشغيل من مساحة الاسم default لأنّ برنامج الاتصال (libRS_internal.so) يتم تحميله أيضًا في مساحة الاسم default.
الشكل 3: مسار احتياطي لوحدة المعالجة المركزية (CPU)
مسار وحدة معالجة الرسومات
بالنسبة إلى مسار وحدة معالجة الرسومات، يتم تحميل libRS_internal.so بشكل مختلف.
أولاً، تستخدم libRS.so
android.hardware.renderscript@1.0.so (وlibhidltransport.so الأساسي)
لتحميل
android.hardware.renderscript@1.0-impl.so (تنفيذ المورّد
لـ RS HAL) في مساحة اسم رابط مختلفة تُسمى
sphal. يتم بعد ذلك dlopen libRS_internal.so في مساحة اسم أخرى خاصة بالرابط تسمى rs.
يمكن للمورّدين توفير برنامج تشغيل RS الخاص بهم من خلال ضبط علامة مدّة التصميم OVERRIDE_RS_DRIVER، والتي يتم تضمينها في تنفيذ طبقة تجريد الأجهزة (HAL) لـ RS
(hardware/interfaces/renderscript/1.0/default/Context.cpp). ثم يتم dlopen اسم برنامج التشغيل هذا لسياق RS لمسار وحدة معالجة الرسومات.
يتم تفويض إنشاء العنصر RsContext إلى عملية تنفيذ RS HAL. يطلب HAL من إطار عمل RS معاودة الاتصال باستخدام الدالة rsContextCreateVendor() مع اسم برنامج التشغيل المطلوب استخدامه كوسيطة. بعد ذلك، يحمّل إطار عمل RS برنامج التشغيل المحدّد عند تهيئة RsContext. في هذه الحالة، يتم تحميل مكتبة برنامج التشغيل في مساحة الاسم rs لأنّه يتم إنشاء العنصر RsContext داخل مساحة الاسم rs، ويكون /vendor/lib في مسار البحث الخاص بمساحة الاسم.
الشكل 4. مسار احتياطي لوحدة معالجة الرسومات
عند الانتقال من مساحة الاسم 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
bcc plugin هي مكتبة يوفّرها المورّد ويتم تحميلها في برنامج الترجمة البرمجية bcc. بما أنّ bcc هي عملية نظام في الدليل /system/bin، يمكن اعتبار مكتبة bcc plugin SP-HAL (أي HAL خاص بالمورّد يمكن تحميله مباشرةً في عملية النظام بدون تحويله إلى Binder). بصفتها طبقة تجريد أجهزة خاصة بمزوّد الخدمة، تتضمّن مكتبة bcc-plugin ما يلي:
- لا يمكن الربط بمكتبات مخصّصة للأُطر فقط، مثل
libLLVM.so. - يمكن الربط فقط بمكتبات VNDK-SP المتاحة للمورّد.
يتم فرض هذا القيد من خلال تحميل bcc plugin في مساحة الاسم sphal باستخدام الدالة android_sphal_load_library(). في إصدارات Android السابقة، كان يتم تحديد اسم المكوّن الإضافي باستخدام الخيار -load، وكان يتم تحميل المكتبة باستخدام dlopen() البسيط من خلال libLLVM.so. في نظام التشغيل Android 8.0 والإصدارات الأحدث، يتم تحديد ذلك في الخيار -plugin ويتم تحميل المكتبة مباشرةً من خلال bcc نفسه. يتيح هذا الخيار مسارًا غير خاص بنظام Android إلى مشروع LLVM المفتوح المصدر.
الشكل 5. جارٍ تحميل المكوّن الإضافي bcc على الإصدار 7.x من نظام التشغيل Android والإصدارات الأقدم.
الشكل 6. تحميل المكوّن الإضافي bcc على الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث
البحث عن مسارات ld.mc
عند تنفيذ ld.mc، يتم تقديم بعض مكتبات وقت التشغيل الخاصة بـ RS كمدخلات إلى أداة الربط. يتم ربط رمز RS الثنائي من التطبيق بمكتبات وقت التشغيل، وعندما يتم تحميل الرمز الثنائي المحوَّل في عملية التطبيق، يتم ربط مكتبات وقت التشغيل مرة أخرى بشكل ديناميكي من الرمز الثنائي المحوَّل.
تشمل مكتبات وقت التشغيل ما يلي:
libcompiler_rt.solibm.solibc.so- برنامج تشغيل RS (إما
libRSDriver.soأوOVERRIDE_RS_DRIVER)
عند تحميل رمز bitcode المجمَّع في عملية التطبيق، يجب توفير المكتبة نفسها التي استخدمتها ld.mc. وبخلاف ذلك، قد لا يعثر رمز البت المجمَّع على رمز كان متاحًا عند ربطه.
ولإجراء ذلك، يستخدم إطار عمل RS مسارات بحث مختلفة لمكتبات وقت التشغيل عند تنفيذ ld.mc، وذلك استنادًا إلى ما إذا كان إطار عمل RS نفسه يتم تحميله من /system/lib أو من /system/lib/vndk-sp.
يمكن تحديد ذلك من خلال قراءة عنوان رمز عشوائي لمكتبة إطار عمل RS
واستخدام dladdr() للحصول على مسار الملف المرتبط
بالعنوان.
سياسة SELinux
نتيجةً للتغييرات التي طرأت على سياسة SELinux في الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، عليك اتّباع قواعد معيّنة (يتم فرضها من خلال neverallows) عند تصنيف ملفات إضافية في قسم vendor:
- يجب أن يكون
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 في استخدام برنامج تشغيل وحدة معالجة الرسومات الحالية (HAL 1.0).
بالنسبة إلى التغييرات الطفيفة في طبقة تجريد الأجهزة (HAL 1.1) التي لا تؤثّر في رمز bitcode، يجب أن تعود الأُطر إلى وحدة المعالجة المركزية (CPU) لواجهات برمجة التطبيقات المضافة حديثًا هذه، وأن تواصل استخدام برنامج تشغيل وحدة معالجة الرسومات (GPU) (HAL 1.0) في أماكن أخرى.
بالنسبة إلى التغييرات الرئيسية في طبقة تجريد الأجهزة (HAL 2.0) التي تؤثر في تجميع/ربط رمز البايت، يجب ألا تختار أُطر RS تحميل برامج تشغيل وحدة معالجة الرسومات التي يوفّرها المورّد، وأن تستخدم بدلاً من ذلك مسار وحدة المعالجة المركزية أو Vulkan للتسريع.
يتم استهلاك رمز بت RenderScript على ثلاث مراحل:
| مسرح | التفاصيل |
|---|---|
| تجميع |
|
| الرابط |
|
| التحميل |
|
بالإضافة إلى طبقة تجريد الأجهزة، فإنّ واجهات برمجة التطبيقات لوقت التشغيل والرموز التي تم تصديرها هي أيضًا واجهات. لم يتغيّر أي من هذين العنصرين منذ الإصدار 7.0 من نظام التشغيل Android (المستوى 24 من واجهة برمجة التطبيقات)، ولا توجد خطط فورية لتغييرهما في الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث. ومع ذلك، إذا تغيّرت الواجهة، سيتم أيضًا زيادة رقم إصدار HAL.
عمليات تنفيذ المورّدين
يتطلّب الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث إجراء بعض التغييرات على برنامج تشغيل وحدة معالجة الرسومات ليعمل بشكل سليم.
وحدات برامج التشغيل
- يجب ألا تعتمد وحدات برامج التشغيل على أي مكتبات نظام غير مضمّنة في القائمة.
- يجب أن يوفّر برنامج التشغيل
android.hardware.renderscript@1.0-impl_{NAME}الخاص به، أو أن يعرّف التنفيذ التلقائيandroid.hardware.renderscript@1.0-implكعنصر تابع له. - يُعد تنفيذ وحدة المعالجة المركزية
libRSDriver.soمثالاً جيدًا على كيفية إزالة التبعيات غير التابعة لمجموعة VNDK-SP.
برنامج تجميع رمز بت
يمكنك تجميع رمز RenderScript الثنائي لبرنامج التشغيل الخاص بالمورّد بطريقتَين:
- استدعاء برنامج تجميع RenderScript خاص بمورّد معيّن في
/vendor/bin/(الطريقة المفضّلة لتجميع وحدة معالجة الرسومات) على غرار وحدات برامج التشغيل الأخرى، لا يمكن أن يعتمد البرنامج الثنائي لمترجم المورّد على أي مكتبة نظام غير مدرَجة في قائمة مكتبات RenderScript المتاحة للمورّدين. - استدعاء
/system/bin/bccلنظام النسخة المخفية الوجهة باستخدامbcc pluginالمقدَّم من المورّد، ولا يمكن أن يعتمد هذا المكوّن الإضافي على أي مكتبة نظام غير مدرَجة في قائمة مكتبات RenderScript المتاحة للمورّدين
إذا كان المورّد bcc plugin بحاجة إلى التدخّل في عملية تجميع وحدة المعالجة المركزية
واعتماديتها على libLLVM.so ولا يمكن إزالتها بسهولة،
على المورّد نسخ bcc (وجميع التبعيات غير LL-NDK،
بما في ذلك libLLVM.so وlibbcc.so) إلى القسم /vendor.
بالإضافة إلى ذلك، على المورّدين إجراء التغييرات التالية:
الشكل 7. التغييرات على برنامج التشغيل الخاص بالمورِّد
- نسخ
libclcore.bcإلى القسم/vendorيضمن ذلك مزامنةlibclcore.bcوlibLLVM.soوlibbcc.so. - غيِّر مسار الملف التنفيذي
bccمن خلال ضبطRsdCpuScriptImpl::BCC_EXE_PATHمن تنفيذ RS HAL.
سياسة 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
الأجهزة القديمة
الأجهزة القديمة هي تلك التي تستوفي الشروط التالية:
- PRODUCT_SHIPPING_API_LEVEL أقل من 26.
- لم يتم تحديد PRODUCT_FULL_TREBLE_OVERRIDE.
بالنسبة إلى الأجهزة القديمة، لا يتم فرض القيود عند الترقية إلى الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، ما يعني أنّه يمكن لمشغّلات الأجهزة مواصلة الربط بالمكتبات في /system/lib[64]. ومع ذلك، بسبب تغيير بنية OVERRIDE_RS_DRIVER، يجب تثبيت android.hardware.renderscript@1.0-impl في قسم /vendor، وإلا سيتم إرجاع وقت تشغيل RenderScript إلى مسار وحدة المعالجة المركزية.
للحصول على معلومات حول سبب إيقاف Renderscript نهائيًا، راجِع مدوّنة مطوّري تطبيقات Android: مستقبل الحوسبة على وحدة معالجة الرسومات في Android. تتضمّن معلومات المرجع بشأن هذا الإيقاف النهائي ما يلي:
- نقل البيانات من Renderscript
- نموذج RenderScriptMigration
- ملف README الخاص بـ Intrinsics Replacement Toolkit
- Intrinsics ReplacementToolkit.kt