तुल्यकालन ढांचा

सिंक्रोनाइज़ेशन फ्रेमवर्क स्पष्ट रूप से एंड्रॉइड ग्राफिक्स सिस्टम में विभिन्न अतुल्यकालिक संचालन के बीच निर्भरता का वर्णन करता है। फ्रेमवर्क एक एपीआई प्रदान करता है जो घटकों को यह इंगित करने में सक्षम बनाता है कि बफ़र्स कब जारी किए जाते हैं। फ्रेमवर्क कर्नेल से यूजरस्पेस तक ड्राइवरों के बीच और यूजरस्पेस प्रक्रियाओं के बीच सिंक्रोनाइज़ेशन प्रिमिटिव को पारित करने की भी अनुमति देता है।

उदाहरण के लिए, कोई एप्लिकेशन GPU में किए जाने वाले कार्य को कतारबद्ध कर सकता है। GPU उस छवि को बनाना शुरू कर देता है। हालाँकि छवि को अभी तक मेमोरी में नहीं खींचा गया है, बफर पॉइंटर को विंडो कंपोजिटर को एक बाड़ के साथ भेज दिया गया है जो इंगित करता है कि GPU का काम कब खत्म होगा। विंडो कंपोज़िटर समय से पहले प्रोसेसिंग शुरू कर देता है और काम को डिस्प्ले कंट्रोलर को भेज देता है। इसी प्रकार सीपीयू का कार्य भी समय से पहले किया जाता है। एक बार जब GPU समाप्त हो जाता है, तो डिस्प्ले नियंत्रक तुरंत छवि प्रदर्शित करता है।

सिंक्रोनाइज़ेशन ढाँचा कार्यान्वयनकर्ताओं को अपने स्वयं के हार्डवेयर घटकों में सिंक्रोनाइज़ेशन संसाधनों का लाभ उठाने की सुविधा भी देता है। अंत में, फ्रेमवर्क डिबगिंग में सहायता के लिए ग्राफिक्स पाइपलाइन में दृश्यता प्रदान करता है।

स्पष्ट तुल्यकालन

स्पष्ट सिंक्रनाइज़ेशन ग्राफिक्स बफ़र्स के उत्पादकों और उपभोक्ताओं को बफ़र का उपयोग समाप्त होने पर संकेत देने में सक्षम बनाता है। स्पष्ट सिंक्रनाइज़ेशन कर्नेल-स्पेस में लागू किया गया है।

स्पष्ट तुल्यकालन के लाभों में शामिल हैं:

  • उपकरणों के बीच कम व्यवहार भिन्नता
  • बेहतर डिबगिंग समर्थन
  • बेहतर परीक्षण मेट्रिक्स

सिंक फ्रेमवर्क में तीन ऑब्जेक्ट प्रकार हैं:

  • sync_timeline
  • sync_pt
  • sync_fence

सिंक_टाइमलाइन

sync_timeline एक नीरस रूप से बढ़ती समयरेखा है जिसे विक्रेताओं को प्रत्येक ड्राइवर उदाहरण के लिए लागू करना चाहिए, जैसे कि GL संदर्भ, डिस्प्ले कंट्रोलर, या 2D ब्लिटर। sync_timeline हार्डवेयर के एक विशेष टुकड़े के लिए कर्नेल को सबमिट की गई नौकरियों की गणना करता है। sync_timeline संचालन के क्रम के बारे में गारंटी प्रदान करता है और हार्डवेयर-विशिष्ट कार्यान्वयन को सक्षम बनाता है।

