रीफ़्रेश रेट की अलग-अलग सेटिंग

Android 11 में, अलग-अलग रिफ़्रेश रेट वाले डिवाइसों के लिए सहायता जोड़ी गई है. इस सुविधा के तीन मुख्य कॉम्पोनेंट हैं:

  • android.hardware.graphics.composer@2.4 में नए HAL API जोड़े गए हैं.
  • अलग-अलग रीफ़्रेश रेट के लिए डिवाइस कॉन्फ़िगरेशन को पार्स करने और मनचाहा रीफ़्रेश रेट सेट करने के लिए प्लैटफ़ॉर्म कोड
  • नए एसडीके और एनडीके एपीआई, ताकि ऐप्लिकेशन अपनी पसंद के हिसाब से फ़्रेम रेट सेट कर सकें

लागू करना

रीफ़्रेश रेट स्विच करने के लिए, सहायता टीम से संपर्क करने की सुविधा android.hardware.graphics.composer@2.4 HAL में जोड़ दी गई है. हमारा सुझाव है कि आप इस वर्शन का इस्तेमाल करें, क्योंकि कंपोज़र एचएएल के पिछले वर्शन में रीफ़्रेश रेट स्विच करने की सुविधा सीमित तौर पर उपलब्ध है.

कॉन्फ़िगरेशन ग्रुप

IComposerClient::Attribute में एक नया एट्रिब्यूट CONFIG_GROUP जोड़ा गया है. इसे getDisplayAttribute_2_4 एपीआई का इस्तेमाल करके क्वेरी किया जा सकता है. इस एट्रिब्यूट की मदद से वेंडर, डिसप्ले कॉन्फ़िगरेशन को एक साथ ग्रुप कर सकते हैं. एक ही ग्रुप में कॉन्फ़िगरेशन होने पर, ज़्यादातर मामलों में उनके बीच आसानी से स्विच किया जा सकता है. कॉन्फ़िगरेशन ग्रुप का इस्तेमाल प्लैटफ़ॉर्म करता है. इससे यह पता चलता है कि किन कॉन्फ़िगरेशन के बीच स्विच किया जा सकता है. ऐसा इसलिए किया जाता है, ताकि कॉन्फ़िगरेशन के लिए रीफ़्रेश रेट को बदला जा सके, न कि अन्य एट्रिब्यूट को.

यहां दिए गए उदाहरण में, कॉन्फ़िगरेशन ग्रुप का इस्तेमाल करने के फ़ायदे बताए गए हैं. यह उदाहरण, ऐसे डिवाइस के लिए है जिसमें चार डिसप्ले कॉन्फ़िगरेशन काम करते हैं:

  • 1080 पिक्सल@60 हर्ट्ज़
  • 1080 पिक्सल@90 हर्ट्ज़
  • 1080i@72Hz
  • 1080i@48Hz

डिवाइस पर 48 हर्ट्ज़, 60 हर्ट्ज़, 72 हर्ट्ज़, और 90 हर्ट्ज़ के रीफ़्रेश रेट काम करते हैं. हालांकि, डिसप्ले अलग मोड में काम करता है. साथ ही, 60 हर्ट्ज़ से 72 हर्ट्ज़ पर स्विच करने से, डिसप्ले कॉन्फ़िगरेशन 1080 पिक्सल से 1080i पर बदल जाता है. ऐसा हो सकता है कि यह आपकी ज़रूरत के मुताबिक न हो. कॉन्फ़िगरेशन ग्रुप का इस्तेमाल करके इस समस्या को हल किया जा सकता है. 60 हर्ट्ज़ और 90 हर्ट्ज़ को एक कॉन्फ़िगरेशन ग्रुप में और 48 हर्ट्ज़ और 72 हर्ट्ज़ को दूसरे कॉन्फ़िगरेशन ग्रुप में रखकर. प्लैटफ़ॉर्म को पता है कि यह 60 हर्ट्ज़ और 90 हर्ट्ज़ के बीच और 48 हर्ट्ज़ और 72 हर्ट्ज़ के बीच स्विच कर सकता है. हालांकि, यह 60 हर्ट्ज़ और 72 हर्ट्ज़ के बीच स्विच नहीं कर सकता, क्योंकि इससे रीफ़्रेश रेट में बदलाव करने के बजाय कॉन्फ़िगरेशन में बदलाव होगा.

