2012-05-30 75 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的聯盟中有點不在意。 –