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

يُجمِّع "برنامج HAL لإنشاء المحتوى بالأجهزة" (HWC) الطبقات التي يتم استلامها من SurfaceFlinger، ما يقلل من مقدار التركيب الذي يؤديه OpenGL ES (GLES) ووحدة معالجة الرسومات.

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

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

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

لتنفيذ ميزة "المعالجة عالية السرعة":

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

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

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

واجهة HIDL

يستخدم نظام التشغيل Android 8.0 والإصدارات الأحدث واجهة HIDL تُعرف باسم Composer HAL لسماح واجهة برمجة التطبيقات بالاتصال بين HWC وSurfaceFlinger. يحلّ Composer HAL محلّ واجهة hwcomposer2.h القديمة. إذا قدّم المورّدون تنفيذًا لواجهة برمجة التطبيقات Composer HAL لوحدة التحكّم في الأجهزة (HWC)، ستقبل واجهة برمجة التطبيقات Composer HAL مباشرةً طلبات HIDL من واجهة برمجة التطبيقات SurfaceFlinger. إذا كان المورّدون يوفّرون تنفيذًا قديمًا لواجهة HWC، يحمِّل Composer HAL مؤشرات الدوال من hwcomposer2.h، ويوجّه استدعاءات HIDL إلى استدعاءات مؤشرات الدوال.

يوفّر "العرض التلقائي للصور" دوال لتحديد خصائص شاشة معيّنة، وللتبديل بين إعدادات الشاشة المختلفة (مثل دقة 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.

للحصول على مستندات تفصيلية عن وظائف HAL في Composer ووظائف تمرير وظائف HWC ، يُرجى الاطّلاع على composer. للحصول على مستندات تفصيلية حول مُشيرات وظائف HWC، يُرجى الاطّلاع على hwcomposer2.h.

أسماء الطبقات والشاشات

يتمّ التحكّم في الطبقات والشاشات باستخدام الأسماء المعرِّفة التي ينشئها "المعالج اللاسلكي للألعاب". الأسماء المعرِّفة غير شفافة لنظام SurfaceFlinger.

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

يتم إنشاء الشاشات الخارجية من خلال توصيلها بالجهاز. عند توصيل شاشة خارجية بجهاز، ينشئ "المعالج الوسائط المتعددة للأجهزة" معرّفًا ويمرره إلى SurfaceFlinger من خلال دالة الاستدعاء hotplug. يتم إنشاء الشاشات الافتراضية بواسطة SurfaceFlinger من خلال استدعاء createVirtualDisplay() لطلب شاشة. إذا كان HWC يتوافق مع تركيب العرض الافتراضي، سيعرض معرّفًا. بعد ذلك، يفوّض SurfaceFlinger إنشاء شاشات العرض إلى HWC. إذا لم يكن "العرض الموحّد للأجهزة" متوافقًا مع تركيب الشاشة الافتراضية، تنشئ SurfaceFlinger المعرّف وتُركّب الشاشة.

عمليات تركيب العرض

يتم تشغيل SurfaceFlinger مرة واحدة لكل دورة VSYNC إذا كان لديه محتوى جديد لجمعه. يمكن أن يكون هذا المحتوى الجديد ذاكرة تخزين مؤقتة جديدة للصور من التطبيقات أو تغييرًا في سمات طبقة واحدة أو أكثر. عندما يوقظه 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 مخصّصة للاستخدام على الإصدار 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()
validateDisplay()
presentDisplay()
presentDisplay()

// In Android 10 and higher:

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

تكوين الشاشة الافتراضية

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

الأوضاع

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

  • GLES: تُدمج وحدة معالجة الرسومات جميع الطبقات، وتكتب مباشرةً في مخزن الإخراج. لا يشارك "المحتوى الذي ينشئه المستخدم" في عملية إنشاء المحتوى.
  • مختلط: تُدمج وحدة معالجة الرسومات بعض الطبقات في ملف التخزين المؤقت للصور، بينما تدمج واجهة معالجة الرسومات (HWC) ملف التخزين المؤقت للصور والطبقات المتبقية، ثم تُجري عملية الكتابة مباشرةً إلى ذاكرة التخزين المؤقت للإخراج.
  • HWC: يُدمج هذا الوضع جميع الطبقات ويكتبها مباشرةً في ذاكرة التخزين المؤقت للإخراج.

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

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

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

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

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

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

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

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