Composer API के अपडेट

getDisplayVsyncPeriod
रीफ़्रेश रेट बदलते समय बेहतर कंट्रोल और अनुमान लगाने की सुविधा के लिए, getDisplayVsyncPeriod को जोड़ा गया है. getDisplayVsyncPeriod, डिसप्ले के मौजूदा रीफ़्रेश रेट (वीसिंक अवधि के हिसाब से) को दिखाता है. यह खास तौर पर तब फ़ायदेमंद होता है, जब रीफ़्रेश रेट में बदलाव किया जा रहा हो. साथ ही, प्लैटफ़ॉर्म को मौजूदा रीफ़्रेश रेट की ज़रूरत हो, ताकि वह यह तय कर सके कि अगला फ़्रेम कब शुरू करना है.
setActiveConfigWithConstraints
यह setActiveConfigWithConstraints तरीका, मौजूदा setActiveConfig तरीके का नया एक्सटेंशन है. इससे कॉन्फ़िगरेशन में हुए बदलाव के बारे में ज़्यादा जानकारी मिलती है. ये शर्तें, vsyncPeriodChangeConstraints पैरामीटर के तौर पर दी जाती हैं. इनमें ये पैरामीटर शामिल होते हैं.
    desiredTimeNanos
    CLOCK_MONOTONIC में वह समय जिसके बाद वीसिंक अवधि बदल सकती है. इसका मतलब है कि वीसिंक अवधि इस समय से पहले नहीं बदलनी चाहिए. यह तब काम आता है, जब प्लैटफ़ॉर्म को रीफ़्रेश रेट में बदलाव करने की योजना बनानी होती है, लेकिन उसके पास पहले से ही प्रज़ेंट करने के लिए कुछ बफ़र मौजूद होते हैं. यह प्लैटफ़ॉर्म, बफ़र के लिए समय को सेट करता है. इससे यह पक्का किया जा सकता है कि रीफ़्रेश रेट में बदलाव आसानी से हो.
    seamlessRequired
    अगर यह सही है, तो इसका मतलब है कि वीसिंक पीरियड में बदलाव, बिना किसी रुकावट के होना चाहिए. साथ ही, इससे विज़ुअल आर्टफ़ैक्ट में कोई खास बदलाव नहीं होना चाहिए. इस फ़्लैग का इस्तेमाल प्लैटफ़ॉर्म तब करता है, जब कॉन्टेंट में बदलाव होने की वजह से रीफ़्रेश रेट में बदलाव करना ज़रूरी होता है. उदाहरण के लिए, डिवाइस के इस्तेमाल में न होने पर ऐनिमेशन शुरू हो जाता है. इससे वेंडर को यह तय करने का मौका मिलता है कि कॉन्फ़िगरेशन में कुछ बदलावों की अनुमति न दी जाए. ऐसा तब किया जाता है, जब इन बदलावों की वजह से कोई विज़ुअल आर्टफ़ैक्ट दिखता है. अगर कॉन्फ़िगरेशन को आसानी से नहीं बदला जा सकता और seamlessRequired को true पर सेट किया गया है, तो लागू करने वाले को SEAMLESS_NOT_POSSIBLE को रिटर्न कोड के तौर पर दिखाना होगा. साथ ही, जब कॉन्फ़िगरेशन को आसानी से बदला जा सकता है, तब नए onSeamlessPossible कॉलबैक को कॉल करना होगा.

लागू करने की प्रोसेस पूरी होने पर, यह VsyncPeriodChangeTimeline दिखाता है. इससे प्लैटफ़ॉर्म को पता चलता है कि रीफ़्रेश रेट में बदलाव कब होगा. newVsyncAppliedTimeNanos पैरामीटर को CLOCK_MONOTONIC में दिए गए समय पर सेट करना होगा. इस समय पर, नया डिसप्ले नई वीसिंक अवधि पर रीफ़्रेश होना शुरू हो जाएगा. इसकी मदद से, desiredTimeNanos प्लैटफ़ॉर्म को रीफ़्रेश रेट स्विच करने की योजना पहले से बनाने में मदद मिलती है. साथ ही, यह नए रीफ़्रेश रेट के लिए ऐप्लिकेशन को पहले से टिक करना शुरू कर देता है. इससे रीफ़्रेश रेट में बिना किसी रुकावट के बदलाव किया जा सकता है.

