تنفيذ HAL Composer للأجهزة

طبقات HAL المركبة من مؤلف الأجهزة (HWC) المستلمة من SurfaceFlinger ، مما يقلل من مقدار تكوين OpenGL ES (GLES) وأداء وحدة معالجة الرسومات.

يقوم HWC بتجريد الكائنات ، مثل التراكبات والنغمات ثنائية الأبعاد ، على الأسطح المركبة ويتواصل مع أجهزة تكوين النوافذ المتخصصة إلى النوافذ المركبة. استخدم HWC لتركيب النوافذ بدلاً من استخدام SurfaceFlinger المركب مع وحدة معالجة الرسومات. لم يتم تحسين معظم وحدات معالجة الرسومات للتكوين ، وعندما تقوم وحدة معالجة الرسومات بتكوين طبقات من SurfaceFlinger ، لا يمكن للتطبيقات استخدام وحدة معالجة الرسومات للعرض الخاص بها.

يجب أن تدعم تطبيقات HWC:

  • أربع تراكبات على الأقل:
    • شريط الحالة
    • شريط النظام
    • برنامج
    • ورق الجدران / الخلفية
  • طبقات أكبر من الشاشة (على سبيل المثال ، خلفية)
  • مزج ألفا لكل بكسل متزامن ومزج ألفا لكل مستوى
  • مسار الأجهزة لتشغيل الفيديو المحمي
  • ترتيب التعبئة RGBA وتنسيقات YUV وخصائص التبليط والتدوير والخطوة

لتنفيذ HWC:

  1. قم بتنفيذ HWC غير التشغيلي وأرسل كل أعمال التكوين إلى GLES.
  2. تنفيذ خوارزمية لتفويض التكوين إلى HWC بشكل تدريجي. على سبيل المثال ، قم بتفويض الأسطح الثلاثة أو الأربعة الأولى فقط إلى أجهزة التراكب الخاصة بـ HWC.
  3. تحسين HWC. قد يشمل ذلك:
    • تحديد الأسطح التي تزيد من الحمل المأخوذ من وحدة معالجة الرسومات وإرسالها إلى HWC.
    • اكتشاف ما إذا كانت الشاشة قيد التحديث. إذا لم يكن كذلك ، فوّض التركيب إلى GLES بدلاً من HWC لتوفير الطاقة. عندما يتم تحديث الشاشة مرة أخرى ، استمر في إلغاء تحميل التركيب إلى HWC.
    • التحضير لحالات الاستخدام الشائعة مثل:
      • الشاشة الرئيسية ، والتي تتضمن شريط الحالة وشريط النظام ونافذة التطبيق والخلفيات الحية
      • ألعاب بملء الشاشة في الوضع الرأسي والأفقي
      • فيديو بملء الشاشة مع تسميات توضيحية مغلقة والتحكم في التشغيل
      • تشغيل الفيديو المحمي
      • تقسيم الشاشة متعدد النوافذ

الأوليات HWC

يوفر HWC اثنين من العناصر الأولية ، الطبقات والشاشات ، لتمثيل العمل التكويني وتفاعله مع أجهزة العرض. يوفر HWC أيضًا التحكم في VSYNC واستدعاء SurfaceFlinger لإعلامه عند حدوث حدث VSYNC.

واجهة HIDL

يستخدم Android 8.0 والإصدارات الأحدث واجهة HIDL تسمى Composer HAL من أجل IPC المرتبط بين HWC و SurfaceFlinger. يحل Composer HAL محل واجهة hwcomposer2.h القديمة. إذا قدم البائعون تطبيق Composer HAL لـ HWC ، يقبل Composer HAL مباشرة استدعاءات HIDL من SurfaceFlinger. إذا قام البائعون بتوفير تطبيق قديم لـ HWC ، يقوم Composer HAL بتحميل مؤشرات الدالة من hwcomposer2.h ، وإعادة توجيه استدعاءات HIDL إلى استدعاءات مؤشر الوظيفة.

يوفر HWC وظائف لتحديد خصائص شاشة معينة ؛ للتبديل بين تكوينات العرض المختلفة (مثل دقة 4K أو 1080 بكسل) وأوضاع الألوان (مثل اللون الأصلي أو sRGB الحقيقي) ؛ ولتشغيل الشاشة أو إيقاف تشغيلها أو تحويلها إلى وضع طاقة منخفضة إذا كان مدعومًا.

مؤشرات الوظيفة

إذا قام البائعون بتطبيق Composer HAL مباشرة ، فإن SurfaceFlinger تستدعي وظائفها من خلال HIDL IPC. على سبيل المثال ، لإنشاء طبقة ، يستدعي createLayer() على Composer HAL.

