如何让Android Render Script Group工作?

时间:2014-01-18 04:45:00

标签: android renderscript

我可以让两个独立的内在函数工作,但不能在ScriptGroup中一起工作。我发现有关如何使用Script Group的文档非常稀疏。

这是我的代码:

        mRS = RenderScript.create(getActivity());

        mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
                Allocation.MipmapControl.MIPMAP_NONE,
                Allocation.USAGE_SCRIPT |
                        Allocation.USAGE_GRAPHICS_TEXTURE|
                        Allocation.USAGE_SHARED
        );

        mOutAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
                Allocation.MipmapControl.MIPMAP_NONE,
                Allocation.USAGE_SCRIPT |
                        Allocation.USAGE_SHARED);

        ScriptIntrinsicColorMatrix gray = ScriptIntrinsicColorMatrix.create(mRS, Element.U8_4(mRS));
        gray.setGreyscale();


        ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
        blur.setRadius(20.f);
        blur.setInput(mInAllocation);

        //gray.forEach(mInAllocation, mOutAllocation);
        blur.forEach(mOutAllocation);

        mOutAllocation.copyTo(mBitmapOut);

灰色和模糊都有效。然后我尝试将它们放在一起,结果是空白的。代码:

       // gray.forEach(mInAllocation, mOutAllocation);
       // blur.forEach(mOutAllocation);
       // mOutAllocation.copyTo(mBitmapOut);

        ScriptGroup.Builder builder = new ScriptGroup.Builder(mRS);

        builder.addKernel(gray.getKernelID());
        builder.addKernel(blur.getKernelID());

        builder.addConnection(mInAllocation.getType(), gray.getKernelID(), blur.getKernelID());

        ScriptGroup group = builder.create();

        group.setInput(gray.getKernelID(), mInAllocation);
        group.setOutput(blur.getKernelID(), mOutAllocation);

        group.execute();

        mOutAllocation.copyTo(mBitmapOut);

1 个答案:

答案 0 :(得分:4)

我能够重现您所看到的问题,并使用我之前使用内在函数的实验中的注释进行交叉检查。我认为renderscript内在函数代码中存在一些错误。

-1- 如果你想让一个使用内在函数的脚本组,下面的序列可以工作。

mBlur.setInput(mInAllocation);
sBuilder = new ScriptGroup.Builder(mRS);
sBuilder.addKernel(mBlur.getKernelID());
sBuilder.addKernel(mColor.getKernelID());
sBuilder.addConnection(connect, mBlur.getKernelID(),
                           mColor.getKernelID());

sGroup = sBuilder.create();
//  sGroup.setInput(mBlur.getKernelID(), mInAllocation); //See point 2
sGroup.setOutput(mColor.getKernelID(), mOutAllocation);
sGroup.execute();

mOutAllocation.copyTo(outBitmap);
mRS.finish();

-2- 请注意输入分配的传递方式。输入分配传递给mBlur.setInput()而不传递给sGroup.setInput()。如果使用了sGroup.setInput(),那么该组正确地找不到输入,并且它会导致以下错误,当然,我也没有在屏幕上看到转换后的图像。

E/RenderScript(12023): rsAssert failed: !"ScriptGroup:setInput kid not found", in frameworks/rs/rsScriptGroup.cpp at 267

在-1-的这个具体示例中,我在使用sGroup.setInput()而不是mBlur.setInput()

时遇到以下错误
E/RenderScript(12023): Blur executed without input, skipping

这似乎是renderscript中的错误

-3- 具体来说,在您的情况下,您希望在序列中使用ScriptIntrinsicBlur执行ScriptIntrinsicColorMatrix,还有另一个问题(不一定是错误)。虽然Blur内部有一个setInput函数,但colorMatrix确实有一个setInput函数。因此,您也不能使用-1-作为解决方法。

-4- 我认为renderscript中的正确修复将是弃用 intrinsic.setInput与ScriptIntrinsicColorMatrix一样普遍,并且在脚本组中使用intrinsics时可以使ScriptGroup.setInput正常工作。

-5- 当我拥有自己的内核时,我没有看到使用scriptgroup的任何问题。换句话说,scriptGroup.setInput()和scriptGroup.setOutput()完全正常