קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
ב-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_.
הערכים האחידים 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) בנתיבים עם דיוק נמוך יותר, כך שההבדלים בדיוק פחות מורגשים.
דוגמאות התוכן והקוד שבדף הזה כפופות לרישיונות המפורטים בקטע רישיון לתוכן. Java ו-OpenJDK הם סימנים מסחריים או סימנים מסחריים רשומים של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-07-27 (שעון UTC).
[[["התוכן קל להבנה","easyToUnderstand","thumb-up"],["התוכן עזר לי לפתור בעיה","solvedMyProblem","thumb-up"],["סיבה אחרת","otherUp","thumb-up"]],[["חסרים לי מידע או פרטים","missingTheInformationINeed","thumb-down"],["התוכן מורכב מדי או עם יותר מדי שלבים","tooComplicatedTooManySteps","thumb-down"],["התוכן לא עדכני","outOfDate","thumb-down"],["בעיה בתרגום","translationIssue","thumb-down"],["בעיה בדוגמאות/בקוד","samplesCodeIssue","thumb-down"],["סיבה אחרת","otherDown","thumb-down"]],["עדכון אחרון: 2025-07-27 (שעון UTC)."],[],[],null,["# Tone Mapping HDR Luminance to an SDR-compatible Range\n\nAndroid 13 introduces a vendor-configurable static\nlibrary called `libtonemap`, which defines tone mapping operations and is shared\nwith the SurfaceFlinger process and Hardware Composer (HWC) implementations.\nThis feature enables OEMs to define and share their display tone mapping\nalgorithms between the framework and vendors, lessening a mismatch in tone\nmapping.\n\nPrior to Android 13, display-specific tone mapping\noperations weren't shared between the HWC, SurfaceFlinger, and apps. Depending\non the rendering path, for HDR content, this led to mismatches in image quality,\nwhere the HDR content was tone mapped to an output space in different ways. This\nwas perceptible in scenarios such as screen rotation, where the composition\nstrategy changes between the GPU and the DPU, and in differences in rendering\nbehavior between TextureView and SurfaceView.\n\nThis page describes the interface, customization, and validation details of the\n`libtonemap` library.\n| **Note:** Android 16 introduces a new HDR tone mapping method called Look-up Table (LUT) for HDR video outputs instead of using `libtonemap`. LUTs primarily resolve the fragmentation issue with HDR video outputs, especially for HLG and PQ, across a diverse range of Android devices. See the AIDL API [`android.hardware.graphics.composer3.DisplayLuts`](https://cs.android.com/android/platform/superproject/+/android-latest-release:hardware/interfaces/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl) for more information.\n\nInterface to the tone mapping library\n-------------------------------------\n\nThe [`libtonemap`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/)\nlibrary contains CPU-backed implementations and SkSL shaders, which can be\nplugged in by SurfaceFlinger for GPU-backend composition and by the HWC for\ngenerating a tone mapping look-up table (LUT). The entry point to `libtonemap`\nis [`android::tonemap::getToneMapper()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/tonemap.cpp#733), which returns an object that\nimplements the [`ToneMapper`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#86) interface.\n\nThe `ToneMapper` interface supports the following capabilities:\n\n- Generate a tone-mapping LUT\n\n The interface [`ToneMapper::lookupTonemapGain`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#147) is a CPU\n implementation of the shader defined in `libtonemap_LookupTonemapGain()`. This\n is used by unit tests in the framework, and can be used by partners for\n assistance with generating a tone-mapping LUT inside their color pipeline.\n\n `libtonemap_LookupTonemapGain()` takes in color values in absolute,\n unnormalized linear space, both in linear RGB and in XYZ, and returns a float\n describing how much to multiply the input colors in linear space.\n- Generate an SkSL shader\n\n The interface [`ToneMapper::generateTonemapGainShaderSkSL()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#122) returns an\n SkSL shader string, given a source and destination dataspace. The SkSL shader is\n plugged into the Skia implementation for [`RenderEngine`](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/native/libs/renderengine/),\n the GPU-accelerated compositing component for SurfaceFlinger. The shader is also\n plugged into [`libhwui`](https://cs.android.com/android/platform/superproject/+/android-latest-release:frameworks/base/libs/hwui),\n so that HDR-to-SDR tone mapping can be performed efficiently for `TextureView`.\n Because the generated string is in-lined into other SkSL shaders used by Skia,\n the shader must adhere to the following rules:\n - The shader string must have an entry point with the `float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)` signature, where `linearRGB` is the value of the absolute nits of the RGB pixels in linear space and `xyz` is `linearRGB` converted into XYZ.\n - Any helper methods used by the shader string must be prefixed with the string `libtonemap_` so that framework shader definitions don't conflict. Similarly, input uniforms must be prefixed with `in_libtonemap_`.\n- Generate SkSL uniforms\n\n The interface [`ToneMapper::generateShaderSkSLUniforms()`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/include/tonemap/tonemap.h#136) returns the\n following, given a metadata `struct` describing metadata from different HDR\n standards and display conditions:\n - A list of uniforms that are bound by an SkSL shader.\n\n - The uniform values `in_libtonemap_displayMaxLuminance` and\n `in_libtonemap_inputMaxLuminance`. These values are used by framework shaders\n when scaling the input into `libtonemap`, and normalizing the output as\n applicable.\n\n Currently the process of generating uniforms is agnostic to the input and\n output dataspace.\n\n### Customization\n\nThe reference implementation of the [`libtonemap`](https://android.googlesource.com/platform/frameworks/native/+/refs/heads/android16-release/libs/tonemap/) library produces acceptable results. However,\nbecause the tone mapping algorithm used by GPU composition can differ from that\nused by the DPU composition, using the reference implementation can cause\nflicker in some scenarios such as the rotation animation. Customization can\nresolve such vendor-specific image quality issues.\n\nOEMs are strongly encouraged to override the implementation of `libtonemap` to\ndefine their own `ToneMapper` subclass, which is returned by `getToneMapper()`.\nWhen customizing the implementation, partners are expected to do one of the\nfollowing:\n\n- Modify the implementation of `libtonemap` directly.\n- Define their own static library, compile the library as a standalone, and replace `libtonemap` library's `.a` file with the one generated from their custom library.\n\nVendors don't need to modify any kernel code, but multiple vendors must\ncommunicate details about the DPU tone-mapping algorithms for proper\nimplementation.\n\n### Validation\n\nFollow these steps to validate your implementation:\n\n1. Play HDR videos on screen of any HDR standards that your [display system supports](https://developer.android.com/reference/android/view/Display#getHdrCapabilities()),\n such as HLG, HDR10, HDR10+, or DolbyVision.\n\n2. Toggle GPU composition to ensure that there's no user perceptible flicker.\n\n Use the following `adb` command to toggle the GPU composition: \n\n adb shell service call SurfaceFlinger 1008 i32 \u003c0 to enable HWC composition,\n 1 to force GPU composition\u003e\n\n### Common issues\n\nThe following issues can occur with this implementation:\n\n- Banding is caused when the render target used by GPU composition is of lower\n precision than the typical value for HDR content. For instance, banding can\n occur when an HWC implementation supports opaque 10-bit formats for HDR such as\n RGBA1010102 or P010, but requires that GPU composition writes to an 8-bit format\n like RGBA8888 to support alpha.\n\n- A subtle color shift is caused by quantization differences if the DPU\n operates at a different precision than the GPU.\n\nEach of these issues is related to the relative precision differences of the\nunderlying hardware. A typical workaround is to ensure that there's a dithering\nstep in the lower precision paths, making any precision differences less human\nperceptible."]]