تعيين درجات سطوع HDR إلى نطاق متوافق مع SDR

في Android 13، تم تقديم مكتبة ثابتة قابلة للإعداد من قِبل مورّد الأجهزة تُسمّى libtonemap، وهي تحدّد عمليات تحويل النطاق اللوني وتتم مشاركتها مع عملية SurfaceFlinger وعمليات تنفيذ Hardware Composer (HWC). تتيح هذه الميزة للمصنّعين الأصليين للأجهزة تحديد خوارزميات ربط درجات الألوان لشاشات العرض ومشاركتها بين إطار العمل والمورّدين، ما يقلّل من حالات عدم تطابق ربط درجات الألوان.

قبل Android 13، لم تتم مشاركة عمليات ربط درجات الألوان الخاصة بشاشات العرض بين HWC وSurfaceFlinger والتطبيقات. اعتمادًا على مسار العرض، أدّى ذلك إلى عدم تطابق جودة الصورة للمحتوى المعروض بتقنية HDR، حيث تم تحويل النطاق اللوني للمحتوى المعروض بتقنية HDR إلى مساحة إخراج بطرق مختلفة. كان ذلك ملحوظًا في سيناريوهات مثل تدوير الشاشة، حيث تتغيّر استراتيجية التركيب بين وحدة معالجة الرسومات (GPU) ووحدة معالجة شاشة العرض (DPU)، وفي الاختلافات في سلوك العرض بين 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، وهو مكوّن التركيب المُسرَّع بواسطة وحدة معالجة الرسومات (GPU) لـ SurfaceFlinger. يتم أيضًا توصيل التظليل بـ libhwui، حتى يمكن إجراء تحويل النطاق اللوني من النطاق العالي الديناميكية إلى النطاق العادي الديناميكية بكفاءة لـ TextureView. بما أنّ السلسلة التي تم إنشاؤها مضمّنة في تظليلات SkSL الأخرى التي تستخدمها Skia، يجب أن يلتزم التظليل بالقواعد التالية:

    • يجب أن تحتوي سلسلة التظليل على نقطة دخول تحمل التوقيع float libtonemap_LookupTonemapGain(vec3 linearRGB, vec3 xyz)، حيث linearRGB هي قيمة النيت المطلقة لوحدات البكسل الحمراء والخضراء والزرقاء في المساحة الخطية و xyz هي linearRGB التي تم تحويلها إلى XYZ.
    • يجب أن تسبق السلسلة libtonemap_ أي طرق مساعدة تستخدمها سلسلة التظليل حتى لا تتعارض تعريفات تظليل الإطار. وبالمثل، يجب أن تسبق السلسلة in_libtonemap_ أي قيم موحّدة للإدخال.
  • إنشاء قيم SkSL الموحّدة

    تعرض الواجهة ToneMapper::generateShaderSkSLUniforms() ما يلي، مع توفّر struct للبيانات الوصفية تصف البيانات الوصفية من معايير النطاق العالي الديناميكية المختلفة وظروف العرض:

    • قائمة بالقيم الموحّدة التي يتم ربطها من قِبل تظليل SkSL

    • القيم الموحّدة in_libtonemap_displayMaxLuminance وin_libtonemap_inputMaxLuminance تُستخدَم هذه القيم من قِبل أدوات تظليل إطار العمل عند تحجيم الإدخال إلى libtonemap، وتسوية الإخراج حسب الاقتضاء.

    في الوقت الحالي، لا تتأثر عملية إنشاء القيم الموحّدة بمساحة بيانات الإدخال والإخراج.

التخصيص

يقدّم التنفيذ المرجعي لمكتبة libtonemap نتائج مقبولة. ومع ذلك، بما أنّ خوارزمية ربط درجات الألوان المستخدَمة من قِبل التركيب المستند إلى وحدة معالجة الرسومات (GPU) يمكن أن تختلف عن تلك المستخدَمة من قِبل التركيب المستند إلى وحدة معالجة شاشة العرض (DPU)، يمكن أن يؤدي استخدام التنفيذ المرجعي إلى حدوث وميض في بعض السيناريوهات، مثل الرسوم المتحركة للتدوير. يمكن أن يؤدي التخصيص إلى حلّ مشاكل جودة الصورة الخاصة بالمورّد.

ننصح مصنّعي المعدات الأصلية بشدة بتجاوز تنفيذ libtonemap لـ تحديد فئة فرعية خاصة بهم من ToneMapper، والتي يتم عرضها من قِبل getToneMapper(). عند تخصيص التنفيذ، يُتوقَّع من الشركاء إجراء أحد الإجراءَين التاليَين:

  • تعديل تنفيذ libtonemap مباشرةً
  • تحديد مكتبة ثابتة خاصة بهم، وتجميع المكتبة كوحدة مستقلة، واستبدال ملف .a الخاص بمكتبة libtonemap بالملف الذي تم إنشاؤه من مكتبتهم المخصّصة

لا يحتاج المورّدون إلى تعديل أي رمز لل kernel، ولكن يجب أن يتواصل مورّدون متعدّدون لتقديم تفاصيل حول خوارزميات تحويل النطاق اللوني لوحدة معالجة شاشة العرض (DPU) من أجل التنفيذ السليم.

التحقق من صحة البيانات

اتّبِع الخطوات التالية للتحقّق من صحة التنفيذ:

  1. شغِّل فيديوهات بالنطاق العالي الديناميكية على شاشة تعرض أي معايير للنطاق العالي الديناميكية يتيحها نظام العرض، مثل HLG أو HDR10 أو HDR10+‎ أو DolbyVision.

  2. بدِّل التركيب المستند إلى وحدة معالجة الرسومات (GPU) للتأكّد من عدم حدوث وميض ملحوظ للمستخدم.

    استخدِم أمر adb التالي لتبديل التركيب المستند إلى وحدة معالجة الرسومات (GPU):

    adb shell service call SurfaceFlinger 1008 i32 <0 to enable HWC composition,
    1 to force GPU composition>
    
    

المشاكل الشائعة

يمكن أن تحدث المشاكل التالية مع هذا التنفيذ:

  • يحدث التدرّج اللوني عندما تكون دقة هدف العرض المستخدَم من قِبل التركيب المستند إلى وحدة معالجة الرسومات (GPU) أقل من القيمة النموذجية للمحتوى المعروض بتقنية HDR. على سبيل المثال، يمكن أن يحدث التدرّج اللوني عندما يتيح تنفيذ HWC تنسيقات غير شفافة بـ 10 بت للنطاق العالي الديناميكية، مثل RGBA1010102 أو P010، ولكن يتطلب أن يكتب التركيب المستند إلى وحدة معالجة الرسومات (GPU) بتنسيق 8 بت مثل RGBA8888 لدعم قناة ألفا.

  • يحدث تحوّل طفيف في الألوان بسبب اختلافات التكميم إذا كانت وحدة معالجة شاشة العرض (DPU) تعمل بدقة مختلفة عن وحدة معالجة الرسومات (GPU).

ترتبط كل من هذه المشاكل بالاختلافات النسبية في دقة الأجهزة الأساسية. أحد الحلول النموذجية هو التأكّد من وجود خطوة تخطيط في المسارات ذات الدقة المنخفضة، ما يجعل أي اختلافات في الدقة أقل وضوحًا للمستخدم.