تنفيذ الأجهزة الملحن HAL

تتكون طبقات 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.

واجهة هيدل

يستخدم 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 أو 1080p) وأنماط الألوان (مثل اللون الأصلي أو sRGB الحقيقي)؛ ولتشغيل الشاشة أو إيقاف تشغيلها أو تحويلها إلى وضع الطاقة المنخفضة إذا كانت مدعومة.

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

إذا قام البائعون بتطبيق Composer HAL مباشرةً، فسيقوم SurfaceFlinger باستدعاء وظائفه من خلال HIDL IPC. على سبيل المثال، لإنشاء طبقة، يستدعي SurfaceFlinger 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 . للحصول على وثائق مفصلة حول مؤشرات وظيفة HWC، راجع hwcomposer2.h .

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

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

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

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

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

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

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

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

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

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

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

شاشات عرض متعددة

يدعم 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 المؤقت بدلاً من الشاشة. يقوم برنامج Hardware Composer (HWC) بكتابة الإخراج إلى مخزن مؤقت، ويوفر حاجز الإكمال، ويرسل المخزن المؤقت إلى المستهلك (مثل أداة تشفير الفيديو، ووحدة معالجة الرسومات، ووحدة المعالجة المركزية، وما إلى ذلك). يمكن أن تستخدم شاشات العرض الافتراضية 2D/blitter أو التراكبات إذا كان خط أنابيب العرض يكتب إلى الذاكرة.

أساليب

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

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

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

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

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

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

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

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

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

لمزيد من المعلومات حول أسوار المزامنة، راجع تكامل مؤلفي الأجهزة .