sync_timeline लागू करते समय इन दिशानिर्देशों का पालन करें:

  • डिबगिंग को सरल बनाने के लिए सभी ड्राइवरों, टाइमलाइन और बाड़ के लिए उपयोगी नाम प्रदान करें।
  • डिबगिंग आउटपुट को अधिक पठनीय बनाने के लिए टाइमलाइन में timeline_value_str और pt_value_str ऑपरेटरों को लागू करें।
  • यदि वांछित हो, तो जीएल लाइब्रेरी जैसी यूजरस्पेस लाइब्रेरी, निजी टाइमलाइन डेटा तक पहुंच प्रदान करने के लिए driver_data भरें लागू करें। data_driver विक्रेताओं को उनके आधार पर कमांड लाइन बनाने के लिए अपरिवर्तनीय sync_fence और sync_pts के बारे में जानकारी देने देता है।
  • उपयोगकर्ता स्थान को स्पष्ट रूप से बाड़ बनाने या संकेत देने की अनुमति न दें। स्पष्ट रूप से सिग्नल/बाड़ बनाने से सेवा से इनकार करने का हमला होता है जो पाइपलाइन की कार्यक्षमता को रोक देता है।
  • sync_timeline , sync_pt , या sync_fence तत्वों तक स्पष्ट रूप से प्रवेश न करें। एपीआई सभी आवश्यक कार्य प्रदान करता है।

सिंक_पीटी

sync_pt sync_timeline पर एक एकल मान या बिंदु है। एक बिंदु की तीन अवस्थाएँ होती हैं: सक्रिय, संकेतित और त्रुटि। अंक सक्रिय अवस्था में शुरू होते हैं और संकेतित या त्रुटि अवस्था में परिवर्तित होते हैं। उदाहरण के लिए, जब किसी छवि उपभोक्ता को बफर की आवश्यकता नहीं होती है, तो एक sync_pt संकेत दिया जाता है ताकि छवि निर्माता को पता चले कि बफर में फिर से लिखना ठीक है।

सिंक_बाड़

sync_fence sync_pt मानों का एक संग्रह है जिसमें अक्सर अलग-अलग sync_timeline माता-पिता होते हैं (जैसे कि डिस्प्ले कंट्रोलर और GPU के लिए)। sync_fence , sync_pt , और sync_timeline मुख्य प्राइमेटिव हैं जिनका उपयोग ड्राइवर और यूजरस्पेस अपनी निर्भरता को संप्रेषित करने के लिए करते हैं। जब एक बाड़ का संकेत मिलता है, तो बाड़ से पहले जारी किए गए सभी आदेशों को पूरा होने की गारंटी दी जाती है क्योंकि कर्नेल ड्राइवर या हार्डवेयर ब्लॉक क्रम में आदेशों को निष्पादित करता है।

सिंक फ्रेमवर्क कई उपभोक्ताओं या उत्पादकों को एक फ़ंक्शन पैरामीटर के साथ निर्भरता जानकारी संचारित करते हुए, बफर का उपयोग करके समाप्त होने पर संकेत देने की अनुमति देता है। फ़ेंस को फ़ाइल डिस्क्रिप्टर द्वारा समर्थित किया जाता है और कर्नेल स्पेस से यूज़रस्पेस तक पास किया जाता है। उदाहरण के लिए, एक बाड़ में दो sync_pt मान हो सकते हैं जो यह दर्शाते हैं कि दो अलग-अलग छवि उपभोक्ता एक बफर को पढ़ रहे हैं। जब बाड़ को संकेत दिया जाता है, तो छवि उत्पादकों को पता चलता है कि दोनों उपभोक्ता उपभोग कर चुके हैं।

sync_pt मानों की तरह, बाड़ें सक्रिय होने लगती हैं और अपने बिंदुओं की स्थिति के आधार पर स्थिति बदलती हैं। यदि सभी sync_pt मान संकेतित हो जाते हैं, तो sync_fence संकेतित हो जाता है। यदि एक sync_pt त्रुटि स्थिति में आता है, तो संपूर्ण sync_fence में त्रुटि स्थिति होती है।

