שכבות ותצוגות

שכבות ותצוגות הן שני פרימיטיבים שמייצגים עבודת קומפוזיציה ואינטראקציות עם חומרת התצוגה.

שכבות

שכבה היא היחידה החשובה ביותר בהרכב. שכבה היא שילוב של משטח ומופע של 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 כדי לצלם את הפעולה של הפעלת המסך ואז מפעילים את הסרטון שוב פריים אחר פריים.