SurfaceFlinger ו-WindManager

‏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 Wraps SurfaceControl מאפשר לאפליקציה ליצור SurfaceControls שמתאימות לשכבות במסך.

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

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

כשהמסך נמצא בין רענונים, הוא שולח את האות VSYNC אל SurfaceFlinger. האות VSYNC מציין שאפשר לרענן את המסך בלי קריעה. כש-SurfaceFlinger מקבל את האות VSYNC, הוא עובר על רשימת השכבות שלו ומחפש מאגרים חדשים. אם SurfaceFlinger מוצא מאגר נתונים זמני חדש, SurfaceFlinger מקבל את מאגר הנתונים הזמני. אם לא, 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 כדי לייצג את הטרנספורמציה שסביר להניח שתחול על מאגר הנתונים הזמני על ידי SuraceFlinger. מנהלי ה-GL יכולים להשתמש בהצעה הזו כדי לבצע טרנספורמציה מראש של המאגר לפני שהוא מגיע ל-SurfaceFlinger, כך שכשהמאגר מגיע, הוא עובר טרנספורמציה בצורה נכונה.

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