API 23中遇到了RenderScript不稳定性问题

3
我的应用程序使用基于 RenderScript 的 Canny 边缘检测的专有实现。我在许多不同API的设备上进行了测试,并且它非常可靠。现在我正在使用 API23 的新款三星S7进行测试。只有在这里,我遇到了一个非常丑陋的问题。一些边缘图片充斥着成千上万个由幅度梯度计算内核产生的伪像,而不是基于实际图像信息。尝试使用各种 TargetAPI,开启和关闭 renderscript.support.mode 等方法后,我终于发现,只有在第二次或更多次使用 RenderScript(和 Script)实例时才会出现这个问题。如果第一次使用就不存在这个问题。

出于效率原因,我仅在 MainActivity 的 onCreate 方法中创建了 RenderScript 和 Script 实例,并在此之后反复使用它们。当然,我不想改变这个做法。

有人有解决这个问题的办法吗?谢谢。

更新:这里发生了很疯狂的事情。似乎新创建的分配从一开始就不是空的!当运行:

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

...... byte Array se里面充满了奇怪的数字.... HELP!有什么想法,这到底是怎么回事?

更新2:我在这里犯了自己的无知——实际上并不应该因为这个杰作而得到分数....然而,为了辩护,我必须说问题比它在这里出现的要微妙一些。情况是我需要分配一个全局分配(Byte/U8),最初应该是空的(即零),然后,在内核中通过rsSetElementAt_uchar()部分设置为1(只有边缘)。由于这个方法已经使用了很多个月,我不再意识到这个分配中没有明确地赋值零....这只在API 23中产生了影响,所以也许这可以帮助其他人不要掉进这个陷阱.....因此,请注意:除了用Java默认值填充为0的数值数组之外,不能假定分配在初始化时都充满了零。谢谢,Sakridge。


你是在使用内在函数还是全部自定义脚本?在你的自定义脚本中有全局数据吗?你是在这些运行之间重复使用分配(而不仅仅是重复使用 RenderScript 和 Script 对象)吗?你可能还想尝试只在 CPU 模式下运行(以防这与 GPU 相关)。尝试 "adb shell setprop debug.rs.default-CPU-driver 1",看看是否有任何不同。 - Stephen Hines
我正在使用ScriptIntrinsicBlur和YUVtoRGB(针对旧相机API)。我也只在计算量最大的内核中看到问题,这是一个Sobel 5x5卷积(虽然我认为ScriptIntrinsicBlur做了更多的工作)。是的,我也以这样的方式重用分配,即在下一个内核中再次使用它们时,我不会将outAllocations复制到数组中。实际上,当我仅在CPU上运行时,该问题消失了。有没有办法在所有设备上永久解决这个问题? - Settembrini
从您在此处的评论http://stackoverflow.com/a/25253181/5148048中可以得出结论,除了每次使用内核重新创建rs实例以获得第一次仅在CPU上运行的rs-run(正如其他帖子中所述)之外,没有其他解决方案。 - Settembrini
不幸的是,重新创建 rs 实例也没有帮助,因为它并不能可靠地在仅使用 CPU 上运行。 - Settembrini
1个回答

2

创建Allocation时,原始类型(非结构体/对象)的分配数据默认情况下不会被初始化,除非使用createFromBitmap api传递了位图。如果您期望这种情况,则可能您的应用程序存在错误,在驱动程序初始化为0时未暴露出来。如果您能够发布可以重现问题的示例代码,将有助于解决问题。

通过从位图或Java数组复制来初始化您的分配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接