إذا قام البائعون بتطبيق واجهة hwcomposer2.h ، يقوم Composer HAL باستدعاء مؤشرات الدالة hwcomposer2.h . في تعليقات hwcomposer2.h ، تتم الإشارة إلى وظائف واجهة HWC بأسماء LowerCamelCase غير موجودة في الواجهة كحقول مسماة. يتم تحميل كل وظيفة تقريبًا عن طريق طلب مؤشر دالة باستخدام دالة getFunction التي يوفرها hwc2_device_t . على سبيل المثال ، الوظيفة createLayer هي مؤشر دالة من النوع HWC2_PFN_CREATE_LAYER ، والذي يتم إرجاعه عندما يتم تمرير القيمة HWC2_FUNCTION_CREATE_LAYER إلى getFunction .

للحصول على وثائق تفصيلية حول وظائف Composer HAL ووظائف تمرير وظيفة HWC ، راجع composer . للحصول على وثائق مفصلة حول مؤشرات دالة hwcomposer2.h ، راجع hwcomposer2.h .

طبقة ومقابض عرض

يتم التعامل مع الطبقات والشاشات بواسطة المقابض التي تم إنشاؤها بواسطة HWC. المقابض غير شفافة بالنسبة لـ SurfaceFlinger.

عندما يقوم SurfaceFlinger بإنشاء طبقة جديدة ، فإنه يستدعي createLayer ، والتي ترجع من النوع Layer للتطبيقات المباشرة أو hwc2_layer_t لتطبيقات العبور. عندما يقوم SurfaceFlinger بتعديل خاصية لتلك الطبقة ، يمرر hwc2_layer_t القيمة hwc2_layer_t إلى وظيفة التعديل المناسبة مع أي معلومات أخرى مطلوبة لإجراء التعديل. النوع hwc2_layer_t كبير بما يكفي hwc2_layer_t مؤشر أو فهرس.

يتم إنشاء شاشات العرض المادية عن طريق التوصيل السريع. عندما يتم توصيل شاشة عرض فعلية ، يقوم HWC بإنشاء مقبض ويمرر المقبض إلى SurfaceFlinger من خلال رد الاتصال hotplug. يتم إنشاء شاشات العرض الافتراضية بواسطة استدعاء createVirtualDisplay() لطلب عرض. إذا كان HWC يدعم تكوين العرض الظاهري ، فإنه يقوم بإرجاع مقبض. بعد ذلك ، يفوض SurfaceFlinger تكوين شاشات العرض إلى HWC. إذا كان HWC لا يدعم تكوين العرض الافتراضي ، يقوم SurfaceFlinger بإنشاء المقبض وتركيب العرض.

عرض عمليات التكوين

مرة واحدة لكل VSYNC ، يستيقظ SurfaceFlinger إذا كان يحتوي على محتوى جديد مركب. يمكن أن يكون هذا المحتوى الجديد عبارة عن مخازن مؤقتة جديدة للصور من التطبيقات أو تغيير في خصائص طبقة واحدة أو أكثر. عندما يستيقظ SurfaceFlinger:

  1. يتعامل مع المعاملات ، إن وجدت.
  2. يغلق المخازن المؤقتة الرسومية الجديدة ، إن وجدت.
  3. يؤدي تكوينًا جديدًا ، إذا أدت الخطوة 1 أو 2 إلى تغيير محتويات العرض.

لإجراء تكوين جديد ، يقوم SurfaceFlinger بإنشاء الطبقات وإتلافها أو تعديل حالات الطبقة ، حسب الاقتضاء. يقوم أيضًا بتحديث الطبقات بمحتوياتها الحالية ، باستخدام استدعاءات مثل setLayerBuffer أو setLayerColor . بعد يتم تحديث كافة الطبقات، إلى SurfaceFlinger يدعو validateDisplay ، الذي يحكي HWC لفحص حالة الطبقات وتحديد كيفية تكوين ستسير. بشكل افتراضي ، يحاول SurfaceFlinger تكوين كل طبقة بحيث يتم تكوين الطبقة بواسطة HWC ؛ على الرغم من أنه في بعض الظروف ، يقوم SurfaceFlinger بتكوين طبقات من خلال احتياطي GPU.

بعد استدعاء validateDisplay ، إلى SurfaceFlinger يدعو getChangedCompositionTypes لمعرفة ما إذا كان HWC يريد أي نوع من أنواع تكوين طبقة تغيرت قبل تنفيذ التكوين. لقبول التغييرات ، تقبل مكالمات acceptDisplayChanges .

إذا تم تمييز أي طبقات لتكوين SurfaceFlinger ، فإن SurfaceFlinger يركبها في المخزن المؤقت المستهدف. ثم يستدعي setClientTarget لإعطاء المخزن المؤقت للشاشة بحيث يمكن عرض المخزن المؤقت على الشاشة أو تكوينه مع طبقات لم يتم تمييزها لتكوين SurfaceFlinger. إذا لم يتم وضع علامة على طبقات لتكوين SurfaceFlinger ، فإن SurfaceFlinger يتجاوز خطوة التكوين.

