ב-Android 13 מוצגת ספרייה סטטית שניתנת להגדרה על ידי הספק בשם libtonemap
, שמגדירה פעולות של מיפוי גוונים ומשותפת לתהליך SurfaceFlinger וליישומים של Hardware Composer (HWC).
התכונה הזו מאפשרת ליצרני ציוד מקורי (OEM) להגדיר ולשתף את האלגוריתמים שלהם למיפוי טונים של התצוגה בין המסגרת לבין הספקים, וכך לצמצם את חוסר ההתאמה במיפוי הטונים.
לפני Android 13, פעולות מיפוי טונים ספציפיות לתצוגה לא שותפו בין HWC, SurfaceFlinger ואפליקציות. בהתאם לנתיב העיבוד, כשמדובר בתוכן HDR, זה הוביל לחוסר התאמה באיכות התמונה, כי תוכן ה-HDR עבר מיפוי טונים למרחב פלט בדרכים שונות. הדבר היה מורגש בתרחישים כמו סיבוב המסך, שבהם אסטרטגיית הקומפוזיציה משתנה בין ה-GPU ל-DPU, ובהבדלים בהתנהגות העיבוד בין TextureView ל-SurfaceView.
בדף הזה מתואר הממשק, ההתאמה האישית ופרטי האימות של הספרייה libtonemap
.
ממשק לספריית מיפוי הגוונים
הספרייה libtonemap
מכילה הטמעות שמגובות על ידי CPU ו-shaders של SkSL, שאפשר לחבר אותם על ידי SurfaceFlinger להרכבה של קצה עורפי של GPU, ועל ידי HWC ליצירה של טבלת בדיקה (LUT) למיפוי טונים. נקודת הכניסה ל-libtonemap
היא android::tonemap::getToneMapper()
, שמחזירה אובייקט שמיישם את הממשק ToneMapper
.
ממשק ToneMapper
תומך ביכולות הבאות:
יצירת טבלת מיפוי טונים
הממשק
ToneMapper::lookupTonemapGain
הוא הטמעה של ה-CPU של ה-Shader שמוגדר ב-libtonemap_LookupTonemapGain()
. הערך הזה משמש לבדיקות יחידה במסגרת, ושותפים יכולים להשתמש בו כדי לקבל עזרה ביצירת LUT למיפוי גוונים בתוך צינור הצבעים שלהם.
libtonemap_LookupTonemapGain()
מקבלת ערכי צבע במרחב לינארי לא מנורמל, גם ב-RGB לינארי וגם ב-XYZ, ומחזירה ערך מסוג float שמתאר בכמה צריך להכפיל את צבעי הקלט במרחב לינארי.יצירת הצללה של SkSL
הממשק
ToneMapper::generateTonemapGainShaderSkSL()
מחזיר מחרוזת של הצללה ב-SkSL, בהינתן מרחב נתונים של מקור ויעד. ה-shader של SkSL מחובר להטמעה של Skia ב-RenderEngine
, רכיב ההרכבה שמואץ על ידי GPU ב-SurfaceFlinger. ה-shader מחובר גם ל-libhwui
, כדי שמיפוי הטונים מ-HDR ל-SDR יוכל להתבצע ביעילות עבורTextureView
. מכיוון שהמחרוזת שנוצרה מוטמעת ב-shaders אחרים של SkSL שמשמשים את Skia, ה-shader חייב לעמוד בכללים הבאים:- מחרוזת ה-shader חייבת לכלול נקודת כניסה עם החתימה
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, כאשרlinearRGB
הוא הערך של הניטים המוחלטים של פיקסלי ה-RGB במרחב לינארי, ו-xyz
הואlinearRGB
שהומר ל-XYZ. - לכל שיטות העזר שמשמשות את מחרוזת ה-shader צריך להוסיף את הקידומת
libtonemap_
כדי שלא יהיה ניגוד בין הגדרות ה-shader של המסגרת. באופן דומה, התחילית של נתוני קלט אחידים צריכה להיותin_libtonemap_
.
- מחרוזת ה-shader חייבת לכלול נקודת כניסה עם החתימה
יצירת משתנים אחידים של SkSL
הממשק
ToneMapper::generateShaderSkSLUniforms()
מחזיר את הערכים הבאים, בהינתן מטא-נתוניםstruct
שמתארים מטא-נתונים מתקנים שונים של HDR ותנאי תצוגה:רשימה של משתנים אחידים שקשורים ל-shader של SkSL.
הערכים האחידים
in_libtonemap_displayMaxLuminance
ו-in_libtonemap_inputMaxLuminance
. הערכים האלה משמשים את shaders של המסגרת כשמבצעים שינוי קנה מידה של הקלט ל-libtonemap
, ומנרמלים את הפלט לפי הצורך.
בשלב הזה, תהליך יצירת המשתנים האחידים לא תלוי במרחב הנתונים של הקלט והפלט.
התאמה אישית
הטמעת ההפניה של ספריית libtonemap
מניבה תוצאות מקובלות. עם זאת, יכול להיות שאלגוריתם מיפוי הטונים שמשמש להרכבה ב-GPU יהיה שונה מזה שמשמש להרכבה ב-DPU, ולכן שימוש בהטמעה לדוגמה עלול לגרום להבהוב בתרחישים מסוימים, כמו אנימציית סיבוב. התאמה אישית יכולה לפתור בעיות כאלה באיכות התמונה שספציפיות לספק.
מומלץ מאוד ליצרני ציוד מקורי (OEM) לבטל את ההטמעה של libtonemap
כדי להגדיר מחלקת משנה משלהם ToneMapper
, שמוחזרת על ידי getToneMapper()
.
כשמבצעים התאמה אישית של ההטמעה, השותפים צריכים לבצע אחת מהפעולות הבאות:
- לשנות את ההטמעה של
libtonemap
ישירות. - להגדיר ספרייה סטטית משלהם, לקמפל את הספרייה כספרייה עצמאית ולהחליף את קובץ
libtonemap
הספרייה.a
בקובץ שנוצר מהספרייה המותאמת אישית שלהם.
הספקים לא צריכים לשנות קוד ליבה כלשהו, אבל כמה ספקים צריכים לתקשר פרטים על האלגוריתמים של מיפוי הטונים של ה-DPU כדי להבטיח הטמעה נכונה.
אימות
כדי לאמת את ההטמעה:
הפעלת סרטוני HDR במסך בכל תקן HDR שמערכת התצוגה תומכת בו, כמו HLG, HDR10, HDR10+ או DolbyVision.
כדאי להפעיל או להשבית את ההגדרה 'הוספת שכבות על ידי GPU' כדי לוודא שלא יהיו הבהובים שמשתמשים יוכלו לראות.
כדי להפעיל או להשבית את ההרכבה של ה-GPU, משתמשים בפקודה
adb
הבאה:adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition, 1 to force GPU composition>
בעיות נפוצות
יכולות להיות בעיות בהטמעה מהסוג הזה:
התופעה של פסים נוצרת כשמטרת הרינדור שמשמשת להרכבת ה-GPU היא בעלת דיוק נמוך מהערך האופייני לתוכן HDR. לדוגמה, יכול להיות שיופיעו פסי צבע אם הטמעה של HWC תומכת בפורמטים אטומים של 10 ביט ל-HDR, כמו RGBA1010102 או P010, אבל מחייבת שהרכבת GPU תכתוב לפורמט של 8 ביט כמו RGBA8888 כדי לתמוך באלפא.
הבדלים בכמות המידע שמוצג גורמים לשינוי קל בצבע אם ה-DPU פועל ברמת דיוק שונה מזו של ה-GPU.
כל אחת מהבעיות האלה קשורה להבדלים בדיוק היחסי של החומרה הבסיסית. פתרון עקיף נפוץ הוא לוודא שיש שלב של דית'רינג (dithering) בנתיבים עם דיוק נמוך יותר, כך שההבדלים בדיוק פחות מורגשים.