הטמעת 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 שמגיעים מרכיבים אחרים במערכת, כמו רכיבי codec של מדיה או המצלמה.
  • תמיכה בתוספים הנדרשים 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 זמין במפרט של גרסה 1.5 של Khronos.

טעינת הדרייבר

מערכת Android מצפה שה-GPU שזמין למערכת יהיה ידוע בזמן בניית תמונת המערכת. הנתיבים המועדפים לדרייברים של OpenGL ES בגרסת 32 ביט ובגרסת 64 ביט הם /vendor/lib/egl ו-/vendor/lib64/egl בהתאמה. ה-loader משתמש בשני מאפייני מערכת, 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 מעדכן את רשימת ה-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 מגובות על ידי CTS של Android, ונדרשות כדי לעבור בדיקות CTS עבור מכשירים תואמים. כדי לזהות אם השכבות פועלות במכשיר, מריצים את הפקודה $ atest CtsGpuToolsHostTestCases.