أخيرًا ، يستدعي presentDisplay لإخبار presentDisplay بإكمال عملية التكوين وعرض النتيجة النهائية.

شاشات متعددة

يدعم Android 10 شاشات عرض مادية متعددة. عند تصميم تطبيق HWC المخصص للاستخدام على Android 7.0 والإصدارات الأحدث ، هناك بعض القيود غير الموجودة في تعريف HWC:

  • من المفترض أن هناك شاشة داخلية واحدة بالضبط. الشاشة الداخلية هي الشاشة التي يبلغ عنها أول توصيل سريع أثناء الإقلاع. بعد توصيل الشاشة الداخلية ، لا يمكن فصلها.
  • بالإضافة إلى الشاشة الداخلية ، قد يتم توصيل أي عدد من شاشات العرض الخارجية أثناء التشغيل العادي للجهاز. يفترض إطار العمل أن جميع المقابس الساخنة بعد العرض الداخلي الأول هي شاشات خارجية ، لذلك إذا تمت إضافة أي شاشات داخلية أخرى ، فسيتم تصنيفها بشكل غير صحيح على أنها Display.TYPE_HDMI بدلاً من Display.TYPE_BUILT_IN .

بينما يتم تنفيذ عمليات SurfaceFlinger الموضحة أعلاه لكل شاشة ، يتم إجراؤها بالتتابع لجميع شاشات العرض النشطة ، حتى إذا تم تحديث محتويات شاشة واحدة فقط.

على سبيل المثال ، إذا تم تحديث الشاشة الخارجية ، فسيكون التسلسل كما يلي:

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

تكوين العرض الافتراضي

تكوين العرض الافتراضي مشابه لتكوين العرض الخارجي. يتمثل الاختلاف بين تكوين العرض الافتراضي وتكوين العرض المادي في أن شاشات العرض الافتراضية ترسل الإخراج إلى مخزن Gralloc المؤقت بدلاً من الشاشة. يكتب مؤلف الأجهزة (HWC) الإخراج إلى المخزن المؤقت ويوفر سور الإكمال ويرسل المخزن المؤقت إلى المستهلك (مثل مشفر الفيديو ووحدة معالجة الرسومات ووحدة المعالجة المركزية وما إلى ذلك). يمكن لشاشات العرض الافتراضية استخدام 2D / blitter أو التراكبات إذا كان خط أنابيب العرض يكتب في الذاكرة.

أساليب

يكون كل إطار في أحد الأوضاع الثلاثة بعد أن يستدعي SurfaceFlinger طريقة ValidateDisplay validateDisplay() HWC:

  • GLES - تُركب وحدة معالجة الرسومات (GPU) جميع الطبقات ، وتكتب مباشرة إلى المخزن المؤقت للإخراج. لا تشارك HWC في التكوين.
  • مختلط - تقوم وحدة معالجة الرسومات بتركيب بعض الطبقات في المخزن المؤقت للإطار وتكوين HWC المخزن المؤقت للإطار والطبقات المتبقية ، والكتابة مباشرة إلى المخزن المؤقت للإخراج.
  • HWC - HWC يركب جميع الطبقات ويكتب مباشرة إلى المخزن المؤقت للإخراج.

تنسيق الإخراج

تعتمد تنسيقات إخراج المخزن المؤقت للعرض الظاهري على الوضع الخاص بها:

  • وضع GLES - يقوم برنامج تشغيل EGL بتعيين تنسيق المخزن المؤقت للإخراج في dequeueBuffer() ، عادةً RGBA_8888 . يجب أن يكون المستهلك قادرًا على قبول تنسيق الإخراج الذي يحدده برنامج التشغيل أو لا يمكن قراءة المخزن المؤقت.
  • الوضعان المختلطان و HWC - إذا احتاج المستهلك إلى الوصول إلى وحدة المعالجة المركزية ، يقوم المستهلك بتعيين التنسيق. بخلاف ذلك ، يكون التنسيق IMPLEMENTATION_DEFINED ، ويقوم Gralloc بتعيين أفضل تنسيق بناءً على علامات الاستخدام. على سبيل المثال ، يقوم Gralloc بتعيين تنسيق YCbCr إذا كان المستهلك هو برنامج تشفير الفيديو ويمكن لـ HWC كتابة التنسيق بكفاءة.

أسوار التزامن

تعد أسوار المزامنة (المزامنة) جانبًا حاسمًا في نظام رسومات Android. تسمح الأسوار لوحدة المعالجة المركزية بالعمل بشكل مستقل عن عمل GPU المتزامن ، ولا يتم الحظر إلا عندما يكون هناك تبعية حقيقية.

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

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

لمزيد من المعلومات حول أسوار المزامنة ، راجع Hardware Composer Integration .