שכבות ותצוגות הן שני פרימיטיבים שמייצגים עבודת קומפוזיציה ואינטראקציות עם חומרת התצוגה.
שכבות
שכבה היא היחידה החשובה ביותר של יצירה. שכבה היא שילוב של משטח ומופע של SurfaceControl
.
לכל שכבה יש קבוצה של מאפיינים שמגדירים את האינטראקציה שלה עם שכבות אחרות. בטבלה הבאה מפורטות המאפיינים של השכבה:
נכס | תיאור |
---|---|
תלויי מיקום | המאפיין מגדיר איפה השכבה מופיעה בתצוגה שלה. כולל מידע כמו מיקומי הקצוות של שכבה וסדר ה-Z שלה ביחס לשכבות אחרות (אם היא צריכה להיות לפני שכבות אחרות או מאחוריהן). |
תוכן | המאפיין מגדיר איך התוכן שמוצג בשכבה צריך להיות מוצג בגבולות שהוגדרו על ידי מאפייני המיקום. כולל מידע כמו חיתוך (להרחבת חלק מהתוכן כדי למלא את הגבולות של השכבה) ושינוי (להצגת תוכן מסובב או הפוך). |
יצירה מוזיקלית | המאפיין הזה מגדיר איך השכבה צריכה להיות מורכבת משכבות אחרות. כולל מידע כמו מצב מיזוג וערך אלפא לכל השכבה עבור alpha compositing. |
אופטימיזציה | המידע הזה לא נחוץ כדי ליצור את השכבה בצורה נכונה, אבל אפשר להשתמש בו במכשיר Hardware Composer (HWC) כדי לבצע אופטימיזציה של אופן יצירת השכבה. כולל מידע כמו האזור הגלוי של השכבה ואיזה חלק בשכבה עודכן מאז הפריים הקודם. |
מקרנים
תצוגה היא יחידה חשובה נוספת של יצירה. למערכת יכולים להיות כמה מסכים, ואפשר להוסיף או להסיר מסכים במהלך פעולות רגילות של המערכת. התצוגות מתווספות או מוסרות לבקשת ה-HWC או לבקשת המסגרת. המכשיר HWC מבקש להוסיף או להסיר מסכים כשמסך חיצוני מחובר למכשיר או מנותק ממנו, תהליך שנקרא hotplugging. לקוחות מבקשים תצוגות וירטואליות, שהתוכן שלהן עובר רינדור במאגר מחוץ למסך במקום בתצוגה פיזית.
מסכים וירטואליים
SurfaceFlinger תומך במסך פנימי (מובנה בטלפון או בטאבלט), במסכים חיצוניים (כמו טלוויזיה שמחוברת באמצעות HDMI) ובמסך וירטואלי אחד או יותר שמאפשרים פלט מורכב בתוך המערכת. אפשר להשתמש במסכים וירטואליים כדי להקליט את המסך או לשלוח את המסך ברשת. מסגרות שנוצרות לתצוגה וירטואלית נכתבות ל-BufferQueue.
יכול להיות שלתצוגות וירטואליות יש את אותו סט שכבות כמו לתצוגה הראשית (מערך השכבות), או סט שכבות משלהן. אין VSync לתצוגה וירטואלית, לכן ה-VSync לתצוגה הפנימית מפעיל קומפוזיציה לכל התצוגות.
ביישומים של HWC שתומכים בתצוגות וירטואליות, אפשר ליצור קומפוזיציה של תצוגות וירטואליות באמצעות OpenGL ES (GLES), HWC או שניהם. ביישומים שלא תומכים ב-GLES, מסכים וירטואליים תמיד מורכבים באמצעות GLES.
מקרה לדוגמה: screenrecord
הפקודה screenrecord
מאפשרת למשתמש להקליט את כל מה שמופיע על המסך כקובץ MP4 בדיסק. כדי להטמיע את זה, המערכת מקבלת פריימים מורכבים מ-SurfaceFlinger, כותבת אותם למקודד הווידאו ואז כותבת את נתוני הווידאו המקודדים לקובץ. הקודקים של הסרטונים מנוהלים על ידי תהליך נפרד (mediaserver
), ולכן מאגרי גרפיקה גדולים צריכים לעבור במערכת. כדי להפוך את המשימה למאתגרת יותר, המטרה היא להקליט סרטון באיכות 60 fps ברזולוציה מלאה. הפתרון היעיל ביותר הוא BufferQueue.
הסיווג MediaCodec
מאפשר לאפליקציה לספק נתונים כבייטים גולמיים במאגרי נתונים זמניים,
או דרך משטח. כש-screenrecord
מבקש גישה למקודד וידאו, התהליך של mediaserver
יוצר BufferQueue, מתחבר לצד הצרכן ואז מעביר את צד היצרן בחזרה ל-screenrecord
כמשטח.
לאחר מכן, כלי השירות screenrecord
מבקש מ-SurfaceFlinger ליצור תצוגה וירטואלית שמשקפת את התצוגה הראשית (כלומר, יש לה את כל השכבות), ומורה לו לשלוח פלט אל השטח שהגיע מהתהליך mediaserver
. במקרה הזה, SurfaceFlinger הוא היוצר של המאגרים ולא הצרכן שלהם.
אחרי שההגדרה מסתיימת, התג screenrecord
מופעל כשהנתונים המקודדים מופיעים. בזמן שהאפליקציות מציירות, המאגרים שלהן מועברים אל SurfaceFlinger, שיוצר מהם מאגר יחיד שנשלח ישירות למקודד הווידאו בתהליך mediaserver
. תהליך screenrecord
אף פעם לא רואה את הפריימים המלאים. באופן פנימי, לתהליך mediaserver
יש דרך משלו להעברת מאגרי נתונים זמניים, שגם מעבירה נתונים באמצעות נקודת אחיזה, וכך מצמצמת את התקורה.
מקרה לדוגמה: הדמיית מסכים משניים
ה-WindowManager יכול לבקש מ-SurfaceFlinger ליצור שכבה גלויה ש-SurfaceFlinger פועל בה כצרכן BufferQueue. אפשר גם לבקש מ-SurfaceFlinger ליצור תצוגה וירטואלית, שבה SurfaceFlinger פועל כמפיק BufferQueue.
אם מחברים תצוגה וירטואלית לשכבה גלויה, נוצרת לולאה סגורה שבה המסך המורכב מופיע בחלון. החלון הזה הוא עכשיו חלק מהפלט המורכב, ולכן ברענון הבא התמונה המורכבת בתוך החלון תציג גם את התוכן של החלון. כדי לראות את זה בפעולה, מפעילים את האפשרויות למפתחים בהגדרות, בוחרים באפשרות הדמיה של מסכים משניים ומפעילים חלון. כדי לראות את הפעולה של מסכים משניים, משתמשים ב-screenrecord
כדי לצלם את הפעולה של הפעלת המסך ואז מפעילים את הסרטון שוב פריים אחר פריים.