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

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

שכבות

שכבה היא יחידת ההרכבה החשובה ביותר. שכבה היא בשילוב של Surface (שטח) ומופע של SurfaceControl. לכל שכבה יש קבוצה של מאפיינים שמגדירים את האינטראקציה שלה עם שכבות אחרות. מאפייני השכבות מתוארים בטבלה הבאה.

נכס תיאור
תלוי מיקום מגדיר איפה השכבה מופיעה בתצוגה. כולל מידע כמו המיקומים של קצוות השכבה וסדר Z שלה ביחס לשכבות אחרות (אם היא צריכה להיות מלפנים או מאחורי השכבות האחרות).
תוכן הגדרת אופן הצגת התוכן בשכבה בתוך הגבולות שמוגדרים על ידי מאפייני המיקום. כולל מידע כמו חיתוך (כדי להרחיב חלק מהתוכן ולמלא את גבולות השכבה) וטרנספורמציה (כדי להציג תוכן שרוטט או הופך).
יצירה מוזיקלית הגדרת האופן שבו השכבה צריכה להיות מורכבת משכבות אחרות. כולל מידע כמו מצב מיזוג וערך אלפא ברמת השכבה לצורך מיזוג אלפא.
אופטימיזציה מספק מידע שאינו הכרחי אך ורק כדי מורכב באופן נכון את השכבה, אבל יכול לשמש את מכשיר 'כלי הכתיבה לחומרה' (HWC) כדי לבצע אופטימיזציה של הרכבה. כולל מידע כמו האזור הגלוי של השכבה ואיזה קטע של השכבה עודכן מאז המסגרת הקודמת.

מקרנים

מסך הוא עוד יחידה חשובה של הרכבה. מערכת יכולה לכלול כמה מסכים, ואפשר להוסיף או להסיר מסכים במהלך הפעולות הרגילות של המערכת. הצגים מתווספים או מוסרם לפי בקשה של HWC או של המסגרת. מכשיר ה-HWC מבקש להוסיף או להסיר מסכים כשמסך חיצוני מחובר או מנותק מהמכשיר. הפעולה הזו נקראת hotplugging. לקוחות מבקשים מסכים וירטואליים, שהתוכן שלהם עובר עיבוד במאגר מחוץ למסך במקום במסך פיזי.

מסכים וירטואליים

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

לתצוגות וירטואליות יכולה להיות אותה קבוצת שכבות כמו לתצוגה הראשית (מקבץ השכבות), או קבוצה משלהם. אין VSYNC למסך וירטואלי, ולכן ה-VSYNC של המסך הפנימי מפעיל את הרכיב של כל המסכים.

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