2014-01-05 72 views
6

我們的遊戲要求我們不斷加載並創建新圖像,然後將其放到紋理頁上,然後用於渲染。我們使用glTexSubImage2d上傳來修改部分紋理頁面。我們不保留系統副本。每當我們這樣做時,我們在glTexSubImage2d調用中有六幀延遲。我們在遊戲開始之前將大部分圖像加載到紋理上,但有些事情必然是動態的。在Android上上傳紋理時避免出現攤位

我假設整個渲染流水線,無論是雙緩衝還是三倍緩衝,都是因爲我想修改它正在使用的紋理,或者有一個引用。即使如此,六幀加上(0.1秒)似乎過度。我們在IOS上完全一樣,並且在紋理被修改時幾乎沒有注意到任何延遲。遊戲通常運行在1或2幀。

任何人都知道發生了什麼事?這是在三星Galaxy Note GTN7000上運行。我們正在使用SurfaceView類。你可以「關閉這個停車場」。我知道這可能意味着一個框架左右的文物,因爲渲染可能沒有更新的紋理。

此外,任何想法如何知道或設置內部是否是雙重或三重緩衝。

我也讀過,大多數桌面/ PC OpenGL驅動程序通過擁有兩個或三個紋理副本並更新僅當前未使用的那些副本,然後及時更新這些副本。我們根本沒有這個記憶!

感謝

肖恩

回答

2

馬裏GPU(在N7000使用的)是此類的紋理上傳失速的最糟糕的GPU。其他GPU對它的處理要好得多(或者至少司機會更好地處理它)。

我已經經歷了與您描述的完全相同的問題,唯一的解決方案是保留紋理數據的CPU副本,並對紋理進行三重緩衝。每當我修改紋理時,我只修改CPU副本,並將紋理標記爲髒。在每幀的開始處,如果緩衝區已經更新,我循環三個紋理,並在其中一個上執行glTexSubImage2D,然後成爲活動紋理。

如果您使用的紋理少於三個,或者如果您犯了錯誤,並且使用了在最後兩幀中使用了glTexSubImage2D的紋理,它仍然會失速。

我只在檢測到Mali GPU時執行此操作(檢查驅動程序GL字符串)。對於其他GPU和iOS,驅動程序足夠好,不需要三重緩衝(因此我不必保留數據的CPU副本)。我確實在Arm/Mali開發者論壇上檢查過這個問題,他們推薦三重緩衝。你不應該需要超過三個。

另一個解決方法我有一些有限的成功,在Mali GPU上總是使用glTexImage2D代替glTexSubImage2D。這需要保留紋理數據的CPU副本。它在我的測試中執行速度更快,大概是因爲驅動程序內部正在製作紋理的新副本,因此如果以前的紋理仍在使用中,則不必停止。

還有一個其他可能的解決方案,我也實施但不再使用。您可以使用Android GraphicBuffers。看到這個鏈接的一些基本信息:Using Direct Textures on Android 這種方法可以讓你寫入沒有停頓的紋理,但是,它不是官方支持的API,我只能在馬裏工作,而且只需付出很多努力。它並沒有完全解決它自己的問題,因爲你仍然需要做你自己的同步控制,否則你的應用程序可能會覆蓋正在使用的紋理數據,並最終在屏幕上出現一些錯誤。

+0

感謝您的支持!我試過CPU拷貝的東西。這使得整體速度略微下降,但卻消除了巨大的峯值,代價是內存使用量幾乎翻了一番。我也嘗試製作「更多」但「更小」的紋理 - 我們試圖避免的,因爲在IOS上紋理交換越少渲染速度越快。有8 @ 2kx2k,但32 @ 1kx1k使尖峯更小,暗示驅動程序下載/轉換/重新上傳glTexSubImage2d上的整個紋理。無論哪種方式可以幫助取決於芯片組兩個簡單的選項,所以再次感謝! – user3162134