फ़ेंस बनने के बाद sync_fence में सदस्यता अपरिवर्तनीय है। एक बाड़ में एक से अधिक बिंदु प्राप्त करने के लिए, एक मर्ज आयोजित किया जाता है जहां दो अलग-अलग बाड़ से अंक तीसरे बाड़ में जोड़े जाते हैं। यदि प्रारंभिक बाड़ में उन बिंदुओं में से एक को संकेत दिया गया था और दूसरे को नहीं, तो तीसरी बाड़ भी संकेतित स्थिति में नहीं होगी।

स्पष्ट सिंक्रनाइज़ेशन लागू करने के लिए, निम्नलिखित प्रदान करें:

  • एक कर्नेल-स्पेस सबसिस्टम जो किसी विशेष हार्डवेयर ड्राइवर के लिए सिंक फ्रेमवर्क लागू करता है। जिन ड्राइवरों को बाड़-जागरूक होने की आवश्यकता होती है, वे आम तौर पर हार्डवेयर कंपोजर तक पहुंचने या संचार करने वाली कोई भी चीज़ होती है। मुख्य फाइलों में शामिल हैं:
    • मुख्य कार्यान्वयन:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • kernel/common/Documentation/sync.txt पर दस्तावेज़ीकरण
    • platform/system/core/libsync में कर्नेल स्पेस के साथ संचार करने के लिए लाइब्रेरी
  • विक्रेता को एचएएल में validateDisplay() और presentDisplay() फ़ंक्शंस के पैरामीटर के रूप में उचित सिंक्रोनाइज़ेशन फ़ेंस प्रदान करना होगा।
  • दो बाड़-संबंधित जीएल एक्सटेंशन ( EGL_ANDROID_native_fence_sync और EGL_ANDROID_wait_sync ) और ग्राफिक्स ड्राइवर में बाड़ समर्थन।

केस स्टडी: एक डिस्प्ले ड्राइवर लागू करें

सिंक्रोनाइज़ेशन फ़ंक्शन का समर्थन करने वाले एपीआई का उपयोग करने के लिए, एक डिस्प्ले ड्राइवर विकसित करें जिसमें डिस्प्ले बफर फ़ंक्शन हो। सिंक्रोनाइज़ेशन फ्रेमवर्क के अस्तित्व में आने से पहले, यह फ़ंक्शन dma-buf ऑब्जेक्ट प्राप्त करता था, उन बफ़र्स को डिस्प्ले पर रखता था, और बफ़र दिखाई देने पर ब्लॉक कर देता था। उदाहरण के लिए:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

सिंक्रोनाइज़ेशन फ्रेमवर्क के साथ, display_buffer फ़ंक्शन अधिक जटिल है। बफ़र को प्रदर्शन पर रखते समय, बफ़र एक बाड़ से जुड़ा होता है जो इंगित करता है कि बफ़र कब तैयार होगा। बाड़ साफ होने के बाद आप कतार में लग सकते हैं और काम शुरू कर सकते हैं।

बाड़ साफ़ होने के बाद कतार में लगना और काम शुरू करना किसी भी चीज़ को अवरुद्ध नहीं करता है। आप तुरंत अपनी बाड़ वापस कर देते हैं, जो गारंटी देता है कि बफर डिस्प्ले से कब हटेगा। जैसे ही आप बफ़र्स को कतारबद्ध करते हैं, कर्नेल सिंक्रनाइज़ेशन ढांचे के साथ निर्भरताओं को सूचीबद्ध करता है:

/*
 * displays buffer when fence is signaled.  returns immediately with a fence
 * that signals when buffer is no longer displayed.
 */
struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence
*fence);

सिंक एकीकरण

यह अनुभाग बताता है कि कर्नेल-स्पेस सिंक फ्रेमवर्क को एंड्रॉइड फ्रेमवर्क के यूजरस्पेस भागों और ड्राइवरों के साथ कैसे एकीकृत किया जाए, जिन्हें एक दूसरे के साथ संचार करना होगा। कर्नेल-स्पेस ऑब्जेक्ट को यूजरस्पेस में फ़ाइल डिस्क्रिप्टर के रूप में दर्शाया जाता है।