कुछ मामलों में, रीफ़्रेश रेट भेजने से पहले, रीफ़्रेश फ़्रेम भेजना ज़रूरी होता है. इसके लिए, HAL में refreshRequired पैरामीटर होता है. इससे यह पता चलता है कि रीफ़्रेश फ़्रेम की ज़रूरत है. साथ ही, refreshTimeNanos पैरामीटर से यह पता चलता है कि रीफ़्रेश फ़्रेम को किस पहले वर्टिकल सिंक के बाद भेजना है.

onVsyncPeriodTimingChanged [callback]
एक नया कॉलबैक, जिसे HAL कॉल कर सकता है. इससे प्लैटफ़ॉर्म को यह पता चलता है कि टाइमलाइन का कोई पैरामीटर बदल गया है और प्लैटफ़ॉर्म को अपनी टाइमलाइन में बदलाव करना होगा. इस कॉलबैक को तब कॉल किया जाता है, जब HAL पर प्रोसेस होने में ज़्यादा समय लगने या फ़्रेम को देर से रीफ़्रेश करने की वजह से, पुरानी टाइमलाइन को किसी वजह से नहीं दिखाया जा सका हो.

प्लैटफ़ॉर्म, रीफ़्रेश रेट बदलने का फ़ैसला कैसे लेता है?

रीफ़्रेश रेट चुनने की सुविधा, इन दो सिस्टम सेवाओं में मिलती है:

DisplayManager
DisplayManager, रीफ़्रेश रेट के लिए उच्च-स्तरीय नीति सेट करता है. यह डिफ़ॉल्ट डिसप्ले कॉन्फ़िगरेशन सेट करता है, जो कंपोज़र एचएएल कॉन्फ़िगरेशन के जैसा ही होता है. इसके अलावा, यह SurfaceFlinger के लिए कम से कम और ज़्यादा से ज़्यादा वैल्यू की एक रेंज सेट करता है, ताकि रीफ़्रेश रेट के तौर पर कोई वैल्यू चुनी जा सके.
SurfaceFlinger
यह डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ कॉन्फ़िगरेशन ग्रुप में मौजूद कॉन्फ़िगरेशन को सेट करके, रीफ़्रेश रेट तय करता है. साथ ही, रीफ़्रेश रेट, कम से कम/ज़्यादा से ज़्यादा सीमा के अंदर होता है.

नीति तय करने के लिए, Display Manager यह तरीका अपनाता है:

  • यह फ़ंक्शन, 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 और 60 पर सेट है, तो SurfaceFlinger 120 हर्ट्ज़ को चुनेगा. हालांकि, ऐसा तब होगा, जब 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 है, तो कॉन्फ़िगर किए गए टाइमआउट के लिए, डिसप्ले चालू करते समय (या एओडी से बाहर निकलते समय) डिफ़ॉल्ट रीफ़्रेश रेट का इस्तेमाल किया जाएगा.

Frame Rate API

फ़्रेम रेट एपीआई की मदद से, ऐप्लिकेशन Android प्लैटफ़ॉर्म को अपने फ़्रेम रेट के बारे में बता सकते हैं. यह एपीआई, Android 11 को टारगेट करने वाले ऐप्लिकेशन के लिए उपलब्ध है. फ़्रेम रेट एपीआई के बारे में ज़्यादा जानने के लिए, developer.android.com पर डेवलपर दस्तावेज़ देखें.

डेवलपर के लिए सेटिंग और टूल

मेन्यू में एक नया डेवलपर विकल्प जोड़ा गया है. यह विकल्प, डिसप्ले पर मौजूदा रीफ़्रेश रेट के साथ ओवरले को टॉगल करता है. यह नया विकल्प यहां मौजूद है: सेटिंग > सिस्टम > डेवलपर के लिए सेटिंग और टूल > रीफ़्रेश रेट दिखाएं.