הטמעת OpenGL ES ו-EGL

OpenGL הוא ממשק API של גרפיקה בפלטפורמות שונות, שמציין ממשק תוכנה סטנדרטי לחומרת עיבוד גרפיקה תלת-ממדית. OpenGL ES היא קבוצת משנה של מפרט OpenGL למכשירים מוטמעים.

כדי להיות תואמים ל-Android, המכשירים צריכים לספק מנהלי התקנים ל-EGL, ל-OpenGL ES 1.x ול-OpenGL ES 2.0. התמיכה ב-OpenGL ES 3.x היא אופציונלית. בין השיקולים העיקריים:

  • מוודאים שמנהל ההתקן של GL יציב ותואמת לסטנדרטים של OpenGL ES.
  • מתן אפשרות ליצירת מספר בלתי מוגבל של הקשרי GL. מכיוון שמערכת Android מאפשרת להריץ אפליקציות ברקע ומנסה לשמור על הקשרי GL פעילים, לא כדאי להגביל את מספר ההקשרים בנהג.
  • חשוב לשים לב לכמות הזיכרון שמוקצית לכל הקשר, כי בדרך כלל יש 20-30 הקשרי GL פעילים בו-זמנית.
  • תמיכה בפורמט התמונה YV12 ובפורמטים אחרים של תמונות YUV שמגיעים מרכיבים אחרים במערכת, כמו קודיקים של מדיה או המצלמה.
  • תמיכה בתוספים החובה EGL_KHR_wait_sync, GL_OES_texture_external, EGL_ANDROID_image_native_buffer, EGL_ANDROID_recordable. בנוסף, כדי להשתמש ב-Hardware Composer בגרסה 1.1 ואילך צריך את התוסף EGL_ANDROID_framebuffer_target.

מומלץ מאוד לתמוך גם ב-EGL_ANDROID_blob_cache, ב-EGL_KHR_fence_sync וב-EGL_ANDROID_native_fence_sync.

Android 10 מטמיע את ממשק EGL 1.5. מידע על התכונות החדשות ב-EGL 1.5 זמין במפרט של Khronos Releases 1.5.

טעינה של מנהל ההתקן

מערכת Android מצפה שה-GPUs שזמינים למערכת יהיו ידועים כשתמונה המערכת נוצרת. הנתיבים המועדפים למנהלי התקן של OpenGL ES ב-32 ביט וב-64 ביט הם /vendor/lib/egl ו-/vendor/lib64/egl, בהתאמה. המטען משתמש בשני מאפייני מערכת, ro.hardware.egl ו-ro.board.platform, או בשם המדויק, כדי לזהות את מנהלי ההתקנים של המערכת ולטעון אותם. מנהל ההתקן של OpenGL ES צריך להישלח כקובץ בינארי אחד או לפלח לשלושה קבצים בינאריים. אם מנהל ההתקן של OpenGL ES נשלחת בקובץ בינארי אחד, צריך להשתמש באחד מהשמות הבאים:

libGLES_${ro.hardware.egl}.so
libGLES_${ro.board.platform}.so
libGLES.so

אם מנהל ה-OpenGL ES נשלח בשלושה קבצים בינאריים, צריך להשתמש באחת מקבוצות השמות הבאות:

libEGL_${ro.hardware.egl}.so
libGLESv1_CM_${ro.hardware.egl}.so
libGLESv2_${ro.hardware.egl}.so

libEGL_${ro.board.platform}.so
libGLESv1_CM_${ro.board.platform}.so
libGLESv2_${ro.board.platform}.so

libEGL.so
libGLESv1_CM.so
libGLESv2.so

שכבות של OpenGL ES

ב-Android 10 נוספה מערכת שכבות ל-GLES 2.0 ואילך. שכבות GLES הן אובייקטים משותפים שזמינים מתוך אפליקציות או שסופקו על ידי כלים. שכבות GLES מאפשרות לאפליקציות שניתן לנפות באגים בהן לגלות ולטעון שכבות באמצעות אותם מנגנוני הגדרה כמו ב-Vulkan.

רכיב GLES LayerLoader בתוך מעבד ה-EGL מזהה שכבות GLES. לכל שכבה ש-GLES LayerLoader מוצא, הוא קורא ל-AndroidGLESLayer_Initialize, עובר על רשימות הפונקציות של libEGL וקורא ל-AndroidGLESLayer_GetProcAddress לכל הפונקציות הידועות. אם השכבה מיירטת פונקציה, היא עוקבת אחרי הכתובת של הפונקציה. אם השכבה לא מפריעה לפונקציה, הפונקציה AndroidGLESLayer_GetProcAddress מחזירה את אותה כתובת פונקציה שהועברה אליה. לאחר מכן, LayerLoader מעדכן את רשימת ה-function hook כך שתצביע על נקודת הכניסה של השכבה.

הפעלת שכבות

אפשר להפעיל שכבות GLES לכל אפליקציה או באופן גלובלי. ההגדרות של כל אפליקציה נשארות ללא שינוי אחרי הפעלה מחדש, אבל המאפיינים הגלובליים נמחקים אחרי הפעלה מחדש.

כדי להפעיל שכבות לכל אפליקציה:

# Enable layers
adb shell settings put global enable_gpu_debug_layers 1

# Specify target app
adb shell settings put global gpu_debug_app package_name

# Specify layer list (from top to bottom)
adb shell settings put global gpu_debug_layers_gles layer1:layer2:...:layerN

# Specify packages to search for layers
adb shell settings put global gpu_debug_layer_app package1:package2:...:packageN

כדי להשבית שכבות לכל אפליקציה:

adb shell settings delete global enable_gpu_debug_layers
adb shell settings delete global gpu_debug_app
adb shell settings delete global gpu_debug_layer_app

כדי להפעיל את השכבות באופן גלובלי:

# Attempts to load layers for all applications, including native executables
adb shell setprop debug.gles.layers layer1:layer2:...:layerN

שכבות בדיקה

השכבות של GLES מגובות על ידי Android CTS, והן נדרשות לעבור את בדיקות ה-CTS למכשירים תואמים. כדי לבדוק אם השכבות פועלות במכשיר, מריצים את הפקודה $ atest CtsGpuToolsHostTestCases.