تنفيذ واجهة برمجة التطبيقات Hardware Composer HAL

تدمج طبقة HAL الخاصة بـ Hardware Composer (HWC) الطبقات التي تم تلقّيها من SurfaceFlinger، ما يقلّل من مقدار الدمج OpenGL ES (GLES) الذي تنفّذه وحدة معالجة الرسومات.

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

يجب أن تتوافق عمليات تنفيذ HWC مع ما يلي:

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

لتنفيذ HWC، اتّبِع الخطوات التالية:

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

عناصر HWC الأساسية

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

واجهة HIDL

يستخدم الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث واجهة HIDL تُسمى Composer HAL لإجراء عملية IPC مرتبطة ببرنامج Binder بين 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 المقبض ويجمع الشاشة.

عمليات إنشاء شاشة العرض

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

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

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

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

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

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

شاشات متعددة

يتيح نظام التشغيل Android 10 استخدام شاشات عرض فعلية متعددة. عند تصميم عملية تنفيذ HWC مخصّصة للاستخدام على الإصدار 7.0 من نظام التشغيل Android والإصدارات الأحدث، هناك بعض القيود غير المتوفّرة في تعريف 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 طريقة validateDisplay() HWC:

  • GLES: تدمج وحدة معالجة الرسومات جميع الطبقات، وتكتب مباشرةً في مخزن الإخراج المؤقت. لا يشارك HWC في تأليف الأغنية.
  • MIXED: تركّب وحدة معالجة الرسومات بعض الطبقات في إطار المخزن المؤقت، بينما يركّب HWC إطار المخزن المؤقت والطبقات المتبقية، ويكتب مباشرةً في المخزن المؤقت للإخراج.
  • HWC: يدمج HWC جميع الطبقات ويكتب مباشرةً في المخزن المؤقت للإخراج.

تنسيق الناتج

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

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

حواجز المزامنة

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

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

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

لمزيد من المعلومات حول حواجز المزامنة، يُرجى الاطّلاع على دمج Hardware Composer.