2011-11-07 44 views
9

我有一個質地很重的OpenGL遊戲,我想根據設備有多少RAM來調整。我在iPhone 4或iPad2上的最高分辨率紋理工作正常,但較早的設備在加載紋理時崩潰。我有這些紋理的低分辨率版本,但我需要知道何時使用它們。我目前的策略是檢測特定的舊設備(3GS有一個低分辨率的屏幕,iPad沒有相機),然後只加載高分辨率的紋理IPad2及以上和iPhone 4及以上 - 我想我需要爲iPod touch做點事情。但我更願意使用特徵檢測而不是硬編碼設備模型,因爲模型檢測對於未來對API和硬件的更改是脆弱的。響應iOS中的RAM可用性

我正在考慮的另一種可能性是首先加載高分辨率紋理,然後在出現低內存警告的時刻將其替換爲低分辨率紋理。但是,我不確定我會有機會迴應;我注意到,在調試控制檯上出現任何通知之前,應用程序經常死亡。

如何檢測我運行的設備是否沒有足夠的RAM來加載我的紋理的高分辨率版本?

退一步,有一些其他的自適應技術,我可以使用特定於OpenGL紋理內存?

注:

  1. 我已經搜查和關閉SO爲與可用RAM檢測的答案,但他們基本上都勸告剖析內存使用情況和消除浪費(減少臨時對象的生命週期,以及所有廢話)。我儘可能多地完成了這些工作,而且我無法將高分辨率紋理壓縮到較舊的設備中。

  2. PVRTC不是一個選項。紋理包含片段着色器要使用的數據,並且必須以無損格式存儲。

+0

注意,您可以同時獲得總RAM和在這個線程詳細的可用RAM統計[iOS上的可用內存(http://stackoverflow.com/questions/5012886)。另外,我測試了我的iPhone 4上的代碼,它效果很好! –

回答

11

要獲得總(最大)物理設備使用[NSProcessInfo processInfo].physicalMemory的RAM。

參見Documentation

0

據我所知道的3件最重要的事情之一能做的就是 -

  1. 實施- (void)didReceiveMemoryWarning和應對時的iOS將警告發送1 & 2.
  2. 檔案代碼工具試圖找到泄漏&更好的mem最佳實施方式。
  3. 檢測設備類型&也許使用該信息。
  4. 使用某種形式的紋理壓縮,如PVRTC來節省空間。

我覺得你正在做的大部分。事情是一個甚至不知道iOS設備有多少內存。 Apple不會爲iOS設備發佈技術規格。

此外,它不能被認爲只有說100mb的消費後,你會得到一個mem警告。 iOS給出的警告取決於設備的當前狀態&其他應用程序正在運行的其他應用程序&它們消耗多少內存。所以它變得棘手。

我可以建議2必須閱讀部分 - Best Practices for Working with Texture DataTuning Your OpenGL ES Application

2

最重要的想你需要知道的內存管理在這種情況下閹使用高或低分辨率的紋理。我用最簡單的方法是檢查這個

CGFloat scale = [[UIScreen mainScreen] scale]; 
if ((scale > 1.0) || (self.view.frame.size.width > 320)) { 
     highRes = TRUE; 
} 

這適用於所有的設備,到目前爲止,應該面向未來,新的設備將使用高分辨率。 你也可以計算出在那裏縱橫比(後來有助於在iPad VS iphone)

aspect = self.view.frame.size.width/self.view.frame.size.width 

不要裝入HIGHRES第一,它殺死你的應用程序加載時間,我的3G我大部分的啓動都花在加載(甚至低分辨率)的紋理,只是在開始時測試這個權利,不要觸摸高分辨率的東西。

在舊設備上的程序將不會因大紋理警告死,可能是與不是去調試器能夠捕獲視頻內存消耗和死亡本身。

爲了更加優化的考慮你的貼圖着色檢查實際上正在使用(僅當您使用3D對象)最低紋理大小。

忘記了視頻RAM的大小問題,內存實際上是共享的,所以你的系統內存競爭,你有一個MB限制使用的舊設備,但它仍然是系統內存。

關於內存管理,有很多種方法可以實現,最簡單的方法是標記加載的紋理和需要的紋理,當出現內存警告時,轉儲加載但不需要的紋理。

+0

謝謝您的詳細回覆。我不能接受這個,因爲它沒有回答如何檢測RAM而不是使用特徵檢測的核心問題(或者你是否暗示這是不可能的或不值得追求的?),但是用於指出'scale> 1.0'來檢測iPhone 4.我沒有想到這一點。 –

+0

你可以嘗試並檢測內存越獄的唯一方法是嘗試填充所有內容並測量你獲得的內容。另外,由於內存與所有可能運行的其他應用程序(系統,如郵件等)共享,即使知道物理內存的數量也不值多少。這就是爲什麼我說要忘記這條路線,這不是你正在尋找的堅實基礎。 – led42

+0

你的措辭是不明確的,我是不是應該把視頻內存看作是單獨的,或者放棄測量RAM。我不關心其他正在運行的應用程序;經驗上,256 MB的設備總是會崩潰,而512 MB的設備永遠不會。此外,您提出的測試失敗,最新的iPod Touch - 視網膜和256 MB - 強調了我對模型檢測脆弱性的擔憂。順便提一句,尋找iPod Touch問題的解決方案讓我有了一個可能的答案,我將分開發布。 –

7

總物理RAM可通過sysctl()獲得,如this blog post中所述,並作爲一個漂亮的清潔API here(參見在相應的.m文件中執行totalMemory)實現。

我解除了博客的代碼爲方便和後人:

#include <sys/sysctl.h> 

size_t phys_mem() 
{ 
int mib[] = { CTL_HW, HW_PHYSMEM }; 
size_t mem; 
size_t len = sizeof(mem); 
sysctl(mib, 2, &mem, &len, NULL, 0); 
return mem; 
} 

我不知道蘋果是否會批准,以這種方式使用sysctl()的應用程序。據記載,但只適用於Mac OS X.

+1

您是否曾經在App Store應用程序中獲得批准? – Nate

+2

@Nate:是的。 [Your World](http://itunes.apple.com/us/app/your-world/id412566625?mt=8)在超過384 MB的設備上加載了9600萬像素的地球;否則,它會回落到2400萬像素版本。這個數字沒有什麼特別之處;它只是可以使用的設備和不能使用的設備之間的一半。 –

+2

只需使用[NSProcessInfo processInfo] .physicalMemory – Steve