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
.