מיפוי גוונים של HDR Luminance לטווח תואם ל-SDR

ב-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 כדי לבצע הטמעה תקינה.

אימות

כדי לאמת את ההטמעה, פועלים לפי השלבים הבאים:

  1. ניתן להפעיל סרטוני HDR במסך של כל תקני HDR שמערכת התצוגה שלכם תומכת בהם, כמו HLG, HDR10, HDR10+ או DolbyVision.

  2. משנים את מצב ה-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, שינויים עדינים בצבעים נובעים מהבדלים בקונטיינרים.

כל אחת מהבעיות האלה קשורה להבדלים הדיוק היחסיים של החומרה הבסיסית. פתרון אופייני הוא להבטיח שיש שלב של מיזוג בנתיבים עם רמת דיוק נמוכה יותר, כך שהבדלים ברמת הדיוק יהיו פחות בולטים.