Renderscript 图像处理 Nexus 6 Marshmallow 问题
Renderscript image processign Nexus 6 Marshmallow issue
我正在使用 renderscript 进行实时图像处理(相机预览)。我在 Nexus 6 Marshmallow 6.1 上遇到问题,我的一些脚本不会 运行 超过几帧(rs 内核 运行s)。这些相同的脚本在 Nexus 4 Lollipop 5.1 上完美运行。
症状:
脚本适用于多个 运行s(构建)。在第 n 次 运行 时,某些脚本停止按预期工作,并且所有后续 运行 都出现上述问题。我无法在导致问题的代码中建立某些特定操作。它看起来完全是随机的,至少从我收集到的信息来看是这样。
我尝试了什么:
- 重新启动 phone、卸载应用程序、清理项目、使 Android Studio 中的缓存无效都没有结果。
- 根据此 post 添加
rsDebug()
:
RenderScript code not working without rsDebug
似乎已经解决了问题,但经过几次构建后出现问题
又出现了。
- 在代码中添加
rsDebug()
并且实际记录显示 运行
按预期编写脚本,但不用说这不是解决方案,因为它
使脚本停止运行。
- 删除
#pragma rs_fp_relaxed
似乎解决了问题,但是
几次构建后问题再次出现。
adb shell setprop debug.rs.default-CPU-driver 1
修复了问题,
但使用 renderscript 的全部意义在于利用
异构计算
我正在使用这个内核签名 uchar4 __attribute__((kernel)) filter(uchar4 v_in, uint32_t x, uint32_t y)
,虽然 RS_KERNEL
导致同样的问题。
感谢您的帮助和想法。
受影响的代码示例:(Google 来自此处的演示代码: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);
}
您能否仔细检查您正在写入的图像是否在查看 alpha 通道或尝试明确设置它。 (这更像是评论,但我没有足够的积分)
经过大量研究后,我认为这很可能是 GPU 驱动程序问题。话虽如此,我在上面提到我尝试删除 #pragma rs_fp_relaxed
似乎暂时解决了问题。我现在认为,选择 RS 使用的 fp
精度是一场赌博,这就是它有时有效有时无效的原因。当我明确设置 #pragma rs_fp_full
时我得出了这个结论,这似乎已经永久解决了这个问题,因为它与 native
函数一起应该是硬件支持的计算(到目前为止适用于所有导致问题的脚本在 Nexus 6 上)。
我在网上发现了几个案例,有人通过刷新驱动来解决 RS 问题,但这对我来说是不能接受的。
回顾一下:我明确设置了 #pragma rs_fp_full
。
我正在使用 renderscript 进行实时图像处理(相机预览)。我在 Nexus 6 Marshmallow 6.1 上遇到问题,我的一些脚本不会 运行 超过几帧(rs 内核 运行s)。这些相同的脚本在 Nexus 4 Lollipop 5.1 上完美运行。
症状: 脚本适用于多个 运行s(构建)。在第 n 次 运行 时,某些脚本停止按预期工作,并且所有后续 运行 都出现上述问题。我无法在导致问题的代码中建立某些特定操作。它看起来完全是随机的,至少从我收集到的信息来看是这样。
我尝试了什么:
- 重新启动 phone、卸载应用程序、清理项目、使 Android Studio 中的缓存无效都没有结果。
- 根据此 post 添加
rsDebug()
:
RenderScript code not working without rsDebug 似乎已经解决了问题,但经过几次构建后出现问题 又出现了。 - 在代码中添加
rsDebug()
并且实际记录显示 运行 按预期编写脚本,但不用说这不是解决方案,因为它 使脚本停止运行。 - 删除
#pragma rs_fp_relaxed
似乎解决了问题,但是 几次构建后问题再次出现。 adb shell setprop debug.rs.default-CPU-driver 1
修复了问题, 但使用 renderscript 的全部意义在于利用 异构计算
我正在使用这个内核签名 uchar4 __attribute__((kernel)) filter(uchar4 v_in, uint32_t x, uint32_t y)
,虽然 RS_KERNEL
导致同样的问题。
感谢您的帮助和想法。
受影响的代码示例:(Google 来自此处的演示代码: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);
}
您能否仔细检查您正在写入的图像是否在查看 alpha 通道或尝试明确设置它。 (这更像是评论,但我没有足够的积分)
经过大量研究后,我认为这很可能是 GPU 驱动程序问题。话虽如此,我在上面提到我尝试删除 #pragma rs_fp_relaxed
似乎暂时解决了问题。我现在认为,选择 RS 使用的 fp
精度是一场赌博,这就是它有时有效有时无效的原因。当我明确设置 #pragma rs_fp_full
时我得出了这个结论,这似乎已经永久解决了这个问题,因为它与 native
函数一起应该是硬件支持的计算(到目前为止适用于所有导致问题的脚本在 Nexus 6 上)。
我在网上发现了几个案例,有人通过刷新驱动来解决 RS 问题,但这对我来说是不能接受的。
回顾一下:我明确设置了 #pragma rs_fp_full
。