سرعت قاب

کتابخانه Android Frame Pacing که با نام Swappy نیز شناخته می‌شود، بخشی از کیت توسعه نرم‌افزاری بازی اندروید (Android Game SDK) است. این کتابخانه به بازی‌های OpenGL و Vulkan کمک می‌کند تا رندر روان و سرعت فریم صحیحی را در اندروید به دست آورند.

تنظیم سرعت فریم، هماهنگ‌سازی منطق و حلقه رندر یک بازی با زیرسیستم نمایش سیستم عامل و سخت‌افزار نمایش زیربنایی آن است. زیرسیستم نمایش اندروید برای جلوگیری از برخی مصنوعات بصری، مانند پارگی تصویر، طراحی شده است. زیرسیستم نمایش با انجام موارد زیر از پارگی تصویر جلوگیری می‌کند:

  • بافر کردن فریم‌های قبلی به صورت داخلی
  • تشخیص ارسال فریم با تأخیر
  • ادامه نمایش فریم فعلی در صورت شناسایی فریم دیرهنگام

زمان‌های نمایش فریم متناقض به دلیل اجرای حلقه رندر بازی با سرعتی متفاوت از آنچه سخت‌افزار نمایشگر بومی پشتیبانی می‌کند، ایجاد می‌شوند. مشکلات زمانی ایجاد می‌شوند که حلقه رندر یک بازی برای سخت‌افزار نمایشگر اصلی خیلی کند اجرا شود و منجر به زمان‌های نمایش متناقض شود. به عنوان مثال، وقتی یک بازی با سرعت 30 فریم در ثانیه سعی می‌کند روی دستگاهی که به طور بومی از 60 فریم در ثانیه پشتیبانی می‌کند، رندر شود، حلقه رندر بازی باعث می‌شود یک فریم تکراری به مدت 16 میلی‌ثانیه اضافی روی صفحه باقی بماند. این نوع قطع ارتباط باعث ایجاد ناهماهنگی‌های قابل توجهی در زمان‌های فریم مانند 33 میلی‌ثانیه، 16 میلی‌ثانیه و 49 میلی‌ثانیه می‌شود. صحنه‌های بیش از حد پیچیده این مشکل را بیشتر می‌کنند زیرا باعث می‌شوند فریم‌های از دست رفته رخ دهند.

کتابخانه Frame Pacing این وظایف را انجام می‌دهد:

  • لکنت ناشی از فریم‌های کوتاه بازی را جبران می‌کند.
    • مهرهای زمانی ارائه را اضافه می‌کند تا فریم‌ها به موقع ارائه شوند، نه زودتر.
    • از افزونه‌های مهر زمانی ارائه EGL_ANDROID_presentation_time و VK_GOOGLE_display_timing استفاده می‌کند.
  • از نرده‌های همگام‌سازی برای فریم‌های طولانی استفاده می‌کند که منجر به لکنت و تأخیر می‌شود.
    • تزریق‌ها در برنامه منتظر می‌مانند. این‌ها به خط لوله نمایشگر اجازه می‌دهند تا به جای ایجاد فشار برگشتی، به آن برسد.
    • از نرده‌های همگام‌سازی ( EGL_KHR_fence_sync و VkFence ) استفاده می‌کند.
  • اگر دستگاه شما از چندین نرخ تازه‌سازی پشتیبانی می‌کند، یک نرخ تازه‌سازی را برای ارائه انعطاف‌پذیری و ارائه روان انتخاب می‌کند.
  • با استفاده از آمار فریم، آماری برای اشکال‌زدایی و پروفایلینگ ارائه می‌دهد.

برای یادگیری نحوه پیکربندی کتابخانه برای عملکرد در حالت‌های مختلف بسته به نیاز شما، به حالت‌های عملیاتی پشتیبانی‌شده مراجعه کنید.

برای پیاده‌سازی با استفاده از رندرکننده OpenGL یا رندرکننده Vulkan، به موارد زیر مراجعه کنید:

برای مطالعه بیشتر، به کتابخانه Frame Pacing مراجعه کنید.

فریم در ثانیه مداخله در تنظیم سرعت

مداخله در تنظیم فریم در ثانیه (FPS) به بازی‌ها این امکان را می‌دهد که تنها با استفاده از تغییرات جانبی پلتفرم و بدون نیاز به هیچ اقدامی از سوی توسعه‌دهندگان، با نرخ فریم مناسب بازی کنند.

پیاده‌سازی مداخله‌ی محدودسازی FPS از اجزای زیر استفاده می‌کند.

سرویس مدیریت بازی

کامپوننت GameManagerService تمام اطلاعات مربوط به هر کاربر و هر بازی در مورد حالت بازی و مداخله در بازی را نگهداری می‌کند. اطلاعات FPS در GameManagerService به همراه سایر اطلاعات مداخله، مانند ضریب کاهش وضوح، در یک نگاشت <PACKAGE_NAME, Interventions> برای هر پروفایل کاربر ذخیره می‌شود. اطلاعات FPS زمانی که حالت بازی تغییر می‌کند یا مداخله به‌روزرسانی می‌شود، قابل دسترسی است. یک UID برای هر PACKAGE_NAME و کاربر منحصر به فرد است و می‌تواند به یک جفت <UID, Frame Rate> برای ارسال به SurfaceFlinger تبدیل شود.

سرفیس‌فلینگر

کامپوننت SurfaceFlinger از قبل از محدود کردن FPS یک برنامه پشتیبانی می‌کند، مادامی که نرخ فریم، مقسوم‌علیه نرخ نوسازی صفحه نمایش باشد. در صورت VSync، SurfaceFlinger اعتبار VSync را برای برنامه‌ی محدود شده با تأیید اینکه آیا برچسب زمانی VSync با نرخ فریم برنامه همفاز است یا خیر، بررسی می‌کند. اگر نرخ فریم با VSync همفاز نباشد، SurfaceFlinger فریم را تا زمانی که نرخ فریم و VSync همفاز شوند، نگه می‌دارد.

شکل زیر تعامل بین GameManagerService و SurfaceFlinger را نشان می‌دهد:

تعامل بین GameManagerService و SurfaceFlinger

شکل ۱. تعامل بین GameServiceManager و SurfaceFlinger.

SurfaceFinger یک نگاشت جفتی <UID, Frame Rate> برای تنظیم اولویت جدید کاهش نرخ فریم حفظ می‌کند. UID بین کاربران و بازی‌ها منحصر به فرد است، به طوری که هر کاربر در یک دستگاه واحد می‌تواند تنظیمات متفاوتی از نرخ فریم را در همان بازی داشته باشد. برای کاهش نرخ فریم یک بازی، GameManagerService SurfaceFlinger را فراخوانی می‌کند تا نرخ فریم را برای یک UID لغو کند. با این مکانیسم، SurfaceFlinger هر زمان که حالت بازی تغییر کند یا مداخله به‌روزرسانی شود، نگاشت را به‌روزرسانی می‌کند. SurfaceFlinger با قفل کردن بافرها بر اساس آن، تغییر FPS را مدیریت می‌کند.

برای درک بیشتر در مورد محدود کردن FPS، به بخش محدود کردن FPS مراجعه کنید.