RenderScript का इस्तेमाल करने वाले ऐप्लिकेशन अब भी Android वीएम के अंदर चलते हैं, आपके पास उन सभी फ़्रेमवर्क के एपीआई का ऐक्सेस होता है जिनके बारे में आपको जानकारी है. हालांकि, जब सही हो, तब RenderScript का इस्तेमाल करें. इस इंटरैक्शन को आसान बनाने के लिए फ़्रेमवर्क और RenderScript रनटाइम, दोनों के साथ काम करता है, तो कोड की एक इंटरमीडिएट लेयर भी इसका इस्तेमाल, कोड के दो लेवल के बीच कम्यूनिकेशन और मेमोरी मैनेजमेंट की सुविधा देने के लिए किया जा सकता है. इस दस्तावेज़ में इनके बारे में ज़्यादा जानकारी दी गई है कोड की अलग-अलग लेयर पर सेट किया गया है. साथ ही, यह भी बताया गया है कि Android वीएम और RenderScript रनटाइम.
RenderScript रनटाइम लेयर
आपका RenderScript कोड कंपाइल किया जाता है और एक छोटी और अच्छी तरह तय की गई रनटाइम लेयर में चलाया जाता है. RenderScript रनटाइम एपीआई, इंटेंसिव कंप्यूटेशन की सेवा एक प्रोसेसर पर उपलब्ध कोर की मात्रा होती है.
ध्यान दें: एनडीके में स्टैंडर्ड C फ़ंक्शन ऐसे होने चाहिए सीपीयू पर चलने की गारंटी देता है, इसलिए RenderScript इन लाइब्रेरी को ऐक्सेस नहीं कर सकता, क्योंकि RenderScript को अलग-अलग तरह के प्रोसेसर पर चलने के लिए डिज़ाइन किया गया है.
आपने .rs
में अपना RenderScript कोड तय किया है
और आपके Android प्रोजेक्ट की src/
डायरेक्ट्री में .rsh
फ़ाइलें हैं. कोड
को इंटरमीडिएट बाइटकोड में
llvm
कंपाइलर, जो Android बिल्ड के हिस्से के तौर पर चलता है. जब आपका आवेदन
एक डिवाइस पर चलता है, फिर बाइट कोड को दूसरे डिवाइस से, मशीन कोड में कंपाइल (जस्ट-इन-टाइम) किया जाता है
llvm
कंपाइलर, जो डिवाइस में रहता है. मशीन कोड को
डिवाइस और कैश मेमोरी में भी सेव किया जाता है, इसलिए RenderScript की मदद से चालू किए गए ऐप्लिकेशन का बाद में इस्तेमाल
बाइट कोड को फिर से कंपाइल करना होगा.
RenderScript रनटाइम लाइब्रेरी की कुछ मुख्य सुविधाओं में ये शामिल हैं:
- मेमोरी के बंटवारे के अनुरोध की सुविधाएं
- स्केलर और वेक्टर, दोनों टाइप के ओवरलोडेड वर्शन के साथ गणित के फ़ंक्शन का एक बड़ा संग्रह में कर सकते हैं. जोड़ना, गुणा करना, डॉट प्रॉडक्ट, और क्रॉस प्रॉडक्ट जैसे ऑपरेशन साथ ही, परमाणु अंकगणित और तुलना करने वाले फ़ंक्शन उपलब्ध हैं.
- प्रिमिटिव डेटा टाइप और वेक्टर, मैट्रिक्स रूटीन, और तारीख और समय के लिए कन्वर्ज़न रूटीन रूटीन
- RenderScript सिस्टम के साथ काम करने के लिए डेटा टाइप और स्ट्रक्चर, जैसे कि वेक्टर टाइप दो, तीन या चार वेक्टर का पता लगाएं.
- फ़ंक्शन लॉग करने का तरीका
उपलब्ध फ़ंक्शन के बारे में ज़्यादा जानने के लिए, RenderScript रनटाइम एपीआई का रेफ़रंस देखें.
रिफ़्लेक्टेड लेयर
परावर्तित लेयर, क्लास का एक सेट है. इसे ऐक्सेस देने के लिए, Android बिल्ड टूल जनरेट करते हैं को Android फ़्रेमवर्क से RenderScript रनटाइम में एक्सपोर्ट कर दिया जाएगा. यह लेयर, तरीके भी देती है और ऐसे कंस्ट्रक्टर जिनकी मदद से, आपको आपका RenderScript कोड. नीचे दी गई सूची में प्रमुख इसमें दिखने वाले कॉम्पोनेंट:
- आपकी बनाई जाने वाली हर
.rs
फ़ाइल, में सेproject_root/gen/package/name/ScriptC_renderscript_filename
ScriptC
टाइप करें. यह फ़ाइल आपके ऐप्लिकेशन का.java
वर्शन है.rs
फ़ाइल डाउनलोड की जा सकती है, जिसे Android फ़्रेमवर्क से कॉल किया जा सकता है. इस क्लास में.rs
फ़ाइल से ये आइटम दिखते हैं:- नॉन-स्टैटिक फ़ंक्शन
- नॉन-स्टैटिक, ग्लोबल RenderScript वैरिएबल. ऐक्सेसर
तरीके हर वैरिएबल के लिए जनरेट किए जाते हैं, ताकि आप इन्हें पढ़ सकें और
Android से RenderScript वैरिएबल लिखें
फ़्रेमवर्क शामिल है. अगर कोई ग्लोबल वैरिएबल
RenderScript रनटाइम लेयर, उन वैल्यू का इस्तेमाल इन कामों के लिए किया जाता है
Android फ़्रेमवर्क में, उससे जुड़ी वैल्यू को शुरू करना
लेयर. अगर ग्लोबल वैरिएबल को
const
के तौर पर मार्क किया गया है, तो तोset
तरीका जनरेट किया गया. यहां देखें देखें. - ग्लोबल पॉइंटर
struct
, इसकी अपनी नाम वाली क्लास में दिखता हैproject_root/gen/package/name/ScriptField_struct_name
, जोScript.FieldBase
तक बढ़ाएं. यह क्लास,struct
, जो आपको इसके एक या ज़्यादा इंस्टेंस के लिए मेमोरी बांटने की अनुमति देता हैstruct
.
फ़ंक्शन
फ़ंक्शन, स्क्रिप्ट क्लास में ही दिखते हैं. ये क्लास में
project_root/gen/package/name/ScriptC_renderscript_filename
. इसके लिए
उदाहरण के लिए, अगर आप अपने RenderScript कोड में नीचे दिए गए फ़ंक्शन को तय करते हैं:
void touch(float x, float y, float pressure, int id) { if (id >= 10) { return; } touchPos[id].x = x; touchPos[id].y = y; touchPressure[id] = pressure; }
तो यह Java कोड जनरेट होता है:
public void invoke_touch(float x, float y, float pressure, int id) { FieldPacker touch_fp = new FieldPacker(16); touch_fp.addF32(x); touch_fp.addF32(y); touch_fp.addF32(pressure); touch_fp.addI32(id); invoke(mExportFuncIdx_touch, touch_fp); }
फ़ंक्शन में रिटर्न वैल्यू नहीं हो सकतीं, क्योंकि RenderScript सिस्टम को इस तरह डिज़ाइन किया गया है कि एसिंक्रोनस. जब आपका Android फ़्रेमवर्क कोड RenderScript में कॉल करता है, तो कॉल सूची में होता है और लागू किया जाता है. इस पाबंदी की मदद से, RenderScript सिस्टम बिना किसी कॉन्सटैंट वैल्यू के काम कर सकता है और क्षमता को बढ़ाता है. अगर फ़ंक्शन को रिटर्न वैल्यू की अनुमति होती है, तो तब तक ब्लॉक रहेगा, जब तक वैल्यू नहीं दिखाई जाती.
अगर आप चाहते हैं कि RenderScript कोड किसी मान को वापस Android फ़्रेमवर्क को भेजे, तो
rsSendToClient()
फ़ंक्शन का इस्तेमाल करना होगा.
वैरिएबल
समर्थित प्रकार के वैरिएबल स्क्रिप्ट क्लास में ही दिखाई देते हैं, जो यहां मौजूद हैं
project_root/gen/package/name/ScriptC_renderscript_filename
. ऐक्सेसर का सेट
हर वैरिएबल के लिए तरीके जनरेट किए जाते हैं. उदाहरण के लिए, अगर नीचे दिए गए वैरिएबल को
आपका RenderScript कोड:
uint32_t unsignedInteger = 1;
तो यह Java कोड जनरेट होता है:
private long mExportVar_unsignedInteger; public void set_unsignedInteger(long v){ mExportVar_unsignedInteger = v; setVar(mExportVarIdx_unsignedInteger, v); } public long get_unsignedInteger(){ return mExportVar_unsignedInteger; }
स्ट्रक्चर
संरचनाएं अपनी ही क्लास में प्रतिबिंबित होती हैं, जो
<project_root>/gen/com/example/renderscript/ScriptField_struct_name
. यह
क्लास, struct
का कलेक्शन दिखाती है. साथ ही, इससे आपको
struct
की बताई गई संख्या. उदाहरण के लिए, अगर नीचे दिए गए स्ट्रक्चर को तय किया जाता है:
typedef struct Point { float2 position; float size; } Point_t;
तो ScriptField_Point.java
में यह कोड जनरेट होता है:
package com.example.android.rs.hellocompute; import android.renderscript.*; import android.content.res.Resources; /** * @hide */ public class ScriptField_Point extends android.renderscript.Script.FieldBase { static public class Item { public static final int sizeof = 12; Float2 position; float size; Item() { position = new Float2(); } } private Item mItemArray[]; private FieldPacker mIOBuffer; public static Element createElement(RenderScript rs) { Element.Builder eb = new Element.Builder(rs); eb.add(Element.F32_2(rs), "position"); eb.add(Element.F32(rs), "size"); return eb.create(); } public ScriptField_Point(RenderScript rs, int count) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count); } public ScriptField_Point(RenderScript rs, int count, int usages) { mItemArray = null; mIOBuffer = null; mElement = createElement(rs); init(rs, count, usages); } private void copyToArray(Item i, int index) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(i.position); mIOBuffer.addF32(i.size); } public void set(Item i, int index, boolean copyNow) { if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; mItemArray[index] = i; if (copyNow) { copyToArray(i, index); mAllocation.setFromFieldPacker(index, mIOBuffer); } } public Item get(int index) { if (mItemArray == null) return null; return mItemArray[index]; } public void set_position(int index, Float2 v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].position = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(8); fp.addF32(v); mAllocation.setFromFieldPacker(index, 0, fp); } } public void set_size(int index, float v, boolean copyNow) { if (mIOBuffer == null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); if (mItemArray == null) mItemArray = new Item[getType().getX() /* count */]; if (mItemArray[index] == null) mItemArray[index] = new Item(); mItemArray[index].size = v; if (copyNow) { mIOBuffer.reset(index * Item.sizeof + 8); mIOBuffer.addF32(v); FieldPacker fp = new FieldPacker(4); fp.addF32(v); mAllocation.setFromFieldPacker(index, 1, fp); } } public Float2 get_position(int index) { if (mItemArray == null) return null; return mItemArray[index].position; } public float get_size(int index) { if (mItemArray == null) return 0; return mItemArray[index].size; } public void copyAll() { for (int ct = 0; ct < mItemArray.length; ct++) copyToArray(mItemArray[ct], ct); mAllocation.setFromFieldPacker(0, mIOBuffer); } public void resize(int newSize) { if (mItemArray != null) { int oldSize = mItemArray.length; int copySize = Math.min(oldSize, newSize); if (newSize == oldSize) return; Item ni[] = new Item[newSize]; System.arraycopy(mItemArray, 0, ni, 0, copySize); mItemArray = ni; } mAllocation.resize(newSize); if (mIOBuffer != null) mIOBuffer = new FieldPacker(Item.sizeof * getType().getX()/* count */); } }
जनरेट किया गया कोड, अनुरोध किए गए स्ट्रक्चर के लिए मेमोरी बांटने में आपकी सुविधा के तौर पर दिया जाता है
RenderScript रनटाइम के ज़रिए और struct
s के साथ इंटरैक्ट करने के लिए
मेमोरी में सेव किया जा सकता है. हर struct
की क्लास इन तरीकों और कंस्ट्रक्टर के बारे में बताती है:
- ओवरलोडेड कंस्ट्रक्टर, जो आपको मेमोरी असाइन करने की अनुमति देते हैं. कॉन्टेंट बनाने
ScriptField_struct_name(RenderScript rs, int count)
कंस्ट्रक्टर की अनुमति है आप उन स्ट्रक्चर की संख्या परिभाषित कर सकते हैं जिनके लिए आपcount
पैरामीटर.ScriptField_struct_name(RenderScript rs, int count, int usages)
कंस्ट्रक्टर, उस अतिरिक्त पैरामीटरusages
के बारे में बताता है जो आपको इस मेमोरी के बंटवारे के लिए मेमोरी स्पेस तय करने की सुविधा देता है. स्टोरेज में चार जगह होती है संभावनाएं:USAGE_SCRIPT
: स्क्रिप्ट मेमोरी में असाइन करता है स्पेस. अगर आप मेमोरी स्पेस तय नहीं करते हैं, तो यह डिफ़ॉल्ट मेमोरी स्पेस होता है.USAGE_GRAPHICS_TEXTURE
: इसमें असाइन किया जाता है जीपीयू का टेक्सचर मेमोरी स्पेस.USAGE_GRAPHICS_VERTEX
: शीर्ष में तय करता है जीपीयू का मेमोरी स्पेस.USAGE_GRAPHICS_CONSTANTS
: इसमें असाइन किया जाता है जीपीयू का स्थायी मेमोरी स्पेस, जिसका इस्तेमाल प्रोग्राम के अलग-अलग ऑब्जेक्ट में किया जाता है.
बिट के अनुसार
OR
ऑपरेटर का इस्तेमाल करके, एक से ज़्यादा मेमोरी स्पेस तय किए जा सकते हैं. ऐसा करना यह RenderScript रनटाइम की सूचना देता है कि आप तय मेमोरी स्पेस. नीचे दिए गए उदाहरण में, कस्टम डेटा टाइप के लिए मेमोरी असाइन की गई है स्क्रिप्ट और वर्टेक्स मेमोरी स्पेस, दोनों में:Kotlin
val touchPoints: ScriptField_Point = ScriptField_Point( myRenderScript, 2, Allocation.USAGE_SCRIPT or Allocation.USAGE_GRAPHICS_VERTEX )
Java
ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2, Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_VERTEX);
- स्टैटिक नेस्ट की गई क्लास,
Item
की मदद से,struct
. अगर काम करना ज़्यादा सही लगता है, तो नेस्ट की गई यह क्लास काम की है अपने Android कोड मेंstruct
से. ऑब्जेक्ट में बदलाव करने के बाद, ऑब्जेक्ट को असाइन की गई मेमोरी में पुश किया जा सकता है. इसके लिए,set(Item i, int index, boolean copyNow)
को कॉल करें औरItem
को अपनी पसंद की जगह पर सेट करें श्रेणी को चुनना होगा. RenderScript रनटाइम को अपने-आप नई मेमोरी का ऐक्सेस मिल जाता है. - किसी स्ट्रक्चर में हर फ़ील्ड की वैल्यू पाने और सेट करने के लिए, ऐक्सेसर के तरीके. इनमें से सभी
ऐक्सेसर के तरीकों में
struct
की जानकारी देने के लिए, एकindex
पैरामीटर होता है वह कलेक्शन होता है जिसे आपको पढ़ना या लिखना है. हर सेटर विधि मेंcopyNow
पैरामीटर से तय होता है कि इस मेमोरी को तुरंत सिंक करना है या नहीं को RenderScript रनटाइम में एक्सपोर्ट कर सकता है. जो मेमोरी सिंक नहीं की गई है उसे सिंक करने के लिए, कॉल करेंcopyAll()
. createElement()
तरीका, मेमोरी में स्ट्रक्चर की जानकारी बनाता है. यह ब्यौरे का इस्तेमाल एक या कई एलिमेंट वाली मेमोरी तय करने के लिए किया जाता है.resize()
, C में मौजूदrealloc()
की तरह काम करता है. इसकी मदद से, ये काम किए जा सकते हैं पहले असाइन की गई मेमोरी को बड़ा करें, ताकि मौजूदा वैल्यू में कोई बदलाव न हो बनाया गया.copyAll()
, फ़्रेमवर्क लेवल पर सेट की गई मेमोरी को RenderScript रनटाइम. जब किसी सदस्य पर, ऐक्सेसर के सेट किए गए तरीके को कॉल किया जाता है, तोcopyNow
बूलियन पैरामीटर, जिसे तय किया जा सकता है. तय किया जा रहा है तरीके को कॉल करने पर,true
मेमोरी को सिंक करता है. अगर गलत वैल्यू दी जाती है, आपcopyAll()
को एक बार कॉल कर सकते हैं और यह सभी ऐसी प्रॉपर्टी जिन्हें अभी तक सिंक नहीं किया गया है.
पॉइंटर
ग्लोबल पॉइंटर, स्क्रिप्ट क्लास में दिखते हैं
project_root/gen/package/name/ScriptC_renderscript_filename
. आपने लोगों तक पहुंचाया मुफ़्त में
किसी struct
या इस्तेमाल किए जा सकने वाले किसी भी RenderScript टाइप के लिए पॉइंटर एलान कर सकता है, लेकिन
struct
में पॉइंटर या नेस्ट किए गए अरे नहीं हो सकते. उदाहरण के लिए, यदि आप
struct
और int32_t
पर ले जाने वाले पॉइंटर
typedef struct Point { float2 position; float size; } Point_t; Point_t *touchPoints; int32_t *intPointer;
तो यह Java कोड जनरेट होता है:
private ScriptField_Point mExportVar_touchPoints; public void bind_touchPoints(ScriptField_Point v) { mExportVar_touchPoints = v; if (v == null) bindAllocation(null, mExportVarIdx_touchPoints); else bindAllocation(v.getAllocation(), mExportVarIdx_touchPoints); } public ScriptField_Point get_touchPoints() { return mExportVar_touchPoints; } private Allocation mExportVar_intPointer; public void bind_intPointer(Allocation v) { mExportVar_intPointer = v; if (v == null) bindAllocation(null, mExportVarIdx_intPointer); else bindAllocation(v, mExportVarIdx_intPointer); } public Allocation get_intPointer() { return mExportVar_intPointer; }
एक get
तरीका और bind_pointer_name
नाम का एक खास तरीका
(set()
तरीके के बजाय) जनरेट किए जाते हैं. bind_pointer_name
तरीका, आपको मेमोरी को बाइंड करने की अनुमति देता है
जिसे Android वीएम में RenderScript रनटाइम में असाइन किया गया हो (आप
मेमोरी) .rs
फ़ाइल में सेव की जाती है). ज़्यादा जानकारी के लिए, देखें काम कर रहा है
तय मेमोरी के साथ.
मेमोरी ऐलोकेशन एपीआई
RenderScript का इस्तेमाल करने वाले ऐप्लिकेशन अब भी Android वीएम में चलते हैं. हालांकि, वास्तविक RenderScript कोड स्थानीय तौर पर चलता है और
को Android वीएम में असाइन की गई मेमोरी का ऐक्सेस चाहिए. ऐसा करने के लिए,
वीएम में तय की गई मेमोरी को RenderScript रनटाइम में अटैच करें. यह
प्रोसेस, जिसे बाइंडिंग कहा जाता है, से RenderScript रनटाइम को उस मेमोरी के साथ बिना किसी रुकावट के काम करने में मदद मिलती है
अनुरोध करते हैं, लेकिन स्पष्ट रूप से आवंटित नहीं कर सकते. नतीजा कुछ ऐसा ही होता है जैसे कि
सी में malloc
कहा जाता है. Android वीएम का अतिरिक्त फ़ायदा यह है कि इसकी मदद से, कूड़ा इकट्ठा करने का काम भी किया जा सकता है
RenderScript रनटाइम लेयर के साथ मेमोरी शेयर करें. बाइंडिंग की ज़रूरत सिर्फ़ डाइनैमिक तरीके से असाइन की गई मेमोरी के लिए होती है. स्टैटिक तरीके से
असाइन की गई मेमोरी, कंपाइल करते समय आपके RenderScript कोड के लिए अपने-आप बन जाती है. पहली इमेज देखें
देखें.
मेमोरी के इस ऐलोकेशन सिस्टम पर काम करने के लिए, एपीआई का एक सेट उपलब्ध है. इसकी मदद से Android वीएम को
मेमोरी का बंटवारा किया जा सकता है और malloc
कॉल जैसी ही सुविधाएं दी जा सकती हैं. ये क्लास
साफ़ तौर पर यह बताएं कि मेमोरी किस तरह असाइन की जानी चाहिए. साथ ही, बंटवारे की सुविधा का पूरा इस्तेमाल कैसे किया जाना चाहिए. बेहतर करने के लिए
इन क्लास के काम करने का तरीका समझने के लिए, इन्हें एक आसान
malloc
कॉल, जो कुछ ऐसा दिख सकता है:
array = (int *)malloc(sizeof(int)*10);
malloc
कॉल को दो हिस्सों में बांटा जा सकता है: असाइन की जा रही मेमोरी का साइज़ (sizeof(int)
),
साथ ही, उस मेमोरी की कितनी यूनिट असाइन की जानी चाहिए (10). Android फ़्रेमवर्क, इन दो हिस्सों के लिए क्लास देता है
और malloc
को दर्शाने वाली क्लास.
Element
क्लास, (sizeof(int)
) वाला हिस्सा दिखाती है
यह malloc
कॉल का हिस्सा होता है और मेमोरी के बंटवारे का एक सेल इनकैप्सुलेट करता है, जैसे कि कोई सिंगल
फ़्लोट वैल्यू या स्ट्रक्चर शामिल करें. Type
क्लास में Element
शामिल होता है
और असाइन किए जाने वाले एलिमेंट की संख्या (हमारे उदाहरण में 10). Type
को ऐसा समझा जा सकता है
Element
का कलेक्शन. Allocation
क्लास
दिए गए Type
के हिसाब से मेमोरी का बंटवारा और असल में असाइन की गई मेमोरी का पता चलता है.
ज़्यादातर मामलों में, आपको इन मेमोरी ऐलोकेशन एपीआई को सीधे कॉल करने की ज़रूरत नहीं होती. परावर्तित परत
क्लास अपने आप इन API का इस्तेमाल करने के लिए कोड जनरेट करती हैं और मेमोरी असाइन करने के लिए आपको बस एक
कंस्ट्रक्टर जिसका एलान किसी एक प्रतिबिंब लेयर क्लास में किया जाता है और फिर बाइंड करता है
इससे बनने वाली मेमोरी Allocation
को RenderScript में बदलें.
कुछ ऐसी स्थितियां हैं जिनमें आपको इन क्लास का इस्तेमाल सीधे तौर पर, अपने
जैसे कि किसी संसाधन से बिटमैप लोड करना या जब आपको पॉइंटर के लिए मेमोरी असाइन करनी हो,
प्रिमिटिव टाइप. इसका तरीका यहां देखें:
RenderScript में मेमोरी असाइन करना और बाइंड करना सेक्शन.
इस टेबल में, मेमोरी मैनेजमेंट के तीन क्लास के बारे में ज़्यादा जानकारी दी गई है:
Android ऑब्जेक्ट टाइप | ब्यौरा |
---|---|
Element |
एलिमेंट, मेमोरी के बंटवारे के एक सेल के बारे में बताता है और इसके दो रूप हो सकते हैं: बेसिक या जटिल. बेसिक एलिमेंट में किसी भी मान्य RenderScript डेटा टाइप के डेटा का एक कॉम्पोनेंट होता है.
बेसिक एलिमेंट डेटा टाइप के उदाहरणों में एक कॉम्प्लेक्स एलिमेंट में बुनियादी एलिमेंट की एक सूची होती है. इन्हें इन एलिमेंट से बनाया जाता है
|
Type |
टाइप, मेमोरी ऐलोकेशन टेंप्लेट होता है. इसमें एक एलिमेंट और एक या उससे ज़्यादा एलिमेंट होते हैं
डाइमेंशन. यह मेमोरी के लेआउट के बारे में बताता है (मूल रूप से एक टाइप के पांच डाइमेंशन होते हैं: X, Y, Z, LOD (जानकारी का लेवल), और फ़ेस (एक क्यूब के) मैप) पर क्लिक करें. X,Y,Z के डाइमेंशन को उपलब्ध मेमोरी की सीमाएं तय करना. एक डाइमेंशन के बंटवारे का X डाइमेंशन शून्य से ज़्यादा है, जबकि Y और Z डाइमेंशन शून्य हैं. इसका मतलब है कि कोई वैल्यू मौजूद नहीं है. इसके लिए जैसे, x=10 का बंटवारा. y=1 को दो डाइमेंशन और x=10 के बीच माना जाता है. y=0 को माना जाता है. मौजूद दिखाने के लिए एलओडी और चेहरे के डाइमेंशन बूलियन हैं या मौजूद न हो. |
Allocation |
असाइन करने से, ऐप्लिकेशन के लिए मेमोरी उपलब्ध होती है. यह मेमोरी के ब्यौरे के आधार पर तय होती है
जिसे आवंटन डेटा को मुख्य रूप से इन दो में से किसी एक तरीके से अपलोड किया जाता है: टाइप को चुना गया और टाइप नहीं किया गया.
सामान्य सरणियों के लिए, |
मेमोरी के साथ काम करना
आपने रेंडर स्क्रिप्ट में, नॉन-स्टैटिक, ग्लोबल वैरिएबल के बारे में जानकारी दी है. वैरिएबल को कंपाइल करते समय मेमोरी असाइन की जाती है.
आप इन वैरिएबल के साथ सीधे अपने RenderScript कोड में काम कर सकते हैं. इसके लिए आपको
मेमोरी की ज़रूरत नहीं होती. Android फ़्रेमवर्क लेयर के पास इन वैरिएबल का ऐक्सेस भी होता है
को ऐक्सेस करने के लिए दिए गए उन तरीकों का इस्तेमाल करना चाहिए जो दिखाई गई लेयर क्लास में जनरेट होते हैं. अगर ये वैरिएबल
RenderScript रनटाइम लेयर पर शुरू किया जाता है, तो उन वैल्यू का इस्तेमाल संबंधित
में मौजूदा वैल्यू शामिल होती हैं. अगर ग्लोबल वैरिएबल को कॉन्स्ट के तौर पर मार्क किया गया है, तो set
तरीका होगा
जनरेट नहीं हुआ. ज़्यादा जानकारी के लिए यहां देखें.
ध्यान दें: अगर आप ऐसे कुछ RenderScript स्ट्रक्चर का इस्तेमाल कर रहे हैं जिनमें पॉइंटर मौजूद हैं, जैसे कि
rs_program_fragment
और rs_allocation
, आपको
पहले संबंधित Android फ़्रेमवर्क क्लास और फिर उसके लिए set
मेथड को कॉल करें
स्ट्रक्चर को रेंडर करने में मदद करता है. आप इन स्ट्रक्चर में सीधे तौर पर बदलाव नहीं कर सकते
RenderScript रनटाइम लेयर पर. यह प्रतिबंध उपयोगकर्ता-तय स्ट्रक्चर पर लागू नहीं है
जिनमें पॉइंटर होते हैं, क्योंकि उन्हें किसी प्रतिबिंब लेयर क्लास में एक्सपोर्ट नहीं किया जा सकता
पहले स्थान पर हैं. किसी नॉन-स्टैटिक, ग्लोबल एलान का एलान करने पर कंपाइलर गड़बड़ी जनरेट होती है
ऐसी संरचना जिसमें पॉइंटर हो.
RenderScript में भी पॉइंटर के लिए समर्थन मौजूद है, लेकिन आपको अपने
Android फ़्रेमवर्क कोड. अपनी .rs
फ़ाइल में ग्लोबल पॉइंटर का एलान करने पर,
उचित परावर्तित लेयर क्लास के ज़रिए मेमोरी असाइन करें और उस मेमोरी को नेटिव से बाइंड करें
RenderScript लेयर. इस मेमोरी के साथ, Android फ़्रेमवर्क लेयर के ज़रिए भी इंटरैक्ट किया जा सकता है
RenderScript लेयर, जो आपको ज़्यादा से ज़्यादा वैरिएबल को बदलने की सुविधा देती है
उचित लेयर.
RenderScript में डाइनैमिक मेमोरी तय करना और जोड़ना
डाइनैमिक मेमोरी असाइन करने के लिए, आपको
Script.FieldBase
क्लास, जो सबसे सामान्य तरीका है. इसका एक विकल्प यह है कि
मैन्युअल रूप से Allocation
, जो कि प्रिमिटिव टाइप पॉइंटर जैसी चीज़ों के लिए ज़रूरी है. आपको ऐसा करना चाहिए
जहां भी आसानी से काम करने के लिए उपलब्ध हो, Script.FieldBase
क्लास कंस्ट्रक्टर का इस्तेमाल करें.
मेमोरी असाइन करने के बाद, पॉइंटर के दिखाए गए bind
तरीके को कॉल करें, ताकि असाइन की गई मेमोरी से
RenderScript रनटाइम.
नीचे दिया गया उदाहरण, प्रिमिटिव टाइप पॉइंटर, दोनों के लिए मेमोरी बांटता है,
intPointer
और स्ट्रक्चर के लिए पॉइंटर, touchPoints
. यह मेमोरी को
रेंडर स्क्रिप्ट:
Kotlin
private lateinit var myRenderScript: RenderScript private lateinit var script: ScriptC_example private lateinit var resources: Resources public fun init(rs: RenderScript, res: Resources) { myRenderScript = rs resources = res // allocate memory for the struct pointer, calling the constructor val touchPoints = ScriptField_Point(myRenderScript, 2) // Create an element manually and allocate memory for the int pointer val intPointer: Allocation = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2) // create an instance of the RenderScript, pointing it to the bytecode resource script = ScriptC_point(myRenderScript/*, resources, R.raw.example*/) // bind the struct and int pointers to the RenderScript script.bind_touchPoints(touchPoints) script.bind_intPointer(intPointer) ... }
Java
private RenderScript myRenderScript; private ScriptC_example script; private Resources resources; public void init(RenderScript rs, Resources res) { myRenderScript = rs; resources = res; // allocate memory for the struct pointer, calling the constructor ScriptField_Point touchPoints = new ScriptField_Point(myRenderScript, 2); // Create an element manually and allocate memory for the int pointer intPointer = Allocation.createSized(myRenderScript, Element.I32(myRenderScript), 2); // create an instance of the RenderScript, pointing it to the bytecode resource script = new ScriptC_example(myRenderScript, resources, R.raw.example); // bind the struct and int pointers to the RenderScript script.bind_touchPoints(touchPoints); script.bind_intPointer(intPointer); ... }
यादों को पढ़ना और लिखना
आपके पास RenderScript रनटाइम, दोनों में स्टैटिक और डाइनैमिक तौर पर असाइन की गई मेमोरी को पढ़ने और उसमें बदलाव करने का विकल्प होता है और Android फ़्रेमवर्क लेयर.
स्टैटिक रूप से असाइन की गई मेमोरी, एकतरफ़ा कम्यूनिकेशन से जुड़ी पाबंदी के साथ मिलती है
RenderScript रनटाइम लेवल पर. जब RenderScript कोड किसी वैरिएबल की वैल्यू में बदलाव करता है, तो ऐसा नहीं होता
बेहतर परफ़ॉर्मेंस के लिए, Android फ़्रेमवर्क लेयर को वापस भेजा जाता है. आखिरी वैल्यू
जो Android फ़्रेमवर्क से सेट किया गया है, वह get
पर कॉल के दौरान हमेशा दिखता है
तरीका. हालांकि, जब Android फ़्रेमवर्क कोड किसी वैरिएबल में बदलाव करता है, तो उस बदलाव को
RenderScript रनटाइम अपने-आप या बाद में सिंक होता है. अगर आपको डेटा भेजने की ज़रूरत हो
RenderScript रनटाइम से लेकर Android फ़्रेमवर्क लेयर तक, आप
rsSendToClient()
फ़ंक्शन
इस सीमा को पार करने के लिए.
डाइनैमिक तौर पर असाइन की गई मेमोरी के साथ काम करते समय, RenderScript रनटाइम लेयर में कोई भी बदलाव लागू होता है Android फ़्रेमवर्क लेयर पर वापस जाएं. Android फ़्रेमवर्क लेयर में किसी ऑब्जेक्ट में बदलाव करने से, वह तुरंत RenderScript में बदल जाता है रनटाइम लेयर.
ग्लोबल वैरिएबल के हिसाब से पढ़ना और लिखना
ग्लोबल वैरिएबल के हिसाब से पढ़ना और लिखना, एक आसान प्रोसेस है. ऐक्सेसर के तरीके इस्तेमाल किए जा सकते हैं पर सेट कर सकते हैं या उन्हें सीधे RenderScript कोड में सेट कर सकते हैं. ध्यान रखें कि किसी आपने अपने RenderScript कोड में जो बदलाव किए हैं वे लागू नहीं होते हैं Android फ़्रेमवर्क लेयर पर वापस जाएँ (यहां देखें देखें).
उदाहरण के लिए, rsfile.rs
नाम की फ़ाइल में दिए गए इस स्ट्रक्चर का एलान किया गया है:
typedef struct Point { int x; int y; } Point_t; Point_t point;
इस तरह के स्ट्रक्चर के लिए, सीधे rsfile.rs
में वैल्यू असाइन की जा सकती हैं. ये मान नहीं हैं
इसे Android फ़्रेमवर्क लेवल पर वापस लागू किया जाएगा:
point.x = 1; point.y = 1;
इस तरह, Android फ़्रेमवर्क लेयर पर स्ट्रक्चर के लिए वैल्यू असाइन की जा सकती हैं. ये वैल्यू हैं: RenderScript रनटाइम लेवल पर एसिंक्रोनस तरीके से वापस लागू किया जाता है:
Kotlin
val script: ScriptC_rsfile = ... ... script._point = ScriptField_Point.Item().apply { x = 1 y = 1 }
Java
ScriptC_rsfile script; ... Item i = new ScriptField_Point.Item(); i.x = 1; i.y = 1; script.set_point(i);
आप अपने रेंडर स्क्रिप्ट कोड में वैल्यू को इस तरह पढ़ सकते हैं:
rsDebug("Printing out a Point", point.x, point.y);
नीचे दिए गए कोड की मदद से, Android फ़्रेमवर्क लेयर में वैल्यू पढ़ी जा सकती हैं. ध्यान रखें कि इस कोड सिर्फ़ तब वैल्यू दिखाता है, जब Android फ़्रेमवर्क लेवल पर सेट किया गया हो. आपको एक शून्य पॉइंटर मिलेगा अपवाद के तौर पर, अगर आपने वैल्यू को सिर्फ़ RenderScript रनटाइम लेवल पर सेट किया है:
Kotlin
Log.i("TAGNAME", "Printing out a Point: ${mScript._point.x} ${mScript._point.y}") println("${point.x} ${point.y}")
Java
Log.i("TAGNAME", "Printing out a Point: " + script.get_point().x + " " + script.get_point().y); System.out.println(point.get_x() + " " + point.get_y());
ग्लोबल पॉइंटर पढ़ना और लिखना
यह मानते हुए कि मेमोरी को Android फ़्रेमवर्क लेवल में बांटा गया है और यह RenderScript रनटाइम से जुड़ा हुआ है,
उस पॉइंटर के लिए get
और set
तरीकों का इस्तेमाल करके, Android फ़्रेमवर्क लेवल से मेमोरी को पढ़ा और लिखा जा सकता है.
RenderScript रनटाइम लेयर में, आप सामान्य रूप से पॉइंटर के साथ मेमोरी में पढ़ और लिख सकते हैं और बदलाव लागू हो जाते हैं
इसमें हम Android फ़्रेमवर्क लेयर पर वापस जा सकते हैं. यह स्टैटिक तरीके से असाइन की गई मेमोरी से अलग होता है.
उदाहरण के लिए, rsfile.rs
नाम की फ़ाइल में struct
का यह पॉइंटर दिया गया है:
typedef struct Point { int x; int y; } Point_t; Point_t *point;
मान लें कि आपने Android फ़्रेमवर्क लेयर में पहले ही मेमोरी असाइन कर दी है, तो
struct
सामान्य रूप से. इसके पॉइंटर वैरिएबल की मदद से, स्ट्रक्चर में किया जाने वाला कोई भी बदलाव
ये टूल, Android फ़्रेमवर्क लेयर में अपने-आप उपलब्ध हो जाते हैं:
Kotlin
point[index].apply { x = 1 y = 1 }
Java
point[index].x = 1; point[index].y = 1;
Android फ़्रेमवर्क लेयर पर, पॉइंटर पर वैल्यू को पढ़ा और लिखा जा सकता है:
Kotlin
val i = ScriptField_Point.Item().apply { x = 100 y = 100 } val p = ScriptField_Point(rs, 1).apply { set(i, 0, true) } script.bind_point(p) p.get_x(0) //read x and y from index 0 p.get_y(0)
Java
ScriptField_Point p = new ScriptField_Point(rs, 1); Item i = new ScriptField_Point.Item(); i.x=100; i.y = 100; p.set(i, 0, true); script.bind_point(p); p.get_x(0); //read x and y from index 0 p.get_y(0);
जब मेमोरी पहले ही बाउंड हो जाए, तो आपको मेमोरी को RenderScript के साथ फिर से बाइंड करने की ज़रूरत नहीं है हर बार वैल्यू में बदलाव करने पर, रनटाइम दिखता है.