نرخ تازه سازی چندگانه

اندروید 11 از دستگاه‌هایی با نرخ‌های تازه‌سازی چندگانه پشتیبانی می‌کند. سه جزء اصلی برای این ویژگی وجود دارد:

  • API های جدید HAL در android.hardware.graphics.composer@2.4 معرفی شدند.
  • کد پلت فرم برای تجزیه تنظیمات دستگاه برای نرخ‌های تازه‌سازی مختلف و تنظیم نرخ تازه‌سازی مورد نظر
  • API های SDK و NDK جدید به برنامه ها اجازه می دهد تا نرخ فریم مورد نظر خود را تنظیم کنند

پیاده سازی

پشتیبانی اختصاصی برای تغییر نرخ تجدید به android.hardware.graphics.composer@2.4 HAL اضافه شده است. ما قویاً استفاده از این نسخه را توصیه می‌کنیم زیرا نسخه‌های قبلی composer HAL پشتیبانی محدودی از تغییر نرخ تازه‌سازی دارند.

گروه های پیکربندی

یک ویژگی جدید CONFIG_GROUP به IComposerClient::Attribute اضافه شد که با استفاده از getDisplayAttribute_2_4 API قابل پرس و جو است. این ویژگی به فروشندگان اجازه می دهد تا پیکربندی های نمایشگر را با هم گروه بندی کنند. پیکربندی‌های موجود در یک گروه امکان جابجایی یکپارچه بین آنها را در بیشتر موارد فراهم می‌کنند. گروه پیکربندی توسط پلتفرم استفاده می‌شود تا مشخص کند کدام پیکربندی را می‌توان بین آنها تغییر داد و نه سایر ویژگی‌های یک پیکربندی را تغییر داد.

مثال زیر را در نظر بگیرید که مزایای استفاده از گروه های پیکربندی را با دستگاهی که از چهار پیکربندی نمایشگر پشتیبانی می کند نشان می دهد:

  • 1080p@60Hz
  • 1080p@90Hz
  • 1080i@72Hz
  • 1080i@48Hz

حتی اگر دستگاه از نرخ‌های تازه‌سازی 48 هرتز، 60 هرتز، 72 هرتز و 90 هرتز پشتیبانی می‌کند، نمایشگر در حالت دیگری کار می‌کند و تغییر از 60 هرتز به 72 هرتز، پیکربندی نمایشگر را از 1080p به 1080i تغییر می‌دهد، که ممکن است رفتار مطلوب نباشد. این با استفاده از گروه های پیکربندی حل می شود. با گروه بندی 60 هرتز و 90 هرتز در یک گروه پیکربندی و 48 هرتز و 72 هرتز در یک گروه پیکربندی دیگر. این پلتفرم می داند که می تواند بین 60 هرتز و 90 هرتز و بین 48 هرتز و 72 هرتز جابجا شود، اما نه بین 60 هرتز و 72 هرتز، زیرا به جای تغییر صرفاً نرخ تازه سازی، منجر به تغییر پیکربندی می شود.

به‌روزرسانی‌های API Composer

getDisplayVsyncPeriod
برای کنترل بهتر و پیش‌بینی‌پذیری هنگام تغییر نرخ‌های تازه‌سازی getDisplayVsyncPeriod اضافه شده است. getDisplayVsyncPeriod نرخ تازه سازی فعلی (از نظر دوره vsync) را که نمایشگر در آن کار می کند، برمی گرداند. این امر به ویژه در زمانی مفید است که پلتفرم برای تصمیم گیری در مورد زمان شروع فریم بعدی، به انتقال بین نرخ تازه سازی و نرخ تازه سازی فعلی نیاز دارد.
setActiveConfigWithConstraints
متد setActiveConfigWithConstraints یک پسوند جدید برای متد setActiveConfig موجود است و اطلاعات بیشتری در مورد تغییر پیکربندی ارائه می دهد. محدودیت ها به عنوان بخشی از پارامترهای vsyncPeriodChangeConstraints داده شده و شامل پارامترهای زیر است.
    دلخواه TimeNanos
    زمانی در CLOCK_MONOTONIC که پس از آن دوره vsync ممکن است تغییر کند (یعنی دوره vsync نباید قبل از این زمان تغییر کند). این زمانی مفید است که پلتفرم می‌خواهد از قبل برای تغییر نرخ تازه‌سازی برنامه‌ریزی کند، اما از قبل دارای بافرهایی برای ارائه در صف است. پلتفرم این زمان را بر این اساس تنظیم می‌کند تا آن بافرها را در نظر بگیرد و مطمئن شود که انتقال نرخ تازه‌سازی تا حد امکان روان خواهد بود.
    بدون درز الزامی است
    اگر درست باشد، مستلزم این است که تغییر دوره vsync باید به طور یکپارچه و بدون یک مصنوع بصری قابل توجه اتفاق بیفتد. این پرچم زمانی توسط پلتفرم مورد استفاده قرار می‌گیرد که در نتیجه تغییر محتوا به تغییر نرخ تازه‌سازی نیاز باشد (مثلاً دستگاه غیرفعال است و انیمیشن شروع می‌شود). این به فروشنده این فرصت را می دهد که اجازه دهد تغییرات پیکربندی خاصی را زمانی که ممکن است منجر به یک مصنوع بصری قابل توجه شود، ندهد. اگر پیکربندی‌ها را نتوان یکپارچه تغییر داد و seamlessRequired روی true تنظیم شده باشد، انتظار می‌رود که پیاده‌سازی SEAMLESS_NOT_POSSIBLE را به عنوان کد بازگشتی برگرداند و زمانی که همان تغییر پیکربندی را می‌توان به‌طور یکپارچه انجام داد، تماس مجدد onSeamlessPossible را فراخوانی کرد.

