يصف إطار عمل المزامنة بوضوح التبعيات بين العمليات غير المتزامنة المختلفة في نظام الرسومات في Android. يقدّم الإطار العملي واجهة برمجة تطبيقات تتيح للمكوّنات الإشارة إلى وقت تحرير ذاكرة التخزين المؤقت. يسمح الإطار أيضًا بتمرير عناصر المزامنة الأساسية بين برامج التشغيل من kernel إلى مساحة المستخدم وبين عمليات مساحة المستخدم نفسها.
على سبيل المثال، قد يضيف التطبيق مهام إلى "قائمة الانتظار" لتنفيذها في وحدة معالجة الرسومات. تبدأ وحدة معالجة الرسومات في رسم هذه الصورة. على الرغم من أنّه لم يتم رسم الصورة في الذاكرة بعد، يتم تمرير مؤشر المخزن المؤقت إلى مؤلف الإطارات للنافذة مع فاصل يشير إلى وقت انتهاء عمل وحدة معالجة الرسومات. يبدأ مركب النوافذ المعالجة مسبقًا ويصعِّد العمل إلى وحدة تحكّم الشاشة. وبطريقة مماثلة، يتم تنفيذ عمل وحدة المعالجة المركزية مسبقًا. بعد انتهاء وحدة معالجة الرسومات، يعرض عنصر التحكّم في الشاشة الصورة على الفور.
يتيح إطار عمل المزامنة أيضًا للمنفّذين الاستفادة من موارد المزامنة في مكوّنات الأجهزة الخاصة بهم. أخيرًا، يقدّم الإطار المرجعي إمكانية الاطّلاع على مسار الرسومات للمساعدة في تصحيح أخطاء الترجمة.
مزامنة صريحة
تتيح المزامنة الصريحة لمنتجي ومستخدِمي ذاكرات التخزين المؤقت للرسومات إعلام بعضهم البعض عند الانتهاء من استخدام ذاكرة تخزين مؤقت. يتم تنفيذ المزامنة الصريحة في مساحة kernel.
تشمل مزايا المزامنة الصريحة ما يلي:
- انخفاض في الاختلاف في السلوك بين الأجهزة
- إتاحة تصحيح أفضل
- مقاييس الاختبار المحسّنة
يتضمّن إطار عمل المزامنة ثلاثة أنواع من العناصر:
sync_timeline
sync_pt
sync_fence
مزامنة_المخطط الزمني
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 عدم إغلاق واصف الملف. - لمواصلة استخدام وصف ملف السياج، يجب أن يكرّر برنامج تشغيل المورّد أو HAL الوصف.
تتم إعادة تسمية عنصر السياج في كل مرة يمر فيها عبر BufferQueue.
يتيح الدعم الخاص بسياج النواة (Kernel) للسياجات وجود سلاسل للأسماء، وبالتالي يستخدم إطار عمل المزامنة اسم النافذة وفهرس المخزن المؤقت الذي يتم وضعه في قائمة الانتظار لتسمية السياج، مثل 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
سمة واصف ملف سياج أصلي
يمكن ضبطها فقط في وقت الإنشاء ولا يمكن طلب البحث عنها مباشرةً من عنصر مزامنة حالي. يمكن ضبط هذه السمة على أحد الوضعَين التاليَين:
- يُغلِّف ملف وصف سياج صالح ملف وصف سياج Android أصليًا في عنصر
EGLSyncKHR
. - ينشئ -1 وصفًا لملف سياج Android أصلي من ملف
EGLSyncKHR
.
يمكنك استخدام استدعاء الدالة DupNativeFenceFD()
لاستخراج
كائن EGLSyncKHR
من أداة وصف ملف السياج الأصلي في Android.
يؤدي ذلك إلى النتيجة نفسها التي يؤدي إليها طلب البحث عن السمة set، ولكنه يلتزم
بالمعيار الذي يقضي بأن يغلق المستلِم السياج (من هنا عملية تكرار
). أخيرًا، يؤدي تدمير عنصر EGLSyncKHR
إلى إغلاق
سمة السياج الداخلي.
دمج Hardware Composer
يعالج "أداة إنشاء الأجهزة" ثلاثة أنواع من حدود المزامنة:
- يتم تمرير حدود الاستحواذ مع وحدات تخزين مؤقت للدخل إلى
طلبَي
setLayerBuffer
وsetClientTarget
. وتمثل هذه التحديثات رسالة نصّية في انتظار المراجعة في المخزن المؤقت ويجب أن تشير قبل أن يحاول SurfaceFlinger أو HWC القراءة من المخزن المؤقت المرتبط لإجراء التركيب. - يتم استرداد إلغاء القيود بعد الاتصال بـ
presentDisplay
باستخدام طلبgetReleaseFences
. تمثل هذه القراءة قراءة معلقة من المخزن المؤقت السابق على نفس الطبقة. يشير ذلك إلى أنّ المخزن المؤقت قبل أن يتوقّف عن استخدام المخزن المؤقت السابق لأنّ المخزن المؤقت الحالي استبدل المخزن المؤقت السابق على الشاشة إذا لم يعد "HWC" مستخدَمًا. يتم تمرير حدود الإصدار مرة أخرى إلى التطبيق مع المخازن المؤقتة السابقة التي سيتم استبدالها أثناء عملية الإنشاء الحالية. على التطبيق الانتظار إلى أن يتم تلقي إشارة بدء الإصدار قبل كتابة محتوى جديد في المخزن المؤقت الذي تم إرجاعه إليه. - يتم عرض حدود العرض، واحدة لكل إطار، كجزء من
طلب
presentDisplay
. تمثّل الأسوار الحالية وقت اكتمال تركيب هذا الإطار، أو بدلاً من ذلك، عندما لم تعُد نتيجة تركيب الإطار السابق مطلوبة. بالنسبة إلى الشاشات الفعلية، تعرضpresentDisplay
الأسوار الحالية عندما يظهر الإطار الحالي على الشاشة. بعد إرجاع الأسوار الحالية، من الآمن الكتابة في المخزن المؤقت المستهدف لـ SurfaceFlinger مرة أخرى، إذا كان ذلك منطبقًا. بالنسبة إلى الشاشات الافتراضية، يتم عرض الأسوار الحالية عندما يكون من الآمن القراءة من مخزن الإخراج.