הטמעת HAL של הכלי לפיתוח חומרה

שכבות ה-HAL המורכבות של Hardware Composer (HWC) שהתקבלו SurfaceFlinger, מפחית את כמות ההרכבת OpenGL ES (GLES) ואת ביצועי ה-GPU.

ה-HWC מפשט אובייקטים, כגון שכבות-על ונצנצים בדו-ממד, ומתקשרים עם חומרה מיוחדת להרכבת חלונות כדי חלונות מורכבים. השתמשו ב-HWC לחלונות מורכבים במקום SurfaceFlinger עם ה-GPU. רוב מעבדי ה-GPU לא מותאמים וכשה-GPU להרכיב שכבות SurfaceFlinger, לא יכול להשתמש ב-GPU לעיבוד בעצמם.

הטמעות HWC צריכות לתמוך ב:

  • לפחות ארבע שכבות-על:
    • שורת סטטוס
    • סרגל המערכת
    • אפליקציה
    • טפט/רקע
  • שכבות גדולות יותר מהמסך (לדוגמה, טפט)
  • מיזוג אלפא לפי מישור ומשולב בו-זמנית מראש אלפא מיזוג
  • נתיב חומרה להפעלת סרטונים מוגן
  • סדר אריזת RGBA, פורמטים של YUV ומשבצות, מפותל וצעד נכסים

כדי להטמיע את HWC:

  1. לבצע HWC לא תפעולי ולשלוח את כל עבודת היצירה אל GLES.
  2. להטמיע אלגוריתם כדי להאציל את היצירה ל-HWC באופן מצטבר. לדוגמה, להקצות רק את שלוש או ארבע הפלטפורמות הראשונות לחומרה של שכבת-העל של ה-HWC.
  3. אופטימיזציה של מרכז האפליקציות (HWC). הפעולות שיהיה צריך לבצע עשויות לכלול את הפעולות הבאות:
    • בחירת פלטפורמות שמגדילות את העומס על ה-GPU וגם שולחים אותם ל-HWC.
    • מתבצע עדכון של המסך. אם לא, האצל בחיבור ל-GLES במקום ל-HWC, כדי לחסוך בסוללה. כאשר המסך עדכונים נוספים, ממשיכים להוריד את העומס על ההרכבה ל-HWC.
    • הכנה לתרחישים נפוצים, כמו:
      • מסך הבית, שכולל את שורת הסטטוס, שורת המערכת והאפליקציה חלון וטפטים מונפשים
      • משחקים במסך מלא במצב פורטרט ובמצב לרוחב
      • צפייה בסרטון במסך מלא עם כתוביות ובקרת הפעלה
      • הפעלת סרטונים מוגנים
      • מסך מפוצל עם כמה חלונות

פרימיטיבים של HWC

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

ממשק HIDL

מערכת Android מגרסה 8.0 ואילך משתמשת ממשק HIDL שנקרא Composer HAL עבור IPC משולב בין HWC ל-SurfaceFlinger. Composer HAL מחליף את לממשק hwcomposer2.h מדור קודם. אם הספקים מספקים הטמעה של Composer HAL ל-HWC, ‏Composer HAL מקבל ישירות קריאות HIDL מ-SurfaceFlinger. אם ספקים מספקים הטמעה מדור קודם של HWC, Composer HAL טוען מצביעי פונקציות מ-hwcomposer2.h, העברת הפעלות HIDL לקריאות של מצביע לפונקציות.

HWC מספק פונקציות כדי לקבוע את המאפיינים של מסך נתון; כדי לעבור בין הגדרות תצוגה שונות (למשל 4k או 1080p רזולוציה) ומצבי צבע (למשל צבע מקורי או sRGB אמיתי). וכדי להפוך המסך מופעל, כבוי או במצב של הספק נמוך, אם הוא נתמך.

מצביע פונקציה

אם ספקים מטמיעים את Composer HAL באופן ישיר, SurfaceFlinger קורא לפונקציות שלו באמצעות HIDL IPC. לדוגמה, כדי ליצור שכבה, הפונקציה SurfaceFlinger createLayer() ב-Composer HAL.

אם ספקים מטמיעים את הממשק של hwcomposer2.h, Composer HAL קריאות לסמנים של פונקציות hwcomposer2.h. בהערות hwcomposer2.h, הפונקציות של ממשק HWC מופיעות בשמות ב-lowerCamelCase שלא קיימים בממשק כשדות עם שם. כמעט כל פונקציה נטענת על ידי בקשה למצביע פונקציה באמצעות getFunction שמסופק על ידי hwc2_device_t. לדוגמה, הפונקציה createLayer הוא מצביע של פונקציה מסוג HWC2_PFN_CREATE_LAYER, מוחזר כאשר הערך המספור HWC2_FUNCTION_CREATE_LAYER הוא הועבר אל getFunction.

לקבלת מידע מפורט על פונקציות Composer HAL ועל מעבר של פונקציית HWC פונקציות, ראו composer. לקבלת הסבר מפורט בנושא מצביעים לפונקציית HWC, hwcomposer2.h

נקודות אחיזה לשכבה ולתצוגה

שכבות ותצוגות מותאמות אישית על ידי נקודות אחיזה שנוצרו על ידי HWC. הכינויים אטומים ל-SurfaceFlinger.

כש-SurfaceFlinger יוצר שכבה חדשה, היא קוראת ל-createLayer, שמחזירה מסוג Layer בשביל תנועה ישירה או hwc2_layer_t להטמעות של צדדים שלישיים. מתי SurfaceFlinger משנה מאפיין של השכבה הזו, PassfaceFlinger את הערך hwc2_layer_t בפונקציית השינוי המתאימה וכל מידע אחר שנדרש לביצוע השינוי. הסוג hwc2_layer_t גדול מספיק בשביל להכיל מצביע או מקש להוסיף לאינדקס.

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

