SurfaceFlinger ו-WindowManager

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

SurfaceFlinger

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

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

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

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

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

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

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

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

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

WindowManager

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.