Settembrini
Settembrini

Reputation: 1386

RenderScript instability encountered in API 23

My app uses a proprietary implementation of Canny edge detection based on RenderScript. I tested this on numerous devices with various APIs and it worked very reliably. Now I got the new Samsung S7 working on API23. Here (and only here) I encountered a rather ugly problem. Some of the edge pictures are studded with thousands of artifacts that stem from the Magnitude gradient calculation kernel and are NOT based on actual image information. After trying with all kind of TargetAPIs, taking renderscript.support.mode on and off, etc. I finally found that the problem only arises, when the RenderScript (and Script) instances are used for the second or more times. It does not arise when using them for the first time.

For efficiency reasons I created the RenderScript and Script instances only once in the onCreate method of MainActivity and used it repeatedly thereafter. Of course I don't like to change that.

Does anyone have a solution of this problem? Thanks.

UPDATE: Crazy things are going on here. It seems that freshly created Allocations are NOT empty from the outset! When running:

    Type.Builder typeUCHAR1 = new Type.Builder(rs, Element.U8(rs));
    typeUCHAR1.setX(width).setY(height);
    Allocation alloc = Allocation.createTyped(rs, typeUCHAR1.create());

    byte se[] = new byte[width*height];
    alloc.copyTo(se);

    for (int i=0;i<width*height;i++){
        if (se[i]!=0){
            Log.e("content: ", String.valueOf(se[i]));
        }
    }

... the byte Array se is full of funny numbers.... HELP! Any idea, what is going on here?

UPDATE2: I stumbled over my own ignorance here - and really don't deserve a point for this masterpiece.... However, to my defense I must say that the problem was slightly more subtle that it appears here. The context was, that I needed to assign a global allocation (Byte/U8) which initially should be empty (i.e. zero) and then, within the kernel getting partially set to 1 (only where the edges are) via rsSetElementAt_uchar(). Since this worked for many months, I was not aware anymore of the fact, that I didn't explicitely assign the zeros in this allocation.... This only had consequences in API 23, so maybe this can help others not to fall into this trap.... So, note: other than numerical Arrays that are filled with 0 (as by Java default), Allocations cannot assumed to be full of zeros at initiation. Thanks, Sakridge.

Upvotes: 3

Views: 285

Answers (1)

sakridge
sakridge

Reputation: 578

Allocation data for primitive types (non-struct/object) is not initialized by default when an Allocation is created unless passed a bitmap using the createFromBitmap api. If you are expecting this then possibly you have a bug in your app which is not exposed when the driver initializes to 0s. It would help if you can post example code which reproduces the problem.

Initialize your allocations by copying from a bitmap or Java array.

Upvotes: 2

Related Questions