1

RenderScript のリフレクション クラスには、カーネルを実行する関数が含まれています。これらの関数は、out 引数パラダイムに従います。引数の 1 つは、出力が格納される割り当てです。

これが出力割り当てを返すよりも良い方法である理由はありますか? (RenderScript 関連の関数で out 引数を使用して、スーツに従う必要がありますか?)

たとえばScriptC_gradient、ビットマップのグラデーションをラップして計算する次のヘルパー クラスを実装しました。入力 Allocation から、出力 Allocation が持つべきタイプを推測できるため、宛先 Allocation を設定するために必要なボイラープレートを非表示にできます。ある実装を他の実装より優先する理由はありcompute()ますか?

public class Gradient {
    private RenderScript mRS;
    private ScriptC_gradient mScript;

    public Gradient(RenderScript RS) {
        mRS = RS;
        mScript = new ScriptC_gradient(mRS);
    }
    /* Out-argument implementation
     * 
     * This closely mirrors RenderScript's kernel functions, but
     * it requires the caller to write boilerplate to set up the 
     * destination Allocation.
     */
    public void compute(Allocation elevation, Allocation gradient) {
        mScript.invoke_setDimensions(elevation);
        mScript.forEach_root(elevation, gradient);
    }
    /* Allocation-returning implementation
     * 
     * This hides the boilerplate. 
     */
    public Allocation compute(Allocation elevation) {
        Allocation gradient = Allocation.createTyped(mRS, 
                new Type.Builder(mRS,Element.F32_2(mRS))
                   .setX(elevation.getType().getX())
                   .setY(elevation.getType().getY())
                   .create(),
                Allocation.USAGE_SCRIPT);
        mScript.invoke_setDimensions(elevation);
        mScript.forEach_root(elevation, gradient);
        return gradient;
    }
4

1 に答える 1

3

はい、出力の割り当てで渡されたアプローチを好む理由は、メモリの再利用です。割り当ての作成はコストがかかるため、必要以上に行うべきではありません。

2 番目の方法では、複数のカーネルを起動してそれぞれが出力割り当ての一部を埋める「タイリング」でも問題が発生します。以前の内容が失われる (またはコピーする必要がある) たびに、出力が再割り当てされるためです。

于 2013-11-14T19:22:17.370 に答える