מידע שכל מפתח צריך לדעת על פלטפורמות, SurfaceHolder, EGLSurface, SurfaceView, GLSurfaceView, SurfaceTexture, TextureView, SurfaceFlinger ו-Vulkan.
בדף הזה מתוארים רכיבים חיוניים של ארכיטקטורת הגרפיקה ברמת המערכת של Android, ואיך הם משמשים את מסגרת האפליקציה ואת מערכת המולטימדיה. הדגש הוא על האופן שבו מאגרי נתונים של נתונים גרפיים עוברים במערכת. אם תהיתם פעם למה SurfaceView ו-TextureView מתנהגים כמו שהם מתנהגים, או איך משטחים ו-EGLSurface פועלים יחד, הגעתם למקום הנכון.
אנחנו מניחים שיש לכם היכרות מסוימת עם מכשירי Android ועם פיתוח אפליקציות. לא נדרש ידע מפורט על מסגרת האפליקציה, ומוזכרות רק כמה קריאות API, אבל התוכן לא חופף לתיעוד ציבורי אחר. המטרה היא לספק פרטים על האירועים המשמעותיים שקשורים לעיבוד של פריים לפלט, כדי לעזור לכם לקבל החלטות מושכלות כשאתם מעצבים אפליקציה. כדי להשיג את המטרה הזו, המסמך הזה מתחיל מהבסיס ומתאר איך פועלות מחלקות ממשק המשתמש, ולא איך אפשר להשתמש בהן.
בקטע הזה יש כמה דפים שכוללים מידע על כל הנושאים, החל מחומר רקע ועד לפרטים על HAL ותרחישים לדוגמה. המאמר מתחיל בהסבר על מאגרי גרפיקה של Android, מתאר את מנגנון ההרכבה והתצוגה, וממשיך למנגנונים ברמה גבוהה יותר שמספקים נתונים למרכיב. מומלץ לקרוא את הדפים בסדר הבא ולא לדלג לנושא שנשמע מעניין.
רכיבים ברמה נמוכה
- BufferQueue ו-gralloc. BufferQueue מקשר בין רכיב שמייצר מאגרי נתונים של נתונים גרפיים (היצרן) לבין רכיב שמקבל את הנתונים לצורך הצגה או עיבוד נוסף (הצרכן). הקצאות של מאגרים זמניים מתבצעות באמצעות מקצה הזיכרון gralloc שהוטמע דרך ממשק HAL ספציפי לספק.
- SurfaceFlinger, Hardware Composer ומסכים וירטואליים. SurfaceFlinger מקבל מאגרי נתונים ממקורות שונים, משלב אותם ושולח אותם לתצוגה. ה-HAL של Hardware Composer (HWC) קובע את הדרך היעילה ביותר ליצור קומפוזיציה של מאגרי נתונים באמצעות החומרה הזמינה, ומסכים וירטואליים מאפשרים ליצור פלט של קומפוזיציה בתוך המערכת (הקלטת המסך או שליחת המסך ברשת).
- Surface, Canvas ו-SurfaceHolder. משטח יוצר תור מאגרים שנצרך לעיתים קרובות על ידי SurfaceFlinger. כשמבצעים רינדור על משטח, התוצאה מגיעה למאגר זמני שנשלח לצרכן. ממשקי ה-API של Canvas מספקים הטמעה של תוכנה (עם תמיכה בהאצת חומרה) לציור ישירות על משטח (חלופה ברמה נמוכה ל-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 משלב בין Surface לבין View. רכיבי התצוגה של SurfaceView מורכבים על ידי SurfaceFlinger (ולא על ידי האפליקציה), מה שמאפשר עיבוד משרשור או מתהליך נפרדים, ובידוד מעיבוד ממשק המשתמש של האפליקציה. GLSurfaceView מספקת מחלקות עזר לניהול הקשרים של EGL, לתקשורת בין השרשורים ולאינטראקציה עם מחזור החיים של הפעילות (אבל לא צריך להשתמש ב-GLES).
- SurfaceTexture. SurfaceTexture משלב בין Surface לבין מרקם GLES כדי ליצור BufferQueue שהאפליקציה שלכם היא הצרכן שלו. כשמפיק מוסיף מאגר חדש לתור, הוא מודיע על כך לאפליקציה. האפליקציה משחררת את המאגר הקודם, מקבלת את המאגר החדש מהתור ומבצעת קריאות ל-EGL כדי להפוך את המאגר לזמין ל-GLES כמרקם חיצוני. ב-Android 7.0 נוספה תמיכה בהפעלה מאובטחת של סרטוני טקסטורה, שמאפשרת עיבוד פוסט של תוכן וידאו מוגן באמצעות GPU.
- TextureView. TextureView משלב תצוגה עם SurfaceTexture. TextureView עוטף SurfaceTexture ומקבל אחריות על תגובה לקריאות חוזרות ועל רכישת מאגרים חדשים. כשמציירים, TextureView משתמש בתוכן של המאגר שהתקבל לאחרונה כמקור הנתונים שלו, ומבצע רינדור בכל מקום ובכל אופן שבו מצב התצוגה מציין שצריך לבצע רינדור. הצגת הקומפוזיציה מתבצעת תמיד באמצעות GLES, ולכן עדכונים בתוכן עשויים לגרום גם לרכיבי תצוגה אחרים לצייר מחדש.