ב-Android 11 נוספה תמיכה במכשירים עם קצב רענון משתנה. התכונה הזו כוללת שלושה רכיבים עיקריים:
- ממשקי HAL API חדשים שהוצגו בגרסה
android.hardware.graphics.composer@2.4. - קוד פלטפורמה לניתוח הגדרות המכשיר לקצב רענון שונה ולהגדרת קצב הרענון הרצוי
- ממשקי API חדשים של SDK ו-NDK שמאפשרים לאפליקציות להגדיר את קצב הפריימים הרצוי
הטמעה
נוסף תמיכה ייעודית להחלפת קצב רענון ב… מומלץ מאוד להשתמש בגרסה הזו כי בגרסאות קודמות של composer HAL יש תמיכה מוגבלת בהחלפת קצב רענון.
קבוצות הגדרות
מאפיין חדש, CONFIG_GROUP, נוסף ל-IComposerClient::Attribute שאפשר להריץ עליו שאילתות באמצעות getDisplayAttribute_2_4 API. המאפיין הזה מאפשר לספקים לקבץ הגדרות תצוגה. הגדרות באותה קבוצה מאפשרות מעבר חלק ביניהן ברוב המקרים. הפלטפורמה משתמשת בקבוצת ההגדרות כדי להבחין בין ההגדרות שאפשר לעבור ביניהן, כדי לשנות את קצב הרענון ולא מאפיינים אחרים בהגדרה.
בדוגמה הבאה אפשר לראות את היתרונות של שימוש בקבוצות הגדרות במכשיר שתומך בארבע הגדרות תצוגה:
- 1080p@60Hz
- 1080p@90Hz
- 1080i@72Hz
- 1080i@48Hz
למרות שהמכשיר תומך בקצב רענון של 48Hz, 60Hz, 72Hz ו-90Hz, המסך פועל במצב אחר, ומעבר מ-60Hz ל-72Hz משנה את הגדרת המסך מ-1080p ל-1080i, וזה לא בהכרח מה שרוצים. הגדרות לקבוצות משתמשים פותרות את הבעיה הזו. אם מקבצים את 60Hz ו-90Hz בקבוצת הגדרות אחת, ואת 48Hz ו-72Hz בקבוצת הגדרות אחרת, הפלטפורמה יודעת שהיא יכולה לעבור בין 60Hz ל-90Hz ובין 48Hz ל-72Hz, אבל לא בין 60Hz ל-72Hz, כי זה יוביל לשינוי בהגדרות ולא רק לשינוי בקצב הרענון.
עדכונים ב-Composer API
- getDisplayVsyncPeriod
- כדי לשפר את השליטה ואת יכולת החיזוי כשמשנים את קצב הרענון, נוספה האפשרות
getDisplayVsyncPeriod. getDisplayVsyncPeriodמחזירה את קצב הרענון הנוכחי (במונחים של תקופת סנכרון אנכי) שבו המסך פועל. האפשרות הזו שימושית במיוחד כשעוברים בין קצב רענון, והפלטפורמה צריכה את קצב הרענון הנוכחי כדי להחליט מתי להתחיל את הפריים הבא. - setActiveConfigWithConstraints
- Method
setActiveConfigWithConstraintsהוא תוסף חדש ל-method setActiveConfigהקיים, והוא מספק מידע נוסף על שינוי ההגדרה. האילוצים מופיעים כחלק מהפרמטריםvsyncPeriodChangeConstraintsוכוללים את הפרמטרים הבאים. - desiredTimeNanos
- הזמן ב-
CLOCK_MONOTONICשאחריו יכולה להשתנות התקופה בין סנכרון אנכי (כלומר, התקופה בין סנכרון אנכי לא יכולה להשתנות לפני הזמן הזה). האפשרות הזו שימושית כשהפלטפורמה רוצה לתכנן מראש שינוי בקצב הרענון, אבל כבר יש לה כמה מאגרי נתונים זמניים בתור להצגה. הפלטפורמה מגדירה את הזמן הזה בהתאם כדי להתחשב במרווחי הזמן האלה ולוודא שהמעבר לקצב הרענון יהיה חלק ככל האפשר. - seamlessRequired
- אם הערך הוא true, שינוי התקופה של סנכרון אנכי (vsync) צריך להתבצע בצורה חלקה, בלי שיופיעו חפצים חזותיים בולטים. הפלטפורמה משתמשת בדגל הזה כשצריך לשנות את קצב הרענון כתוצאה משינוי בתוכן (לדוגמה, המכשיר לא פעיל והאנימציה מתחילה). כך הספק יכול למנוע שינויים מסוימים בהגדרות אם הם עלולים לגרום לאפקט ויזואלי בולט. אם אי אפשר לשנות את ההגדרות בצורה חלקה וערך המשתנה
seamlessRequiredהואtrue, ההטמעה צפויה להחזיר את הערךSEAMLESS_NOT_POSSIBLEכקוד החזרה ולהפעיל את הקריאה החוזרתonSeamlessPossibleהחדשה כשניתן לבצע את אותו שינוי בהגדרות בצורה חלקה. אם ההטמעה מצליחה, היא מחזירה את הערך
VsyncPeriodChangeTimelineשמציין לפלטפורמה מתי צפוי להתרחש השינוי בקצב הרענון.newVsyncAppliedTimeNanosצריך להגדיר את הפרמטרים לזמן ב-CLOCK_MONOTONICשבו התצוגה החדשה תתחיל לרענן במחזור ה-Vsync החדש. הפרמטר הזה, יחד עםdesiredTimeNanos, מאפשר לפלטפורמה לתכנן מראש את המעבר לקצב הרענון החדש ולהתחיל להפעיל את האפליקציות בקצב הרענון החדש מראש. כך מתאפשר מעבר חלק בין קצבי הרענון.ביישומים מסוימים צריך לשלוח מסגרת רענון לפני שאפשר לשלוח את קצב הרענון. לשם כך, ל-HAL יש את הפרמטר
refreshRequiredשמציין שצריך לרענן את הפריים, ואת הפרמטרrefreshTimeNanosשמציין את הסנכרון האנכי הראשון שבו צריך לשלוח את הפריים לרענון אחריו.- onVsyncPeriodTimingChanged [callback]
- פונקציית קריאה חוזרת חדשה ש-HAL יכול לקרוא לה כדי לציין לפלטפורמה שפרמטר מסוים בציר הזמן השתנה, ושהפלטפורמה צריכה להתאים את ציר הזמן שלה. הקריאה החוזרת הזו צפויה להתבצע אם מסיבה כלשהי ציר הזמן הישן לא הגיע בגלל זמן עיבוד ארוך ב-HAL או בגלל רענון מאוחר של המסגרת.
איך הפלטפורמה מחליטה לשנות את קצב הרענון?
בחירת קצב הרענון מתבצעת בשני שירותי המערכת הבאים:
- DisplayManager
- The
DisplayManagersets the high level policy around the refresh rate. היא מגדירה את תצורת התצוגה שמוגדרת כברירת מחדל, שהיא זהה לתצורת ה-HAL של ה-Composer. בנוסף, הוא מגדיר טווח של ערכים מינימליים ומקסימליים שמהםSurfaceFlingerיכול לבחור את קצב הרענון. - SurfaceFlinger
- קובעת את קצב הרענון על ידי הגדרת תצורה שנמצאת באותה קבוצת תצורה כמו תצורת ברירת המחדל, וקצב הרענון שלה נמצא בטווח המינימלי/מקסימלי.
כדי לקבוע את המדיניות, המרכז לניהול מודעות לרשת המדיה מבצע את השלבים הבאים:
- הפונקציה מוצאת את מזהה הגדרת ברירת המחדל על ידי שליחת שאילתה להגדרה הפעילה מ-
SurfaceFlinger - הגבלת הטווח של ערכי המינימום והמקסימום על ידי איטרציה על תנאי המערכת
- הגדרת קצב רענון ברירת המחדל: ערך ברירת המחדל של קצב הרענון מוגדר בשכבת העל של ההגדרה
R.integer.config_defaultRefreshRate. הערך הזה משמש לקביעת קצב הרענון הסטנדרטי של המכשיר לאנימציות ולאינטראקציות עם מסך המגע. - הגדרה של קצב רענון מרבי: הערך של קצב הרענון המרבי נקרא מ-
Settings.System.PEAK_REFRESH_RATE. הערך הזה משתנה בזמן הריצה כדי לשקף את ההגדרה הנוכחית של המכשיר (למשל, מתוך אפשרות בתפריט). ערך ברירת המחדל מוגדר בשכבת העל של התצורהR.integer.config_defaultPeakRefreshRate. - הגדרה של קצב רענון מינימלי: הערך של קצב הרענון המינימלי נקרא מ-
Settings.System.MIN_REFRESH_RATE. אפשר לשנות את הערך הזה בזמן הריצה כדי לשקף את ההגדרה הנוכחית של המכשיר (למשל, מתוך אפשרות בתפריט). ערך ברירת המחדל הוא 0, כך שאין ערך מינימלי שמוגדר כברירת מחדל. - מזהה מצב שהאפליקציה ביקשה: אפליקציות יכולות להגדיר את
WindowManager.LayoutParams.preferredDisplayModeIdכדי לשקף את ההגדרה המועדפת שבה המסך צריך לפעול. ברוב המקרים, הפקודהDisplayManagerמגדירה את מזהה ברירת המחדל של התצורה בהתאם, ומגדירה את קצב הרענון המינימלי והמקסימלי כך שיתאימו לקצב הרענון של התצורה. - חיסכון בסוללה: קצב הרענון מוגבל ל-60 הרץ או פחות כשהמכשיר במצב צריכת חשמל נמוכה, שמסומן באמצעות
Settings.Global.LOW_POWER_MODE.
- הגדרת קצב רענון ברירת המחדל: ערך ברירת המחדל של קצב הרענון מוגדר בשכבת העל של ההגדרה
אחרי ש-DisplayManager מגדיר את המדיניות, SurfaceFlinger מגדיר את קצב הרענון על סמך השכבות הפעילות (שכבות שמעדכנות את המסגרות בתור). אם הבעלים של השכבה מגדיר קצב פריימים, SurfaceFlinger מנסה להגדיר את קצב הרענון למכפלה של הקצב הזה.
לדוגמה, אם בשתי שכבות פעילות מוגדר קצב פריימים של 24 ו-60, SurfaceFlinger יבחר 120Hz אם הוא זמין. אם קצב הרענון הזה לא זמין ל-SurfaceFlinger, הוא ינסה לבחור את קצב הרענון עם השגיאה המינימלית עבור קצב הפריימים. מידע נוסף זמין במסמכי התיעוד למפתחים באתר developer.android.com
SurfaceFlinger שומר על הדגלים הבאים כדי לשלוט באופן שבו נקבע קצב הרענון:
ro.surface_flinger.use_content_detection_for_refresh_rate:אם ההגדרה הזו מוגדרת, קצב הרענון נקבע על סמך השכבות הפעילות, גם אם לא הוגדר קצב פריימים. SurfaceFlinger שומר על היוריסטיקה שבה הוא מוצא את מספר הפריימים לשנייה הממוצע שהשכבה מפרסמת מאגרי נתונים על ידי בדיקת חותמת הזמן של ההצגה שמצורפת למאגר הנתונים.-
ro.surface_flinger.set_touch_timer_ms: אם הערך גדול מ-0, קצב הרענון שמוגדר כברירת מחדל ישמש כשהמשתמש יגע במסך למשך הזמן שהוגדר כפסק זמן. ההיוריסטיקה הזו מתבצעת כדי להיות מוכנים עם קצב הרענון שמוגדר כברירת מחדל לאנימציות. -
ro.surface_flinger.set_idle_timer_ms: אם הערך גדול מ-0, קצב הרענון המינימלי ישמש כשאין עדכונים במסך למשך הזמן הקצוב לתפוגה שהוגדר. -
ro.surface_flinger.set_display_power_timer_ms: אם הערך גדול מ-0, קצב הרענון שמוגדר כברירת מחדל ישמש להפעלת המסך (או ליציאה ממצב תצוגה פעילה תמיד) למשך הזמן שהוגדר לטיימאוט.
Frame Rate API
ממשק ה-API של קצב הפריימים מאפשר לאפליקציות להודיע לפלטפורמת Android מהו קצב הפריימים המיועד שלהן, והוא זמין באפליקציות שמטרגטות ל-Android 11. מידע נוסף על Frame Rate API זמין בתיעוד למפתחים בכתובת developer.android.com.
אפשרויות למפתחים
נוספה לתפריט אפשרות חדשה למפתחים שמאפשרת להפעיל או להשבית שכבת-על בתצוגה עם קצב הרענון הנוכחי. האפשרות החדשה נמצאת בהגדרות > מערכת > אפשרויות למפתחים > הצגת קצב הרענון.