ארכיטקטורת גרפיקה

מה כל מפתח צריך לדעת על surfaces,‏ SurfaceHolder,‏ EGLSurface,‏ SurfaceView,‏ GLSurfaceView,‏ SurfaceTexture,‏ TextureView,‏ SurfaceFlinger ו-Vulkan

בדף הזה מתוארים רכיבים חיוניים בארכיטקטורת הגרפיקה ברמת המערכת של Android, ואיך הם משמשים את מסגרת האפליקציה ואת מערכת המולטימדיה. הדגש הוא על האופן שבו מאגרי נתונים גרפיים עוברים במערכת. אם תהיתם אי פעם למה SurfaceView ו-TextureView מתנהגים כפי שהם מתנהגים, או איך מתבצעת האינטראקציה בין surfaces ל-EGLSurface, הגעתם למקום הנכון.

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

הקטע הזה כולל כמה דפים שכוללים מידע מגוון, החל מחומר רקע ועד לפרטים של HAL ותרחישי לדוגמה. המאמר מתחיל בהסבר על מאגרי הגרפיקה של Android, מתאר את המנגנון של הרכבת התמונה והצגתה, ולאחר מכן עובר למנגנונים ברמה גבוהה יותר שמספקים ל-Compositor נתונים. מומלץ לקרוא את הדפים בסדר שמופיע בהמשך, ולא לדלג לנושא שנשמע מעניין.

רכיבים ברמה נמוכה

  • BufferQueue ו-gralloc. BufferQueue מחבר בין רכיב שיוצר מאגרים של נתונים גרפיים (הבעלים) לבין רכיב שמקבל את הנתונים להצגה או לעיבוד נוסף (הצרכן). הקצאות של מאגרי נתונים זמניים מתבצעות באמצעות מנהל הזיכרון gralloc שמוטמע דרך ממשק HAL ספציפי לספק.
  • SurfaceFlinger,‏ Hardware Composer ומסכים וירטואליים. SurfaceFlinger מקבל מאגרי נתונים ממקורות מרובים, משלבים אותם ושולח אותם למסך. ‏Hardware Composer HAL‏ (HWC) קובע את הדרך היעילה ביותר לשילוב מאגרים עם החומרה הזמינה, ומסכים וירטואליים מאפשרים להציג פלט משולב בתוך המערכת (הקלטת המסך או שליחת המסך ברשת).
  • Surface,‏ canvas ו-SurfaceHolder. פני השטח יוצרים תור של מאגר, ש-SurfaceFlinger משתמש בו לעיתים קרובות. כשמבצעים עיבוד (רינדור) על גבי משטח, התוצאה נשלחת למאגר (buffer) ומשם לצרכן. ממשקי Canvas API מספקים הטמעת תוכנה (עם תמיכה בהאצה בחומרה) לציור ישירות על משטח (חלופה ברמה נמוכה ל-OpenGL ES). כל מה שקשור לתצוגה כרוך ב-SurfaceHolder, שממשקי ה-API שלו מאפשרים לקבל ולקבוע פרמטרים של משטח, כמו גודל ופורמט.
  • EGLSurface ו-OpenGL ES. OpenGL ES‏ (GLES) מגדיר ממשק API לעיבוד גרפיקה שמיועד לשילוב עם EGL, ספרייה שיכולה ליצור חלונות ולגשת אליהם דרך מערכת ההפעלה (כדי לצייר פוליגונים עם טקסטורה, משתמשים בקריאות ל-GLES. כדי להציג עיבוד על המסך, משתמשים בקריאות ל-EGL). בדף הזה מוסבר גם על ANativeWindow, המקבילה ב-C/C++ לכיתה Surface ב-Java, שמשמשת ליצירת פני שטח של חלון EGL מקוד מקומי.
  • Vulkan. Vulkan הוא ממשק API לפלטפורמות שונות עם תקורה נמוכה, שמאפשר ליצור גרפיקה תלת-ממדית עם ביצועים גבוהים. בדומה ל-OpenGL ES, Vulkan מספק כלים ליצירת גרפיקה באיכות גבוהה בזמן אמת באפליקציות. היתרונות של Vulkan כוללים הפחתה בעלויות העל של המעבד ותמיכה בשפה SPIR-V Binary Intermediate.

רכיבים ברמה גבוהה

  • SurfaceView ו-GLSurfaceView. SurfaceView משלבת בין משטח לתצוגה. רכיבי התצוגה של SurfaceView מורכבים על ידי SurfaceFlinger (ולא על ידי האפליקציה), וכך מתאפשר עיבוד באמצעות שרשור/תהליך נפרד והפרדה מהעיבוד של ממשק המשתמש של האפליקציה. GLSurfaceView מספק כיתות עזר לניהול הקשרים של EGL, תקשורת בין חוטים ואינטראקציה עם מחזור החיים של הפעילות (אבל לא נדרש להשתמש ב-GLES).
  • SurfaceTexture. ‏SurfaceTexture משלבת בין משטח לבין טקסטורה של GLES כדי ליצור BufferQueue שהאפליקציה שלכם היא הצרכן שלו. כשבעל תוכן דיגיטלי מוסר מאגר חדש לתור, הוא שולח התראה לאפליקציה, והיא בתורה משחררת את המאגר הקודם, מקבלת את המאגר החדש מהתור ומבצעת קריאות ל-EGL כדי להפוך את המאגר לזמין ל-GLES כטקסטורה חיצונית. ב-Android 7.0 נוספה תמיכה בהפעלה מאובטחת של סרטונים עם טקסטורה, שמאפשרת עיבוד לאחרי הפעלה (post-processing) של תוכן וידאו מוגן על ידי GPU.
  • TextureView. ‏TextureView משלבת תצוגה עם SurfaceTexture. ‏TextureView עוטף את SurfaceTexture ומקבל אחריות על תגובה להודעות חזרה (callbacks) ועל יצירת מאגרים חדשים. כשמתבצעת ציור, ‏TextureView משתמשת בתוכן של המאגר שהתקבל לאחרונה כמקור הנתונים שלה, ומבצעת רינדור בכל מקום ובכל אופן שמצוין במצב התצוגה. הרכבת התצוגה מתבצעת תמיד באמצעות GLES, כלומר עדכונים בתוכן עשויים לגרום לציור מחדש של רכיבי תצוגה אחרים.