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

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

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

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

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

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

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

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

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

  • sync_timeline
  • sync_pt
  • sync_fence

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

sync_timeline एक नीरस रूप से बढ़ती समयरेखा है जिसे विक्रेताओं को प्रत्येक ड्राइवर उदाहरण के लिए लागू करना चाहिए, जैसे कि जीएल संदर्भ, डिस्प्ले कंट्रोलर, या 2 डी ब्लिटर। 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 माता-पिता होते हैं (जैसे डिस्प्ले कंट्रोलर और जीपीयू के लिए)। 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 में कर्नेल स्पेस के साथ संचार करने के लिए लाइब्रेरी
  • विक्रेता को एचएएल में presentDisplay() validateDisplay() और प्रेजेंटडिसप्ले () फ़ंक्शन के पैरामीटर के रूप में उपयुक्त सिंक्रोनाइज़ेशन फ़ेंस प्रदान करना चाहिए।
  • दो बाड़ से संबंधित जीएल एक्सटेंशन ( 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);

समन्वयन एकीकरण

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

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

Android HAL इंटरफ़ेस सम्मेलनों का पालन करें:

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

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

एनाटिवविंडो एकीकरण

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

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

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

  • EGL_ANDROID_native_fence_sync EGLSyncKHR ऑब्जेक्ट्स में मूल Android फ़ेंस फ़ाइल डिस्क्रिप्टर को लपेटने या बनाने का एक तरीका प्रदान करता है।
  • EGL_ANDROID_wait_sync साइड के बजाय 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 एक्सटेंशन एक संबंधित नेटिव फ़ेंस फ़ाइल डिस्क्रिप्टर विशेषता को नियोजित करता है जिसे केवल निर्माण समय पर सेट किया जा सकता है और मौजूदा सिंक ऑब्जेक्ट से सीधे आगे की ओर नहीं देखा जा सकता है। यह विशेषता दो मोड में से एक पर सेट की जा सकती है:

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

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

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

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

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