SurfaceFlinger ו-WindManager

SurfaceFlinger מקבל אגירת נתונים, מחבר חוצץ ושולח חוצצים מסך. WindowManager מספק ל-SurfaceFlinger מאגרים ומטא-נתונים של חלונות, שבהם SurfaceFlinger משתמש כדי ליצור קומפוזיציה של משטחים בתצוגה.

SurfaceFlinger

SurfaceFlinger יכול לקבל מאגרים בשתי דרכים: דרך BufferQueue ו-SurfaceControl, או דרך ASurfaceControl.

אחת מהדרכים שבהן SurfaceFlinger מקבל מאגרים היא דרך BufferQueue ו-SurfaceControl. כשאפליקציה עוברת לחזית, היא מבקשת מאגרים מ-WindowManager. לאחר מכן, windowManager מבקש שכבה מ- SurfaceFlinger. שכבה היא שילוב של surface, שמכיל את BufferQueue, ושל SurfaceControl, שמכיל את המטא-נתונים של השכבה, כמו מסגרת התצוגה. SurfaceFlinger יוצר את השכבה ושולח אותה אל windowManager. מנהל החלונות לאחר מכן שולח את הפלטפורמה לאפליקציה, אבל שומר את ה-SurfaceControl לשנות את המראה של האפליקציה במסך.

ב-Android 10 נוסיף את ASurfaceControl, הדרך שבה SurfaceFlinger יכול לקבל חוצצים. ASurfaceControl משלב משטח ו-SurfaceControl בחבילת עסקה אחת שנשלחת אל SurfaceFlinger. ASurfaceControl משויך לשכבה, לאפליקציות בוצע עדכון דרך ASurfaceTransactions. האפליקציות מקבלות מידע על ASurfaceTransactions דרך קריאות חוזרות (callbacks) שמעבירות את ASurfaceTransactionStats שמכיל מידע, כמו זמן התריס, זמני אחזור וכו'.

בטבלה הבאה מפורטים פרטים נוספים על ASurfaceControl ועל הרכיבים המשויכים אליו.

רכיב תיאור
ASurfaceControl עטיפה של SurfaceControl שמאפשרת לאפליקציה ליצור SurfaceControls שתואמים לשכבות במסך.

אפשר ליצור אותו כצאצא של ANativeWindow או כצאצא של ASurfaceControl אחר.
עסקת ASurface פונקציה שמקיפה את Transaction כדי לאפשר ללקוח לערוך את המאפיינים התיאוריים של שכבה, כמו גיאומטריה, ולשלוח את המאגרים המעודכנים ל-SurfaceFlinger.
ASurfaceTransactionStats שליחת מידע על עסקאות שהוצגו, כמו זמן הנעילה, זמני הרכישה ומחסום השחרור הקודם, לאפליקציה באמצעות קריאה חוזרת (callback) שנרשמה מראש.

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

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

אחרי ש-SurfaceFlinger אוסף את כל המאגרים של השכבות הגלויות, הוא שואל את Hardware Composer (HWC) איך צריך לבצע את הרכבת התמונה. אם ה-HWC מסמנים את סוג ה-composition של השכבה כ-client composition,‏ SurfaceFlinger משלבת את השכבות האלה. לאחר מכן, SurfaceFlinger מעביר את מאגר הפלט אל HWC.

מנהל החלונות

WindowManager שולט באובייקטים מסוג window, שהם קונטיינרים של אובייקטים מסוג view. אובייקטים של חלונות תמיד נתמכים על ידי אובייקטים של משטחים. WindowManager מנהל את מחזורי החיים, אירועי הקלט והמיקוד, כיוון המסך, מעברים, אנימציות, מיקום, טרנספורמציות, סדר Z ועוד הרבה היבטים אחרים של חלון. WindowManager שולח את כל המטא-נתונים של החלון אל SurfaceFlinger, כדי ש-SurfaceFlinger יוכל להשתמש בנתונים האלה כדי ליצור משטחים מורכבים במסך.

לפני סיבוב

שכבות-על רבות של חומרה לא תומכות בכיוון (וגם אם כן, הן צורכות יותר כוח עיבוד). הפתרון הוא לבצע טרנספורמציה של המאגר לפני שהוא מגיע ל-SurfaceFlinger. ב-Android יש תמיכה בהצעה לשאילתה (NATIVE_WINDOW_TRANSFORM_HINT) ב-ANativeWindow, שמייצגת את הטרנספורמציה הסבירה ביותר שתיושם על המאגר על ידי SurfaceFlinger. מנהלי התקנים של GL יכולים להשתמש ברמז הזה כדי לבצע טרנספורמציה מראש של מאגר הנתונים הזמני לפני שהוא מגיע ל-SurfaceFlinger, כך שכשהמאגר הזמני מגיע שעברו טרנספורמציה.

לדוגמה, כאשר מקבלים רמז לסובב ב-90 מעלות, יוצרים ומפעילים למאגר הנתונים הזמני כדי למנוע את ההצגה שלו בסוף הדף. כדי לחסוך בחשמל, כדאי לבצע את הפעולה הזו לפני החזרה. לפרטים נוספים, ראו את הממשק ANativeWindow שמוגדר ב-system/core/include/system/window.h.