החל מגרסה 13 של Android, מתבצעת הקצאה של מאגרי framebuffer חדשים, שמשמשים במהלך היצירה של הלקוח, בכל פעם שרזולוציית המסך משתנה. הקצאה זו מתבצעת על ידי SurfaceFlinger במחזור הinvalidate הבא אחרי שינוי הרזולוציה.
ניהול של framebuffer במהלך מעברים בין רזולוציות
שינויים ברזולוציה מתרחשים בגלל אחד משני התרחישים הבאים:
אירוע hotplug, שמופעל על ידי Hardware Composer (HWC), שמתרחש כשמעבירים מסך חיצוני אחד למסך חיצוני אחר עם רזולוציית ברירת מחדל שונה.
במהלך אירוע hotplug, הלחצנים של מסכי ה-framebuffer הישנים משוחררים כשהקצאת הנתונים הישנים של המסך מבוטלת.
מעבר של מצב התצוגה שמופעל על ידי SurfaceFlinger, שמתרחש כשהמשתמש משנה את הרזולוציה באמצעות הגדרות המשתמש, או כשאפליקציה משנה את הרזולוציה באמצעות
preferredDisplayModeId
.במהלך מעבר בין מצבי תצוגה, SurfaceFlinger משחרר את הלחצנים של מאגרי ה-framebuffer הקיימים של הלקוח לפני שהוא קורא ל-
setActiveConfig
או ל-setActiveConfigWithConstraints
.
כדי למנוע בעיות חמורות, כמו פיצול זיכרון, במכשירים שלא שומרים מספיק זיכרון למערכי ה-framebuffer הישנים והחדשים, חשוב מאוד ש-HWC יפסיק להשתמש במערכי ה-framebuffer הישנים וישחרר את כל ה-handles למערכי ה-framebuffer האלה, כפי שמתואר במקרים הבאים:
באירועי hotplug, מיד לפני הקריאה ל-
onHotplug
.במעברי מצב, מיד אחרי הקריאה ל-
setActiveConfig
או ל-setActiveConfigWithConstraints
.
שחרור הלחצנים מאפשר לבטל את ההקצאה של זיכרון framebuffer באופן מלא לפני ההקצאה של framebuffers חדשים, שתתבצע על ידי SurfaceFlinger במהלך המחזור הבא של invalidate.
המלצות לניהול של framebuffer
אם ה-HWC לא משחרר את הלחצנים של מסכי ה-framebuffer הישנים בזמן, הקצאת ה-framebuffer החדשה מתרחשת לפני הביטול של הקצאת ה-framebuffer הישן. מצב כזה עלול לגרום לבעיות חמורות אם ההקצאה החדשה נכשלת בגלל פיצול או בעיות אחרות. גרוע מכך, אם ה-HWC לא משחרר את ה-handles האלה בכלל, יכולה להתרחש דליפת זיכרון.
כדי למנוע כשלים חמורים בהקצאה, מומלץ לפעול לפי ההמלצות הבאות:
אם HWC צריך להמשיך להשתמש במאגרי ה-framebuffer הישנים של הלקוח עד שמקבלים את מאגרי ה-framebuffer החדשים של הלקוח, חשוב להקצות מספיק זיכרון גם למאגר ה-framebuffer הישן וגם למאגר ה-framebuffer החדש, ואולי גם להריץ אלגוריתמים לפינוי מקום במרחב הזיכרון של מאגר ה-framebuffer.
הקצאת מאגר זיכרון ייעודי למאגרי הפריימים, נפרד משאר זיכרון מאגר הנתונים הגרפי. זה חשוב כי בין ביטול ההקצאה לבין ההקצאה מחדש של מאגרי הפריימים, תהליך של צד שלישי יכול לנסות להקצות זיכרון גרפיקה. אם אותו מאגר של זיכרון גרפיקה משמש את מאגר ה-framebuffer, ואם זיכרון הגרפיקה מלא, התהליך של הצד השלישי יכול לתפוס את זיכרון הגרפיקה שהוקצה בעבר על ידי מאגר ה-framebuffer, וכך לא יישאר מספיק זיכרון להקצאה מחדש של מאגר ה-framebuffer, או שיכול להיות שיגרום לפיצול של מרחב הזיכרון.
בדיקת ניהול של מאגר הפריימים
יצרני ציוד מקורי מומלצים לבדוק אם יש ניהול תקין של זיכרון framebuffer של לקוח במעברים בין רזולוציות במכשיר שלהם, כפי שמתואר בהמשך:
כדי ליצור אירועי hotplug, פשוט מנתקים שני מסכים שונים עם רזולוציות שונות ומחברים אותם מחדש.
כדי לבצע מעבר בין מצבים, משתמשים בבדיקה
ModeSwitchingTestActivity
של CTS Verifier כדי להתחיל מעבר בין מצבים לצורך בדיקת ההתנהגות של זיכרון framebuffer. הבדיקה הזו מאפשרת לזהות באופן ויזואלי בעיות שקשה לזהות אותן באופן פרוגרמטי.