רנדרscript

RenderScript היא מסגרת להפעלת משימות אינטנסיביות מבחינה חישובית בביצועים גבוהים באנדרואיד. הוא מיועד לשימוש עם חישוב מקביל לנתונים, אם כי עומסי עבודה טוריים יכולים להועיל גם כן. זמן הריצה של RenderScript מקביל לעבודה בין מעבדים הזמינים במכשיר, כגון מעבדים מרובי ליבות ומעבדי GPU, מה שמאפשר למפתחים להתמקד באלגוריתמים להבעה במקום בתזמון עבודה. RenderScript שימושי במיוחד עבור יישומים המבצעים עיבוד תמונה, צילום חישובי או ראייה ממוחשבת.

מכשירים המריצים אנדרואיד 8.0 ואילך משתמשים במסגרת ה-RenderScript וה-HAL של הספקים הבאים:

איור 1. קוד ספק המקשר ל-libs פנימי

ההבדלים בין RenderScript ב-Android 7.x ומטה כוללים:

  • שני מופעים של libs פנימי של RenderScript בתהליך. קבוצה אחת מיועדת לנתיב חילופין של מעבד ומגיעה ישירות ב- /system/lib ; הסט השני מיועד לנתיב GPU והוא מ- /system/lib/vndk-sp .
  • RS libs פנימי ב- /system/lib בנויים כחלק מהפלטפורמה ומתעדכנים עם שדרוג system.img . עם זאת, libs ב- /system/lib/vndk-sp בנויים עבור הספק ואינם מתעדכנים כאשר system.img משודרג (בעוד שניתן לעדכן אותם לתיקון אבטחה, ה-ABI שלהם נשאר זהה).
  • קוד הספק (RS HAL, מנהל התקן RS bcc plugin ) מקושרים אל מול ה-libs הפנימיים של RenderScript הממוקמים ב- /system/lib/vndk-sp . הם לא יכולים לקשר מול libs ב- /system/lib מכיוון ש-libs בספרייה זו בנויים עבור הפלטפורמה ולכן עשויים שלא להיות תואמים לקוד הספק (כלומר, סמלים עשויים להיות מוסרים). פעולה זו תהפוך OTA למסגרת בלבד לבלתי אפשרית.

לְעַצֵב

הסעיפים הבאים מפרטים את עיצוב RenderScript באנדרואיד 8.0 ואילך.

ספרי RenderScript זמינים לספקים

