एकाधिक रीफ़्रेश दर

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

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

लागू करना

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

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

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

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

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

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

Composer API से जुड़े अपडेट

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

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

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

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

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

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

DisplayManager
DisplayManager, रीफ़्रेश रेट के लिए सबसे ऊपर की नीति सेट करता है. इससे एक डिफ़ॉल्ट डिसप्ले कॉन्फ़िगरेशन सेट हो जाता है, जो कंपोज़र HAL कॉन्फ़िगरेशन जैसा ही होता है. इसके अलावा, यह 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 उसी के हिसाब से डिफ़ॉल्ट कॉन्फ़िगरेशन आईडी सेट करता है. साथ ही, रीफ़्रेश दर को कॉन्फ़िगर करने के लिए, कम से कम और ज़्यादा से ज़्यादा रीफ़्रेश दर को सेट करता है.
    • बैटरी सेवर मोड: डिवाइस के लो पावर मोड में, रिफ़्रेश रेट 60Hz या इससे कम पर सेट होता है. इस मोड के चालू होने की जानकारी, Settings.Global.LOW_POWER_MODE. के ज़रिए दी जाती है

DisplayManager नीति सेट करने के बाद, SurfaceFlinger ऐक्टिव लेयर (लेयर जो फ़्रेम अपडेट को कतार में डालती हैं) के आधार पर रीफ़्रेश रेट सेट करता है. अगर लेयर का मालिक फ़्रेम रेट सेट करता है, तो SurfaceFlinger रिफ़्रेश रेट को उस रेट के मल्टीप्लायर पर सेट करने की कोशिश करता है. उदाहरण के लिए, अगर दो चालू लेयर अपना फ़्रेम रेट 24 और 60 पर सेट करती हैं, तो SurfaceFlinger 120Hz चुनेगा. हालांकि, ऐसा तब होगा, जब यह उपलब्ध हो. अगर ऐसी रीफ़्रेश दर 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 से बाहर निकलने) के दौरान किया जाएगा.

Frame Rate API

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

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

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