Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Android Render Script Group work?

I can get two separate intrinsics working, but not together in a ScriptGroup. I found document on how to use Script Group is extremely sparse.

Here is my code:

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);

Both gray and blur work. And then I tried putting them together, the result is blank. Code:

// 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);
like image 865
X.Y. Avatar asked Jan 18 '14 04:01

X.Y.


1 Answers

I was able to reproduce the issue you are seeing and cross checked with notes from my earlier experiments with intrinsics. I think there are a few bugs in renderscript intrinsics code.

-1- If you want to get a scripgroup working with intrinsics, the below sequence works.

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- Note the way how the input allocation is passed. The input allocation is passed to mBlur.setInput() and not to sGroup.setInput(). If sGroup.setInput() is used, then the group correctly does not find the input and it results in the following error and ofcourse, I dont see the transformed image on the screen as well.

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

In this specific example from -1-, I was getting the following errors as well the moment sGroup.setInput() is used instead of mBlur.setInput()

E/RenderScript(12023): Blur executed without input, skipping

This appears to be bug(s) in renderscript

-3- Specifically, in your case, where you want to do ScriptIntrinsicColorMatrix with ScriptIntrinsicBlur in a sequence, there is another issue (not necessarily a bug). While Blur intrinsic has a setInput function, colorMatrix does have a setInput function. So you cannot use -1- as a workaround as well.

-4- I think the right fixes in renderscript would to be to deprecate intrinsic.setInput universally just as it was done for ScriptIntrinsicColorMatrix and get ScriptGroup.setInput working while using intrinsics in a script group.

-5- I did not see any issues using scriptgroup, when I have my own kernels. In other words, scriptGroup.setInput() and scriptGroup.setOutput() work perfectly fine

like image 113
Mahesh Renduchintala Avatar answered Sep 18 '22 17:09

Mahesh Renduchintala