مكتبة Frame Pacing جزء من Android Game Development Kit
مكتبة Android Frame Pacing، المعروفة أيضًا باسم Swappy، هي جزء من مكتبات AGDK. تساعد هذه الأداة ألعاب OpenGL وVulkan في تحقيق عرض سلس وتحديد معدّل عرض اللقطات بشكل صحيح على Android. يوضّح هذا المستند مفهوم "مزامنة اللقطات"، ويصف الحالات التي تكون فيها هذه الميزة ضرورية، ويوضّح كيفية تعامل المكتبة مع هذه الحالات. إذا أردت الانتقال مباشرةً إلى تنفيذ ميزة "مزامنة عرض اللقطات" في لعبتك، اطّلِع على الخطوة التالية.
الخلفية
مزامنة اللقطات هي مزامنة حلقة عرض اللعبة ومنطقها مع نظام فرعي للعرض في نظام التشغيل وأجهزة العرض الأساسية. تم تصميم نظام Android الفرعي للعرض لتجنُّب التشويش المرئي (المعروف باسم التمزّق) الذي يمكن أن يحدث عندما تنتقل أجهزة العرض إلى إطار جديد في منتصف عملية التحديث. لتجنُّب هذه المشاكل، يقوم نظام العرض الفرعي بما يلي:
- تخزين الإطارات السابقة مؤقتًا بشكل داخلي
- رصد عمليات إرسال الإطارات المتأخرة
- تكرار عرض اللقطات السابقة عند رصد لقطات متأخرة
تُعلم اللعبة
SurfaceFlinger،
وهي أداة التركيب ضِمن نظام العرض الفرعي، بأنّها أرسلت جميع طلبات الرسم اللازمة لإطار واحد (من خلال استدعاء eglSwapBuffers
أو vkQueuePresentKHR
).
تشير SurfaceFlinger إلى توفّر إطار واحد لأجهزة العرض باستخدام
مزلاج. تعرض أجهزة العرض بعد ذلك اللقطة المحدّدة. تعمل أجهزة العرض بمعدل ثابت، مثلاً 60 هرتز، وإذا لم يكن هناك إطار جديد عندما يحتاج الجهاز إلى إطار، يعرض الجهاز الإطار السابق مرة أخرى.
تحدث أحيانًا أوقات عرض غير متسقة للّقطات عندما تعرض حلقة عرض اللعبة اللقطات بمعدّل مختلف عن معدّل عرض أجهزة العرض الأصلية. إذا حاولت لعبة تعمل بمعدل 30 لقطة في الثانية عرض المحتوى على جهاز يتيح عرض 60 لقطة في الثانية، لن تدرك حلقة عرض اللعبة أنّ إطارًا مكررًا يبقى على الشاشة لمدة 16 ملي ثانية إضافية. يؤدي هذا الانقطاع عادةً إلى حدوث تفاوت كبير في أوقات عرض اللقطات، مثل: 49 ملي ثانية و16 ملي ثانية و33 ملي ثانية. تزيد المشاهد المعقّدة من حدة هذه المشكلة، لأنّها تؤدي إلى عدم عرض بعض اللقطات.
حلول غير مثالية
استخدمت الألعاب في السابق الحلول التالية لمزامنة عرض اللقطات، وهي تؤدي عادةً إلى أوقات غير متسقة لعرض اللقطات وزيادة في وقت استجابة الإدخال.
إرسال اللقطات بأسرع ما تسمح به واجهة برمجة التطبيقات للعرض
يربط هذا النهج اللعبة بنشاط SurfaceFlinger المتغيّر ويؤدي إلى تأخير إضافي في عرض الإطار. تحتوي سلسلة عرض الصور على قائمة انتظار للإطارات، عادةً ما يكون حجمها 2، وتتم تعبئتها إذا كانت اللعبة تحاول عرض الإطارات بسرعة كبيرة. عندما لا يكون هناك مساحة في قائمة الانتظار، يتم حظر حلقة اللعبة (أو على الأقل سلسلة عرض الصور) من خلال طلب OpenGL أو Vulkan. بعد ذلك، يتم إجبار اللعبة على الانتظار إلى أن تعرض أجهزة العرض إطارًا، ويؤدي هذا الضغط الخلفي إلى مزامنة المكوّنين. يُعرف هذا الوضع باسم تعبئة المخزن المؤقت أو تعبئة قائمة الانتظار. لا تدرك عملية العرض ما يحدث، ما يؤدي إلى تفاقم مشكلة عدم اتساق معدل عرض اللقطات. إذا أخذت اللعبة عيّنات من البيانات قبل عرض الإطار، سيزداد تأخّر الاستجابة.
استخدام Android Choreographer بمفرده
تستخدم الألعاب أيضًا Android Choreographer للمزامنة. يتوفّر هذا المكوّن في Java من المستوى 16 لواجهة برمجة التطبيقات وفي C++ من المستوى 24 لواجهة برمجة التطبيقات، ويعرض علامات منتظمة بالوتيرة نفسها التي يعرض بها النظام الفرعي. لا تزال هناك تفاصيل دقيقة بشأن وقت عرض علامة التجزئة هذه مقارنةً بعملية VSYNC الفعلية للأجهزة، وتختلف هذه الإزاحات حسب الجهاز. قد يستمرّ حدوث حشو مؤقت للإطارات الطويلة.
مزايا مكتبة Frame Pacing
تستخدم مكتبة Frame Pacing أداة Choreographer في Android للمزامنة، وتتعامل مع التفاوت في عرض اللقطات نيابةً عنك. يستخدم هذا التطبيق الطوابع الزمنية للعرض للتأكّد من عرض اللقطات في الوقت المناسب، كما يستخدم حواجز المزامنة لتجنُّب حشو المخزن المؤقت. تستخدم المكتبة NDK Choreographer إذا كانت متاحة، وتعود إلى Java Choreographer إذا لم تكن متاحة.
تتعامل المكتبة مع معدّلات تحديث متعدّدة إذا كان الجهاز يتيح ذلك، ما يمنح اللعبة مرونة أكبر في عرض اللقطة. على سبيل المثال، بالنسبة إلى جهاز يتيح معدّل تحديث 60 هرتز و90 هرتز، يمكن أن ينخفض معدّل اللقطات في الثانية في لعبة لا يمكنها عرض 60 لقطة في الثانية إلى 45 لقطة في الثانية بدلاً من 30 لقطة في الثانية للحفاظ على سلاسة الأداء. ترصد المكتبة معدّل عرض اللقطات المتوقّع في اللعبة وتعدّل تلقائيًا أوقات عرض اللقطات وفقًا لذلك. تعمل مكتبة Frame Pacing أيضًا على تحسين عمر البطارية لأنّها تتجنّب تحديثات العرض غير الضرورية. على سبيل المثال، إذا كانت إحدى الألعاب تعرض 60 لقطة في الثانية، ولكن الشاشة تعرض 120 لقطة في الثانية، سيتم تعديل الشاشة مرتين لكل لقطة. تتجنّب مكتبة Frame Pacing حدوث ذلك من خلال ضبط معدّل التحديث على القيمة التي يتيحها الجهاز الأقرب إلى عدد اللقطات المستهدَف في الثانية.
آلية العمل
توضّح الأقسام التالية كيف تتعامل مكتبة Frame Pacing مع إطارات الألعاب الطويلة والقصيرة من أجل تحقيق معدّل عرض لقطات صحيح.
تحديد سرعة عرض اللقطات بشكل صحيح عند 30 هرتز
عند العرض بمعدل 30 هرتز على جهاز بمعدل 60 هرتز، يظهر الوضع المثالي على Android في الشكل 1. تثبّت SurfaceFlinger مخازن مؤقتة جديدة للرسومات، إذا كانت متوفرة (يشير الرمز NB في الرسم البياني إلى عدم توفّر أي مخزن مؤقت ويتم تكرار المخزن السابق).
الشكل 1. مزامنة مثالية لعرض اللقطات بمعدّل 30 هرتز على جهاز بمعدّل 60 هرتز
تؤدي لقطات الألعاب القصيرة إلى تقطُّع في الصورة
في معظم الأجهزة الحديثة، تعتمد محركات الألعاب على أداة تنظيم الوقت في النظام الأساسي لتوفير وحدات زمنية تؤدي إلى إرسال اللقطات. ومع ذلك، لا يزال من المحتمل حدوث مشاكل في سرعة عرض اللقطات بسبب اللقطات القصيرة، كما هو موضّح في الشكل 2. يُدرك المشغّل أنّ اللقطات القصيرة التي تليها لقطات طويلة هي لقطات متقطّعة.
الشكل 2. تتسبّب اللقطة C القصيرة في اللعبة في عرض لقطة واحدة فقط من اللقطة B، يليها لقطات C متعدّدة.
تعمل مكتبة Frame Pacing على حلّ هذه المشكلة باستخدام الطوابع الزمنية للعرض. تستخدم المكتبة امتدادات الطابع الزمني للعرض التقديمي
EGL_ANDROID_presentation_time
و
VK_GOOGLE_display_timing
حتى لا يتم عرض اللقطات مبكرًا، كما هو موضّح في الشكل 3.
الشكل 3. تم عرض إطار اللعبة B مرتين للحصول على عرض أكثر سلاسة.
تؤدي اللقطات الطويلة إلى تقطُّع الفيديو وتأخُّر الاستجابة
عندما تستغرق وحدة عمل العرض وقتًا أطول من وحدة عمل التطبيق، تتم إضافة إطارات إضافية إلى قائمة انتظار. يؤدي ذلك مرة أخرى إلى تقطُّع الصوت وقد يؤدي أيضًا إلى تأخير إضافي في عرض اللقطة بسبب حشو المخزن المؤقت (راجِع الشكل 4). تزيل المكتبة كلاً من التقطّع والتأخير الإضافي في عرض اللقطات.
الشكل 4 يؤدي إطار B الطويل إلى وتيرة غير صحيحة لإطارَين، وهما A وB
تتغلّب المكتبة على هذه المشكلة باستخدام حواجز المزامنة
(EGL_KHR_fence_sync
و
VkFence
)
لإضافة عمليات انتظار إلى التطبيق تتيح لخط أنابيب العرض اللحاق بالركب، بدلاً من السماح بتراكم الضغط الخلفي. لا يزال الإطار (أ) يعرض إطارًا إضافيًا، ولكن يعرض الإطار (ب) الآن بشكل صحيح، كما هو موضّح في الشكل 5.
الشكل 5. تنتظر اللقطتان C وD العرض.
أوضاع التشغيل المتوافقة
يمكنك ضبط مكتبة Frame Pacing للعمل في أحد الأوضاع الثلاثة التالية:
- إيقاف الوضع التلقائي + البث المباشر
- الوضع التلقائي مفعّل + ميزة "المعالجة المتسلسلة"
- الوضع التلقائي مُفعَّل + وضع المعالجة التلقائي (معالجة/بدون معالجة)
الوضع المقترَح
يمكنك تجربة وضع التشغيل التلقائي ووضع خطوط الأنابيب، ولكن عليك البدء بإيقافهما وتضمين ما يلي بعد تهيئة Swappy:
swappyAutoSwapInterval(false);
swappyAutoPipelineMode(false);
swappyEnableStats(false);
swappySwapIntervalNS(1000000000L/yourPreferredFrameRateInHz);
وضع "خطوات متسلسلة"
لتنسيق أحمال عمل المحرّك، تستخدم المكتبة عادةً نموذجًا لتنفيذ التعليمات البرمجية بالتسلسل يفصل أحمال عمل وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسومات (GPU) على مستوى حدود VSYNC.
الشكل 6. وضع العرض المتسلسل
وضع عدم استخدام خطوط الإنتاج
وبشكل عام، يؤدي هذا النهج إلى تقليل وقت الاستجابة بين شاشة الإدخال وشاشة العرض، ما يجعله أكثر قابلية للتوقّع. في الحالات التي تكون فيها مدة عرض اللقطة في إحدى الألعاب منخفضة جدًا، قد تتناسب أحمال عمل وحدة المعالجة المركزية ووحدة معالجة الرسومات مع فاصل تبديل واحد. في هذه الحالة، سيؤدي استخدام طريقة غير مجزأة إلى تقليل وقت الاستجابة بين الإدخال والشاشة.
الشكل 7. وضع عدم استخدام المسار
وضع "تلقائي"
لا تعرف معظم الألعاب كيفية اختيار فاصل التبديل، وهو المدة الزمنية التي يتم فيها عرض كل إطار (على سبيل المثال، 33.3 ملي ثانية عند 30 هرتز). في بعض الأجهزة، يمكن عرض اللعبة بمعدّل 60 لقطة في الثانية، بينما قد تحتاج إلى خفض المعدّل إلى قيمة أقل على جهاز آخر. يقيس "الوضع التلقائي" أوقات وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسومات (GPU) من أجل تنفيذ ما يلي:
- اختيار فواصل التبديل تلقائيًا: يمكن للألعاب التي تعرض 30 لقطة في الثانية في بعض المشاهد و60 لقطة في الثانية في مشاهد أخرى أن تسمح للمكتبة بضبط هذا الفاصل زمنيًا بشكل ديناميكي.
- إيقاف ميزة "نقل البيانات عبر خطوط الأنابيب" للقطات فائقة السرعة: تتيح هذه الميزة تحقيق أفضل وقت استجابة بين الإدخال والشاشة في جميع الحالات.
معدّلات تحديث متعدّدة
توفّر الأجهزة التي تتيح معدّلات تحديث متعدّدة مرونة أكبر في اختيار فاصل تبديل يبدو سلسًا:
- على الأجهزة التي تعمل بمعدل 60 هرتز: 60 لقطة في الثانية / 30 لقطة في الثانية / 20 لقطة في الثانية
- على الأجهزة التي تعمل بتردد 60 هرتز و90 هرتز: 90 لقطة في الثانية / 60 لقطة في الثانية / 45 لقطة في الثانية / 30 لقطة في الثانية
- على الأجهزة التي تعمل بمعدل 60 هرتز و90 هرتز و120 هرتز: 120 لقطة في الثانية / 90 لقطة في الثانية / 60 لقطة في الثانية / 45 لقطة في الثانية / 40 لقطة في الثانية / 30 لقطة في الثانية
تختار المكتبة معدّل التحديث الذي يتطابق بشكل أفضل مع مدة العرض الفعلية للقطات في اللعبة، ما يوفّر تجربة بصرية أفضل.
لمزيد من المعلومات حول مزامنة اللقطات بمعدّلات تحديث متعدّدة، يُرجى الاطّلاع على مشاركة المدوّنة عرض المحتوى بمعدّل تحديث عالٍ على Android.
إحصاءات اللقطات
تقدّم مكتبة Frame Pacing الإحصاءات التالية لأغراض تصحيح الأخطاء وإنشاء الملفات الشخصية:
- مدرّج تكراري لعدد مرات إعادة تحميل الشاشة التي انتظرها أحد الإطارات في قائمة انتظار برنامج التجميع بعد اكتمال العرض
- مدرّج تكراري لعدد عمليات إعادة تحميل الشاشة التي تمّت بين وقت العرض المطلوب ووقت العرض الفعلي
- مدرّج تكراري لعدد عمليات إعادة تحميل الشاشة التي تم إجراؤها بين إطارين متتاليين.
- مدرّج تكراري لعدد عمليات إعادة تحميل الشاشة التي تم إجراؤها بين بداية عمل وحدة المعالجة المركزية لهذا الإطار والوقت الحالي الفعلي
الخطوة التالية
راجِع أحد الدليلَين التاليَين لدمج مكتبة Android Frame Pacing في لعبتك:
- دمج ميزة "مزامنة اللقطات" في Android في أداة العرض OpenGL
- دمج Android Frame Pacing في أداة العرض Vulkan
مراجع إضافية
- تحسّن لعبة Mir 2 أداء العرض باستخدام Swappy، ما أدّى إلى انخفاض معدّل الجلسات البطيئة من% 40 إلى %10.