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.
  • يتم إنشاء المكتبات الداخلية لخدمة "البحث الذكي" في /system/lib كجزء من النظام الأساسي، ويتم تعديلها عند ترقية system.img. ومع ذلك، يتم إنشاء المكتبات في /system/lib/vndk-sp للبائع ولا يتم تعديلها عند ترقية system.img (مع أنّه يمكن تعديلها لإصلاح مشكلة أمان، إلا أنّ واجهة التطبيق الثنائية تظل كما هي).
  • يتم ربط رمز المورّد (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 في مساحة الاسم الخاصة بـ RenderScript rs، وهو موقع جغرافي يتيح تطبيقًا أقل صرامة لمكتبات RenderScript. بما أنّ عملية تنفيذ RS تتطلّب تحميل رمز البايت المجمَّع، تتم إضافة /data/*/*.so إلى مسار مساحة الاسم rs (لا يُسمح لواجهات SP-HAL الأخرى بتحميل المكتبات من قسم البيانات).

بالإضافة إلى ذلك، تتيح مساحة الاسم rs استخدام عدد أكبر من المكتبات مقارنةً بمساحات الأسماء الأخرى. يتم عرض libmediandk.so وlibft2.so في مساحة الاسم rs لأنّ libRS_internal.so لديها تبعية داخلية لهذه المكتبات.

الشكل 2. إعداد مساحة الاسم الخاصة بأداة الربط

تحميل برامج التشغيل

مسار احتياطي لوحدة المعالجة المركزية

اعتمادًا على وجود البت RS_CONTEXT_LOW_LATENCY عند إنشاء سياق RS، يتم اختيار مسار وحدة المعالجة المركزية أو وحدة معالجة الرسومات. عند اختيار مسار وحدة المعالجة المركزية، يتم libRS_internal.so (التنفيذ الرئيسي لإطار عمل RS) dlopen مباشرةً من مساحة الاسم التلقائية للرابط حيث يتم توفير إصدار النظام الأساسي من مكتبات RS.

لا يتم استخدام تنفيذ RS HAL من المورّد على الإطلاق عند اتّخاذ مسار الاحتياطي لوحدة المعالجة المركزية (CPU)، ويتم إنشاء كائن RsContext بقيمة فارغة mVendorDriverName. يتم dlopen libRSDriver.so (تلقائيًا) ويتم تحميل مكتبة برنامج التشغيل من مساحة الاسم default لأنّ برنامج الاتصال (libRS_internal.so) يتم تحميله أيضًا في مساحة الاسم default.

الشكل 3. مسار احتياطي لوحدة المعالجة المركزية

مسار وحدة معالجة الرسومات

بالنسبة إلى مسار وحدة معالجة الرسومات، يتم تحميل 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، والتي يتم تضمينها في تنفيذ RS HAL (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). بصفتها SP-HAL، تتضمّن مكتبة 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 في ثلاث مراحل:

المرحلة التفاصيل
تجميع
  • يجب أن يكون رمز البت المدخل (.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. تتضمّن معلومات المرجع بشأن هذا الإيقاف النهائي ما يلي: