ב-Android 13 מוצגת ספרייה סטטית שאפשר להגדיר על ידי הספק, בשם libtonemap
, שמגדירה פעולות של מיפוי טונים, ומשותפת עם תהליך SurfaceFlinger ו-HWC של Hardware Composer.
התכונה הזו מאפשרת ליצרני ציוד מקורי להגדיר ולשתף את האלגוריתמים שלהם למיפוי טון התצוגה בין ה-framework לבין הספקים, וכך לצמצם את אי-ההתאמה במיפוי הגוונים.
לפני Android 13, פעולות מיפוי טונים ספציפיות למסך לא שותפו בין HWC, SurfaceFlinger והאפליקציות. בהתאם לנתיב הרינדור, בתוכן HDR התרחשו אי-התאמות באיכות התמונה, כאשר הטון של תוכן ה-HDR מופה לשטח פלט בדרכים שונות. ניתן היה לראות זאת בתרחישים כמו סיבוב המסך, שבהם אסטרטגיית ההרכבה משתנה בין ה-GPU ל-DPU, ובהבדלים בהתנהגות הרינדור בין TextureView לבין SurfaceView.
בדף הזה מתוארים פרטי הממשק, ההתאמה האישית ופרטי האימות של ספריית libtonemap
.
ממשק לספריית מיפוי הגוונים
הספרייה libtonemap
מכילה הטמעות בגיבוי מעבד (CPU) ורכיבי הצללה (shader) של SkSL, שאפשר לחבר על ידי SurfaceFlinger להרכבת קצה עורפי של GPU ועל ידי HWC ליצירת טבלת חיפוש של מיפוי גוונים (LUT). נקודת הכניסה ל-libtonemap
היא android::tonemap::getToneMapper()
, שמחזירה אובייקט שמטמיע את הממשק ToneMapper
.
הממשק ToneMapper
תומך ביכולות הבאות:
יצירת טבלת LUT למיפוי גוונים
הממשק
ToneMapper::lookupTonemapGain
הוא הטמעה של תוכנת ההצללה (shader) שהוגדרה ב-libtonemap_LookupTonemapGain()
במעבד (CPU). ה-LUT הזה משמש את בדיקות היחידה במסגרת, ושותפים יכולים להשתמש בו כדי לקבל עזרה ביצירת LUT של מיפוי גוונים בצינור עיבוד הנתונים של הצבעים.libtonemap_LookupTonemapGain()
מקבלת ערכי צבעים במרחב ליניארי מוחלט ולא נורמלי, גם ב-RGB ליניארי וגם ב-XYZ, ומחזירה מספר ממשי (float) שמתאר את שיעור ההכפלה של צבעי הקלט במרחב הלינארי.יצירת שובר SkSL
הממשק
ToneMapper::generateTonemapGainShaderSkSL()
מחזיר מחרוזת של שפת שדרן (shader) ב-SkSL, בהתאם למרחב הנתונים של המקור והיעד. ה-shader של SkSL מחובר להטמעה של Skia עבורRenderEngine
, רכיב ההרכבה המואץ על ידי GPU ל-SurfaceFlinger. ה-shader מחובר גם ל-libhwui
, כדי שאפשר יהיה לבצע מיפוי גוונים מ-HDR ל-SDR ביעילות עבורTextureView
. מאחר שהמחרוזת שנוצרת מוטמעת בשיידרים אחרים של SkSL שבהם Skia משתמשת, השיידר חייב לפעול בהתאם לכללים הבאים:- מחרוזת ההצללה חייבת לכלול נקודת כניסה עם החתימה
float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)
, שבהlinearRGB
הוא הערך של ה-nit המוחלטים של הפיקסלים ב-RGB במרחב ליניארי, ו-xyz
מומר ל-XYZ.linearRGB
- כל שיטות העזר שמשמשות את מחרוזת ה-shader חייבות לכלול את הקידומת
libtonemap_
כדי שלא יהיו התנגשויות בהגדרות של ה-shader במסגרת. באופן דומה, תחילית שלin_libtonemap_
חייבת להופיע לפני תבניות קלט.
- מחרוזת ההצללה חייבת לכלול נקודת כניסה עם החתימה
יצירת מדים של SkSL
הממשק
ToneMapper::generateShaderSkSLUniforms()
מחזיר את הערכים הבאים, בהתאם למטא-נתוניםstruct
שמתארים מטא-נתונים מסטנדרטים שונים של HDR ומתנאי תצוגה שונים:רשימה של מערכות אחידות (uniforms) שמקושרות על ידי שדרן SkSL.
הערכים האחידים
in_libtonemap_displayMaxLuminance
ו-in_libtonemap_inputMaxLuminance
. הערכים האלה משמשים את ה-shaders של המסגרת כשהם משנים את קנה המידה של הקלט ל-libtonemap
, ומנרמלים את הפלט לפי הצורך.
נכון לעכשיו, תהליך היצירה של פורמטים אחידים לא תלוי במרחב הנתונים של הקלט והפלט.
התאמה אישית
ההטמעה לדוגמה של הספרייה libtonemap
מניבה תוצאות מקובלות. עם זאת, מכיוון שהאלגוריתם של מיפוי הגוונים שבו נעשה שימוש בהרכבת ה-GPU עשוי להיות שונה מהאלגוריתם שבו נעשה שימוש בהרכבת ה-DPU, השימוש בהטמעת קובץ העזר עלול לגרום להבהוב בתרחישים מסוימים, כמו האנימציה הסיבובית. התאמה אישית יכולה לפתור בעיות כאלה באיכות התמונה שספציפיות לספק.
מומלץ מאוד ליצרני ציוד מקורי (OEM) לבטל את ההטמעה של libtonemap
כדי להגדיר את תת-המחלקה ToneMapper
שלהם, שמוחזר על ידי getToneMapper()
.
כשמשתמשים בהתאמה אישית של ההטמעה, השותפים צריכים לבצע אחת מהפעולות הבאות:
- יש לשנות את ההטמעה של
libtonemap
ישירות. - מגדירים ספרייה סטטית משלהם, מקמפלים את הספרייה כקובץ עצמאי ומחליפים את הקובץ
.a
של הספרייהlibtonemap
בקובץ שנוצר מהספרייה בהתאמה אישית.
הספקים לא צריכים לשנות קוד ליבה, אבל מספר ספקים צריכים להעביר פרטים על אלגוריתמי המיפוי של הטונים ב-DPU כדי לבצע הטמעה תקינה.
אימות
כדי לאמת את ההטמעה, פועלים לפי השלבים הבאים:
ניתן להפעיל סרטוני HDR במסך של כל תקני HDR שמערכת התצוגה שלכם תומכת בהם, כמו HLG, HDR10, HDR10+ או DolbyVision.
משנים את מצב ה-GPU composition כדי לוודא שאין הבהוב שגלוי למשתמש.
משתמשים בפקודה
adb
הבאה כדי להחליף את הרכב ה-GPU: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, שינויים עדינים בצבעים נובעים מהבדלים בקונטיינרים.
כל אחת מהבעיות האלה קשורה להבדלים הדיוק היחסיים של החומרה הבסיסית. פתרון אופייני הוא להבטיח שיש שלב של מיזוג בנתיבים עם רמת דיוק נמוכה יותר, כך שהבדלים ברמת הדיוק יהיו פחות בולטים.