RenderScript, Android पर बेहतर परफ़ॉर्मेंस के साथ, ज़्यादा कंप्यूटिंग वाले टास्क चलाने के लिए एक फ़्रेमवर्क है. इसे डेटा-पаралल कंप्यूटेशन के साथ इस्तेमाल करने के लिए डिज़ाइन किया गया है. हालांकि, सीरियल वर्कलोड को भी इससे फ़ायदा मिल सकता है. RenderScript रनटाइम, डिवाइस पर उपलब्ध सभी प्रोसेसर पर काम को एक साथ करता है. जैसे, मल्टी-कोर सीपीयू और जीपीयू. इससे डेवलपर, काम को शेड्यूल करने के बजाय, एल्गोरिदम को बेहतर बनाने पर ध्यान दे पाते हैं. RenderScript खास तौर पर इमेज प्रोसेसिंग, कंप्यूटेशनल फ़ोटोग्राफ़ी या कंप्यूटर विज़न का काम करने वाले ऐप्लिकेशन के लिए काम का है.
Android 8.0 और उसके बाद के वर्शन पर चलने वाले डिवाइस, इन RenderScript के फ़्रेमवर्क और वेंडर एचएएल का इस्तेमाल करते हैं:
पहली इमेज. इंटरनल लिब्स से लिंक करने वाला वेंडर कोड.
Android 7.x और इससे पहले के वर्शन में RenderScript के मुकाबले, इनमें अंतर है:
- किसी प्रोसेस में, RenderScript के इंटरनल लाइब्रेरी के दो इंस्टेंस. एक सेट, सीपीयू फ़ॉलबैक पाथ के लिए है और यह सीधे
/system/lib
से है. दूसरा सेट, जीपीयू पाथ के लिए है और यह/system/lib/vndk-sp
से है. /system/lib
में RS के इंटरनल लाइब्रेरी, प्लैटफ़ॉर्म के हिस्से के तौर पर बनाई जाती हैं औरsystem.img
के अपग्रेड होने पर अपडेट की जाती हैं. हालांकि,/system/lib/vndk-sp
में मौजूद लाइब्रेरी, वेंडर के लिए बनाई गई हैं औरsystem.img
के अपग्रेड होने पर, उन्हें अपडेट नहीं किया जाता. हालांकि, सुरक्षा से जुड़ी समस्या को ठीक करने के लिए, उन्हें अपडेट किया जा सकता है. हालांकि, उनका एबीआई (एबिट्रेशन इंटरफ़ेस) एक जैसा ही रहता है.- वेंडर कोड (आरएस एचएएल, आरएस ड्राइवर, और
bcc plugin
) को/system/lib/vndk-sp
पर मौजूद RenderScript इंटरनल लाइब्रेरी से लिंक किया गया है. वे/system/lib
में लाइब्रेरी से लिंक नहीं कर सकते, क्योंकि उस डायरेक्ट्री में मौजूद लिब्स, प्लैटफ़ॉर्म के लिए बनाई गई हैं. इसलिए, हो सकता है कि ये वेंडर कोड के साथ काम न करें (जैसे, सिंबल हटाए जा सकते हैं). ऐसा करने से, सिर्फ़ फ़्रेमवर्क के लिए ओटीए (ओवर-द-एयर) अपडेट करना मुमकिन नहीं होगा.
डिज़ाइन
नीचे दिए गए सेक्शन, Android 8.0 और इसके बाद के वर्शन में RenderScript के डिज़ाइन के बारे में बताते हैं.
वेंडर के लिए उपलब्ध RenderScript लाइब्रेरी
इस सेक्शन में RenderScript लिब्स (एक ही प्रोसेस वाले HAL या VNDK-SP के लिए वेंडर एनडीके कहा जाता है) की सूची दी गई है. ये वेंडर कोड में उपलब्ध होते हैं और इनसे लिंक किए जा सकते हैं. इसमें उन अन्य लाइब्रेरी के बारे में भी जानकारी दी जाती है जो RenderScript से जुड़ी नहीं हैं, लेकिन वेंडर कोड के लिए भी उपलब्ध कराई जाती हैं.
लाइब्रेरी की यह सूची, Android रिलीज़ के हिसाब से अलग-अलग हो सकती है. हालांकि, किसी खास Android रिलीज़ के लिए यह सूची नहीं बदलती. उपलब्ध लाइब्रेरी की अप-टू-डेट सूची के लिए, /system/etc/ld.config.txt
देखें.
RenderScript लिब | RenderScript के अलावा अन्य लाइब्रेरी |
---|---|
|
|
लिंकर नेमस्पेस कॉन्फ़िगरेशन
लिंक करने से जुड़ी पाबंदी, रनटाइम के दौरान लागू की जाती है. इससे, VNDK-SP में शामिल नहीं होने वाले लाइब्रेरी का इस्तेमाल, वेंडर कोड से नहीं किया जा सकता. इसके लिए, लिंकर नेमस्पेस का इस्तेमाल किया जाता है. ज़्यादा जानकारी के लिए, वीएनडीके डिज़ाइन प्रज़ेंटेशन देखें.
Android 8.0 और उसके बाद के वर्शन वाले डिवाइस पर, RenderScript को छोड़कर सभी सेम-प्रोसेस एचएएल (SP-HAL)
लिंकर नेमस्पेस
sphal
में लोड किए जाते हैं. RenderScript, RenderScript के लिए बने नेमस्पेस rs
में लोड होता है. यह एक ऐसी जगह है जहां RenderScript लाइब्रेरी के लिए, कुछ हद तक नीति को लागू करने की सुविधा मिलती है. आरएस को लागू करने के लिए, कंपाइल किया गया बिटकोड
लोड करना ज़रूरी होता है. इसलिए, /data/*/*.so
को
rs
नेमस्पेस के पाथ में जोड़ा जाता है. दूसरे एसपी-एचएएल को डेटा पार्टिशन से
लिब्स लोड करने की अनुमति नहीं होती.
इसके अलावा, rs
नेमस्पेस में, दूसरे नेमस्पेस के मुकाबले ज़्यादा लाइब्रेरी इस्तेमाल की जा सकती हैं. libmediandk.so
और libft2.so
को rs
नेमस्पेस में दिखाया जाता है, क्योंकि libRS_internal.so
में इन लाइब्रेरी पर इंटरनल डिपेंडेंसी है.
दूसरी इमेज. लिंकर के लिए नेमस्पेस कॉन्फ़िगरेशन.
ड्राइवर लोड करें
सीपीयू फ़ॉलबैक पाथ
आरएस कॉन्टेक्स्ट बनाते समय, RS_CONTEXT_LOW_LATENCY
बिट की मौजूदगी के आधार पर, सीपीयू या जीपीयू पाथ चुना जाता है. जब
सीपीयू पाथ चुना जाता है, तो libRS_internal.so
(RS फ़्रेमवर्क का मुख्य लागू होना) को डिफ़ॉल्ट लिंकर नेमस्पेस से सीधे dlopen
किया जाता है. यहां RS लाइब्रेरी का प्लैटफ़ॉर्म वर्शन उपलब्ध कराया जाता है.
जब सीपीयू के लिए फ़ॉलबैक पाथ चुना जाता है, तो वेंडर के आरएस एचएएल लागू करने का इस्तेमाल बिलकुल नहीं किया जाता. साथ ही, RsContext
ऑब्जेक्ट को शून्य mVendorDriverName
के साथ बनाया जाता है. libRSDriver.so
को डिफ़ॉल्ट रूप से dlopen
किया गया है और ड्राइवर लाइब्रेरी को default
नेमस्पेस से लोड किया गया है, क्योंकि कॉलर (libRS_internal.so
) को भी default
नेमस्पेस में लोड किया गया है.
तीसरी इमेज. सीपीयू फ़ॉलबैक पाथ.
जीपीयू पाथ
जीपीयू पाथ के लिए, libRS_internal.so
को अलग तरीके से लोड किया जाता है.
सबसे पहले, libRS.so
, android.hardware.renderscript@1.0-impl.so
(आरएस एचएएल का वेंडर लागू करने वाला) को sphal
नाम के किसी दूसरे लिंकर नेमस्पेस में लोड करने के लिए, android.hardware.renderscript@1.0.so
(और उसके नीचे मौजूद libhidltransport.so
) का इस्तेमाल करता है. इसके बाद, RS
HAL, rs
नाम के किसी दूसरे लिंकर नेमस्पेस में dlopen
s libRS_internal.so
को rs
में बदल देता है.
वेंडर, बिल्ड टाइम फ़्लैग OVERRIDE_RS_DRIVER
सेट करके अपना आरएस ड्राइवर उपलब्ध करा सकते हैं. यह फ़्लैग, आरएस एचएएल लागू करने (hardware/interfaces/renderscript/1.0/default/Context.cpp
) में एम्बेड होता है. इसके बाद, जीपीयू पाथ के लिए आरएस कॉन्टेक्स्ट में इस ड्राइवर का नाम dlopen
किया जाता है.
RsContext
ऑब्जेक्ट बनाने का काम, RS HAL के लागू करने वाले को सौंपा गया है. HAL, rsContextCreateVendor()
फ़ंक्शन का इस्तेमाल करके, ड्राइवर के नाम के साथ RS फ़्रेमवर्क को फिर से कॉल करता है, ताकि उसे आर्ग्युमेंट के तौर पर इस्तेमाल किया जा सके. इसके बाद, RsContext
शुरू होने पर, आरएस फ़्रेमवर्क तय किए गए ड्राइवर को लोड करता है. इस मामले में, ड्राइवर लाइब्रेरी को rs
नेमस्पेस में लोड किया जाता है, क्योंकि RsContext
ऑब्जेक्ट को rs
नेमस्पेस में बनाया गया है और /vendor/lib
, नेमस्पेस के खोज पाथ में है.
चौथी इमेज. जीपीयू फ़ॉलबैक पाथ.
default
नेमस्पेस से sphal
नेमस्पेस पर ट्रांज़िशन करते समय, libhidltransport.so
android_load_sphal_library()
फ़ंक्शन का इस्तेमाल करता है. इससे डाइनैमिक लिंकर को sphal
नेमस्पेस से -impl.so
लाइब्रेरी लोड करने का निर्देश दिया जाता है.
sphal
नेमस्पेस से rs
नेमस्पेस पर ट्रांज़िशन करते समय, /system/etc/ld.config.txt
में मौजूद इस लाइन की मदद से, डेटा को अप्रत्यक्ष तरीके से लोड किया जाता है:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
इस लाइन से पता चलता है कि डाइनैमिक लिंकर को rs
नेमस्पेस से libRS_internal.so
को तब लोड करना चाहिए, जब लिब
को sphal
नेमस्पेस से ढूंढा या लोड न किया जा सके (ऐसा हमेशा होता है, क्योंकि sphal
नेमस्पेस
/system/lib/vndk-sp
की खोज नहीं करता, जहां libRS_internal.so
मौजूद होता है. इस कॉन्फ़िगरेशन में, dlopen()
का इस्तेमाल करके
libRS_internal.so
को किया गया सामान्य कॉल, नेमस्पेस ट्रांज़िशन करने के लिए काफ़ी है.
गुप्त कॉपी प्लग इन लोड करना
bcc plugin
, वेंडर की ओर से उपलब्ध कराई गई लाइब्रेरी है, जिसे bcc
कंपाइलर में लोड किया जाता है. bcc
, /system/bin
डायरेक्ट्री में मौजूद एक सिस्टम प्रोसेस है.इसलिए, bcc plugin
लाइब्रेरी को एक एसपी-एचएएल माना जा सकता है. इसका मतलब है कि यह एक वेंडर एचएएल है, जिसे बाइंडर किए बिना सीधे सिस्टम प्रोसेस में लोड किया जा सकता है. SP-HAL के तौर पर, bcc-plugin
लाइब्रेरी:
- सिर्फ़ फ़्रेमवर्क वाली लाइब्रेरी के साथ लिंक नहीं किया जा सकता, जैसे कि
libLLVM.so
. - सिर्फ़ वेंडर के लिए उपलब्ध VNDK-SP लाइब्रेरी से लिंक किया जा सकता है.
यह पाबंदी, android_sphal_load_library()
फ़ंक्शन का इस्तेमाल करके, bcc plugin
को sphal
नेमस्पेस में लोड करके लागू की जाती है. Android के पिछले वर्शन में,
प्लगिन का नाम -load
विकल्प का इस्तेमाल करके बताया गया था.
साथ ही, लिब को
libLLVM.so
के आसान dlopen()
का इस्तेमाल करके लोड किया गया था. Android 8.0 और इसके बाद के वर्शन में, यह जानकारी
-plugin
विकल्प में दी गई होती है. साथ ही, bcc
से ही लाइब्रेरी को सीधे लोड किया जाता है. इस विकल्प की मदद से, ओपन सोर्स एलएलवीएम प्रोजेक्ट के लिए, Android के अलावा किसी दूसरे तरीके का पाथ चालू किया जाता है.
पांचवी इमेज. गुप्त कॉपी प्लगिन, Android 7.x और उससे पहले के वर्शन लोड हो रहे हैं.
छठी इमेज. गुप्त कॉपी प्लगिन, Android 8.0 और इसके बाद के वर्शन लोड हो रहे हैं.
ld.mc के लिए खोज पाथ
ld.mc
को लागू करते समय, कुछ RS रनटाइम लाइब्रेरी को लिंकर के तौर पर इनपुट के तौर पर दिया जाता है. ऐप्लिकेशन का आरएस बिटकोड, रनटाइम लाइब्रेरी के साथ लिंक होता है. जब बदले गए बिटकोड को ऐप्लिकेशन प्रोसेस में लोड किया जाता है, तो रनटाइम लाइब्रेरी को बदले गए बिटकोड से फिर से डाइनैमिक तौर पर लिंक किया जाता है.
रनटाइम लाइब्रेरी में ये शामिल हैं:
libcompiler_rt.so
libm.so
libc.so
- आरएस ड्राइवर (
libRSDriver.so
याOVERRIDE_RS_DRIVER
)
ऐप्लिकेशन प्रोसेस में कंपाइल किए गए बिटकोड को लोड करते समय, वही लाइब्रेरी दें जिसका इस्तेमाल ld.mc
ने किया था. ऐसा न करने पर, हो सकता है कि कंपाइल किए गए बिटकोड को वह सिंबल न मिले जो लिंक करते समय उपलब्ध था.
ऐसा करने के लिए, RS फ़्रेमवर्क, ld.mc
को लागू करते समय, रनटाइम लाइब्रेरी के लिए अलग-अलग सर्च पाथ का इस्तेमाल करता है. यह इस बात पर निर्भर करता है कि RS फ़्रेमवर्क, /system/lib
से लोड किया गया है या /system/lib/vndk-sp
से.
यह पता लगाने के लिए, RS फ़्रेमवर्क के किसी भी सिंबल का पता पढ़ें और dladdr()
का इस्तेमाल करके, पते से मैप किया गया फ़ाइल पाथ पाएं.
SELinux नीति
Android 8.0 और इसके बाद के वर्शन में SELinux नीति में हुए बदलावों की वजह से, आपको vendor
पार्टीशन में अन्य फ़ाइलों को लेबल करते समय, neverallows
के ज़रिए लागू किए गए खास नियमों का पालन करना होगा:
vendor_file
vendor
पार्टीशन में मौजूद सभी फ़ाइलों के लिए डिफ़ॉल्ट लेबल होना चाहिए. प्लैटफ़ॉर्म की नीति के मुताबिक, पासथ्रू एचएएल लागू करने के लिए, ऐसा करना ज़रूरी है.- वेंडर SEPolicy के ज़रिए
vendor
partition में जोड़े गए सभी नएexec_types
मेंvendor_file_type
एट्रिब्यूट होना चाहिए. इसेneverallows
के ज़रिए लागू किया जाता है. - आने वाले समय में प्लैटफ़ॉर्म/फ़्रेमवर्क के अपडेट से होने वाली समस्याओं से बचने के लिए,
vendor
सेक्शन मेंexec_types
के अलावा किसी और फ़ाइल को लेबल न करें. - एओएसपी से तय की गई एक जैसी प्रोसेस एचएएल के लिए, सभी लाइब्रेरी डिपेंडेंसी को
same_process_hal_file
के तौर पर लेबल किया जाना चाहिए.
SELinux की नीति के बारे में ज़्यादा जानने के लिए, Android में बेहतर सुरक्षा देने वाला Linux लेख पढ़ें.
बिटकोड के लिए एबीआई (ऑब्जेक्ट फ़ाइल फ़ॉर्मैट) की सुविधा
अगर कोई नया एपीआई नहीं जोड़ा जाता है, तो इसका मतलब है कि HAL वर्शन में कोई बदलाव नहीं हुआ है. ऐसे में, आरएस फ़्रेमवर्क, मौजूदा जीपीयू (HAL 1.0) ड्राइवर का इस्तेमाल करते रहेंगे.
अगर एचएएल में किए गए छोटे बदलावों (एचएएल 1.1) से बिटकोड पर असर नहीं पड़ता है, तो फ़्रेमवर्क को इन नए एपीआई के लिए सीपीयू पर फ़ॉलबैक करना चाहिए. साथ ही, अन्य जगहों पर जीपीयू (एचएएल 1.0) ड्राइवर का इस्तेमाल करना चाहिए.
बिटकोड कोड को कंपाइल/लिंक करने पर असर डालने वाले एचएएल (एचएएल 2.0) में हुए बड़े बदलावों के लिए, आरएस फ़्रेमवर्क को वेंडर से मिले जीपीयू ड्राइवर लोड नहीं करने चाहिए. इसके बजाय, तेज़ी के लिए सीपीयू या Vulkan पाथ का इस्तेमाल करना चाहिए.
RenderScript बिट कोड का इस्तेमाल तीन चरणों में होता है:
स्टेज | जानकारी |
---|---|
कंपाइल करें |
|
लिंक |
|
लोड करना |
|
एचएएल के अलावा, रनटाइम एपीआई और एक्सपोर्ट किए गए सिंबल भी इंटरफ़ेस हैं. Android 7.0 (एपीआई 24) के बाद से, दोनों में से कोई भी इंटरफ़ेस नहीं बदला है. साथ ही, Android 8.0 और इसके बाद के वर्शन के लिए, इस इंटरफ़ेस को तुरंत बदलने की कोई योजना नहीं है. हालांकि, अगर इंटरफ़ेस में बदलाव होता है, तो एचएएल वर्शन भी बढ़ जाएगा.
वेंडर के लागू करने की सुविधा
Android 8.0 और उसके बाद के वर्शन में, जीपीयू ड्राइवर ठीक से काम करे, इसके लिए उसमें कुछ बदलाव करने पड़ते हैं.
ड्राइवर मॉड्यूल
- ड्राइवर मॉड्यूल, ऐसी किसी भी सिस्टम लाइब्रेरी पर निर्भर नहीं होने चाहिए जो सूची में शामिल नहीं है.
- ड्राइवर को अपना
android.hardware.renderscript@1.0-impl_{NAME}
देना होगा या डिफ़ॉल्ट रूप से लागूandroid.hardware.renderscript@1.0-impl
को डिपेंडेंसी के तौर पर एलान करना होगा. - सीपीयू लागू करने की प्रोसेस
libRSDriver.so
, बिना वीएनडीके-एसपी डिपेंडेंसी को हटाने के तरीके का अच्छा उदाहरण है.
बिटकोड कंपाइलर
वेंडर ड्राइवर के लिए, RenderScript बिटकोड को दो तरीकों से कंपाइल किया जा सकता है:
/vendor/bin/
में, वेंडर के हिसाब से RenderScript कंपाइलर को कॉल करें (जीपीयू कंपाइलेशन का पसंदीदा तरीका). अन्य ड्राइवर मॉड्यूल की तरह ही, वेंडर कंपाइलर बाइनरी किसी ऐसी सिस्टम लाइब्रेरी पर निर्भर नहीं हो सकती जो वेंडर के लिए उपलब्ध RenderScript लाइब्रेरी की सूची में शामिल न हो.- वेंडर की ओर से उपलब्ध कराई गई
bcc plugin
के साथ, सिस्टम बीसीसी:/system/bin/bcc
को शुरू करें; यह प्लग इन किसी भी ऐसी सिस्टम लाइब्रेरी पर निर्भर नहीं हो सकता जो वेंडर के लिए उपलब्ध RenderScript लाइब्रेरी की सूची में शामिल नहीं है.
अगर वेंडर bcc plugin
को सीपीयू के संकलन में बदलाव करना है और libLLVM.so
पर निर्भरता को आसानी से नहीं हटाया जा सकता, तो वेंडर को bcc
(और libLLVM.so
, libbcc.so
के साथ-साथ सभी नॉन-एलएल-एनडीके डिपेंडेंसी) को /vendor
सेक्शन में कॉपी करना चाहिए.
इसके अलावा, वेंडर को ये बदलाव करने होंगे:
सातवीं इमेज. वेंडर ड्राइवर में बदलाव.
libclcore.bc
को/vendor
पार्टीशन में कॉपी करें. इससे यह पक्का होता है किlibclcore.bc
,libLLVM.so
, औरlibbcc.so
सिंक किए गए हैं.- आरएस एचएएल को लागू करने के तरीके से
RsdCpuScriptImpl::BCC_EXE_PATH
को सेट करके,bcc
एक्ज़ीक्यूटेबल फ़ाइल का पाथ बदलें.
SELinux नीति
SELinux नीति का असर, ड्राइवर और कंपाइलर के एक्सीक्यूटेबल, दोनों पर पड़ता है. डिवाइस के file_contexts
में, सभी ड्राइवर मॉड्यूल को same_process_hal_file
के तौर पर लेबल किया जाना चाहिए. उदाहरण के लिए:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
कंपाइलर को ऐप्लिकेशन प्रोसेस से शुरू किया जा सकता है, ठीक वैसे ही जैसे bcc (/vendor/bin/bcc
) की वेंडर कॉपी को किया जाता है. उदाहरण के लिए:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
लेगसी डिवाइस
लेगसी डिवाइस वे होते हैं जो इन शर्तों को पूरा करते हैं:
- PRODUCT_SHIPPING_API_LEVEL की वैल्यू 26 से कम है.
- PRODUCT_FULL_TREBLE_OVERRIDE की वैल्यू नहीं दी गई है.
लेगसी डिवाइसों के लिए, Android 8.0 और उसके बाद के वर्शन पर अपग्रेड करने पर पाबंदियां लागू नहीं होतीं. इसका मतलब है कि ड्राइवर, /system/lib[64]
में लाइब्रेरी से लिंक किए जा सकते हैं. हालांकि, OVERRIDE_RS_DRIVER
से जुड़े आर्किटेक्चर में हुए बदलाव की वजह से, android.hardware.renderscript@1.0-impl
को /vendor
सेगमेंट में इंस्टॉल करना ज़रूरी है. ऐसा न करने पर, RenderScript रनटाइम को सीपीयू पाथ पर फ़ॉलबैक करना पड़ता है.
रेंडर स्क्रिप्ट का इस्तेमाल बंद होने की वजह के बारे में जानने के लिए, Android डेवलपर ब्लॉग देखें: Android जीपीयू Compute Going Forward. इस सुविधा के बंद होने के बारे में संसाधनों की जानकारी में ये चीज़ें शामिल हैं:
- Renderscript से माइग्रेट करना
- RenderScript Migration सैंपल
- इंट्रिंसिक्स रिप्लेसमेंट टूलकिट README
- Intrinsics ReplacementToolkit.kt