SurfaceFlinger ו-WindowManager

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

SurfaceFlinger

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

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

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

בטבלה הבאה מתוארים ASurfaceControl והרכיבים שמשויכים אליו:

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

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

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

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

WindowManager

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

הגדרה מראש של מיקום המודעה

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

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