RenderScript'i kullanan uygulamalar hâlâ Android sanal makinesi içinde çalıştığından, aşina olduğunuz tüm çerçeve API'lerine erişebilirsiniz ancak ve uygun durumlarda RenderScript'i kullanmalısınız. Proje yöneticileri arasındaki bu etkileşimi kolaylaştırmak çerçeveyi ve RenderScript çalışma zamanını, ara kod katmanını da iki kod düzeyi arasındaki iletişimi ve bellek yönetimini kolaylaştırmak için kullanılır. Bu belgede, bu riskler hakkında ve belleğin Android sanal makinesi ile Android sanal makinesi arasında nasıl RenderScript çalışma zamanı.
RenderScript Çalışma Zamanı Katmanı
RenderScript kodunuz derlenir ve iyi tanımlanmış bir çalışma zamanı katmanında yürütülmesini sağlar. RenderScript çalışma zamanı API'leri, yoğun hesaplama imkanı sunar. mevcut çekirdek sayısını ifade eder.
Not: NDK'daki standart C işlevleri CPU üzerinde çalışacağı garanti edildiği için RenderScript bu kitaplıklara erişemez. çünkü RenderScript farklı işlemci türlerinde çalışacak şekilde tasarlanmıştır.
RenderScript kodunuzu .rs
içinde tanımlarsınız
ve Android projenizin src/
dizininde .rsh
dosya yer alıyor. Kod
tarafından ara bayt koduna
Android derlemesinin parçası olarak çalışan llvm
derleyici. Uygulamanız
çalıştırıldığında, bayt kodu başka bir cihaz tarafından makine koduna derlenir (tam zamanında)
Cihazda bulunan llvm
derleyicisi. Makine kodu, varsayılan olarak
hem de önbelleğe alınmış bir uygulamadır. Böylece, RenderScript kullanan uygulamanın sonraki kullanımlarında
bayt kodunu yeniden derleyin.
RenderScript çalışma zamanı kitaplıklarının bazı temel özellikleri şunlardır:
- Bellek ayırma isteği özellikleri
- Hem skaler hem de vektör türünde aşırı yüklenmiş sürümlere sahip büyük bir matematik fonksiyonları koleksiyonu vazgeçilmez bir parçasıdır. Toplama, çarpma, nokta çarpımı ve çapraz çarpım gibi işlemler atomik aritmetik ve karşılaştırma fonksiyonlarının yanı sıra mevcuttur.
- Temel veri türleri ve vektörler, matris rutinleri ile tarih ve saat için dönüşüm rutinleri rutinler
- RenderScript sistemini destekleyecek veri türleri ve yapıları (örneğin, iki, üç veya dört vektörü tanımladık.
- İşlevleri günlüğe kaydetme
Kullanılabilir işlevler hakkında daha fazla bilgi için RenderScript çalışma zamanı API'si referansına bakın.
Yansıtılan Katman
Yansıtılan katman, Android derleme araçlarının erişime izin vermek için oluşturduğu sınıf kümesidir Android çerçevesinden RenderScript çalışma zamanına geçireceğiz. Bu katman aynı zamanda, ve oluşturucuları kullanarak, burada tanımlanan işaretçiler için bellek ayırmanıza ve bu bellekle çalışmanıza olanak bir kod snippet'i ekleyin. Aşağıdaki listede en önemli yansıtılan bileşenler:
- Oluşturduğunuz her
.rs
dosyası,project_root/gen/package/name/ScriptC_renderscript_filename
/ScriptC
yazın. Bu dosya,.java
.rs
dosyası oluşturun. Bu dosyayı Android çerçevesinden çağırabilirsiniz. Bu sınıf şunu içeriyor:.rs
dosyasından yansıtılan şu öğeler:- Statik olmayan işlevler
- Statik olmayan, genel RenderScript değişkenleri. Erişen
yöntem oluşturulur. Böylece, bu verileri okuyabilir ve
Android'deki RenderScript değişkenlerini
bahsedeceğim. Bir genel değişken
RenderScript çalışma zamanı katmanında, bu değerler kullanılarak
Android çerçevesinde karşılık gelen değerleri başlat
katmanıdır. Genel değişkenler
const
olarak işaretlenirseset
yöntemi elde edilir. Buraya bakın inceleyebilirsiniz. - Global işaretçiler
- Bir
struct
, adlı kendi sınıfına yansıtılırproject_root/gen/package/name/ScriptField_struct_name
,Script.FieldBase
uzatılır. Bu sınıf,struct
, bu değer, bu öğenin bir veya daha fazla örneği için bellek ayırmanızı sağlarstruct
Fonksiyonlar
İşlevler komut dosyası sınıfının kendisine yansıtılır:
project_root/gen/package/name/ScriptC_renderscript_filename
Örneğin,
Örneğin, RenderScript kodunuzda aşağıdaki işlevi tanımlarsanız:
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; }
aşağıdaki Java kodu oluşturulur:
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 sistemi şunu kullanacak şekilde tasarlandığından, işlevlerin döndürülen değerleri olamaz: eşzamansız. Android çerçeve kodunuz RenderScript'i çağırdığında, çağrı sıraya alınır ve yürütmelerini de sağlar. Bu kısıtlama, RenderScript sisteminin sabit değer olmadan çalışmasına olanak sağlar kesintilere neden olur ve verimliliği artırır. İşlevlerin değer döndürmesine izin verildiyse çağrı olması için değer döndürülene kadar engellenir.
RenderScript kodunun Android çerçevesine geri bir değer göndermesini isterseniz
rsSendToClient()
işlevini kullanın.
Değişkenler
Desteklenen türlerin değişkenleri,
project_root/gen/package/name/ScriptC_renderscript_filename
Erişimci grubu
yöntem oluşturulur. Örneğin, aşağıdaki değişkeni
RenderScript kodunuz:
uint32_t unsignedInteger = 1;
aşağıdaki Java kodu oluşturulur:
private long mExportVar_unsignedInteger; public void set_unsignedInteger(long v){ mExportVar_unsignedInteger = v; setVar(mExportVarIdx_unsignedInteger, v); } public long get_unsignedInteger(){ return mExportVar_unsignedInteger; }
Yapılar
Yapılar kendi sınıflarına yansıtılır:
<project_root>/gen/com/example/renderscript/ScriptField_struct_name
Bu
class, bir struct
dizisini temsil eder ve bir öğe için bellek ayırmanıza
belirtilen sayıda struct
. Örneğin, aşağıdaki struct'ı tanımlarsanız:
typedef struct Point { float2 position; float size; } Point_t;
aşağıdaki kod ScriptField_Point.java
içinde oluşturulur:
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 */); } }
Oluşturulan kod, istenen struct'lar için bellek tahsisi sağlamak amacıyla size sağlanır
ve struct
s ile etkileşim kurmak için RenderScript çalışma zamanına göre
inceleyebilirsiniz. Her struct
sınıfı, aşağıdaki yöntemleri ve oluşturucuları tanımlar:
- Bellek ayırmanızı sağlayan aşırı yüklenmiş oluşturucular. İlgili içeriği oluşturmak için kullanılan
ScriptField_struct_name(RenderScript rs, int count)
oluşturucu kullanarak bellek ayırmak istediğiniz yapıların sayısınıcount
parametresinden yararlanın.ScriptField_struct_name(RenderScript rs, int count, int usages)
oluşturucusu, ek bir parametre (usages
) tanımlar. bu bellek ayırmanın bellek alanını belirtmenizi sağlar. Dört bellek alanı vardır olanaklar:USAGE_SCRIPT
: Komut dosyası belleğinde ayırma boşluk oluşturur. Bu, bir bellek alanı belirtmezseniz varsayılan bellek alanıdır.USAGE_GRAPHICS_TEXTURE
: GPU'nun doku bellek alanını kullanır.USAGE_GRAPHICS_VERTEX
: Köşede paylaştırır GPU'nun bellek alanını kullanır.USAGE_GRAPHICS_CONSTANTS
: program nesneleri tarafından kullanılan GPU'nun sabit bellek alanı
Bit tabanlı
OR
operatörünü kullanarak birden fazla bellek alanı belirtebilirsiniz. İşlem devam ediyor içindeki verilere erişmeyi düşündüğünüz RenderScript çalışma zamanını bildirir. belirtilen bellek alanları. Aşağıdaki örnek, özel bir veri türü için bellek ayırıyor hem komut dosyası hem de tepe noktası bellek alanlarında kullanabilirsiniz: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);
- İç içe yerleştirilmiş statik bir sınıf (
Item
),struct
, bir nesne biçimindedir. İç içe yerleştirilmiş bu sınıf, çalışmak daha mantıklı olduğunda kullanışlıdır. Android kodunuzdakistruct
ile. Nesneyi değiştirmeyi tamamladığınızda,set(Item i, int index, boolean copyNow)
öğesini çağırıpItem
öğesini gösterir. RenderScript çalışma zamanı, yeni yazılan belleğe otomatik olarak erişir. - Bir struct'taki her alanın değerlerini almak ve ayarlamak için kullanılan erişimci yöntemleri. Bunların her biri
erişimci yöntemlerinde
struct
belirtmek için birindex
parametresi bulunur diziyi seçebilirsiniz. Her belirleme yöntemi aynı zamanda Bu belleğin hemen senkronize edilip edilmeyeceğini belirtencopyNow
parametresi gönderir. Senkronize edilmemiş herhangi bir hafızayı senkronize etmek için şu numarayı arayın:copyAll()
createElement()
yöntemi, bellekteki struct'ın bir açıklamasını oluşturur. Bu açıklama, bir veya daha fazla öğeden oluşan belleği ayırmak için kullanılır.resize()
, C dilindekirealloc()
işlevine çok benzer. önceki değerleri koruyarak önceden ayrılmış belleği genişlet oluşturuldu.copyAll()
, çerçeve düzeyinde ayarlanan belleği RenderScript çalışma zamanı. Bir üyede ayarlanan erişimci yöntemini çağırırken isteğe bağlı bir BelirtebileceğinizcopyNow
boole parametresi. Belirtmetrue
, yöntemi çağırdığınızda belleği senkronize eder. Yanlış değerini belirtirsenizcopyAll()
öğesini bir kez çağırabilirsiniz. Bu çağrı, tüm özellikleri olabilir.
İşaretçiler
Genel işaretçiler, buradaki komut dosyası sınıfının kendisine yansıtılır:
project_root/gen/package/name/ScriptC_renderscript_filename
Siz
bir struct
veya desteklenen RenderScript türlerinden herhangi birine işaretçiler tanımlayabilir, ancak
struct
, işaretçiler veya iç içe yerleştirilmiş diziler içeremez. Örneğin,
aşağıdaki işaretçileri struct
ve int32_t
typedef struct Point { float2 position; float size; } Point_t; Point_t *touchPoints; int32_t *intPointer;
aşağıdaki Java kodu oluşturulur:
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; }
Bir get
yöntemi ve bind_pointer_name
adlı özel bir yöntem
(set()
yöntemi yerine) oluşturulur. bind_pointer_name
yöntemi, belleği bağlamanızı sağlar
RenderScript çalışma zamanına ayrılmış (
hafızaya (.rs
dosyanız) ekleyin. Daha fazla bilgi için bkz. Çalışmalar
içe aktarılmalıdır.
Bellek Ayırma API'leri
RenderScript kullanan uygulamalar yine Android sanal makinesinde çalışır. Ancak gerçek RenderScript kodu yerel olarak çalışır ve
Android sanal makinesinde ayrılan belleğe erişmesi gerekir. Bunu başarmak için şunları yapmanız gerekir:
sanal makinede ayrılan belleği RenderScript çalışma zamanına ekler. Bu
işlemi, RenderScript çalışma zamanının mevcut bellekle sorunsuz bir şekilde
ancak açıkça tahsis edilemez. Nihai sonuç, daha önce
C dilinde malloc
olarak adlandırıldı. Ek avantaj, Android sanal makinesinin hem atık toplama hem de
ilgili bellekten yararlanılabilir. Bağlama işlemi yalnızca dinamik olarak ayrılmış bellek için gereklidir. Statik olarak
oluşturulan bellek derleme sırasında RenderScript kodunuz için otomatik olarak oluşturulur. Bkz. Şekil 1
bakın.
Bu bellek ayırma sistemini desteklemek için Android sanal makinesinin şunları yapmasına olanak tanıyan bir dizi API vardır:
Belleği ayırabilir ve malloc
çağrısına benzer işlevler sunabilir. Bu sınıflar
belleğin nasıl ayrılması gerektiğini açıklar ve ayırma yapar. Daha iyi
nasıl çalıştığını anlamak için bu sınıfları, basit bir model yerine
malloc
çağrısı şöyle görünebilir:
array = (int *)malloc(sizeof(int)*10);
malloc
çağrısı iki bölüme ayrılabilir: Ayrılan belleğin boyutu (sizeof(int)
),
ve o belleğin kaç birimin ayrılması gerektiğini (10) gösterir. Android çerçevesi bu iki bölüm için aşağıdaki sınıfları sağlar:
ve malloc
kendisini temsil edecek bir sınıf içerir.
Element
sınıfı, (sizeof(int)
) bölümünü temsil eder.
malloc
çağrısının örneğidir ve bellek ayırmanın bir hücresini (örneğin, tek bir
kayan noktalı değer veya struct. Type
sınıfı Element
etiketini kapsar
ve ayrılacak öğe miktarı (örneğimizde 10). Type
kavramını
Element
dizisidir. Allocation
sınıfı şunları yapar:
belirli bir Type
öğesine göre bellek tahsisi ve ayrılan gerçek belleği temsil eder.
Çoğu durumda bu bellek ayırma API'lerini doğrudan çağırmanız gerekmez. Yansıtılan katman
sınıfları, bu API'leri otomatik olarak kullanmak için kod oluşturur. Bellek tahsis etmek için tek yapmanız gereken,
yansıtılan katman sınıflarından birinde bildirilen ve ardından bağlayan kurucu
oluşturulan belleği RenderScript'e Allocation
.
Bazı durumlarda, doğrudan depolama alanınızda bellek tahsisi için bu sınıfları
mesela bir kaynaktan bit eşlem yüklediğinizde veya işaretçiler için
temel türler. Bunu nasıl yapacağınızı
RenderScript'e bellek ayırma ve bağlama bölümü.
Aşağıdaki tabloda üç bellek yönetimi sınıfı daha ayrıntılı olarak açıklanmaktadır:
Android Nesne Türü | Açıklama |
---|---|
Element |
Bir öğe, bellek ayırmadaki bir hücreyi tanımlar ve iki biçimde olabilir: temel veya karmaşıktır. Temel öğe, herhangi bir geçerli RenderScript veri türünün tek bir veri bileşenini içerir.
Temel öğe veri türlerine örnek olarak tek bir Karmaşık öğeler, temel öğelerin bir listesini içerir ve aşağıdakilerden oluşturulur
|
Type |
Tür, bir bellek ayırma şablonudur ve bir öğe ile bir veya daha fazla öğeden oluşur
seçin. Belleğin düzenini (temel olarak Bir tür, beş boyuttan oluşur: X, Y, Z, LOD (ayrıntı seviyesi) ve Yüzler (bir küpün) haritası). X,Y,Z boyutlarını kısıtlanabilir. Tek boyut ayırmanın X boyutu şudur: değeri sıfırdan büyük, Y ve Z boyutları ise sıfır olarak ayarlanır. Örneğin, Örneğin, x=10, y=1 ayırması iki boyutlu olarak kabul edilir ve x=10, y=0 ise tek boyutlu kabul edilir. LOD ve Yüzler boyutları, mevcut olduğunu gösteren boole değerleridir olup olmadığını kontrol edin. |
Allocation |
Ayırma, belleğin açıklamasına göre uygulamalar için bellek sağlar
Ayırma verileri iki temel yöntemden biriyle yüklenir: Tür işaretli ve tür işareti kaldırıldı.
Basit diziler için |
Bellek ile Çalışma
RenderScript'inizde bildirdiğiniz statik olmayan, genel değişkenlere derleme sırasında bellek ayrılır.
Bu değişkenlerle herhangi bir ayırma işlemi yapmanıza gerek kalmadan doğrudan RenderScript kodunuzda çalışabilirsiniz.
Android çerçevesi düzeyinde
yapabilirsiniz. Android çerçeve katmanı da bu değişkenlere erişebilir
işlemini, yansıtılan katman sınıflarında oluşturulan sağlanan erişimci yöntemleriyle değiştirin. Bu değişkenler
ilk kullanıma sunulduğunda bu değerler, ilgili komut dosyasını
değerlerini daha iyi
anlatacağım. Genel değişkenler const olarak işaretlenirse set
yöntemi
oluşturulmadı. Daha fazla bilgi için buraya bakın.
Not: Örneğin,
rs_program_fragment
ve rs_allocation
için öğenin bir nesnesini edinmeniz
Bunun için önce karşılık gelen Android çerçeve sınıfını, ardından set
yöntemini çağırın
gereken temel yapıyı kullandığınızdan emin olun. Bu yapılara doğrudan müdahale edemezsiniz
iki kat daha fazla belirlenebilir. Bu kısıtlama, kullanıcı tanımlı yapılar için geçerli değildir
içeren bir katmandır. Çünkü bunlar, yansıtılan bir katman sınıfına aktarılamaz
en başta sunun. Statik olmayan, global bir kod bildirmeye çalışırsanız derleyici hatası oluşur.
struct'ı içerir.
RenderScript'in işaretçiler de desteği vardır ancak işaretleyiciyi
Android çerçeve kodu. .rs
dosyanızda global işaretçi bildirdiğinizde
yansıtılan uygun katman sınıfı aracılığıyla belleği ayırmak ve belleği
RenderScript katmanını kullanın. Bu bellekle Android çerçeve katmanından ve
RenderScript katmanını kullanarak, değişkenleri en hızlı şekilde değiştirme esnekliğine
katmanız gerekir.
Dinamik bellek ayırma ve RenderScript'e bağlama
Dinamik bellek ayırmak için
Script.FieldBase
sınıfını kullanır. Bu, en sık kullanılan yöntemdir. Alternatif olarak,
Allocation
manuel olarak oluşturulur. Bu, temel türden işaretçiler gibi işlemler için gereklidir. Şunları yapmalısınız:
kullanım kolaylığı sağlamak için Script.FieldBase
sınıf oluşturucusu kullanın.
Bir bellek tahsisi elde ettikten sonra, ayrılan belleğibind
RenderScript çalışma zamanı.
Aşağıdaki örnekte, bellek hem temel tür bir işaretçi hem de
intPointer
ve bir struct'ın işaretçisi touchPoints
. Bu ayrıca belleği
RenderScript:
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); ... }
Okuma ve hafızaya yazma
Hem RenderScript çalışma zamanında statik ve dinamik olarak ayrılmış bellek üzerinde okuma hem de yazma işlemi yapabilirsiniz. çerçeve katmanı içerir.
Statik olarak ayrılmış bellek tek yönlü iletişim kısıtlamasıyla birlikte gelir
aynı işlemi yapabilirsiniz. RenderScript kodu bir değişkenin değerini değiştirdiğinde,
tekrar Android'in çerçeve katmanına iletilecek. Son değer
Android çerçevesinden ayarlanan bir kod, get
çağrısı sırasında her zaman döndürülür
yöntemidir. Bununla birlikte, Android çerçevesi kodu bir değişkeni değiştirdiğinde bu değişiklik
otomatik olarak veya daha sonra senkronize edilir. Veri göndermeniz gerekiyorsa
farklı içerik türleri oluşturmak için
rsSendToClient()
işlevi
üzerine eğilmeniz gerek.
Dinamik olarak ayrılmış bellekle çalışırken RenderScript çalışma zamanı katmanındaki tüm değişiklikler bellek ayırmayı ilişkili işaretçisini kullanarak değiştirdiyseniz Android çerçeve katmanına geri dönebilirsiniz. Android çerçeve katmanındaki bir nesnede değişiklik yapıldığında, bu değişiklik hemen RenderScript'e geri döndürülür çalışma zamanı katmanı.
Genel değişkenlere okuma ve yazma
Global değişkenlere okuma ve yazma işlemleri basit bir süreçtir. Erişimci yöntemlerini kullanabilirsiniz veya bunları doğrudan RenderScript kodunda ayarlamanız gerekir. Herhangi bir RenderScript kodunuzda yaptığınız değişiklikler dağıtılmaz Android çerçeve katmanına dön (buraya bakın bakın).
Örneğin, aşağıdaki struct'ın rsfile.rs
adlı bir dosyada tanımlandığını varsayalım:
typedef struct Point { int x; int y; } Point_t; Point_t point;
struct'a doğrudan rsfile.rs
içinde bunun gibi değerler atayabilirsiniz. Bu değerler
Android çerçevesi düzeyine geri yayıldı:
point.x = 1; point.y = 1;
Android çerçeve katmanında struct'a değerler atayabilirsiniz. Bu değerler, RenderScript çalışma zamanı düzeyine eşzamansız olarak geri uygulanır:
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);
RenderScript kodunuzdaki değerleri şu şekilde okuyabilirsiniz:
rsDebug("Printing out a Point", point.x, point.y);
Android çerçevesi katmanındaki değerleri aşağıdaki kodla okuyabilirsiniz. Bu kodu yalnızca Android çerçevesi düzeyinde ayarlanmışsa değer döndürür. Boş bir işaretçi alacaksınız Örneğin, değeri yalnızca RenderScript çalışma zamanı düzeyinde ayarladıysanız:
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());
Global işaretçileri okuma ve yazma
Belleğin Android çerçevesi düzeyinde ayrıldığı ve RenderScript çalışma zamanına bağlı olduğu varsayıldığında,
söz konusu işaretçi için get
ve set
yöntemlerini kullanarak Android çerçevesi düzeyinden belleği okuyabilir ve yazabilirsiniz.
RenderScript çalışma zamanı katmanında, işaretçileri kullanarak belleğe normal bir şekilde okuma ve yazma işlemi yapabilirsiniz ve değişiklikler yayılır.
istatistiksel olarak ayrılmış belleğin aksine
Android çerçeve katmanına geri dönebilir.
Örneğin, aşağıdaki işaretçi rsfile.rs
adlı bir dosyadaki struct
öğesinin üzerine getirildiğinde:
typedef struct Point { int x; int y; } Point_t; Point_t *point;
Android çerçeve katmanında bellek ayırdığınızı varsayarsak değerlere
struct
her zamanki gibi. struct'ta işaretçi değişkeni aracılığıyla yaptığınız değişiklikler
otomatik olarak Android çerçeve katmanında kullanılabilir:
Kotlin
point[index].apply { x = 1 y = 1 }
Java
point[index].x = 1; point[index].y = 1;
Ayrıca, Android çerçeve katmanındaki işaretçiye değer yazabilir ve yazabilirsiniz:
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);
Bellek halihazırda bağlandıktan sonra, belleği RenderScript'e yeniden bağlamanız gerekmez değeri her değiştirdiğinizde çalışma zamanı oluşturur.