एकीकरण सम्मेलन

एंड्रॉइड एचएएल इंटरफ़ेस सम्मेलनों का पालन करें:

  • यदि एपीआई एक फ़ाइल डिस्क्रिप्टर प्रदान करता है जो sync_pt को संदर्भित करता है, तो विक्रेता के ड्राइवर या एपीआई का उपयोग करने वाले एचएएल को फ़ाइल डिस्क्रिप्टर को बंद करना होगा।
  • यदि विक्रेता ड्राइवर या एचएएल एक फ़ाइल डिस्क्रिप्टर पास करता है जिसमें एपीआई फ़ंक्शन के लिए sync_pt शामिल है, तो विक्रेता ड्राइवर या एचएएल को फ़ाइल डिस्क्रिप्टर को बंद नहीं करना चाहिए।
  • फ़ेंस फ़ाइल डिस्क्रिप्टर का उपयोग जारी रखने के लिए, विक्रेता ड्राइवर या HAL को डिस्क्रिप्टर की नकल बनानी होगी।

हर बार बफ़रक्यू से गुजरने पर एक बाड़ वस्तु का नाम बदल दिया जाता है। कर्नेल बाड़ समर्थन बाड़ को नामों के लिए स्ट्रिंग रखने की अनुमति देता है, इसलिए सिंक फ्रेमवर्क विंडो नाम और बफर इंडेक्स का उपयोग करता है जिसे बाड़ को नाम देने के लिए कतारबद्ध किया जा रहा है, जैसे SurfaceView:0 । यह गतिरोध के स्रोत की पहचान करने के लिए डिबगिंग में सहायक है क्योंकि नाम /d/sync और बग रिपोर्ट के आउटपुट में दिखाई देते हैं।

ANativeWindow एकीकरण

ANativeWindow बाड़ जागरूक है। dequeueBuffer , queueBuffer , और cancelBuffer में बाड़ पैरामीटर हैं।

ओपनजीएल ईएस एकीकरण

ओपनजीएल ईएस सिंक एकीकरण दो ईजीएल एक्सटेंशन पर निर्भर करता है:

  • EGL_ANDROID_native_fence_sync EGLSyncKHR ऑब्जेक्ट्स में मूल एंड्रॉइड बाड़ फ़ाइल डिस्क्रिप्टर को लपेटने या बनाने का एक तरीका प्रदान करता है।
  • EGL_ANDROID_wait_sync CPU-साइड के बजाय GPU-साइड स्टॉल की अनुमति देता है, जिससे GPU EGLSyncKHR की प्रतीक्षा करता है। EGL_ANDROID_wait_sync एक्सटेंशन EGL_KHR_wait_sync एक्सटेंशन के समान है।

इन एक्सटेंशनों का स्वतंत्र रूप से उपयोग करने के लिए, संबंधित कर्नेल समर्थन के साथ EGL_ANDROID_native_fence_sync एक्सटेंशन लागू करें। इसके बाद, अपने ड्राइवर में EGL_ANDROID_wait_sync एक्सटेंशन सक्षम करें। EGL_ANDROID_native_fence_sync एक्सटेंशन में एक विशिष्ट मूल बाड़ EGLSyncKHR ऑब्जेक्ट प्रकार होता है। परिणामस्वरूप, मौजूदा EGLSyncKHR ऑब्जेक्ट प्रकारों पर लागू होने वाले एक्सटेंशन आवश्यक रूप से EGL_ANDROID_native_fence ऑब्जेक्ट्स पर लागू नहीं होते हैं, जिससे अवांछित इंटरैक्शन से बचा जा सकता है।

