सिंक्रोनाइज़ेशन फ्रेमवर्क स्पष्ट रूप से एंड्रॉइड ग्राफिक्स सिस्टम में विभिन्न अतुल्यकालिक संचालन के बीच निर्भरता का वर्णन करता है। फ्रेमवर्क एक एपीआई प्रदान करता है जो घटकों को यह इंगित करने में सक्षम बनाता है कि बफ़र्स कब जारी किए जाते हैं। फ्रेमवर्क कर्नेल से यूजरस्पेस तक ड्राइवरों के बीच और यूजरस्पेस प्रक्रियाओं के बीच सिंक्रोनाइज़ेशन प्रिमिटिव को पारित करने की भी अनुमति देता है।
उदाहरण के लिए, कोई एप्लिकेशन 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-साइड स्टॉल की अनुमति देता है, जिससे GPUEGLSyncKHR
की प्रतीक्षा करता है।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
वर्तमान बाड़ लौटाता है। वर्तमान बाड़ वापस आने के बाद, यदि लागू हो तो सरफेसफ्लिंगर लक्ष्य बफर पर फिर से लिखना सुरक्षित है। वर्चुअल डिस्प्ले के लिए, वर्तमान फ़ेंस तब लौटाए जाते हैं जब आउटपुट बफ़र से पढ़ना सुरक्षित होता है।