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:
rsDebug()
per this post:rsDebug()
in code and actually logging appears to run the
script as intended, but needless to say this is no solution since it
slows the scripts down to a halt.#pragma rs_fp_relaxed
seemed to have fixed the problem, but
after a few builds problem reappeared.adb shell setprop debug.rs.default-CPU-driver 1
fixes the problem,
but the whole point of using renderscript was to utilize
heterogeneous computingI 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);
}
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
.