اعتبارًا من 27 آذار (مارس) 2025، ننصحك باستخدام android-latest-release بدلاً من aosp-main لإنشاء AOSP والمساهمة فيه. لمزيد من المعلومات، يُرجى الاطّلاع على التغييرات في AOSP.
تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
يقدّم نظام التشغيل Android 13 مكتبة ثابتة يمكن للمورّد ضبطها باسم libtonemap، وهي تحدّد عمليات ربط الدرجات اللونية ويتم مشاركتها مع عملية SurfaceFlinger وعمليات تنفيذ Hardware Composer (HWC).
تتيح هذه الميزة لمصنّعي المعدات الأصلية تحديد ومشاركة خوارزميات تعيين درجات الألوان على الشاشة بين إطار العمل والمورّدين، ما يقلّل من عدم تطابق تعيين درجات الألوان.
قبل الإصدار 13 من نظام التشغيل Android، لم تكن عمليات ربط الألوان الخاصة بالشاشة تتم مشاركتها بين HWC وSurfaceFlinger والتطبيقات. واستنادًا إلى مسار العرض، أدّى ذلك إلى حدوث اختلافات في جودة الصورة عند عرض محتوى HDR، حيث تم تحويل درجات الألوان في محتوى HDR إلى مساحة إخراج بطرق مختلفة. كان هذا التأخير ملحوظًا في سيناريوهات مثل تدوير الشاشة، حيث تتغير استراتيجية التركيب بين وحدة معالجة الرسومات ووحدة معالجة العرض، وفي الاختلافات في سلوك العرض بين TextureView وSurfaceView.
توضّح هذه الصفحة تفاصيل الواجهة والتخصيص والتحقّق الخاصة بمكتبة
libtonemap.
واجهة مكتبة تعيين الدرجات اللونية
تحتوي مكتبة libtonemap على عمليات تنفيذ مستندة إلى وحدة المعالجة المركزية (CPU) وتظليلات SkSL، ويمكن أن يضيفها SurfaceFlinger لإنشاء تركيبة مستندة إلى وحدة معالجة الرسومات (GPU)، ويمكن أن تضيفها HWC لإنشاء جدول بحث (LUT) لربط الدرجات اللونية. نقطة الدخول إلى libtonemap
هي android::tonemap::getToneMapper()، التي تعرض عنصرًا
ينفّذ الواجهة ToneMapper.
تتيح واجهة ToneMapper الإمكانات التالية:
إنشاء جدول بحث لضبط درجة اللون
الواجهة ToneMapper::lookupTonemapGain هي تنفيذ لوحدة المعالجة المركزية (CPU) لبرنامج تظليل محدّد في libtonemap_LookupTonemapGain(). يتم استخدام هذا
الخيار من خلال اختبارات الوحدة في إطار العمل، ويمكن أن يستخدمه الشركاء
للمساعدة في إنشاء جدول بحث لضبط درجة اللون داخل مسار الألوان.
تتلقّى libtonemap_LookupTonemapGain() قيم الألوان في مساحة خطية مطلقة وغير عادية، سواء في نموذج الأحمر والأخضر والأزرق الخطي أو في نموذج XYZ، وتعرض عددًا عشريًا يوضّح مقدار مضاعفة الألوان المُدخَلة في المساحة الخطية.
إنشاء برنامج تظليل SkSL
تعرض الواجهة ToneMapper::generateTonemapGainShaderSkSL() سلسلة تظليل SkSL، مع توفّر مساحة بيانات المصدر والوجهة. يتم توصيل برنامج تظليل SkSL بتنفيذ Skia في RenderEngine، وهو مكوّن التركيب المسرَّع بواسطة وحدة معالجة الرسومات في SurfaceFlinger. يتم أيضًا توصيل برنامج التظليل بـ libhwui،
بحيث يمكن إجراء عملية مطابقة الألوان من النطاق العالي الديناميكية إلى النطاق العادي الديناميكية بكفاءة في TextureView.
بما أنّ السلسلة التي تم إنشاؤها مضمّنة في برامج تظليل SkSL الأخرى التي تستخدمها Skia، يجب أن يلتزم برنامج التظليل بالقواعد التالية:
يجب أن تتضمّن سلسلة برنامج التظليل نقطة دخول بالتوقيع float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)، حيث linearRGB هي قيمة وحدات السطوع المطلقة لبكسلات RGB في المساحة الخطية، وxyz هي linearRGB التي تم تحويلها إلى XYZ.
يجب أن تبدأ أي طرق مساعدة تستخدمها سلسلة برنامج التظليل بالسلسلة libtonemap_ حتى لا تتعارض تعريفات برنامج التظليل في إطار العمل.
وبالمثل، يجب أن تسبق البادئة in_libtonemap_ عناصر التحكّم في الإدخال.
إنشاء متغيرات SkSL موحّدة
تعرض الواجهة ToneMapper::generateShaderSkSLUniforms() ما يلي، مع الأخذ في الاعتبار البيانات الوصفية struct التي تصف البيانات الوصفية من معايير مختلفة لنطاق HDR وشروط العرض:
قائمة بالمتغيرات الموحّدة التي يربطها برنامج تظليل SkSL.
القيم الموحّدة in_libtonemap_displayMaxLuminance وin_libtonemap_inputMaxLuminance تستخدم هذه القيم تظليلات إطار العمل عند تغيير حجم الإدخال إلى libtonemap، وتسوية الإخراج حسب الاقتضاء.
في الوقت الحالي، لا تتأثر عملية إنشاء المعرّفات الموحّدة بمساحة بيانات الإدخال والإخراج.
التخصيص
يقدّم التنفيذ المرجعي لمكتبة libtonemap نتائج مقبولة. ومع ذلك،
بما أنّ خوارزمية مطابقة الألوان التي تستخدمها عملية التركيب على وحدة معالجة الرسومات قد تختلف عن تلك
التي تستخدمها عملية التركيب على وحدة معالجة البيانات، قد يؤدي استخدام التنفيذ المرجعي إلى
حدوث وميض في بعض السيناريوهات، مثل الرسوم المتحركة الخاصة بالتدوير. يمكن أن يحلّ التخصيص مشاكل جودة الصور الخاصة بمورّد معيّن.
ننصح بشدة مصنّعي المعدات الأصلية بتجاوز تنفيذ libtonemap لتحديد فئة فرعية خاصة بهم ToneMapper، يتم عرضها من خلال getToneMapper().
عند تخصيص عملية التنفيذ، يُتوقّع من الشركاء إجراء أحد الإجراءات التالية:
تعديل طريقة تنفيذ العلامة libtonemap مباشرةً
تحديد مكتبتهم الثابتة الخاصة، وتجميع المكتبة كوحدة مستقلة، واستبدال ملف .a الخاص بمكتبة libtonemap بالملف الذي تم إنشاؤه من مكتبتهم المخصّصة
لا يحتاج المورّدون إلى تعديل أي رمز نواة، ولكن يجب أن يتبادل المورّدون المتعدّدون تفاصيل حول خوارزميات ربط الدرجات اللونية في وحدة معالجة البيانات (DPU) من أجل التنفيذ السليم.
التحقُّق
اتّبِع الخطوات التالية للتحقّق من صحة عملية التنفيذ:
تشغيل فيديوهات HDR على شاشة تتوافق مع أي من معايير HDR التي يدعمها نظام العرض، مثل HLG أو HDR10 أو HDR10+ أو DolbyVision
فعِّل ميزة "التركيب باستخدام وحدة معالجة الرسومات" لضمان عدم حدوث أي وميض ملحوظ للمستخدم.
استخدِم الأمر adb التالي لتفعيل ميزة "التركيب باستخدام وحدة معالجة الرسومات" أو إيقافها:
adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
1 to force GPU composition>
المشاكل الشائعة
يمكن أن تحدث المشاكل التالية عند استخدام طريقة التنفيذ هذه:
يحدث التقطيع عندما تكون دقة هدف العرض الذي تستخدمه عملية التركيب في وحدة معالجة الرسومات أقل من القيمة النموذجية لمحتوى HDR. على سبيل المثال، يمكن أن يحدث التدرّج غير المنتظم للألوان عندما يتيح تنفيذ HWC تنسيقات 10 بت غير شفافة لنطاق HDR، مثل RGBA1010102 أو P010، ولكن يتطلّب أن تكتب تركيبة وحدة معالجة الرسومات بتنسيق 8 بت، مثل RGBA8888، لتوفير قناة ألفا.
يحدث تغيير طفيف في الألوان بسبب اختلافات التكميم إذا كانت وحدة معالجة البيانات (DPU) تعمل بدقة مختلفة عن وحدة معالجة الرسومات (GPU).
ترتبط كل مشكلة من هذه المشاكل باختلافات الدقة النسبية للأجهزة الأساسية. ويتم عادةً حل هذه المشكلة من خلال التأكّد من توفّر خطوة تمويه في مسارات الدقة المنخفضة، ما يجعل أي اختلافات في الدقة أقل وضوحًا بالنسبة إلى العين البشرية.
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-07-27 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","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 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],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."]]