يصف إطار عمل المزامنة بوضوح التبعيات بين العمليات غير المتزامنة المختلفة في نظام الرسومات في Android. يقدّم الإطار العملي واجهة برمجة تطبيقات تتيح للمكوّنات الإشارة إلى وقت تحرير ذاكرة التخزين المؤقت. يسمح الإطار أيضًا بتمرير عناصر المزامنة الأساسية بين برامج التشغيل من kernel إلى مساحة المستخدم وبين عمليات مساحة المستخدم نفسها.
على سبيل المثال، قد يضيف التطبيق مهمة إلى "قائمة الانتظار" لتنفيذها في وحدة معالجة الرسومات. تبدأ وحدة معالجة الرسومات في رسم هذه الصورة. على الرغم من أنّه لم يتم رسم الصورة في الذاكرة بعد، يتم تمرير مؤشر المخزن المؤقت إلى مؤلف النوافذ مع فاصل يشير إلى وقت انتهاء عمل وحدة معالجة الرسومات. يبدأ مركب النوافذ المعالجة مسبقًا ويصعِّد العمل إلى وحدة تحكّم الشاشة. وبطريقة مماثلة، يتم تنفيذ عمل وحدة المعالجة المركزية قبل الموعد. بعد انتهاء وحدة معالجة الرسومات، يعرض عنصر التحكّم في الشاشة الصورة على الفور.
يتيح إطار عمل المزامنة أيضًا للمنفِّذين الاستفادة من موارد المزامنة في مكوّنات الأجهزة الخاصة بهم. أخيرًا، يقدّم الإطار المرجعي إمكانية الاطّلاع على مسار الرسومات للمساعدة في معالجة أخطاء الترجمة البرمجية.
المزامنة الصريحة
تتيح المزامنة الصريحة لمنتجي ومستخدِمي ذاكرات التخزين المؤقت للرسومات إعلام بعضهم البعض عند الانتهاء من استخدام ذاكرة تخزين مؤقت. يتم تنفيذ المزامنة الصريحة في مساحة النواة.
تشمل مزايا المزامنة الصريحة ما يلي:
- سلوك أقل اختلافًا بين الأجهزة
- تحسين دعم تصحيح الأخطاء
- مقاييس الاختبار المحسّنة
يتضمّن إطار عمل المزامنة ثلاثة أنواع من العناصر:
sync_timeline
sync_pt
sync_fence
sync_timeline
sync_timeline
هو مخطط زمني متزايد بشكل منتظم يجب أن ينفّذه المورّدون لكل مثيل برنامج تشغيل، مثل سياق GL أو معالج تحكم في الشاشة أو وحدة معالجة رسومات ثنائية الأبعاد. يحصِّل sync_timeline
المهام المرسَلة إلى النواة لجهاز معيّن.
sync_timeline
يوفّر ضمانات بشأن ترتيب العمليات ويمكّن من عمليات التنفيذ الخاصة بالأجهزة.
اتّبِع هذه الإرشادات عند تنفيذ sync_timeline
:
- قدِّم أسماء مفيدة لجميع العوامل المشغِّلة والمخططات الزمنية والحدود لتبسيط تصحيح الأخطاء.
- استخدِم عاملَي التشغيل
timeline_value_str
وpt_value_str
في المخططات الزمنية لجعل نتائج تصحيح الأخطاء أكثر سهولة في القراءة. - نفِّذ العنصر fill
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
بعد
إنشاء السياج. للحصول على أكثر من نقطة واحدة في سياج، يتم إجراء دمج
حيث تتم إضافة نقاط من سياجَين مختلفَين إلى سياج ثالث.
إذا تم إرسال إشارة إلى إحدى هاتين النقطتَين في السياج الأصلي ولم يتم إرسال إشارة إلى الأخرى، لن يكون السياج الثالث أيضًا في حالة تم إرسال إشارة إليه.
لتنفيذ المزامنة الصريحة، قدِّم ما يلي:
- نظام فرعي في مساحة النواة ينفذ إطار عمل المزامنة
لبرنامج تشغيل جهاز معيّن إنّ برامج التشغيل التي يجب أن تكون على دراية بالحدود هي عمومًا أيّ برنامج يصل إلى "أداة إنشاء الأجهزة" أو يتواصل معها.
تشمل الملفات الرئيسية ما يلي:
- التنفيذ الأساسي:
kernel/common/include/linux/sync.h
kernel/common/drivers/base/sync.c
- المستندات على
kernel/common/Documentation/sync.txt
- مكتبة للتواصل مع مساحة النواة في
platform/system/core/libsync
- التنفيذ الأساسي:
- على المورّد تقديم حدود التنسيق المناسبة
كمَعلمات لدوالّ
validateDisplay()
وpresentDisplay()
في HAL. - تم توفير اثنتان من إضافات GL ذات الصلة بحدود العناصر (
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
أكثر تعقيدًا. أثناء عرض المخزن المؤقت، يتم ربطه
بحدود تشير إلى وقت استعداد المخزن المؤقت. يمكنك إضافة المحتوى إلى "قائمة المحتوى التالي"
وبدء العمل بعد انتهاء فترة الحظر.
لا يؤدي وضع العمل في "قائمة الانتظار" وبدء العمل بعد إزالة المحتوى المحظور إلى حظر أي محتوى. يمكنك إعادة السياج الخاص بك على الفور، ما يضمن إزالة المخزن المؤقت من الشاشة. أثناء إضافة المخزن المؤقت إلى "قائمة الانتظار"، يُدرج kernel التبعيات في إطار عمل المزامنة:
/* * 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 وصف الملف. - لمواصلة استخدام وصف ملف السياج، يجب أن يكرّر برنامج تشغيل المورّد أو HMA descriptor.
تتم إعادة تسمية عنصر السياج في كل مرة يمر فيها عبر BufferQueue.
يتيح دعم سياج النواة أن تحتوي الأسوار على سلاسل للأسماء، لذا يستخدم إطار العمل
المخصص للمزامنة اسم النافذة وفهرسة المخزن المؤقت التي يتم وضعها في قائمة الانتظار لتسمية
السياج، مثل SurfaceView:0
. ويُعدّ ذلك مفيداً في تصحيح الأخطاء لتحديد مصدر حالة التوقف المفاجئ، لأنّ الأسماء تظهر في ناتج /d/sync
وتقارير الأخطاء.
دمج ANativeWindow
يراعي ANativeWindow السياج. تحتوي dequeueBuffer
وqueueBuffer
وcancelBuffer
على مَعلمات حدود.
دمج OpenGL ES
يعتمد دمج مزامنة OpenGL ES على إضافتَين من EGL:
- يوفّر
EGL_ANDROID_native_fence_sync
طريقة لملفEGLSyncKHR
لملفEGL_ANDROID_native_fence_sync
- يسمح
EGL_ANDROID_wait_sync
بتوقّف وحدة معالجة الرسومات بدلاً من وحدة المعالجة المركزية، ما يجعل وحدة معالجة الرسومات تنتظرEGLSyncKHR
. إضافةEGL_ANDROID_wait_sync
هي نفسها إضافةEGL_KHR_wait_sync
.
لاستخدام هذه الإضافات بشكل مستقل، عليك تنفيذ إضافة
EGL_ANDROID_native_fence_sync
مع ميزة
دعم kernel المرتبطة بها. بعد ذلك، فعِّل EGL_ANDROID_wait_sync
الإضافة في برنامج تشغيل الجهاز. تتألف إضافة EGL_ANDROID_native_fence_sync
من نوع EGLSyncKHR
خاص بعنصر السياج الأصلي. ونتيجةً لذلك، لا تنطبق بالضرورة الإضافات التي تنطبق على أنواع EGLSyncKHR
العناصر الحالية على عناصر EGL_ANDROID_native_fence
، ما يتجنّب التفاعلات غير المرغوب فيها.
تستخدِم إضافة EGL_ANDROID_native_fence_sync
سمة وصف ملف
fence الأصلية المقابلة التي لا يمكن ضبطها إلا في وقت الإنشاء
ولا يمكن الاستعلام عنها مباشرةً من عنصر مزامنة حالي. يمكن ضبط هذه السمة
على أحد الوضعَين التاليَين:
- يُغلِّف ملف وصف سياج صالح ملف وصف سياج Android أصليًا قائمًا في عنصر
EGLSyncKHR
. - ينشئ -1 وصفًا لملف سياج Android أصلي من
EGLSyncKHR
.
استخدِم طلب دالة DupNativeFenceFD()
لاستخراج كائن
EGLSyncKHR
من وصف ملف السياج الأصلي في Android.
يؤدي ذلك إلى النتيجة نفسها التي يؤدي إليها طلب البحث عن السمة set، ولكنه يلتزم
بالمعيار الذي يقضي بأن يغلق المستلِم السياج (من هنا عملية تكرار
). أخيرًا، يؤدي تدمير عنصر EGLSyncKHR
إلى إغلاق
سمة السياج الداخلي.
دمج Hardware Composer
يعالج "أداة إنشاء الأجهزة" ثلاثة أنواع من حدود المزامنة:
- يتم تمرير حدود الاستحواذ مع وحدات تخزين مؤقت للإدخال إلى
طلبَي
setLayerBuffer
وsetClientTarget
. يمثّل ذلك عملية كتابة في انتظار المعالجة في المخزن المؤقت، ويجب أن يتم إرسال إشارة قبل أن يحاول SurfaceFlinger أو HWC القراءة من المخزن المؤقت المرتبط للقيام بالتركيب. - يتم استرداد حدود الإصدار بعد المكالمة المرسَلة إلى
presentDisplay
باستخدام المكالمةgetReleaseFences
. ويمثّل ذلك عملية قراءة في انتظار المراجعة من المخزن المؤقت السابق في الطبقة نفسها. يشير رمز الإصدار إلى أنّ وحدة التحكّم في الأجهزة لم تعُد تستخدم المخزن المؤقت السابق لأنّ المخزن المؤقت الحالي قد حلّ محلّ المخزن المؤقت السابق على الشاشة. يتم تمرير حدود الإصدار مرة أخرى إلى التطبيق مع المخازن المؤقتة السابقة التي سيتم استبدالها أثناء عملية الإنشاء الحالية. على التطبيق الانتظار إلى أن يتم تلقي إشارة بدء الإصدار قبل كتابة محتوى جديد في المخزن المؤقت الذي تم إرجاعه إليه. - يتم عرض حدود العرض، واحدة لكل إطار، كجزء من
طلب
presentDisplay
. تمثّل الأسوار الحالية وقت اكتمال تركيب هذا الإطار، أو بدلاً من ذلك، عندما لم تعُد نتيجة تركيب الإطار السابق مطلوبة. بالنسبة إلى الشاشات الفعلية، تعرضpresentDisplay
الأسوار الحالية عندما يظهر الإطار الحالي على الشاشة. بعد إرجاع الأسوار الحالية، من الآمن الكتابة إلى المخزن المؤقت المستهدَف في SurfaceFlinger مرة أخرى، إذا كان ذلك منطبقًا. بالنسبة إلى الشاشات الافتراضية، يتم عرض الأسوار الحالية عندما يكون من الآمن القراءة من مخزن الإخراج.