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