יכולות המסך (כמו מצבי תצוגה וסוגים נתמכים של HDR) יכולות להשתנות באופן דינמי במכשירים עם מסכים מחוברים חיצונית (באמצעות HDMI או DisplayPort), כמו ממירי Android TV ומכשירי OTT. השינוי הזה יכול לקרות כתוצאה מאות של חיבור חם ב-HDMI, למשל כשהמשתמש עובר ממסך אחד למסך אחר או מפעיל את המכשיר בלי מסך מחובר. ב-Android מגרסה 12 ואילך יש שינויים במסגרת לטיפול ביכולות של חיבור חם ותצוגה דינמית.
בדף הזה מוסבר איך מטפלים בהתקנה חמה של צגים ובשינויים ביכולות של הצגים בהטמעת HAL של Composer. בנוסף, מוסבר איך לנהל את framebuffer המשויך ולמנוע מרוץ תנאים במצבים כאלה.
עדכון יכולות התצוגה
בקטע הזה מוסבר איך מסגרת Android מטפלת בשינויים ביכולות התצוגה שמתחילים ב-Composer HAL.
כדי שמערכת Android תוכל לטפל כראוי בשינויים ביכולות התצוגה, יצרני הציוד המקורי צריכים להטמיע את Composer HAL כך שישתמש ב-onHotplug(display, connection=CONNECTED)
כדי להודיע למסגרת על כל שינוי ביכולות התצוגה. אחרי ההטמעה, Android מטפלת בשינויים ביכולות התצוגה באופן הבא:
- כשהמערכת מזהה שינוי ביכולות התצוגה, היא מקבלת התראה מסוג
onHotplug(display, connection=CONNECTED)
. - כשמתקבלת ההתראה, המסגרת משחררת את מצב התצוגה שלה ויוצרת אותו מחדש עם היכולות החדשות מ-HAL באמצעות השיטות
getActiveConfig
,getDisplayConfigs
,getDisplayAttribute
,getColorModes
,getHdrCapabilities
ו-getDisplayCapabilities
. - אחרי שהמסגרת יוצרת מחדש מצב תצוגה חדש, היא שולחת את הפונקציה החוזרת (callback)
onDisplayChanged
לאפליקציות שמקשיבות לאירועים כאלה.
המסגרת מקצה מחדש את מאגרי ה-framebuffer באירועי onHotplug(display, connection=CONNECTED)
עתידיים. במאמר ניהול framebuffer של לקוח מוסבר איך לנהל כראוי את זיכרון ה-framebuffer כדי למנוע כשלים במהלך הקצאת framebuffers חדשים.
טיפול בתרחישי חיבור נפוצים
בקטע הזה מוסבר איך לטפל כראוי בתרחישי חיבור שונים בהטמעות שלכם כשהמסך הראשי מחובר וכשלא מחובר.
מסגרת Android נוצרה למכשירים ניידים, ולכן אין בה תמיכה מובנית במסך ראשי מנותק. במקום זאת, ה-HAL צריך להחליף את המסך הראשי במסך placeholder באינטראקציות שלו עם המסגרת, במקרה שהמסך הראשי מנותק פיזית.
התרחישים הבאים יכולים להתרחש ב-STB ובמתאמי TV שיש להם מסכים שמחוברים באופן חיצוני ואפשר לנתק אותם. כדי להטמיע תמיכה בתרחישים האלה, אפשר להיעזר במידע בטבלה הבאה:
תרחיש | שימוש |
---|---|
אין מסך מחובר בזמן האתחול |
|
המסך הראשי מחובר פיזית |
|
המסך הראשי מנותק פיזית |
|
שיקולים לגבי חיבור שאינו HDMI
ב-Android TV יש תמיכה רק ברזולוציות הבאות:
- 720x1280
- 1080x1920
- 2160x3840
- 4320x7680
כש-STB או מתאם טלוויזיה מנסים להציג רזולוציה שלא נתמכת, כמו 480i בחיבור CVBS, מוצגת למשתמש הודעת שגיאה.
אם ל-STB או ל-TV dongle יש חיבורי HDMI וגם חיבורים אחרים, חיבור ה-HDMI הוא המסך הראשי והחיבור שאינו HDMI לא פעיל. כתוצאה מכך, אם חיבור ה-HDMI מנותק בזמן שחיבור שאינו HDMI עדיין מחובר, מתבצע שליחת אירוע אל SurfaceFlinger, והיכולות של המסך שאינו HDMI צריכות לעבור דרך getDisplayAttribute
ו-API אחרים של iComposerClient
(כמו getHdrCapabilities
).
שימוש במזהי תצורה ברצף כדי למנוע מרוץ תהליכים
תנאי מרוץ יכולים להתרחש אם ה-HAL של Composer מעדכן את הגדרות התצוגה הנתמכות בו-זמנית עם הקריאה של המסגרת ל-setActiveConfig
או ל-setActiveConfigWithConstraints
.
הפתרון הוא להטמיע את Composer HAL כך שישתמש במזהים רציפים כדי למנוע את הבעיה הזו.
בקטע הזה מוסבר איך מרוץ התהליכים יכול להתרחש, ולאחר מכן מוסבר איך להטמיע את Composer HAL כך שישתמש במזהים רציפים כדי למנוע תנאים כאלה.
נניח את רצף האירועים הבא, שבו לא הוקצו מזהי רצף חדשים להגדרות התצוגה החדשות, וכתוצאה מכך נוצר מצב מרוץ:
מזהי התצורה הנתמכים של התצוגה הם:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
המסגרת קוראת ל-
setActiveConfig(display, config=1)
.במקביל, ה-HAL של Composer מעבד שינוי בהגדרות התצוגה ומעדכן את המצב הפנימי שלו לקבוצה חדשה של הגדרות תצוגה, כפי שמתואר בהמשך:
- id=1, 2160x3840 60 Hz
- id=2, 2160x3840 50 Hz
- id=3, 1080x1920 60 Hz
- id=4, 1080x1920 50 Hz
Composer HAL שולח לארגז הכלים אירוע
onHotplug
כדי להודיע על שינוי בקבוצת המצבים הנתמכים.ה-HAL של Composer מקבל את
setActiveConfig(display, config=1)
(משלב 2).ה-HAL מפרש שהמסגרת ביקשה שינוי בהגדרה ל-2160x3840 60 Hz, אבל בפועל רצתה 1080x1920 60 Hz.
התהליך שמשתמש בהקצאות מזהה לא רצופות מסתיים כאן עם פרשנות שגויה של שינוי התצורה הרצוי.
הגדרת Composer HAL לשימוש במזהים עוקבים
כדי למנוע תנאי מרוץ כאלה, יצרני הציוד המקורי צריכים להטמיע את HAL של Composer באופן הבא:
- כש-HAL של Composer מעדכן את הגדרות התצוגה הנתמכות, הוא מקצה מזהי רצף חדשים להגדרות התצוגה החדשות.
- כשהמסגרת קוראת ל-
setActiveConfig
או ל-setActiveConfigWithConstraints
עם מזהה תצורה לא תקין, ה-HAL של Composer מתעלם מהקריאה.
השלבים האלה נועדו למנוע מרוץ תהליכים, כפי שמתואר בהמשך.
רצף האירועים הבא מתייחס למקרה שבו המערכת מקצה מזהי רצף חדשים להגדרות התצוגה החדשות:
מזהי התצורה הנתמכים של התצוגה הם:
- id=1, 1080x1920 60 Hz
- id=2, 1080x1920 50 Hz
המסגרת קוראת ל-
setActiveConfig(display, config=1)
.כשמתבצע עיבוד של שינוי בהגדרות התצוגה, המערכת מקצה את קבוצת מזהי ההגדרות הבאה, החל ממספר שלם לא מנוצל הבא בתור, כפי שמתואר בהמשך:
id=3, 2160x3840 60 Hz
id=4, 2160x3840 50 Hz
id=5, 1080x1920 60 Hz
id=6, 1080x1920 50 Hz
ה-HAL של Composer שולח לארגז הכלים אירוע
onHotplug
כדי להודיע על שינוי בקבוצת המצבים הנתמכים.ה-HAL של Composer מקבל את
setActiveConfig(display, config=1)
(משלב 2).ה-HAL של Composer מתעלם מהקריאה כי המזהה כבר לא בתוקף.
המסגרת מקבלת ומעבדת את האירוע
onHotplug
משלב 4. הוא קורא ל-HAL של Composer באמצעות הפונקציותgetDisplayConfigs
ו-getDisplayAttribute
. באמצעות הפונקציות האלה, המסגרת מזהה את המזהה החדש (5) לרזולוציה ולקצב הרענון הרצויים של 1080x1920 ו-60 Hz.המסגרת שולחת אירוע
setActiveConfig
נוסף עם מזהה מעודכן של 5.ה-HAL של Composer מקבל את
setActiveConfig(display, config=5)
משלב 5.ה-HAL מפרש בצורה נכונה שהמסגרת ביקשה שינוי של ההגדרות ל-1080x1920 60 Hz.
כפי שמוצג בדוגמה שלמעלה, התהליך שמשתמש בהקצאות של מזהי רצף מבטיח שהמרוץ בין תהליכים יונעם, וששינוי ההגדרה הנכון של התצוגה יתעדכן.