2012-05-30 46 views
2

我编写了一个快速应用程序,以了解RenderScript的极限,并发现当达到大约65,000个三角形时,系统根本不会绘制任何附加的三角形。例如,如果我创建了一个包含70,000个三角形的圆柱体,则圆柱体中缺少一个与超过〜65,000个计数的三角形相对应的楔形体。三角形被纹理化,为了便于编写应用程序,我只使用了TriangleMeshBuilder类,因此没有真正的优化,例如使用trifans或tristrips。硬件是三星Galaxy Nexus。 LogCat报告堆大小约15MB,免费3%。我没有收到有关图形系统或RenderScript的错误或警告。RenderScript中的最大三角形数

任何人都可以解释三角形被丢弃的原因吗?我是否处于RenderScript正在优雅处理的硬件限制?

UPDATE发生在三星银河NEXUS(4.0.3),三星Galaxy Tab 7.0+(3.2)和摩托罗拉Xoom的(3.2)。全部在大约65,000个三角形的同一点。这些设备中的每一个都有不同的GPU。

UPDATE 2为了回应史蒂夫布莱克威尔的见解,我还有一些想法。

710-712行确实将int索引向下转换为short,因此65536变为0,正如Steve指出的那样。另外,757行的“强制转换”并不像告诉RenderScript最终发送给它的二进制数据的格式那么简单。 RenderScript需要将所有数据打包成RenderScript特定的数据类型,称为Allocation,以便从Java移动到RenderScript运行时,并且需要通知数据结构。根据Steve的观点,这是一个bug,第757行告诉RenderScript将索引数据当作short(无符号16位),但是它发送了一个32位有符号值(由于没有检查而被接受, ,然后只使用较低的16位,因此为什么我们在低于该阈值时绘制某些东西,以及在我们走过时连接回第一个索引的三角形)。

子类TriangleMeshBuilder,看看我是否可以把它接受这些数值都为整数来增加此限制没有工作,这使我相信,在深代码的地方,我们没有获得,还有一个额外的参考未签名的短裤。看起来像唯一的解决办法是按照Steve的建议添加额外的顶点缓冲区,这与现有的Mesh.AllocationBuilder类很容易完成。我还会在开发人员环聊中与Google展开讨论,以确定这实际上是一个错误还是故意。

+0

你有没有在其他设备上试过这个? –

回答

3

我对RenderScript几乎一无所知,所以我不知道这是否是一些固有的限制,硬件问题,或与TriangleMeshBuilder有关,但我敢打赌,你会在数字65535之后用完三角形。

这是一个幻数,因为它是无符号16位整数的最大值。 (Wikipedia

我会怀疑代码中的某个地方有一个可容纳三角形数的unsigned short。它不会在Java代码中,因为Java没有无符号值。由于CPU寄存器/路径> = 32位,所以限制可能不是硬件。所以我会检查TriangleMeshBuilder。

编辑:

这是上line 553一个伟大的发现。每个索引的值必须符合short。它看起来像在line 710-712发生downcast。

我假设你打电话给addTriangle()。该功能需要三个int s,然后明确转换为short。我认为那是一个错误,因为沮丧发生在默默地发生,而这不是你期望的函数签名。

line 768上,该虚假数据被传递给Allocation.copy1DRangeFromUnchecked()。我没有完全遵循,但我想象一下,在某些时候,那些有符号值将被转换为无符号值:-32768到-1会变回32768到65535.因此,将索引转换为负值看起来很糟糕,但它只是重新解释相同的数据,这不是一个真正的问题。

当您发送像65536这样的值时,真正的问题就开始了。当65536被转换为short时,它会变成0.这是一个真正的数据丢失。现在你指的是不同的索引,而一个未签名的转换不能解决它。

真正的启发是copy1DRangeFromUnchecked()是一个重载函数,并且其中一个overloads takes an int[],所以这不需要成为一个问题。

对于解决方法,我想你可以继承TriangleMeshBuilder并重写成员变量mIndexData[]和方法addTriangle()。或者,也许你可以使用多个顶点缓冲区。或者在某个地方提交错误报告?无论如何,有趣的问题。

+0

它不能在TriangleMeshBuilder中,因为它也是Java,但是因为RenderScript是用C99编写的,所以很可能是这样。我觉得没有意识到自己已经接近了这个门槛,因此觉得很愚蠢,特别是因为它让我觉得我低于32位的限制。我会试着看看C代码,看看是否有任何东西弹出。 – Jared

+0

我只是看了一下相关RenderScript数据类型的类型定义,它们都使用无符号的32位整数。最初我会怀疑(请纠正我,如果我错了),这不是问题,但我没有办法查看RenderScript的实际来源(只是头文件)。 – Jared

+0

我不知道该从哪里出发。如果你有你想要展示的代码,或者你可以指出你正在使用的一个例子,那可能会有所帮助,但我在RenderScript的联盟中有点不在意。 –