إطار التزامن

يصف إطار عمل المزامنة بوضوح التبعيات بين العمليات غير المتزامنة المختلفة في نظام رسومات 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 مرة أخرى، إن أمكن. بالنسبة لشاشات العرض الافتراضية، يتم إرجاع الأسوار الحالية عندما يكون من الآمن قراءتها من المخزن المؤقت للإخراج.