EGL_ANDROID_native_fence_sync एक्सटेंशन एक संबंधित मूल बाड़ फ़ाइल डिस्क्रिप्टर विशेषता को नियोजित करता है जिसे केवल निर्माण के समय सेट किया जा सकता है और किसी मौजूदा सिंक ऑब्जेक्ट से सीधे पूछताछ नहीं की जा सकती है। इस विशेषता को दो मोड में से एक पर सेट किया जा सकता है:

  • एक वैध बाड़ फ़ाइल डिस्क्रिप्टर एक मौजूदा मूल एंड्रॉइड बाड़ फ़ाइल डिस्क्रिप्टर को EGLSyncKHR ऑब्जेक्ट में लपेटता है।
  • -1 EGLSyncKHR ऑब्जेक्ट से एक मूल एंड्रॉइड फ़ेंस फ़ाइल डिस्क्रिप्टर बनाता है।

मूल एंड्रॉइड फ़ेंस फ़ाइल डिस्क्रिप्टर से EGLSyncKHR ऑब्जेक्ट को निकालने के लिए DupNativeFenceFD() फ़ंक्शन कॉल का उपयोग करें। इसका परिणाम सेट विशेषता को क्वेरी करने जैसा ही होता है, लेकिन यह इस परंपरा का पालन करता है कि प्राप्तकर्ता बाड़ को बंद कर देता है (इसलिए डुप्लिकेट ऑपरेशन)। अंत में, EGLSyncKHR ऑब्जेक्ट को नष्ट करने से आंतरिक बाड़ विशेषता बंद हो जाती है।

हार्डवेयर संगीतकार एकीकरण

हार्डवेयर कंपोज़र तीन प्रकार के सिंक बाड़ को संभालता है:

  • एक्वायर फेंस को इनपुट बफ़र्स के साथ setLayerBuffer और setClientTarget कॉल में पास किया जाता है। ये बफर में लंबित लेखन का प्रतिनिधित्व करते हैं और सरफेसफ्लिंगर या एचडब्ल्यूसी द्वारा कंपोजिशन निष्पादित करने के लिए संबंधित बफर से पढ़ने का प्रयास करने से पहले संकेत देना चाहिए।
  • getReleaseFences कॉल का उपयोग करके presentDisplay पर कॉल के बाद रिलीज़ फ़ेंस को पुनः प्राप्त किया जाता है। ये उसी परत पर पिछले बफ़र से लंबित रीड का प्रतिनिधित्व करते हैं। एक रिलीज़ फ़ेंस तब संकेत देता है जब HWC अब पिछले बफ़र का उपयोग नहीं कर रहा है क्योंकि वर्तमान बफ़र ने डिस्प्ले पर पिछले बफ़र को बदल दिया है। रिलीज़ फ़ेंस को पिछले बफ़र्स के साथ ऐप में वापस भेज दिया जाता है जिन्हें वर्तमान संरचना के दौरान बदल दिया जाएगा। ऐप को उस बफ़र में नई सामग्री लिखने से पहले रिलीज़ फ़ेंस सिग्नल मिलने तक प्रतीक्षा करनी चाहिए जो उन्हें वापस कर दिया गया था।
  • presentDisplay पर कॉल के हिस्से के रूप में, प्रति फ्रेम एक-एक वर्तमान बाड़ लौटा दी जाती है। वर्तमान बाड़ तब दर्शाते हैं जब इस फ्रेम की संरचना पूरी हो गई है, या वैकल्पिक रूप से, जब पिछले फ्रेम की संरचना परिणाम की अब आवश्यकता नहीं है। भौतिक डिस्प्ले के लिए, जब वर्तमान फ्रेम स्क्रीन पर दिखाई देता है तो presentDisplay वर्तमान बाड़ लौटाता है। वर्तमान बाड़ वापस आने के बाद, यदि लागू हो तो सरफेसफ्लिंगर लक्ष्य बफर पर फिर से लिखना सुरक्षित है। वर्चुअल डिस्प्ले के लिए, वर्तमान फ़ेंस तब लौटाए जाते हैं जब आउटपुट बफ़र से पढ़ना सुरक्षित होता है।