פעולות הרכבה במסך

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

  1. טיפול בעסקאות, אם יש כאלה.
  2. מתבצעת נעילה של מאגרי נתונים גרפיים חדשים, אם יש כאלה.
  3. מבצע הרכבה חדשה, אם שלב 1 או 2 הובילו לשינוי לתוכן התצוגה.

כדי לבצע יצירה חדשה, SurfaceFlinger יוצר משמיד שכבות או משנה מצבי שכבה, לפי הצורך. הוא גם מתעדכן בשכבות עם התוכן הנוכחי שלהן, באמצעות קריאות כמו setLayerBuffer או setLayerColor. אחרי שכל השכבות מעודכן, SurfaceFlinger מתקשר אל validateDisplay, וכך את ה-HWC כדי לבחון את מצב השכבות ולקבוע איך ההרכב להמשיך. כברירת מחדל, SurfaceFlinger מנסה להגדיר כל שכבה כך שהשכבה מורכבת על ידי ה-HWC. אבל בחלק מהמקרים בנסיבות מסוימות, SurfaceFlinger מרכיב שכבות באמצעות החלופה ל-GPU.

אחרי השיחה ל-validateDisplay, SurfaceFlinger מתקשר getChangedCompositionTypes כדי לבדוק אם צוות HWC רוצה לשנות את אחד מסוגי הרכבה של השכבות לפני ביצוע של משפטים יחידים, כדי לאשר את השינויים, SurfaceFlinger קורא ל-acceptDisplayChanges.

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

לבסוף, SurfaceFlinger מתקשר אל presentDisplay כדי לספר את HWC כדי להשלים את תהליך ההרכבה ולהציג את התוצאה הסופית.

מודעות לרשת המדיה בכמה גדלים

Android 10 תומך בכמה מסכים פיזיים. כשמתכננים הטמעת HWC שמיועדת לשימוש ב-Android 7.0 קיימות כמה הגבלות שלא קיימות בהגדרת HWC:

  • ההנחה היא שיש רק מסך פנימי אחד. התוכן הפנימי התצוגה היא התצוגה הראשונית לאתחל. אחרי שהמסך הפנימי מחובר לחשמל, לא ניתן יהיה להיות מנותקים.
  • בנוסף למסך הפנימי, אפשר לחבר מספר בלתי מוגבל של מסכים חיצוניים במהלך הפעולה הרגילה של המכשיר. המסגרת הרעיונית מניחה מחוברים לשקעי חשמל אחרי המסך הפנימי הראשון הם מסכים חיצוניים, כך שאם נוספו מסכים פנימיים, הם מסווגים בטעות בתור Display.TYPE_HDMI במקום Display.TYPE_BUILT_IN.

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

לדוגמה, אם המסך החיצוני מתעדכן, הרצף הוא:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

הרכב המסך הווירטואלי

הרכב המסך הווירטואלי דומה לצג החיצוני של משפטים יחידים, ההבדל בין הרכבה של תצוגה וירטואלית לבין הרכבה פיזית הרכב התצוגה הוא שמסכים וירטואליים שולחים פלט למאגר נתונים זמני של Gralloc במקום למסך. Hardware Composer (HWC) כותב את הפלט למאגר הנתונים, מספק את גדר ההשלמה, ושולח את מאגר הנתונים הזמני לצרכן (למשל מקודד וידאו, GPU, מעבד (CPU) וכן הלאה). במסכים וירטואליים ניתן להשתמש בדו-ממד/בטשטוש או שכבות-על אם צינור עיבוד הנתונים של התצוגה כותב לזיכרון.

מצבים

כל פריים נמצא באחד משלושה מצבים אחרי ש-SurfaceFlinger קורא שיטת HWC validateDisplay():

  • GLES — ה-GPU מורכב מכל השכבות, ככה ישירות למאגר הנתונים הזמני של הפלט. HWC לא מעורב ביצירה.
  • MIXED — ה-GPU מרכיב כמה שכבות ה-framebuffer ו-HWC מרכיבים את ה-framebuffer ואת השכבות שנותרו, לכתוב ישירות למאגר הנתונים הזמני של הפלט.
  • HWC –‏ HWC משלבת את כל השכבות וכותבת ישירות למאגר הפלט.

פורמט פלט

הפורמטים של הפלט של מאגר הנתונים הזמני של התצוגה הווירטואלית תלויים במצב:

  • מצב GLES — מנהל התקן ה-EGL מגדיר את מאגר הנתונים הזמני של הפלט בפורמט dequeueBuffer(), בדרך כלל RGBA_8888. לצרכן צריכה להיות אפשרות לקבל את פורמט הפלט שהנהג מגדיר או לא ניתן לקרוא את מאגר הנתונים הזמני.
  • מצבי MIXED ו-HWC – אם הצרכן צריך מעבד (CPU) גישה, הצרכן מגדיר את הפורמט. אחרת, הפורמט הוא IMPLEMENTATION_DEFINED ו-Gralloc מגדיר את הפורמט הטוב ביותר על סמך דגלי השימוש. לדוגמה, Gralloc מגדירה פורמט YCbCr אם הצרכן מקודד וידאו ו-HWC יכולים לכתוב את הפורמט ביעילות.

גדרות סנכרון

גדרות סנכרון (סנכרון) הן היבט חיוני בגרפיקה של Android המערכת. גדרות מאפשרות למעבד (CPU) לפעול בנפרד מעבודה של GPU בו-זמנית, חסימה רק כשיש תלות אמיתית.

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

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

מידע נוסף על גדרות סנכרון זמין במאמר Hardware Composer שילוב.