Renderscript致命信号11(代码= 1)

时间:2014-06-30 20:30:14

标签: android renderscript

在我的项目中,我采用15x15的随机颜色位图,并确定每个像素与其他像素的区别。

调用Distinct.start()时,出现以下错误:

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

从我能够找到的信号11可以看出我试图非法访问内存,但我无法找到它的位置。我甚至尝试从脚本中删除所有内容,除了结果的实例化并返回它。

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

    }

1 个答案:

答案 0 :(得分:4)

您的错误来自:

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

您假设位图的布局允许您以这种方式对其进行索引,但这实际上是未定义的行为。您应该为rsGetElementAt()的x和y部分使用适当的索引。我还建议你切换到性能更高的rsGetElementAt_uchar4()函数(对于所有的原始/矢量类型都存在这样的帮助器)。此函数将直接返回uchar4,因此无需转换指针并取消引用它。

我的另一个建议是尝试使用调试运行时来发现这些边界错误。只需将标志添加到上面的create()调用中:

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

错误/警告将显示在adb logcat下。