Renderscript Fatal Signal 11 (code = 1)

0

In my project I am taking a 15x15 bitmap of random colors and determining how distinct each is from each other pixel.

When Distinct.start() is called, I get the following error:

A/libc(18416): Fatal signal 11 (SIGSEGV) at 0x00000038 (code=1), thread 18538 (AsyncTask #1)

From what I've been able to find, signal 11 indicates that I tried to illegally access memory, but I can't find where that might be. I even tried removing everything from the script except the instantiation of result and returning it.

distinct.rs:

#pragma version(1)
#pragma rs java_package_name(com.moffitj.horizon)
#pragma rs_fp_relaxed

rs_allocation image;
int imgSize;
int side;


float __attribute__((kernel)) root(float in, uint32_t x, uint32_t y){

    //where we'll store the cumulative distance for the current pixel
    float result = 0.0f;

    //Pull the current pixel and unpack it's componants
    const uchar4 current = *(const uchar4*)rsGetElementAt(image, (y * side) + x, 0);
    float4 currentPixel = rsUnpackColor8888(current);

    //find how distinct the current pixel is from all others (and self, to save a branch)
    for(int i = 0; i < imgSize; i++){

        //get the next pixel and uppack it
        const uchar4 pixel = *(const uchar4*)rsGetElementAt(image, i, 0);
        float4 unpackedPixel = rsUnpackColor8888(pixel);

        //compare the distance between the two pixels
        float4 temp = sqrt(pow(currentPixel - unpackedPixel,2));

        //add the difference to the running total
        result += (temp.w + temp.x + temp.y + temp.z);
    }

    result /= imgSize;

    return result;

}

distinct.java:

public class Distinct {

    private Allocation mBitmapAllocation;
    private Allocation mReferenceAllocation;
    private Allocation mResultAllocation;
    private int mImgSize;
    private int mNumBlocks;
    private RenderScript mRS;
    private Context mContext;
    private ScriptC_distinct mScript;
    private Bitmap mBitmap;

    /**
     * 
     * @param bitmap
     * @throws IllegalArgumentException if the bitmap is not square or divisible by 64
     */
    public Distinct(Bitmap bitmap, Context context) throws IllegalArgumentException {

        mBitmap = bitmap;
        mContext = context;
        mImgSize = bitmap.getHeight() * bitmap.getWidth();
        mRS = RenderScript.create(mContext);
        mBitmapAllocation = Allocation.createFromBitmap(mRS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);

        Type.Builder referenceBuilder = new Type.Builder(mRS, Element.F32(mRS));//Dummy data won't be used, just to get location once inside script
        referenceBuilder.setX(bitmap.getWidth());
        referenceBuilder.setY(bitmap.getHeight());
        Type type = referenceBuilder.create();

        mReferenceAllocation = Allocation.createTyped(mRS, type, Allocation.USAGE_SCRIPT);

        Type.Builder resultBuilder = new Type.Builder(mRS, Element.F32(mRS));
        resultBuilder.setX(bitmap.getWidth());
        resultBuilder.setY(bitmap.getHeight());
        Type resultType = resultBuilder.create();

        mResultAllocation = Allocation.createTyped(mRS, resultType, Allocation.USAGE_SCRIPT);       

        /*Type.Builder imgTypeBuilder = new Type.Builder(mRS, Element.I32(mRS));
        imgTypeBuilder.setX(mImgSize * mImgSize);
        imgTypeBuilder.setY(1);
        Type imgType = imgTypeBuilder.create();

        mBitmapAllocation = Allocation.createTyped(mRS, imgType, Allocation.USAGE_SCRIPT);*/

        mScript = new ScriptC_distinct(mRS, mContext.getResources(), R.raw.average);
        mScript.set_image(mBitmapAllocation);
        mScript.set_imgSize(mImgSize);
        mScript.set_side(bitmap.getHeight());

    }

    public void start(){

        mScript.forEach_root(mReferenceAllocation, mResultAllocation);

    }
android
renderscript
asked on Stack Overflow Jun 30, 2014 by John Moffitt

2 Answers

4

Your error comes in at:

rsGetElementAt(image, (y * side) + x, 0);

You are assuming that the layout of the bitmap allows you to index it this way, but that is actually undefined behavior. You should be using an appropriate index for both the x and y parts of the rsGetElementAt(). I also will suggest that you switch to the higher performance rsGetElementAt_uchar4() function (helpers like this exist for all of the primitive/vector types). This function will return a uchar4 directly, so no need to cast a pointer and dereference it.

One other suggestion I have is to try using the debug runtime to spot these bounds errors. Just add the flag to your create() call above:

RenderScript.create(mContext, RenderScript.ContextType.DEBUG);

Errors/warnings will show up under adb logcat.

answered on Stack Overflow Jun 30, 2014 by Stephen Hines
0

In my haste I copied a working solution from another project and missed updating a line.

 mScript = new ScriptC_distinct(mRS, mContext.getResources(), R.raw.average);

should have been changed to

mScript = new ScriptC_distinct(mRS, mContext.getResources(), R.raw.distinct);
answered on Stack Overflow Jul 20, 2014 by John Moffitt

User contributions licensed under CC BY-SA 3.0