يصف إطار المزامنة بشكلٍ صريح التبعيات بين العمليات غير المتزامنة المختلفة في نظام الرسومات في Android. توفّر هذه البنية الأساسية واجهة برمجة تطبيقات تتيح للمكوّنات الإشارة إلى وقت تحرير المخازن المؤقتة. تسمح البنية الأساسية أيضًا بنقل العناصر الأساسية للمزامنة بين برامج التشغيل من النواة إلى مساحة المستخدم وبين عمليات مساحة المستخدم نفسها.
على سبيل المثال، قد يضع أحد التطبيقات في قائمة الانتظار عملاً ليتم تنفيذه في وحدة معالجة الرسومات. تبدأ وحدة معالجة الرسومات في رسم تلك الصورة. على الرغم من أنّه لم يتم رسم الصورة في الذاكرة بعد، يتم تمرير مؤشر المخزن المؤقت إلى مكوّن نافذة العرض مع حاجز يشير إلى وقت انتهاء عمل وحدة معالجة الرسومات. يبدأ مكوّن نافذة العرض في المعالجة مسبقًا ويمرّر العمل إلى وحدة التحكّم في شاشة العرض. وبطريقة مماثلة، يتم إنجاز عمل وحدة المعالجة المركزية مسبقًا. بعد انتهاء وحدة معالجة الرسومات، تعرض وحدة التحكّم في شاشة العرض الصورة على الفور.
تسمح البنية الأساسية للمزامنة أيضًا للمنفّذين باستخدام موارد المزامنة في مكوّنات الأجهزة الخاصة بهم. أخيرًا، توفّر البنية الأساسية إمكانية الاطّلاع على مسار الرسومات للمساعدة في تصحيح الأخطاء.
المزامنة الصريحة
تتيح المزامنة الصريحة للمنتجين والمستهلكين للمخازن المؤقتة للرسومات الإشارة إلى وقت الانتهاء من استخدام مخزن مؤقت. يتم تنفيذ المزامنة الصريحة في مساحة النواة.
تشمل مزايا المزامنة الصريحة ما يلي:
- تقليل الاختلاف في السلوك بين الأجهزة
- تحسين دعم تصحيح الأخطاء
- تحسين مقاييس الاختبار
يحتوي إطار المزامنة على ثلاثة أنواع من الكائنات:
sync_timelinesync_ptsync_fence
sync_timeline
sync_timeline هو مخطط زمني متزايد بشكلٍ رتيب يجب أن ينفّذه المورّدون لكل مثيل من برامج التشغيل، مثل سياق GL أو وحدة التحكّم في شاشة العرض أو أداة التسطيح الثنائية الأبعاد. تحسب sync_timeline المهام التي تم إرسالها إلى النواة لجهاز معيّن.
تضمن sync_timeline ترتيب العمليات وتتيح عمليات التنفيذ الخاصة بالأجهزة.
اتّبِع الإرشادات التالية عند تنفيذ sync_timeline:
- قدِّم أسماء مفيدة لجميع برامج التشغيل والمخططات الزمنية والحواجز لتسهيل تصحيح الأخطاء.
- نفِّذ عاملَي التشغيل
timeline_value_strوpt_value_strفي المخططات الزمنية لجعل ناتج تصحيح الأخطاء أكثر قابلية للقراءة. - نفِّذ عملية ملء
driver_dataلمنح مكتبات مساحة المستخدم، مثل مكتبة GL، إمكانية الوصول إلى بيانات المخطط الزمني الخاصة، إذا لزم الأمر.data_driverتسمح للمورّدين بتمرير معلومات عن غير القابلة للتغييرsync_fenceوsync_ptsلإنشاء أسطر الأوامر استنادًا إليها. - لا تسمح لمساحة المستخدم بإنشاء حاجز أو الإشارة إليه بشكلٍ صريح. يؤدي إنشاء الإشارات أو الحواجز بشكلٍ صريح إلى هجمة حجب خدمة توقف وظائف مسار البيانات.
- لا تصل إلى عناصر
sync_timelineأوsync_ptأوsync_fenceبشكلٍ صريح. توفّر واجهة برمجة التطبيقات جميع الدوال المطلوبة.
sync_pt
sync_pt هي قيمة أو نقطة واحدة على sync_timeline. للنقطة ثلاث حالات: نشطة ومُشار إليها وفيها خطأ. تبدأ النقاط في الحالة النشطة وتنتقل إلى الحالة المُشار إليها أو الحالة التي فيها خطأ. على سبيل المثال، عندما لا يعود مستهلك الصور بحاجة إلى مخزن مؤقت، تتم الإشارة إلى sync_pt لكي يعرف منتج الصور أنّه يمكنه الكتابة في المخزن المؤقت مرة أخرى.
sync_fence
sync_fence هي مجموعة من قيم sync_pt التي غالبًا ما يكون لها عناصر رئيسية مختلفة في sync_timeline (مثل وحدة التحكّم في شاشة العرض ووحدة معالجة الرسومات). sync_fenceوsync_pt وsync_timeline هي العناصر الأساسية الرئيسية التي تستخدمها برامج التشغيل ومساحة المستخدم للإشارة إلى تبعياتها. عند الإشارة إلى حاجز، تكتمل جميع الأوامر الصادرة قبل الحاجز لأنّ برنامج تشغيل النواة أو كتلة الأجهزة ينفّذ الأوامر بالترتيب.
تسمح البنية الأساسية للمزامنة لعدة مستهلكين أو منتجين بالإشارة إلى وقت الانتهاء من استخدام مخزن مؤقت، مع إرسال معلومات الاعتمادية باستخدام مَعلمة دالة واحدة. تستند الحواجز إلى واصف ملف ويتم تمريرها من مساحة النواة إلى مساحة المستخدم. على سبيل المثال، يمكن أن يحتوي الحاجز على قيمتَين لـ sync_pt تشيران إلى وقت انتهاء مستهلكَين منفصلَين للصور من قراءة مخزن مؤقت. عند الإشارة إلى الحاجز، يعرف منتجو الصور أنّ كلا المستهلكَين قد انتهيا من الاستهلاك.
تبدأ الحواجز، مثل قيم sync_pt، في الحالة النشطة وتتغيّر حالتها استنادًا إلى حالة نقاطها. إذا تم الإشارة إلى جميع قيم sync_pt، تتم الإشارة إلى sync_fence. إذا انتقلت إحدى قيم sync_pt إلى حالة الخطأ، ستكون sync_fence بأكملها في حالة الخطأ.
تكون العضوية في sync_fence غير قابلة للتغيير بعد إنشاء الحاجز. للحصول على أكثر من نقطة واحدة في الحاجز، يتم إجراء عملية دمج حيث تتم إضافة نقاط من حاجزَين منفصلَين إلى حاجز ثالث.
إذا تم الإشارة إلى إحدى هاتَين النقطتَين في الحاجز الأصلي ولم يتم الإشارة إلى النقطة الأخرى، لن يكون الحاجز الثالث أيضًا في حالة الإشارة.
لتنفيذ المزامنة الصريحة، قدِّم ما يلي:
- نظام فرعي في مساحة النواة ينفّذ إطار المزامنة لبرنامج تشغيل جهاز معيّن. إنّ برامج التشغيل التي يجب أن تكون على دراية بالحواجز هي بشكلٍ عام أي برنامج يصل إلى مكوّن Hardware Composer (HWC) أو يتواصل معه.
تشمل الملفات الرئيسية ما يلي:
- التنفيذ الأساسي:
kernel/common/include/linux/sync.hkernel/common/drivers/base/sync.c
- المستندات في
kernel/common/Documentation/sync.txt - مكتبة للتواصل مع مساحة النواة في
platform/system/core/libsync
- التنفيذ الأساسي:
- على المورّد تقديم حواجز المزامنة المناسبة كمعلّمات للدالتَين
validateDisplay()وpresentDisplay()في طبقة تجريد الأجهزة (HAL). - إضافتان مرتبطتان بالحواجز في OpenGL (
EGL_ANDROID_native_fence_syncوEGL_ANDROID_wait_sync) ودعم الحواجز في برنامج تشغيل الرسومات
دراسة حالة: تنفيذ برنامج تشغيل شاشة عرض
لاستخدام واجهة برمجة التطبيقات التي تتيح وظيفة المزامنة، عليك تطوير برنامج تشغيل شاشة عرض يحتوي على دالة مخزن مؤقت لشاشة العرض. قبل توفّر إطار عمل المزامنة، كانت هذه الدالة تتلقّى كائنات dma-buf، وتضع تلك المخازن المؤقتة على شاشة العرض، وتتوقف مؤقتًا أثناء ظهور المخزن المؤقت. على سبيل المثال:
/* * assumes buffer is ready to be displayed. returns when buffer is no longer on * screen. */ void display_buffer(struct dma_buf *buffer);
باستخدام إطار المزامنة، تكون دالة display_buffer أكثر تعقيدًا. أثناء وضع مخزن مؤقت على شاشة العرض، يتم ربط المخزن المؤقت بحاجز يشير إلى وقت جهوزية المخزن المؤقت. يمكنك وضع العمل في قائمة الانتظار وبدءه بعد إزالة الحاجز.
لا يؤدي وضع العمل في قائمة الانتظار وبدءه بعد إزالة الحاجز إلى حظر أي شيء. يمكنك على الفور عرض الحاجز الخاص بك، والذي يشير إلى وقت إزالة المخزن المؤقت من شاشة العرض. أثناء وضع المخازن المؤقتة في قائمة الانتظار، تسرد النواة التبعيات باستخدام إطار المزامنة:
/* * displays buffer when fence is signaled. returns immediately with a fence * that signals when buffer is no longer displayed. */ struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence *fence);
دمج المزامنة
يوضّح هذا القسم كيفية دمج إطار عمل المزامنة في مساحة النواة مع أجزاء مساحة المستخدم من إطار عمل Android وبرامج التشغيل التي يجب أن تتواصل مع بعضها البعض. يتم تمثيل كائنات مساحة النواة كواصفات ملفات في مساحة المستخدم.
اتفاقيات الدمج
اتّبِع اتفاقيات واجهة Android HAL:
- إذا كانت واجهة برمجة التطبيقات توفّر واصف ملف يشير إلى
sync_pt، يجب أن يغلق برنامج التشغيل الخاص بالمورّد أو طبقة HAL التي تستخدم واجهة برمجة التطبيقات واصف الملف. - إذا كان برنامج تشغيل المورّد أو طبقة HAL يمرّر واصف ملف يحتوي على
sync_ptإلى دالة واجهة برمجة تطبيقات، يجب ألا يغلق برنامج تشغيل المورّد أو طبقة HAL واصف الملف. - لمتابعة استخدام واصف ملف الحاجز، يجب أن يكرّر برنامج تشغيل المورّد أو الـ HAL الواصف.
تتم إعادة تسمية كائن الحاجز في كل مرة يمر فيها عبر BufferQueue.
يتيح دعم الحاجز في النواة أن تحتوي الحواجز على سلاسل للأسماء، لذا يستخدم إطار المزامنة اسم النافذة وفهرس المخزن المؤقت الذي يتم وضعه في قائمة الانتظار لتسمية الحاجز، مثل SurfaceView:0. يساعد ذلك في تصحيح الأخطاء لتحديد مصدر حالة الجمود لأنّ الأسماء تظهر في ناتج /d/sync وتقارير الأخطاء.
دمج ANativeWindow
ANativeWindow على دراية بالحواجز. dequeueBuffer،
queueBuffer، وcancelBuffer تحتوي على مَعلمات الحاجز.
دمج OpenGL ES
يعتمد دمج المزامنة في OpenGL ES على إضافتَين في EGL:
EGL_ANDROID_native_fence_syncتوفّر طريقة لتضمين أو إنشاء واصفات ملفات حواجز Android الأصلية فيEGLSyncKHRكائنات.- تسمح
EGL_ANDROID_wait_syncبتأخيرات من جانب وحدة معالجة الرسومات بدلاً من التأخيرات من جانب وحدة المعالجة المركزية، ما يجعل وحدة معالجة الرسومات تنتظرEGLSyncKHR. تتطابق إضافةEGL_ANDROID_wait_syncمع إضافةEGL_KHR_wait_sync.
لاستخدام هاتَين الإضافتَين بشكلٍ مستقل، نفِّذ إضافة EGL_ANDROID_native_fence_sync مع دعم النواة المرتبط بها. بعد ذلك، فعِّل إضافة EGL_ANDROID_wait_sync في برنامج التشغيل. تتألف إضافة EGL_ANDROID_native_fence_sync من نوع كائن EGLSyncKHR لحاجز أصلي مميّز. نتيجةً لذلك، لا تنطبق الإضافات التي تنطبق على أنواع كائنات EGLSyncKHR الحالية بالضرورة على كائنات EGL_ANDROID_native_fence، ما يؤدي إلى تجنُّب التفاعلات غير المرغوب فيها.
تستخدم إضافة EGL_ANDROID_native_fence_sync سمة واصف ملف حاجز أصلي مقابلة لا يمكن ضبطها إلا في وقت الإنشاء ولا يمكن الاستعلام عنها مباشرةً من كائن مزامنة حالي. يمكن ضبط هذه السمة على أحد الوضعَين التاليَين:
- واصف ملف حاجز صالح يضمّن واصف ملف حاجز Android أصلي حالي في كائن
EGLSyncKHR. - -1 ينشئ واصف ملف حاجز Android أصلي من كائن
EGLSyncKHR.
استخدِم استدعاء الدالة DupNativeFenceFD() لاستخراج كائن EGLSyncKHR من واصف ملف حاجز Android الأصلي.
ويحقق ذلك النتيجة نفسها التي تحقّقها عملية الاستعلام عن السمة التي تم ضبطها، ولكنّه يلتزم بالاتفاقية التي تنص على أنّ المستلِم يغلق الحاجز (وبالتالي عملية التكرار). أخيرًا، يؤدي إتلاف كائن EGLSyncKHR إلى إغلاق سمة الحاجز الداخلية.
دمج Hardware Composer
يتعامل HWC مع ثلاثة أنواع من حواجز المزامنة:
- يتم تمرير حواجز الاستحواذ مع المخازن المؤقتة للإدخال إلى
استدعاءات
setLayerBufferوsetClientTarget. تمثّل هذه الحواجز عملية كتابة معلّقة في المخزن المؤقت ويجب أن تشير إلى ذلك قبل أن يحاول SurfaceFlinger أو HWC القراءة من المخزن المؤقت المرتبط لإجراء عملية التركيب. - يتم استردادحواجز الإصدار
بعد استدعاء
presentDisplayباستخدام استدعاءgetReleaseFences. تمثّل هذه الحواجز عملية قراءة معلّقة من المخزن المؤقت السابق على الطبقة نفسها. تشير حواجز الإصدار إلى وقت توقّف HWC عن استخدام المخزن المؤقت السابق لأنّ المخزن المؤقت الحالي قد حلّ محل المخزن المؤقت السابق على شاشة العرض. يتم تمرير حواجز الإصدار مرة أخرى إلى التطبيق مع المخازن المؤقتة السابقة التي سيتم استبدالها أثناء عملية التركيب الحالية. يجب أن ينتظر التطبيق إلى أن تشير حواجز الإصدار قبل كتابة محتوى جديد في المخزن المؤقت الذي تم إرجاعه إليه. - يتم عرض**حواجز العرض**، واحد لكل إطار، كجزء من
استدعاء
presentDisplay. تمثّل حواجز العرض وقت اكتمال عملية تركيب هذا الإطار، أو بدلاً من ذلك، وقت عدم الحاجة إلى نتيجة تركيب الإطار السابق. بالنسبة إلى شاشات العرض الفعلية ، تعرضpresentDisplayحواجز العرض عندما يظهر الإطار الحالي على الشاشة. بعد عرض حواجز العرض، يصبح من الآمن الكتابة في المخزن المؤقت المستهدَف لـ SurfaceFlinger مرة أخرى، إذا كان ذلك ممكنًا. بالنسبة إلى شاشات العرض الافتراضية، يتم عرض حواجز العرض عندما يكون من الآمن القراءة من المخزن المؤقت للناتج.