RenderScript

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

إعداد مساحة اسم أداة الربط

يتم فرض قيود الربط التي تمنع استخدام المكتبات غير المتوفّرة في 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.solibhidltransport.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.so
  • libm.so
  • libc.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 على ثلاث مراحل:

مسرح التفاصيل
تجميع
  • يجب أن يكون رمز bitcode المدخل (.bc) الخاص بـ bcc بتنسيق LLVM 3.2، ويجب أن يكون bcc متوافقًا مع الإصدارات السابقة من التطبيقات الحالية (القديمة).
  • ومع ذلك، يمكن أن تتغير البيانات الوصفية في ملف .bc (قد تظهر دوال جديدة في وقت التشغيل، مثل أدوات ضبط عمليات التخصيص وأدوات الحصول عليها، ودوال رياضية، وما إلى ذلك). يتم تخزين جزء من دوال وقت التشغيل في libclcore.bc، ويتم تخزين جزء آخر في LibRSDriver أو ما يعادله من المورّد.
  • تتطلّب الوظائف الجديدة في وقت التشغيل أو التغييرات الكبيرة في البيانات الوصفية زيادة مستوى واجهة برمجة التطبيقات لرمز Bitcode. وبما أنّ برامج تشغيل المورّد لن تتمكّن من استخدامه، يجب أيضًا زيادة رقم إصدار HAL.
  • قد يكون لدى البائعين برامج ترجمة خاصة بهم، ولكن تنطبق الاستنتاجات/المتطلبات الخاصة بـ bcc أيضًا على برامج الترجمة هذه.
الرابط
  • سيتم ربط ملف ‎.o المجمّع ببرنامج تشغيل المورّد، على سبيل المثال، libRSDriver_foo.so وlibcompiler_rt.so. سيتم ربط مسار وحدة المعالجة المركزية (CPU) بـ libRSDriver.so.
  • إذا كان الملف .o يتطلّب واجهة برمجة تطبيقات جديدة لوقت التشغيل من libRSDriver_foo، يجب تعديل برنامج التشغيل الخاص بالمورِّد ليتوافق معها.
  • قد يملك بعض المورّدين أدوات ربط خاصة بهم، ولكنّ الحجّة التي تنطبق على ld.mc تنطبق عليهم أيضًا.
التحميل
  • تحمّل libRSCpuRef العنصر المشترَك. إذا تم إجراء تغييرات على هذه الواجهة، يجب زيادة رقم إصدار HAL.
  • يمكن للمورّدين إما الاعتماد على libRSCpuRef لتحميل العنصر المشترَك، أو تنفيذ العنصر الخاص بهم.

بالإضافة إلى طبقة تجريد الأجهزة، فإنّ واجهات برمجة التطبيقات لوقت التشغيل والرموز التي تم تصديرها هي أيضًا واجهات. لم يتغيّر أي من هذين العنصرين منذ الإصدار 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 الثنائي لبرنامج التشغيل الخاص بالمورّد بطريقتَين:

  1. استدعاء برنامج تجميع RenderScript خاص بمورّد معيّن في /vendor/bin/ (الطريقة المفضّلة لتجميع وحدة معالجة الرسومات) على غرار وحدات برامج التشغيل الأخرى، لا يمكن أن يعتمد البرنامج الثنائي لمترجم المورّد على أي مكتبة نظام غير مدرَجة في قائمة مكتبات RenderScript المتاحة للمورّدين.
  2. استدعاء /system/bin/bcc لنظام النسخة المخفية الوجهة باستخدام bcc plugin المقدَّم من المورّد، ولا يمكن أن يعتمد هذا المكوّن الإضافي على أي مكتبة نظام غير مدرَجة في قائمة مكتبات RenderScript المتاحة للمورّدين

إذا كان المورّد bcc plugin بحاجة إلى التدخّل في عملية تجميع وحدة المعالجة المركزية واعتماديتها على libLLVM.so ولا يمكن إزالتها بسهولة، على المورّد نسخ bcc (وجميع التبعيات غير LL-NDK، بما في ذلك libLLVM.so وlibbcc.so) إلى القسم /vendor.

بالإضافة إلى ذلك، على المورّدين إجراء التغييرات التالية:

الشكل 7. التغييرات على برنامج التشغيل الخاص بالمورِّد

  1. نسخ libclcore.bc إلى القسم /vendor يضمن ذلك مزامنة libclcore.bc وlibLLVM.so وlibbcc.so.
  2. غيِّر مسار الملف التنفيذي 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

الأجهزة القديمة

الأجهزة القديمة هي تلك التي تستوفي الشروط التالية:

  1. PRODUCT_SHIPPING_API_LEVEL أقل من 26.
  2. لم يتم تحديد PRODUCT_FULL_TREBLE_OVERRIDE.

بالنسبة إلى الأجهزة القديمة، لا يتم فرض القيود عند الترقية إلى الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، ما يعني أنّه يمكن لمشغّلات الأجهزة مواصلة الربط بالمكتبات في /system/lib[64]. ومع ذلك، بسبب تغيير بنية OVERRIDE_RS_DRIVER، يجب تثبيت android.hardware.renderscript@1.0-impl في قسم /vendor، وإلا سيتم إرجاع وقت تشغيل RenderScript إلى مسار وحدة المعالجة المركزية.

للحصول على معلومات حول سبب إيقاف Renderscript نهائيًا، راجِع مدوّنة مطوّري تطبيقات Android: مستقبل الحوسبة على وحدة معالجة الرسومات في Android. تتضمّن معلومات المرجع بشأن هذا الإيقاف النهائي ما يلي: