私の調査によると、RenderScript 内からメモリを割り当てることはできないことがわかりました。たとえばint* values = new int[10];
、C99 では許可されていません。この配列が処理中の現在のピクセルに対してのみローカルであるようにしたいと思います。このような動的割り当ては、カーネル関数内で宣言およびインスタンス化されている場合に保証されます。
私はそれint values[10];
が有効な宣言であることを知っています。これを RenderScript の先頭に配置すると、グローバル配列になり、Java コードから ( を使用してAllocation
) 設定できるようになります。
int values[10];
現在のピクセルに対してローカルであると想定したカーネルの中に入れてみました。単一値の変数 (uint32_t、float4 など) を宣言することは、現在のピクセルに対して確実にローカルであることを知っています。ただし、カーネル内で宣言された配列は依然としてグローバル変数であり、他のすべてのピクセルはそれから読み書きできます。
uchar4 RS_KERNEL mykernel(uchar4 in, uint32_t x, uint32_t y){
int* values = (int*)malloc(sizeof(int)*256); // illegal
int* values2 = new int[256]; // illegal
int values3[256]; // legal, but it's global. I want a local array
}
ご参考までに、現在のピクセル (x, y) から隣接するピクセルにアクセスしたいと思います。それを引っ張ることができました。ただし、最も頻繁に発生する色成分、その配列が並べ替えられた後の正確な中間成分などを選択する必要がある場合があるため、いくつかのピクセル情報 (隣接するピクセルの色成分のそれぞれのようなもの) を配列に格納する必要があります。 . だから、私はモード フィルタとメジアン フィルタ、さらには油絵効果を取得しようとしています - これらはすべて、ローカル配列に隣接するピクセル データを格納する必要があります。
では、RenderScript でローカル/プライベート配列を宣言するにはどうすればよいでしょうか?現在処理中のピクセルだけが触れることができます。それが不可能な場合、単一値変数のみを使用してタスクを必要とするローカル配列をシミュレートするにはどうすればよいですか?
アップデート
上記int values3[256];
は確かに現在のスレッドに対してローカルです。望ましくないゴミの値が含まれている可能性があることがわかりました。デフォルトでは、各インデックスの値は 0 であると仮定しました。ある人もいれば、そうでない人もいます。そのため、他のすべてのスレッドがそれに書き込みを行っていると思いました。上記を集計するつもりだったので、期待どおりに常に 0 から開始するとは限りませんでした。それが私の計算が外れていた理由です!