پس از موفقیت، پیاده‌سازی یک VsyncPeriodChangeTimeline را برمی‌گرداند که به پلتفرم می‌گوید چه زمانی باید انتظار داشته باشد که تغییر نرخ تازه‌سازی رخ دهد. پارامترهای newVsyncAppliedTimeNanos باید روی زمانی در CLOCK_MONOTONIC تنظیم شوند که نمایشگر جدید در دوره vsync جدید شروع به تازه شدن می‌کند. این به همراه desiredTimeNanos به پلتفرم اجازه می‌دهد تا سوئیچ نرخ تازه‌سازی را از قبل برنامه‌ریزی کند و از قبل برنامه‌ها را برای نرخ تازه‌سازی جدید علامت بزند. این اجازه می دهد تا یک انتقال یکپارچه از نرخ تجدید.

برخی از پیاده‌سازی‌ها نیاز به ارسال یک فریم تازه‌سازی دارند تا بتوان نرخ تازه‌سازی را ارسال کرد. برای آن، HAL دارای پارامتر refreshRequired برای نشان دادن نیاز به یک فریم به‌روزرسانی و refreshTimeNanos برای نشان دادن اولین vsync است که یک فریم تازه‌سازی باید بعد از آن ارسال شود.

onVsyncPeriodTimingChanged [بازخوانی]
یک فراخوان جدید که می تواند توسط HAL فراخوانی شود تا به پلت فرم نشان دهد که برخی از پارامترهای خط زمانی تغییر کرده است و پلت فرم باید خط زمانی خود را تنظیم کند. در صورتی که به دلایلی خط زمانی قدیمی به دلیل زمان پردازش طولانی در HAL یا یک فریم به‌روزرسانی دیرهنگام از دست رفته باشد، انتظار می‌رود این تماس برگشتی فراخوانی شود.

چگونه پلتفرم تصمیم می‌گیرد نرخ تازه‌سازی را تغییر دهد؟

انتخاب نرخ تازه سازی در دو سرویس سیستم زیر انجام می شود:

DisplayManager
DisplayManager خط مشی سطح بالا را حول نرخ تازه سازی تنظیم می کند. یک پیکربندی نمایش پیش فرض را تنظیم می کند، که همان پیکربندی HAL آهنگساز است. علاوه بر این، محدوده ای از حداقل و حداکثر مقادیر را برای SurfaceFlinger تنظیم می کند تا به عنوان نرخ تازه سازی انتخاب شود.
سرفیس فلینگر
با تنظیم پیکربندی که در همان گروه پیکربندی پیکربندی پیش‌فرض و با نرخ تازه‌سازی در محدوده حداقل/حداکثر است، نرخ تازه‌سازی را تعیین می‌کند.

