androidandroid-6.0-marshmallowrenderscriptnexus6android-renderscript

Renderscript image processign Nexus 6 Marshmallow issue


I am using renderscript for live image processing (camera preview). I am having an issue on Nexus 6 Marshmallow 6.1 where some of my scripts won't run for more than a couple of frames (rs kernel runs). Those same scripts work flawlessly on Nexus 4 Lollipop 5.1.

Symptoms: Script works for several runs (builds). On an nth run some script ceases to work as expected and all subsequent runs exhibit the above issue. I haven't been able to establish some particular operation in code which causes the issue. It appears completely random, at least from what I can gather.

What iv'e tried:

I am using this kernel signature uchar4 __attribute__((kernel)) filter(uchar4 v_in, uint32_t x, uint32_t y), although RS_KERNEL causes the same issue.

Thanks for any help and ideas.

Sample of affected code: (Google demo code from here: https://android.googlesource.com/platform/frameworks/rs/+/master/java/tests/ImageProcessing2/src/com/android/rs/image/)

static float sr = 0.f;
static float sg = 0.f;
static float sb = 0.f;

void prepareBwFilter(uint32_t rw, uint32_t gw, uint32_t bw) {

    sr = rw;
    sg = gw;
    sb = bw;

    float imageMin = min(sg,sb);
    imageMin = fmin(sr,imageMin);
    float imageMax = max(sg,sb);
    imageMax = fmax(sr,imageMax);
    float avg = (imageMin + imageMax)/2;
    sb /= avg;
    sg /= avg;
    sr /= avg;

}

void bwFilterKernel(const uchar4 *in, uchar4 *out) {
    float r = in->r * sr;
    float g = in->g * sg;
    float b = in->b * sb;
    float localMin, localMax, avg;
    localMin = fmin(g,b);
    localMin = fmin(r,localMin);
    localMax = fmax(g,b);
    localMax = fmax(r,localMax);
    avg = (localMin+localMax) * 0.5f;
    out->r = out->g = out->b = rsClamp(avg, 0, 255);
}

Solution

  • After quite a bit of research I decided that this is most probably a GPU driver issue. Having said that, I mentioned above that I tried removing #pragma rs_fp_relaxed which appeared to have solved the problem temporarily. I now believe that it was a gamble with the choice of fp precision RS was using and that that was the reason it sometimes worked and sometimes not. I came to this conclusion when i explicitly set #pragma rs_fp_full which seems to have fixed the issue permanently since it, along with native functions, should be a hardware backed calculation (so far works for all scripts that caused problems on Nexus 6).

    I found a few cases on the web with people solving RS issues by flashing new drivers, but this is unacceptable for me.

    To recap: I explicitly set #pragma rs_fp_full.