1

RenderScript 中的反射类包含执行内核的函数。这些函数遵循输出参数范式——它们的参数之一是存储输出的分配。

有没有理由比返回输出分配更好的做法?(我应该效仿并在与 RenderScript 相关的函数中使用参数吗?)

例如,我实现了以下帮助类,它包装ScriptC_gradient并计算位图的渐变。它可以从输入分配推断输出分配应该具有什么类型,从而隐藏设置目标分配所需的样板。是否有理由更喜欢一种实现而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

是的,更喜欢使用传入分配输出的方法的原因是内存重用。创建分配是昂贵的,不应该做超过必要的事情。

第二种方法也会导致“平铺”问题,在这种情况下,您执行多个内核启动以每次填充输出分配的一部分。因为每次先前的内容丢失(或必须复制)时,都会重新分配输出。

于 2013-11-14T19:22:17.370 回答