مدیر نمایش برای تعیین خط مشی مراحل زیر را طی می کند:

  • شناسه پیکربندی پیش‌فرض را با جستجو در پیکربندی فعال از SurfaceFlinger پیدا می‌کند
  • محدود کردن دامنه مقادیر حداقل و حداکثر با تکرار در شرایط سیستم
    • تنظیم نرخ نوسازی پیش‌فرض : مقدار نرخ تازه‌سازی پیش‌فرض در پوشش پیکربندی R.integer.config_defaultRefreshRate تنظیم می‌شود. این مقدار برای تعیین نرخ تازه سازی استاندارد دستگاه برای انیمیشن ها و تعاملات لمسی استفاده می شود.
    • تنظیم نرخ نوسازی اوج : مقدار اوج نرخ تازه‌سازی از Settings.System.PEAK_REFRESH_RATE خوانده می‌شود. این مقدار در زمان اجرا تغییر می کند تا تنظیمات فعلی دستگاه را منعکس کند (مانند یک گزینه منو). مقدار پیش‌فرض در روکش پیکربندی R.integer.config_defaultPeakRefreshRate تنظیم شده است.
    • تنظیم حداقل نرخ تازه‌سازی : مقدار حداقل نرخ تازه‌سازی از Settings.System.MIN_REFRESH_RATE خوانده می‌شود. این مقدار را می توان در زمان اجرا تغییر داد تا تنظیمات فعلی دستگاه را منعکس کند (مانند یک گزینه منو). مقدار پیش فرض 0 است، بنابراین حداقل پیش فرض وجود ندارد.
    • درخواست ModeId : برنامه‌ها می‌توانند WindowManager.LayoutParams.preferredDisplayModeId تنظیم کنند تا پیکربندی ترجیحی را که نمایشگر باید در آن کار کند، منعکس کند. در بیشتر شرایط DisplayManager شناسه تنظیمات پیش‌فرض را بر اساس آن تنظیم می‌کند و حداقل و حداکثر نرخ تازه‌سازی را برای مطابقت با نرخ تازه‌سازی پیکربندی تنظیم می‌کند.
    • صرفه جویی در باتری : هنگامی که دستگاه در حالت کم مصرف است، نرخ تازه سازی به 60 هرتز یا کمتر محدود می شود که از طریق Settings.Global.LOW_POWER_MODE.

هنگامی که DisplayManager خط‌مشی را تنظیم کرد، SurfaceFlinger نرخ تازه‌سازی را بر اساس لایه‌های فعال (لایه‌هایی که به‌روزرسانی‌های فریم را در صف قرار می‌دهند) تنظیم می‌کند. اگر صاحب لایه یک نرخ فریم را تعیین کند، SurfaceFlinger سعی می‌کند نرخ تازه‌سازی را روی چیزی تنظیم کند که ضریب آن نرخ است. به عنوان مثال اگر دو لایه فعال نرخ فریم خود را روی 24 تنظیم کنند و SurfaceFlinger 60 در صورت موجود بودن آن 120 هرتز را انتخاب می کند. اگر چنین نرخ تازه‌سازی برای SurfaceFlinger در دسترس نباشد، سعی می‌کند نرخ تازه‌سازی را انتخاب کند که کمترین خطا را برای نرخ فریم دارد. برای اطلاعات بیشتر به مستندات توسعه دهنده در developer.android.com مراجعه کنید

SurfaceFlinger پرچم‌های زیر را برای کنترل نحوه تصمیم‌گیری نرخ تازه‌سازی حفظ می‌کند:

  • ro.surface_flinger.use_content_detection_for_refresh_rate: اگر تنظیم شود، نرخ تازه‌سازی براساس لایه‌های فعال تعیین می‌شود، حتی اگر نرخ فریم تنظیم نشده باشد. SurfaceFlinger یک اکتشافی را حفظ می کند که در آن میانگین فریم در ثانیه را که لایه بافر ارسال می کند را با نگاه کردن به مهر زمانی ارائه متصل به بافر می یابد.
  • ro.surface_flinger.set_touch_timer_ms : اگر > 0 باشد، زمانی که کاربر صفحه را برای مهلت زمانی پیکربندی شده لمس می کند، نرخ تازه سازی پیش فرض استفاده می شود. این اکتشافی برای آماده شدن با نرخ تازه سازی پیش فرض برای انیمیشن ها انجام می شود.
  • ro.surface_flinger.set_idle_timer_ms : اگر > 0 باشد، زمانی که هیچ به‌روزرسانی صفحه نمایش برای مهلت زمانی پیکربندی شده وجود نداشته باشد، از نرخ تازه‌سازی دقیقه استفاده می‌شود.
  • ro.surface_flinger.set_display_power_timer_ms : اگر > 0 باشد، هنگام روشن کردن نمایشگر (یا هنگام خارج شدن از AOD) برای زمان تنظیم شده، از نرخ تازه سازی پیش فرض استفاده می شود.

API نرخ فریم

API نرخ فریم به برنامه‌ها اجازه می‌دهد تا پلتفرم Android را از نرخ فریم مورد نظر خود مطلع کنند و در برنامه‌هایی که Android 11 را هدف قرار می‌دهند در دسترس است. برای اطلاعات بیشتر درباره API نرخ فریم، مستندات برنامه‌نویس را در developer.android.com بررسی کنید.

گزینه های توسعه دهنده

یک گزینه توسعه دهنده جدید به منو اضافه شده است که یک پوشش روی نمایشگر را با نرخ تازه سازی فعلی تغییر می دهد. گزینه جدید در قسمت تنظیمات > سیستم > گزینه های برنامه نویس > نمایش نرخ تازه سازی قرار دارد.