סעיף זה מפרט את ה-RenderScript libs (הידוע כספק NDK עבור Same-Process HALs או 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

תצורת מרחב השמות של המקשר

מגבלת הקישור שמונעת מ-libs שאינם ב-VNDK-SP להשתמש בקוד הספק, נאכפת בזמן ריצה באמצעות מרחב השמות המקשר. (לפרטים, עיין במצגת VNDK Design .)

במכשיר המריץ אנדרואיד 8.0 ואילך, כל ה-HALs של Same-Process (SP-HAL) מלבד RenderScript נטענים בתוך מרחב השמות המקשר sphal . RenderScript נטען לתוך מרחב השמות הספציפי ל-RenderScript rs , מיקום המאפשר אכיפה מעט יותר רופפת עבור libs של RenderScript. מכיוון שהיישום של RS צריך לטעון את ה-bitcode המהודר, /data/*/*.so מתווסף לנתיב של מרחב השמות rs (SP-HALs אחרים אינם רשאים לטעון libs ממחיצת הנתונים).

בנוסף, מרחב השמות rs מאפשר יותר libs ממה שמספקים מרחבי שמות אחרים. libmediandk.so ו- libft2.so חשופים למרחב השמות rs מכיוון libRS_internal.so יש תלות פנימית לספריות אלו.

איור 2. תצורת מרחב שמות עבור מקשר

טוען דרייברים

נתיב ניצול מעבד

בהתאם לקיומו של סיביות RS_CONTEXT_LOW_LATENCY בעת יצירת הקשר RS, הנתיב של המעבד או ה-GPU נבחר. כאשר נתיב ה-CPU נבחר, libRS_internal.so (היישום העיקרי של מסגרת RS) dlopen ישירות ממרחב השמות המקשר ברירת המחדל שבו מסופקת גרסת הפלטפורמה של RS libs.

היישום RS HAL מהספק אינו בשימוש כלל כאשר נלקח נתיב ה-CPU, ואובייקט RsContext נוצר עם mVendorDriverName null. libRSDriver.so הוא (כברירת מחדל) dlopen ed ומנהל ההתקן lib נטען ממרחב השמות default מכיוון שהמתקשר ( libRS_internal.so ) נטען גם במרחב השמות default .

איור 4. נתיב ניצול מעבד

נתיב GPU

עבור נתיב ה-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 ד dlopen s libRS_internal.so במרחב שמות קישור אחר בשם rs .

ספקים יכולים לספק מנהל התקן RS משלהם על ידי הגדרת דגל זמן הבנייה OVERRIDE_RS_DRIVER , המוטמע ביישום RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp ). שם מנהל ההתקן הזה dlopen לאחר מכן עבור הקשר RS עבור נתיב ה-GPU.

יצירת האובייקט RsContext מואצלת למימוש RS HAL. ה-HAL קורא חזרה למסגרת RS באמצעות הפונקציה rsContextCreateVendor() עם שם מנהל ההתקן לשימוש כארגומנט. לאחר מכן, המסגרת של 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 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, Android 7.x ומטה


איור 7. טוען תוסף Bcc, Android 8.0 ומעלה

נתיבי חיפוש עבור ld.mc

בעת ביצוע ld.mc , כמה libs זמן ריצה של RS ניתנים כקלט למקשר. קוד הסיביות של RS מהאפליקציה מקושר ל-Libs של זמן הריצה וכאשר ה-bitcode המומר נטען לתהליך של אפליקציה, ה-Libs של זמן הריצה מקושרים שוב באופן דינמי מה-bitcode שהומר.

ספרי זמן ריצה כוללים:

  • libcompiler_rt.so
  • libm.so
  • libc.so
  • מנהל התקן RS (או libRSDriver.so או OVERRIDE_RS_DRIVER )

בעת טעינת ה-bitcode המהידור לתהליך האפליקציה, ספק את אותה ספרייה בדיוק שבה השתמש ld.mc אחרת, ייתכן שקוד הסיביות המהודר לא ימצא סמל שהיה זמין כאשר הוא היה מקושר.

לשם כך, RS framework משתמש בנתיבי חיפוש שונים עבור libs זמן הריצה בעת ביצוע ld.mc , תלוי אם המסגרת RS עצמה נטענת מ- /system/lib או מ- /system/lib/vndk-sp . ניתן לקבוע זאת על ידי קריאת הכתובת של סמל שרירותי של מסגרת RS lib ושימוש dladdr() כדי למפות את נתיב הקובץ לכתובת.

מדיניות SELinux

כתוצאה משינויי מדיניות SELinux באנדרואיד 8.0 ואילך, עליך לפעול לפי כללים ספציפיים (נאכפים באמצעות neverallows ) בעת תיוג קבצים נוספים במחיצת vendor :

  • vendor_file חייבת להיות תווית ברירת המחדל עבור כל הקבצים במחיצת vendor . מדיניות הפלטפורמה מחייבת זאת כדי לגשת למימושי HAL מעבר.
  • כל exec_types החדשים שנוספו במחיצת vendor דרך הספק SEPolicy חייבים להיות בעלי תכונה vendor_file_type . זה נאכף באמצעות neverallows .
  • כדי למנוע התנגשויות עם עדכוני פלטפורמה/מסגרת עתידיים, הימנע מתיוג קבצים שאינם exec_types במחיצת vendor .
  • כל התלות בספרייה עבור HAL של אותו תהליך מזוהה ב-AOSP חייבות להיות מסומנות כ- same_process_hal_file .

לפרטים על מדיניות SELinux, ראה לינוקס משופרת באבטחה באנדרואיד .

תאימות ABI עבור bitcode

אם לא יתווספו ממשקי 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 מתרחשת בשלושה שלבים:

שלב פרטים
לְלַקֵט
  • קוד ה-bitcode הקלט (.bc) עבור bcc חייב להיות בפורמט LLVM 3.2 bitcode וה- bcc חייב להיות תואם לאחור עם אפליקציות קיימות (מדור קודם).
  • עם זאת, המטא-נתונים ב-.bc עשויים להשתנות (יכולות להיות פונקציות חדשות של זמן ריצה, למשל, מגדירי הקצאה ∓ מגטרים, פונקציות מתמטיות וכו'). חלק מפונקציות זמן הריצה נמצאות ב- libclcore.bc , חלק מהן חיים ב-LibRSDriver או מקבילה של ספק.
  • פונקציות חדשות של זמן ריצה או שבירה של שינויים במטא-נתונים דורשים הגדלה של רמת ה-Bitcode API. מכיוון שמנהלי התקנים של הספקים לא יוכלו לצרוך אותו, יש להגדיל גם את גרסת HAL.
  • לספקים עשויים להיות מהדרים משלהם, אבל המסקנות/דרישות עבור bcc חלות גם על אותם מהדרים.
קישור
  • ה-.o המהודר יהיה מקושר עם מנהל ההתקן של הספק, למשל, libRSDriver_foo.so ו- libcompiler_rt.so . נתיב המעבד יקשר עם libRSDriver.so .
  • אם ה-.o דורש API חדש של זמן ריצה מ- libRSDriver_foo , יש לעדכן את מנהל ההתקן של הספק כדי לתמוך בו.
  • ספקים מסוימים עשויים להיות בעלי קישורים משלהם, אבל הטיעון של ld.mc חל גם עליהם.
לִטעוֹן
  • libRSCpuRef טוען את האובייקט המשותף. אם יש שינויים בממשק זה, יש צורך ב-bump בגרסת HAL.
  • ספקים יסתמכו על libRSCpuRef כדי לטעון את האובייקט המשותף, או ליישם את האובייקט שלהם.

בנוסף ל-HAL, ממשקים של זמן ריצה והסמלים המיוצאים הם גם ממשקים. אף ממשק לא השתנה מאז אנדרואיד 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.

מהדר Bitcode

אתה יכול להרכיב קוד סיביות של RenderScript עבור מנהל ההתקן של הספק בשתי דרכים:

  1. הפעל מהדר RenderScript הספציפי לספק ב- /vendor/bin/ (שיטה מועדפת להידור GPU). בדומה למודולי מנהלי התקנים אחרים, ה-Binary Compiler של הספק אינו יכול להיות תלוי בספריית מערכת שאינה ברשימת ה- RenderScript libs הזמינים לספקים .
  2. הפעל עותק מוסתר של המערכת: /system/bin/bcc עם bcc plugin מוסתר שסופק על ידי הספק; תוסף זה אינו יכול להיות תלוי בכל ספריית מערכת שאינה ברשימת ה-RenderScript libs הזמינים לספקים .

אם 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. שנה את הנתיב לקובץ ההפעלה 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 אינו מוגדר.

עבור מכשירים מדור קודם, ההגבלות אינן נאכפות בעת שדרוג ל-Android 8.0 ומעלה, כלומר מנהלי ההתקן יכולים להמשיך לקשר לספריות ב- /system/lib[64] . עם זאת, בגלל השינוי בארכיטקטורה הקשור ל- OVERRIDE_RS_DRIVER , יש להתקין android.hardware.renderscript@1.0-impl במחיצת /vendor ; כשלון עושה זאת מאלץ את חזרת זמן הריצה של RenderScript לנתיב המעבד.

למידע על המניע להוצאה משימוש של Renderscript, ראה את הבלוג של מפתחי Android: Android GPU Compute Going Forward . מידע על משאבים עבור הוצאה משימוש זה כולל את הדברים הבאים: